]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
mount-util: keep fd to /proc/self/mountinfo continously open in umount_recursive()
authorLennart Poettering <lennart@poettering.net>
Tue, 16 May 2023 13:52:33 +0000 (15:52 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 17 May 2023 08:26:51 +0000 (10:26 +0200)
That way, if we end up unmounting /proc/ in our loop we can still
operate correctly, since we don't have to go through /proc/ again to
open the mount table again.

src/shared/mount-util.c

index b41672eb922ad595eece9857304e6d129d891a57..b7f3616a1dbbc5dfa8f7dff33090b3052631ae00 100644 (file)
 #include "user-util.h"
 
 int umount_recursive(const char *prefix, int flags) {
+        _cleanup_fclose_ FILE *f = NULL;
         int n = 0, r;
-        bool again;
 
         /* Try to umount everything recursively below a directory. Also, take care of stacked mounts, and
          * keep unmounting them until they are gone. */
 
-        do {
+        f = fopen("/proc/self/mountinfo", "re"); /* Pin the file, in case we unmount /proc/ as part of the logic here */
+        if (!f)
+                return log_debug_errno(errno, "Failed to open /proc/self/mountinfo: %m");
+
+        for (;;) {
                 _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
                 _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
+                bool again = false;
 
-                again = false;
-
-                r = libmount_parse("/proc/self/mountinfo", NULL, &table, &iter);
+                r = libmount_parse("/proc/self/mountinfo", f, &table, &iter);
                 if (r < 0)
                         return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
 
@@ -89,7 +92,12 @@ int umount_recursive(const char *prefix, int flags) {
 
                         break;
                 }
-        } while (again);
+
+                if (!again)
+                        break;
+
+                rewind(f);
+        }
 
         return n;
 }