shared/mount-util: convert to libmount
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Thu, 4 Apr 2019 11:36:19 +0000 (13:36 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Tue, 23 Apr 2019 21:29:29 +0000 (23:29 +0200)
It seems better to use just a single parsing algorithm for /proc/self/mountinfo.

Also, unify the naming of variables in all places that use mnt_table_next_fs().
It makes it easier to compare the different call sites.

src/core/mount.c
src/shared/mount-util.c
src/shutdown/umount.c

index b7fd35f..bb42955 100644 (file)
@@ -1597,31 +1597,30 @@ static int mount_setup_unit(
 }
 
 static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
-        _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
-        _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
+        _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
+        _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
         int r;
 
         assert(m);
 
-        t = mnt_new_table();
-        i = mnt_new_iter(MNT_ITER_FORWARD);
-        if (!t || !i)
+        table = mnt_new_table();
+        iter = mnt_new_iter(MNT_ITER_FORWARD);
+        if (!table || !iter)
                 return log_oom();
 
-        r = mnt_table_parse_mtab(t, NULL);
+        r = mnt_table_parse_mtab(table, NULL);
         if (r < 0)
                 return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
 
         for (;;) {
                 struct libmnt_fs *fs;
                 const char *device, *path, *options, *fstype;
-                int k;
 
-                k = mnt_table_next_fs(t, i, &fs);
-                if (k == 1)
+                r = mnt_table_next_fs(table, iter, &fs);
+                if (r == 1)
                         break;
-                if (k < 0)
-                        return log_error_errno(k, "Failed to get next entry from /proc/self/mountinfo: %m");
+                if (r < 0)
+                        return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
 
                 device = mnt_fs_get_source(fs);
                 path = mnt_fs_get_target(fs);
index 680c452..0561064 100644 (file)
@@ -8,16 +8,13 @@
 #include <sys/statvfs.h>
 #include <unistd.h>
 
-/* Include later */
-#include <libmount.h>
-
 #include "alloc-util.h"
-#include "escape.h"
 #include "extract-word.h"
 #include "fd-util.h"
 #include "fileio.h"
 #include "fs-util.h"
 #include "hashmap.h"
+#include "libmount-util.h"
 #include "mount-util.h"
 #include "mountpoint-util.h"
 #include "parse-util.h"
@@ -36,52 +33,43 @@ int umount_recursive(const char *prefix, int flags) {
          * unmounting them until they are gone. */
 
         do {
-                _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
+                _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
+                _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
 
                 again = false;
 
-                r = fopen_unlocked("/proc/self/mountinfo", "re", &proc_self_mountinfo);
+                table = mnt_new_table();
+                iter = mnt_new_iter(MNT_ITER_FORWARD);
+                if (!table || !iter)
+                        return -ENOMEM;
+
+                r = mnt_table_parse_mtab(table, NULL);
                 if (r < 0)
-                        return r;
+                        return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
 
                 for (;;) {
-                        _cleanup_free_ char *path = NULL, *p = NULL;
-                        int k;
-
-                        k = fscanf(proc_self_mountinfo,
-                                   "%*s "       /* (1) mount id */
-                                   "%*s "       /* (2) parent id */
-                                   "%*s "       /* (3) major:minor */
-                                   "%*s "       /* (4) root */
-                                   "%ms "       /* (5) mount point */
-                                   "%*s"        /* (6) mount options */
-                                   "%*[^-]"     /* (7) optional fields */
-                                   "- "         /* (8) separator */
-                                   "%*s "       /* (9) file system type */
-                                   "%*s"        /* (10) mount source */
-                                   "%*s"        /* (11) mount options 2 */
-                                   "%*[^\n]",   /* some rubbish at the end */
-                                   &path);
-                        if (k != 1) {
-                                if (k == EOF)
-                                        break;
+                        struct libmnt_fs *fs;
+                        const char *path;
 
-                                continue;
-                        }
+                        r = mnt_table_next_fs(table, iter, &fs);
+                        if (r == 1)
+                                break;
+                        if (r < 0)
+                                return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
 
-                        k = cunescape(path, UNESCAPE_RELAX, &p);
-                        if (k < 0)
-                                return k;
+                        path = mnt_fs_get_target(fs);
+                        if (!path)
+                                continue;
 
-                        if (!path_startswith(p, prefix))
+                        if (!path_startswith(path, prefix))
                                 continue;
 
-                        if (umount2(p, flags) < 0) {
-                                r = log_debug_errno(errno, "Failed to umount %s: %m", p);
+                        if (umount2(path, flags) < 0) {
+                                r = log_debug_errno(errno, "Failed to umount %s: %m", path);
                                 continue;
                         }
 
-                        log_debug("Successfully unmounted %s", p);
+                        log_debug("Successfully unmounted %s", path);
 
                         again = true;
                         n++;
@@ -91,7 +79,7 @@ int umount_recursive(const char *prefix, int flags) {
 
         } while (again);
 
-        return r < 0 ? r : n;
+        return n;
 }
 
 static int get_mount_flags(const char *path, unsigned long *flags) {
@@ -141,6 +129,8 @@ int bind_remount_recursive_with_mountinfo(
 
         for (;;) {
                 _cleanup_set_free_free_ Set *todo = NULL;
+                _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
+                _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
                 bool top_autofs = false;
                 char *x;
                 unsigned long orig_flags;
@@ -149,58 +139,52 @@ int bind_remount_recursive_with_mountinfo(
                 if (!todo)
                         return -ENOMEM;
 
+                table = mnt_new_table();
+                iter = mnt_new_iter(MNT_ITER_FORWARD);
+                if (!table || !iter)
+                        return -ENOMEM;
+
                 rewind(proc_self_mountinfo);
 
-                for (;;) {
-                        _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
-                        int k;
-
-                        k = fscanf(proc_self_mountinfo,
-                                   "%*s "       /* (1) mount id */
-                                   "%*s "       /* (2) parent id */
-                                   "%*s "       /* (3) major:minor */
-                                   "%*s "       /* (4) root */
-                                   "%ms "       /* (5) mount point */
-                                   "%*s"        /* (6) mount options (superblock) */
-                                   "%*[^-]"     /* (7) optional fields */
-                                   "- "         /* (8) separator */
-                                   "%ms "       /* (9) file system type */
-                                   "%*s"        /* (10) mount source */
-                                   "%*s"        /* (11) mount options (bind mount) */
-                                   "%*[^\n]",   /* some rubbish at the end */
-                                   &path,
-                                   &type);
-                        if (k != 2) {
-                                if (k == EOF)
-                                        break;
+                r = mnt_table_parse_stream(table, proc_self_mountinfo, "/proc/self/mountinfo");
+                if (r < 0)
+                        return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
 
-                                continue;
-                        }
+                for (;;) {
+                        struct libmnt_fs *fs;
+                        const char *path, *type;
 
-                        r = cunescape(path, UNESCAPE_RELAX, &p);
+                        r = mnt_table_next_fs(table, iter, &fs);
+                        if (r == 1)
+                                break;
                         if (r < 0)
-                                return r;
+                                return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
+
+                        path = mnt_fs_get_target(fs);
+                        type = mnt_fs_get_fstype(fs);
+                        if (!path || !type)
+                                continue;
 
-                        if (!path_startswith(p, cleaned))
+                        if (!path_startswith(path, cleaned))
                                 continue;
 
-                        /* Ignore this mount if it is blacklisted, but only if it isn't the top-level mount we shall
-                         * operate on. */
-                        if (!path_equal(cleaned, p)) {
+                        /* Ignore this mount if it is blacklisted, but only if it isn't the top-level mount
+                         * we shall operate on. */
+                        if (!path_equal(path, cleaned)) {
                                 bool blacklisted = false;
                                 char **i;
 
                                 STRV_FOREACH(i, blacklist) {
-
                                         if (path_equal(*i, cleaned))
                                                 continue;
 
                                         if (!path_startswith(*i, cleaned))
                                                 continue;
 
-                                        if (path_startswith(p, *i)) {
+                                        if (path_startswith(path, *i)) {
                                                 blacklisted = true;
-                                                log_debug("Not remounting %s blacklisted by %s, called for %s", p, *i, cleaned);
+                                                log_debug("Not remounting %s blacklisted by %s, called for %s",
+                                                          path, *i, cleaned);
                                                 break;
                                         }
                                 }
@@ -215,15 +199,12 @@ int bind_remount_recursive_with_mountinfo(
                          * already triggered, then we will find
                          * another entry for this. */
                         if (streq(type, "autofs")) {
-                                top_autofs = top_autofs || path_equal(cleaned, p);
+                                top_autofs = top_autofs || path_equal(path, cleaned);
                                 continue;
                         }
 
-                        if (!set_contains(done, p)) {
-                                r = set_consume(todo, p);
-                                p = NULL;
-                                if (r == -EEXIST)
-                                        continue;
+                        if (!set_contains(done, path)) {
+                                r = set_put_strdup(todo, path);
                                 if (r < 0)
                                         return r;
                         }
index 6afa512..ea9fba8 100644 (file)
@@ -55,18 +55,18 @@ void mount_points_list_free(MountPoint **head) {
 }
 
 int mount_points_list_get(const char *mountinfo, MountPoint **head) {
-        _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
-        _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
+        _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
+        _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
         int r;
 
         assert(head);
 
-        t = mnt_new_table();
-        i = mnt_new_iter(MNT_ITER_FORWARD);
-        if (!t || !i)
+        table = mnt_new_table();
+        iter = mnt_new_iter(MNT_ITER_FORWARD);
+        if (!table || !iter)
                 return log_oom();
 
-        r = mnt_table_parse_mtab(t, mountinfo);
+        r = mnt_table_parse_mtab(table, mountinfo);
         if (r < 0)
                 return log_error_errno(r, "Failed to parse %s: %m", mountinfo);
 
@@ -79,7 +79,7 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) {
                 bool try_remount_ro;
                 _cleanup_free_ MountPoint *m = NULL;
 
-                r = mnt_table_next_fs(t, i, &fs);
+                r = mnt_table_next_fs(table, iter, &fs);
                 if (r == 1)
                         break;
                 if (r < 0)