[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