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.
This commit is contained in:
Zbigniew Jędrzejewski-Szmek
2019-04-23 23:29:29 +02:00
parent f5f899ef04
commit 13dcfe4661
3 changed files with 77 additions and 97 deletions
+10 -11
View File
@@ -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);
+60 -79
View File
@@ -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;
struct libmnt_fs *fs;
const char *path;
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;
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");
path = mnt_fs_get_target(fs);
if (!path)
continue;
if (!path_startswith(path, prefix))
continue;
if (umount2(path, flags) < 0) {
r = log_debug_errno(errno, "Failed to umount %s: %m", path);
continue;
}
k = cunescape(path, UNESCAPE_RELAX, &p);
if (k < 0)
return k;
if (!path_startswith(p, prefix))
continue;
if (umount2(p, flags) < 0) {
r = log_debug_errno(errno, "Failed to umount %s: %m", p);
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);
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");
for (;;) {
_cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
int k;
struct libmnt_fs *fs;
const char *path, *type;
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;
continue;
}
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");
if (!path_startswith(p, cleaned))
path = mnt_fs_get_target(fs);
type = mnt_fs_get_fstype(fs);
if (!path || !type)
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)) {
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(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;
}
+7 -7
View File
@@ -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)