diff options
author | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-04-04 13:36:19 +0200 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2019-04-23 23:29:29 +0200 |
commit | 13dcfe4661b467131c943620d0f44711798bfd54 (patch) | |
tree | 848fe89e5ec5b230c81f7197ddac2d36c46161c8 | |
parent | f5f899ef044e4b159e723b273ff35fda935f6427 (diff) | |
download | systemd-13dcfe4661b467131c943620d0f44711798bfd54.tar.gz systemd-13dcfe4661b467131c943620d0f44711798bfd54.tar.bz2 systemd-13dcfe4661b467131c943620d0f44711798bfd54.zip |
shared/mount-util: convert to libmount
It seems better to use just a single parsing algorithm for /proc/self/mountinfo.
Also, unify the naming of variables in all places that use mnt_table_next_fs().
It makes it easier to compare the different call sites.
-rw-r--r-- | src/core/mount.c | 21 | ||||
-rw-r--r-- | src/shared/mount-util.c | 133 | ||||
-rw-r--r-- | src/shutdown/umount.c | 14 |
3 files changed, 74 insertions, 94 deletions
diff --git a/src/core/mount.c b/src/core/mount.c index b7fd35fc67..bb42955e84 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -1597,31 +1597,30 @@ static int mount_setup_unit( } static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) { - _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL; - _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL; + _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; + _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; int r; assert(m); - t = mnt_new_table(); - i = mnt_new_iter(MNT_ITER_FORWARD); - if (!t || !i) + table = mnt_new_table(); + iter = mnt_new_iter(MNT_ITER_FORWARD); + if (!table || !iter) return log_oom(); - r = mnt_table_parse_mtab(t, NULL); + r = mnt_table_parse_mtab(table, NULL); if (r < 0) return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m"); for (;;) { struct libmnt_fs *fs; const char *device, *path, *options, *fstype; - int k; - k = mnt_table_next_fs(t, i, &fs); - if (k == 1) + r = mnt_table_next_fs(table, iter, &fs); + if (r == 1) break; - if (k < 0) - return log_error_errno(k, "Failed to get next entry from /proc/self/mountinfo: %m"); + if (r < 0) + return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); device = mnt_fs_get_source(fs); path = mnt_fs_get_target(fs); diff --git a/src/shared/mount-util.c b/src/shared/mount-util.c index 680c4522ad..056106488d 100644 --- a/src/shared/mount-util.c +++ b/src/shared/mount-util.c @@ -8,16 +8,13 @@ #include <sys/statvfs.h> #include <unistd.h> -/* Include later */ -#include <libmount.h> - #include "alloc-util.h" -#include "escape.h" #include "extract-word.h" #include "fd-util.h" #include "fileio.h" #include "fs-util.h" #include "hashmap.h" +#include "libmount-util.h" #include "mount-util.h" #include "mountpoint-util.h" #include "parse-util.h" @@ -36,52 +33,43 @@ int umount_recursive(const char *prefix, int flags) { * unmounting them until they are gone. */ do { - _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; again = false; - r = fopen_unlocked("/proc/self/mountinfo", "re", &proc_self_mountinfo); + table = mnt_new_table(); + iter = mnt_new_iter(MNT_ITER_FORWARD); + if (!table || !iter) + return -ENOMEM; + + r = mnt_table_parse_mtab(table, NULL); if (r < 0) - return r; + return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m"); for (;;) { - _cleanup_free_ char *path = NULL, *p = NULL; - int k; - - k = 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 */ - "%*s" /* (10) mount source */ - "%*s" /* (11) mount options 2 */ - "%*[^\n]", /* some rubbish at the end */ - &path); - if (k != 1) { - if (k == EOF) - break; + struct libmnt_fs *fs; + const char *path; - continue; - } + r = mnt_table_next_fs(table, iter, &fs); + if (r == 1) + break; + if (r < 0) + return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); - k = cunescape(path, UNESCAPE_RELAX, &p); - if (k < 0) - return k; + path = mnt_fs_get_target(fs); + if (!path) + continue; - if (!path_startswith(p, prefix)) + if (!path_startswith(path, prefix)) continue; - if (umount2(p, flags) < 0) { - r = log_debug_errno(errno, "Failed to umount %s: %m", p); + if (umount2(path, flags) < 0) { + r = log_debug_errno(errno, "Failed to umount %s: %m", path); continue; } - log_debug("Successfully unmounted %s", p); + log_debug("Successfully unmounted %s", path); again = true; n++; @@ -91,7 +79,7 @@ int umount_recursive(const char *prefix, int flags) { } while (again); - return r < 0 ? r : n; + return n; } static int get_mount_flags(const char *path, unsigned long *flags) { @@ -141,6 +129,8 @@ int bind_remount_recursive_with_mountinfo( for (;;) { _cleanup_set_free_free_ Set *todo = NULL; + _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; + _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; bool top_autofs = false; char *x; unsigned long orig_flags; @@ -149,58 +139,52 @@ 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); - for (;;) { - _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL; - int k; - - k = 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 (superblock) */ - "%*[^-]" /* (7) optional fields */ - "- " /* (8) separator */ - "%ms " /* (9) file system type */ - "%*s" /* (10) mount source */ - "%*s" /* (11) mount options (bind mount) */ - "%*[^\n]", /* some rubbish at the end */ - &path, - &type); - if (k != 2) { - if (k == EOF) - break; + r = mnt_table_parse_stream(table, proc_self_mountinfo, "/proc/self/mountinfo"); + if (r < 0) + return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m"); - continue; - } + for (;;) { + struct libmnt_fs *fs; + const char *path, *type; - r = cunescape(path, UNESCAPE_RELAX, &p); + r = mnt_table_next_fs(table, iter, &fs); + if (r == 1) + break; if (r < 0) - return r; + return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); + + path = mnt_fs_get_target(fs); + type = mnt_fs_get_fstype(fs); + if (!path || !type) + continue; - if (!path_startswith(p, cleaned)) + if (!path_startswith(path, cleaned)) continue; - /* Ignore this mount if it is blacklisted, but only if it isn't the top-level mount we shall - * operate on. */ - if (!path_equal(cleaned, p)) { + /* Ignore this mount if it is blacklisted, but only if it isn't the top-level mount + * we shall operate on. */ + if (!path_equal(path, cleaned)) { bool blacklisted = false; char **i; STRV_FOREACH(i, blacklist) { - if (path_equal(*i, cleaned)) continue; if (!path_startswith(*i, cleaned)) continue; - if (path_startswith(p, *i)) { + if (path_startswith(path, *i)) { blacklisted = true; - log_debug("Not remounting %s blacklisted by %s, called for %s", p, *i, cleaned); + log_debug("Not remounting %s blacklisted by %s, called for %s", + path, *i, cleaned); break; } } @@ -215,15 +199,12 @@ int bind_remount_recursive_with_mountinfo( * already triggered, then we will find * another entry for this. */ if (streq(type, "autofs")) { - top_autofs = top_autofs || path_equal(cleaned, p); + top_autofs = top_autofs || path_equal(path, cleaned); continue; } - if (!set_contains(done, p)) { - r = set_consume(todo, p); - p = NULL; - if (r == -EEXIST) - continue; + if (!set_contains(done, path)) { + r = set_put_strdup(todo, path); if (r < 0) return r; } diff --git a/src/shutdown/umount.c b/src/shutdown/umount.c index 6afa512bff..ea9fba8831 100644 --- a/src/shutdown/umount.c +++ b/src/shutdown/umount.c @@ -55,18 +55,18 @@ void mount_points_list_free(MountPoint **head) { } int mount_points_list_get(const char *mountinfo, MountPoint **head) { - _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL; - _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL; + _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; + _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL; int r; assert(head); - t = mnt_new_table(); - i = mnt_new_iter(MNT_ITER_FORWARD); - if (!t || !i) + table = mnt_new_table(); + iter = mnt_new_iter(MNT_ITER_FORWARD); + if (!table || !iter) return log_oom(); - r = mnt_table_parse_mtab(t, mountinfo); + r = mnt_table_parse_mtab(table, mountinfo); if (r < 0) return log_error_errno(r, "Failed to parse %s: %m", mountinfo); @@ -79,7 +79,7 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) { bool try_remount_ro; _cleanup_free_ MountPoint *m = NULL; - r = mnt_table_next_fs(t, i, &fs); + r = mnt_table_next_fs(table, iter, &fs); if (r == 1) break; if (r < 0) |