Package: nbd-client
Version: 1:2.9.15-1
Severity: minor
Tags: patch

If KILLALL is set false in /etc/nbd-client, then the init script
attempts to umount all listed devices, even those that are selected to
be swap devices.  This means an error and a long wait for every network
swap device.

My patch corrects this by being selective about which devices to umount
and which to swapoff.

The only change when KILLALL is not false is to swapoff only devices
listed in /proc/swaps if that exists.  If /proc/swaps does not exist,
then we get the old behaviour of swapoff all devices.

As I use nbd only for swaps, and have no filesystems other than NFS in
my kernel (diskless embedded device) it would be worth verifying with
filesystems before committing - sorry I'm not in a position to have
tested that.  But I'm pretty confident I haven't broken it.

Here's the patch:

--- etc/init.d/nbd-client.dpkg-dist	2010-03-24 22:08:02.000000000 +0000
+++ etc/init.d/nbd-client	2010-05-24 12:33:11.000000000 +0100
@@ -38,6 +38,57 @@
 
 test -x $DAEMON || exit 0
 
+get_devices() {
+    DEVICES=
+    i=0
+    while [ ! -z ${NBD_DEVICE[$i]} ]
+    do
+	if [ ${NBD_TYPE[$i]} == "$1" ]
+	then
+	    DEVICES="$DEVICES ${NBD_DEVICE[$i]}"
+	fi
+	i=$(($i + 1))
+    done
+}
+
+get_all_devices() {
+	if [ "$KILLALL" == "false" ]
+	then
+	    DEVICES=${NBD_DEVICE[*]}
+	else
+	    if [ -d /dev/nbd ]
+	    then
+		    DEVICES=/dev/nbd/*
+	    else
+		    DEVICES=/dev/nb*
+	    fi
+	fi
+}
+
+get_swap_devices() {
+	if [ "$KILLALL" == "false" ]
+	then
+	    get_devices s
+	else
+	    if [ -f /proc/swaps ]
+	    then
+		DEVICES=`grep '^/dev/nb' /proc/swaps | cut -d ' ' -f1`
+	    else
+		get_all_devices
+	    fi
+	fi
+}
+
+get_mount_devices() {
+	if [ "$KILLALL" == "false" ]
+	then
+	    get_devices f
+	else
+	    DEVICES=`mount | cut -d " " -f 1 | grep /dev/nbd`
+	fi
+}
+
+
 case "$1" in
     connect)
 	# I don't use start-stop-daemon: nbd-client only does some setup
@@ -134,19 +185,14 @@
 	;;
     stop)
 	echo "Stopping $DESC: "
-	echo "umounting all filesystems for nbd-blockdevices..."
-	if [ "$KILLALL" != "false" ]
-	then
-	  DEVICES=`mount | cut -d " " -f 1 | grep /dev/nbd`
-	else
-	  DEVICES=${NBD_DEVICE[*]}
-	fi
+	get_mount_devices
 	for dev in $DEVICES
 	do
 	  # Ignore devices with _netdev option (sysvinit takes care of those)
 	  line=$(grep $dev /etc/fstab | grep "_netdev")
 	  if [ -z "$line" ]
 	  then
+	    echo "umounting filesystem from $dev..."
 	    umount $dev 2>/dev/null
 	    if [ $? -eq 1 ]
 	    then
@@ -162,20 +208,16 @@
 	  fi
 	  echo $dev
 	done
-	if [ "$KILLALL" != "false" ]
-	then
-	    if [ -d /dev/nbd ]
+	get_swap_devices
+	if [ "$DEVICES" ]
 	    then
-		    DEVICES=/dev/nbd/*
-	    else
-		    DEVICES=/dev/nb*
-	    fi
+	    echo "Invoking swapoff on $DEVICES..."
+	    swapoff $DEVICES 2>/dev/null
 	fi
-	echo "Invoking swapoff on NBD devices..."
-	swapoff $DEVICES 2>/dev/null
-	echo "Disconnecting $DESCes..."
+	get_all_devices
 	for i in $DEVICES
-	  do
+	do
+	  echo "Disconnecting $i"
 	  $DAEMON -d $i 2>/dev/null >/dev/null
 	done
 	rmmod nbd

Reply via email to