]> git.ipfire.org Git - thirdparty/lxc.git/commitdiff
use lazy umount when umount returns EBUSY
authorDaniel Lezcano <daniel.lezcano@free.fr>
Wed, 24 Feb 2010 09:57:43 +0000 (10:57 +0100)
committerDaniel Lezcano <dlezcano@fr.ibm.com>
Wed, 24 Feb 2010 09:57:43 +0000 (10:57 +0100)
When the umount fails, we force the umount and make the mount point
unaccessible by using a lazy umount.

Signed-off-by: Daniel Lezcano <dlezcano@fr.ibm.com>
src/lxc/conf.c

index d84e22f9db88901453e54ed97f3efcf4bade716e..5960a4c41ae06e9b9fcf40a41af5dc9b7c97abdb 100644 (file)
@@ -67,6 +67,10 @@ lxc_log_define(lxc_conf, lxc);
 #define MS_REC 16384
 #endif
 
+#ifndef MNT_DETACH
+#define MNT_DETACH 2
+#endif
+
 #ifndef CAP_SETFCAP
 #define CAP_SETFCAP 31
 #endif
@@ -532,6 +536,7 @@ static int setup_rootfs_pivot_root(const char *rootfs, const char *pivotdir)
 
                lxc_list_for_each(iterator, &mountlist) {
 
+                       /* umount normally */
                        if (!umount(iterator->elem)) {
                                DEBUG("umounted '%s'", (char *)iterator->elem);
                                lxc_list_del(iterator);
@@ -544,24 +549,38 @@ static int setup_rootfs_pivot_root(const char *rootfs, const char *pivotdir)
        } while (still_mounted > 0 && still_mounted != last_still_mounted);
 
 
-       lxc_list_for_each(iterator, &mountlist)
+       lxc_list_for_each(iterator, &mountlist) {
+
+               /* let's try a lazy umount */
+               if (!umount2(iterator->elem, MNT_DETACH)) {
+                       INFO("lazy unmount of '%s'", (char *)iterator->elem);
+                       continue;
+               }
+
+               /* be more brutal (nfs) */
+               if (!umount2(iterator->elem, MNT_FORCE)) {
+                       INFO("forced unmount of '%s'", (char *)iterator->elem);
+                       continue;
+               }
+
                WARN("failed to unmount '%s'", (char *)iterator->elem);
+       }
 
-       /* umount old root fs */
-       if (umount(pivotdir)) {
+       /* umount old root fs; if some other mount points are still
+        * there, we won't be able to umount it, so we have to do
+        * that in a lazy way otherwise the container will always
+        * fail to start
+        */
+       if (umount2(pivotdir, MNT_DETACH)) {
                SYSERROR("could not unmount old rootfs");
                return -1;
        }
        DEBUG("umounted '%s'", pivotdir);
 
-       /* remove temporary mount point */
-       if (pivotdir_is_temp) {
-               if (rmdir(pivotdir)) {
-                       SYSERROR("can't remove temporary mountpoint");
-                       return -1;
-               }
-
-       }
+       /* remove temporary mount point, we don't consider the removing
+        * as fatal */
+       if (pivotdir_is_temp && rmdir(pivotdir))
+               WARN("can't remove temporary mountpoint: %m");
 
        INFO("pivoted to '%s'", rootfs);
        return 0;