[systemd-devel] [PATCH 1/6] systemd: try to use libmount fsinfo if available

Ian Kent ikent at redhat.com
Mon Jul 27 04:57:55 UTC 2020


From: Ian Kent <raven at themaw.net>

Try and use the new fsinfo() system call when loading the mount table
if possible.

Signed-off-by: Ian Kent <raven at themaw.net>
---
 src/core/mount.c           |    6 ++++--
 src/mount/mount-tool.c     |    4 +++-
 src/shared/libmount-util.h |   28 ++++++++++++++++++++++++++++
 src/shared/mount-util.c    |    4 +++-
 src/shutdown/umount.c      |   18 ++++++++++--------
 5 files changed, 48 insertions(+), 12 deletions(-)

diff --git a/src/core/mount.c b/src/core/mount.c
index 8b30a4db6a..299f2d56f6 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1726,7 +1726,9 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
 
         assert(m);
 
-        r = libmount_parse(NULL, NULL, &table, &iter);
+        r = libmount_parse_fsinfo(&table, &iter);
+        if (r < 0)
+                r = libmount_parse(NULL, NULL, &table, &iter);
         if (r < 0)
                 return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
 
@@ -1745,7 +1747,7 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
                 options = mnt_fs_get_options(fs);
                 fstype = mnt_fs_get_fstype(fs);
 
-                if (!device || !path)
+                if (!device || !path || !options || !fstype)
                         continue;
 
                 device_found_node(m, device, DEVICE_FOUND_MOUNT, DEVICE_FOUND_MOUNT);
diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c
index 13f8a37ddf..2762060fb7 100644
--- a/src/mount/mount-tool.c
+++ b/src/mount/mount-tool.c
@@ -730,7 +730,9 @@ static int find_mount_points(const char *what, char ***list) {
         /* Returns all mount points obtained from /proc/self/mountinfo in *list,
          * and the number of mount points as return value. */
 
-        r = libmount_parse(NULL, NULL, &table, &iter);
+        r = libmount_parse_fsinfo(&table, &iter);
+        if (r < 0)
+                r = libmount_parse(NULL, NULL, &table, &iter);
         if (r < 0)
                 return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
 
diff --git a/src/shared/libmount-util.h b/src/shared/libmount-util.h
index 7c3b855df5..e2d2383233 100644
--- a/src/shared/libmount-util.h
+++ b/src/shared/libmount-util.h
@@ -45,3 +45,31 @@ static inline int libmount_parse(
         *ret_iter = TAKE_PTR(iter);
         return 0;
 }
+
+static inline int libmount_parse_fsinfo(
+                struct libmnt_table **ret_table,
+                struct libmnt_iter **ret_iter) {
+
+        _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
+        _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
+        int r;
+
+        if (!mnt_has_fsinfo())
+                return -ENOSYS;
+
+        table = mnt_new_table();
+        iter = mnt_new_iter(MNT_ITER_FORWARD);
+        if (!table || !iter)
+                return -ENOMEM;
+
+        /* If source or path are specified, we use on the functions which ignore utab.
+         * Only if both are empty, we use mnt_table_parse_mtab(). */
+
+        r = mnt_table_parse_fsinfo(table);
+        if (r < 0)
+                return r;
+
+        *ret_table = TAKE_PTR(table);
+        *ret_iter = TAKE_PTR(iter);
+        return 0;
+}
diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c
index 45fdd3b2da..ceb4a68999 100644
--- a/src/shared/mount-util.c
+++ b/src/shared/mount-util.c
@@ -37,7 +37,9 @@ int umount_recursive(const char *prefix, int flags) {
 
                 again = false;
 
-                r = libmount_parse("/proc/self/mountinfo", NULL, &table, &iter);
+                r = libmount_parse_fsinfo(&table, &iter);
+                if (r < 0)
+                        r = libmount_parse("/proc/self/mountinfo", NULL, &table, &iter);
                 if (r < 0)
                         return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
 
diff --git a/src/shutdown/umount.c b/src/shutdown/umount.c
index 8a5e80eeaa..7cf2987607 100644
--- a/src/shutdown/umount.c
+++ b/src/shutdown/umount.c
@@ -60,13 +60,15 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) {
 
         assert(head);
 
-        r = libmount_parse(mountinfo, NULL, &table, &iter);
+        r = libmount_parse_fsinfo(&table, &iter);
+        if (r < 0)
+                r = libmount_parse(mountinfo, NULL, &table, &iter);
         if (r < 0)
                 return log_error_errno(r, "Failed to parse %s: %m", mountinfo ?: "/proc/self/mountinfo");
 
         for (;;) {
                 struct libmnt_fs *fs;
-                const char *path, *fstype;
+                const char *path, *fstype, *vfs_options, *fs_options;
                 _cleanup_free_ char *options = NULL;
                 unsigned long remount_flags = 0u;
                 _cleanup_free_ char *remount_options = NULL;
@@ -84,6 +86,10 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) {
                         continue;
 
                 fstype = mnt_fs_get_fstype(fs);
+                vfs_options = mnt_fs_get_vfs_options(fs);
+                fs_options = mnt_fs_get_fs_options(fs);
+                if (!fstype || !vfs_options || !fs_options)
+                        continue;
 
                 /* Combine the generic VFS options with the FS-specific
                  * options. Duplicates are not a problem here, because the only
@@ -93,13 +99,9 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) {
                  * Even if there are duplicates later in mount_option_mangle()
                  * they shouldn't hurt anyways as they override each other.
                  */
-                if (!strextend_with_separator(&options, ",",
-                                              mnt_fs_get_vfs_options(fs),
-                                              NULL))
+                if (!strextend_with_separator(&options, ",", vfs_options, NULL))
                         return log_oom();
-                if (!strextend_with_separator(&options, ",",
-                                              mnt_fs_get_fs_options(fs),
-                                              NULL))
+                if (!strextend_with_separator(&options, ",", fs_options, NULL))
                         return log_oom();
 
                 /* Ignore mount points we can't unmount because they




More information about the systemd-devel mailing list