commit f5ccff802700320f28addd420e0916e621235f5a
parent 148be7283b4ca7ec05ceb417f2797e367d829a22
Author: Jaromil <jaromil@dyne.org>
Date:   Wed, 15 May 2013 13:53:28 +0200
new lookup for mounted tombs fully adopted
now tomb close looks up bind hooks correctly
this commit includes backward compatibility fix for Debian 6
Diffstat:
| M | src/tomb |  |  | 323 | +++++++++++++++++++++++++++++++++++++------------------------------------------ | 
1 file changed, 152 insertions(+), 171 deletions(-)
diff --git a/src/tomb b/src/tomb
@@ -850,7 +850,7 @@ lock_tomb_with_key() {
     if [ $? = 0 ]; then
         # is it a LUKS encrypted nest? then bail out and avoid reformatting it
         _warning "The tomb was already locked with another key"
-        losetup -d ${nstloop}
+	losetup -d ${nstloop}
 	die "Operation aborted. I cannot lock an already locked tomb. Go dig a new one."
     else
 	_message "fine, this tomb seems empty."
@@ -1324,6 +1324,78 @@ mount_tomb() {
 }
 
 # }}}
+
+# {{{ - Internal operations on mounted tombs
+
+# list_tomb_mounts 
+# print out an array of mounted tombs (internal use)
+# format is semi-colon separated list of attributes
+# if 1st arg is supplied, then list only that tomb
+# Positions in array:
+# 1 = full mapper path
+# 2 = mountpoint
+# 3 = filesystem type
+# 4 = mount options
+# 5 = tomb name
+list_tomb_mounts() {
+    if [ "$1" = "" ]; then
+	# list all open tombs
+	mount -l \
+	    | awk '
+BEGIN { main="" }
+/^\/dev\/mapper\/tomb/ { 
+  if(main==$1) next;
+  print $1 ";" $3 ";" $5 ";" $6 ";" $7
+  main=$1
+}
+'
+    else
+    	# list a specific tomb
+	mount -l \
+	    | awk -vtomb="[$1]" '
+BEGIN { main="" }
+/^\/dev\/mapper\/tomb/ {
+  if($7!=tomb) next;
+  if(main==$1) next;
+  print $1 ";" $3 ";" $5 ";" $6 ";" $7
+  main=$1
+}
+'
+    fi
+}
+
+# list_tomb_binds
+# print out an array of mounted bind hooks (internal use)
+# format is semi-colon separated list of attributes
+# needs an argument: name of tomb whose hooks belong
+list_tomb_binds() {
+    if [ "$1" = "" ]; then
+        _failure "internal error: list_tomb_binds called without argument."; fi
+    
+    # list bind hooks on util-linux 2.20 (Debian 7)
+    mount -l \
+	| awk -vtomb="$1" '
+BEGIN { main="" }
+/^\/dev\/mapper\/tomb/ {
+  if($7!=tomb) next;
+  if(main=="") { main=$1; next; }
+  if(main==$1)
+    print $1 ";" $3 ";" $5 ";" $6 ";" $7 
+}
+'
+    
+    # list bind hooks on util-linux 2.17 (Debian 6)
+    tombmount=`mount -l \
+      | awk -vtomb="$1" '
+/^\/dev\/mapper\/tomb/ { if($7!=tomb) next; print $3; exit; }'`
+    
+    mount -l | grep "^$tombmount" \
+	| awk -vtomb="$1" '
+        /bind/ { print $1 ";" $3 ";" $5 ";" $6 ";" $7 }'
+}
+
+# }}}
+
 # {{{ - Close
 # {{{   - Slam the door
 # Kill all processes using the tomb
@@ -1358,141 +1430,104 @@ umount_tomb() {
     local pathmap mapper tombname tombmount loopdev
     local ans pidk pname
 
-    if ! [ $1 ]; then
-	tombs=`find /dev/mapper -name 'tomb.*'`
-	how_many_tombs=`wc -w <<< "$tombs"`
-	if [[ "$how_many_tombs" == "0" ]]; then
-	    _warning "There is no open tomb to be closed"
-	    return 1
-	elif [[ "$how_many_tombs" == "1" ]]; then
-	    #mapper=`find /dev/mapper -name 'tomb.*'`
-	    xxx "closing mapper $tombs"
-	    umount_tomb ${tombs}
-	    return 1
-	else
-	    _warning "Too many tombs mounted, please specify which to unmount:"
-	    ls /dev/mapper/tomb.*
-	    _warning "or issue the command 'tomb close all' to clos'em all."
-	    return 1
-	fi
-    fi
-
     if [ "$1" = "all" ]; then
-	tombs=`find /dev/mapper -name 'tomb.*'`
-	if ! [ $tombs ]; then
-	    _success "Tombs are all closed, cemetery is quiet."
-	    return 0
-	fi
-	for t in ${(f)tombs}; do
-	    umount_tomb ${t}
-	done
-	return 0
-    fi
-
-    # tomb close argument deduction
-    pathmap=`dirname "$1"`
-
-    if [ "${pathmap}" = "/dev/mapper" ]; then
-	mapper="$1" # argument is the mapper (or none which autofills mapper)
-	tombname="${mapper[(ws:.:)2]}"
-	tombmount=`mount -l | \
-	    awk -vtomb="[$tombname]" '/^\/dev\/mapper\/tomb/ { if($7==tomb) print $3 } '`
-    elif [ "$pathmap" = "." ]; then
-	tombname="$1" # argument is the name
-	mapper=`mount -l | \
-	    awk -vtomb="[$tombname]" '/^\/dev\/mapper\/tomb/ { if($7==tomb) print $1 } '`
-	tombmount=`mount -l | \
-	    awk -vtomb="[$tombname]" '/^\/dev\/mapper\/tomb/ { if($7==tomb) print $3 } '`
+	mounted_tombs=(`list_tomb_mounts`)
     else
-	tombmount="$1" # argument should be the mount
-    	mapper=`mount | awk -vmnt="$tombmount" '/^\/dev\/mapper\/tomb/ { if($3==mnt) print $1 }'`
-	tombname="${mapper[(ws:.:)2]}"
+	mounted_tombs=(`list_tomb_mounts $1`)
     fi
 
-    # avoid block when the same tomb is mounted, take only the first
-    for tm in ${(f)tombmount}; do tombmount=${tm}; break; done
+    { test ${#mounted_tombs} = 0 } && {
+	    _warning "There is no open tomb to be closed"
+	    return 1 }
 
-    xxx "tomb close argument: $1"
-    xxx "name: $tombname"
-    xxx "mount: $tombmount"
-    xxx "mapper: $mapper"
+    { test ${#mounted_tombs} -gt 1 } && { test "$1" = "" } && {
+	    _warning "Too many tombs mounted, please specify one (see tomb list)"
+	    _warning "or issue the command 'tomb close all' to close them all."
+	    return 1 }
 
-    if ! [ -e "$mapper" ]; then
-	_warning "Tomb not found: $1"
-	_warning "Please specify an existing tomb."
-	return 0
-    fi
+    say "Tomb close $1"
 
-    if [ $SLAM ]; then
-	_success "Slamming tomb $tombname mounted on $tombmount"
-	_message "Kill all processes busy inside the tomb"
-        if ! slam_tomb "$tombmount"; then
-            _warning "Cannot slam the tomb $tombname"
-            return 1
-        fi
-    else
-	_success "Closing tomb $tombname mounted on $tombmount"
-    fi
+    for t in ${mounted_tombs}; do
+	mapper=`basename ${t[(ws:;:)1]}`
+	tombname=${t[(ws:;:)5]}
+	tombmount=${t[(ws:;:)2]}
+	tombfs=${t[(ws:;:)3]}
+	tombfsopts=${t[(ws:;:)4]}
+	tombloop=${mapper[(ws:.:)4]}
 
-    # check if there are binded dirs and close them
-    tombmount_esc=`sed 's:\/:\\\/:g' <<< $tombmount `
-    unbind=`mount | awk "/^$tombmount_esc.*bind/"' { print $3 }'`
-    for b in ${(f)unbind}; do
-	hook="`basename $b`"
-	_message "closing tomb hook: $hook"
-	umount $b
-	if [[ $? != 0 ]]; then
-	    if [ $SLAM ]; then
-		_success "Slamming tomb: killing all processes using this hook"
-                slam_tomb "$b"
-                if [[ $? == 1 ]]; then
-                    _warning "Cannot slam the tomb $b"
-                    return 1
-                fi
-		umount $b
-            else
-		_warning "Tomb hook is busy, cannot close tomb."
+	xxx "name: $tombname"
+	xxx "mount: $tombmount"
+	xxx "mapper: $mapper"
+	
+	{ test -e "$mapper" } && {
+	    _warning "Tomb not found: $1"
+	    _warning "Please specify an existing tomb."
+	    return 0 }
+	
+	if [ $SLAM ]; then
+	    _success "Slamming tomb $tombname mounted on $tombmount"
+	    _message "Kill all processes busy inside the tomb"
+            if ! slam_tomb "$tombmount"; then
+		_warning "Cannot slam the tomb $tombname"
 		return 1
-	    fi
+            fi
+	else
+	    say "Closing tomb $tombname mounted on $tombmount"
 	fi
-    done
 
+    # check if there are binded dirs and close them
+	bind_tombs=(`list_tomb_binds $tombname`)
+	for b in ${bind_tombs}; do
+	    bind_mapper="${b[(ws:;:)1]}"
+	    bind_mount="${b[(ws:;:)2]}"
+	    _message "closing tomb bind hook: $bind_mount"
+	    umount $bind_mount
+	    if [[ $? != 0 ]]; then
+		if [ $SLAM ]; then
+		    _success "Slamming tomb: killing all processes using this hook"
+                    slam_tomb "$bind_mount"
+                    if [[ $? == 1 ]]; then
+			_warning "Cannot slam the bind hook $bind_mount"
+			return 1
+                    fi
+		    umount $bind_mount
+		else
+		    _warning "Tomb bind hook $bind_mount is busy, cannot close tomb."
+		fi
+	    fi
+	done
+	
     # Execute post-hooks for eventual cleanup
-    if ! option_is_set -n ; then
-	exec_safe_post_hooks ${tombmount%%/} close
-    fi
+	if ! option_is_set -n ; then
+	    exec_safe_post_hooks ${tombmount%%/} close
+	fi
 
-    if [ $tombmount ]; then # tomb is actively mounted
 	xxx "performing umount of $tombmount"
 	umount ${tombmount}
-	if ! [ $? = 0 ]; then
-	    _warning "Tomb is busy, cannot umount!"
+	if ! [ $? = 0 ]; then _warning "Tomb is busy, cannot umount!"
 	else
         # this means we used a "default" mount point
-            if [ "${tombmount}" = "/media/${tombname}.tomb" ]; then
-	        rmdir ${tombmount}
-            fi
+            { test "${tombmount}" = "/media/${tombname}.tomb" } && {
+	        rmdir ${tombmount} }
 	fi
-    fi
-
-    cryptsetup luksClose $mapper
-    if ! [ $? = 0 ]; then
-	_warning "error occurred in cryptsetup luksClose ${mapper}"
-	return 1
-    fi
-
-    loopdev=`cut -d '.' -f4 <<< "$mapper"`
-    losetup -d "/dev/$loopdev"
-
-    # kill the status tray widget if still present
-    # this makes the widget disappear when closing tomb from cli
-    awkmapper=`sed 's:\/:\\\/:g' <<< $mapper`
-    statustray_pid=`ps ax | awk "/tomb-status $awkmapper/"' {print $1} '`
-    if [ ${statustray_pid} ]; then
-	kill ${statustray_pid}
-    fi
 
-    _success "Tomb $tombname closed: your bones will rest in peace."
+	cryptsetup luksClose $mapper
+	{ test $? = 0 } || {
+	    _warning "error occurred in cryptsetup luksClose ${mapper}"
+	    return 1 }
+	
+	losetup -d "/dev/$tombloop"
+	
+    # # kill the status tray widget if still present
+    # # this makes the widget disappear when closing tomb from cli
+    # 	awkmapper=`sed 's:\/:\\\/:g' <<< $mapper`
+    # 	statustray_pid=`ps ax | awk "/tomb-status $awkmapper/"' {print $1} '`
+    # 	{ test "$statustray_pid" = "" } || { kill ${statustray_pid} }
+	
+	_success "Tomb $tombname closed: your bones will rest in peace."
+	
+    done # loop across mounted tombs
+    
     return 0
 }
 # }}}
@@ -1700,60 +1735,6 @@ resize_tomb() {
 
 # }}}
 
-# print out an array of mounted tombs (internal use)
-# format is semi-colon separated list of attributes
-# if 1st arg is supplied, then list only that tomb
-# Positions in array:
-# 1 = full mapper path
-# 2 = mountpoint
-# 3 = filesystem type
-# 4 = mount options
-# 5 = tomb name
-list_tomb_mounts() {
-    if [ "$1" = "" ]; then
-	# list all open tombs
-	mount -l |
-	awk '
-BEGIN { main="" }
-/^\/dev\/mapper\/tomb/ { 
-  if(main==$1) next;
-  print $1 ";" $3 ";" $5 ";" $6 ";" $7
-  main=$1
-}
-'
-    else
-    	# list a specific tomb
-	mount -l |
-	awk -vtomb="[$1]" '
-BEGIN { main="" }
-/^\/dev\/mapper\/tomb/ {
-  if($7!=tomb) next;
-  if(main==$1) next;
-  print $1 ";" $3 ";" $5 ";" $6 ";" $7
-  main=$1
-}
-'
-    fi
-}
-
-# print out an array of mounted bind hooks (internal use)
-# format is semi-colon separated list of attributes
-# needs an argument: name of tomb whose hooks belong
-list_tomb_binds() {
-    if [ "$1" = "" ]; then
-        _failure "internal error: list_tomb_binds called without argument."; fi
-
-	mount -l |
-	awk -vtomb="$1" '
-BEGIN { main="" }
-/^\/dev\/mapper\/tomb/ {
-  if($7!=tomb) next;
-  if(main=="") { main=$1; next; }
-  if(main==$1)
-    print $1 ";" $3 ";" $5 ";" $6 ";" $7 
-}
-'
-}    
 
 # {{{ - Index
 # index files in all tombs for search