[Pbuilder-maint] Bug#391390: fails to umount /proc if /proc is not mounted

Loïc Minier lool at dooz.org
Mon Oct 30 00:50:42 CET 2006


        Hi,

 With the input of Martin, and following my own suggestions:

On Sat, Oct 28, 2006, Loïc Minier wrote:
>  On the topic of mounts, I'd like to add:
>  * a sanity check to popup a shell if a mount point isn't an empty
>    directory after umount
>  * reverse order of umounts so that /proc is umounted last
>  * perhaps a sanity check to grep /proc/mounts for the base path to the
>    chroot and see if anything mounted remains

 I completely reworked the patch.  A newer version is attached, which I
 tested in some scenarios already:

----- Unmounting /proc twice:
 -> unmounting proc filesystem
W: Could not unmount proc: umount: /home/lool/.pbuilder/build/sid/cow.2610/proc: not mounted
W: Ignored error in unmount

----- Unmounting /etc:
 -> unmounting etc filesystem
W: Could not unmount etc: umount: /home/lool/.pbuilder/build/sid/cow.4574/etc: not mounted
W: etc not empty
W: Tried ignoring error in unmount, but sanity check failed: etc might still be mounted
W: Retrying to unmount etc in 5s

----- Unmounting /etc/passwd:
 -> unmounting etc/passwd filesystem
W: Could not unmount etc/passwd: umount: /home/lool/.pbuilder/build/sid/cow.6381/etc/passwd: not mounted
W: etc/passwd isn't a directory
W: Tried ignoring error in unmount, but sanity check failed: etc/passwd might still be mounted
W: Retrying to unmount etc/passwd in 5s

----- Launching a process with CWD in the filesystem being unmounted:
 -> unmounting dev/pts filesystem
W: Could not unmount dev/pts: umount: /home/lool/.pbuilder/build/sid/cow.8223/dev/pts: device is busy
umount: /home/lool/.pbuilder/build/sid/cow.8223/dev/pts: device is busy
W: Retrying to unmount dev/pts in 5s
umount: /home/lool/.pbuilder/build/sid/cow.8223/dev/pts: device is busy

 It adds a sanity checking function, seems_truly_unmounted, which goes
 through great length to fail if there's a slight change that a
 mountpoint is still mounted.

 I will commit this patch and change the order of umounts so that bind
 mounts are unmounted first, and /proc last.

   Bye,
-- 
Loïc Minier <lool at dooz.org>
-------------- next part --------------
Index: ChangeLog
===================================================================
RCS file: /cvsroot/pbuilder/pbuilder/ChangeLog,v
retrieving revision 1.412
diff -u -r1.412 ChangeLog
--- ChangeLog	29 Oct 2006 02:16:49 -0000	1.412
+++ ChangeLog	29 Oct 2006 23:44:28 -0000
@@ -1,3 +1,10 @@
+2006-10-29  Loic Minier <lool at dooz.org>
+
+	* pbuilder-modules: add sanity checks during umount_one(); ignore
+	umount errors of the type "umount: /foobar: not mounted" and "umount:
+	/foobar: not found" as retries will be useless anyway, and these
+	errors shouldn't cause data loss; fixes #391390.
+
 2006-10-29  Junichi Uekawa  <dancer at debian.org>
 
 	* Documentation/pbuilder-doc.xml: developer info is updated.
Index: pbuilder-modules
===================================================================
RCS file: /cvsroot/pbuilder/pbuilder/pbuilder-modules,v
retrieving revision 1.99
diff -u -r1.99 pbuilder-modules
--- pbuilder-modules	24 Aug 2006 22:58:57 -0000	1.99
+++ pbuilder-modules	29 Oct 2006 23:44:28 -0000
@@ -86,6 +86,41 @@
     exit 1
 }
 
+# test whether a directory is empty
+# fails if "$*" exists but isn't a directory
+# fails and outputs garbage if "$*" doesn't actually exist
+is_empty_dir() {
+  return "$(find "$*" -maxdepth 0 -type d -empty -printf 0 -o -printf 1)"
+}
+
+# sanity checks to ensure mountpoint $1 is truly unmounted in $BUILDPLACE
+# (fails relatively often to ensure we don't "rm -rf" a bind mount)
+function seems_truly_unmounted() {
+    local mountpoint
+    mountpoint="$1"
+    if ! [ -e "$BUILDPLACE/$mountpoint" ]; then
+        echo "W: $mountpoint doesn't exist"
+        return 1
+    fi
+    if ! [ -d "$BUILDPLACE/$mountpoint" ]; then
+        echo "W: $mountpoint isn't a directory"
+        return 1
+    fi
+    if [ -r "$BUILDPLACE/proc/mounts" ] && grep -q "^[^ ]* $mountpoint " "$BUILDPLACE/proc/mounts"; then
+        echo "W: $mountpoint is mounted according to build place's /proc/mounts"
+        return 1
+    fi
+    if [ -r "/proc/mounts" ] && grep -q "^[^ ]* $BUILDPLACE/$mountpoint " "/proc/mounts"; then
+        echo "W: $mountpoint is mounted according to system's /proc/mounts"
+        return 1
+    fi
+    if ! is_empty_dir "$BUILDPLACE/$mountpoint"; then
+        echo "W: $mountpoint not empty"
+        return 1
+    fi
+    return 0
+}
+
 function umount_one () {
     if [ "${IGNORE_UMOUNT}" = "yes" ]; then
 	# support ignore umount option.
@@ -93,24 +128,45 @@
 	return
     fi
     echo " -> unmounting $1 filesystem"
-    if ! umount "$BUILDPLACE/$1"; then
-	    echo "W: Retrying to unmount $1"
+    local UMOUNT_OUTPUT
+    if ! UMOUNT_OUTPUT="$(LC_ALL=C umount "$BUILDPLACE/$1" 2>&1)"; then
+        echo "W: Could not unmount $1: $UMOUNT_OUTPUT"
+        local ignore_umount_error="no"
+        case $UMOUNT_OUTPUT in
+          "umount: "*": not found"|"umount:"*": not mounted")
+            # run an additional set of sanity checks
+            if seems_truly_unmounted "$1"; then
+                ignore_umount_error="yes"
+            else
+                echo "W: Tried ignoring error in unmount, but sanity check failed: $1 might still be mounted"
+            fi
+            ;;
+          *)
+            ;;
+        esac
+        if [ "$ignore_umount_error" != "yes" ]; then
+	    echo "W: Retrying to unmount $1 in 5s"
 	    sleep 5s
 	    while ! umount "$BUILDPLACE/$1"; do
 		sleep 5s
 		cat <<EOF
 
-  Could not unmount $1, there might be some program 
-  still using files in /proc (klogd?).
-  Please check and kill the process manually so that I can unmount $1
+  Could not unmount $1, some programs might
+  still be using files in /proc (klogd?).
+  Please check and kill these processes manually
+  so that I can unmount $1.  Last umount error was:
+$UMOUNT_OUTPUT
 
-  This error is only happens with chroot; try using user-mode-linux to 
-  avoid this message.
+  This error only affects chroots; you may want to use
+  user-mode-linux to avoid this message.
 
 EOF
 		chroot "$BUILDPLACE" bin/sh
 	    done
-	fi
+        else
+            echo "W: Ignored error in unmount"
+        fi
+    fi
 }
 
 function umountproc () {


More information about the Pbuilder-maint mailing list