From: Karel Zak Date: Mon, 22 Mar 2021 10:29:28 +0000 (+0100) Subject: umount: support over-mounts for --recursive X-Git-Tag: v2.37-rc1~52 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=e2f6c9eaa2deb019ba2a9dad495881b20e797f91;p=thirdparty%2Futil-linux.git umount: support over-mounts for --recursive For example for hierarchy: $ findmnt -oTARGET,ID,PARENT TARGET ID PARENT /mnt/A 802 62 └─/mnt/A/B 937 802 ├─/mnt/A/B/C 964 937 │ └─/mnt/A/B/C 991 964 └─/mnt/A/B 1018 937 └─/mnt/A/B 1045 1018 we need umount in order (id): 1045, 1018, 991, 964, 937, 802. The current code first tries 991 in 937 branch. Reported-by: Lennart Poettering Signed-off-by: Karel Zak --- diff --git a/sys-utils/umount.8 b/sys-utils/umount.8 index a7f6b12e03..9f0c99777d 100644 --- a/sys-utils/umount.8 +++ b/sys-utils/umount.8 @@ -181,7 +181,8 @@ between mountpoints is determined by .I /proc/self/mountinfo entries. The filesystem must be specified by mountpoint path; a recursive unmount by device name (or UUID) -is unsupported. +is unsupported. Since version 2.37 it umounts also all over-mounted filesystems +(more filesystems on the same mountpoint). .TP .BR \-r , " \-\-read\-only" When an unmount fails, try to remount the filesystem read-only. diff --git a/sys-utils/umount.c b/sys-utils/umount.c index 2f4742d13d..ec357d0dfe 100644 --- a/sys-utils/umount.c +++ b/sys-utils/umount.c @@ -299,13 +299,20 @@ static int umount_one_if_mounted(struct libmnt_context *cxt, const char *spec) static int umount_do_recurse(struct libmnt_context *cxt, struct libmnt_table *tb, struct libmnt_fs *fs) { - struct libmnt_fs *child; + struct libmnt_fs *child, *over = NULL; struct libmnt_iter *itr = mnt_new_iter(MNT_ITER_BACKWARD); int rc; if (!itr) err(MNT_EX_SYSERR, _("libmount iterator allocation failed")); + /* first try overmount */ + if (mnt_table_over_fs(tb, fs, &over) == 0 && over) { + rc = umount_do_recurse(cxt, tb, over); + if (rc != MNT_EX_SUCCESS) + goto done; + } + /* umount all children */ for (;;) { rc = mnt_table_next_child_fs(tb, itr, fs, &child); @@ -317,6 +324,9 @@ static int umount_do_recurse(struct libmnt_context *cxt, } else if (rc == 1) break; /* no more children */ + if (over && child == over) + continue; + rc = umount_do_recurse(cxt, tb, child); if (rc != MNT_EX_SUCCESS) goto done;