diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-04-04 13:41:47 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-04-23 23:29:29 +0200 |
commit | 7d991d4818dcf55916c1076003c3508c91df9934 (patch) | |
tree | 7550d27b42d31dd7c9aaa35e91772352586dfbb1 /src/mount | |
parent | shared/mount-util: convert to libmount (diff) | |
download | systemd-7d991d4818dcf55916c1076003c3508c91df9934.tar.xz systemd-7d991d4818dcf55916c1076003c3508c91df9934.zip |
mount-tool: use libmount to parse /proc/self/mountinfo
Same motivation as in other places: let's use a single logic to parse this.
Use path_equal() to compare the path.
A bug in error handling is fixed: if we failed after the GREEDY_REALLOC but
before the line that sets the last item to NULL, we would jump to
_cleanup_strv_free_ with the strv unterminated. Let's use GREEDY_REALLOC0
to avoid the issue.
Diffstat (limited to 'src/mount')
-rw-r--r-- | src/mount/mount-tool.c | 63 |
1 files changed, 29 insertions, 34 deletions
diff --git a/src/mount/mount-tool.c b/src/mount/mount-tool.c index b290095b0e..fc18dd28d7 100644 --- a/src/mount/mount-tool.c +++ b/src/mount/mount-tool.c @@ -17,6 +17,7 @@ #include "format-util.h" #include "fs-util.h" #include "fstab-util.h" +#include "libmount-util.h" #include "main-func.h" #include "mount-util.h" #include "mountpoint-util.h" @@ -713,9 +714,11 @@ static int start_transient_automount( } static int find_mount_points(const char *what, char ***list) { - _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; _cleanup_strv_free_ char **l = NULL; size_t bufsize = 0, n = 0; + int r; assert(what); assert(list); @@ -723,55 +726,47 @@ 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. */ - proc_self_mountinfo = fopen("/proc/self/mountinfo", "re"); - if (!proc_self_mountinfo) - return log_error_errno(errno, "Can't open /proc/self/mountinfo: %m"); + table = mnt_new_table(); + iter = mnt_new_iter(MNT_ITER_FORWARD); + if (!table || !iter) + return log_oom(); - for (;;) { - _cleanup_free_ char *path = NULL, *where = NULL, *dev = NULL; - int r; + r = mnt_table_parse_mtab(table, NULL); + if (r < 0) + return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m"); - r = 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 */ - "%ms" /* (10) mount source */ - "%*s" /* (11) mount options 2 */ - "%*[^\n]", /* some rubbish at the end */ - &path, &dev); - if (r != 2) { - if (r == EOF) - break; + for (;;) { + struct libmnt_fs *fs; + const char *source, *target; - continue; - } + r = mnt_table_next_fs(table, iter, &fs); + if (r == 1) + break; + if (r < 0) + return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); - if (!streq(what, dev)) + source = mnt_fs_get_source(fs); + target = mnt_fs_get_target(fs); + if (!source || !target) continue; - r = cunescape(path, UNESCAPE_RELAX, &where); - if (r < 0) + if (!path_equal(source, what)) continue; /* one extra slot is needed for the terminating NULL */ - if (!GREEDY_REALLOC(l, bufsize, n + 2)) + if (!GREEDY_REALLOC0(l, bufsize, n + 2)) return log_oom(); - l[n++] = TAKE_PTR(where); + l[n] = strdup(target); + if (!l[n]) + return log_oom(); + n++; } - if (!GREEDY_REALLOC(l, bufsize, n + 1)) + if (!GREEDY_REALLOC0(l, bufsize, n + 1)) return log_oom(); - l[n] = NULL; *list = TAKE_PTR(l); - return n; } |