This introduces libmount_parse_mountinfo() and libmount_parse_with_utab().
The former one parses only mountinfo, but the latter one also parse
utab. Hopefully this avoids pitfalls like issue #35949.
assert(m);
- r = libmount_parse(NULL, NULL, &table, &iter);
+ r = libmount_parse_with_utab(&table, &iter);
if (r < 0)
return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
/* 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_mountinfo(/* source = */ NULL, &table, &iter);
if (r < 0)
return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
#include "libmount-util.h"
-int libmount_parse(
+int libmount_parse_full(
const char *path,
FILE *source,
struct libmnt_table **ret_table,
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct libmnt_table*, mnt_free_table, NULL);
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct libmnt_iter*, mnt_free_iter, NULL);
-int libmount_parse(
+int libmount_parse_full(
const char *path,
FILE *source,
struct libmnt_table **ret_table,
struct libmnt_iter **ret_iter);
+static inline int libmount_parse_mountinfo(
+ FILE *source,
+ struct libmnt_table **ret_table,
+ struct libmnt_iter **ret_iter) {
+
+ return libmount_parse_full("/proc/self/mountinfo", source, ret_table, ret_iter);
+}
+
+static inline int libmount_parse_with_utab(
+ struct libmnt_table **ret_table,
+ struct libmnt_iter **ret_iter) {
+
+ return libmount_parse_full(NULL, NULL, ret_table, ret_iter);
+}
+
int libmount_is_leaf(
struct libmnt_table *table,
struct libmnt_fs *fs);
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
bool again = false;
- r = libmount_parse("/proc/self/mountinfo", f, &table, &iter);
+ r = libmount_parse_mountinfo(f, &table, &iter);
if (r < 0)
return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
rewind(proc_self_mountinfo);
- r = libmount_parse("/proc/self/mountinfo", proc_self_mountinfo, &table, &iter);
+ r = libmount_parse_mountinfo(proc_self_mountinfo, &table, &iter);
if (r < 0)
return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
assert(ret_mounts);
assert(ret_n_mounts);
- r = libmount_parse("/proc/self/mountinfo", NULL, &table, &iter);
+ r = libmount_parse_mountinfo(/* source = */ NULL, &table, &iter);
if (r < 0)
return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
if (r < 0)
return log_debug_errno(r, "Failed to get mount ID: %m");
- /* When getting options is requested, do not pass filename, otherwise utab will not read, and
- * userspace options like "_netdev" will be lost. */
- r = libmount_parse(ret_options ? NULL : "/proc/self/mountinfo", /* source = */ NULL, &table, &iter);
+ /* When getting options is requested, we also need to parse utab, otherwise userspace options like
+ * "_netdev" will be lost. */
+ if (ret_options)
+ r = libmount_parse_with_utab(&table, &iter);
+ else
+ r = libmount_parse_mountinfo(/* source = */ NULL, &table, &iter);
if (r < 0)
return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
#include "alloc-util.h"
#include "detach-swap.h"
#include "errno-util.h"
+#include "fd-util.h"
#include "log.h"
#include "path-util.h"
#include "string-util.h"
static void test_mount_points_list_one(const char *fname) {
_cleanup_(mount_points_list_free) LIST_HEAD(MountPoint, mp_list_head);
- _cleanup_free_ char *testdata_fname = NULL;
+ _cleanup_fclose_ FILE *f = NULL;
log_info("/* %s(\"%s\") */", __func__, fname ?: "/proc/self/mountinfo");
if (fname) {
+ _cleanup_free_ char *testdata_fname = NULL;
assert_se(get_testdata_dir(fname, &testdata_fname) >= 0);
- fname = testdata_fname;
+ ASSERT_NOT_NULL(f = fopen(testdata_fname, "re"));
}
LIST_HEAD_INIT(mp_list_head);
- assert_se(mount_points_list_get(fname, &mp_list_head) >= 0);
+ assert_se(mount_points_list_get(f, &mp_list_head) >= 0);
LIST_FOREACH(mount_point, m, mp_list_head)
log_debug("path=%s o=%s f=0x%lx try-ro=%s",
mount_point_free(head, *head);
}
-int mount_points_list_get(const char *mountinfo, MountPoint **head) {
+int mount_points_list_get(FILE *f, MountPoint **head) {
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
int r;
assert(head);
- r = libmount_parse(mountinfo, NULL, &table, &iter);
+ r = libmount_parse_mountinfo(f, &table, &iter);
if (r < 0)
- return log_error_errno(r, "Failed to parse %s: %m", mountinfo ?: "/proc/self/mountinfo");
+ return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
for (;;) {
_cleanup_free_ char *options = NULL, *remount_options = NULL;
if (r == 1) /* EOF */
break;
if (r < 0)
- return log_error_errno(r, "Failed to get next entry from %s: %m", mountinfo ?: "/proc/self/mountinfo");
+ return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
path = mnt_fs_get_target(fs);
if (!path)
r = libmount_is_leaf(table, fs);
if (r < 0)
- return log_error_errno(r, "Failed to get children mounts for %s from %s: %m", path, mountinfo ?: "/proc/self/mountinfo");
+ return log_error_errno(r, "Failed to get children mounts for %s from /proc/self/mountinfo: %m", path);
bool leaf = r;
*m = (MountPoint) {
***/
#include <stdbool.h>
+#include <stdio.h>
#include "list.h"
LIST_FIELDS(struct MountPoint, mount_point);
} MountPoint;
-int mount_points_list_get(const char *mountinfo, MountPoint **head);
+int mount_points_list_get(FILE *f, MountPoint **head);
void mount_points_list_free(MountPoint **head);
f = fmemopen((char*) string, strlen(string), "r");
assert_se(f);
- assert_se(libmount_parse(title, f, &table, &iter) >= 0);
+ assert_se(libmount_parse_mountinfo(f, &table, &iter) >= 0);
struct libmnt_fs *fs;
const char *source, *target;
assert_se(umount_recursive_full(t->prefix, MNT_DETACH, (char**) t->keep) >= 0);
- r = libmount_parse("/proc/self/mountinfo", f, &table, &iter);
+ r = libmount_parse_mountinfo(f, &table, &iter);
if (r < 0) {
log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
_exit(EXIT_FAILURE);