]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
umount: support over-mounts for --recursive
authorKarel Zak <kzak@redhat.com>
Mon, 22 Mar 2021 10:29:28 +0000 (11:29 +0100)
committerKarel Zak <kzak@redhat.com>
Mon, 22 Mar 2021 10:29:28 +0000 (11:29 +0100)
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 <lennart@poettering.net>
Signed-off-by: Karel Zak <kzak@redhat.com>
sys-utils/umount.8
sys-utils/umount.c

index a7f6b12e03a5747ddbe8277ebbf9328de430e1fd..9f0c99777d81dd15ba9fae11db7d815eb673d8c2 100644 (file)
@@ -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.
index 2f4742d13d0b679e8ef49a3da8bad24b1b69ec7c..ec357d0dfe61b9bc8833c4c6f4259e4eaf62e961 100644 (file)
@@ -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;