mirror of
https://github.com/systemd/systemd.git
synced 2025-01-11 09:18:07 +03:00
Merge pull request #12218 from keszybz/use-libmount-more
Use libmount more
This commit is contained in:
commit
adb7b782f8
@ -2470,6 +2470,7 @@ exe = executable('systemd-mount',
|
||||
'src/mount/mount-tool.c',
|
||||
include_directories : includes,
|
||||
link_with : [libshared],
|
||||
dependencies: [libmount],
|
||||
install_rpath : rootlibexecdir,
|
||||
install : true)
|
||||
public_programs += exe
|
||||
|
@ -1597,31 +1597,25 @@ 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)
|
||||
return log_oom();
|
||||
|
||||
r = mnt_table_parse_mtab(t, NULL);
|
||||
r = libmount_parse(NULL, NULL, &table, &iter);
|
||||
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);
|
||||
|
@ -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,42 @@ 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");
|
||||
r = libmount_parse(NULL, NULL, &table, &iter);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse /proc/self/mountinfo: %m");
|
||||
|
||||
for (;;) {
|
||||
_cleanup_free_ char *path = NULL, *where = NULL, *dev = NULL;
|
||||
int r;
|
||||
struct libmnt_fs *fs;
|
||||
const char *source, *target;
|
||||
|
||||
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;
|
||||
|
||||
continue;
|
||||
}
|
||||
|
||||
if (!streq(what, dev))
|
||||
continue;
|
||||
|
||||
r = cunescape(path, UNESCAPE_RELAX, &where);
|
||||
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");
|
||||
|
||||
source = mnt_fs_get_source(fs);
|
||||
target = mnt_fs_get_target(fs);
|
||||
if (!source || !target)
|
||||
continue;
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
|
@ -1,6 +1,8 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1+ */
|
||||
#pragma once
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* This needs to be after sys/mount.h */
|
||||
#include <libmount.h>
|
||||
|
||||
@ -8,3 +10,38 @@
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_table*, mnt_free_table);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC(struct libmnt_iter*, mnt_free_iter);
|
||||
|
||||
static inline int libmount_parse(
|
||||
const char *path,
|
||||
FILE *source,
|
||||
struct libmnt_table **ret_table,
|
||||
struct libmnt_iter **ret_iter) {
|
||||
|
||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
||||
int r;
|
||||
|
||||
/* Older libmount seems to require this. */
|
||||
assert(!source || path);
|
||||
|
||||
table = mnt_new_table();
|
||||
iter = mnt_new_iter(MNT_ITER_FORWARD);
|
||||
if (!table || !iter)
|
||||
return -ENOMEM;
|
||||
|
||||
/* If source or path are specified, we use on the functions which ignore utab.
|
||||
* Only if both are empty, we use mnt_table_parse_mtab(). */
|
||||
|
||||
if (source)
|
||||
r = mnt_table_parse_stream(table, source, path);
|
||||
else if (path)
|
||||
r = mnt_table_parse_file(table, path);
|
||||
else
|
||||
r = mnt_table_parse_mtab(table, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
*ret_table = TAKE_PTR(table);
|
||||
*ret_iter = TAKE_PTR(iter);
|
||||
return 0;
|
||||
}
|
||||
|
@ -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,38 @@ 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);
|
||||
r = libmount_parse("/proc/self/mountinfo", NULL, &table, &iter);
|
||||
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 +74,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 +124,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;
|
||||
@ -151,56 +136,45 @@ int bind_remount_recursive_with_mountinfo(
|
||||
|
||||
rewind(proc_self_mountinfo);
|
||||
|
||||
r = libmount_parse("/proc/self/mountinfo", proc_self_mountinfo, &table, &iter);
|
||||
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 +189,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;
|
||||
}
|
||||
|
@ -55,18 +55,13 @@ 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)
|
||||
return log_oom();
|
||||
|
||||
r = mnt_table_parse_mtab(t, mountinfo);
|
||||
r = libmount_parse(mountinfo, NULL, &table, &iter);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to parse %s: %m", mountinfo);
|
||||
|
||||
@ -79,7 +74,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)
|
||||
|
@ -21,13 +21,10 @@ static void test_libmount_unescaping_one(
|
||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
||||
_cleanup_fclose_ FILE *f = NULL;
|
||||
|
||||
assert_se(table = mnt_new_table());
|
||||
assert_se(iter = mnt_new_iter(MNT_ITER_FORWARD));
|
||||
|
||||
f = fmemopen((char*) string, strlen(string), "re");
|
||||
assert_se(f);
|
||||
|
||||
assert_se(mnt_table_parse_stream(table, f, title) >= 0);
|
||||
assert_se(libmount_parse(title, f, &table, &iter) >= 0);
|
||||
|
||||
struct libmnt_fs *fs;
|
||||
const char *source, *target;
|
||||
|
Loading…
Reference in New Issue
Block a user