1
0
mirror of https://github.com/systemd/systemd synced 2026-04-24 07:55:12 +02:00

Compare commits

..

No commits in common. "996e6d0d8957653ff84387367e81ba5f9cbfbbf2" and "3b6288f6becf0e55da6de9ff55e824c2ada93f2c" have entirely different histories.

120 changed files with 870 additions and 1530 deletions

View File

@ -347,7 +347,7 @@
<varlistentry> <varlistentry>
<term><option>--chrome=</option></term> <term><option>--chrome=</option></term>
<listitem><para>Takes a boolean argument. By default the initial setup screen will show reverse color <listitem><para>Takes a boolean argument. By default the initial setup scren will show reverse color
"chrome" bars at the top and and the bottom of the terminal screen, which may be disabled by setting "chrome" bars at the top and and the bottom of the terminal screen, which may be disabled by setting
this option to false.</para> this option to false.</para>

View File

@ -1149,7 +1149,7 @@ NFTSet=cgroup:inet:filter:my_service user:inet:filter:serviceuser
one more restricted, depending on the use case.</para> one more restricted, depending on the use case.</para>
<para>Note that these settings might not be supported on some systems (for example if eBPF control group <para>Note that these settings might not be supported on some systems (for example if eBPF control group
support is not enabled in the underlying kernel or container manager). These settings will have no effect in support is not enabled in the underlying kernel or container manager). These settings will fail the service in
that case. If compatibility with such systems is desired it is hence recommended to attach your filter manually that case. If compatibility with such systems is desired it is hence recommended to attach your filter manually
(requires <varname>Delegate=</varname><constant>yes</constant>) instead of using this setting.</para> (requires <varname>Delegate=</varname><constant>yes</constant>) instead of using this setting.</para>

View File

@ -1122,7 +1122,6 @@ libmount = dependency('mount',
version : fuzzer_build ? '>= 0' : '>= 2.30', version : fuzzer_build ? '>= 0' : '>= 2.30',
disabler : true, disabler : true,
required : get_option('libmount')) required : get_option('libmount'))
libmount_cflags = libmount.partial_dependency(includes: true, compile_args: true)
libfdisk = dependency('fdisk', libfdisk = dependency('fdisk',
version : '>= 2.32', version : '>= 2.32',

View File

@ -2446,6 +2446,8 @@ static int analyze_security_one(sd_bus *bus,
/* Refactoring SecurityInfo so that it can make use of existing struct variables instead of reading from dbus */ /* Refactoring SecurityInfo so that it can make use of existing struct variables instead of reading from dbus */
static int get_security_info(Unit *u, ExecContext *c, CGroupContext *g, SecurityInfo **ret_info) { static int get_security_info(Unit *u, ExecContext *c, CGroupContext *g, SecurityInfo **ret_info) {
int r;
assert(ret_info); assert(ret_info);
_cleanup_(security_info_freep) SecurityInfo *info = security_info_new(); _cleanup_(security_info_freep) SecurityInfo *info = security_info_new();
@ -2575,7 +2577,8 @@ static int get_security_info(Unit *u, ExecContext *c, CGroupContext *g, Security
info->_umask = c->umask; info->_umask = c->umask;
#if HAVE_SECCOMP #if HAVE_SECCOMP
if (dlopen_libseccomp() >= 0) { r = dlopen_libseccomp();
if (r >= 0) {
SET_FOREACH(key, c->syscall_archs) { SET_FOREACH(key, c->syscall_archs) {
const char *name; const char *name;

View File

@ -15,20 +15,3 @@ const char* runtime_scope_to_string(RuntimeScope scope) _const_;
RuntimeScope runtime_scope_from_string(const char *s) _const_; RuntimeScope runtime_scope_from_string(const char *s) _const_;
const char* runtime_scope_cmdline_option_to_string(RuntimeScope scope) _const_; const char* runtime_scope_cmdline_option_to_string(RuntimeScope scope) _const_;
static inline mode_t runtime_scope_to_socket_mode(RuntimeScope scope) {
/* Returns the right socket mode to use for binding AF_UNIX sockets intended for the specified
* scope. If system mode is selected the whole system can connect to it, if user mode is selected
* only the user can connect to it. */
switch (scope) {
case RUNTIME_SCOPE_SYSTEM:
return 0666;
case RUNTIME_SCOPE_USER:
return 0600;
default:
return MODE_INVALID;
}
}

View File

@ -547,9 +547,9 @@ int bpf_firewall_compile(Unit *u) {
if (!cc) if (!cc)
return -EINVAL; return -EINVAL;
crt = unit_get_cgroup_runtime(u); crt = unit_setup_cgroup_runtime(u);
if (!crt) if (!crt)
return -ESTALE; return -ENOMEM;
if (bpf_program_supported() <= 0) if (bpf_program_supported() <= 0)
return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP), return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP),

View File

@ -2204,6 +2204,12 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
if (set_isempty(pids)) if (set_isempty(pids))
return 0; return 0;
/* Load any custom firewall BPF programs here once to test if they are existing and actually loadable.
* Fail here early since later errors in the call chain unit_realize_cgroup to cgroup_context_apply are ignored. */
r = bpf_firewall_load_custom(u);
if (r < 0)
return r;
r = unit_realize_cgroup(u); r = unit_realize_cgroup(u);
if (r < 0) if (r < 0)
return r; return r;
@ -4277,15 +4283,6 @@ int cgroup_runtime_serialize(Unit *u, FILE *f, FDSet *fds) {
if (!crt) if (!crt)
return 0; return 0;
if (crt->cgroup_path)
(void) serialize_item(f, "cgroup", crt->cgroup_path);
if (crt->cgroup_id != 0)
(void) serialize_item_format(f, "cgroup-id", "%" PRIu64, crt->cgroup_id);
(void) serialize_cgroup_mask(f, "cgroup-realized-mask", crt->cgroup_realized_mask);
(void) serialize_cgroup_mask(f, "cgroup-enabled-mask", crt->cgroup_enabled_mask);
(void) serialize_cgroup_mask(f, "cgroup-invalidated-mask", crt->cgroup_invalidated_mask);
(void) serialize_item_format(f, "cpu-usage-base", "%" PRIu64, crt->cpu_usage_base); (void) serialize_item_format(f, "cpu-usage-base", "%" PRIu64, crt->cpu_usage_base);
if (crt->cpu_usage_last != NSEC_INFINITY) if (crt->cpu_usage_last != NSEC_INFINITY)
(void) serialize_item_format(f, "cpu-usage-last", "%" PRIu64, crt->cpu_usage_last); (void) serialize_item_format(f, "cpu-usage-last", "%" PRIu64, crt->cpu_usage_last);
@ -4319,6 +4316,15 @@ int cgroup_runtime_serialize(Unit *u, FILE *f, FDSet *fds) {
(void) serialize_item_format(f, io_accounting_metric_field_last_to_string(im), "%" PRIu64, crt->io_accounting_last[im]); (void) serialize_item_format(f, io_accounting_metric_field_last_to_string(im), "%" PRIu64, crt->io_accounting_last[im]);
} }
if (crt->cgroup_path)
(void) serialize_item(f, "cgroup", crt->cgroup_path);
if (crt->cgroup_id != 0)
(void) serialize_item_format(f, "cgroup-id", "%" PRIu64, crt->cgroup_id);
(void) serialize_cgroup_mask(f, "cgroup-realized-mask", crt->cgroup_realized_mask);
(void) serialize_cgroup_mask(f, "cgroup-enabled-mask", crt->cgroup_enabled_mask);
(void) serialize_cgroup_mask(f, "cgroup-invalidated-mask", crt->cgroup_invalidated_mask);
(void) bpf_socket_bind_serialize(u, f, fds); (void) bpf_socket_bind_serialize(u, f, fds);
(void) bpf_program_serialize_attachment(f, fds, "ip-bpf-ingress-installed", crt->ip_bpf_ingress_installed); (void) bpf_program_serialize_attachment(f, fds, "ip-bpf-ingress-installed", crt->ip_bpf_ingress_installed);

View File

@ -134,7 +134,7 @@ libcore_static = static_library(
dependencies : [libaudit_cflags, dependencies : [libaudit_cflags,
libdl, libdl,
libm, libm,
libmount_cflags, libmount,
librt, librt,
libseccomp_cflags, libseccomp_cflags,
libselinux, libselinux,
@ -222,7 +222,7 @@ executables += [
libcore, libcore,
libshared libshared
], ],
'dependencies' : libmount_cflags, 'dependencies' : libmount,
}, },
fuzz_template + { fuzz_template + {
'sources' : files('fuzz-manager-serialize.c'), 'sources' : files('fuzz-manager-serialize.c'),

View File

@ -1952,16 +1952,16 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
struct libmnt_fs *fs; struct libmnt_fs *fs;
const char *device, *path, *options, *fstype; const char *device, *path, *options, *fstype;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r == 1) if (r == 1)
break; break;
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
device = sym_mnt_fs_get_source(fs); device = mnt_fs_get_source(fs);
path = sym_mnt_fs_get_target(fs); path = mnt_fs_get_target(fs);
options = sym_mnt_fs_get_options(fs); options = mnt_fs_get_options(fs);
fstype = sym_mnt_fs_get_fstype(fs); fstype = mnt_fs_get_fstype(fs);
if (!device || !path) if (!device || !path)
continue; continue;
@ -1983,11 +1983,9 @@ static void mount_shutdown(Manager *m) {
m->mount_event_source = sd_event_source_disable_unref(m->mount_event_source); m->mount_event_source = sd_event_source_disable_unref(m->mount_event_source);
if (m->mount_monitor) { mnt_unref_monitor(m->mount_monitor);
sym_mnt_unref_monitor(m->mount_monitor);
m->mount_monitor = NULL; m->mount_monitor = NULL;
} }
}
static void mount_handoff_timestamp( static void mount_handoff_timestamp(
Unit *u, Unit *u,
@ -2077,39 +2075,33 @@ static void mount_enumerate(Manager *m) {
assert(m); assert(m);
r = dlopen_libmount(); mnt_init_debug(0);
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) { if (!m->mount_monitor) {
usec_t mount_rate_limit_interval = 1 * USEC_PER_SEC; usec_t mount_rate_limit_interval = 1 * USEC_PER_SEC;
unsigned mount_rate_limit_burst = 5; unsigned mount_rate_limit_burst = 5;
int fd; int fd;
m->mount_monitor = sym_mnt_new_monitor(); m->mount_monitor = mnt_new_monitor();
if (!m->mount_monitor) { if (!m->mount_monitor) {
log_oom(); log_oom();
goto fail; goto fail;
} }
r = sym_mnt_monitor_enable_kernel(m->mount_monitor, 1); r = mnt_monitor_enable_kernel(m->mount_monitor, 1);
if (r < 0) { if (r < 0) {
log_error_errno(r, "Failed to enable watching of kernel mount events: %m"); log_error_errno(r, "Failed to enable watching of kernel mount events: %m");
goto fail; goto fail;
} }
r = sym_mnt_monitor_enable_userspace(m->mount_monitor, 1, NULL); r = mnt_monitor_enable_userspace(m->mount_monitor, 1, NULL);
if (r < 0) { if (r < 0) {
log_error_errno(r, "Failed to enable watching of userspace mount events: %m"); log_error_errno(r, "Failed to enable watching of userspace mount events: %m");
goto fail; goto fail;
} }
/* mnt_unref_monitor() will close the fd */ /* mnt_unref_monitor() will close the fd */
fd = r = sym_mnt_monitor_get_fd(m->mount_monitor); fd = r = mnt_monitor_get_fd(m->mount_monitor);
if (r < 0) { if (r < 0) {
log_error_errno(r, "Failed to acquire watch file descriptor: %m"); log_error_errno(r, "Failed to acquire watch file descriptor: %m");
goto fail; goto fail;
@ -2173,9 +2165,6 @@ static int drain_libmount(Manager *m) {
assert(m); assert(m);
if (!m->mount_monitor)
return false;
/* Drain all events and verify that the event is valid. /* 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 * Note that libmount also monitors /run/mount mkdir if the directory does not exist yet. The mkdir
@ -2183,7 +2172,7 @@ static int drain_libmount(Manager *m) {
* *
* error: r < 0; valid: r == 0, false positive: r == 1 */ * error: r < 0; valid: r == 0, false positive: r == 1 */
do { do {
r = sym_mnt_monitor_next_change(m->mount_monitor, NULL, NULL); r = mnt_monitor_next_change(m->mount_monitor, NULL, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to drain libmount events: %m"); return log_error_errno(r, "Failed to drain libmount events: %m");
if (r == 0) if (r == 0)

View File

@ -664,6 +664,8 @@ static int timer_start(Unit *u) {
if (r < 0) if (r < 0)
return r; return r;
t->last_trigger = DUAL_TIMESTAMP_NULL;
/* Reenable all timers that depend on unit activation time */ /* Reenable all timers that depend on unit activation time */
LIST_FOREACH(value, v, t->values) LIST_FOREACH(value, v, t->values)
if (v->base == TIMER_ACTIVE) if (v->base == TIMER_ACTIVE)

View File

@ -5559,11 +5559,11 @@ int unit_fork_helper_process(Unit *u, const char *name, bool into_cgroup, PidRef
* with the child's PID. */ * with the child's PID. */
if (into_cgroup) { if (into_cgroup) {
r = unit_realize_cgroup(u); (void) unit_realize_cgroup(u);
if (r < 0)
return r;
crt = unit_get_cgroup_runtime(u); crt = unit_setup_cgroup_runtime(u);
if (!crt)
return -ENOMEM;
} }
r = safe_fork(name, FORK_REOPEN_LOG|FORK_DEATHSIG_SIGTERM, &pid); r = safe_fork(name, FORK_REOPEN_LOG|FORK_DEATHSIG_SIGTERM, &pid);
@ -6005,12 +6005,16 @@ int unit_prepare_exec(Unit *u) {
assert(u); assert(u);
/* Prepares everything so that we can fork of a process for this unit */ /* Load any custom firewall BPF programs here once to test if they are existing and actually loadable.
* Fail here early since later errors in the call chain unit_realize_cgroup to cgroup_context_apply are ignored. */
r = unit_realize_cgroup(u); r = bpf_firewall_load_custom(u);
if (r < 0) if (r < 0)
return r; return r;
/* Prepares everything so that we can fork of a process for this unit */
(void) unit_realize_cgroup(u);
CGroupRuntime *crt = unit_get_cgroup_runtime(u); CGroupRuntime *crt = unit_get_cgroup_runtime(u);
if (crt && crt->reset_accounting) { if (crt && crt->reset_accounting) {
(void) unit_reset_accounting(u); (void) unit_reset_accounting(u);

View File

@ -191,23 +191,19 @@ static int is_tmpfs_with_noswap(dev_t devno) {
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL; _cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
int r; int r;
r = dlopen_libmount(); table = mnt_new_table();
if (r < 0)
return r;
table = sym_mnt_new_table();
if (!table) if (!table)
return -ENOMEM; return -ENOMEM;
r = sym_mnt_table_parse_mtab(table, /* filename= */ NULL); r = mnt_table_parse_mtab(table, /* filename= */ NULL);
if (r < 0) if (r < 0)
return r; return r;
struct libmnt_fs *fs = sym_mnt_table_find_devno(table, devno, MNT_ITER_FORWARD); struct libmnt_fs *fs = mnt_table_find_devno(table, devno, MNT_ITER_FORWARD);
if (!fs) if (!fs)
return -ENODEV; return -ENODEV;
r = sym_mnt_fs_get_option(fs, "noswap", /* value= */ NULL, /* valuesz= */ NULL); r = mnt_fs_get_option(fs, "noswap", /* value= */ NULL, /* valuesz= */ NULL);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -6,7 +6,7 @@ executables += [
'public' : true, 'public' : true,
'sources' : files('creds.c'), 'sources' : files('creds.c'),
'dependencies' : [ 'dependencies' : [
libmount_cflags, libmount,
libopenssl, libopenssl,
threads, threads,
], ],

View File

@ -753,12 +753,12 @@ static char* disk_mount_point(const char *label) {
for (;;) { for (;;) {
struct libmnt_fs *fs; struct libmnt_fs *fs;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r != 0) if (r != 0)
return NULL; return NULL;
if (path_equal(sym_mnt_fs_get_source(fs), device)) { if (path_equal(mnt_fs_get_source(fs), device)) {
const char *target = sym_mnt_fs_get_target(fs); const char *target = mnt_fs_get_target(fs);
if (target) if (target)
return strdup(target); return strdup(target);
} }

View File

@ -19,7 +19,7 @@ executables += [
'sources' : systemd_cryptsetup_sources, 'sources' : systemd_cryptsetup_sources,
'dependencies' : [ 'dependencies' : [
libcryptsetup, libcryptsetup,
libmount_cflags, libmount,
libopenssl, libopenssl,
libp11kit_cflags, libp11kit_cflags,
], ],

View File

@ -1048,19 +1048,15 @@ static int parse_fstab(bool prefix_sysroot) {
for (;;) { for (;;) {
struct libmnt_fs *fs; struct libmnt_fs *fs;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get next entry from '%s': %m", fstab); return log_error_errno(r, "Failed to get next entry from '%s': %m", fstab);
if (r > 0) /* EOF */ if (r > 0) /* EOF */
return ret; return ret;
r = parse_fstab_one( r = parse_fstab_one(fstab,
fstab, mnt_fs_get_source(fs), mnt_fs_get_target(fs),
sym_mnt_fs_get_source(fs), mnt_fs_get_fstype(fs), mnt_fs_get_options(fs), mnt_fs_get_passno(fs),
sym_mnt_fs_get_target(fs),
sym_mnt_fs_get_fstype(fs),
sym_mnt_fs_get_options(fs),
sym_mnt_fs_get_passno(fs),
prefix_sysroot, prefix_sysroot,
/* accept_root = */ false, /* accept_root = */ false,
/* use_swap_enabled = */ true); /* use_swap_enabled = */ true);
@ -1449,19 +1445,15 @@ static int add_mounts_from_creds(bool prefix_sysroot) {
for (;;) { for (;;) {
struct libmnt_fs *fs; struct libmnt_fs *fs;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get next fstab entry from credential '%s': %m", cred); return log_error_errno(r, "Failed to get next fstab entry from credential '%s': %m", cred);
if (r > 0) /* EOF */ if (r > 0) /* EOF */
return ret; return ret;
RET_GATHER(ret, parse_fstab_one( RET_GATHER(ret, parse_fstab_one("/run/credentials",
"/run/credentials", mnt_fs_get_source(fs), mnt_fs_get_target(fs),
sym_mnt_fs_get_source(fs), mnt_fs_get_fstype(fs), mnt_fs_get_options(fs), mnt_fs_get_passno(fs),
sym_mnt_fs_get_target(fs),
sym_mnt_fs_get_fstype(fs),
sym_mnt_fs_get_options(fs),
sym_mnt_fs_get_passno(fs),
prefix_sysroot, prefix_sysroot,
/* accept_root = */ true, /* accept_root = */ true,
/* use_swap_enabled = */ true)); /* use_swap_enabled = */ true));

View File

@ -4,7 +4,7 @@ executables += [
generator_template + { generator_template + {
'name' : 'systemd-fstab-generator', 'name' : 'systemd-fstab-generator',
'sources' : files('fstab-generator.c'), 'sources' : files('fstab-generator.c'),
'dependencies' : libmount_cflags, 'dependencies' : libmount,
}, },
] ]

View File

@ -25,7 +25,6 @@ static int run(int argc, char *argv[]) {
"A service to create, remove, change or inspect home areas.", "A service to create, remove, change or inspect home areas.",
BUS_IMPLEMENTATIONS(&manager_object, BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object), &log_control_object),
/* runtime_scope= */ NULL,
argc, argv); argc, argv);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -1988,7 +1988,6 @@ static int run(int argc, char *argv[]) {
"Manage the system hostname and related metadata.", "Manage the system hostname and related metadata.",
BUS_IMPLEMENTATIONS(&manager_object, BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object), &log_control_object),
/* runtime_scope= */ NULL,
argc, argv); argc, argv);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -2019,7 +2019,6 @@ static int run(int argc, char *argv[]) {
"VM and container image import and export service.", "VM and container image import and export service.",
BUS_IMPLEMENTATIONS(&manager_object, BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object), &log_control_object),
/* runtime_scope= */ NULL,
argc, argv); argc, argv);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -33,54 +33,32 @@ int user_search_dirs(const char *suffix, char ***ret_config_dirs, char ***ret_da
return 0; return 0;
} }
int runtime_directory_generic(RuntimeScope scope, const char *suffix, char **ret) { int runtime_directory(RuntimeScope scope, const char *suffix, char **ret) {
int r; int r;
assert(IN_SET(scope, RUNTIME_SCOPE_SYSTEM, RUNTIME_SCOPE_USER));
assert(suffix);
assert(ret); assert(ret);
/* This does not bother with $RUNTIME_DIRECTORY, and hence can be applied to get other service's /* Accept $RUNTIME_DIRECTORY as authoritative
* runtime dir */
switch (scope) {
case RUNTIME_SCOPE_USER:
r = xdg_user_runtime_dir(suffix, ret);
if (r < 0)
return r;
break;
case RUNTIME_SCOPE_SYSTEM: {
char *d = path_join("/run", suffix);
if (!d)
return -ENOMEM;
*ret = d;
break;
}
default:
return -EINVAL;
}
return 0;
}
int runtime_directory(RuntimeScope scope, const char *fallback_suffix, char **ret) {
int r;
assert(ret);
/* Accept $RUNTIME_DIRECTORY as authoritative, i.e. only works for our service's own runtime dir.
*
* If it's missing, apply the suffix to /run/, or $XDG_RUNTIME_DIR if we are in a user runtime scope. * If it's missing, apply the suffix to /run/, or $XDG_RUNTIME_DIR if we are in a user runtime scope.
* *
* Return value indicates whether the suffix was applied or not. */ * Return value indicates whether the suffix was applied or not */
const char *e = secure_getenv("RUNTIME_DIRECTORY"); const char *e = secure_getenv("RUNTIME_DIRECTORY");
if (e) if (e)
return strdup_to(ret, e); return strdup_to(ret, e);
r = runtime_directory_generic(scope, fallback_suffix, ret); if (scope == RUNTIME_SCOPE_USER) {
r = xdg_user_runtime_dir(suffix, ret);
if (r < 0) if (r < 0)
return r; return r;
} else {
char *d = path_join("/run", suffix);
if (!d)
return -ENOMEM;
*ret = d;
}
return 1; return 1;
} }

View File

@ -57,8 +57,7 @@ int lookup_paths_init_or_warn(LookupPaths *lp, RuntimeScope scope, LookupPathsFl
void lookup_paths_log(LookupPaths *p); void lookup_paths_log(LookupPaths *p);
void lookup_paths_done(LookupPaths *p); void lookup_paths_done(LookupPaths *p);
int runtime_directory_generic(RuntimeScope scope, const char *suffix, char **ret); int runtime_directory(RuntimeScope scope, const char *suffix, char **ret);
int runtime_directory(RuntimeScope scope, const char *fallback_suffix, char **ret);
/* We don't treat /etc/xdg/systemd/ in these functions as the xdg base dir spec suggests because we assume /* We don't treat /etc/xdg/systemd/ in these functions as the xdg base dir spec suggests because we assume
* that is a link to /etc/systemd/ anyway. */ * that is a link to /etc/systemd/ anyway. */

View File

@ -635,7 +635,6 @@ static int run(int argc, char *argv[]) {
"Manage system locale settings and key mappings.", "Manage system locale settings and key mappings.",
BUS_IMPLEMENTATIONS(&manager_object, BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object), &log_control_object),
/* runtime_scope= */ NULL,
argc, argv); argc, argv);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -1340,7 +1340,6 @@ static int run(int argc, char *argv[]) {
"Manager for user logins and devices and privileged operations.", "Manager for user logins and devices and privileged operations.",
BUS_IMPLEMENTATIONS(&manager_object, BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object), &log_control_object),
/* runtime_scope= */ NULL,
argc, argv); argc, argv);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -40,7 +40,6 @@ int bus_image_method_remove(
if (m->n_operations >= OPERATIONS_MAX) if (m->n_operations >= OPERATIONS_MAX)
return sd_bus_error_set(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations."); return sd_bus_error_set(error, SD_BUS_ERROR_LIMITS_EXCEEDED, "Too many ongoing operations.");
if (m->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"image", image->name, "image", image->name,
"verb", "remove", "verb", "remove",
@ -57,7 +56,6 @@ int bus_image_method_remove(
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0) if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m"); return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
@ -67,7 +65,7 @@ int bus_image_method_remove(
return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m"); return sd_bus_error_set_errnof(error, r, "Failed to fork(): %m");
if (r == 0) { if (r == 0) {
errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]); errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
r = image_remove(image, m->runtime_scope); r = image_remove(image);
report_errno_and_exit(errno_pipe_fd[1], r); report_errno_and_exit(errno_pipe_fd[1], r);
} }
@ -103,7 +101,6 @@ int bus_image_method_rename(
if (!image_name_is_valid(new_name)) if (!image_name_is_valid(new_name))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name); return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
if (m->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"image", image->name, "image", image->name,
"verb", "rename", "verb", "rename",
@ -121,7 +118,6 @@ int bus_image_method_rename(
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
r = rename_image_and_update_cache(m, image, new_name); r = rename_image_and_update_cache(m, image, new_name);
if (r < 0) if (r < 0)
@ -154,7 +150,6 @@ int bus_image_method_clone(
if (!image_name_is_valid(new_name)) if (!image_name_is_valid(new_name))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name); return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
if (m->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"image", image->name, "image", image->name,
"verb", "clone", "verb", "clone",
@ -172,7 +167,6 @@ int bus_image_method_clone(
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0) if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m"); return sd_bus_error_set_errnof(error, errno, "Failed to create pipe: %m");
@ -205,7 +199,7 @@ int bus_image_method_mark_read_only(
sd_bus_error *error) { sd_bus_error *error) {
Image *image = userdata; Image *image = userdata;
Manager *m = ASSERT_PTR(image->userdata); Manager *m = image->userdata;
int read_only, r; int read_only, r;
assert(message); assert(message);
@ -214,7 +208,6 @@ int bus_image_method_mark_read_only(
if (r < 0) if (r < 0)
return r; return r;
if (m->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"image", image->name, "image", image->name,
"verb", "mark_read_only", "verb", "mark_read_only",
@ -232,9 +225,8 @@ int bus_image_method_mark_read_only(
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
r = image_read_only(image, read_only, m->runtime_scope); r = image_read_only(image, read_only);
if (r < 0) if (r < 0)
return r; return r;
@ -259,7 +251,6 @@ int bus_image_method_set_limit(
if (!FILE_SIZE_VALID_OR_INFINITY(limit)) if (!FILE_SIZE_VALID_OR_INFINITY(limit))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "New limit out of range"); return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "New limit out of range");
if (m->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"machine", image->name, "machine", image->name,
"verb", "set_limit", "verb", "set_limit",
@ -276,7 +267,6 @@ int bus_image_method_set_limit(
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
r = image_set_limit(image, limit); r = image_set_limit(image, limit);
if (r < 0) if (r < 0)
@ -290,12 +280,11 @@ int bus_image_method_get_hostname(
void *userdata, void *userdata,
sd_bus_error *error) { sd_bus_error *error) {
Image *image = ASSERT_PTR(userdata); Image *image = userdata;
Manager *m = ASSERT_PTR(image->userdata);
int r; int r;
if (!image->metadata_valid) { if (!image->metadata_valid) {
r = image_read_metadata(image, &image_policy_container, m->runtime_scope); r = image_read_metadata(image, &image_policy_container);
if (r < 0) if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m"); return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
} }
@ -309,12 +298,11 @@ int bus_image_method_get_machine_id(
sd_bus_error *error) { sd_bus_error *error) {
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL; _cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
Image *image = ASSERT_PTR(userdata); Image *image = userdata;
Manager *m = ASSERT_PTR(image->userdata);
int r; int r;
if (!image->metadata_valid) { if (!image->metadata_valid) {
r = image_read_metadata(image, &image_policy_container, m->runtime_scope); r = image_read_metadata(image, &image_policy_container);
if (r < 0) if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m"); return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
} }
@ -338,12 +326,11 @@ int bus_image_method_get_machine_info(
void *userdata, void *userdata,
sd_bus_error *error) { sd_bus_error *error) {
Image *image = ASSERT_PTR(userdata); Image *image = userdata;
Manager *m = ASSERT_PTR(image->userdata);
int r; int r;
if (!image->metadata_valid) { if (!image->metadata_valid) {
r = image_read_metadata(image, &image_policy_container, m->runtime_scope); r = image_read_metadata(image, &image_policy_container);
if (r < 0) if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m"); return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
} }
@ -356,12 +343,11 @@ int bus_image_method_get_os_release(
void *userdata, void *userdata,
sd_bus_error *error) { sd_bus_error *error) {
Image *image = ASSERT_PTR(userdata); Image *image = userdata;
Manager *m = ASSERT_PTR(image->userdata);
int r; int r;
if (!image->metadata_valid) { if (!image->metadata_valid) {
r = image_read_metadata(image, &image_policy_container, m->runtime_scope); r = image_read_metadata(image, &image_policy_container);
if (r < 0) if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m"); return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
} }

View File

@ -66,17 +66,15 @@ int vl_method_update_image(sd_varlink *link, sd_json_variant *parameters, sd_var
if (r < 0) if (r < 0)
return r; return r;
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
r = varlink_verify_polkit_async( r = varlink_verify_polkit_async(
link, link,
manager->system_bus, manager->bus,
"org.freedesktop.machine1.manage-images", "org.freedesktop.machine1.manage-images",
(const char**) STRV_MAKE("image", image->name, (const char**) STRV_MAKE("image", image->name,
"verb", "update"), "verb", "update"),
&manager->polkit_registry); &manager->polkit_registry);
if (r <= 0) if (r <= 0)
return r; return r;
}
if (p.new_name) { if (p.new_name) {
r = rename_image_and_update_cache(manager, image, p.new_name); r = rename_image_and_update_cache(manager, image, p.new_name);
@ -85,7 +83,7 @@ int vl_method_update_image(sd_varlink *link, sd_json_variant *parameters, sd_var
} }
if (p.read_only >= 0) { if (p.read_only >= 0) {
r = image_read_only(image, p.read_only, manager->runtime_scope); r = image_read_only(image, p.read_only);
if (r < 0) if (r < 0)
RET_GATHER(ret, log_debug_errno(r, "Failed to toggle image read only, ignoring: %m")); RET_GATHER(ret, log_debug_errno(r, "Failed to toggle image read only, ignoring: %m"));
} }
@ -141,10 +139,9 @@ int vl_method_clone_image(sd_varlink *link, sd_json_variant *parameters, sd_varl
if (r < 0) if (r < 0)
return r; return r;
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
r = varlink_verify_polkit_async( r = varlink_verify_polkit_async(
link, link,
manager->system_bus, manager->bus,
"org.freedesktop.machine1.manage-images", "org.freedesktop.machine1.manage-images",
(const char**) STRV_MAKE("image", image->name, (const char**) STRV_MAKE("image", image->name,
"verb", "clone", "verb", "clone",
@ -152,7 +149,6 @@ int vl_method_clone_image(sd_varlink *link, sd_json_variant *parameters, sd_varl
&manager->polkit_registry); &manager->polkit_registry);
if (r <= 0) if (r <= 0)
return r; return r;
}
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0) if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return log_debug_errno(errno, "Failed to open pipe: %m"); return log_debug_errno(errno, "Failed to open pipe: %m");
@ -211,17 +207,15 @@ int vl_method_remove_image(sd_varlink *link, sd_json_variant *parameters, sd_var
if (r < 0) if (r < 0)
return r; return r;
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
r = varlink_verify_polkit_async( r = varlink_verify_polkit_async(
link, link,
manager->system_bus, manager->bus,
"org.freedesktop.machine1.manage-images", "org.freedesktop.machine1.manage-images",
(const char**) STRV_MAKE("image", image->name, (const char**) STRV_MAKE("image", image->name,
"verb", "remove"), "verb", "remove"),
&manager->polkit_registry); &manager->polkit_registry);
if (r <= 0) if (r <= 0)
return r; return r;
}
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0) if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
return log_debug_errno(errno, "Failed to open pipe: %m"); return log_debug_errno(errno, "Failed to open pipe: %m");
@ -231,7 +225,7 @@ int vl_method_remove_image(sd_varlink *link, sd_json_variant *parameters, sd_var
return log_debug_errno(r, "Failed to fork: %m"); return log_debug_errno(r, "Failed to fork: %m");
if (r == 0) { if (r == 0) {
errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]); errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
r = image_remove(image, manager->runtime_scope); r = image_remove(image);
report_errno_and_exit(errno_pipe_fd[1], r); report_errno_and_exit(errno_pipe_fd[1], r);
} }
@ -268,23 +262,21 @@ int vl_method_set_pool_limit(sd_varlink *link, sd_json_variant *parameters, sd_v
if (!FILE_SIZE_VALID_OR_INFINITY(limit)) if (!FILE_SIZE_VALID_OR_INFINITY(limit))
return sd_varlink_error_invalid_parameter_name(link, "limit"); return sd_varlink_error_invalid_parameter_name(link, "limit");
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
r = varlink_verify_polkit_async( r = varlink_verify_polkit_async(
link, link,
manager->system_bus, manager->bus,
"org.freedesktop.machine1.manage-images", "org.freedesktop.machine1.manage-images",
(const char**) STRV_MAKE("verb", "set_pool_limit"), (const char**) STRV_MAKE("verb", "set_pool_limit"),
&manager->polkit_registry); &manager->polkit_registry);
if (r <= 0) if (r <= 0)
return r; return r;
}
/* Set up the machine directory if necessary */ /* Set up the machine directory if necessary */
r = setup_machine_directory(/* error = */ NULL, /* use_btrfs_subvol= */ true, /* use_btrfs_quota= */ true); r = setup_machine_directory(/* error = */ NULL, /* use_btrfs_subvol= */ true, /* use_btrfs_quota= */ true);
if (r < 0) if (r < 0)
return r; return r;
r = image_set_pool_limit(manager->runtime_scope, IMAGE_MACHINE, limit); r = image_set_pool_limit(IMAGE_MACHINE, limit);
if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
return sd_varlink_error(link, VARLINK_ERROR_MACHINE_IMAGE_NOT_SUPPORTED, NULL); return sd_varlink_error(link, VARLINK_ERROR_MACHINE_IMAGE_NOT_SUPPORTED, NULL);
if (r < 0) if (r < 0)
@ -402,17 +394,15 @@ int vl_method_clean_pool(sd_varlink *link, sd_json_variant *parameters, sd_varli
if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE)) if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL); return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL);
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
r = varlink_verify_polkit_async( r = varlink_verify_polkit_async(
link, link,
manager->system_bus, manager->bus,
"org.freedesktop.machine1.manage-images", "org.freedesktop.machine1.manage-images",
(const char**) STRV_MAKE("mode", image_clean_pool_mode_to_string(mode), (const char**) STRV_MAKE("mode", image_clean_pool_mode_to_string(mode),
"verb", "clean_pool"), "verb", "clean_pool"),
&manager->polkit_registry); &manager->polkit_registry);
if (r <= 0) if (r <= 0)
return r; return r;
}
Operation *op; Operation *op;
r = image_clean_pool_operation(manager, mode, &op); r = image_clean_pool_operation(manager, mode, &op);

View File

@ -143,7 +143,7 @@ int image_clean_pool_operation(Manager *manager, ImageCleanPoolMode mode, Operat
if (mode == IMAGE_CLEAN_POOL_REMOVE_HIDDEN && !image_is_hidden(image)) if (mode == IMAGE_CLEAN_POOL_REMOVE_HIDDEN && !image_is_hidden(image))
continue; continue;
r = image_remove(image, manager->runtime_scope); r = image_remove(image);
if (r == -EBUSY) { if (r == -EBUSY) {
log_debug("Keeping image '%s' because it's currently used.", image->name); log_debug("Keeping image '%s' because it's currently used.", image->name);
continue; continue;

View File

@ -55,7 +55,6 @@ int bus_machine_method_unregister(sd_bus_message *message, void *userdata, sd_bu
assert(message); assert(message);
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"machine", m->name, "machine", m->name,
"verb", "unregister", "verb", "unregister",
@ -74,7 +73,6 @@ int bus_machine_method_unregister(sd_bus_message *message, void *userdata, sd_bu
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
r = machine_finalize(m); r = machine_finalize(m);
if (r < 0) if (r < 0)
@ -89,7 +87,6 @@ int bus_machine_method_terminate(sd_bus_message *message, void *userdata, sd_bus
assert(message); assert(message);
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"machine", m->name, "machine", m->name,
"verb", "terminate", "verb", "terminate",
@ -108,7 +105,6 @@ int bus_machine_method_terminate(sd_bus_message *message, void *userdata, sd_bus
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
r = machine_stop(m); r = machine_stop(m);
if (r < 0) if (r < 0)
@ -141,7 +137,6 @@ int bus_machine_method_kill(sd_bus_message *message, void *userdata, sd_bus_erro
if (!SIGNAL_VALID(signo)) if (!SIGNAL_VALID(signo))
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo); return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"machine", m->name, "machine", m->name,
"verb", "kill", "verb", "kill",
@ -160,7 +155,6 @@ int bus_machine_method_kill(sd_bus_message *message, void *userdata, sd_bus_erro
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
r = machine_kill(m, whom, signo); r = machine_kill(m, whom, signo);
if (r < 0) if (r < 0)
@ -266,7 +260,6 @@ int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_
assert(message); assert(message);
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"machine", m->name, "machine", m->name,
NULL NULL
@ -284,7 +277,6 @@ int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name); master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name);
if (master < 0) if (master < 0)
@ -310,7 +302,6 @@ int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bu
assert(message); assert(message);
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"machine", m->name, "machine", m->name,
"verb", "login", "verb", "login",
@ -329,7 +320,6 @@ int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bu
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name); master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name);
if (master < 0) if (master < 0)
@ -355,6 +345,7 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
_cleanup_free_ char *pty_name = NULL; _cleanup_free_ char *pty_name = NULL;
_cleanup_close_ int master = -EBADF; _cleanup_close_ int master = -EBADF;
_cleanup_strv_free_ char **env = NULL, **args_wire = NULL, **args = NULL; _cleanup_strv_free_ char **env = NULL, **args_wire = NULL, **args = NULL;
_cleanup_free_ char *command_line = NULL;
Machine *m = ASSERT_PTR(userdata); Machine *m = ASSERT_PTR(userdata);
const char *user, *path; const char *user, *path;
int r; int r;
@ -411,11 +402,9 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
if (!strv_env_is_valid(env)) if (!strv_env_is_valid(env))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments"); return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) { command_line = strv_join(args, " ");
_cleanup_free_ char *command_line = strv_join(args, " ");
if (!command_line) if (!command_line)
return -ENOMEM; return -ENOMEM;
const char *details[] = { const char *details[] = {
"machine", m->name, "machine", m->name,
"user", user, "user", user,
@ -436,7 +425,6 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name); master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name);
if (master < 0) if (master < 0)
@ -482,7 +470,6 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
else if (!path_is_absolute(dest) || !path_is_normalized(dest)) else if (!path_is_absolute(dest) || !path_is_normalized(dest))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute and normalized."); return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute and normalized.");
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"machine", m->name, "machine", m->name,
"verb", "bind", "verb", "bind",
@ -502,7 +489,6 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
r = machine_get_uid_shift(m, &uid); r = machine_get_uid_shift(m, &uid);
if (r < 0) if (r < 0)
@ -570,7 +556,6 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
else if (!path_is_absolute(dest)) else if (!path_is_absolute(dest))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute."); return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute.");
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"machine", m->name, "machine", m->name,
"verb", "copy", "verb", "copy",
@ -590,7 +575,6 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
copy_from = strstr(sd_bus_message_get_member(message), "CopyFrom"); copy_from = strstr(sd_bus_message_get_member(message), "CopyFrom");
@ -618,7 +602,6 @@ int bus_machine_method_open_root_directory(sd_bus_message *message, void *userda
assert(message); assert(message);
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"machine", m->name, "machine", m->name,
"verb", "open_root_directory", "verb", "open_root_directory",
@ -636,7 +619,6 @@ int bus_machine_method_open_root_directory(sd_bus_message *message, void *userda
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
fd = machine_open_root_directory(m); fd = machine_open_root_directory(m);
if (ERRNO_IS_NEG_NOT_SUPPORTED(fd)) if (ERRNO_IS_NEG_NOT_SUPPORTED(fd))
@ -880,7 +862,7 @@ int machine_send_signal(Machine *m, bool new_machine) {
return -ENOMEM; return -ENOMEM;
return sd_bus_emit_signal( return sd_bus_emit_signal(
m->manager->api_bus, m->manager->bus,
"/org/freedesktop/machine1", "/org/freedesktop/machine1",
"org.freedesktop.machine1.Manager", "org.freedesktop.machine1.Manager",
new_machine ? "MachineNew" : "MachineRemoved", new_machine ? "MachineNew" : "MachineRemoved",

View File

@ -155,17 +155,15 @@ int vl_method_register(sd_varlink *link, sd_json_variant *parameters, sd_varlink
if (r != 0) if (r != 0)
return r; return r;
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
r = varlink_verify_polkit_async( r = varlink_verify_polkit_async(
link, link,
manager->system_bus, manager->bus,
machine->allocate_unit ? "org.freedesktop.machine1.create-machine" : "org.freedesktop.machine1.register-machine", machine->allocate_unit ? "org.freedesktop.machine1.create-machine" : "org.freedesktop.machine1.register-machine",
(const char**) STRV_MAKE("name", machine->name, (const char**) STRV_MAKE("name", machine->name,
"class", machine_class_to_string(machine->class)), "class", machine_class_to_string(machine->class)),
&manager->polkit_registry); &manager->polkit_registry);
if (r <= 0) if (r <= 0)
return r; return r;
}
if (!pidref_is_set(&machine->leader)) { if (!pidref_is_set(&machine->leader)) {
r = varlink_get_peer_pidref(link, &machine->leader); r = varlink_get_peer_pidref(link, &machine->leader);
@ -308,10 +306,9 @@ int vl_method_unregister_internal(sd_varlink *link, sd_json_variant *parameters,
Manager *manager = ASSERT_PTR(machine->manager); Manager *manager = ASSERT_PTR(machine->manager);
int r; int r;
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
r = varlink_verify_polkit_async_full( r = varlink_verify_polkit_async_full(
link, link,
manager->system_bus, manager->bus,
"org.freedesktop.machine1.manage-machines", "org.freedesktop.machine1.manage-machines",
(const char**) STRV_MAKE("name", machine->name, (const char**) STRV_MAKE("name", machine->name,
"verb", "unregister"), "verb", "unregister"),
@ -320,7 +317,6 @@ int vl_method_unregister_internal(sd_varlink *link, sd_json_variant *parameters,
&manager->polkit_registry); &manager->polkit_registry);
if (r <= 0) if (r <= 0)
return r; return r;
}
r = machine_finalize(machine); r = machine_finalize(machine);
if (r < 0) if (r < 0)
@ -334,10 +330,9 @@ int vl_method_terminate_internal(sd_varlink *link, sd_json_variant *parameters,
Manager *manager = ASSERT_PTR(machine->manager); Manager *manager = ASSERT_PTR(machine->manager);
int r; int r;
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
r = varlink_verify_polkit_async_full( r = varlink_verify_polkit_async_full(
link, link,
manager->system_bus, manager->bus,
"org.freedesktop.machine1.manage-machines", "org.freedesktop.machine1.manage-machines",
(const char**) STRV_MAKE("name", machine->name, (const char**) STRV_MAKE("name", machine->name,
"verb", "terminate"), "verb", "terminate"),
@ -346,7 +341,6 @@ int vl_method_terminate_internal(sd_varlink *link, sd_json_variant *parameters,
&manager->polkit_registry); &manager->polkit_registry);
if (r <= 0) if (r <= 0)
return r; return r;
}
r = machine_stop(machine); r = machine_stop(machine);
if (r < 0) if (r < 0)
@ -406,10 +400,9 @@ int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
return sd_varlink_error_invalid_parameter_name(link, "whom"); return sd_varlink_error_invalid_parameter_name(link, "whom");
} }
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
r = varlink_verify_polkit_async_full( r = varlink_verify_polkit_async_full(
link, link,
manager->system_bus, manager->bus,
"org.freedesktop.machine1.manage-machines", "org.freedesktop.machine1.manage-machines",
(const char**) STRV_MAKE("name", machine->name, (const char**) STRV_MAKE("name", machine->name,
"verb", "kill"), "verb", "kill"),
@ -418,7 +411,6 @@ int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
&manager->polkit_registry); &manager->polkit_registry);
if (r <= 0) if (r <= 0)
return r; return r;
}
r = machine_kill(machine, whom, p.signo); r = machine_kill(machine, whom, p.signo);
if (r < 0) if (r < 0)
@ -517,8 +509,8 @@ int vl_method_open(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
}; };
_cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL; _cleanup_(sd_json_variant_unrefp) sd_json_variant *v = NULL;
_cleanup_free_ char *ptmx_name = NULL, *command_line = NULL; _cleanup_free_ char *ptmx_name = NULL, *command_line = NULL;
_cleanup_strv_free_ char **polkit_details = NULL, **args = NULL;
const char *user = NULL, *path = NULL; /* gcc complains about uninitialized variables */ const char *user = NULL, *path = NULL; /* gcc complains about uninitialized variables */
_cleanup_strv_free_ char **args = NULL;
Machine *machine; Machine *machine;
int r, ptmx_fd_idx; int r, ptmx_fd_idx;
@ -551,13 +543,10 @@ int vl_method_open(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
if (r < 0) if (r < 0)
return r; return r;
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
_cleanup_strv_free_ char **polkit_details = NULL;
polkit_details = machine_open_polkit_details(p.mode, machine->name, user, path, command_line); polkit_details = machine_open_polkit_details(p.mode, machine->name, user, path, command_line);
r = varlink_verify_polkit_async_full( r = varlink_verify_polkit_async_full(
link, link,
manager->system_bus, manager->bus,
machine_open_polkit_action(p.mode, machine->class), machine_open_polkit_action(p.mode, machine->class),
(const char**) polkit_details, (const char**) polkit_details,
machine->uid, machine->uid,
@ -565,7 +554,6 @@ int vl_method_open(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
&manager->polkit_registry); &manager->polkit_registry);
if (r <= 0) if (r <= 0)
return r; return r;
}
ptmx_fd = machine_openpt(machine, O_RDWR|O_NOCTTY|O_CLOEXEC, &ptmx_name); ptmx_fd = machine_openpt(machine, O_RDWR|O_NOCTTY|O_CLOEXEC, &ptmx_name);
if (ERRNO_IS_NEG_NOT_SUPPORTED(ptmx_fd)) if (ERRNO_IS_NEG_NOT_SUPPORTED(ptmx_fd))
@ -836,11 +824,10 @@ int vl_method_bind_mount(sd_varlink *link, sd_json_variant *parameters, sd_varli
if (machine->class != MACHINE_CONTAINER) if (machine->class != MACHINE_CONTAINER)
return sd_varlink_error(link, VARLINK_ERROR_MACHINE_NOT_SUPPORTED, NULL); return sd_varlink_error(link, VARLINK_ERROR_MACHINE_NOT_SUPPORTED, NULL);
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
/* NB: For now not opened up to owner of machine without auth */ /* NB: For now not opened up to owner of machine without auth */
r = varlink_verify_polkit_async( r = varlink_verify_polkit_async(
link, link,
manager->system_bus, manager->bus,
"org.freedesktop.machine1.manage-machines", "org.freedesktop.machine1.manage-machines",
(const char**) STRV_MAKE("name", machine->name, (const char**) STRV_MAKE("name", machine->name,
"verb", "bind", "verb", "bind",
@ -849,7 +836,6 @@ int vl_method_bind_mount(sd_varlink *link, sd_json_variant *parameters, sd_varli
&manager->polkit_registry); &manager->polkit_registry);
if (r <= 0) if (r <= 0)
return r; return r;
}
r = machine_get_uid_shift(machine, &uid_shift); r = machine_get_uid_shift(machine, &uid_shift);
if (r < 0) if (r < 0)
@ -950,11 +936,10 @@ int vl_method_copy_internal(sd_varlink *link, sd_json_variant *parameters, sd_va
if (machine->class != MACHINE_CONTAINER) if (machine->class != MACHINE_CONTAINER)
return sd_varlink_error(link, VARLINK_ERROR_MACHINE_NOT_SUPPORTED, NULL); return sd_varlink_error(link, VARLINK_ERROR_MACHINE_NOT_SUPPORTED, NULL);
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
/* NB: For now not opened up to owner of machine without auth */ /* NB: For now not opened up to owner of machine without auth */
r = varlink_verify_polkit_async( r = varlink_verify_polkit_async(
link, link,
manager->system_bus, manager->bus,
"org.freedesktop.machine1.manage-machines", "org.freedesktop.machine1.manage-machines",
(const char**) STRV_MAKE("name", machine->name, (const char**) STRV_MAKE("name", machine->name,
"verb", "copy", "verb", "copy",
@ -963,7 +948,6 @@ int vl_method_copy_internal(sd_varlink *link, sd_json_variant *parameters, sd_va
&manager->polkit_registry); &manager->polkit_registry);
if (r <= 0) if (r <= 0)
return r; return r;
}
Operation *op; Operation *op;
r = machine_copy_from_to_operation(manager, machine, host_path, container_path, copy_from, copy_flags, &op); r = machine_copy_from_to_operation(manager, machine, host_path, container_path, copy_from, copy_flags, &op);
@ -983,17 +967,15 @@ int vl_method_open_root_directory_internal(sd_varlink *link, sd_json_variant *pa
int r; int r;
/* NB: For now not opened up to owner of machine without auth */ /* NB: For now not opened up to owner of machine without auth */
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
r = varlink_verify_polkit_async( r = varlink_verify_polkit_async(
link, link,
manager->system_bus, manager->bus,
"org.freedesktop.machine1.manage-machines", "org.freedesktop.machine1.manage-machines",
(const char**) STRV_MAKE("name", machine->name, (const char**) STRV_MAKE("name", machine->name,
"verb", "open_root_directory"), "verb", "open_root_directory"),
&manager->polkit_registry); &manager->polkit_registry);
if (r <= 0) if (r <= 0)
return r; return r;
}
fd = machine_open_root_directory(machine); fd = machine_open_root_directory(machine);
if (ERRNO_IS_NEG_NOT_SUPPORTED(fd)) if (ERRNO_IS_NEG_NOT_SUPPORTED(fd))

View File

@ -88,7 +88,7 @@ int machine_link(Manager *manager, Machine *machine) {
return -EINVAL; return -EINVAL;
if (machine->class != MACHINE_HOST) { if (machine->class != MACHINE_HOST) {
char *temp = path_join(manager->state_dir, machine->name); char *temp = path_join("/run/systemd/machines", machine->name);
if (!temp) if (!temp)
return -ENOMEM; return -ENOMEM;
@ -170,14 +170,14 @@ int machine_save(Machine *m) {
_cleanup_(unlink_and_freep) char *sl = NULL; /* auto-unlink! */ _cleanup_(unlink_and_freep) char *sl = NULL; /* auto-unlink! */
if (m->unit && !m->subgroup) { if (m->unit && !m->subgroup) {
sl = strjoin(m->manager->state_dir, "/unit:", m->unit); sl = strjoin("/run/systemd/machines/unit:", m->unit);
if (!sl) if (!sl)
return log_oom(); return log_oom();
} }
r = mkdir_safe_label(m->manager->state_dir, 0755, 0, 0, MKDIR_WARN_MODE); r = mkdir_safe_label("/run/systemd/machines", 0755, 0, 0, MKDIR_WARN_MODE);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to create '%s': %m", m->manager->state_dir); return log_error_errno(r, "Failed to create /run/systemd/machines/: %m");
_cleanup_(unlink_and_freep) char *temp_path = NULL; _cleanup_(unlink_and_freep) char *temp_path = NULL;
_cleanup_fclose_ FILE *f = NULL; _cleanup_fclose_ FILE *f = NULL;
@ -267,7 +267,7 @@ static void machine_unlink(Machine *m) {
assert(m); assert(m);
if (m->unit && !m->subgroup) { if (m->unit && !m->subgroup) {
const char *sl = strjoina(m->manager->state_dir, "/unit:", m->unit); const char *sl = strjoina("/run/systemd/machines/unit:", m->unit);
(void) unlink(sl); (void) unlink(sl);
} }
@ -438,7 +438,7 @@ static int machine_start_scope(
return log_oom(); return log_oom();
r = bus_message_new_method_call( r = bus_message_new_method_call(
machine->manager->api_bus, machine->manager->bus,
&m, &m,
bus_systemd_mgr, bus_systemd_mgr,
"StartTransientUnit"); "StartTransientUnit");
@ -920,7 +920,7 @@ int machine_start_getty(Machine *m, const char *ptmx_name, sd_bus_error *error)
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to create DBus to machine: %m"); return log_debug_errno(r, "Failed to create DBus to machine: %m");
container_bus = allocated_bus ?: m->manager->system_bus; container_bus = allocated_bus ?: m->manager->bus;
getty = strjoina("container-getty@", p, ".service"); getty = strjoina("container-getty@", p, ".service");
r = bus_call_method(container_bus, bus_systemd_mgr, "StartUnit", error, /* ret_reply = */ NULL, "ss", getty, "replace"); r = bus_call_method(container_bus, bus_systemd_mgr, "StartUnit", error, /* ret_reply = */ NULL, "ss", getty, "replace");
@ -966,7 +966,7 @@ int machine_start_shell(
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to create DBus to machine: %m"); return log_debug_errno(r, "Failed to create DBus to machine: %m");
container_bus = allocated_bus ?: m->manager->system_bus; container_bus = allocated_bus ?: m->manager->bus;
r = bus_message_new_method_call(container_bus, &tm, bus_systemd_mgr, "StartTransientUnit"); r = bus_message_new_method_call(container_bus, &tm, bus_systemd_mgr, "StartTransientUnit");
if (r < 0) if (r < 0)
return r; return r;

View File

@ -104,7 +104,6 @@ static const char* arg_format = NULL;
static const char *arg_uid = NULL; static const char *arg_uid = NULL;
static char **arg_setenv = NULL; static char **arg_setenv = NULL;
static unsigned arg_max_addresses = 1; static unsigned arg_max_addresses = 1;
static RuntimeScope arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
STATIC_DESTRUCTOR_REGISTER(arg_property, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_property, strv_freep);
STATIC_DESTRUCTOR_REGISTER(arg_setenv, strv_freep); STATIC_DESTRUCTOR_REGISTER(arg_setenv, strv_freep);
@ -2100,8 +2099,6 @@ static int help(int argc, char *argv[], void *userdata) {
" --no-ask-password Do not ask for system passwords\n" " --no-ask-password Do not ask for system passwords\n"
" -H --host=[USER@]HOST Operate on remote host\n" " -H --host=[USER@]HOST Operate on remote host\n"
" -M --machine=CONTAINER Operate on local container\n" " -M --machine=CONTAINER Operate on local container\n"
" --system Connect to system machine manager\n"
" --user Connect to user machine manager\n"
" -p --property=NAME Show only properties by this name\n" " -p --property=NAME Show only properties by this name\n"
" --value When showing properties, only print the value\n" " --value When showing properties, only print the value\n"
" -P NAME Equivalent to --value --property=NAME\n" " -P NAME Equivalent to --value --property=NAME\n"
@ -2155,8 +2152,6 @@ static int parse_argv(int argc, char *argv[]) {
ARG_FORMAT, ARG_FORMAT,
ARG_UID, ARG_UID,
ARG_MAX_ADDRESSES, ARG_MAX_ADDRESSES,
ARG_SYSTEM,
ARG_USER,
}; };
static const struct option options[] = { static const struct option options[] = {
@ -2186,8 +2181,6 @@ static int parse_argv(int argc, char *argv[]) {
{ "uid", required_argument, NULL, ARG_UID }, { "uid", required_argument, NULL, ARG_UID },
{ "setenv", required_argument, NULL, 'E' }, { "setenv", required_argument, NULL, 'E' },
{ "max-addresses", required_argument, NULL, ARG_MAX_ADDRESSES }, { "max-addresses", required_argument, NULL, ARG_MAX_ADDRESSES },
{ "user", no_argument, NULL, ARG_USER },
{ "system", no_argument, NULL, ARG_SYSTEM },
{} {}
}; };
@ -2411,14 +2404,6 @@ static int parse_argv(int argc, char *argv[]) {
"Invalid number of addresses: %s", optarg); "Invalid number of addresses: %s", optarg);
break; break;
case ARG_USER:
arg_runtime_scope = RUNTIME_SCOPE_USER;
break;
case ARG_SYSTEM:
arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
break;
case '?': case '?':
return -EINVAL; return -EINVAL;
@ -2503,9 +2488,9 @@ static int run(int argc, char *argv[]) {
"list-transfers", "cancel-transfer")) "list-transfers", "cancel-transfer"))
return chainload_importctl(argc, argv); return chainload_importctl(argc, argv);
r = bus_connect_transport(arg_transport, arg_host, arg_runtime_scope, &bus); r = bus_connect_transport(arg_transport, arg_host, RUNTIME_SCOPE_SYSTEM, &bus);
if (r < 0) if (r < 0)
return bus_log_connect_error(r, arg_transport, arg_runtime_scope); return bus_log_connect_error(r, arg_transport, RUNTIME_SCOPE_SYSTEM);
(void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password); (void) sd_bus_set_allow_interactive_authorization(bus, arg_ask_password);

View File

@ -278,7 +278,6 @@ static int machine_add_from_params(
return sd_bus_error_set(error, SD_BUS_ERROR_ACCESS_DENIED, "Only root may register machines for other users"); return sd_bus_error_set(error, SD_BUS_ERROR_ACCESS_DENIED, "Only root may register machines for other users");
} }
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"name", name, "name", name,
"class", machine_class_to_string(c), "class", machine_class_to_string(c),
@ -295,7 +294,6 @@ static int machine_add_from_params(
return r; return r;
if (r == 0) if (r == 0)
return 0; /* Will call us back */ return 0; /* Will call us back */
}
r = manager_add_machine(manager, name, &m); r = manager_add_machine(manager, name, &m);
if (r < 0) if (r < 0)
@ -699,18 +697,7 @@ static int method_register_machine(sd_bus_message *message, void *userdata, sd_b
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
switch (manager->runtime_scope) {
case RUNTIME_SCOPE_USER:
r = cg_pidref_get_user_unit_full(&m->leader, &m->unit, &m->subgroup);
break;
case RUNTIME_SCOPE_SYSTEM:
r = cg_pidref_get_unit_full(&m->leader, &m->unit, &m->subgroup); r = cg_pidref_get_unit_full(&m->leader, &m->unit, &m->subgroup);
break;
default:
assert_not_reached();
}
if (r < 0) { if (r < 0) {
r = sd_bus_error_set_errnof(error, r, r = sd_bus_error_set_errnof(error, r,
"Failed to determine unit of process "PID_FMT" : %m", "Failed to determine unit of process "PID_FMT" : %m",
@ -996,7 +983,6 @@ static int method_clean_pool(sd_bus_message *message, void *userdata, sd_bus_err
else else
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mode '%s'.", mm); return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unknown mode '%s'.", mm);
if (m->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"verb", "clean_pool", "verb", "clean_pool",
"mode", mm, "mode", mm,
@ -1013,7 +999,6 @@ static int method_clean_pool(sd_bus_message *message, void *userdata, sd_bus_err
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
r = image_clean_pool_operation(m, mode, &operation); r = image_clean_pool_operation(m, mode, &operation);
if (r < 0) if (r < 0)
@ -1037,7 +1022,6 @@ static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus
if (!FILE_SIZE_VALID_OR_INFINITY(limit)) if (!FILE_SIZE_VALID_OR_INFINITY(limit))
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "New limit out of range"); return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "New limit out of range");
if (m->runtime_scope != RUNTIME_SCOPE_USER) {
const char *details[] = { const char *details[] = {
"verb", "set_pool_limit", "verb", "set_pool_limit",
NULL NULL
@ -1053,14 +1037,13 @@ static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus
return r; return r;
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
}
/* Set up the machine directory if necessary */ /* Set up the machine directory if necessary */
r = setup_machine_directory(error, /* use_btrfs_subvol= */ true, /* use_btrfs_quota= */ true); r = setup_machine_directory(error, /* use_btrfs_subvol= */ true, /* use_btrfs_quota= */ true);
if (r < 0) if (r < 0)
return r; return r;
r = image_set_pool_limit(m->runtime_scope, IMAGE_MACHINE, limit); r = image_set_pool_limit(IMAGE_MACHINE, limit);
if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs."); return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs.");
if (r < 0) if (r < 0)
@ -1551,7 +1534,7 @@ int manager_unref_unit(
assert(m); assert(m);
assert(unit); assert(unit);
return bus_call_method(m->api_bus, bus_systemd_mgr, "UnrefUnit", error, NULL, "s", unit); return bus_call_method(m->bus, bus_systemd_mgr, "UnrefUnit", error, NULL, "s", unit);
} }
int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) { int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) {
@ -1561,7 +1544,7 @@ int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, c
assert(manager); assert(manager);
assert(unit); assert(unit);
r = bus_call_method(manager->api_bus, bus_systemd_mgr, "StopUnit", error, &reply, "ss", unit, "fail"); r = bus_call_method(manager->bus, bus_systemd_mgr, "StopUnit", error, &reply, "ss", unit, "fail");
if (r < 0) { if (r < 0) {
if (sd_bus_error_has_names(error, BUS_ERROR_NO_SUCH_UNIT, if (sd_bus_error_has_names(error, BUS_ERROR_NO_SUCH_UNIT,
BUS_ERROR_LOAD_FAILED)) { BUS_ERROR_LOAD_FAILED)) {
@ -1599,9 +1582,9 @@ int manager_kill_unit(Manager *manager, const char *unit, const char *subgroup,
assert(unit); assert(unit);
if (empty_or_root(subgroup)) if (empty_or_root(subgroup))
return bus_call_method(manager->api_bus, bus_systemd_mgr, "KillUnit", reterr_error, NULL, "ssi", unit, "all", signo); return bus_call_method(manager->bus, bus_systemd_mgr, "KillUnit", reterr_error, NULL, "ssi", unit, "all", signo);
return bus_call_method(manager->api_bus, bus_systemd_mgr, "KillUnitSubgroup", reterr_error, NULL, "sssi", unit, "cgroup", subgroup, signo); return bus_call_method(manager->bus, bus_systemd_mgr, "KillUnitSubgroup", reterr_error, NULL, "sssi", unit, "cgroup", subgroup, signo);
} }
int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *reterr_error) { int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *reterr_error) {
@ -1619,7 +1602,7 @@ int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *ret
return -ENOMEM; return -ENOMEM;
r = sd_bus_get_property( r = sd_bus_get_property(
manager->api_bus, manager->bus,
"org.freedesktop.systemd1", "org.freedesktop.systemd1",
path, path,
"org.freedesktop.systemd1.Unit", "org.freedesktop.systemd1.Unit",
@ -1655,7 +1638,7 @@ int manager_job_is_active(Manager *manager, const char *path, sd_bus_error *rete
assert(path); assert(path);
r = sd_bus_get_property( r = sd_bus_get_property(
manager->api_bus, manager->bus,
"org.freedesktop.systemd1", "org.freedesktop.systemd1",
path, path,
"org.freedesktop.systemd1.Job", "org.freedesktop.systemd1.Job",

View File

@ -18,7 +18,6 @@
#include "machine-varlink.h" #include "machine-varlink.h"
#include "machined.h" #include "machined.h"
#include "machined-varlink.h" #include "machined-varlink.h"
#include "path-lookup.h"
#include "string-util.h" #include "string-util.h"
#include "strv.h" #include "strv.h"
#include "user-util.h" #include "user-util.h"
@ -615,15 +614,14 @@ static int vl_method_open_root_directory(sd_varlink *link, sd_json_variant *para
return lookup_machine_and_call_method(link, parameters, flags, userdata, vl_method_open_root_directory_internal); return lookup_machine_and_call_method(link, parameters, flags, userdata, vl_method_open_root_directory_internal);
} }
static int list_image_one_and_maybe_read_metadata(Manager *m, sd_varlink *link, Image *image, bool more, AcquireMetadata am) { static int list_image_one_and_maybe_read_metadata(sd_varlink *link, Image *image, bool more, AcquireMetadata am) {
int r; int r;
assert(m);
assert(link); assert(link);
assert(image); assert(image);
if (should_acquire_metadata(am) && !image->metadata_valid) { if (should_acquire_metadata(am) && !image->metadata_valid) {
r = image_read_metadata(image, &image_policy_container, m->runtime_scope); r = image_read_metadata(image, &image_policy_container);
if (r < 0 && am != ACQUIRE_METADATA_GRACEFUL) if (r < 0 && am != ACQUIRE_METADATA_GRACEFUL)
return log_debug_errno(r, "Failed to read image metadata: %m"); return log_debug_errno(r, "Failed to read image metadata: %m");
if (r < 0) if (r < 0)
@ -699,7 +697,7 @@ static int vl_method_list_images(sd_varlink *link, sd_json_variant *parameters,
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to find image: %m"); return log_debug_errno(r, "Failed to find image: %m");
return list_image_one_and_maybe_read_metadata(m, link, found, /* more = */ false, p.acquire_metadata); return list_image_one_and_maybe_read_metadata(link, found, /* more = */ false, p.acquire_metadata);
} }
if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE)) if (!FLAGS_SET(flags, SD_VARLINK_METHOD_MORE))
@ -713,7 +711,7 @@ static int vl_method_list_images(sd_varlink *link, sd_json_variant *parameters,
Image *image, *previous = NULL; Image *image, *previous = NULL;
HASHMAP_FOREACH(image, images) { HASHMAP_FOREACH(image, images) {
if (previous) { if (previous) {
r = list_image_one_and_maybe_read_metadata(m, link, previous, /* more = */ true, p.acquire_metadata); r = list_image_one_and_maybe_read_metadata(link, previous, /* more = */ true, p.acquire_metadata);
if (r < 0) if (r < 0)
return r; return r;
} }
@ -722,7 +720,7 @@ static int vl_method_list_images(sd_varlink *link, sd_json_variant *parameters,
} }
if (previous) if (previous)
return list_image_one_and_maybe_read_metadata(m, link, previous, /* more = */ false, p.acquire_metadata); return list_image_one_and_maybe_read_metadata(link, previous, /* more = */ false, p.acquire_metadata);
return sd_varlink_error(link, VARLINK_ERROR_MACHINE_IMAGE_NO_SUCH_IMAGE, NULL); return sd_varlink_error(link, VARLINK_ERROR_MACHINE_IMAGE_NO_SUCH_IMAGE, NULL);
} }
@ -735,8 +733,6 @@ static int manager_varlink_init_userdb(Manager *m) {
if (m->varlink_userdb_server) if (m->varlink_userdb_server)
return 0; return 0;
if (m->runtime_scope != RUNTIME_SCOPE_SYSTEM) /* no userdb in per-user mode! */
return 0;
r = varlink_server_new(&s, SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA, m); r = varlink_server_new(&s, SD_VARLINK_SERVER_ACCOUNT_UID|SD_VARLINK_SERVER_INHERIT_USERDATA, m);
if (r < 0) if (r < 0)
@ -821,20 +817,11 @@ static int manager_varlink_init_machine(Manager *m) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to bind to passed Varlink sockets: %m"); return log_error_errno(r, "Failed to bind to passed Varlink sockets: %m");
if (r == 0) { if (r == 0) {
_cleanup_free_ char *socket_path = NULL; r = sd_varlink_server_listen_address(s, "/run/systemd/machine/io.systemd.Machine", 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
r = runtime_directory_generic(m->runtime_scope, "systemd/machine/io.systemd.Machine", &socket_path);
if (r < 0)
return log_error_errno(r, "Failed to determine socket path: %m");
r = sd_varlink_server_listen_address(s, socket_path, runtime_scope_to_socket_mode(m->runtime_scope) | SD_VARLINK_SERVER_MODE_MKDIR_0755);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to bind to io.systemd.Machine varlink socket: %m"); return log_error_errno(r, "Failed to bind to io.systemd.Machine varlink socket: %m");
socket_path = mfree(socket_path); r = sd_varlink_server_listen_address(s, "/run/systemd/machine/io.systemd.MachineImage", 0666);
r = runtime_directory_generic(m->runtime_scope, "systemd/machine/io.systemd.MachineImage", &socket_path);
if (r < 0)
return log_error_errno(r, "Failed to determine socket path: %m");
r = sd_varlink_server_listen_address(s, socket_path, runtime_scope_to_socket_mode(m->runtime_scope));
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to bind to io.systemd.MachineImage varlink socket: %m"); return log_error_errno(r, "Failed to bind to io.systemd.MachineImage varlink socket: %m");
} }

View File

@ -27,7 +27,6 @@
#include "main-func.h" #include "main-func.h"
#include "mkdir-label.h" #include "mkdir-label.h"
#include "operation.h" #include "operation.h"
#include "path-lookup.h"
#include "service-util.h" #include "service-util.h"
#include "signal-util.h" #include "signal-util.h"
#include "socket-util.h" #include "socket-util.h"
@ -39,7 +38,7 @@ DEFINE_TRIVIAL_CLEANUP_FUNC(Manager*, manager_unref);
DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(machine_hash_ops, char, string_hash_func, string_compare_func, Machine, machine_free); DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(machine_hash_ops, char, string_hash_func, string_compare_func, Machine, machine_free);
static int manager_new(RuntimeScope scope, Manager **ret) { static int manager_new(Manager **ret) {
_cleanup_(manager_unrefp) Manager *m = NULL; _cleanup_(manager_unrefp) Manager *m = NULL;
int r; int r;
@ -50,13 +49,9 @@ static int manager_new(RuntimeScope scope, Manager **ret) {
return -ENOMEM; return -ENOMEM;
*m = (Manager) { *m = (Manager) {
.runtime_scope = scope, .runtime_scope = RUNTIME_SCOPE_SYSTEM,
}; };
r = runtime_directory_generic(scope, "systemd/machines", &m->state_dir);
if (r < 0)
return r;
m->machines = hashmap_new(&machine_hash_ops); m->machines = hashmap_new(&machine_hash_ops);
if (!m->machines) if (!m->machines)
return -ENOMEM; return -ENOMEM;
@ -110,12 +105,9 @@ static Manager* manager_unref(Manager *m) {
manager_varlink_done(m); manager_varlink_done(m);
sd_bus_flush_close_unref(m->api_bus); sd_bus_flush_close_unref(m->bus);
sd_bus_flush_close_unref(m->system_bus);
sd_event_unref(m->event); sd_event_unref(m->event);
free(m->state_dir);
return mfree(m); return mfree(m);
} }
@ -126,8 +118,6 @@ static int manager_add_host_machine(Manager *m) {
Machine *t; Machine *t;
int r; int r;
if (m->runtime_scope != RUNTIME_SCOPE_SYSTEM)
return 0;
if (m->host_machine) if (m->host_machine)
return 0; return 0;
@ -184,12 +174,12 @@ static int manager_enumerate_machines(Manager *m) {
return r; return r;
/* Read in machine data stored on disk */ /* Read in machine data stored on disk */
d = opendir(m->state_dir); d = opendir("/run/systemd/machines");
if (!d) { if (!d) {
if (errno == ENOENT) if (errno == ENOENT)
return 0; return 0;
return log_error_errno(errno, "Failed to open '%s': %m", m->state_dir); return log_error_errno(errno, "Failed to open %s: %m", "/run/systemd/machines");
} }
FOREACH_DIRENT(de, d, return -errno) { FOREACH_DIRENT(de, d, return -errno) {
@ -224,45 +214,26 @@ static int manager_connect_bus(Manager *m) {
int r; int r;
assert(m); assert(m);
assert(!m->system_bus); assert(!m->bus);
assert(!m->api_bus);
r = sd_bus_default_system(&m->system_bus); r = sd_bus_default_system(&m->bus);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to connect to system bus: %m"); return log_error_errno(r, "Failed to connect to system bus: %m");
r = sd_bus_attach_event(m->system_bus, m->event, 0); r = bus_add_implementation(m->bus, &manager_object, m);
if (r < 0)
return log_error_errno(r, "Failed to attach system bus to event loop: %m");
if (m->runtime_scope == RUNTIME_SCOPE_SYSTEM)
m->api_bus = sd_bus_ref(m->system_bus);
else {
assert(m->runtime_scope == RUNTIME_SCOPE_USER);
r = sd_bus_default_user(&m->api_bus);
if (r < 0)
return log_error_errno(r, "Failed to connect to user bus: %m");
r = sd_bus_attach_event(m->api_bus, m->event, 0);
if (r < 0)
return log_error_errno(r, "Failed to attach user bus to event loop: %m");
}
r = bus_add_implementation(m->api_bus, &manager_object, m);
if (r < 0) if (r < 0)
return r; return r;
r = bus_match_signal_async(m->api_bus, NULL, bus_systemd_mgr, "JobRemoved", match_job_removed, NULL, m); r = bus_match_signal_async(m->bus, NULL, bus_systemd_mgr, "JobRemoved", match_job_removed, NULL, m);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to add match for JobRemoved: %m"); return log_error_errno(r, "Failed to add match for JobRemoved: %m");
r = bus_match_signal_async(m->api_bus, NULL, bus_systemd_mgr, "UnitRemoved", match_unit_removed, NULL, m); r = bus_match_signal_async(m->bus, NULL, bus_systemd_mgr, "UnitRemoved", match_unit_removed, NULL, m);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to request match for UnitRemoved: %m"); return log_error_errno(r, "Failed to request match for UnitRemoved: %m");
r = sd_bus_match_signal_async( r = sd_bus_match_signal_async(
m->api_bus, m->bus,
NULL, NULL,
"org.freedesktop.systemd1", "org.freedesktop.systemd1",
NULL, NULL,
@ -272,22 +243,26 @@ static int manager_connect_bus(Manager *m) {
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to request match for PropertiesChanged: %m"); return log_error_errno(r, "Failed to request match for PropertiesChanged: %m");
r = bus_match_signal_async(m->api_bus, NULL, bus_systemd_mgr, "Reloading", match_reloading, NULL, m); r = bus_match_signal_async(m->bus, NULL, bus_systemd_mgr, "Reloading", match_reloading, NULL, m);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to request match for Reloading: %m"); return log_error_errno(r, "Failed to request match for Reloading: %m");
r = bus_call_method_async(m->api_bus, NULL, bus_systemd_mgr, "Subscribe", NULL, NULL, NULL); r = bus_call_method_async(m->bus, NULL, bus_systemd_mgr, "Subscribe", NULL, NULL, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to enable subscription: %m"); return log_error_errno(r, "Failed to enable subscription: %m");
r = bus_log_control_api_register(m->api_bus); r = bus_log_control_api_register(m->bus);
if (r < 0) if (r < 0)
return r; return r;
r = sd_bus_request_name_async(m->api_bus, NULL, "org.freedesktop.machine1", 0, NULL, NULL); r = sd_bus_request_name_async(m->bus, NULL, "org.freedesktop.machine1", 0, NULL, NULL);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to request name: %m"); return log_error_errno(r, "Failed to request name: %m");
r = sd_bus_attach_event(m->bus, m->event, 0);
if (r < 0)
return log_error_errno(r, "Failed to attach bus to event loop: %m");
return 0; return 0;
} }
@ -340,7 +315,6 @@ static bool check_idle(void *userdata) {
static int run(int argc, char *argv[]) { static int run(int argc, char *argv[]) {
_cleanup_(manager_unrefp) Manager *m = NULL; _cleanup_(manager_unrefp) Manager *m = NULL;
RuntimeScope scope = RUNTIME_SCOPE_SYSTEM;
int r; int r;
log_set_facility(LOG_AUTH); log_set_facility(LOG_AUTH);
@ -350,7 +324,6 @@ static int run(int argc, char *argv[]) {
"Manage registrations of local VMs and containers.", "Manage registrations of local VMs and containers.",
BUS_IMPLEMENTATIONS(&manager_object, BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object), &log_control_object),
&scope,
argc, argv); argc, argv);
if (r <= 0) if (r <= 0)
return r; return r;
@ -360,12 +333,11 @@ static int run(int argc, char *argv[]) {
/* Always create the directories people can create inotify watches in. Note that some applications might check /* Always create the directories people can create inotify watches in. Note that some applications might check
* for the existence of /run/systemd/machines/ to determine whether machined is available, so please always * for the existence of /run/systemd/machines/ to determine whether machined is available, so please always
* make sure this check stays in. */ * make sure this check stays in. */
if (scope == RUNTIME_SCOPE_SYSTEM)
(void) mkdir_label("/run/systemd/machines", 0755); (void) mkdir_label("/run/systemd/machines", 0755);
assert_se(sigprocmask_many(SIG_BLOCK, /* ret_old_mask= */ NULL, SIGCHLD) >= 0); assert_se(sigprocmask_many(SIG_BLOCK, /* ret_old_mask= */ NULL, SIGCHLD) >= 0);
r = manager_new(scope, &m); r = manager_new(&m);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to allocate manager object: %m"); return log_error_errno(r, "Failed to allocate manager object: %m");
@ -379,7 +351,7 @@ static int run(int argc, char *argv[]) {
r = bus_event_loop_with_idle( r = bus_event_loop_with_idle(
m->event, m->event,
m->api_bus, m->bus,
"org.freedesktop.machine1", "org.freedesktop.machine1",
DEFAULT_EXIT_USEC, DEFAULT_EXIT_USEC,
check_idle, m); check_idle, m);

View File

@ -7,8 +7,7 @@
typedef struct Manager { typedef struct Manager {
sd_event *event; sd_event *event;
sd_bus *api_bus; /* this is where we offer our services */ sd_bus *bus;
sd_bus *system_bus; /* this is where we talk to system services on, for example PK or so */
Hashmap *machines; Hashmap *machines;
Hashmap *machines_by_unit; /* This hashmap only tracks machines where a system-level encapsulates Hashmap *machines_by_unit; /* This hashmap only tracks machines where a system-level encapsulates
@ -33,8 +32,7 @@ typedef struct Manager {
sd_varlink_server *varlink_userdb_server; sd_varlink_server *varlink_userdb_server;
sd_varlink_server *varlink_machine_server; sd_varlink_server *varlink_machine_server;
RuntimeScope runtime_scope; RuntimeScope runtime_scope; /* for now: always RUNTIME_SCOPE_SYSTEM */
char *state_dir;
} Manager; } Manager;
int manager_add_machine(Manager *m, const char *name, Machine **ret); int manager_add_machine(Manager *m, const char *name, Machine **ret);

View File

@ -49,8 +49,5 @@ install_data('org.freedesktop.machine1.conf',
install_dir : dbuspolicydir) install_dir : dbuspolicydir)
install_data('org.freedesktop.machine1.service', install_data('org.freedesktop.machine1.service',
install_dir : dbussystemservicedir) install_dir : dbussystemservicedir)
install_data('org.freedesktop.machine1.service-for-session',
install_dir : dbussessionservicedir,
rename : 'org.freedesktop.machine1.service')
install_data('org.freedesktop.machine1.policy', install_data('org.freedesktop.machine1.policy',
install_dir : polkitpolicydir) install_dir : polkitpolicydir)

View File

@ -1,13 +0,0 @@
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# This file is part of systemd.
#
# systemd is free software; you can redistribute it and/or modify it
# under the terms of the GNU Lesser General Public License as published by
# the Free Software Foundation; either version 2.1 of the License, or
# (at your option) any later version.
[D-BUS Service]
Name=org.freedesktop.machine1
Exec=/bin/false
SystemdService=dbus-org.freedesktop.machine1.service

View File

@ -5,7 +5,7 @@ executables += [
'name' : 'systemd-mount', 'name' : 'systemd-mount',
'public' : true, 'public' : true,
'sources' : files('mount-tool.c'), 'sources' : files('mount-tool.c'),
'dependencies' : libmount_cflags, 'dependencies' : libmount,
}, },
] ]

View File

@ -860,14 +860,14 @@ static int find_mount_points_by_source(const char *what, char ***ret) {
struct libmnt_fs *fs; struct libmnt_fs *fs;
const char *source, *target; const char *source, *target;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r == 1) if (r == 1)
break; break;
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
source = sym_mnt_fs_get_source(fs); source = mnt_fs_get_source(fs);
target = sym_mnt_fs_get_target(fs); target = mnt_fs_get_target(fs);
if (!source || !target) if (!source || !target)
continue; continue;

View File

@ -29,7 +29,6 @@ static int run(int argc, char *argv[]) {
r = service_parse_argv("systemd-networkd.service", r = service_parse_argv("systemd-networkd.service",
"Manage and configure network devices, create virtual network devices", "Manage and configure network devices, create virtual network devices",
BUS_IMPLEMENTATIONS(&manager_object, &log_control_object), BUS_IMPLEMENTATIONS(&manager_object, &log_control_object),
/* runtime_scope= */ NULL,
argc, argv); argc, argv);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -294,7 +294,6 @@ int register_machine(
return 0; return 0;
if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD)) if (!sd_bus_error_has_name(&error, SD_BUS_ERROR_UNKNOWN_METHOD))
return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r)); return log_error_errno(r, "Failed to register machine: %s", bus_error_message(&error, r));
sd_bus_error_free(&error);
if (FLAGS_SET(flags, REGISTER_MACHINE_KEEP_UNIT)) { if (FLAGS_SET(flags, REGISTER_MACHINE_KEEP_UNIT)) {
r = bus_call_method( r = bus_call_method(
bus, bus,

View File

@ -6055,7 +6055,6 @@ static int run(int argc, char *argv[]) {
/* We take an exclusive lock on this image, since it's our private, ephemeral copy /* We take an exclusive lock on this image, since it's our private, ephemeral copy
* only owned by us and no one else. */ * only owned by us and no one else. */
r = image_path_lock( r = image_path_lock(
arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER,
np, np,
LOCK_EX|LOCK_NB, LOCK_EX|LOCK_NB,
arg_privileged ? &tree_global_lock : NULL, arg_privileged ? &tree_global_lock : NULL,
@ -6092,7 +6091,6 @@ static int run(int argc, char *argv[]) {
goto finish; goto finish;
r = image_path_lock( r = image_path_lock(
arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER,
arg_directory, arg_directory,
(arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB, (arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB,
arg_privileged ? &tree_global_lock : NULL, arg_privileged ? &tree_global_lock : NULL,
@ -6220,7 +6218,6 @@ static int run(int argc, char *argv[]) {
/* Always take an exclusive lock on our own ephemeral copy. */ /* Always take an exclusive lock on our own ephemeral copy. */
r = image_path_lock( r = image_path_lock(
arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER,
np, np,
LOCK_EX|LOCK_NB, LOCK_EX|LOCK_NB,
arg_privileged ? &tree_global_lock : NULL, arg_privileged ? &tree_global_lock : NULL,
@ -6248,7 +6245,6 @@ static int run(int argc, char *argv[]) {
remove_image = true; remove_image = true;
} else { } else {
r = image_path_lock( r = image_path_lock(
arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER,
arg_image, arg_image,
(arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB, (arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB,
arg_privileged ? &tree_global_lock : NULL, arg_privileged ? &tree_global_lock : NULL,

View File

@ -61,7 +61,7 @@ int bus_image_common_get_os_release(
return 1; return 1;
if (!image->metadata_valid) { if (!image->metadata_valid) {
r = image_read_metadata(image, &image_policy_service, m->runtime_scope); r = image_read_metadata(image, &image_policy_service);
if (r < 0) if (r < 0)
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m"); return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
} }
@ -539,7 +539,7 @@ int bus_image_common_remove(
if (r == 0) { if (r == 0) {
errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]); errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
r = image_remove(image, m->runtime_scope); r = image_remove(image);
if (r < 0) { if (r < 0) {
(void) write(errno_pipe_fd[1], &r, sizeof(r)); (void) write(errno_pipe_fd[1], &r, sizeof(r));
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
@ -801,7 +801,7 @@ int bus_image_common_mark_read_only(
if (r == 0) if (r == 0)
return 1; /* Will call us back */ return 1; /* Will call us back */
r = image_read_only(image, read_only, m->runtime_scope); r = image_read_only(image, read_only);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -133,7 +133,6 @@ static int run(int argc, char *argv[]) {
"Manage registrations of portable images.", "Manage registrations of portable images.",
BUS_IMPLEMENTATIONS(&manager_object, BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object), &log_control_object),
/* runtime_scope= */ NULL,
argc, argv); argc, argv);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -4,6 +4,6 @@ executables += [
libexec_template + { libexec_template + {
'name' : 'systemd-remount-fs', 'name' : 'systemd-remount-fs',
'sources' : files('remount-fs.c'), 'sources' : files('remount-fs.c'),
'dependencies' : libmount_cflags, 'dependencies' : libmount,
}, },
] ]

View File

@ -90,13 +90,13 @@ static int remount_by_fstab(Hashmap **ret_pids) {
for (;;) { for (;;) {
struct libmnt_fs *fs; struct libmnt_fs *fs;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get next entry from fstab: %m"); return log_error_errno(r, "Failed to get next entry from fstab: %m");
if (r > 0) /* EOF */ if (r > 0) /* EOF */
break; break;
const char *target = sym_mnt_fs_get_target(fs); const char *target = mnt_fs_get_target(fs);
if (!target) if (!target)
continue; continue;

View File

@ -30,7 +30,6 @@ static int run(int argc, char *argv[]) {
"Provide name resolution with caching using DNS, mDNS, LLMNR.", "Provide name resolution with caching using DNS, mDNS, LLMNR.",
BUS_IMPLEMENTATIONS(&manager_object, BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object), &log_control_object),
/* runtime_scope= */ NULL,
argc, argv); argc, argv);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -19,7 +19,6 @@
#include "chase.h" #include "chase.h"
#include "chattr-util.h" #include "chattr-util.h"
#include "copy.h" #include "copy.h"
#include "devnum-util.h"
#include "dirent-util.h" #include "dirent-util.h"
#include "discover-image.h" #include "discover-image.h"
#include "dissect-image.h" #include "dissect-image.h"
@ -38,7 +37,6 @@
#include "mkdir.h" #include "mkdir.h"
#include "nulstr-util.h" #include "nulstr-util.h"
#include "os-util.h" #include "os-util.h"
#include "path-lookup.h"
#include "path-util.h" #include "path-util.h"
#include "rm-rf.h" #include "rm-rf.h"
#include "runtime-scope.h" #include "runtime-scope.h"
@ -121,15 +119,6 @@ static const char *const image_root_runtime_table[_IMAGE_CLASS_MAX] = {
DEFINE_STRING_TABLE_LOOKUP_TO_STRING(image_root_runtime, ImageClass); DEFINE_STRING_TABLE_LOOKUP_TO_STRING(image_root_runtime, ImageClass);
static const char *const image_dirname_table[_IMAGE_CLASS_MAX] = {
[IMAGE_MACHINE] = "machines",
[IMAGE_PORTABLE] = "portables",
[IMAGE_SYSEXT] = "extensions",
[IMAGE_CONFEXT] = "confexts",
};
DEFINE_PRIVATE_STRING_TABLE_LOOKUP_TO_STRING(image_dirname, ImageClass);
static Image* image_free(Image *i) { static Image* image_free(Image *i) {
assert(i); assert(i);
@ -149,7 +138,7 @@ DEFINE_TRIVIAL_REF_UNREF_FUNC(Image, image, image_free);
DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(image_hash_ops, char, string_hash_func, string_compare_func, DEFINE_HASH_OPS_WITH_VALUE_DESTRUCTOR(image_hash_ops, char, string_hash_func, string_compare_func,
Image, image_unref); Image, image_unref);
static char** image_settings_path(Image *image, RuntimeScope scope) { static char** image_settings_path(Image *image) {
_cleanup_strv_free_ char **l = NULL; _cleanup_strv_free_ char **l = NULL;
_cleanup_free_ char *fn = NULL; _cleanup_free_ char *fn = NULL;
size_t i = 0; size_t i = 0;
@ -157,7 +146,7 @@ static char** image_settings_path(Image *image, RuntimeScope scope) {
assert(image); assert(image);
l = new0(char*, 5); l = new0(char*, 4);
if (!l) if (!l)
return NULL; return NULL;
@ -165,41 +154,7 @@ static char** image_settings_path(Image *image, RuntimeScope scope) {
if (!fn) if (!fn)
return NULL; return NULL;
static const uint64_t system_locations[] = { FOREACH_STRING(s, "/etc/systemd/nspawn", "/run/systemd/nspawn") {
SD_PATH_SYSTEM_CONFIGURATION,
SD_PATH_SYSTEM_RUNTIME,
SD_PATH_SYSTEM_LIBRARY_PRIVATE,
UINT64_MAX
};
static const uint64_t user_locations[] = {
SD_PATH_USER_CONFIGURATION,
SD_PATH_USER_RUNTIME,
SD_PATH_USER_LIBRARY_PRIVATE,
UINT64_MAX
};
const uint64_t *locations;
switch (scope) {
case RUNTIME_SCOPE_SYSTEM:
locations = system_locations;
break;
case RUNTIME_SCOPE_USER:
locations = user_locations;
break;
default:
assert_not_reached();
}
for (size_t k = 0; locations[k] != UINT64_MAX; k++) {
_cleanup_free_ char *s = NULL;
r = sd_path_lookup(locations[k], "systemd/nspawn", &s);
if (r == -ENXIO)
continue;
if (r < 0)
return NULL;
l[i] = path_join(s, fn); l[i] = path_join(s, fn);
if (!l[i]) if (!l[i])
return NULL; return NULL;
@ -1131,7 +1086,7 @@ int image_discover(
return 0; return 0;
} }
int image_remove(Image *i, RuntimeScope scope) { int image_remove(Image *i) {
_cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT; _cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT;
_cleanup_strv_free_ char **settings = NULL; _cleanup_strv_free_ char **settings = NULL;
_cleanup_free_ char *roothash = NULL; _cleanup_free_ char *roothash = NULL;
@ -1142,7 +1097,7 @@ int image_remove(Image *i, RuntimeScope scope) {
if (image_is_vendor(i) || image_is_host(i)) if (image_is_vendor(i) || image_is_host(i))
return -EROFS; return -EROFS;
settings = image_settings_path(i, scope); settings = image_settings_path(i);
if (!settings) if (!settings)
return -ENOMEM; return -ENOMEM;
@ -1151,7 +1106,7 @@ int image_remove(Image *i, RuntimeScope scope) {
return r; return r;
/* Make sure we don't interfere with a running nspawn */ /* Make sure we don't interfere with a running nspawn */
r = image_path_lock(scope, i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock); r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
if (r < 0) if (r < 0)
return r; return r;
@ -1237,7 +1192,7 @@ int image_rename(Image *i, const char *new_name, RuntimeScope scope) {
if (image_is_vendor(i) || image_is_host(i)) if (image_is_vendor(i) || image_is_host(i))
return -EROFS; return -EROFS;
settings = image_settings_path(i, scope); settings = image_settings_path(i);
if (!settings) if (!settings)
return -ENOMEM; return -ENOMEM;
@ -1246,14 +1201,14 @@ int image_rename(Image *i, const char *new_name, RuntimeScope scope) {
return r; return r;
/* Make sure we don't interfere with a running nspawn */ /* Make sure we don't interfere with a running nspawn */
r = image_path_lock(scope, i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock); r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
if (r < 0) if (r < 0)
return r; return r;
/* Make sure nobody takes the new name, between the time we /* Make sure nobody takes the new name, between the time we
* checked it is currently unused in all search paths, and the * checked it is currently unused in all search paths, and the
* time we take possession of it */ * time we take possession of it */
r = image_name_lock(scope, new_name, LOCK_EX|LOCK_NB, &name_lock); r = image_name_lock(new_name, LOCK_EX|LOCK_NB, &name_lock);
if (r < 0) if (r < 0)
return r; return r;
@ -1344,64 +1299,11 @@ static int clone_auxiliary_file(const char *path, const char *new_name, const ch
return copy_file_atomic(path, rs, 0664, COPY_REFLINK); return copy_file_atomic(path, rs, 0664, COPY_REFLINK);
} }
static int get_pool_directory(
RuntimeScope scope,
ImageClass class,
const char *fname,
const char *suffix,
char **ret) {
int r;
assert(scope >= 0);
assert(scope < _RUNTIME_SCOPE_MAX);
assert(class >= 0);
assert(class < _IMAGE_CLASS_MAX);
assert(ret);
_cleanup_free_ char *root = NULL;
switch (scope) {
case RUNTIME_SCOPE_SYSTEM:
r = sd_path_lookup(SD_PATH_SYSTEM_STATE_PRIVATE, /* suffix= */ NULL, &root);
break;
case RUNTIME_SCOPE_USER:
r = sd_path_lookup(SD_PATH_USER_STATE_PRIVATE, /* suffix= */ NULL, &root);
break;
default:
return -EOPNOTSUPP;
}
if (r < 0)
return r;
const char *n = image_dirname_to_string(class);
if (!n)
return -EOPNOTSUPP;
_cleanup_free_ char *j = NULL;
const char *fn;
if (fname && suffix) {
j = strjoin(fname, suffix);
if (!j)
return -ENOMEM;
fn = j;
} else
fn = fname ?: suffix;
_cleanup_free_ char *p = path_join(root, n, fn);
if (!p)
return -ENOMEM;
*ret = TAKE_PTR(p);
return 0;
}
int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope scope) { int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope scope) {
_cleanup_(release_lock_file) LockFile name_lock = LOCK_FILE_INIT; _cleanup_(release_lock_file) LockFile name_lock = LOCK_FILE_INIT;
_cleanup_strv_free_ char **settings = NULL; _cleanup_strv_free_ char **settings = NULL;
_cleanup_free_ char *roothash = NULL; _cleanup_free_ char *roothash = NULL;
const char *new_path;
int r; int r;
assert(i); assert(i);
@ -1409,7 +1311,7 @@ int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope sco
if (!image_name_is_valid(new_name)) if (!image_name_is_valid(new_name))
return -EINVAL; return -EINVAL;
settings = image_settings_path(i, scope); settings = image_settings_path(i);
if (!settings) if (!settings)
return -ENOMEM; return -ENOMEM;
@ -1420,11 +1322,11 @@ int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope sco
/* Make sure nobody takes the new name, between the time we /* Make sure nobody takes the new name, between the time we
* checked it is currently unused in all search paths, and the * checked it is currently unused in all search paths, and the
* time we take possession of it */ * time we take possession of it */
r = image_name_lock(scope, new_name, LOCK_EX|LOCK_NB, &name_lock); r = image_name_lock(new_name, LOCK_EX|LOCK_NB, &name_lock);
if (r < 0) if (r < 0)
return r; return r;
r = image_find(scope, i->class, new_name, NULL, NULL); r = image_find(scope, IMAGE_MACHINE, new_name, NULL, NULL);
if (r >= 0) if (r >= 0)
return -EEXIST; return -EEXIST;
if (r != -ENOENT) if (r != -ENOENT)
@ -1433,14 +1335,11 @@ int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope sco
switch (i->type) { switch (i->type) {
case IMAGE_SUBVOLUME: case IMAGE_SUBVOLUME:
case IMAGE_DIRECTORY: { case IMAGE_DIRECTORY:
/* If we can we'll always try to create a new btrfs subvolume here, even if the source is a plain /* If we can we'll always try to create a new btrfs subvolume here, even if the source is a plain
* directory. */ * directory. */
_cleanup_free_ char *new_path = NULL; new_path = strjoina("/var/lib/machines/", new_name);
r = get_pool_directory(scope, i->class, new_name, /* suffix= */ NULL, &new_path);
if (r < 0)
return r;
r = btrfs_subvol_snapshot_at(AT_FDCWD, i->path, AT_FDCWD, new_path, r = btrfs_subvol_snapshot_at(AT_FDCWD, i->path, AT_FDCWD, new_path,
(read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) | (read_only ? BTRFS_SNAPSHOT_READ_ONLY : 0) |
@ -1454,23 +1353,19 @@ int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope sco
(void) btrfs_subvol_auto_qgroup(new_path, 0, true); (void) btrfs_subvol_auto_qgroup(new_path, 0, true);
break; break;
}
case IMAGE_RAW: { case IMAGE_RAW:
_cleanup_free_ char *new_path = NULL; new_path = strjoina("/var/lib/machines/", new_name, ".raw");
r = get_pool_directory(scope, i->class, new_name, ".raw", &new_path);
if (r < 0)
return r;
r = copy_file_atomic(i->path, new_path, read_only ? 0444 : 0644, r = copy_file_atomic(i->path, new_path, read_only ? 0444 : 0644,
COPY_REFLINK|COPY_CRTIME|COPY_NOCOW_AFTER); COPY_REFLINK|COPY_CRTIME|COPY_NOCOW_AFTER);
break; break;
}
case IMAGE_BLOCK: case IMAGE_BLOCK:
default: default:
return -EOPNOTSUPP; return -EOPNOTSUPP;
} }
if (r < 0) if (r < 0)
return r; return r;
@ -1487,7 +1382,7 @@ int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope sco
return 0; return 0;
} }
int image_read_only(Image *i, bool b, RuntimeScope scope) { int image_read_only(Image *i, bool b) {
_cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT; _cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT;
int r; int r;
@ -1497,7 +1392,7 @@ int image_read_only(Image *i, bool b, RuntimeScope scope) {
return -EROFS; return -EROFS;
/* Make sure we don't interfere with a running nspawn */ /* Make sure we don't interfere with a running nspawn */
r = image_path_lock(scope, i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock); r = image_path_lock(i->path, LOCK_EX|LOCK_NB, &global_lock, &local_lock);
if (r < 0) if (r < 0)
return r; return r;
@ -1574,33 +1469,12 @@ int image_read_only(Image *i, bool b, RuntimeScope scope) {
return 0; return 0;
} }
static int make_lock_dir(RuntimeScope scope) { static void make_lock_dir(void) {
int r; (void) mkdir_p("/run/systemd/nspawn", 0755);
(void) mkdir("/run/systemd/nspawn/locks", 0700);
_cleanup_free_ char *p = NULL;
r = runtime_directory_generic(scope, "systemd", &p);
if (r < 0)
return r;
_cleanup_close_ int pfd = open_mkdir_at(AT_FDCWD, p, O_CLOEXEC, 0755);
if (pfd < 0)
return pfd;
_cleanup_close_ int nfd = open_mkdir_at(pfd, "nspawn", O_CLOEXEC, 0755);
if (nfd < 0)
return nfd;
r = RET_NERRNO(mkdirat(nfd, "locks", 0700));
if (r == -EEXIST)
return 0;
if (r < 0)
return r;
return 1;
} }
int image_path_lock( int image_path_lock(
RuntimeScope scope,
const char *path, const char *path,
int operation, int operation,
LockFile *ret_global, LockFile *ret_global,
@ -1616,7 +1490,7 @@ int image_path_lock(
assert(ret_local); assert(ret_local);
/* Locks an image path. This actually creates two locks: one "local" one, next to the image path /* Locks an image path. This actually creates two locks: one "local" one, next to the image path
* itself, which might be shared via NFS. And another "global" one, in /run/, that uses the * itself, which might be shared via NFS. And another "global" one, in /run, that uses the
* device/inode number. This has the benefit that we can even lock a tree that is a mount point, * device/inode number. This has the benefit that we can even lock a tree that is a mount point,
* correctly. */ * correctly. */
@ -1660,21 +1534,15 @@ int image_path_lock(
} }
if (ret_global) { if (ret_global) {
if (stat(path, &st) < 0) if (stat(path, &st) >= 0) {
log_debug_errno(errno, "Failed to stat() image '%s', not locking image: %m", path);
else {
r = runtime_directory_generic(scope, "systemd/nspawn/locks/", &p);
if (r < 0)
return r;
if (S_ISBLK(st.st_mode)) if (S_ISBLK(st.st_mode))
r = strextendf(&p, "block-" DEVNUM_FORMAT_STR, DEVNUM_FORMAT_VAL(st.st_rdev)); r = asprintf(&p, "/run/systemd/nspawn/locks/block-%u:%u", major(st.st_rdev), minor(st.st_rdev));
else if (S_ISDIR(st.st_mode) || S_ISREG(st.st_mode)) else if (S_ISDIR(st.st_mode) || S_ISREG(st.st_mode))
r = strextendf(&p, "inode-%" PRIu64 ":%" PRIu64, (uint64_t) st.st_dev, (uint64_t) st.st_ino); r = asprintf(&p, "/run/systemd/nspawn/locks/inode-%lu:%lu", (unsigned long) st.st_dev, (unsigned long) st.st_ino);
else else
return -ENOTTY; return -ENOTTY;
if (r < 0) if (r < 0)
return r; return -ENOMEM;
} }
} }
@ -1683,15 +1551,15 @@ int image_path_lock(
if (!path_startswith(path, "/dev/")) { if (!path_startswith(path, "/dev/")) {
r = make_lock_file_for(path, operation, &t); r = make_lock_file_for(path, operation, &t);
if (r < 0) { if (r < 0) {
if (exclusive || r != -EROFS) if (!exclusive && r == -EROFS)
return r;
log_debug_errno(r, "Failed to create shared lock for '%s', ignoring: %m", path); log_debug_errno(r, "Failed to create shared lock for '%s', ignoring: %m", path);
else
return r;
} }
} }
if (p) { if (p) {
(void) make_lock_dir(scope); make_lock_dir();
r = make_lock_file(p, operation, ret_global); r = make_lock_file(p, operation, ret_global);
if (r < 0) { if (r < 0) {
@ -1731,39 +1599,36 @@ int image_set_limit(Image *i, uint64_t referenced_max) {
return 0; return 0;
} }
int image_set_pool_limit(RuntimeScope scope, ImageClass class, uint64_t referenced_max) { int image_set_pool_limit(ImageClass class, uint64_t referenced_max) {
const char *dir;
int r; int r;
assert(scope >= 0 && scope < _RUNTIME_SCOPE_MAX);
assert(class >= 0 && class < _IMAGE_CLASS_MAX); assert(class >= 0 && class < _IMAGE_CLASS_MAX);
_cleanup_free_ char *pool = NULL; dir = image_root_to_string(class);
r = get_pool_directory(scope, class, /* fname= */ NULL, /* suffix= */ NULL, &pool);
if (r < 0)
return r;
r = btrfs_qgroup_set_limit(pool, /* qgroupid = */ 0, referenced_max); r = btrfs_qgroup_set_limit(dir, /* qgroupid = */ 0, referenced_max);
if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
return r; return r;
if (r < 0) if (r < 0)
log_debug_errno(r, "Failed to set limit on btrfs quota group for '%s', ignoring: %m", pool); log_debug_errno(r, "Failed to set limit on btrfs quota group for '%s', ignoring: %m", dir);
r = btrfs_subvol_set_subtree_quota_limit(pool, /* subvol_id = */ 0, referenced_max); r = btrfs_subvol_set_subtree_quota_limit(dir, /* subvol_id = */ 0, referenced_max);
if (ERRNO_IS_NEG_NOT_SUPPORTED(r)) if (ERRNO_IS_NEG_NOT_SUPPORTED(r))
return r; return r;
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to set subtree quota limit for '%s': %m", pool); return log_debug_errno(r, "Failed to set subtree quota limit for '%s': %m", dir);
return 0; return 0;
} }
int image_read_metadata(Image *i, const ImagePolicy *image_policy, RuntimeScope scope) { int image_read_metadata(Image *i, const ImagePolicy *image_policy) {
_cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT; _cleanup_(release_lock_file) LockFile global_lock = LOCK_FILE_INIT, local_lock = LOCK_FILE_INIT;
int r; int r;
assert(i); assert(i);
r = image_path_lock(scope, i->path, LOCK_SH|LOCK_NB, &global_lock, &local_lock); r = image_path_lock(i->path, LOCK_SH|LOCK_NB, &global_lock, &local_lock);
if (r < 0) if (r < 0)
return r; return r;
@ -1893,13 +1758,8 @@ int image_read_metadata(Image *i, const ImagePolicy *image_policy, RuntimeScope
return 0; return 0;
} }
int image_name_lock( int image_name_lock(const char *name, int operation, LockFile *ret) {
RuntimeScope scope, const char *p;
const char *name,
int operation,
LockFile *ret) {
int r;
assert(name); assert(name);
assert(ret); assert(ret);
@ -1917,16 +1777,9 @@ int image_name_lock(
return 0; return 0;
} }
(void) make_lock_dir(scope); make_lock_dir();
_cleanup_free_ char *p = NULL;
r = runtime_directory_generic(scope, "systemd/nspawn/locks/name-", &p);
if (r < 0)
return r;
if (!strextend(&p, name))
return -ENOMEM;
p = strjoina("/run/systemd/nspawn/locks/name-", name);
return make_lock_file(p, operation, ret); return make_lock_file(p, operation, ret);
} }

View File

@ -55,21 +55,21 @@ int image_from_path(const char *path, Image **ret);
int image_find_harder(RuntimeScope scope, ImageClass class, const char *name_or_path, const char *root, Image **ret); int image_find_harder(RuntimeScope scope, ImageClass class, const char *name_or_path, const char *root, Image **ret);
int image_discover(RuntimeScope scope, ImageClass class, const char *root, Hashmap **images); int image_discover(RuntimeScope scope, ImageClass class, const char *root, Hashmap **images);
int image_remove(Image *i, RuntimeScope scope); int image_remove(Image *i);
int image_rename(Image *i, const char *new_name, RuntimeScope scope); int image_rename(Image *i, const char *new_name, RuntimeScope scope);
int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope scope); int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope scope);
int image_read_only(Image *i, bool b, RuntimeScope scope); int image_read_only(Image *i, bool b);
const char* image_type_to_string(ImageType t) _const_; const char* image_type_to_string(ImageType t) _const_;
ImageType image_type_from_string(const char *s) _pure_; ImageType image_type_from_string(const char *s) _pure_;
int image_path_lock(RuntimeScope scope, const char *path, int operation, LockFile *global, LockFile *local); int image_path_lock(const char *path, int operation, LockFile *global, LockFile *local);
int image_name_lock(RuntimeScope scope, const char *name, int operation, LockFile *ret); int image_name_lock(const char *name, int operation, LockFile *ret);
int image_set_limit(Image *i, uint64_t referenced_max); int image_set_limit(Image *i, uint64_t referenced_max);
int image_set_pool_limit(RuntimeScope scope, ImageClass class, uint64_t referenced_max); int image_set_pool_limit(ImageClass class, uint64_t referenced_max);
int image_read_metadata(Image *i, const ImagePolicy *image_policy, RuntimeScope scope); int image_read_metadata(Image *i, const ImagePolicy *image_policy);
bool image_in_search_path(RuntimeScope scope, ImageClass class, const char *root, const char *image); bool image_in_search_path(RuntimeScope scope, ImageClass class, const char *root, const char *image);

View File

@ -56,13 +56,13 @@ int fstab_has_fstype(const char *fstype) {
for (;;) { for (;;) {
struct libmnt_fs *fs; struct libmnt_fs *fs;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r < 0) if (r < 0)
return r; return r;
if (r > 0) /* EOF */ if (r > 0) /* EOF */
return false; return false;
if (streq_ptr(sym_mnt_fs_get_fstype(fs), fstype)) if (streq_ptr(mnt_fs_get_fstype(fs), fstype))
return true; return true;
} }
} }
@ -134,13 +134,13 @@ int fstab_has_mount_point_prefix_strv(char * const *prefixes) {
struct libmnt_fs *fs; struct libmnt_fs *fs;
const char *path; const char *path;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r < 0) if (r < 0)
return r; return r;
if (r > 0) /* EOF */ if (r > 0) /* EOF */
return false; return false;
path = sym_mnt_fs_get_target(fs); path = mnt_fs_get_target(fs);
if (!path) if (!path)
continue; continue;
@ -168,19 +168,19 @@ int fstab_is_mount_point_full(const char *where, const char *path) {
for (;;) { for (;;) {
struct libmnt_fs *fs; struct libmnt_fs *fs;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r < 0) if (r < 0)
return r; return r;
if (r > 0) /* EOF */ if (r > 0) /* EOF */
return false; return false;
if (where && !path_equal(sym_mnt_fs_get_target(fs), where)) if (where && !path_equal(mnt_fs_get_target(fs), where))
continue; continue;
if (!path) if (!path)
return true; return true;
r = fstab_is_same_node(sym_mnt_fs_get_source(fs), path); r = fstab_is_same_node(mnt_fs_get_source(fs), path);
if (r > 0 || (r < 0 && !ERRNO_IS_DEVICE_ABSENT(r))) if (r > 0 || (r < 0 && !ERRNO_IS_DEVICE_ABSENT(r)))
return r; return r;
} }

View File

@ -6,83 +6,6 @@
#include "libmount-util.h" #include "libmount-util.h"
#include "log.h" #include "log.h"
static void *libmount_dl = NULL;
DLSYM_PROTOTYPE(mnt_free_iter) = NULL;
DLSYM_PROTOTYPE(mnt_free_table) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_fs_options) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_fstype) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_id) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_option) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_options) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_passno) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_propagation) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_source) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_target) = NULL;
DLSYM_PROTOTYPE(mnt_fs_get_vfs_options) = NULL;
DLSYM_PROTOTYPE(mnt_get_builtin_optmap) = NULL;
DLSYM_PROTOTYPE(mnt_init_debug) = NULL;
DLSYM_PROTOTYPE(mnt_monitor_enable_kernel) = NULL;
DLSYM_PROTOTYPE(mnt_monitor_enable_userspace) = NULL;
DLSYM_PROTOTYPE(mnt_monitor_get_fd) = NULL;
DLSYM_PROTOTYPE(mnt_monitor_next_change) = NULL;
DLSYM_PROTOTYPE(mnt_new_iter) = NULL;
DLSYM_PROTOTYPE(mnt_new_monitor) = NULL;
DLSYM_PROTOTYPE(mnt_new_table) = NULL;
DLSYM_PROTOTYPE(mnt_optstr_get_flags) = NULL;
DLSYM_PROTOTYPE(mnt_table_find_devno) = NULL;
DLSYM_PROTOTYPE(mnt_table_find_target) = NULL;
DLSYM_PROTOTYPE(mnt_table_next_child_fs) = NULL;
DLSYM_PROTOTYPE(mnt_table_next_fs) = NULL;
DLSYM_PROTOTYPE(mnt_table_parse_file) = NULL;
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;
int dlopen_libmount(void) {
ELF_NOTE_DLOPEN("mount",
"Support for mount enumeration",
ELF_NOTE_DLOPEN_PRIORITY_RECOMMENDED,
"libmount.so.1");
return dlopen_many_sym_or_warn(
&libmount_dl,
"libmount.so.1",
LOG_DEBUG,
DLSYM_ARG(mnt_free_iter),
DLSYM_ARG(mnt_free_table),
DLSYM_ARG(mnt_fs_get_fs_options),
DLSYM_ARG(mnt_fs_get_fstype),
DLSYM_ARG(mnt_fs_get_id),
DLSYM_ARG(mnt_fs_get_option),
DLSYM_ARG(mnt_fs_get_options),
DLSYM_ARG(mnt_fs_get_passno),
DLSYM_ARG(mnt_fs_get_propagation),
DLSYM_ARG(mnt_fs_get_source),
DLSYM_ARG(mnt_fs_get_target),
DLSYM_ARG(mnt_fs_get_vfs_options),
DLSYM_ARG(mnt_get_builtin_optmap),
DLSYM_ARG(mnt_init_debug),
DLSYM_ARG(mnt_monitor_enable_kernel),
DLSYM_ARG(mnt_monitor_enable_userspace),
DLSYM_ARG(mnt_monitor_get_fd),
DLSYM_ARG(mnt_monitor_next_change),
DLSYM_ARG(mnt_new_iter),
DLSYM_ARG(mnt_new_monitor),
DLSYM_ARG(mnt_new_table),
DLSYM_ARG(mnt_optstr_get_flags),
DLSYM_ARG(mnt_table_find_devno),
DLSYM_ARG(mnt_table_find_target),
DLSYM_ARG(mnt_table_next_child_fs),
DLSYM_ARG(mnt_table_next_fs),
DLSYM_ARG(mnt_table_parse_file),
DLSYM_ARG(mnt_table_parse_mtab),
DLSYM_ARG(mnt_table_parse_stream),
DLSYM_ARG(mnt_table_parse_swaps),
DLSYM_ARG(mnt_unref_monitor));
}
int libmount_parse_full( int libmount_parse_full(
const char *path, const char *path,
FILE *source, FILE *source,
@ -96,12 +19,8 @@ int libmount_parse_full(
/* Older libmount seems to require this. */ /* Older libmount seems to require this. */
assert(!source || path); assert(!source || path);
r = dlopen_libmount(); table = mnt_new_table();
if (r < 0) iter = mnt_new_iter(MNT_ITER_FORWARD);
return r;
table = sym_mnt_new_table();
iter = sym_mnt_new_iter(MNT_ITER_FORWARD);
if (!table || !iter) if (!table || !iter)
return -ENOMEM; return -ENOMEM;
@ -109,11 +28,11 @@ int libmount_parse_full(
* Only if both are empty, we use mnt_table_parse_mtab(). */ * Only if both are empty, we use mnt_table_parse_mtab(). */
if (source) if (source)
r = sym_mnt_table_parse_stream(table, source, path); r = mnt_table_parse_stream(table, source, path);
else if (path) else if (path)
r = sym_mnt_table_parse_file(table, path); r = mnt_table_parse_file(table, path);
else else
r = sym_mnt_table_parse_mtab(table, NULL); r = mnt_table_parse_mtab(table, NULL);
if (r < 0) if (r < 0)
return r; return r;
@ -134,16 +53,14 @@ int libmount_is_leaf(
struct libmnt_fs *fs) { struct libmnt_fs *fs) {
int r; int r;
assert(table);
_cleanup_(mnt_free_iterp) struct libmnt_iter *iter_children = NULL; _cleanup_(mnt_free_iterp) struct libmnt_iter *iter_children = NULL;
iter_children = sym_mnt_new_iter(MNT_ITER_FORWARD); iter_children = mnt_new_iter(MNT_ITER_FORWARD);
if (!iter_children) if (!iter_children)
return log_oom(); return log_oom();
/* We care only whether it exists, it is unused */ /* We care only whether it exists, it is unused */
_unused_ struct libmnt_fs *child; _unused_ struct libmnt_fs *child;
r = sym_mnt_table_next_child_fs(table, iter_children, fs, &child); r = mnt_table_next_child_fs(table, iter_children, fs, &child);
if (r < 0) if (r < 0)
return r; return r;

View File

@ -4,45 +4,10 @@
/* This needs to be after sys/mount.h */ /* This needs to be after sys/mount.h */
#include <libmount.h> /* IWYU pragma: export */ #include <libmount.h> /* IWYU pragma: export */
#include "dlfcn-util.h"
#include "forward.h" #include "forward.h"
extern DLSYM_PROTOTYPE(mnt_free_iter); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct libmnt_table*, mnt_free_table, NULL);
extern DLSYM_PROTOTYPE(mnt_free_table); DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct libmnt_iter*, mnt_free_iter, NULL);
extern DLSYM_PROTOTYPE(mnt_fs_get_fs_options);
extern DLSYM_PROTOTYPE(mnt_fs_get_fstype);
extern DLSYM_PROTOTYPE(mnt_fs_get_id);
extern DLSYM_PROTOTYPE(mnt_fs_get_option);
extern DLSYM_PROTOTYPE(mnt_fs_get_options);
extern DLSYM_PROTOTYPE(mnt_fs_get_passno);
extern DLSYM_PROTOTYPE(mnt_fs_get_propagation);
extern DLSYM_PROTOTYPE(mnt_fs_get_source);
extern DLSYM_PROTOTYPE(mnt_fs_get_target);
extern DLSYM_PROTOTYPE(mnt_fs_get_vfs_options);
extern DLSYM_PROTOTYPE(mnt_get_builtin_optmap);
extern DLSYM_PROTOTYPE(mnt_init_debug);
extern DLSYM_PROTOTYPE(mnt_monitor_enable_kernel);
extern DLSYM_PROTOTYPE(mnt_monitor_enable_userspace);
extern DLSYM_PROTOTYPE(mnt_monitor_get_fd);
extern DLSYM_PROTOTYPE(mnt_monitor_next_change);
extern DLSYM_PROTOTYPE(mnt_new_iter);
extern DLSYM_PROTOTYPE(mnt_new_monitor);
extern DLSYM_PROTOTYPE(mnt_new_table);
extern DLSYM_PROTOTYPE(mnt_optstr_get_flags);
extern DLSYM_PROTOTYPE(mnt_table_find_devno);
extern DLSYM_PROTOTYPE(mnt_table_find_target);
extern DLSYM_PROTOTYPE(mnt_table_next_child_fs);
extern DLSYM_PROTOTYPE(mnt_table_next_fs);
extern DLSYM_PROTOTYPE(mnt_table_parse_file);
extern DLSYM_PROTOTYPE(mnt_table_parse_mtab);
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);
int libmount_parse_full( int libmount_parse_full(
const char *path, const char *path,

View File

@ -322,7 +322,7 @@ libshared_deps = [threads,
libgcrypt_cflags, libgcrypt_cflags,
libkmod_cflags, libkmod_cflags,
liblz4_cflags, liblz4_cflags,
libmount_cflags, libmount,
libopenssl, libopenssl,
libp11kit_cflags, libp11kit_cflags,
libpam_cflags, libpam_cflags,

View File

@ -60,13 +60,13 @@ int umount_recursive_full(const char *prefix, int flags, char **keep) {
struct libmnt_fs *fs; struct libmnt_fs *fs;
const char *path; const char *path;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r == 1) if (r == 1)
break; break;
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
path = sym_mnt_fs_get_target(fs); path = mnt_fs_get_target(fs);
if (!path) if (!path)
continue; continue;
@ -247,20 +247,20 @@ int bind_remount_recursive_with_mountinfo(
unsigned long flags = 0; unsigned long flags = 0;
struct libmnt_fs *fs; struct libmnt_fs *fs;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r == 1) /* EOF */ if (r == 1) /* EOF */
break; break;
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
path = sym_mnt_fs_get_target(fs); path = mnt_fs_get_target(fs);
if (!path) if (!path)
continue; continue;
if (!path_startswith(path, prefix)) if (!path_startswith(path, prefix))
continue; continue;
type = sym_mnt_fs_get_fstype(fs); type = mnt_fs_get_fstype(fs);
if (!type) if (!type)
continue; continue;
@ -298,9 +298,9 @@ int bind_remount_recursive_with_mountinfo(
continue; continue;
} }
opts = sym_mnt_fs_get_vfs_options(fs); opts = mnt_fs_get_vfs_options(fs);
if (opts) { if (opts) {
r = sym_mnt_optstr_get_flags(opts, &flags, sym_mnt_get_builtin_optmap(MNT_LINUX_MAP)); r = mnt_optstr_get_flags(opts, &flags, mnt_get_builtin_optmap(MNT_LINUX_MAP));
if (r < 0) if (r < 0)
log_debug_errno(r, "Could not get flags for '%s', ignoring: %m", path); log_debug_errno(r, "Could not get flags for '%s', ignoring: %m", path);
} }
@ -438,19 +438,15 @@ int bind_remount_one_with_mountinfo(
rewind(proc_self_mountinfo); rewind(proc_self_mountinfo);
r = dlopen_libmount(); table = mnt_new_table();
if (r < 0)
return r;
table = sym_mnt_new_table();
if (!table) if (!table)
return -ENOMEM; return -ENOMEM;
r = sym_mnt_table_parse_stream(table, proc_self_mountinfo, "/proc/self/mountinfo"); r = mnt_table_parse_stream(table, proc_self_mountinfo, "/proc/self/mountinfo");
if (r < 0) if (r < 0)
return r; return r;
fs = sym_mnt_table_find_target(table, path, MNT_ITER_FORWARD); fs = mnt_table_find_target(table, path, MNT_ITER_FORWARD);
if (!fs) { if (!fs) {
r = access_nofollow(path, F_OK); /* Hmm, it's not in the mount table, but does it exist at all? */ r = access_nofollow(path, F_OK); /* Hmm, it's not in the mount table, but does it exist at all? */
if (r < 0) if (r < 0)
@ -459,9 +455,9 @@ int bind_remount_one_with_mountinfo(
return -EINVAL; /* Not a mount point we recognize */ return -EINVAL; /* Not a mount point we recognize */
} }
opts = sym_mnt_fs_get_vfs_options(fs); opts = mnt_fs_get_vfs_options(fs);
if (opts) { if (opts) {
r = sym_mnt_optstr_get_flags(opts, &flags, sym_mnt_get_builtin_optmap(MNT_LINUX_MAP)); r = mnt_optstr_get_flags(opts, &flags, mnt_get_builtin_optmap(MNT_LINUX_MAP));
if (r < 0) if (r < 0)
log_debug_errno(r, "Could not get flags for '%s', ignoring: %m", path); log_debug_errno(r, "Could not get flags for '%s', ignoring: %m", path);
} }
@ -877,11 +873,7 @@ int mount_option_mangle(
assert(ret_mount_flags); assert(ret_mount_flags);
assert(ret_remaining_options); assert(ret_remaining_options);
r = dlopen_libmount(); map = mnt_get_builtin_optmap(MNT_LINUX_MAP);
if (r < 0)
return r;
map = sym_mnt_get_builtin_optmap(MNT_LINUX_MAP);
if (!map) if (!map)
return -EINVAL; return -EINVAL;
@ -1645,20 +1637,20 @@ int get_sub_mounts(const char *prefix, SubMount **ret_mounts, size_t *ret_n_moun
const char *path; const char *path;
int id1, id2; int id1, id2;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r == 1) if (r == 1)
break; /* EOF */ break; /* EOF */
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
path = sym_mnt_fs_get_target(fs); path = mnt_fs_get_target(fs);
if (!path) if (!path)
continue; continue;
if (isempty(path_startswith(path, prefix))) if (isempty(path_startswith(path, prefix)))
continue; continue;
id1 = sym_mnt_fs_get_id(fs); id1 = mnt_fs_get_id(fs);
r = path_get_mnt_id(path, &id2); r = path_get_mnt_id(path, &id2);
if (r < 0) { if (r < 0) {
log_debug_errno(r, "Failed to get mount ID of '%s', ignoring: %m", path); log_debug_errno(r, "Failed to get mount ID of '%s', ignoring: %m", path);
@ -1990,31 +1982,31 @@ int path_get_mount_info_at(
for (;;) { for (;;) {
struct libmnt_fs *fs; struct libmnt_fs *fs;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r == 1) if (r == 1)
break; /* EOF */ break; /* EOF */
if (r < 0) if (r < 0)
return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
if (sym_mnt_fs_get_id(fs) != mnt_id) if (mnt_fs_get_id(fs) != mnt_id)
continue; continue;
_cleanup_free_ char *fstype = NULL, *options = NULL, *source = NULL; _cleanup_free_ char *fstype = NULL, *options = NULL, *source = NULL;
if (ret_fstype) { if (ret_fstype) {
fstype = strdup(strempty(sym_mnt_fs_get_fstype(fs))); fstype = strdup(strempty(mnt_fs_get_fstype(fs)));
if (!fstype) if (!fstype)
return log_oom_debug(); return log_oom_debug();
} }
if (ret_options) { if (ret_options) {
options = strdup(strempty(sym_mnt_fs_get_options(fs))); options = strdup(strempty(mnt_fs_get_options(fs)));
if (!options) if (!options)
return log_oom_debug(); return log_oom_debug();
} }
if (ret_source) { if (ret_source) {
source = strdup(strempty(sym_mnt_fs_get_source(fs))); source = strdup(strempty(mnt_fs_get_source(fs)));
if (!source) if (!source)
return log_oom_debug(); return log_oom_debug();
} }

View File

@ -8,19 +8,9 @@
#include "bus-object.h" #include "bus-object.h"
#include "log.h" #include "log.h"
#include "pretty-print.h" #include "pretty-print.h"
#include "runtime-scope.h"
#include "service-util.h" #include "service-util.h"
typedef enum HelpFlags { static int help(const char *program_path, const char *service, const char *description, bool bus_introspect) {
HELP_WITH_BUS_INTROSPECT = 1 << 0,
HELP_WITH_RUNTIME_SCOPE = 1 << 1,
} HelpFlags;
static int help(const char *program_path,
const char *service,
const char *description,
HelpFlags flags) {
_cleanup_free_ char *link = NULL; _cleanup_free_ char *link = NULL;
int r; int r;
@ -35,7 +25,6 @@ static int help(const char *program_path,
" -h --help Show this help\n" " -h --help Show this help\n"
" --version Show package version\n" " --version Show package version\n"
"%8$s" "%8$s"
"%9$s"
"\nSee the %2$s for details.\n", "\nSee the %2$s for details.\n",
program_path, program_path,
link, link,
@ -44,9 +33,7 @@ static int help(const char *program_path,
ansi_highlight(), ansi_highlight(),
ansi_normal(), ansi_normal(),
description, description,
FLAGS_SET(flags, HELP_WITH_BUS_INTROSPECT) ? " --bus-introspect=PATH Write D-Bus XML introspection data\n" : "", bus_introspect ? " --bus-introspect=PATH Write D-Bus XML introspection data\n" : "");
FLAGS_SET(flags, HELP_WITH_RUNTIME_SCOPE) ? " --system Start service in system mode\n"
" --user Start service in user mode\n" : "");
return 0; /* No further action */ return 0; /* No further action */
} }
@ -55,22 +42,17 @@ int service_parse_argv(
const char *service, const char *service,
const char *description, const char *description,
const BusObjectImplementation* const* bus_objects, const BusObjectImplementation* const* bus_objects,
RuntimeScope *runtime_scope,
int argc, char *argv[]) { int argc, char *argv[]) {
enum { enum {
ARG_VERSION = 0x100, ARG_VERSION = 0x100,
ARG_BUS_INTROSPECT, ARG_BUS_INTROSPECT,
ARG_SYSTEM,
ARG_USER,
}; };
static const struct option options[] = { static const struct option options[] = {
{ "help", no_argument, NULL, 'h' }, { "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION }, { "version", no_argument, NULL, ARG_VERSION },
{ "bus-introspect", required_argument, NULL, ARG_BUS_INTROSPECT }, { "bus-introspect", required_argument, NULL, ARG_BUS_INTROSPECT },
{ "system", no_argument, NULL, ARG_SYSTEM },
{ "user", no_argument, NULL, ARG_USER },
{} {}
}; };
@ -83,11 +65,7 @@ int service_parse_argv(
switch (c) { switch (c) {
case 'h': case 'h':
return help(argv[0], return help(argv[0], service, description, bus_objects);
service,
description,
(bus_objects ? HELP_WITH_BUS_INTROSPECT : 0) |
(runtime_scope ? HELP_WITH_RUNTIME_SCOPE : 0));
case ARG_VERSION: case ARG_VERSION:
return version(); return version();
@ -98,14 +76,6 @@ int service_parse_argv(
optarg, optarg,
bus_objects); bus_objects);
case ARG_SYSTEM:
case ARG_USER:
if (!runtime_scope)
return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "This service cannot be run in --system or --user mode, refusing.");
*runtime_scope = c == ARG_SYSTEM ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER;
break;
case '?': case '?':
return -EINVAL; return -EINVAL;

View File

@ -7,5 +7,4 @@ int service_parse_argv(
const char *service, const char *service,
const char *description, const char *description,
const BusObjectImplementation* const* bus_objects, const BusObjectImplementation* const* bus_objects,
RuntimeScope *runtime_scope,
int argc, char *argv[]); int argc, char *argv[]);

View File

@ -36,16 +36,12 @@ int swap_list_get(const char *swaps, SwapDevice **head) {
assert(head); assert(head);
r = dlopen_libmount(); t = mnt_new_table();
if (r < 0) i = mnt_new_iter(MNT_ITER_FORWARD);
return log_error_errno(r, "Cannot enumerate swap partitions, no libmount support.");
t = sym_mnt_new_table();
i = sym_mnt_new_iter(MNT_ITER_FORWARD);
if (!t || !i) if (!t || !i)
return log_oom(); return log_oom();
r = sym_mnt_table_parse_swaps(t, swaps); r = mnt_table_parse_swaps(t, swaps);
if (r == -ENOENT) /* no /proc/swaps is fine */ if (r == -ENOENT) /* no /proc/swaps is fine */
return 0; return 0;
if (r < 0) if (r < 0)
@ -56,13 +52,13 @@ int swap_list_get(const char *swaps, SwapDevice **head) {
_cleanup_free_ SwapDevice *swap = NULL; _cleanup_free_ SwapDevice *swap = NULL;
const char *source; const char *source;
r = sym_mnt_table_next_fs(t, i, &fs); r = mnt_table_next_fs(t, i, &fs);
if (r == 1) /* EOF */ if (r == 1) /* EOF */
break; break;
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get next entry from %s: %m", swaps ?: "/proc/swaps"); return log_error_errno(r, "Failed to get next entry from %s: %m", swaps ?: "/proc/swaps");
source = sym_mnt_fs_get_source(fs); source = mnt_fs_get_source(fs);
if (!source) if (!source)
continue; continue;

View File

@ -16,7 +16,7 @@ executables += [
'name' : 'systemd-shutdown', 'name' : 'systemd-shutdown',
'sources' : systemd_shutdown_sources + systemd_shutdown_extract_sources, 'sources' : systemd_shutdown_sources + systemd_shutdown_extract_sources,
'extract' : systemd_shutdown_extract_sources, 'extract' : systemd_shutdown_extract_sources,
'dependencies' : libmount_cflags, 'dependencies' : libmount,
}, },
libexec_template + { libexec_template + {
'name' : 'systemd-shutdown.standalone', 'name' : 'systemd-shutdown.standalone',
@ -28,11 +28,11 @@ executables += [
libshared_static, libshared_static,
libsystemd_static, libsystemd_static,
], ],
'dependencies' : libmount_cflags, 'dependencies' : libmount,
}, },
test_template + { test_template + {
'sources' : files('test-umount.c'), 'sources' : files('test-umount.c'),
'objects' : ['systemd-shutdown'], 'objects' : ['systemd-shutdown'],
'dependencies' : libmount_cflags, 'dependencies' : libmount,
}, },
] ]

View File

@ -69,17 +69,17 @@ int mount_points_list_get(FILE *f, MountPoint **head) {
bool try_remount_ro, is_api_vfs, is_network; bool try_remount_ro, is_api_vfs, is_network;
_cleanup_free_ MountPoint *m = NULL; _cleanup_free_ MountPoint *m = NULL;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r == 1) /* EOF */ if (r == 1) /* EOF */
break; break;
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m"); return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
path = sym_mnt_fs_get_target(fs); path = mnt_fs_get_target(fs);
if (!path) if (!path)
continue; continue;
fstype = sym_mnt_fs_get_fstype(fs); fstype = mnt_fs_get_fstype(fs);
/* Combine the generic VFS options with the FS-specific options. Duplicates are not a problem /* Combine the generic VFS options with the FS-specific options. Duplicates are not a problem
* here, because the only options that should come up twice are typically ro/rw, which are * here, because the only options that should come up twice are typically ro/rw, which are
@ -87,9 +87,9 @@ int mount_points_list_get(FILE *f, MountPoint **head) {
* *
* Even if there are duplicates later in mount_option_mangle() they shouldn't hurt anyways as * Even if there are duplicates later in mount_option_mangle() they shouldn't hurt anyways as
* they override each other. */ * they override each other. */
if (!strextend_with_separator(&options, ",", sym_mnt_fs_get_vfs_options(fs))) if (!strextend_with_separator(&options, ",", mnt_fs_get_vfs_options(fs)))
return log_oom(); return log_oom();
if (!strextend_with_separator(&options, ",", sym_mnt_fs_get_fs_options(fs))) if (!strextend_with_separator(&options, ",", mnt_fs_get_fs_options(fs)))
return log_oom(); return log_oom();
/* Ignore mount points we can't unmount because they are API or because we are keeping them /* Ignore mount points we can't unmount because they are API or because we are keeping them
@ -122,7 +122,7 @@ int mount_points_list_get(FILE *f, MountPoint **head) {
* were when the filesystem was mounted, except for the desired changes. So we * were when the filesystem was mounted, except for the desired changes. So we
* reconstruct both here and adjust them for the later remount call too. */ * reconstruct both here and adjust them for the later remount call too. */
r = sym_mnt_fs_get_propagation(fs, &remount_flags); r = mnt_fs_get_propagation(fs, &remount_flags);
if (r < 0) { if (r < 0) {
log_warning_errno(r, "mnt_fs_get_propagation() failed for %s, ignoring: %m", path); log_warning_errno(r, "mnt_fs_get_propagation() failed for %s, ignoring: %m", path);
continue; continue;

View File

@ -2127,7 +2127,7 @@ static int image_discover_and_read_metadata(ImageClass image_class, Hashmap **re
return log_error_errno(r, "Failed to discover images: %m"); return log_error_errno(r, "Failed to discover images: %m");
HASHMAP_FOREACH(img, images) { HASHMAP_FOREACH(img, images) {
r = image_read_metadata(img, image_class_info[image_class].default_image_policy, RUNTIME_SCOPE_SYSTEM); r = image_read_metadata(img, image_class_info[image_class].default_image_policy);
if (r < 0) if (r < 0)
return log_error_errno(r, "Failed to read metadata for image %s: %m", img->name); return log_error_errno(r, "Failed to read metadata for image %s: %m", img->name);
} }

View File

@ -2079,7 +2079,6 @@ static int run(int argc, char *argv[]) {
"System update management service.", "System update management service.",
BUS_IMPLEMENTATIONS(&manager_object, BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object), &log_control_object),
/* runtime_scope= */ NULL,
argc, argv); argc, argv);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -215,7 +215,7 @@ simple_tests += files(
############################################################ ############################################################
common_test_dependencies = [ common_test_dependencies = [
libmount_cflags, libmount,
librt, librt,
libseccomp_cflags, libseccomp_cflags,
libselinux, libselinux,
@ -289,7 +289,6 @@ executables += [
'dependencies' : [ 'dependencies' : [
libblkid_cflags, libblkid_cflags,
libkmod_cflags, libkmod_cflags,
libmount_cflags,
libp11kit_cflags, libp11kit_cflags,
libseccomp_cflags, libseccomp_cflags,
], ],
@ -342,7 +341,7 @@ executables += [
test_template + { test_template + {
'sources' : files('test-libmount.c'), 'sources' : files('test-libmount.c'),
'dependencies' : [ 'dependencies' : [
libmount_cflags, libmount,
threads, threads,
], ],
}, },
@ -360,7 +359,7 @@ executables += [
}, },
test_template + { test_template + {
'sources' : files('test-mount-util.c'), 'sources' : files('test-mount-util.c'),
'dependencies' : libmount_cflags, 'dependencies' : libmount,
}, },
test_template + { test_template + {
'sources' : files('test-netlink-manual.c'), 'sources' : files('test-netlink-manual.c'),

View File

@ -49,8 +49,7 @@ int main(int argc, char *argv[]) {
if (!can_memlock()) if (!can_memlock())
return log_tests_skipped("Can't use mlock()"); return log_tests_skipped("Can't use mlock()");
_cleanup_free_ char *cgroup_path = NULL; r = enter_cgroup_subroot(NULL);
r = enter_cgroup_subroot(&cgroup_path);
if (r == -ENOMEDIUM) if (r == -ENOMEDIUM)
return log_tests_skipped("cgroupfs not available"); return log_tests_skipped("cgroupfs not available");
@ -129,8 +128,6 @@ int main(int argc, char *argv[]) {
SERVICE(u)->type = SERVICE_ONESHOT; SERVICE(u)->type = SERVICE_ONESHOT;
u->load_state = UNIT_LOADED; u->load_state = UNIT_LOADED;
CGroupRuntime *crt = ASSERT_PTR(unit_setup_cgroup_runtime(u));
unit_dump(u, stdout, NULL); unit_dump(u, stdout, NULL);
r = bpf_firewall_compile(u); r = bpf_firewall_compile(u);
@ -138,6 +135,7 @@ int main(int argc, char *argv[]) {
return log_tests_skipped("Kernel doesn't support the necessary bpf bits (masked out via seccomp?)"); return log_tests_skipped("Kernel doesn't support the necessary bpf bits (masked out via seccomp?)");
ASSERT_OK(r); ASSERT_OK(r);
CGroupRuntime *crt = ASSERT_PTR(unit_get_cgroup_runtime(u));
ASSERT_NOT_NULL(crt->ip_bpf_ingress); ASSERT_NOT_NULL(crt->ip_bpf_ingress);
ASSERT_NOT_NULL(crt->ip_bpf_egress); ASSERT_NOT_NULL(crt->ip_bpf_egress);

View File

@ -12,7 +12,6 @@
#include "libarchive-util.h" #include "libarchive-util.h"
#include "libaudit-util.h" #include "libaudit-util.h"
#include "libfido2-util.h" #include "libfido2-util.h"
#include "libmount-util.h"
#include "main-func.h" #include "main-func.h"
#include "module-util.h" #include "module-util.h"
#include "pam-util.h" #include "pam-util.h"
@ -59,7 +58,6 @@ static int run(int argc, char **argv) {
ASSERT_DLOPEN(dlopen_libacl, HAVE_ACL); ASSERT_DLOPEN(dlopen_libacl, HAVE_ACL);
ASSERT_DLOPEN(dlopen_libblkid, HAVE_BLKID); ASSERT_DLOPEN(dlopen_libblkid, HAVE_BLKID);
ASSERT_DLOPEN(dlopen_libseccomp, HAVE_SECCOMP); ASSERT_DLOPEN(dlopen_libseccomp, HAVE_SECCOMP);
ASSERT_DLOPEN(dlopen_libmount, true);
return 0; return 0;
} }

View File

@ -32,7 +32,7 @@ static void test_libmount_unescaping_one(
/* We allow this call and the checks below to fail in some cases. See the case definitions below. */ /* We allow this call and the checks below to fail in some cases. See the case definitions below. */
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r != 0 && may_fail) { if (r != 0 && may_fail) {
log_error_errno(r, "mnt_table_next_fs failed: %m"); log_error_errno(r, "mnt_table_next_fs failed: %m");
return; return;
@ -41,8 +41,8 @@ static void test_libmount_unescaping_one(
assert_se(x = cescape(string)); assert_se(x = cescape(string));
assert_se(source = sym_mnt_fs_get_source(fs)); assert_se(source = mnt_fs_get_source(fs));
assert_se(target = sym_mnt_fs_get_target(fs)); assert_se(target = mnt_fs_get_target(fs));
assert_se(cs = cescape(source)); assert_se(cs = cescape(source));
assert_se(ct = cescape(target)); assert_se(ct = cescape(target));
@ -63,7 +63,7 @@ static void test_libmount_unescaping_one(
assert_se(may_fail || streq(source, expected_source)); assert_se(may_fail || streq(source, expected_source));
assert_se(may_fail || streq(target, expected_target)); assert_se(may_fail || streq(target, expected_target));
assert_se(sym_mnt_table_next_fs(table, iter, &fs) == 1); assert_se(mnt_table_next_fs(table, iter, &fs) == 1);
} }
TEST(libmount_unescaping) { TEST(libmount_unescaping) {

View File

@ -361,7 +361,7 @@ TEST(umount_recursive) {
for (;;) { for (;;) {
struct libmnt_fs *fs; struct libmnt_fs *fs;
r = sym_mnt_table_next_fs(table, iter, &fs); r = mnt_table_next_fs(table, iter, &fs);
if (r == 1) if (r == 1)
break; break;
if (r < 0) { if (r < 0) {
@ -369,7 +369,7 @@ TEST(umount_recursive) {
_exit(EXIT_FAILURE); _exit(EXIT_FAILURE);
} }
log_debug("left after complete umount: %s", sym_mnt_fs_get_target(fs)); log_debug("left after complete umount: %s", mnt_fs_get_target(fs));
} }
_exit(EXIT_SUCCESS); _exit(EXIT_SUCCESS);

View File

@ -1164,7 +1164,6 @@ static int run(int argc, char *argv[]) {
"Manage the system clock and timezone and NTP enablement.", "Manage the system clock and timezone and NTP enablement.",
BUS_IMPLEMENTATIONS(&manager_object, BUS_IMPLEMENTATIONS(&manager_object,
&log_control_object), &log_control_object),
/* runtime_scope= */ NULL,
argc, argv); argc, argv);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -151,7 +151,6 @@ static int run(int argc, char *argv[]) {
r = service_parse_argv("systemd-timesyncd.service", r = service_parse_argv("systemd-timesyncd.service",
"Network time synchronization", "Network time synchronization",
BUS_IMPLEMENTATIONS(&manager_object, &log_control_object), BUS_IMPLEMENTATIONS(&manager_object, &log_control_object),
/* runtime_scope= */ NULL,
argc, argv); argc, argv);
if (r <= 0) if (r <= 0)
return r; return r;

View File

@ -70,7 +70,7 @@ foreach dirname : [
'TEST-46-HOMED', 'TEST-46-HOMED',
'TEST-50-DISSECT', 'TEST-50-DISSECT',
'TEST-52-HONORFIRSTSHUTDOWN', 'TEST-52-HONORFIRSTSHUTDOWN',
'TEST-53-TIMER', 'TEST-53-ISSUE-16347',
'TEST-54-CREDS', 'TEST-54-CREDS',
'TEST-55-OOMD', 'TEST-55-OOMD',
'TEST-58-REPART', 'TEST-58-REPART',

View File

@ -3,6 +3,8 @@
set -eux set -eux
set -o pipefail set -o pipefail
systemd-analyze log-level debug
cat >/run/systemd/system/floodme@.service <<EOF cat >/run/systemd/system/floodme@.service <<EOF
[Service] [Service]
ExecStart=true ExecStart=true

View File

@ -4,6 +4,8 @@
set -eux set -eux
set -o pipefail set -o pipefail
systemd-analyze log-level debug
test_quotas() { test_quotas() {
local directory="$1" local directory="$1"
@ -88,4 +90,6 @@ EOF
test_quotas "/var/lib/private" "StateDirectory=quotadir" "StateDirectoryQuota=1%" test_quotas "/var/lib/private" "StateDirectory=quotadir" "StateDirectoryQuota=1%"
systemd-analyze log-level info
touch /testok touch /testok

View File

@ -20,6 +20,8 @@ at_exit() {
trap at_exit EXIT trap at_exit EXIT
systemctl service-log-level systemd-importd debug
# Mount tmpfs over /var/lib/confexts to not pollute the image # Mount tmpfs over /var/lib/confexts to not pollute the image
mkdir -p /var/lib/confexts mkdir -p /var/lib/confexts
mount -t tmpfs tmpfs /var/lib/confexts -o mode=755 mount -t tmpfs tmpfs /var/lib/confexts -o mode=755

View File

@ -20,6 +20,8 @@ at_exit() {
trap at_exit EXIT trap at_exit EXIT
systemctl service-log-level systemd-machined debug
systemctl service-log-level systemd-importd debug
# per request in https://github.com/systemd/systemd/pull/35117 # per request in https://github.com/systemd/systemd/pull/35117
systemctl edit --runtime --stdin 'systemd-nspawn@.service' --drop-in=debug.conf <<EOF systemctl edit --runtime --stdin 'systemd-nspawn@.service' --drop-in=debug.conf <<EOF
[Service] [Service]

View File

@ -11,6 +11,8 @@ if [[ "$(get_cgroup_hierarchy)" != unified ]]; then
exit 0 exit 0
fi fi
systemd-analyze log-level debug
# Multiple level process tree, parent process stays up # Multiple level process tree, parent process stays up
cat >/tmp/test19-exit-cgroup.sh <<EOF cat >/tmp/test19-exit-cgroup.sh <<EOF
#!/usr/bin/env bash #!/usr/bin/env bash
@ -96,3 +98,6 @@ systemd-run --wait \
--property="Type=notify" \ --property="Type=notify" \
--property="ExitType=cgroup" \ --property="ExitType=cgroup" \
/tmp/test19-exit-cgroup-parentless.sh 'systemctl kill --signal 9 six' /tmp/test19-exit-cgroup-parentless.sh 'systemctl kill --signal 9 six'
systemd-analyze log-level info

View File

@ -1,46 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -ex
set -o pipefail
# Test that the service is not invoked if the cgroup cannot be created.
# It seems openSUSE kernel (at least kernel-default-6.16.8-1.1.x86_64.rpm) has a
# bag in kernel oom killer or clone3 syscall, and spawning executor on a cgroup
# with too small MemoryMax= triggers infinite loop of OOM kill, and posix_spawn()
# will never return, and the service manager will stuck.
####
# [ 119.776797] systemd invoked oom-killer: gfp_mask=0xcc0(GFP_KERNEL), order=0, oom_score_adj=0
# [ 119.776859] CPU: 1 UID: 0 PID: 1472 Comm: systemd Not tainted 6.16.8-1-default #1 PREEMPT(voluntary) openSUSE Tumbleweed 6c85865973e4ae641870ed68afe8933a6986c974
# [ 119.776865] Hardware name: QEMU Standard PC (Q35 + ICH9, 2009), BIOS 1.17.0-5.fc42 04/01/2014
# [ 119.776867] Call Trace:
# (snip)
# [ 119.778126] Out of memory and no killable processes...
####
# On other distributions, the oom killer is triggered, but clone3 immediately
# fails with ENOMEM, and such problematic loop does not happen.
. /etc/os-release
if [[ "$ID" =~ opensuse ]]; then
echo "Skipping cgroup test with too small MemoryMax= setting on openSUSE."
exit 0
fi
cat >/run/systemd/system/testslice.slice <<EOF
[Slice]
MemoryMax=1
EOF
cat >/run/systemd/system/testservice.service <<EOF
[Service]
Type=oneshot
ExecStart=cat /proc/self/cgroup
Slice=testslice.slice
EOF
systemctl daemon-reload
(! systemctl start testservice.service)
rm /run/systemd/system/testslice.slice
rm /run/systemd/system/testservice.service
exit 0

View File

@ -5,6 +5,8 @@ set -o pipefail
# Test ExecReload= (PR #13098) # Test ExecReload= (PR #13098)
systemd-analyze log-level debug
export SYSTEMD_PAGER= export SYSTEMD_PAGER=
SERVICE_PATH="$(mktemp /etc/systemd/system/execreloadXXX.service)" SERVICE_PATH="$(mktemp /etc/systemd/system/execreloadXXX.service)"
SERVICE_NAME="${SERVICE_PATH##*/}" SERVICE_NAME="${SERVICE_PATH##*/}"
@ -55,3 +57,5 @@ systemctl status "$SERVICE_NAME"
systemctl reload "$SERVICE_NAME" systemctl reload "$SERVICE_NAME"
systemctl status "$SERVICE_NAME" systemctl status "$SERVICE_NAME"
systemctl stop "$SERVICE_NAME" systemctl stop "$SERVICE_NAME"
systemd-analyze log-level info

View File

@ -4,6 +4,8 @@ set -eux
# Test that ExecStopPost= is always run # Test that ExecStopPost= is always run
systemd-analyze log-level debug
systemd-run --unit=simple1.service --wait -p StandardOutput=tty -p StandardError=tty -p Type=simple \ systemd-run --unit=simple1.service --wait -p StandardOutput=tty -p StandardError=tty -p Type=simple \
-p ExecStopPost='touch /run/simple1' true -p ExecStopPost='touch /run/simple1' true
test -f /run/simple1 test -f /run/simple1
@ -99,3 +101,5 @@ test -f /run/idle1
(! systemd-run --unit=idle2.service --wait -p StandardOutput=tty -p StandardError=tty -p Type=idle \ (! systemd-run --unit=idle2.service --wait -p StandardOutput=tty -p StandardError=tty -p Type=idle \
-p ExecStopPost='touch /run/idle2' false) -p ExecStopPost='touch /run/idle2' false)
test -f /run/idle2 test -f /run/idle2
systemd-analyze log-level info

View File

@ -18,6 +18,8 @@ mkdir /tmp/test-extra-fd
echo "Hello" > /tmp/test-extra-fd/1.txt echo "Hello" > /tmp/test-extra-fd/1.txt
echo "Extra" > /tmp/test-extra-fd/2.txt echo "Extra" > /tmp/test-extra-fd/2.txt
systemd-analyze log-level debug
# Open files and assign FD to variables # Open files and assign FD to variables
exec {TEST_FD1}</tmp/test-extra-fd/1.txt exec {TEST_FD1}</tmp/test-extra-fd/1.txt
exec {TEST_FD2}</tmp/test-extra-fd/2.txt exec {TEST_FD2}</tmp/test-extra-fd/2.txt
@ -59,3 +61,5 @@ assert_eq "$(systemctl show -P Result "$TEST_UNIT")" "success"
assert_eq "$(systemctl show -P ExecMainStatus "$TEST_UNIT")" "0" assert_eq "$(systemctl show -P ExecMainStatus "$TEST_UNIT")" "0"
systemctl stop "$TEST_UNIT" systemctl stop "$TEST_UNIT"
systemctl log-level info

View File

@ -6,6 +6,9 @@ set -o pipefail
# Test JoinsNamespaceOf= with PrivateTmp=yes # Test JoinsNamespaceOf= with PrivateTmp=yes
systemd-analyze log-level debug
systemd-analyze log-target journal
# simple case # simple case
systemctl start TEST-23-UNIT-FILE-joins-namespace-of-1.service systemctl start TEST-23-UNIT-FILE-joins-namespace-of-1.service
systemctl start TEST-23-UNIT-FILE-joins-namespace-of-2.service systemctl start TEST-23-UNIT-FILE-joins-namespace-of-2.service
@ -24,3 +27,5 @@ systemctl start TEST-23-UNIT-FILE-joins-namespace-of-8.service
systemctl start TEST-23-UNIT-FILE-joins-namespace-of-9.service systemctl start TEST-23-UNIT-FILE-joins-namespace-of-9.service
systemctl stop TEST-23-UNIT-FILE-joins-namespace-of-6.service systemctl stop TEST-23-UNIT-FILE-joins-namespace-of-6.service
systemctl stop TEST-23-UNIT-FILE-joins-namespace-of-8.service systemctl stop TEST-23-UNIT-FILE-joins-namespace-of-8.service
systemd-analyze log-level info

View File

@ -5,6 +5,8 @@ set -o pipefail
# Test StandardOutput=file: # Test StandardOutput=file:
systemd-analyze log-level debug
systemd-run --wait --unit=TEST-23-UNIT-FILE-standard-output-one \ systemd-run --wait --unit=TEST-23-UNIT-FILE-standard-output-one \
-p StandardOutput=file:/tmp/stdout \ -p StandardOutput=file:/tmp/stdout \
-p StandardError=file:/tmp/stderr \ -p StandardError=file:/tmp/stderr \
@ -54,3 +56,5 @@ EOF
cmp /tmp/stderr <<EOF cmp /tmp/stderr <<EOF
b b
EOF EOF
systemd-analyze log-level info

View File

@ -6,6 +6,9 @@ set -o pipefail
# Test OnSuccess= + Uphold= + PropagatesStopTo= + BindsTo= # Test OnSuccess= + Uphold= + PropagatesStopTo= + BindsTo=
systemd-analyze log-level debug
systemd-analyze log-target journal
# Idea is this: # Idea is this:
# 1. we start TEST-23-UNIT-FILE-success.service # 1. we start TEST-23-UNIT-FILE-success.service
# 2. which through OnSuccess= starts TEST-23-UNIT-FILE-fail.service, # 2. which through OnSuccess= starts TEST-23-UNIT-FILE-fail.service,
@ -99,3 +102,5 @@ for _ in {1..120}; do
fi fi
done done
[[ "$sigrtmin1" == 1 ]] [[ "$sigrtmin1" == 1 ]]
systemd-analyze log-level info

View File

@ -5,6 +5,8 @@ set -o pipefail
# Test ExecXYZEx= service unit dbus hookups # Test ExecXYZEx= service unit dbus hookups
systemd-analyze log-level debug
declare -A property declare -A property
property[1_one]=ExecCondition property[1_one]=ExecCondition
@ -29,3 +31,5 @@ for c in "${!property[@]}"; do
systemctl show -p "${property[$c]}" "$c" | grep -F "path=echo ; argv[]=echo \${$c} ; ignore_errors=no" systemctl show -p "${property[$c]}" "$c" | grep -F "path=echo ; argv[]=echo \${$c} ; ignore_errors=no"
systemctl show -p "${property[$c]}Ex" "$c" | grep -F "path=echo ; argv[]=echo \${$c} ; flags=no-env-expand" systemctl show -p "${property[$c]}Ex" "$c" | grep -F "path=echo ; argv[]=echo \${$c} ; flags=no-env-expand"
done done
systemd-analyze log-level info

View File

@ -11,6 +11,8 @@ set -o pipefail
# wait this many secs for each test service to succeed in what is being tested # wait this many secs for each test service to succeed in what is being tested
MAX_SECS=60 MAX_SECS=60
systemctl log-level debug
# test one: Restart=on-failure should restart the service # test one: Restart=on-failure should restart the service
(! systemd-run --unit=oneshot-restart-one -p Type=oneshot -p Restart=on-failure bash -c "exit 1") (! systemd-run --unit=oneshot-restart-one -p Type=oneshot -p Restart=on-failure bash -c "exit 1")
@ -95,3 +97,5 @@ EOF
systemctl disable "$UNIT_NAME" systemctl disable "$UNIT_NAME"
rm "$TMP_FILE" /run/systemd/system/{"$UNIT_NAME","$ONSUCCESS_UNIT_NAME"} "$FIFO_FILE" rm "$TMP_FILE" /run/systemd/system/{"$UNIT_NAME","$ONSUCCESS_UNIT_NAME"} "$FIFO_FILE"
systemctl log-level info

View File

@ -14,6 +14,8 @@ at_exit() {
trap at_exit EXIT trap at_exit EXIT
systemctl log-level debug
# Existing files # Existing files
mkdir /tmp/test-open-file mkdir /tmp/test-open-file
@ -49,3 +51,5 @@ systemctl stop TEST-23-UNIT-FILE-openfile-server.socket
assert_rc 202 systemd-run -p OpenFile=/run/missing/foo:missing-file:read-only --wait true assert_rc 202 systemd-run -p OpenFile=/run/missing/foo:missing-file:read-only --wait true
assert_rc 0 systemd-run -p OpenFile=/run/missing/foo:missing-file:read-only,graceful --wait true assert_rc 0 systemd-run -p OpenFile=/run/missing/foo:missing-file:read-only,graceful --wait true
systemctl log-level info

View File

@ -5,6 +5,8 @@ set -o pipefail
# Test OnSuccess=/OnFailure= in combination # Test OnSuccess=/OnFailure= in combination
systemd-analyze log-level debug
# Start-up should fail, but the automatic restart should fix it # Start-up should fail, but the automatic restart should fix it
(! systemctl start success-failure-test ) (! systemctl start success-failure-test )
@ -43,3 +45,5 @@ done
test "$(systemctl is-active success-failure-test-failure)" = "inactive" test "$(systemctl is-active success-failure-test-failure)" = "inactive"
systemctl stop success-failure-test success-failure-test-success systemctl stop success-failure-test success-failure-test-success
systemd-analyze log-level info

View File

@ -5,6 +5,8 @@ set -o pipefail
# Test Type=exec # Test Type=exec
systemd-analyze log-level debug
# Create a binary for which execve() will fail # Create a binary for which execve() will fail
touch /tmp/brokenbinary touch /tmp/brokenbinary
chmod +x /tmp/brokenbinary chmod +x /tmp/brokenbinary
@ -57,3 +59,5 @@ busctl call \
sleep 0 true \ sleep 0 true \
sleep 2 sleep 1 true \ sleep 2 sleep 1 true \
0) 0)
systemd-analyze log-level info

View File

@ -3,6 +3,8 @@
set -eux set -eux
set -o pipefail set -o pipefail
systemd-analyze log-level debug
systemctl disable --now systemd-timesyncd.service systemctl disable --now systemd-timesyncd.service
timedatectl set-timezone Europe/Berlin timedatectl set-timezone Europe/Berlin
@ -59,4 +61,6 @@ while test ! -f /tmp/timezone-changed-alternate-path-2 ; do sleep .5 ; done
rm /run/systemd/system.conf /run/systemd/system/systemd-timedated.service.d/override.conf rm /run/systemd/system.conf /run/systemd/system/systemd-timedated.service.d/override.conf
systemctl daemon-reload systemctl daemon-reload
systemd-analyze log-level info
touch /testok touch /testok

View File

@ -10,6 +10,8 @@ set -o pipefail
# kernels where the concept was still new. # kernels where the concept was still new.
if test -f /sys/fs/cgroup/system.slice/TEST-32-OOMPOLICY.service/memory.oom.group; then if test -f /sys/fs/cgroup/system.slice/TEST-32-OOMPOLICY.service/memory.oom.group; then
systemd-analyze log-level debug
# Run a service that is guaranteed to be the first candidate for OOM killing # Run a service that is guaranteed to be the first candidate for OOM killing
systemd-run --unit=oomtest.service \ systemd-run --unit=oomtest.service \
-p Type=exec -p OOMScoreAdjust=1000 -p OOMPolicy=stop -p MemoryAccounting=yes \ -p Type=exec -p OOMScoreAdjust=1000 -p OOMPolicy=stop -p MemoryAccounting=yes \
@ -27,6 +29,8 @@ if test -f /sys/fs/cgroup/system.slice/TEST-32-OOMPOLICY.service/memory.oom.grou
RESULT="$(systemctl show -P Result oomtest.service)" RESULT="$(systemctl show -P Result oomtest.service)"
test "$RESULT" = "oom-kill" test "$RESULT" = "oom-kill"
systemd-analyze log-level info
fi fi
touch /testok touch /testok

View File

@ -3,6 +3,8 @@
set -eux set -eux
set -o pipefail set -o pipefail
systemd-analyze log-level debug
test_directory() { test_directory() {
local directory="$1" local directory="$1"
local path="$2" local path="$2"
@ -237,4 +239,6 @@ if systemd-analyze compare-versions "$(uname -r)" ge 5.12; then
test_check_idmapped_mounts_root test_check_idmapped_mounts_root
fi fi
systemd-analyze log-level info
touch /testok touch /testok

View File

@ -21,6 +21,9 @@ at_exit() {
trap at_exit EXIT trap at_exit EXIT
systemd-analyze log-level debug
systemd-analyze log-target journal
# Log files # Log files
straceLog='strace.log' straceLog='strace.log'
journalLog='journal.log' journalLog='journal.log'
@ -349,4 +352,6 @@ fi
rm -rf "$confDir" rm -rf "$confDir"
systemctl daemon-reload systemctl daemon-reload
systemd-analyze log-level info
touch /testok touch /testok

View File

@ -12,6 +12,8 @@ if [[ -n "${COVERAGE_BUILD_DIR:-}" ]]; then
exit 77 exit 77
fi fi
systemd-analyze log-level debug
unit=TEST-38-FREEZER-sleep.service unit=TEST-38-FREEZER-sleep.service
start_test_service() { start_test_service() {

View File

@ -13,9 +13,13 @@ fi
install_extension_images install_extension_images
systemd-analyze log-level debug
runas testuser systemd-run --wait --user --unit=test-private-users \ runas testuser systemd-run --wait --user --unit=test-private-users \
-p PrivateUsers=yes -P echo hello -p PrivateUsers=yes -P echo hello
runas testuser systemctl --user log-level debug
runas testuser systemd-run --wait --user --unit=test-private-tmp-innerfile \ runas testuser systemd-run --wait --user --unit=test-private-tmp-innerfile \
-p PrivateTmp=yes \ -p PrivateTmp=yes \
-P touch /tmp/innerfile.txt -P touch /tmp/innerfile.txt
@ -136,4 +140,6 @@ if unshare --mount --user --map-root-user mount -t overlay overlay /tmp/c -o low
grep PORTABLE_PREFIXES=app1 /usr/lib/extension-release.d/extension-release.app2 grep PORTABLE_PREFIXES=app1 /usr/lib/extension-release.d/extension-release.app2
fi fi
systemd-analyze log-level info
touch /testok touch /testok

View File

@ -2,6 +2,8 @@
# SPDX-License-Identifier: LGPL-2.1-or-later # SPDX-License-Identifier: LGPL-2.1-or-later
set -eux set -eux
systemd-analyze log-level debug
journalctl --list-namespaces -o json | jq . journalctl --list-namespaces -o json | jq .
systemd-run --wait -p LogNamespace=foobar echo "hello world" systemd-run --wait -p LogNamespace=foobar echo "hello world"
@ -23,4 +25,6 @@ journalctl --list-namespaces -o json | jq .
grep "^hello world$" /tmp/hello-world grep "^hello world$" /tmp/hello-world
(! grep "^hello world$" /tmp/no-hello-world) (! grep "^hello world$" /tmp/no-hello-world)
systemd-analyze log-level info
touch /testok touch /testok

View File

@ -40,6 +40,9 @@ FSTYPE="$(stat --file-system --format "%T" /)"
systemctl start systemd-homed.service systemd-userdbd.socket systemctl start systemd-homed.service systemd-userdbd.socket
systemd-analyze log-level debug
systemctl service-log-level systemd-homed debug
# Create a tmpfs to use as backing store for the home dir. That way we can enforce a size limit nicely. # Create a tmpfs to use as backing store for the home dir. That way we can enforce a size limit nicely.
mkdir -p /home mkdir -p /home
mount -t tmpfs tmpfs /home -o size=290M mount -t tmpfs tmpfs /home -o size=290M
@ -845,4 +848,6 @@ homectl inspect matchtest
homectl inspect matchtest | grep "Area: quux3" homectl inspect matchtest | grep "Area: quux3"
homectl remove matchtest homectl remove matchtest
systemd-analyze log-level info
touch /testok touch /testok

View File

@ -3,6 +3,8 @@
set -ex set -ex
set -o pipefail set -o pipefail
systemd-analyze log-level debug
systemctl enable test-honor-first-shutdown.service systemctl enable test-honor-first-shutdown.service
systemctl start test-honor-first-shutdown.service systemctl start test-honor-first-shutdown.service

View File

@ -3,9 +3,10 @@
set -eux set -eux
set -o pipefail set -o pipefail
: >/failed
# Reset host date to current time, 3 days in the past. # Reset host date to current time, 3 days in the past.
date -s "-3 days" date -s "-3 days"
trap 'date -s "+3 days"' EXIT
# Run a timer for every 15 minutes. # Run a timer for every 15 minutes.
systemd-run --unit test-timer --on-calendar "*:0/15:0" true systemd-run --unit test-timer --on-calendar "*:0/15:0" true
@ -16,12 +17,15 @@ now=$(date +%s)
time_delta=$((next_elapsed - now)) time_delta=$((next_elapsed - now))
# Check that the timer will elapse in less than 20 minutes. # Check that the timer will elapse in less than 20 minutes.
if [[ "$time_delta" -lt 0 || "$time_delta" -gt 1200 ]]; then ((0 < time_delta && time_delta < 1200)) || {
echo 'Timer elapse outside of the expected 20 minute window.' echo 'Timer elapse outside of the expected 20 minute window.'
echo " next_elapsed=${next_elapsed}" echo " next_elapsed=${next_elapsed}"
echo " now=${now}" echo " now=${now}"
echo " time_delta=${time_delta}" echo " time_delta=${time_delta}"
echo echo ''
} >>/failed
exit 1 if test ! -s /failed ; then
rm -f /failed
touch /testok
fi fi

View File

@ -1,97 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# When deserializing a serialized timer unit with RandomizedDelaySec= set, systemd should use the last
# inactive exit timestamp instead of current realtime to calculate the new next elapse, so the timer unit
# actually runs in the given calendar window.
#
# Provides coverage for:
# - https://github.com/systemd/systemd/issues/18678
# - https://github.com/systemd/systemd/pull/27752
set -eux
set -o pipefail
# shellcheck source=test/units/test-control.sh
. "$(dirname "$0")"/util.sh
UNIT_NAME="timer-RandomizedDelaySec-$RANDOM"
TARGET_TS="$(date --date="tomorrow 00:10")"
TARGET_TS_S="$(date --date="$TARGET_TS" "+%s")"
# Maximum possible next elapse timestamp: $TARGET_TS (OnCalendar=) + 22 hours (RandomizedDelaySec=)
MAX_NEXT_ELAPSE_REALTIME_S="$((TARGET_TS_S + 22 * 60 * 60))"
MAX_NEXT_ELAPSE_REALTIME="$(date --date="@$MAX_NEXT_ELAPSE_REALTIME_S")"
# Let's make sure to return the date & time back to the original state once we're done with our time
# shenigans. One way to do this would be to use hwclock, but the RTC in VMs can be unreliable or slow to
# respond, causing unexpected test fails/timeouts.
#
# Instead, let's save the realtime timestamp before we start with the test together with a current monotonic
# timestamp, after the test ends take the difference between the current monotonic timestamp and the "start"
# one, add it to the originally saved realtime timestamp, and finally use that timestamp to set the system
# time. This should advance the system time by the amount of time the test actually ran, and hence restore it
# to some sane state after the time jumps performed by the test. It won't be perfect, but it should be close
# enough for our needs.
START_REALTIME="$(date "+%s")"
START_MONOTONIC="$(cut -d . -f 1 /proc/uptime)"
at_exit() {
: "Restore the system date to a sane state"
END_MONOTONIC="$(cut -d . -f 1 /proc/uptime)"
date --set="@$((START_REALTIME + END_MONOTONIC - START_MONOTONIC))"
}
trap at_exit EXIT
# Set some predictable time so we can schedule the first timer elapse in a deterministic-ish way
date --set="23:00"
# Setup
cat >"/run/systemd/system/$UNIT_NAME.timer" <<EOF
[Timer]
# Run this timer daily, ten minutes after midnight
OnCalendar=*-*-* 00:10:00
RandomizedDelaySec=22h
AccuracySec=1ms
EOF
cat >"/run/systemd/system/$UNIT_NAME.service" <<EOF
[Service]
ExecStart=echo "Hello world"
EOF
systemctl daemon-reload
check_elapse_timestamp() {
systemctl status "$UNIT_NAME.timer"
systemctl show -p InactiveExitTimestamp "$UNIT_NAME.timer"
NEXT_ELAPSE_REALTIME="$(systemctl show -P NextElapseUSecRealtime "$UNIT_NAME.timer")"
NEXT_ELAPSE_REALTIME_S="$(date --date="$NEXT_ELAPSE_REALTIME" "+%s")"
: "Next elapse timestamp should be $TARGET_TS <= $NEXT_ELAPSE_REALTIME <= $MAX_NEXT_ELAPSE_REALTIME"
assert_ge "$NEXT_ELAPSE_REALTIME_S" "$TARGET_TS_S"
assert_le "$NEXT_ELAPSE_REALTIME_S" "$MAX_NEXT_ELAPSE_REALTIME_S"
}
# Restart the timer unit and check the initial next elapse timestamp
: "Initial next elapse timestamp"
systemctl restart "$UNIT_NAME.timer"
check_elapse_timestamp
# Bump the system date to 1 minute after the original calendar timer would've expired (without any random
# delay!) - systemd should recalculate the next elapse timestamp with a new randomized delay, but it should
# use the original inactive exit timestamp as a "base", so the final timestamp should not end up beyond the
# original calendar timestamp + randomized delay range.
#
# Similarly, do the same check after doing daemon-reload, as that also forces systemd to recalculate the next
# elapse timestamp (this goes through a slightly different codepath that actually contained the original
# issue).
: "Next elapse timestamp after time jump"
date -s "tomorrow 00:11"
check_elapse_timestamp
: "Next elapse timestamp after daemon-reload"
systemctl daemon-reload
check_elapse_timestamp
# Cleanup
systemctl stop "$UNIT_NAME".{timer,service}
rm -f "/run/systemd/system/$UNIT_NAME".{timer,service}
systemctl daemon-reload

View File

@ -1,77 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
#
# Restarting an already elapsed timer shouldn't immediately trigger the corresponding service unit.
#
# Provides coverage for:
# - https://github.com/systemd/systemd/issues/31231
# - https://github.com/systemd/systemd/issues/35805
set -eux
set -o pipefail
# shellcheck source=test/units/test-control.sh
. "$(dirname "$0")"/util.sh
UNIT_NAME="timer-restart-$RANDOM"
TEST_MESSAGE="Hello from timer $RANDOM"
# Setup
cat >"/run/systemd/system/$UNIT_NAME.timer" <<EOF
[Timer]
OnCalendar=$(date --date="+1 hour" "+%Y-%m-%d %H:%M:%S")
AccuracySec=1s
EOF
cat >"/run/systemd/system/$UNIT_NAME.service" <<EOF
[Service]
ExecStart=echo "$TEST_MESSAGE"
EOF
systemctl daemon-reload
JOURNAL_TS="$(date "+%s")"
# Paranoia check that the test message is not already in the logs
(! journalctl -p info --since="@$JOURNAL_TS" --unit="$UNIT_NAME" --grep="$TEST_MESSAGE")
# Restart time timer and move time forward by 2 hours to trigger the timer
systemctl restart "$UNIT_NAME.timer"
systemctl status "$UNIT_NAME.timer"
date -s '+2 hours'
trap 'date -s "-2 hours"' EXIT
sleep 1
systemctl status "$UNIT_NAME.timer"
assert_eq "$(journalctl -q -p info --since="@$JOURNAL_TS" --unit="$UNIT_NAME" --grep="$TEST_MESSAGE" | wc -l)" "1"
# Restarting the timer unit shouldn't trigger neither the timer nor the service, so these
# fields should remain constant through the following tests
SERVICE_INV_ID="$(systemctl show --property=InvocationID "$UNIT_NAME.service")"
TIMER_LAST_TRIGGER="$(systemctl show --property=LastTriggerUSec "$UNIT_NAME.timer")"
# Now restart the timer and check if the timer and the service weren't triggered again
systemctl restart "$UNIT_NAME.timer"
sleep 5
assert_eq "$(journalctl -q -p info --since="@$JOURNAL_TS" --unit="$UNIT_NAME" --grep="$TEST_MESSAGE" | wc -l)" "1"
assert_eq "$SERVICE_INV_ID" "$(systemctl show --property=InvocationID "$UNIT_NAME.service")"
assert_eq "$TIMER_LAST_TRIGGER" "$(systemctl show --property=LastTriggerUSec "$UNIT_NAME.timer")"
# Set the timer into the past, restart it, and again check if it wasn't triggered
TIMER_TS="$(date --date="-1 day" "+%Y-%m-%d %H:%M:%S")"
mkdir "/run/systemd/system/$UNIT_NAME.timer.d/"
cat >"/run/systemd/system/$UNIT_NAME.timer.d/99-override.conf" <<EOF
[Timer]
OnCalendar=$TIMER_TS
EOF
systemctl daemon-reload
systemctl status "$UNIT_NAME.timer"
assert_in "OnCalendar=$TIMER_TS" "$(systemctl show -P TimersCalendar "$UNIT_NAME".timer)"
systemctl restart "$UNIT_NAME.timer"
sleep 5
assert_eq "$(journalctl -q -p info --since="@$JOURNAL_TS" --unit="$UNIT_NAME" --grep="$TEST_MESSAGE" | wc -l)" "1"
assert_eq "$SERVICE_INV_ID" "$(systemctl show --property=InvocationID "$UNIT_NAME.service")"
assert_eq "$TIMER_LAST_TRIGGER" "$(systemctl show --property=LastTriggerUSec "$UNIT_NAME.timer")"
# Cleanup
systemctl stop "$UNIT_NAME".{timer,service}
rm -f "/run/systemd/system/$UNIT_NAME".{timer,service}
systemctl daemon-reload

View File

@ -1,11 +0,0 @@
#!/usr/bin/env bash
# SPDX-License-Identifier: LGPL-2.1-or-later
set -eux
set -o pipefail
# shellcheck source=test/units/test-control.sh
. "$(dirname "$0")"/test-control.sh
run_subtests
touch /testok

Some files were not shown because too many files have changed in this diff Show More