summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-04-05 14:43:06 +0200
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>2019-04-23 23:29:29 +0200
commite2857b3d87306d93f0fba526f3e79f4f6806fb02 (patch)
tree80e0b279f908dec754abb1ee8fe497d087839026
parent7d991d4818dcf55916c1076003c3508c91df9934 (diff)
downloadsystemd-e2857b3d87306d93f0fba526f3e79f4f6806fb02.tar.gz
Add helper function for mnt_table_parse_{stream,mtab}
This wraps a few common steps. It is defined as inline function instead of in a .c file to avoid having a .c file. With a .c file, we would have three choices: - either link it into libshared, but then then libshared would have to be linked to libmount. - or compile the .c file into each target separately. This has the disdvantage that configuration of every target has to be updated and stuff will be compiled multiple times anyway, which is not too different from keeping this in the header file. - or create a new convenience library just for this. This also has the disadvantage that the every target would have to be updated, and a separate library for a 10 line function seems overkill. By keeping everything in a header file, we compile this a few times, but otherwise it's the least painful option. The compiler can optimize most of the function away, because it knows if 'source' is set or not.
-rw-r--r--src/core/mount.c7
-rw-r--r--src/mount/mount-tool.c7
-rw-r--r--src/shared/libmount-util.h32
-rw-r--r--src/shared/mount-util.c14
-rw-r--r--src/shutdown/umount.c7
-rw-r--r--src/test/test-libmount.c5
6 files changed, 38 insertions, 34 deletions
diff --git a/src/core/mount.c b/src/core/mount.c
index bb42955e84..e32db2bf63 100644
--- a/src/core/mount.c
+++ b/src/core/mount.c
@@ -1603,12 +1603,7 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
assert(m);
- table = mnt_new_table();
- iter = mnt_new_iter(MNT_ITER_FORWARD);
- if (!table || !iter)
- return log_oom();
-
- r = mnt_table_parse_mtab(table, NULL);
+ 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/mount/mount-tool.c b/src/mount/mount-tool.c
index fc18dd28d7..739f52c219 100644
--- a/src/mount/mount-tool.c
+++ b/src/mount/mount-tool.c
@@ -726,12 +726,7 @@ 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. */
- table = mnt_new_table();
- iter = mnt_new_iter(MNT_ITER_FORWARD);
- if (!table || !iter)
- return log_oom();
-
- r = mnt_table_parse_mtab(table, NULL);
+ 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 7d94468e52..6e8e61ed6c 100644
--- a/src/shared/libmount-util.h
+++ b/src/shared/libmount-util.h
@@ -1,6 +1,8 @@
/* SPDX-License-Identifier: LGPL-2.1+ */
#pragma once
+#include <stdio.h>
+
/* This needs to be after sys/mount.h */
#include <libmount.h>
@@ -8,3 +10,33 @@
DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_table*, mnt_free_table);
DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_iter*, mnt_free_iter);
+
+static inline int libmount_parse(
+ const char *path,
+ FILE *source,
+ 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;
+
+ /* Older libmount seems to require this. */
+ assert(!source || path);
+
+ table = mnt_new_table();
+ iter = mnt_new_iter(MNT_ITER_FORWARD);
+ if (!table || !iter)
+ return -ENOMEM;
+
+ if (source)
+ r = mnt_table_parse_stream(table, source, path);
+ else
+ r = mnt_table_parse_mtab(table, path);
+ 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 056106488d..97cc7b44c5 100644
--- a/src/shared/mount-util.c
+++ b/src/shared/mount-util.c
@@ -38,12 +38,7 @@ int umount_recursive(const char *prefix, int flags) {
again = false;
- table = mnt_new_table();
- iter = mnt_new_iter(MNT_ITER_FORWARD);
- if (!table || !iter)
- return -ENOMEM;
-
- r = mnt_table_parse_mtab(table, NULL);
+ r = libmount_parse(NULL, NULL, &table, &iter);
if (r < 0)
return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
@@ -139,14 +134,9 @@ 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);
- r = mnt_table_parse_stream(table, proc_self_mountinfo, "/proc/self/mountinfo");
+ r = libmount_parse("/proc/self/mountinfo", proc_self_mountinfo, &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 ea9fba8831..5b1160833b 100644
--- a/src/shutdown/umount.c
+++ b/src/shutdown/umount.c
@@ -61,12 +61,7 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) {
assert(head);
- table = mnt_new_table();
- iter = mnt_new_iter(MNT_ITER_FORWARD);
- if (!table || !iter)
- return log_oom();
-
- r = mnt_table_parse_mtab(table, mountinfo);
+ r = libmount_parse(mountinfo, NULL, &table, &iter);
if (r < 0)
return log_error_errno(r, "Failed to parse %s: %m", mountinfo);
diff --git a/src/test/test-libmount.c b/src/test/test-libmount.c
index fc28f27d53..c3395493d4 100644
--- a/src/test/test-libmount.c
+++ b/src/test/test-libmount.c
@@ -21,13 +21,10 @@ static void test_libmount_unescaping_one(
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
_cleanup_fclose_ FILE *f = NULL;
- assert_se(table = mnt_new_table());
- assert_se(iter = mnt_new_iter(MNT_ITER_FORWARD));
-
f = fmemopen((char*) string, strlen(string), "re");
assert_se(f);
- assert_se(mnt_table_parse_stream(table, f, title) >= 0);
+ assert_se(libmount_parse(title, f, &table, &iter) >= 0);
struct libmnt_fs *fs;
const char *source, *target;