mirror of
https://github.com/morgan9e/systemd
synced 2026-04-15 00:47:10 +09:00
core/mount: comprehensively disable mount unit support if no libmount (#39884)
This commit is contained in:
@@ -84,6 +84,7 @@ void block_dlopen(void) {
|
||||
}
|
||||
|
||||
int dlopen_safe(const char *filename, void **ret, const char **reterr_dlerror) {
|
||||
_cleanup_(dlclosep) void *dl = NULL;
|
||||
int r;
|
||||
|
||||
assert(filename);
|
||||
@@ -99,8 +100,8 @@ int dlopen_safe(const char *filename, void **ret, const char **reterr_dlerror) {
|
||||
flags |= RTLD_NOLOAD;
|
||||
|
||||
errno = 0;
|
||||
void *p = dlopen(filename, flags);
|
||||
if (!p) {
|
||||
dl = dlopen(filename, flags);
|
||||
if (!dl) {
|
||||
if (dlopen_blocked) {
|
||||
(void) dlerror(); /* consume error, so that no later call will return it */
|
||||
|
||||
@@ -121,7 +122,7 @@ int dlopen_safe(const char *filename, void **ret, const char **reterr_dlerror) {
|
||||
}
|
||||
|
||||
if (ret)
|
||||
*ret = TAKE_PTR(p);
|
||||
*ret = TAKE_PTR(dl);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -1033,6 +1033,9 @@ static void automount_reset_failed(Unit *u) {
|
||||
static bool automount_supported(void) {
|
||||
static int supported = -1;
|
||||
|
||||
if (!unit_type_supported(UNIT_MOUNT))
|
||||
return false;
|
||||
|
||||
if (supported < 0)
|
||||
supported = access("/dev/autofs", F_OK) >= 0;
|
||||
|
||||
|
||||
@@ -59,7 +59,6 @@
|
||||
#include "killall.h"
|
||||
#include "kmod-setup.h"
|
||||
#include "label-util.h"
|
||||
#include "libmount-util.h"
|
||||
#include "limits-util.h"
|
||||
#include "load-fragment.h"
|
||||
#include "log.h"
|
||||
@@ -3311,12 +3310,6 @@ int main(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = dlopen_libmount();
|
||||
if (r < 0) {
|
||||
error_message = "Failed to load libmount.so";
|
||||
goto finish;
|
||||
}
|
||||
|
||||
r = initialize_runtime(skip_setup,
|
||||
first_boot,
|
||||
&saved_rlimit_nofile,
|
||||
|
||||
@@ -202,7 +202,6 @@ executables += [
|
||||
'dependencies' : [
|
||||
libapparmor_cflags,
|
||||
libkmod_cflags,
|
||||
libmount_cflags,
|
||||
libseccomp_cflags,
|
||||
libselinux_cflags,
|
||||
],
|
||||
|
||||
106
src/core/mount.c
106
src/core/mount.c
@@ -240,34 +240,6 @@ static void mount_done(Unit *u) {
|
||||
m->timer_event_source = sd_event_source_disable_unref(m->timer_event_source);
|
||||
}
|
||||
|
||||
static int update_parameters_proc_self_mountinfo(
|
||||
Mount *m,
|
||||
const char *what,
|
||||
const char *options,
|
||||
const char *fstype) {
|
||||
|
||||
MountParameters *p;
|
||||
int r, q, w;
|
||||
|
||||
assert(m);
|
||||
|
||||
p = &m->parameters_proc_self_mountinfo;
|
||||
|
||||
r = free_and_strdup(&p->what, what);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
q = free_and_strdup(&p->options, options);
|
||||
if (q < 0)
|
||||
return q;
|
||||
|
||||
w = free_and_strdup(&p->fstype, fstype);
|
||||
if (w < 0)
|
||||
return w;
|
||||
|
||||
return r > 0 || q > 0 || w > 0;
|
||||
}
|
||||
|
||||
static int mount_add_mount_dependencies(Mount *m) {
|
||||
MountParameters *pm;
|
||||
int r;
|
||||
@@ -1747,6 +1719,34 @@ static int mount_dispatch_timer(sd_event_source *source, usec_t usec, void *user
|
||||
}
|
||||
|
||||
#if HAVE_LIBMOUNT
|
||||
static int update_parameters_proc_self_mountinfo(
|
||||
Mount *m,
|
||||
const char *what,
|
||||
const char *options,
|
||||
const char *fstype) {
|
||||
|
||||
MountParameters *p;
|
||||
int r, q, w;
|
||||
|
||||
assert(m);
|
||||
|
||||
p = &m->parameters_proc_self_mountinfo;
|
||||
|
||||
r = free_and_strdup(&p->what, what);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
q = free_and_strdup(&p->options, options);
|
||||
if (q < 0)
|
||||
return q;
|
||||
|
||||
w = free_and_strdup(&p->fstype, fstype);
|
||||
if (w < 0)
|
||||
return w;
|
||||
|
||||
return r > 0 || q > 0 || w > 0;
|
||||
}
|
||||
|
||||
static int mount_setup_new_unit(
|
||||
Manager *m,
|
||||
const char *name,
|
||||
@@ -1927,10 +1927,8 @@ static int mount_setup_unit(
|
||||
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
|
||||
#if HAVE_LIBMOUNT
|
||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
||||
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter = NULL;
|
||||
_cleanup_set_free_ Set *devices = NULL;
|
||||
@@ -1970,10 +1968,8 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "libmount support not compiled in");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
static void mount_shutdown(Manager *m) {
|
||||
assert(m);
|
||||
@@ -2025,6 +2021,7 @@ static void mount_enumerate_perpetual(Manager *m) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(unit_type_supported(UNIT_MOUNT));
|
||||
|
||||
/* Whatever happens, we know for sure that the root directory is around, and cannot go away. Let's
|
||||
* unconditionally synthesize it here and mark it as perpetual. */
|
||||
@@ -2044,13 +2041,13 @@ static void mount_enumerate_perpetual(Manager *m) {
|
||||
unit_add_to_dbus_queue(u);
|
||||
}
|
||||
|
||||
#if HAVE_LIBMOUNT
|
||||
static bool mount_is_mounted(Mount *m) {
|
||||
assert(m);
|
||||
|
||||
return UNIT(m)->perpetual || FLAGS_SET(m->proc_flags, MOUNT_PROC_IS_MOUNTED);
|
||||
}
|
||||
|
||||
#if HAVE_LIBMOUNT
|
||||
static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) {
|
||||
Manager *m = ASSERT_PTR(userdata);
|
||||
Job *j;
|
||||
@@ -2072,17 +2069,12 @@ static int mount_on_ratelimit_expire(sd_event_source *s, void *userdata) {
|
||||
#endif
|
||||
|
||||
static void mount_enumerate(Manager *m) {
|
||||
assert(m);
|
||||
assert(unit_type_supported(UNIT_MOUNT));
|
||||
|
||||
#if HAVE_LIBMOUNT
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
r = dlopen_libmount();
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Cannot enumerate mounts, as libmount is not available: %m");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sym_mnt_init_debug(0);
|
||||
|
||||
if (!m->mount_monitor) {
|
||||
@@ -2164,23 +2156,20 @@ static void mount_enumerate(Manager *m) {
|
||||
return;
|
||||
|
||||
fail:
|
||||
mount_shutdown(m);
|
||||
#else
|
||||
log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP), "Cannot enumerate mounts, as libmount support is not compiled in");
|
||||
mount_shutdown(m);
|
||||
#endif
|
||||
mount_shutdown(m);
|
||||
}
|
||||
|
||||
static int drain_libmount(Manager *m) {
|
||||
#if HAVE_LIBMOUNT
|
||||
bool rescan = false;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
|
||||
if (!m->mount_monitor)
|
||||
return false;
|
||||
|
||||
#if HAVE_LIBMOUNT
|
||||
bool rescan = false;
|
||||
int r;
|
||||
|
||||
/* Drain all events and verify that the event is valid.
|
||||
*
|
||||
* Note that libmount also monitors /run/mount mkdir if the directory does not exist yet. The mkdir
|
||||
@@ -2196,14 +2185,13 @@ static int drain_libmount(Manager *m) {
|
||||
} while (r == 0);
|
||||
|
||||
return rescan;
|
||||
|
||||
#else
|
||||
return 0;
|
||||
assert_not_reached();
|
||||
#endif
|
||||
}
|
||||
|
||||
static int mount_process_proc_self_mountinfo(Manager *m) {
|
||||
_cleanup_set_free_ Set *around = NULL, *gone = NULL;
|
||||
const char *what;
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
@@ -2212,6 +2200,7 @@ static int mount_process_proc_self_mountinfo(Manager *m) {
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
#if HAVE_LIBMOUNT
|
||||
r = mount_load_proc_self_mountinfo(m, true);
|
||||
if (r < 0) {
|
||||
/* Reset flags, just in case, for later calls */
|
||||
@@ -2223,6 +2212,8 @@ static int mount_process_proc_self_mountinfo(Manager *m) {
|
||||
|
||||
manager_dispatch_load_queue(m);
|
||||
|
||||
_cleanup_set_free_ Set *around = NULL, *gone = NULL;
|
||||
|
||||
LIST_FOREACH(units_by_type, u, m->units_by_type[UNIT_MOUNT]) {
|
||||
Mount *mount = MOUNT(u);
|
||||
|
||||
@@ -2302,6 +2293,7 @@ static int mount_process_proc_self_mountinfo(Manager *m) {
|
||||
mount->proc_flags = 0;
|
||||
}
|
||||
|
||||
const char *what;
|
||||
SET_FOREACH(what, gone) {
|
||||
if (set_contains(around, what))
|
||||
continue;
|
||||
@@ -2311,6 +2303,9 @@ static int mount_process_proc_self_mountinfo(Manager *m) {
|
||||
}
|
||||
|
||||
return 0;
|
||||
#else
|
||||
assert_not_reached();
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAVE_LIBMOUNT
|
||||
@@ -2410,6 +2405,10 @@ static int mount_test_startable(Unit *u) {
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool mount_supported(void) {
|
||||
return dlopen_libmount() >= 0;
|
||||
}
|
||||
|
||||
static int mount_subsystem_ratelimited(Manager *m) {
|
||||
assert(m);
|
||||
|
||||
@@ -2554,6 +2553,7 @@ const UnitVTable mount_vtable = {
|
||||
.enumerate_perpetual = mount_enumerate_perpetual,
|
||||
.enumerate = mount_enumerate,
|
||||
.shutdown = mount_shutdown,
|
||||
.supported = mount_supported,
|
||||
.subsystem_ratelimited = mount_subsystem_ratelimited,
|
||||
|
||||
.status_message_formats = {
|
||||
|
||||
@@ -5023,6 +5023,11 @@ int unit_add_mounts_for(Unit *u, const char *path, UnitDependencyMask mask, Unit
|
||||
if (hashmap_contains(*unit_map, path)) /* Exit quickly if the path is already covered. */
|
||||
return 0;
|
||||
|
||||
if (!unit_type_supported(UNIT_MOUNT)) {
|
||||
log_once(LOG_NOTICE, "Mount unit not supported, skipping *MountsFor= dependencies.");
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* Use the canonical form of the path as the stored key. We call path_is_normalized()
|
||||
* only after simplification, since path_is_normalized() rejects paths with '.'.
|
||||
* path_is_normalized() also verifies that the path fits in PATH_MAX. */
|
||||
|
||||
@@ -1,11 +1,9 @@
|
||||
/* SPDX-License-Identifier: LGPL-2.1-or-later */
|
||||
|
||||
#include "libmount-util.h"
|
||||
|
||||
#if HAVE_LIBMOUNT
|
||||
#include <stdio.h>
|
||||
|
||||
#include "fstab-util.h"
|
||||
#include "libmount-util.h"
|
||||
#include "log.h"
|
||||
|
||||
static void *libmount_dl = NULL;
|
||||
@@ -41,10 +39,8 @@ DLSYM_PROTOTYPE(mnt_table_parse_mtab) = NULL;
|
||||
DLSYM_PROTOTYPE(mnt_table_parse_stream) = NULL;
|
||||
DLSYM_PROTOTYPE(mnt_table_parse_swaps) = NULL;
|
||||
DLSYM_PROTOTYPE(mnt_unref_monitor) = NULL;
|
||||
#endif
|
||||
|
||||
int dlopen_libmount(void) {
|
||||
#if HAVE_LIBMOUNT
|
||||
ELF_NOTE_DLOPEN("mount",
|
||||
"Support for mount enumeration",
|
||||
ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED,
|
||||
@@ -85,12 +81,8 @@ int dlopen_libmount(void) {
|
||||
DLSYM_ARG(mnt_table_parse_stream),
|
||||
DLSYM_ARG(mnt_table_parse_swaps),
|
||||
DLSYM_ARG(mnt_unref_monitor));
|
||||
#else
|
||||
return -EOPNOTSUPP;
|
||||
#endif
|
||||
}
|
||||
|
||||
#if HAVE_LIBMOUNT
|
||||
int libmount_parse_full(
|
||||
const char *path,
|
||||
FILE *source,
|
||||
@@ -159,4 +151,3 @@ int libmount_is_leaf(
|
||||
|
||||
return r == 1;
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -42,6 +42,8 @@ extern DLSYM_PROTOTYPE(mnt_table_parse_stream);
|
||||
extern DLSYM_PROTOTYPE(mnt_table_parse_swaps);
|
||||
extern DLSYM_PROTOTYPE(mnt_unref_monitor);
|
||||
|
||||
int dlopen_libmount(void);
|
||||
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct libmnt_table*, sym_mnt_free_table, mnt_free_tablep, NULL);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL_RENAME(struct libmnt_iter*, sym_mnt_free_iter, mnt_free_iterp, NULL);
|
||||
|
||||
@@ -56,12 +58,14 @@ static inline int libmount_parse_mountinfo(
|
||||
FILE *source,
|
||||
struct libmnt_table **ret_table,
|
||||
struct libmnt_iter **ret_iter) {
|
||||
|
||||
return libmount_parse_full("/proc/self/mountinfo", source, MNT_ITER_FORWARD, ret_table, ret_iter);
|
||||
}
|
||||
|
||||
static inline int libmount_parse_with_utab(
|
||||
struct libmnt_table **ret_table,
|
||||
struct libmnt_iter **ret_iter) {
|
||||
|
||||
return libmount_parse_full(NULL, NULL, MNT_ITER_FORWARD, ret_table, ret_iter);
|
||||
}
|
||||
|
||||
@@ -70,15 +74,18 @@ int libmount_parse_fstab(struct libmnt_table **ret_table, struct libmnt_iter **r
|
||||
int libmount_is_leaf(
|
||||
struct libmnt_table *table,
|
||||
struct libmnt_fs *fs);
|
||||
|
||||
#else
|
||||
|
||||
struct libmnt_monitor;
|
||||
|
||||
static inline void *sym_mnt_unref_monitor(struct libmnt_monitor *p) {
|
||||
static inline int dlopen_libmount(void) {
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
static inline void* sym_mnt_unref_monitor(struct libmnt_monitor *p) {
|
||||
assert(p == NULL);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
int dlopen_libmount(void);
|
||||
|
||||
@@ -115,7 +115,6 @@ shared_sources = files(
|
||||
'libaudit-util.c',
|
||||
'libcrypt-util.c',
|
||||
'libfido2-util.c',
|
||||
'libmount-util.c',
|
||||
'local-addresses.c',
|
||||
'locale-setup.c',
|
||||
'log-assert-critical.c',
|
||||
@@ -239,10 +238,6 @@ shared_sources = files(
|
||||
'xml.c',
|
||||
)
|
||||
|
||||
if conf.get('ENABLE_NSS') == 1
|
||||
shared_sources += files('nss-util.c')
|
||||
endif
|
||||
|
||||
if get_option('tests') != 'false'
|
||||
shared_sources += files('tests.c')
|
||||
endif
|
||||
@@ -257,6 +252,10 @@ syscall_list_inc = custom_target(
|
||||
generated_sources += syscall_list_inc
|
||||
shared_sources += syscall_list_inc
|
||||
|
||||
if conf.get('ENABLE_NSS') == 1
|
||||
shared_sources += files('nss-util.c')
|
||||
endif
|
||||
|
||||
if conf.get('ENABLE_UTMP') == 1
|
||||
shared_sources += files('utmp-wtmp.c')
|
||||
endif
|
||||
@@ -269,6 +268,10 @@ if conf.get('HAVE_PAM') == 1
|
||||
shared_sources += files('pam-util.c')
|
||||
endif
|
||||
|
||||
if conf.get('HAVE_LIBMOUNT') == 1
|
||||
shared_sources += files('libmount-util.c')
|
||||
endif
|
||||
|
||||
generate_ip_protocol_list = files('generate-ip-protocol-list.sh')
|
||||
ip_protocol_list_txt = custom_target(
|
||||
input : [generate_ip_protocol_list, ipproto_sources],
|
||||
|
||||
Reference in New Issue
Block a user