use lazy umount when umount returns EBUSY

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>
This commit is contained in:
Daniel Lezcano 2010-02-24 10:57:43 +01:00 committed by Daniel Lezcano
parent 1560f6c9a7
commit c08556c6ec

View File

@ -67,6 +67,10 @@ lxc_log_define(lxc_conf, lxc);
#define MS_REC 16384 #define MS_REC 16384
#endif #endif
#ifndef MNT_DETACH
#define MNT_DETACH 2
#endif
#ifndef CAP_SETFCAP #ifndef CAP_SETFCAP
#define CAP_SETFCAP 31 #define CAP_SETFCAP 31
#endif #endif
@ -532,6 +536,7 @@ static int setup_rootfs_pivot_root(const char *rootfs, const char *pivotdir)
lxc_list_for_each(iterator, &mountlist) { lxc_list_for_each(iterator, &mountlist) {
/* umount normally */
if (!umount(iterator->elem)) { if (!umount(iterator->elem)) {
DEBUG("umounted '%s'", (char *)iterator->elem); DEBUG("umounted '%s'", (char *)iterator->elem);
lxc_list_del(iterator); 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); } while (still_mounted > 0 && still_mounted != last_still_mounted);
lxc_list_for_each(iterator, &mountlist) lxc_list_for_each(iterator, &mountlist) {
WARN("failed to unmount '%s'", (char *)iterator->elem);
/* umount old root fs */ /* let's try a lazy umount */
if (umount(pivotdir)) { 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 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"); SYSERROR("could not unmount old rootfs");
return -1; return -1;
} }
DEBUG("umounted '%s'", pivotdir); DEBUG("umounted '%s'", pivotdir);
/* remove temporary mount point */ /* remove temporary mount point, we don't consider the removing
if (pivotdir_is_temp) { * as fatal */
if (rmdir(pivotdir)) { if (pivotdir_is_temp && rmdir(pivotdir))
SYSERROR("can't remove temporary mountpoint"); WARN("can't remove temporary mountpoint: %m");
return -1;
}
}
INFO("pivoted to '%s'", rootfs); INFO("pivoted to '%s'", rootfs);
return 0; return 0;