|
|
b677e7 |
From ca634baa10e2249d4a706d59b67be764867e5f32 Mon Sep 17 00:00:00 2001
|
|
|
b677e7 |
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
|
b677e7 |
Date: Mon, 30 Nov 2020 10:37:06 +0100
|
|
|
b677e7 |
Subject: [PATCH] shared/mount-util: convert to libmount
|
|
|
b677e7 |
|
|
|
b677e7 |
It seems better to use just a single parsing algorithm for /proc/self/mountinfo.
|
|
|
b677e7 |
|
|
|
b677e7 |
Also, unify the naming of variables in all places that use mnt_table_next_fs().
|
|
|
b677e7 |
It makes it easier to compare the different call sites.
|
|
|
b677e7 |
|
|
|
b677e7 |
(cherry picked from commit 13dcfe4661b467131c943620d0f44711798bfd54)
|
|
|
b677e7 |
|
|
|
b677e7 |
Related: #1885143
|
|
|
b677e7 |
---
|
|
|
b677e7 |
src/basic/mount-util.c | 133 ++++++++++++++++++-----------------------
|
|
|
b677e7 |
src/core/mount.c | 22 +++----
|
|
|
b677e7 |
src/core/umount.c | 14 ++---
|
|
|
b677e7 |
3 files changed, 76 insertions(+), 93 deletions(-)
|
|
|
b677e7 |
|
|
|
b677e7 |
diff --git a/src/basic/mount-util.c b/src/basic/mount-util.c
|
|
|
b677e7 |
index 5b04e21f34..bac1a25cc8 100644
|
|
|
b677e7 |
--- a/src/basic/mount-util.c
|
|
|
b677e7 |
+++ b/src/basic/mount-util.c
|
|
|
b677e7 |
@@ -13,7 +13,6 @@
|
|
|
b677e7 |
#include <libmount.h>
|
|
|
b677e7 |
|
|
|
b677e7 |
#include "alloc-util.h"
|
|
|
b677e7 |
-#include "escape.h"
|
|
|
b677e7 |
#include "extract-word.h"
|
|
|
b677e7 |
#include "fd-util.h"
|
|
|
b677e7 |
#include "fileio.h"
|
|
|
b677e7 |
@@ -27,6 +26,9 @@
|
|
|
b677e7 |
#include "string-util.h"
|
|
|
b677e7 |
#include "strv.h"
|
|
|
b677e7 |
|
|
|
b677e7 |
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_table*, mnt_free_table);
|
|
|
b677e7 |
+DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_iter*, mnt_free_iter);
|
|
|
b677e7 |
+
|
|
|
b677e7 |
/* This is the original MAX_HANDLE_SZ definition from the kernel, when the API was introduced. We use that in place of
|
|
|
b677e7 |
* any more currently defined value to future-proof things: if the size is increased in the API headers, and our code
|
|
|
b677e7 |
* is recompiled then it would cease working on old kernels, as those refuse any sizes larger than this value with
|
|
|
b677e7 |
@@ -313,55 +315,43 @@ int umount_recursive(const char *prefix, int flags) {
|
|
|
b677e7 |
* unmounting them until they are gone. */
|
|
|
b677e7 |
|
|
|
b677e7 |
do {
|
|
|
b677e7 |
- _cleanup_fclose_ FILE *proc_self_mountinfo = NULL;
|
|
|
b677e7 |
+ _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
|
|
b677e7 |
+ _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
|
|
b677e7 |
|
|
|
b677e7 |
again = false;
|
|
|
b677e7 |
- r = 0;
|
|
|
b677e7 |
|
|
|
b677e7 |
- proc_self_mountinfo = fopen("/proc/self/mountinfo", "re");
|
|
|
b677e7 |
- if (!proc_self_mountinfo)
|
|
|
b677e7 |
- return -errno;
|
|
|
b677e7 |
+ table = mnt_new_table();
|
|
|
b677e7 |
+ iter = mnt_new_iter(MNT_ITER_FORWARD);
|
|
|
b677e7 |
+ if (!table || !iter)
|
|
|
b677e7 |
+ return -ENOMEM;
|
|
|
b677e7 |
|
|
|
b677e7 |
- (void) __fsetlocking(proc_self_mountinfo, FSETLOCKING_BYCALLER);
|
|
|
b677e7 |
+ r = mnt_table_parse_mtab(table, NULL);
|
|
|
b677e7 |
+ if (r < 0)
|
|
|
b677e7 |
+ return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
|
|
|
b677e7 |
|
|
|
b677e7 |
for (;;) {
|
|
|
b677e7 |
- _cleanup_free_ char *path = NULL, *p = NULL;
|
|
|
b677e7 |
- int k;
|
|
|
b677e7 |
-
|
|
|
b677e7 |
- k = fscanf(proc_self_mountinfo,
|
|
|
b677e7 |
- "%*s " /* (1) mount id */
|
|
|
b677e7 |
- "%*s " /* (2) parent id */
|
|
|
b677e7 |
- "%*s " /* (3) major:minor */
|
|
|
b677e7 |
- "%*s " /* (4) root */
|
|
|
b677e7 |
- "%ms " /* (5) mount point */
|
|
|
b677e7 |
- "%*s" /* (6) mount options */
|
|
|
b677e7 |
- "%*[^-]" /* (7) optional fields */
|
|
|
b677e7 |
- "- " /* (8) separator */
|
|
|
b677e7 |
- "%*s " /* (9) file system type */
|
|
|
b677e7 |
- "%*s" /* (10) mount source */
|
|
|
b677e7 |
- "%*s" /* (11) mount options 2 */
|
|
|
b677e7 |
- "%*[^\n]", /* some rubbish at the end */
|
|
|
b677e7 |
- &path);
|
|
|
b677e7 |
- if (k != 1) {
|
|
|
b677e7 |
- if (k == EOF)
|
|
|
b677e7 |
- break;
|
|
|
b677e7 |
+ struct libmnt_fs *fs;
|
|
|
b677e7 |
+ const char *path;
|
|
|
b677e7 |
|
|
|
b677e7 |
- continue;
|
|
|
b677e7 |
- }
|
|
|
b677e7 |
-
|
|
|
b677e7 |
- r = cunescape(path, UNESCAPE_RELAX, &p);
|
|
|
b677e7 |
+ r = mnt_table_next_fs(table, iter, &fs);
|
|
|
b677e7 |
+ if (r == 1)
|
|
|
b677e7 |
+ break;
|
|
|
b677e7 |
if (r < 0)
|
|
|
b677e7 |
- return r;
|
|
|
b677e7 |
+ return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
|
|
|
b677e7 |
|
|
|
b677e7 |
- if (!path_startswith(p, prefix))
|
|
|
b677e7 |
+ path = mnt_fs_get_target(fs);
|
|
|
b677e7 |
+ if (!path)
|
|
|
b677e7 |
continue;
|
|
|
b677e7 |
|
|
|
b677e7 |
- if (umount2(p, flags) < 0) {
|
|
|
b677e7 |
- r = log_debug_errno(errno, "Failed to umount %s: %m", p);
|
|
|
b677e7 |
+ if (!path_startswith(path, prefix))
|
|
|
b677e7 |
+ continue;
|
|
|
b677e7 |
+
|
|
|
b677e7 |
+ if (umount2(path, flags) < 0) {
|
|
|
b677e7 |
+ r = log_debug_errno(errno, "Failed to umount %s: %m", path);
|
|
|
b677e7 |
continue;
|
|
|
b677e7 |
}
|
|
|
b677e7 |
|
|
|
b677e7 |
- log_debug("Successfully unmounted %s", p);
|
|
|
b677e7 |
+ log_debug("Successfully unmounted %s", path);
|
|
|
b677e7 |
|
|
|
b677e7 |
again = true;
|
|
|
b677e7 |
n++;
|
|
|
b677e7 |
@@ -416,6 +406,8 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl
|
|
|
b677e7 |
|
|
|
b677e7 |
for (;;) {
|
|
|
b677e7 |
_cleanup_set_free_free_ Set *todo = NULL;
|
|
|
b677e7 |
+ _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
|
|
b677e7 |
+ _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
|
|
b677e7 |
bool top_autofs = false;
|
|
|
b677e7 |
char *x;
|
|
|
b677e7 |
unsigned long orig_flags;
|
|
|
b677e7 |
@@ -424,58 +416,52 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl
|
|
|
b677e7 |
if (!todo)
|
|
|
b677e7 |
return -ENOMEM;
|
|
|
b677e7 |
|
|
|
b677e7 |
+ table = mnt_new_table();
|
|
|
b677e7 |
+ iter = mnt_new_iter(MNT_ITER_FORWARD);
|
|
|
b677e7 |
+ if (!table || !iter)
|
|
|
b677e7 |
+ return -ENOMEM;
|
|
|
b677e7 |
+
|
|
|
b677e7 |
rewind(proc_self_mountinfo);
|
|
|
b677e7 |
|
|
|
b677e7 |
- for (;;) {
|
|
|
b677e7 |
- _cleanup_free_ char *path = NULL, *p = NULL, *type = NULL;
|
|
|
b677e7 |
- int k;
|
|
|
b677e7 |
-
|
|
|
b677e7 |
- k = fscanf(proc_self_mountinfo,
|
|
|
b677e7 |
- "%*s " /* (1) mount id */
|
|
|
b677e7 |
- "%*s " /* (2) parent id */
|
|
|
b677e7 |
- "%*s " /* (3) major:minor */
|
|
|
b677e7 |
- "%*s " /* (4) root */
|
|
|
b677e7 |
- "%ms " /* (5) mount point */
|
|
|
b677e7 |
- "%*s" /* (6) mount options (superblock) */
|
|
|
b677e7 |
- "%*[^-]" /* (7) optional fields */
|
|
|
b677e7 |
- "- " /* (8) separator */
|
|
|
b677e7 |
- "%ms " /* (9) file system type */
|
|
|
b677e7 |
- "%*s" /* (10) mount source */
|
|
|
b677e7 |
- "%*s" /* (11) mount options (bind mount) */
|
|
|
b677e7 |
- "%*[^\n]", /* some rubbish at the end */
|
|
|
b677e7 |
- &path,
|
|
|
b677e7 |
- &type);
|
|
|
b677e7 |
- if (k != 2) {
|
|
|
b677e7 |
- if (k == EOF)
|
|
|
b677e7 |
- break;
|
|
|
b677e7 |
+ r = mnt_table_parse_stream(table, proc_self_mountinfo, "/proc/self/mountinfo");
|
|
|
b677e7 |
+ if (r < 0)
|
|
|
b677e7 |
+ return log_debug_errno(r, "Failed to parse /proc/self/mountinfo: %m");
|
|
|
b677e7 |
|
|
|
b677e7 |
- continue;
|
|
|
b677e7 |
- }
|
|
|
b677e7 |
+ for (;;) {
|
|
|
b677e7 |
+ struct libmnt_fs *fs;
|
|
|
b677e7 |
+ const char *path, *type;
|
|
|
b677e7 |
|
|
|
b677e7 |
- r = cunescape(path, UNESCAPE_RELAX, &p);
|
|
|
b677e7 |
+ r = mnt_table_next_fs(table, iter, &fs);
|
|
|
b677e7 |
+ if (r == 1)
|
|
|
b677e7 |
+ break;
|
|
|
b677e7 |
if (r < 0)
|
|
|
b677e7 |
- return r;
|
|
|
b677e7 |
+ return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
|
|
|
b677e7 |
+
|
|
|
b677e7 |
+ path = mnt_fs_get_target(fs);
|
|
|
b677e7 |
+ type = mnt_fs_get_fstype(fs);
|
|
|
b677e7 |
+ if (!path || !type)
|
|
|
b677e7 |
+ continue;
|
|
|
b677e7 |
|
|
|
b677e7 |
- if (!path_startswith(p, cleaned))
|
|
|
b677e7 |
+ if (!path_startswith(path, cleaned))
|
|
|
b677e7 |
continue;
|
|
|
b677e7 |
|
|
|
b677e7 |
- /* Ignore this mount if it is blacklisted, but only if it isn't the top-level mount we shall
|
|
|
b677e7 |
- * operate on. */
|
|
|
b677e7 |
- if (!path_equal(cleaned, p)) {
|
|
|
b677e7 |
+ /* Ignore this mount if it is blacklisted, but only if it isn't the top-level mount
|
|
|
b677e7 |
+ * we shall operate on. */
|
|
|
b677e7 |
+ if (!path_equal(path, cleaned)) {
|
|
|
b677e7 |
bool blacklisted = false;
|
|
|
b677e7 |
char **i;
|
|
|
b677e7 |
|
|
|
b677e7 |
STRV_FOREACH(i, blacklist) {
|
|
|
b677e7 |
-
|
|
|
b677e7 |
if (path_equal(*i, cleaned))
|
|
|
b677e7 |
continue;
|
|
|
b677e7 |
|
|
|
b677e7 |
if (!path_startswith(*i, cleaned))
|
|
|
b677e7 |
continue;
|
|
|
b677e7 |
|
|
|
b677e7 |
- if (path_startswith(p, *i)) {
|
|
|
b677e7 |
+ if (path_startswith(path, *i)) {
|
|
|
b677e7 |
blacklisted = true;
|
|
|
b677e7 |
- log_debug("Not remounting %s, because blacklisted by %s, called for %s", p, *i, cleaned);
|
|
|
b677e7 |
+ log_debug("Not remounting %s blacklisted by %s, called for %s",
|
|
|
b677e7 |
+ path, *i, cleaned);
|
|
|
b677e7 |
break;
|
|
|
b677e7 |
}
|
|
|
b677e7 |
}
|
|
|
b677e7 |
@@ -490,15 +476,12 @@ int bind_remount_recursive_with_mountinfo(const char *prefix, bool ro, char **bl
|
|
|
b677e7 |
* already triggered, then we will find
|
|
|
b677e7 |
* another entry for this. */
|
|
|
b677e7 |
if (streq(type, "autofs")) {
|
|
|
b677e7 |
- top_autofs = top_autofs || path_equal(cleaned, p);
|
|
|
b677e7 |
+ top_autofs = top_autofs || path_equal(path, cleaned);
|
|
|
b677e7 |
continue;
|
|
|
b677e7 |
}
|
|
|
b677e7 |
|
|
|
b677e7 |
- if (!set_contains(done, p)) {
|
|
|
b677e7 |
- r = set_consume(todo, p);
|
|
|
b677e7 |
- p = NULL;
|
|
|
b677e7 |
- if (r == -EEXIST)
|
|
|
b677e7 |
- continue;
|
|
|
b677e7 |
+ if (!set_contains(done, path)) {
|
|
|
b677e7 |
+ r = set_put_strdup(todo, path);
|
|
|
b677e7 |
if (r < 0)
|
|
|
b677e7 |
return r;
|
|
|
b677e7 |
}
|
|
|
b677e7 |
diff --git a/src/core/mount.c b/src/core/mount.c
|
|
|
b677e7 |
index 076dfd06a3..7e80a0c974 100644
|
|
|
b677e7 |
--- a/src/core/mount.c
|
|
|
b677e7 |
+++ b/src/core/mount.c
|
|
|
b677e7 |
@@ -1606,18 +1606,18 @@ fail:
|
|
|
b677e7 |
}
|
|
|
b677e7 |
|
|
|
b677e7 |
static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
|
|
|
b677e7 |
- _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
|
|
|
b677e7 |
- _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
|
|
|
b677e7 |
- int r = 0;
|
|
|
b677e7 |
+ _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
|
|
b677e7 |
+ _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
|
|
b677e7 |
+ int r;
|
|
|
b677e7 |
|
|
|
b677e7 |
assert(m);
|
|
|
b677e7 |
|
|
|
b677e7 |
- t = mnt_new_table();
|
|
|
b677e7 |
- i = mnt_new_iter(MNT_ITER_FORWARD);
|
|
|
b677e7 |
- if (!t || !i)
|
|
|
b677e7 |
+ table = mnt_new_table();
|
|
|
b677e7 |
+ iter = mnt_new_iter(MNT_ITER_FORWARD);
|
|
|
b677e7 |
+ if (!table || !iter)
|
|
|
b677e7 |
return log_oom();
|
|
|
b677e7 |
|
|
|
b677e7 |
- r = mnt_table_parse_mtab(t, NULL);
|
|
|
b677e7 |
+ r = mnt_table_parse_mtab(table, NULL);
|
|
|
b677e7 |
if (r < 0)
|
|
|
b677e7 |
return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
|
|
|
b677e7 |
|
|
|
b677e7 |
@@ -1628,11 +1628,11 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
|
|
|
b677e7 |
_cleanup_free_ char *d = NULL, *p = NULL;
|
|
|
b677e7 |
int k;
|
|
|
b677e7 |
|
|
|
b677e7 |
- k = mnt_table_next_fs(t, i, &fs);
|
|
|
b677e7 |
- if (k == 1)
|
|
|
b677e7 |
+ r = mnt_table_next_fs(table, iter, &fs);
|
|
|
b677e7 |
+ if (r == 1)
|
|
|
b677e7 |
break;
|
|
|
b677e7 |
- if (k < 0)
|
|
|
b677e7 |
- return log_error_errno(k, "Failed to get next entry from /proc/self/mountinfo: %m");
|
|
|
b677e7 |
+ if (r < 0)
|
|
|
b677e7 |
+ return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
|
|
|
b677e7 |
|
|
|
b677e7 |
device = mnt_fs_get_source(fs);
|
|
|
b677e7 |
path = mnt_fs_get_target(fs);
|
|
|
b677e7 |
diff --git a/src/core/umount.c b/src/core/umount.c
|
|
|
b677e7 |
index 241fe6fc62..3f02bf141a 100644
|
|
|
b677e7 |
--- a/src/core/umount.c
|
|
|
b677e7 |
+++ b/src/core/umount.c
|
|
|
b677e7 |
@@ -55,18 +55,18 @@ void mount_points_list_free(MountPoint **head) {
|
|
|
b677e7 |
}
|
|
|
b677e7 |
|
|
|
b677e7 |
int mount_points_list_get(const char *mountinfo, MountPoint **head) {
|
|
|
b677e7 |
- _cleanup_(mnt_free_tablep) struct libmnt_table *t = NULL;
|
|
|
b677e7 |
- _cleanup_(mnt_free_iterp) struct libmnt_iter *i = NULL;
|
|
|
b677e7 |
+ _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
|
|
b677e7 |
+ _cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
|
|
b677e7 |
int r;
|
|
|
b677e7 |
|
|
|
b677e7 |
assert(head);
|
|
|
b677e7 |
|
|
|
b677e7 |
- t = mnt_new_table();
|
|
|
b677e7 |
- i = mnt_new_iter(MNT_ITER_FORWARD);
|
|
|
b677e7 |
- if (!t || !i)
|
|
|
b677e7 |
+ table = mnt_new_table();
|
|
|
b677e7 |
+ iter = mnt_new_iter(MNT_ITER_FORWARD);
|
|
|
b677e7 |
+ if (!table || !iter)
|
|
|
b677e7 |
return log_oom();
|
|
|
b677e7 |
|
|
|
b677e7 |
- r = mnt_table_parse_mtab(t, mountinfo);
|
|
|
b677e7 |
+ r = mnt_table_parse_mtab(table, mountinfo);
|
|
|
b677e7 |
if (r < 0)
|
|
|
b677e7 |
return log_error_errno(r, "Failed to parse %s: %m", mountinfo);
|
|
|
b677e7 |
|
|
|
b677e7 |
@@ -79,7 +79,7 @@ int mount_points_list_get(const char *mountinfo, MountPoint **head) {
|
|
|
b677e7 |
bool try_remount_ro;
|
|
|
b677e7 |
MountPoint *m;
|
|
|
b677e7 |
|
|
|
b677e7 |
- r = mnt_table_next_fs(t, i, &fs);
|
|
|
b677e7 |
+ r = mnt_table_next_fs(table, iter, &fs);
|
|
|
b677e7 |
if (r == 1)
|
|
|
b677e7 |
break;
|
|
|
b677e7 |
if (r < 0)
|