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.
996e6d0d89
...
3b6288f6be
@ -347,7 +347,7 @@
|
||||
<varlistentry>
|
||||
<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
|
||||
this option to false.</para>
|
||||
|
||||
|
||||
@ -1149,7 +1149,7 @@ NFTSet=cgroup:inet:filter:my_service user:inet:filter:serviceuser
|
||||
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
|
||||
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
|
||||
(requires <varname>Delegate=</varname><constant>yes</constant>) instead of using this setting.</para>
|
||||
|
||||
|
||||
@ -1122,7 +1122,6 @@ libmount = dependency('mount',
|
||||
version : fuzzer_build ? '>= 0' : '>= 2.30',
|
||||
disabler : true,
|
||||
required : get_option('libmount'))
|
||||
libmount_cflags = libmount.partial_dependency(includes: true, compile_args: true)
|
||||
|
||||
libfdisk = dependency('fdisk',
|
||||
version : '>= 2.32',
|
||||
|
||||
@ -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 */
|
||||
static int get_security_info(Unit *u, ExecContext *c, CGroupContext *g, SecurityInfo **ret_info) {
|
||||
int r;
|
||||
|
||||
assert(ret_info);
|
||||
|
||||
_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;
|
||||
|
||||
#if HAVE_SECCOMP
|
||||
if (dlopen_libseccomp() >= 0) {
|
||||
r = dlopen_libseccomp();
|
||||
if (r >= 0) {
|
||||
SET_FOREACH(key, c->syscall_archs) {
|
||||
const char *name;
|
||||
|
||||
|
||||
@ -15,20 +15,3 @@ const char* runtime_scope_to_string(RuntimeScope scope) _const_;
|
||||
RuntimeScope runtime_scope_from_string(const char *s) _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;
|
||||
}
|
||||
}
|
||||
|
||||
@ -547,9 +547,9 @@ int bpf_firewall_compile(Unit *u) {
|
||||
if (!cc)
|
||||
return -EINVAL;
|
||||
|
||||
crt = unit_get_cgroup_runtime(u);
|
||||
crt = unit_setup_cgroup_runtime(u);
|
||||
if (!crt)
|
||||
return -ESTALE;
|
||||
return -ENOMEM;
|
||||
|
||||
if (bpf_program_supported() <= 0)
|
||||
return log_unit_debug_errno(u, SYNTHETIC_ERRNO(EOPNOTSUPP),
|
||||
|
||||
@ -2204,6 +2204,12 @@ int unit_attach_pids_to_cgroup(Unit *u, Set *pids, const char *suffix_path) {
|
||||
if (set_isempty(pids))
|
||||
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);
|
||||
if (r < 0)
|
||||
return r;
|
||||
@ -4277,15 +4283,6 @@ int cgroup_runtime_serialize(Unit *u, FILE *f, FDSet *fds) {
|
||||
if (!crt)
|
||||
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);
|
||||
if (crt->cpu_usage_last != NSEC_INFINITY)
|
||||
(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]);
|
||||
}
|
||||
|
||||
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_program_serialize_attachment(f, fds, "ip-bpf-ingress-installed", crt->ip_bpf_ingress_installed);
|
||||
|
||||
@ -134,7 +134,7 @@ libcore_static = static_library(
|
||||
dependencies : [libaudit_cflags,
|
||||
libdl,
|
||||
libm,
|
||||
libmount_cflags,
|
||||
libmount,
|
||||
librt,
|
||||
libseccomp_cflags,
|
||||
libselinux,
|
||||
@ -222,7 +222,7 @@ executables += [
|
||||
libcore,
|
||||
libshared
|
||||
],
|
||||
'dependencies' : libmount_cflags,
|
||||
'dependencies' : libmount,
|
||||
},
|
||||
fuzz_template + {
|
||||
'sources' : files('fuzz-manager-serialize.c'),
|
||||
|
||||
@ -1952,16 +1952,16 @@ static int mount_load_proc_self_mountinfo(Manager *m, bool set_flags) {
|
||||
struct libmnt_fs *fs;
|
||||
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)
|
||||
break;
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
|
||||
|
||||
device = sym_mnt_fs_get_source(fs);
|
||||
path = sym_mnt_fs_get_target(fs);
|
||||
options = sym_mnt_fs_get_options(fs);
|
||||
fstype = sym_mnt_fs_get_fstype(fs);
|
||||
device = mnt_fs_get_source(fs);
|
||||
path = mnt_fs_get_target(fs);
|
||||
options = mnt_fs_get_options(fs);
|
||||
fstype = mnt_fs_get_fstype(fs);
|
||||
|
||||
if (!device || !path)
|
||||
continue;
|
||||
@ -1983,10 +1983,8 @@ static void mount_shutdown(Manager *m) {
|
||||
|
||||
m->mount_event_source = sd_event_source_disable_unref(m->mount_event_source);
|
||||
|
||||
if (m->mount_monitor) {
|
||||
sym_mnt_unref_monitor(m->mount_monitor);
|
||||
mnt_unref_monitor(m->mount_monitor);
|
||||
m->mount_monitor = NULL;
|
||||
}
|
||||
}
|
||||
|
||||
static void mount_handoff_timestamp(
|
||||
@ -2077,39 +2075,33 @@ static void mount_enumerate(Manager *m) {
|
||||
|
||||
assert(m);
|
||||
|
||||
r = dlopen_libmount();
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Cannot enumerate mounts, as libmount is not available: %m");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
sym_mnt_init_debug(0);
|
||||
mnt_init_debug(0);
|
||||
|
||||
if (!m->mount_monitor) {
|
||||
usec_t mount_rate_limit_interval = 1 * USEC_PER_SEC;
|
||||
unsigned mount_rate_limit_burst = 5;
|
||||
int fd;
|
||||
|
||||
m->mount_monitor = sym_mnt_new_monitor();
|
||||
m->mount_monitor = mnt_new_monitor();
|
||||
if (!m->mount_monitor) {
|
||||
log_oom();
|
||||
goto fail;
|
||||
}
|
||||
|
||||
r = sym_mnt_monitor_enable_kernel(m->mount_monitor, 1);
|
||||
r = mnt_monitor_enable_kernel(m->mount_monitor, 1);
|
||||
if (r < 0) {
|
||||
log_error_errno(r, "Failed to enable watching of kernel mount events: %m");
|
||||
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) {
|
||||
log_error_errno(r, "Failed to enable watching of userspace mount events: %m");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
/* 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) {
|
||||
log_error_errno(r, "Failed to acquire watch file descriptor: %m");
|
||||
goto fail;
|
||||
@ -2173,9 +2165,6 @@ static int drain_libmount(Manager *m) {
|
||||
|
||||
assert(m);
|
||||
|
||||
if (!m->mount_monitor)
|
||||
return false;
|
||||
|
||||
/* 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
|
||||
@ -2183,7 +2172,7 @@ static int drain_libmount(Manager *m) {
|
||||
*
|
||||
* error: r < 0; valid: r == 0, false positive: r == 1 */
|
||||
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)
|
||||
return log_error_errno(r, "Failed to drain libmount events: %m");
|
||||
if (r == 0)
|
||||
|
||||
@ -664,6 +664,8 @@ static int timer_start(Unit *u) {
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
t->last_trigger = DUAL_TIMESTAMP_NULL;
|
||||
|
||||
/* Reenable all timers that depend on unit activation time */
|
||||
LIST_FOREACH(value, v, t->values)
|
||||
if (v->base == TIMER_ACTIVE)
|
||||
|
||||
@ -5559,11 +5559,11 @@ int unit_fork_helper_process(Unit *u, const char *name, bool into_cgroup, PidRef
|
||||
* with the child's PID. */
|
||||
|
||||
if (into_cgroup) {
|
||||
r = unit_realize_cgroup(u);
|
||||
if (r < 0)
|
||||
return r;
|
||||
(void) unit_realize_cgroup(u);
|
||||
|
||||
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);
|
||||
@ -6005,12 +6005,16 @@ int unit_prepare_exec(Unit *u) {
|
||||
|
||||
assert(u);
|
||||
|
||||
/* Prepares everything so that we can fork of a process for this unit */
|
||||
|
||||
r = unit_realize_cgroup(u);
|
||||
/* 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;
|
||||
|
||||
/* 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);
|
||||
if (crt && crt->reset_accounting) {
|
||||
(void) unit_reset_accounting(u);
|
||||
|
||||
@ -191,23 +191,19 @@ static int is_tmpfs_with_noswap(dev_t devno) {
|
||||
_cleanup_(mnt_free_tablep) struct libmnt_table *table = NULL;
|
||||
int r;
|
||||
|
||||
r = dlopen_libmount();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
table = sym_mnt_new_table();
|
||||
table = mnt_new_table();
|
||||
if (!table)
|
||||
return -ENOMEM;
|
||||
|
||||
r = sym_mnt_table_parse_mtab(table, /* filename= */ NULL);
|
||||
r = mnt_table_parse_mtab(table, /* filename= */ NULL);
|
||||
if (r < 0)
|
||||
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)
|
||||
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)
|
||||
return r;
|
||||
|
||||
|
||||
@ -6,7 +6,7 @@ executables += [
|
||||
'public' : true,
|
||||
'sources' : files('creds.c'),
|
||||
'dependencies' : [
|
||||
libmount_cflags,
|
||||
libmount,
|
||||
libopenssl,
|
||||
threads,
|
||||
],
|
||||
|
||||
@ -753,12 +753,12 @@ static char* disk_mount_point(const char *label) {
|
||||
for (;;) {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
r = sym_mnt_table_next_fs(table, iter, &fs);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r != 0)
|
||||
return NULL;
|
||||
|
||||
if (path_equal(sym_mnt_fs_get_source(fs), device)) {
|
||||
const char *target = sym_mnt_fs_get_target(fs);
|
||||
if (path_equal(mnt_fs_get_source(fs), device)) {
|
||||
const char *target = mnt_fs_get_target(fs);
|
||||
if (target)
|
||||
return strdup(target);
|
||||
}
|
||||
|
||||
@ -19,7 +19,7 @@ executables += [
|
||||
'sources' : systemd_cryptsetup_sources,
|
||||
'dependencies' : [
|
||||
libcryptsetup,
|
||||
libmount_cflags,
|
||||
libmount,
|
||||
libopenssl,
|
||||
libp11kit_cflags,
|
||||
],
|
||||
|
||||
@ -1048,19 +1048,15 @@ static int parse_fstab(bool prefix_sysroot) {
|
||||
for (;;) {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
r = sym_mnt_table_next_fs(table, iter, &fs);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get next entry from '%s': %m", fstab);
|
||||
if (r > 0) /* EOF */
|
||||
return ret;
|
||||
|
||||
r = parse_fstab_one(
|
||||
fstab,
|
||||
sym_mnt_fs_get_source(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),
|
||||
r = parse_fstab_one(fstab,
|
||||
mnt_fs_get_source(fs), mnt_fs_get_target(fs),
|
||||
mnt_fs_get_fstype(fs), mnt_fs_get_options(fs), mnt_fs_get_passno(fs),
|
||||
prefix_sysroot,
|
||||
/* accept_root = */ false,
|
||||
/* use_swap_enabled = */ true);
|
||||
@ -1449,19 +1445,15 @@ static int add_mounts_from_creds(bool prefix_sysroot) {
|
||||
for (;;) {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
r = sym_mnt_table_next_fs(table, iter, &fs);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get next fstab entry from credential '%s': %m", cred);
|
||||
if (r > 0) /* EOF */
|
||||
return ret;
|
||||
|
||||
RET_GATHER(ret, parse_fstab_one(
|
||||
"/run/credentials",
|
||||
sym_mnt_fs_get_source(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),
|
||||
RET_GATHER(ret, parse_fstab_one("/run/credentials",
|
||||
mnt_fs_get_source(fs), mnt_fs_get_target(fs),
|
||||
mnt_fs_get_fstype(fs), mnt_fs_get_options(fs), mnt_fs_get_passno(fs),
|
||||
prefix_sysroot,
|
||||
/* accept_root = */ true,
|
||||
/* use_swap_enabled = */ true));
|
||||
|
||||
@ -4,7 +4,7 @@ executables += [
|
||||
generator_template + {
|
||||
'name' : 'systemd-fstab-generator',
|
||||
'sources' : files('fstab-generator.c'),
|
||||
'dependencies' : libmount_cflags,
|
||||
'dependencies' : libmount,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@ -25,7 +25,6 @@ static int run(int argc, char *argv[]) {
|
||||
"A service to create, remove, change or inspect home areas.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
/* runtime_scope= */ NULL,
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -1988,7 +1988,6 @@ static int run(int argc, char *argv[]) {
|
||||
"Manage the system hostname and related metadata.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
/* runtime_scope= */ NULL,
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -2019,7 +2019,6 @@ static int run(int argc, char *argv[]) {
|
||||
"VM and container image import and export service.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
/* runtime_scope= */ NULL,
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -33,54 +33,32 @@ int user_search_dirs(const char *suffix, char ***ret_config_dirs, char ***ret_da
|
||||
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;
|
||||
|
||||
assert(IN_SET(scope, RUNTIME_SCOPE_SYSTEM, RUNTIME_SCOPE_USER));
|
||||
assert(suffix);
|
||||
assert(ret);
|
||||
|
||||
/* This does not bother with $RUNTIME_DIRECTORY, and hence can be applied to get other service's
|
||||
* 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.
|
||||
*
|
||||
/* Accept $RUNTIME_DIRECTORY as authoritative
|
||||
* 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");
|
||||
if (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)
|
||||
return r;
|
||||
} else {
|
||||
char *d = path_join("/run", suffix);
|
||||
if (!d)
|
||||
return -ENOMEM;
|
||||
*ret = d;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
@ -57,8 +57,7 @@ int lookup_paths_init_or_warn(LookupPaths *lp, RuntimeScope scope, LookupPathsFl
|
||||
void lookup_paths_log(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 *fallback_suffix, char **ret);
|
||||
int runtime_directory(RuntimeScope scope, const char *suffix, char **ret);
|
||||
|
||||
/* 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. */
|
||||
|
||||
@ -635,7 +635,6 @@ static int run(int argc, char *argv[]) {
|
||||
"Manage system locale settings and key mappings.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
/* runtime_scope= */ NULL,
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -1340,7 +1340,6 @@ static int run(int argc, char *argv[]) {
|
||||
"Manager for user logins and devices and privileged operations.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
/* runtime_scope= */ NULL,
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -40,7 +40,6 @@ int bus_image_method_remove(
|
||||
if (m->n_operations >= OPERATIONS_MAX)
|
||||
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[] = {
|
||||
"image", image->name,
|
||||
"verb", "remove",
|
||||
@ -57,7 +56,6 @@ int bus_image_method_remove(
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
|
||||
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");
|
||||
if (r == 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);
|
||||
}
|
||||
|
||||
@ -103,7 +101,6 @@ int bus_image_method_rename(
|
||||
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);
|
||||
|
||||
if (m->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
const char *details[] = {
|
||||
"image", image->name,
|
||||
"verb", "rename",
|
||||
@ -121,7 +118,6 @@ int bus_image_method_rename(
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
r = rename_image_and_update_cache(m, image, new_name);
|
||||
if (r < 0)
|
||||
@ -154,7 +150,6 @@ int bus_image_method_clone(
|
||||
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);
|
||||
|
||||
if (m->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
const char *details[] = {
|
||||
"image", image->name,
|
||||
"verb", "clone",
|
||||
@ -172,7 +167,6 @@ int bus_image_method_clone(
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
|
||||
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) {
|
||||
|
||||
Image *image = userdata;
|
||||
Manager *m = ASSERT_PTR(image->userdata);
|
||||
Manager *m = image->userdata;
|
||||
int read_only, r;
|
||||
|
||||
assert(message);
|
||||
@ -214,7 +208,6 @@ int bus_image_method_mark_read_only(
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (m->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
const char *details[] = {
|
||||
"image", image->name,
|
||||
"verb", "mark_read_only",
|
||||
@ -232,9 +225,8 @@ int bus_image_method_mark_read_only(
|
||||
return r;
|
||||
if (r == 0)
|
||||
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)
|
||||
return r;
|
||||
|
||||
@ -259,7 +251,6 @@ int bus_image_method_set_limit(
|
||||
if (!FILE_SIZE_VALID_OR_INFINITY(limit))
|
||||
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[] = {
|
||||
"machine", image->name,
|
||||
"verb", "set_limit",
|
||||
@ -276,7 +267,6 @@ int bus_image_method_set_limit(
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
r = image_set_limit(image, limit);
|
||||
if (r < 0)
|
||||
@ -290,12 +280,11 @@ int bus_image_method_get_hostname(
|
||||
void *userdata,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Image *image = ASSERT_PTR(userdata);
|
||||
Manager *m = ASSERT_PTR(image->userdata);
|
||||
Image *image = userdata;
|
||||
int r;
|
||||
|
||||
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)
|
||||
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) {
|
||||
|
||||
_cleanup_(sd_bus_message_unrefp) sd_bus_message *reply = NULL;
|
||||
Image *image = ASSERT_PTR(userdata);
|
||||
Manager *m = ASSERT_PTR(image->userdata);
|
||||
Image *image = userdata;
|
||||
int r;
|
||||
|
||||
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)
|
||||
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,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Image *image = ASSERT_PTR(userdata);
|
||||
Manager *m = ASSERT_PTR(image->userdata);
|
||||
Image *image = userdata;
|
||||
int r;
|
||||
|
||||
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)
|
||||
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,
|
||||
sd_bus_error *error) {
|
||||
|
||||
Image *image = ASSERT_PTR(userdata);
|
||||
Manager *m = ASSERT_PTR(image->userdata);
|
||||
Image *image = userdata;
|
||||
int r;
|
||||
|
||||
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)
|
||||
return sd_bus_error_set_errnof(error, r, "Failed to read image metadata: %m");
|
||||
}
|
||||
|
||||
@ -66,17 +66,15 @@ int vl_method_update_image(sd_varlink *link, sd_json_variant *parameters, sd_var
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
manager->system_bus,
|
||||
manager->bus,
|
||||
"org.freedesktop.machine1.manage-images",
|
||||
(const char**) STRV_MAKE("image", image->name,
|
||||
"verb", "update"),
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (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) {
|
||||
r = image_read_only(image, p.read_only, manager->runtime_scope);
|
||||
r = image_read_only(image, p.read_only);
|
||||
if (r < 0)
|
||||
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)
|
||||
return r;
|
||||
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
manager->system_bus,
|
||||
manager->bus,
|
||||
"org.freedesktop.machine1.manage-images",
|
||||
(const char**) STRV_MAKE("image", image->name,
|
||||
"verb", "clone",
|
||||
@ -152,7 +149,6 @@ int vl_method_clone_image(sd_varlink *link, sd_json_variant *parameters, sd_varl
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
|
||||
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)
|
||||
return r;
|
||||
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
manager->system_bus,
|
||||
manager->bus,
|
||||
"org.freedesktop.machine1.manage-images",
|
||||
(const char**) STRV_MAKE("image", image->name,
|
||||
"verb", "remove"),
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (pipe2(errno_pipe_fd, O_CLOEXEC|O_NONBLOCK) < 0)
|
||||
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");
|
||||
if (r == 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);
|
||||
}
|
||||
|
||||
@ -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))
|
||||
return sd_varlink_error_invalid_parameter_name(link, "limit");
|
||||
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
manager->system_bus,
|
||||
manager->bus,
|
||||
"org.freedesktop.machine1.manage-images",
|
||||
(const char**) STRV_MAKE("verb", "set_pool_limit"),
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
/* Set up the machine directory if necessary */
|
||||
r = setup_machine_directory(/* error = */ NULL, /* use_btrfs_subvol= */ true, /* use_btrfs_quota= */ true);
|
||||
if (r < 0)
|
||||
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))
|
||||
return sd_varlink_error(link, VARLINK_ERROR_MACHINE_IMAGE_NOT_SUPPORTED, NULL);
|
||||
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))
|
||||
return sd_varlink_error(link, SD_VARLINK_ERROR_EXPECTED_MORE, NULL);
|
||||
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
manager->system_bus,
|
||||
manager->bus,
|
||||
"org.freedesktop.machine1.manage-images",
|
||||
(const char**) STRV_MAKE("mode", image_clean_pool_mode_to_string(mode),
|
||||
"verb", "clean_pool"),
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
Operation *op;
|
||||
r = image_clean_pool_operation(manager, mode, &op);
|
||||
|
||||
@ -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))
|
||||
continue;
|
||||
|
||||
r = image_remove(image, manager->runtime_scope);
|
||||
r = image_remove(image);
|
||||
if (r == -EBUSY) {
|
||||
log_debug("Keeping image '%s' because it's currently used.", image->name);
|
||||
continue;
|
||||
|
||||
@ -55,7 +55,6 @@ int bus_machine_method_unregister(sd_bus_message *message, void *userdata, sd_bu
|
||||
|
||||
assert(message);
|
||||
|
||||
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
const char *details[] = {
|
||||
"machine", m->name,
|
||||
"verb", "unregister",
|
||||
@ -74,7 +73,6 @@ int bus_machine_method_unregister(sd_bus_message *message, void *userdata, sd_bu
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
r = machine_finalize(m);
|
||||
if (r < 0)
|
||||
@ -89,7 +87,6 @@ int bus_machine_method_terminate(sd_bus_message *message, void *userdata, sd_bus
|
||||
|
||||
assert(message);
|
||||
|
||||
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
const char *details[] = {
|
||||
"machine", m->name,
|
||||
"verb", "terminate",
|
||||
@ -108,7 +105,6 @@ int bus_machine_method_terminate(sd_bus_message *message, void *userdata, sd_bus
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
r = machine_stop(m);
|
||||
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))
|
||||
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[] = {
|
||||
"machine", m->name,
|
||||
"verb", "kill",
|
||||
@ -160,7 +155,6 @@ int bus_machine_method_kill(sd_bus_message *message, void *userdata, sd_bus_erro
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
r = machine_kill(m, whom, signo);
|
||||
if (r < 0)
|
||||
@ -266,7 +260,6 @@ int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_
|
||||
|
||||
assert(message);
|
||||
|
||||
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
const char *details[] = {
|
||||
"machine", m->name,
|
||||
NULL
|
||||
@ -284,7 +277,6 @@ int bus_machine_method_open_pty(sd_bus_message *message, void *userdata, sd_bus_
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name);
|
||||
if (master < 0)
|
||||
@ -310,7 +302,6 @@ int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bu
|
||||
|
||||
assert(message);
|
||||
|
||||
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
const char *details[] = {
|
||||
"machine", m->name,
|
||||
"verb", "login",
|
||||
@ -329,7 +320,6 @@ int bus_machine_method_open_login(sd_bus_message *message, void *userdata, sd_bu
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name);
|
||||
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_close_ int master = -EBADF;
|
||||
_cleanup_strv_free_ char **env = NULL, **args_wire = NULL, **args = NULL;
|
||||
_cleanup_free_ char *command_line = NULL;
|
||||
Machine *m = ASSERT_PTR(userdata);
|
||||
const char *user, *path;
|
||||
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))
|
||||
return sd_bus_error_set(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid environment assignments");
|
||||
|
||||
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
_cleanup_free_ char *command_line = strv_join(args, " ");
|
||||
command_line = strv_join(args, " ");
|
||||
if (!command_line)
|
||||
return -ENOMEM;
|
||||
|
||||
const char *details[] = {
|
||||
"machine", m->name,
|
||||
"user", user,
|
||||
@ -436,7 +425,6 @@ int bus_machine_method_open_shell(sd_bus_message *message, void *userdata, sd_bu
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
master = machine_openpt(m, O_RDWR|O_NOCTTY|O_CLOEXEC, &pty_name);
|
||||
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))
|
||||
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[] = {
|
||||
"machine", m->name,
|
||||
"verb", "bind",
|
||||
@ -502,7 +489,6 @@ int bus_machine_method_bind_mount(sd_bus_message *message, void *userdata, sd_bu
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
r = machine_get_uid_shift(m, &uid);
|
||||
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))
|
||||
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[] = {
|
||||
"machine", m->name,
|
||||
"verb", "copy",
|
||||
@ -590,7 +575,6 @@ int bus_machine_method_copy(sd_bus_message *message, void *userdata, sd_bus_erro
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
if (m->manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
const char *details[] = {
|
||||
"machine", m->name,
|
||||
"verb", "open_root_directory",
|
||||
@ -636,7 +619,6 @@ int bus_machine_method_open_root_directory(sd_bus_message *message, void *userda
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
fd = machine_open_root_directory(m);
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(fd))
|
||||
@ -880,7 +862,7 @@ int machine_send_signal(Machine *m, bool new_machine) {
|
||||
return -ENOMEM;
|
||||
|
||||
return sd_bus_emit_signal(
|
||||
m->manager->api_bus,
|
||||
m->manager->bus,
|
||||
"/org/freedesktop/machine1",
|
||||
"org.freedesktop.machine1.Manager",
|
||||
new_machine ? "MachineNew" : "MachineRemoved",
|
||||
|
||||
@ -155,17 +155,15 @@ int vl_method_register(sd_varlink *link, sd_json_variant *parameters, sd_varlink
|
||||
if (r != 0)
|
||||
return r;
|
||||
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
manager->system_bus,
|
||||
manager->bus,
|
||||
machine->allocate_unit ? "org.freedesktop.machine1.create-machine" : "org.freedesktop.machine1.register-machine",
|
||||
(const char**) STRV_MAKE("name", machine->name,
|
||||
"class", machine_class_to_string(machine->class)),
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
if (!pidref_is_set(&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);
|
||||
int r;
|
||||
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
r = varlink_verify_polkit_async_full(
|
||||
link,
|
||||
manager->system_bus,
|
||||
manager->bus,
|
||||
"org.freedesktop.machine1.manage-machines",
|
||||
(const char**) STRV_MAKE("name", machine->name,
|
||||
"verb", "unregister"),
|
||||
@ -320,7 +317,6 @@ int vl_method_unregister_internal(sd_varlink *link, sd_json_variant *parameters,
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = machine_finalize(machine);
|
||||
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);
|
||||
int r;
|
||||
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
r = varlink_verify_polkit_async_full(
|
||||
link,
|
||||
manager->system_bus,
|
||||
manager->bus,
|
||||
"org.freedesktop.machine1.manage-machines",
|
||||
(const char**) STRV_MAKE("name", machine->name,
|
||||
"verb", "terminate"),
|
||||
@ -346,7 +341,6 @@ int vl_method_terminate_internal(sd_varlink *link, sd_json_variant *parameters,
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = machine_stop(machine);
|
||||
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");
|
||||
}
|
||||
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
r = varlink_verify_polkit_async_full(
|
||||
link,
|
||||
manager->system_bus,
|
||||
manager->bus,
|
||||
"org.freedesktop.machine1.manage-machines",
|
||||
(const char**) STRV_MAKE("name", machine->name,
|
||||
"verb", "kill"),
|
||||
@ -418,7 +411,6 @@ int vl_method_kill(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = machine_kill(machine, whom, p.signo);
|
||||
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_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 */
|
||||
_cleanup_strv_free_ char **args = NULL;
|
||||
Machine *machine;
|
||||
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)
|
||||
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);
|
||||
r = varlink_verify_polkit_async_full(
|
||||
link,
|
||||
manager->system_bus,
|
||||
manager->bus,
|
||||
machine_open_polkit_action(p.mode, machine->class),
|
||||
(const char**) polkit_details,
|
||||
machine->uid,
|
||||
@ -565,7 +554,6 @@ int vl_method_open(sd_varlink *link, sd_json_variant *parameters, sd_varlink_met
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
ptmx_fd = machine_openpt(machine, O_RDWR|O_NOCTTY|O_CLOEXEC, &ptmx_name);
|
||||
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)
|
||||
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 */
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
manager->system_bus,
|
||||
manager->bus,
|
||||
"org.freedesktop.machine1.manage-machines",
|
||||
(const char**) STRV_MAKE("name", machine->name,
|
||||
"verb", "bind",
|
||||
@ -849,7 +836,6 @@ int vl_method_bind_mount(sd_varlink *link, sd_json_variant *parameters, sd_varli
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
r = machine_get_uid_shift(machine, &uid_shift);
|
||||
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)
|
||||
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 */
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
manager->system_bus,
|
||||
manager->bus,
|
||||
"org.freedesktop.machine1.manage-machines",
|
||||
(const char**) STRV_MAKE("name", machine->name,
|
||||
"verb", "copy",
|
||||
@ -963,7 +948,6 @@ int vl_method_copy_internal(sd_varlink *link, sd_json_variant *parameters, sd_va
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
Operation *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;
|
||||
|
||||
/* NB: For now not opened up to owner of machine without auth */
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
r = varlink_verify_polkit_async(
|
||||
link,
|
||||
manager->system_bus,
|
||||
manager->bus,
|
||||
"org.freedesktop.machine1.manage-machines",
|
||||
(const char**) STRV_MAKE("name", machine->name,
|
||||
"verb", "open_root_directory"),
|
||||
&manager->polkit_registry);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
}
|
||||
|
||||
fd = machine_open_root_directory(machine);
|
||||
if (ERRNO_IS_NEG_NOT_SUPPORTED(fd))
|
||||
|
||||
@ -88,7 +88,7 @@ int machine_link(Manager *manager, Machine *machine) {
|
||||
return -EINVAL;
|
||||
|
||||
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)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -170,14 +170,14 @@ int machine_save(Machine *m) {
|
||||
|
||||
_cleanup_(unlink_and_freep) char *sl = NULL; /* auto-unlink! */
|
||||
if (m->unit && !m->subgroup) {
|
||||
sl = strjoin(m->manager->state_dir, "/unit:", m->unit);
|
||||
sl = strjoin("/run/systemd/machines/unit:", m->unit);
|
||||
if (!sl)
|
||||
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)
|
||||
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_fclose_ FILE *f = NULL;
|
||||
@ -267,7 +267,7 @@ static void machine_unlink(Machine *m) {
|
||||
assert(m);
|
||||
|
||||
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);
|
||||
}
|
||||
|
||||
@ -438,7 +438,7 @@ static int machine_start_scope(
|
||||
return log_oom();
|
||||
|
||||
r = bus_message_new_method_call(
|
||||
machine->manager->api_bus,
|
||||
machine->manager->bus,
|
||||
&m,
|
||||
bus_systemd_mgr,
|
||||
"StartTransientUnit");
|
||||
@ -920,7 +920,7 @@ int machine_start_getty(Machine *m, const char *ptmx_name, sd_bus_error *error)
|
||||
if (r < 0)
|
||||
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");
|
||||
|
||||
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)
|
||||
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");
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -104,7 +104,6 @@ static const char* arg_format = NULL;
|
||||
static const char *arg_uid = NULL;
|
||||
static char **arg_setenv = NULL;
|
||||
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_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"
|
||||
" -H --host=[USER@]HOST Operate on remote host\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"
|
||||
" --value When showing properties, only print the value\n"
|
||||
" -P NAME Equivalent to --value --property=NAME\n"
|
||||
@ -2155,8 +2152,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
ARG_FORMAT,
|
||||
ARG_UID,
|
||||
ARG_MAX_ADDRESSES,
|
||||
ARG_SYSTEM,
|
||||
ARG_USER,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
@ -2186,8 +2181,6 @@ static int parse_argv(int argc, char *argv[]) {
|
||||
{ "uid", required_argument, NULL, ARG_UID },
|
||||
{ "setenv", required_argument, NULL, 'E' },
|
||||
{ "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);
|
||||
break;
|
||||
|
||||
case ARG_USER:
|
||||
arg_runtime_scope = RUNTIME_SCOPE_USER;
|
||||
break;
|
||||
|
||||
case ARG_SYSTEM:
|
||||
arg_runtime_scope = RUNTIME_SCOPE_SYSTEM;
|
||||
break;
|
||||
|
||||
case '?':
|
||||
return -EINVAL;
|
||||
|
||||
@ -2503,9 +2488,9 @@ static int run(int argc, char *argv[]) {
|
||||
"list-transfers", "cancel-transfer"))
|
||||
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)
|
||||
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);
|
||||
|
||||
|
||||
@ -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");
|
||||
}
|
||||
|
||||
if (manager->runtime_scope != RUNTIME_SCOPE_USER) {
|
||||
const char *details[] = {
|
||||
"name", name,
|
||||
"class", machine_class_to_string(c),
|
||||
@ -295,7 +294,6 @@ static int machine_add_from_params(
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 0; /* Will call us back */
|
||||
}
|
||||
|
||||
r = manager_add_machine(manager, name, &m);
|
||||
if (r < 0)
|
||||
@ -699,18 +697,7 @@ static int method_register_machine(sd_bus_message *message, void *userdata, sd_b
|
||||
if (r == 0)
|
||||
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);
|
||||
break;
|
||||
|
||||
default:
|
||||
assert_not_reached();
|
||||
}
|
||||
if (r < 0) {
|
||||
r = sd_bus_error_set_errnof(error, r,
|
||||
"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
|
||||
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[] = {
|
||||
"verb", "clean_pool",
|
||||
"mode", mm,
|
||||
@ -1013,7 +999,6 @@ static int method_clean_pool(sd_bus_message *message, void *userdata, sd_bus_err
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
r = image_clean_pool_operation(m, mode, &operation);
|
||||
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))
|
||||
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[] = {
|
||||
"verb", "set_pool_limit",
|
||||
NULL
|
||||
@ -1053,14 +1037,13 @@ static int method_set_pool_limit(sd_bus_message *message, void *userdata, sd_bus
|
||||
return r;
|
||||
if (r == 0)
|
||||
return 1; /* Will call us back */
|
||||
}
|
||||
|
||||
/* Set up the machine directory if necessary */
|
||||
r = setup_machine_directory(error, /* use_btrfs_subvol= */ true, /* use_btrfs_quota= */ true);
|
||||
if (r < 0)
|
||||
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))
|
||||
return sd_bus_error_set(error, SD_BUS_ERROR_NOT_SUPPORTED, "Quota is only supported on btrfs.");
|
||||
if (r < 0)
|
||||
@ -1551,7 +1534,7 @@ int manager_unref_unit(
|
||||
assert(m);
|
||||
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) {
|
||||
@ -1561,7 +1544,7 @@ int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, c
|
||||
assert(manager);
|
||||
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 (sd_bus_error_has_names(error, BUS_ERROR_NO_SUCH_UNIT,
|
||||
BUS_ERROR_LOAD_FAILED)) {
|
||||
@ -1599,9 +1582,9 @@ int manager_kill_unit(Manager *manager, const char *unit, const char *subgroup,
|
||||
assert(unit);
|
||||
|
||||
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) {
|
||||
@ -1619,7 +1602,7 @@ int manager_unit_is_active(Manager *manager, const char *unit, sd_bus_error *ret
|
||||
return -ENOMEM;
|
||||
|
||||
r = sd_bus_get_property(
|
||||
manager->api_bus,
|
||||
manager->bus,
|
||||
"org.freedesktop.systemd1",
|
||||
path,
|
||||
"org.freedesktop.systemd1.Unit",
|
||||
@ -1655,7 +1638,7 @@ int manager_job_is_active(Manager *manager, const char *path, sd_bus_error *rete
|
||||
assert(path);
|
||||
|
||||
r = sd_bus_get_property(
|
||||
manager->api_bus,
|
||||
manager->bus,
|
||||
"org.freedesktop.systemd1",
|
||||
path,
|
||||
"org.freedesktop.systemd1.Job",
|
||||
|
||||
@ -18,7 +18,6 @@
|
||||
#include "machine-varlink.h"
|
||||
#include "machined.h"
|
||||
#include "machined-varlink.h"
|
||||
#include "path-lookup.h"
|
||||
#include "string-util.h"
|
||||
#include "strv.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);
|
||||
}
|
||||
|
||||
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;
|
||||
|
||||
assert(m);
|
||||
assert(link);
|
||||
assert(image);
|
||||
|
||||
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)
|
||||
return log_debug_errno(r, "Failed to read image metadata: %m");
|
||||
if (r < 0)
|
||||
@ -699,7 +697,7 @@ static int vl_method_list_images(sd_varlink *link, sd_json_variant *parameters,
|
||||
if (r < 0)
|
||||
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))
|
||||
@ -713,7 +711,7 @@ static int vl_method_list_images(sd_varlink *link, sd_json_variant *parameters,
|
||||
Image *image, *previous = NULL;
|
||||
HASHMAP_FOREACH(image, images) {
|
||||
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)
|
||||
return r;
|
||||
}
|
||||
@ -722,7 +720,7 @@ static int vl_method_list_images(sd_varlink *link, sd_json_variant *parameters,
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
@ -735,8 +733,6 @@ static int manager_varlink_init_userdb(Manager *m) {
|
||||
|
||||
if (m->varlink_userdb_server)
|
||||
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);
|
||||
if (r < 0)
|
||||
@ -821,20 +817,11 @@ static int manager_varlink_init_machine(Manager *m) {
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind to passed Varlink sockets: %m");
|
||||
if (r == 0) {
|
||||
_cleanup_free_ char *socket_path = NULL;
|
||||
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);
|
||||
r = sd_varlink_server_listen_address(s, "/run/systemd/machine/io.systemd.Machine", 0666 | SD_VARLINK_SERVER_MODE_MKDIR_0755);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind to io.systemd.Machine varlink socket: %m");
|
||||
|
||||
socket_path = mfree(socket_path);
|
||||
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));
|
||||
r = sd_varlink_server_listen_address(s, "/run/systemd/machine/io.systemd.MachineImage", 0666);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to bind to io.systemd.MachineImage varlink socket: %m");
|
||||
}
|
||||
|
||||
@ -27,7 +27,6 @@
|
||||
#include "main-func.h"
|
||||
#include "mkdir-label.h"
|
||||
#include "operation.h"
|
||||
#include "path-lookup.h"
|
||||
#include "service-util.h"
|
||||
#include "signal-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);
|
||||
|
||||
static int manager_new(RuntimeScope scope, Manager **ret) {
|
||||
static int manager_new(Manager **ret) {
|
||||
_cleanup_(manager_unrefp) Manager *m = NULL;
|
||||
int r;
|
||||
|
||||
@ -50,13 +49,9 @@ static int manager_new(RuntimeScope scope, Manager **ret) {
|
||||
return -ENOMEM;
|
||||
|
||||
*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);
|
||||
if (!m->machines)
|
||||
return -ENOMEM;
|
||||
@ -110,12 +105,9 @@ static Manager* manager_unref(Manager *m) {
|
||||
|
||||
manager_varlink_done(m);
|
||||
|
||||
sd_bus_flush_close_unref(m->api_bus);
|
||||
sd_bus_flush_close_unref(m->system_bus);
|
||||
sd_bus_flush_close_unref(m->bus);
|
||||
sd_event_unref(m->event);
|
||||
|
||||
free(m->state_dir);
|
||||
|
||||
return mfree(m);
|
||||
}
|
||||
|
||||
@ -126,8 +118,6 @@ static int manager_add_host_machine(Manager *m) {
|
||||
Machine *t;
|
||||
int r;
|
||||
|
||||
if (m->runtime_scope != RUNTIME_SCOPE_SYSTEM)
|
||||
return 0;
|
||||
if (m->host_machine)
|
||||
return 0;
|
||||
|
||||
@ -184,12 +174,12 @@ static int manager_enumerate_machines(Manager *m) {
|
||||
return r;
|
||||
|
||||
/* Read in machine data stored on disk */
|
||||
d = opendir(m->state_dir);
|
||||
d = opendir("/run/systemd/machines");
|
||||
if (!d) {
|
||||
if (errno == ENOENT)
|
||||
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) {
|
||||
@ -224,45 +214,26 @@ static int manager_connect_bus(Manager *m) {
|
||||
int r;
|
||||
|
||||
assert(m);
|
||||
assert(!m->system_bus);
|
||||
assert(!m->api_bus);
|
||||
assert(!m->bus);
|
||||
|
||||
r = sd_bus_default_system(&m->system_bus);
|
||||
r = sd_bus_default_system(&m->bus);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to connect to system bus: %m");
|
||||
|
||||
r = sd_bus_attach_event(m->system_bus, m->event, 0);
|
||||
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);
|
||||
r = bus_add_implementation(m->bus, &manager_object, m);
|
||||
if (r < 0)
|
||||
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)
|
||||
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)
|
||||
return log_error_errno(r, "Failed to request match for UnitRemoved: %m");
|
||||
|
||||
r = sd_bus_match_signal_async(
|
||||
m->api_bus,
|
||||
m->bus,
|
||||
NULL,
|
||||
"org.freedesktop.systemd1",
|
||||
NULL,
|
||||
@ -272,22 +243,26 @@ static int manager_connect_bus(Manager *m) {
|
||||
if (r < 0)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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)
|
||||
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;
|
||||
}
|
||||
|
||||
@ -340,7 +315,6 @@ static bool check_idle(void *userdata) {
|
||||
|
||||
static int run(int argc, char *argv[]) {
|
||||
_cleanup_(manager_unrefp) Manager *m = NULL;
|
||||
RuntimeScope scope = RUNTIME_SCOPE_SYSTEM;
|
||||
int r;
|
||||
|
||||
log_set_facility(LOG_AUTH);
|
||||
@ -350,7 +324,6 @@ static int run(int argc, char *argv[]) {
|
||||
"Manage registrations of local VMs and containers.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
&scope,
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
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
|
||||
* for the existence of /run/systemd/machines/ to determine whether machined is available, so please always
|
||||
* make sure this check stays in. */
|
||||
if (scope == RUNTIME_SCOPE_SYSTEM)
|
||||
(void) mkdir_label("/run/systemd/machines", 0755);
|
||||
|
||||
assert_se(sigprocmask_many(SIG_BLOCK, /* ret_old_mask= */ NULL, SIGCHLD) >= 0);
|
||||
|
||||
r = manager_new(scope, &m);
|
||||
r = manager_new(&m);
|
||||
if (r < 0)
|
||||
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(
|
||||
m->event,
|
||||
m->api_bus,
|
||||
m->bus,
|
||||
"org.freedesktop.machine1",
|
||||
DEFAULT_EXIT_USEC,
|
||||
check_idle, m);
|
||||
|
||||
@ -7,8 +7,7 @@
|
||||
|
||||
typedef struct Manager {
|
||||
sd_event *event;
|
||||
sd_bus *api_bus; /* this is where we offer our services */
|
||||
sd_bus *system_bus; /* this is where we talk to system services on, for example PK or so */
|
||||
sd_bus *bus;
|
||||
|
||||
Hashmap *machines;
|
||||
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_machine_server;
|
||||
|
||||
RuntimeScope runtime_scope;
|
||||
char *state_dir;
|
||||
RuntimeScope runtime_scope; /* for now: always RUNTIME_SCOPE_SYSTEM */
|
||||
} Manager;
|
||||
|
||||
int manager_add_machine(Manager *m, const char *name, Machine **ret);
|
||||
|
||||
@ -49,8 +49,5 @@ install_data('org.freedesktop.machine1.conf',
|
||||
install_dir : dbuspolicydir)
|
||||
install_data('org.freedesktop.machine1.service',
|
||||
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_dir : polkitpolicydir)
|
||||
|
||||
@ -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
|
||||
@ -5,7 +5,7 @@ executables += [
|
||||
'name' : 'systemd-mount',
|
||||
'public' : true,
|
||||
'sources' : files('mount-tool.c'),
|
||||
'dependencies' : libmount_cflags,
|
||||
'dependencies' : libmount,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
@ -860,14 +860,14 @@ static int find_mount_points_by_source(const char *what, char ***ret) {
|
||||
struct libmnt_fs *fs;
|
||||
const char *source, *target;
|
||||
|
||||
r = sym_mnt_table_next_fs(table, iter, &fs);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r == 1)
|
||||
break;
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
|
||||
|
||||
source = sym_mnt_fs_get_source(fs);
|
||||
target = sym_mnt_fs_get_target(fs);
|
||||
source = mnt_fs_get_source(fs);
|
||||
target = mnt_fs_get_target(fs);
|
||||
if (!source || !target)
|
||||
continue;
|
||||
|
||||
|
||||
@ -29,7 +29,6 @@ static int run(int argc, char *argv[]) {
|
||||
r = service_parse_argv("systemd-networkd.service",
|
||||
"Manage and configure network devices, create virtual network devices",
|
||||
BUS_IMPLEMENTATIONS(&manager_object, &log_control_object),
|
||||
/* runtime_scope= */ NULL,
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -294,7 +294,6 @@ int register_machine(
|
||||
return 0;
|
||||
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));
|
||||
sd_bus_error_free(&error);
|
||||
if (FLAGS_SET(flags, REGISTER_MACHINE_KEEP_UNIT)) {
|
||||
r = bus_call_method(
|
||||
bus,
|
||||
|
||||
@ -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
|
||||
* only owned by us and no one else. */
|
||||
r = image_path_lock(
|
||||
arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER,
|
||||
np,
|
||||
LOCK_EX|LOCK_NB,
|
||||
arg_privileged ? &tree_global_lock : NULL,
|
||||
@ -6092,7 +6091,6 @@ static int run(int argc, char *argv[]) {
|
||||
goto finish;
|
||||
|
||||
r = image_path_lock(
|
||||
arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER,
|
||||
arg_directory,
|
||||
(arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB,
|
||||
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. */
|
||||
r = image_path_lock(
|
||||
arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER,
|
||||
np,
|
||||
LOCK_EX|LOCK_NB,
|
||||
arg_privileged ? &tree_global_lock : NULL,
|
||||
@ -6248,7 +6245,6 @@ static int run(int argc, char *argv[]) {
|
||||
remove_image = true;
|
||||
} else {
|
||||
r = image_path_lock(
|
||||
arg_privileged ? RUNTIME_SCOPE_SYSTEM : RUNTIME_SCOPE_USER,
|
||||
arg_image,
|
||||
(arg_read_only ? LOCK_SH : LOCK_EX) | LOCK_NB,
|
||||
arg_privileged ? &tree_global_lock : NULL,
|
||||
|
||||
@ -61,7 +61,7 @@ int bus_image_common_get_os_release(
|
||||
return 1;
|
||||
|
||||
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)
|
||||
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) {
|
||||
errno_pipe_fd[0] = safe_close(errno_pipe_fd[0]);
|
||||
|
||||
r = image_remove(image, m->runtime_scope);
|
||||
r = image_remove(image);
|
||||
if (r < 0) {
|
||||
(void) write(errno_pipe_fd[1], &r, sizeof(r));
|
||||
_exit(EXIT_FAILURE);
|
||||
@ -801,7 +801,7 @@ int bus_image_common_mark_read_only(
|
||||
if (r == 0)
|
||||
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)
|
||||
return r;
|
||||
|
||||
|
||||
@ -133,7 +133,6 @@ static int run(int argc, char *argv[]) {
|
||||
"Manage registrations of portable images.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
/* runtime_scope= */ NULL,
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -4,6 +4,6 @@ executables += [
|
||||
libexec_template + {
|
||||
'name' : 'systemd-remount-fs',
|
||||
'sources' : files('remount-fs.c'),
|
||||
'dependencies' : libmount_cflags,
|
||||
'dependencies' : libmount,
|
||||
},
|
||||
]
|
||||
|
||||
@ -90,13 +90,13 @@ static int remount_by_fstab(Hashmap **ret_pids) {
|
||||
for (;;) {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
r = sym_mnt_table_next_fs(table, iter, &fs);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r < 0)
|
||||
return log_error_errno(r, "Failed to get next entry from fstab: %m");
|
||||
if (r > 0) /* EOF */
|
||||
break;
|
||||
|
||||
const char *target = sym_mnt_fs_get_target(fs);
|
||||
const char *target = mnt_fs_get_target(fs);
|
||||
if (!target)
|
||||
continue;
|
||||
|
||||
|
||||
@ -30,7 +30,6 @@ static int run(int argc, char *argv[]) {
|
||||
"Provide name resolution with caching using DNS, mDNS, LLMNR.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
/* runtime_scope= */ NULL,
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -19,7 +19,6 @@
|
||||
#include "chase.h"
|
||||
#include "chattr-util.h"
|
||||
#include "copy.h"
|
||||
#include "devnum-util.h"
|
||||
#include "dirent-util.h"
|
||||
#include "discover-image.h"
|
||||
#include "dissect-image.h"
|
||||
@ -38,7 +37,6 @@
|
||||
#include "mkdir.h"
|
||||
#include "nulstr-util.h"
|
||||
#include "os-util.h"
|
||||
#include "path-lookup.h"
|
||||
#include "path-util.h"
|
||||
#include "rm-rf.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);
|
||||
|
||||
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) {
|
||||
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,
|
||||
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_free_ char *fn = NULL;
|
||||
size_t i = 0;
|
||||
@ -157,7 +146,7 @@ static char** image_settings_path(Image *image, RuntimeScope scope) {
|
||||
|
||||
assert(image);
|
||||
|
||||
l = new0(char*, 5);
|
||||
l = new0(char*, 4);
|
||||
if (!l)
|
||||
return NULL;
|
||||
|
||||
@ -165,41 +154,7 @@ static char** image_settings_path(Image *image, RuntimeScope scope) {
|
||||
if (!fn)
|
||||
return NULL;
|
||||
|
||||
static const uint64_t system_locations[] = {
|
||||
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;
|
||||
|
||||
FOREACH_STRING(s, "/etc/systemd/nspawn", "/run/systemd/nspawn") {
|
||||
l[i] = path_join(s, fn);
|
||||
if (!l[i])
|
||||
return NULL;
|
||||
@ -1131,7 +1086,7 @@ int image_discover(
|
||||
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_strv_free_ char **settings = 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))
|
||||
return -EROFS;
|
||||
|
||||
settings = image_settings_path(i, scope);
|
||||
settings = image_settings_path(i);
|
||||
if (!settings)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1151,7 +1106,7 @@ int image_remove(Image *i, RuntimeScope scope) {
|
||||
return r;
|
||||
|
||||
/* 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)
|
||||
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))
|
||||
return -EROFS;
|
||||
|
||||
settings = image_settings_path(i, scope);
|
||||
settings = image_settings_path(i);
|
||||
if (!settings)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -1246,14 +1201,14 @@ int image_rename(Image *i, const char *new_name, RuntimeScope scope) {
|
||||
return r;
|
||||
|
||||
/* 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)
|
||||
return r;
|
||||
|
||||
/* Make sure nobody takes the new name, between the time we
|
||||
* checked it is currently unused in all search paths, and the
|
||||
* 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)
|
||||
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);
|
||||
}
|
||||
|
||||
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) {
|
||||
_cleanup_(release_lock_file) LockFile name_lock = LOCK_FILE_INIT;
|
||||
_cleanup_strv_free_ char **settings = NULL;
|
||||
_cleanup_free_ char *roothash = NULL;
|
||||
const char *new_path;
|
||||
int r;
|
||||
|
||||
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))
|
||||
return -EINVAL;
|
||||
|
||||
settings = image_settings_path(i, scope);
|
||||
settings = image_settings_path(i);
|
||||
if (!settings)
|
||||
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
|
||||
* checked it is currently unused in all search paths, and the
|
||||
* 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)
|
||||
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)
|
||||
return -EEXIST;
|
||||
if (r != -ENOENT)
|
||||
@ -1433,14 +1335,11 @@ int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope sco
|
||||
switch (i->type) {
|
||||
|
||||
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
|
||||
* directory. */
|
||||
|
||||
_cleanup_free_ char *new_path = NULL;
|
||||
r = get_pool_directory(scope, i->class, new_name, /* suffix= */ NULL, &new_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
new_path = strjoina("/var/lib/machines/", new_name);
|
||||
|
||||
r = btrfs_subvol_snapshot_at(AT_FDCWD, i->path, AT_FDCWD, new_path,
|
||||
(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);
|
||||
|
||||
break;
|
||||
}
|
||||
|
||||
case IMAGE_RAW: {
|
||||
_cleanup_free_ char *new_path = NULL;
|
||||
r = get_pool_directory(scope, i->class, new_name, ".raw", &new_path);
|
||||
if (r < 0)
|
||||
return r;
|
||||
case IMAGE_RAW:
|
||||
new_path = strjoina("/var/lib/machines/", new_name, ".raw");
|
||||
|
||||
r = copy_file_atomic(i->path, new_path, read_only ? 0444 : 0644,
|
||||
COPY_REFLINK|COPY_CRTIME|COPY_NOCOW_AFTER);
|
||||
break;
|
||||
}
|
||||
|
||||
case IMAGE_BLOCK:
|
||||
default:
|
||||
return -EOPNOTSUPP;
|
||||
}
|
||||
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -1487,7 +1382,7 @@ int image_clone(Image *i, const char *new_name, bool read_only, RuntimeScope sco
|
||||
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;
|
||||
int r;
|
||||
|
||||
@ -1497,7 +1392,7 @@ int image_read_only(Image *i, bool b, RuntimeScope scope) {
|
||||
return -EROFS;
|
||||
|
||||
/* 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)
|
||||
return r;
|
||||
|
||||
@ -1574,33 +1469,12 @@ int image_read_only(Image *i, bool b, RuntimeScope scope) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int make_lock_dir(RuntimeScope scope) {
|
||||
int r;
|
||||
|
||||
_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;
|
||||
static void make_lock_dir(void) {
|
||||
(void) mkdir_p("/run/systemd/nspawn", 0755);
|
||||
(void) mkdir("/run/systemd/nspawn/locks", 0700);
|
||||
}
|
||||
|
||||
int image_path_lock(
|
||||
RuntimeScope scope,
|
||||
const char *path,
|
||||
int operation,
|
||||
LockFile *ret_global,
|
||||
@ -1616,7 +1490,7 @@ int image_path_lock(
|
||||
assert(ret_local);
|
||||
|
||||
/* 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,
|
||||
* correctly. */
|
||||
|
||||
@ -1660,21 +1534,15 @@ int image_path_lock(
|
||||
}
|
||||
|
||||
if (ret_global) {
|
||||
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 (stat(path, &st) >= 0) {
|
||||
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))
|
||||
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
|
||||
return -ENOTTY;
|
||||
if (r < 0)
|
||||
return r;
|
||||
return -ENOMEM;
|
||||
}
|
||||
}
|
||||
|
||||
@ -1683,15 +1551,15 @@ int image_path_lock(
|
||||
if (!path_startswith(path, "/dev/")) {
|
||||
r = make_lock_file_for(path, operation, &t);
|
||||
if (r < 0) {
|
||||
if (exclusive || r != -EROFS)
|
||||
return r;
|
||||
|
||||
if (!exclusive && r == -EROFS)
|
||||
log_debug_errno(r, "Failed to create shared lock for '%s', ignoring: %m", path);
|
||||
else
|
||||
return r;
|
||||
}
|
||||
}
|
||||
|
||||
if (p) {
|
||||
(void) make_lock_dir(scope);
|
||||
make_lock_dir();
|
||||
|
||||
r = make_lock_file(p, operation, ret_global);
|
||||
if (r < 0) {
|
||||
@ -1731,39 +1599,36 @@ int image_set_limit(Image *i, uint64_t referenced_max) {
|
||||
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;
|
||||
|
||||
assert(scope >= 0 && scope < _RUNTIME_SCOPE_MAX);
|
||||
assert(class >= 0 && class < _IMAGE_CLASS_MAX);
|
||||
|
||||
_cleanup_free_ char *pool = NULL;
|
||||
r = get_pool_directory(scope, class, /* fname= */ NULL, /* suffix= */ NULL, &pool);
|
||||
if (r < 0)
|
||||
return r;
|
||||
dir = image_root_to_string(class);
|
||||
|
||||
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))
|
||||
return r;
|
||||
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))
|
||||
return r;
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
int r;
|
||||
|
||||
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)
|
||||
return r;
|
||||
|
||||
@ -1893,13 +1758,8 @@ int image_read_metadata(Image *i, const ImagePolicy *image_policy, RuntimeScope
|
||||
return 0;
|
||||
}
|
||||
|
||||
int image_name_lock(
|
||||
RuntimeScope scope,
|
||||
const char *name,
|
||||
int operation,
|
||||
LockFile *ret) {
|
||||
|
||||
int r;
|
||||
int image_name_lock(const char *name, int operation, LockFile *ret) {
|
||||
const char *p;
|
||||
|
||||
assert(name);
|
||||
assert(ret);
|
||||
@ -1917,16 +1777,9 @@ int image_name_lock(
|
||||
return 0;
|
||||
}
|
||||
|
||||
(void) make_lock_dir(scope);
|
||||
|
||||
_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;
|
||||
make_lock_dir();
|
||||
|
||||
p = strjoina("/run/systemd/nspawn/locks/name-", name);
|
||||
return make_lock_file(p, operation, ret);
|
||||
}
|
||||
|
||||
|
||||
@ -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_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_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_;
|
||||
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_name_lock(RuntimeScope scope, const char *name, int operation, LockFile *ret);
|
||||
int image_path_lock(const char *path, int operation, LockFile *global, LockFile *local);
|
||||
int image_name_lock(const char *name, int operation, LockFile *ret);
|
||||
|
||||
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);
|
||||
|
||||
|
||||
@ -56,13 +56,13 @@ int fstab_has_fstype(const char *fstype) {
|
||||
for (;;) {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
r = sym_mnt_table_next_fs(table, iter, &fs);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0) /* EOF */
|
||||
return false;
|
||||
|
||||
if (streq_ptr(sym_mnt_fs_get_fstype(fs), fstype))
|
||||
if (streq_ptr(mnt_fs_get_fstype(fs), fstype))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -134,13 +134,13 @@ int fstab_has_mount_point_prefix_strv(char * const *prefixes) {
|
||||
struct libmnt_fs *fs;
|
||||
const char *path;
|
||||
|
||||
r = sym_mnt_table_next_fs(table, iter, &fs);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0) /* EOF */
|
||||
return false;
|
||||
|
||||
path = sym_mnt_fs_get_target(fs);
|
||||
path = mnt_fs_get_target(fs);
|
||||
if (!path)
|
||||
continue;
|
||||
|
||||
@ -168,19 +168,19 @@ int fstab_is_mount_point_full(const char *where, const char *path) {
|
||||
for (;;) {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
r = sym_mnt_table_next_fs(table, iter, &fs);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r < 0)
|
||||
return r;
|
||||
if (r > 0) /* EOF */
|
||||
return false;
|
||||
|
||||
if (where && !path_equal(sym_mnt_fs_get_target(fs), where))
|
||||
if (where && !path_equal(mnt_fs_get_target(fs), where))
|
||||
continue;
|
||||
|
||||
if (!path)
|
||||
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)))
|
||||
return r;
|
||||
}
|
||||
|
||||
@ -6,83 +6,6 @@
|
||||
#include "libmount-util.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(
|
||||
const char *path,
|
||||
FILE *source,
|
||||
@ -96,12 +19,8 @@ int libmount_parse_full(
|
||||
/* Older libmount seems to require this. */
|
||||
assert(!source || path);
|
||||
|
||||
r = dlopen_libmount();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
table = sym_mnt_new_table();
|
||||
iter = sym_mnt_new_iter(MNT_ITER_FORWARD);
|
||||
table = mnt_new_table();
|
||||
iter = mnt_new_iter(MNT_ITER_FORWARD);
|
||||
if (!table || !iter)
|
||||
return -ENOMEM;
|
||||
|
||||
@ -109,11 +28,11 @@ int libmount_parse_full(
|
||||
* Only if both are empty, we use mnt_table_parse_mtab(). */
|
||||
|
||||
if (source)
|
||||
r = sym_mnt_table_parse_stream(table, source, path);
|
||||
r = mnt_table_parse_stream(table, source, path);
|
||||
else if (path)
|
||||
r = sym_mnt_table_parse_file(table, path);
|
||||
r = mnt_table_parse_file(table, path);
|
||||
else
|
||||
r = sym_mnt_table_parse_mtab(table, NULL);
|
||||
r = mnt_table_parse_mtab(table, NULL);
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
@ -134,16 +53,14 @@ int libmount_is_leaf(
|
||||
struct libmnt_fs *fs) {
|
||||
int r;
|
||||
|
||||
assert(table);
|
||||
|
||||
_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)
|
||||
return log_oom();
|
||||
|
||||
/* We care only whether it exists, it is unused */
|
||||
_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)
|
||||
return r;
|
||||
|
||||
|
||||
@ -4,45 +4,10 @@
|
||||
/* This needs to be after sys/mount.h */
|
||||
#include <libmount.h> /* IWYU pragma: export */
|
||||
|
||||
#include "dlfcn-util.h"
|
||||
#include "forward.h"
|
||||
|
||||
extern DLSYM_PROTOTYPE(mnt_free_iter);
|
||||
extern DLSYM_PROTOTYPE(mnt_free_table);
|
||||
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);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct libmnt_table*, mnt_free_table, NULL);
|
||||
DEFINE_TRIVIAL_CLEANUP_FUNC_FULL(struct libmnt_iter*, mnt_free_iter, NULL);
|
||||
|
||||
int libmount_parse_full(
|
||||
const char *path,
|
||||
|
||||
@ -322,7 +322,7 @@ libshared_deps = [threads,
|
||||
libgcrypt_cflags,
|
||||
libkmod_cflags,
|
||||
liblz4_cflags,
|
||||
libmount_cflags,
|
||||
libmount,
|
||||
libopenssl,
|
||||
libp11kit_cflags,
|
||||
libpam_cflags,
|
||||
|
||||
@ -60,13 +60,13 @@ int umount_recursive_full(const char *prefix, int flags, char **keep) {
|
||||
struct libmnt_fs *fs;
|
||||
const char *path;
|
||||
|
||||
r = sym_mnt_table_next_fs(table, iter, &fs);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r == 1)
|
||||
break;
|
||||
if (r < 0)
|
||||
return log_debug_errno(r, "Failed to get next entry from /proc/self/mountinfo: %m");
|
||||
|
||||
path = sym_mnt_fs_get_target(fs);
|
||||
path = mnt_fs_get_target(fs);
|
||||
if (!path)
|
||||
continue;
|
||||
|
||||
@ -247,20 +247,20 @@ int bind_remount_recursive_with_mountinfo(
|
||||
unsigned long flags = 0;
|
||||
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 */
|
||||
break;
|
||||
if (r < 0)
|
||||
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)
|
||||
continue;
|
||||
|
||||
if (!path_startswith(path, prefix))
|
||||
continue;
|
||||
|
||||
type = sym_mnt_fs_get_fstype(fs);
|
||||
type = mnt_fs_get_fstype(fs);
|
||||
if (!type)
|
||||
continue;
|
||||
|
||||
@ -298,9 +298,9 @@ int bind_remount_recursive_with_mountinfo(
|
||||
continue;
|
||||
}
|
||||
|
||||
opts = sym_mnt_fs_get_vfs_options(fs);
|
||||
opts = mnt_fs_get_vfs_options(fs);
|
||||
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)
|
||||
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);
|
||||
|
||||
r = dlopen_libmount();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
table = sym_mnt_new_table();
|
||||
table = mnt_new_table();
|
||||
if (!table)
|
||||
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)
|
||||
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) {
|
||||
r = access_nofollow(path, F_OK); /* Hmm, it's not in the mount table, but does it exist at all? */
|
||||
if (r < 0)
|
||||
@ -459,9 +455,9 @@ int bind_remount_one_with_mountinfo(
|
||||
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) {
|
||||
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)
|
||||
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_remaining_options);
|
||||
|
||||
r = dlopen_libmount();
|
||||
if (r < 0)
|
||||
return r;
|
||||
|
||||
map = sym_mnt_get_builtin_optmap(MNT_LINUX_MAP);
|
||||
map = mnt_get_builtin_optmap(MNT_LINUX_MAP);
|
||||
if (!map)
|
||||
return -EINVAL;
|
||||
|
||||
@ -1645,20 +1637,20 @@ int get_sub_mounts(const char *prefix, SubMount **ret_mounts, size_t *ret_n_moun
|
||||
const char *path;
|
||||
int id1, id2;
|
||||
|
||||
r = sym_mnt_table_next_fs(table, iter, &fs);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r == 1)
|
||||
break; /* EOF */
|
||||
if (r < 0)
|
||||
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)
|
||||
continue;
|
||||
|
||||
if (isempty(path_startswith(path, prefix)))
|
||||
continue;
|
||||
|
||||
id1 = sym_mnt_fs_get_id(fs);
|
||||
id1 = mnt_fs_get_id(fs);
|
||||
r = path_get_mnt_id(path, &id2);
|
||||
if (r < 0) {
|
||||
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 (;;) {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
r = sym_mnt_table_next_fs(table, iter, &fs);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r == 1)
|
||||
break; /* EOF */
|
||||
if (r < 0)
|
||||
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;
|
||||
|
||||
_cleanup_free_ char *fstype = NULL, *options = NULL, *source = NULL;
|
||||
|
||||
if (ret_fstype) {
|
||||
fstype = strdup(strempty(sym_mnt_fs_get_fstype(fs)));
|
||||
fstype = strdup(strempty(mnt_fs_get_fstype(fs)));
|
||||
if (!fstype)
|
||||
return log_oom_debug();
|
||||
}
|
||||
|
||||
if (ret_options) {
|
||||
options = strdup(strempty(sym_mnt_fs_get_options(fs)));
|
||||
options = strdup(strempty(mnt_fs_get_options(fs)));
|
||||
if (!options)
|
||||
return log_oom_debug();
|
||||
}
|
||||
|
||||
if (ret_source) {
|
||||
source = strdup(strempty(sym_mnt_fs_get_source(fs)));
|
||||
source = strdup(strempty(mnt_fs_get_source(fs)));
|
||||
if (!source)
|
||||
return log_oom_debug();
|
||||
}
|
||||
|
||||
@ -8,19 +8,9 @@
|
||||
#include "bus-object.h"
|
||||
#include "log.h"
|
||||
#include "pretty-print.h"
|
||||
#include "runtime-scope.h"
|
||||
#include "service-util.h"
|
||||
|
||||
typedef enum HelpFlags {
|
||||
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) {
|
||||
|
||||
static int help(const char *program_path, const char *service, const char *description, bool bus_introspect) {
|
||||
_cleanup_free_ char *link = NULL;
|
||||
int r;
|
||||
|
||||
@ -35,7 +25,6 @@ static int help(const char *program_path,
|
||||
" -h --help Show this help\n"
|
||||
" --version Show package version\n"
|
||||
"%8$s"
|
||||
"%9$s"
|
||||
"\nSee the %2$s for details.\n",
|
||||
program_path,
|
||||
link,
|
||||
@ -44,9 +33,7 @@ static int help(const char *program_path,
|
||||
ansi_highlight(),
|
||||
ansi_normal(),
|
||||
description,
|
||||
FLAGS_SET(flags, HELP_WITH_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" : "");
|
||||
bus_introspect ? " --bus-introspect=PATH Write D-Bus XML introspection data\n" : "");
|
||||
|
||||
return 0; /* No further action */
|
||||
}
|
||||
@ -55,22 +42,17 @@ int service_parse_argv(
|
||||
const char *service,
|
||||
const char *description,
|
||||
const BusObjectImplementation* const* bus_objects,
|
||||
RuntimeScope *runtime_scope,
|
||||
int argc, char *argv[]) {
|
||||
|
||||
enum {
|
||||
ARG_VERSION = 0x100,
|
||||
ARG_BUS_INTROSPECT,
|
||||
ARG_SYSTEM,
|
||||
ARG_USER,
|
||||
};
|
||||
|
||||
static const struct option options[] = {
|
||||
{ "help", no_argument, NULL, 'h' },
|
||||
{ "version", no_argument, NULL, ARG_VERSION },
|
||||
{ "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) {
|
||||
|
||||
case 'h':
|
||||
return help(argv[0],
|
||||
service,
|
||||
description,
|
||||
(bus_objects ? HELP_WITH_BUS_INTROSPECT : 0) |
|
||||
(runtime_scope ? HELP_WITH_RUNTIME_SCOPE : 0));
|
||||
return help(argv[0], service, description, bus_objects);
|
||||
|
||||
case ARG_VERSION:
|
||||
return version();
|
||||
@ -98,14 +76,6 @@ int service_parse_argv(
|
||||
optarg,
|
||||
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 '?':
|
||||
return -EINVAL;
|
||||
|
||||
|
||||
@ -7,5 +7,4 @@ int service_parse_argv(
|
||||
const char *service,
|
||||
const char *description,
|
||||
const BusObjectImplementation* const* bus_objects,
|
||||
RuntimeScope *runtime_scope,
|
||||
int argc, char *argv[]);
|
||||
|
||||
@ -36,16 +36,12 @@ int swap_list_get(const char *swaps, SwapDevice **head) {
|
||||
|
||||
assert(head);
|
||||
|
||||
r = dlopen_libmount();
|
||||
if (r < 0)
|
||||
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);
|
||||
t = mnt_new_table();
|
||||
i = mnt_new_iter(MNT_ITER_FORWARD);
|
||||
if (!t || !i)
|
||||
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 */
|
||||
return 0;
|
||||
if (r < 0)
|
||||
@ -56,13 +52,13 @@ int swap_list_get(const char *swaps, SwapDevice **head) {
|
||||
_cleanup_free_ SwapDevice *swap = NULL;
|
||||
const char *source;
|
||||
|
||||
r = sym_mnt_table_next_fs(t, i, &fs);
|
||||
r = mnt_table_next_fs(t, i, &fs);
|
||||
if (r == 1) /* EOF */
|
||||
break;
|
||||
if (r < 0)
|
||||
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)
|
||||
continue;
|
||||
|
||||
|
||||
@ -16,7 +16,7 @@ executables += [
|
||||
'name' : 'systemd-shutdown',
|
||||
'sources' : systemd_shutdown_sources + systemd_shutdown_extract_sources,
|
||||
'extract' : systemd_shutdown_extract_sources,
|
||||
'dependencies' : libmount_cflags,
|
||||
'dependencies' : libmount,
|
||||
},
|
||||
libexec_template + {
|
||||
'name' : 'systemd-shutdown.standalone',
|
||||
@ -28,11 +28,11 @@ executables += [
|
||||
libshared_static,
|
||||
libsystemd_static,
|
||||
],
|
||||
'dependencies' : libmount_cflags,
|
||||
'dependencies' : libmount,
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-umount.c'),
|
||||
'objects' : ['systemd-shutdown'],
|
||||
'dependencies' : libmount_cflags,
|
||||
'dependencies' : libmount,
|
||||
},
|
||||
]
|
||||
|
||||
@ -69,17 +69,17 @@ int mount_points_list_get(FILE *f, MountPoint **head) {
|
||||
bool try_remount_ro, is_api_vfs, is_network;
|
||||
_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 */
|
||||
break;
|
||||
if (r < 0)
|
||||
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)
|
||||
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
|
||||
* 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
|
||||
* 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();
|
||||
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();
|
||||
|
||||
/* 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
|
||||
* 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) {
|
||||
log_warning_errno(r, "mnt_fs_get_propagation() failed for %s, ignoring: %m", path);
|
||||
continue;
|
||||
|
||||
@ -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");
|
||||
|
||||
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)
|
||||
return log_error_errno(r, "Failed to read metadata for image %s: %m", img->name);
|
||||
}
|
||||
|
||||
@ -2079,7 +2079,6 @@ static int run(int argc, char *argv[]) {
|
||||
"System update management service.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
/* runtime_scope= */ NULL,
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -215,7 +215,7 @@ simple_tests += files(
|
||||
############################################################
|
||||
|
||||
common_test_dependencies = [
|
||||
libmount_cflags,
|
||||
libmount,
|
||||
librt,
|
||||
libseccomp_cflags,
|
||||
libselinux,
|
||||
@ -289,7 +289,6 @@ executables += [
|
||||
'dependencies' : [
|
||||
libblkid_cflags,
|
||||
libkmod_cflags,
|
||||
libmount_cflags,
|
||||
libp11kit_cflags,
|
||||
libseccomp_cflags,
|
||||
],
|
||||
@ -342,7 +341,7 @@ executables += [
|
||||
test_template + {
|
||||
'sources' : files('test-libmount.c'),
|
||||
'dependencies' : [
|
||||
libmount_cflags,
|
||||
libmount,
|
||||
threads,
|
||||
],
|
||||
},
|
||||
@ -360,7 +359,7 @@ executables += [
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-mount-util.c'),
|
||||
'dependencies' : libmount_cflags,
|
||||
'dependencies' : libmount,
|
||||
},
|
||||
test_template + {
|
||||
'sources' : files('test-netlink-manual.c'),
|
||||
|
||||
@ -49,8 +49,7 @@ int main(int argc, char *argv[]) {
|
||||
if (!can_memlock())
|
||||
return log_tests_skipped("Can't use mlock()");
|
||||
|
||||
_cleanup_free_ char *cgroup_path = NULL;
|
||||
r = enter_cgroup_subroot(&cgroup_path);
|
||||
r = enter_cgroup_subroot(NULL);
|
||||
if (r == -ENOMEDIUM)
|
||||
return log_tests_skipped("cgroupfs not available");
|
||||
|
||||
@ -129,8 +128,6 @@ int main(int argc, char *argv[]) {
|
||||
SERVICE(u)->type = SERVICE_ONESHOT;
|
||||
u->load_state = UNIT_LOADED;
|
||||
|
||||
CGroupRuntime *crt = ASSERT_PTR(unit_setup_cgroup_runtime(u));
|
||||
|
||||
unit_dump(u, stdout, NULL);
|
||||
|
||||
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?)");
|
||||
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_egress);
|
||||
|
||||
|
||||
@ -12,7 +12,6 @@
|
||||
#include "libarchive-util.h"
|
||||
#include "libaudit-util.h"
|
||||
#include "libfido2-util.h"
|
||||
#include "libmount-util.h"
|
||||
#include "main-func.h"
|
||||
#include "module-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_libblkid, HAVE_BLKID);
|
||||
ASSERT_DLOPEN(dlopen_libseccomp, HAVE_SECCOMP);
|
||||
ASSERT_DLOPEN(dlopen_libmount, true);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
@ -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. */
|
||||
|
||||
r = sym_mnt_table_next_fs(table, iter, &fs);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r != 0 && may_fail) {
|
||||
log_error_errno(r, "mnt_table_next_fs failed: %m");
|
||||
return;
|
||||
@ -41,8 +41,8 @@ static void test_libmount_unescaping_one(
|
||||
|
||||
assert_se(x = cescape(string));
|
||||
|
||||
assert_se(source = sym_mnt_fs_get_source(fs));
|
||||
assert_se(target = sym_mnt_fs_get_target(fs));
|
||||
assert_se(source = mnt_fs_get_source(fs));
|
||||
assert_se(target = mnt_fs_get_target(fs));
|
||||
|
||||
assert_se(cs = cescape(source));
|
||||
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(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) {
|
||||
|
||||
@ -361,7 +361,7 @@ TEST(umount_recursive) {
|
||||
for (;;) {
|
||||
struct libmnt_fs *fs;
|
||||
|
||||
r = sym_mnt_table_next_fs(table, iter, &fs);
|
||||
r = mnt_table_next_fs(table, iter, &fs);
|
||||
if (r == 1)
|
||||
break;
|
||||
if (r < 0) {
|
||||
@ -369,7 +369,7 @@ TEST(umount_recursive) {
|
||||
_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);
|
||||
|
||||
@ -1164,7 +1164,6 @@ static int run(int argc, char *argv[]) {
|
||||
"Manage the system clock and timezone and NTP enablement.",
|
||||
BUS_IMPLEMENTATIONS(&manager_object,
|
||||
&log_control_object),
|
||||
/* runtime_scope= */ NULL,
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -151,7 +151,6 @@ static int run(int argc, char *argv[]) {
|
||||
r = service_parse_argv("systemd-timesyncd.service",
|
||||
"Network time synchronization",
|
||||
BUS_IMPLEMENTATIONS(&manager_object, &log_control_object),
|
||||
/* runtime_scope= */ NULL,
|
||||
argc, argv);
|
||||
if (r <= 0)
|
||||
return r;
|
||||
|
||||
@ -70,7 +70,7 @@ foreach dirname : [
|
||||
'TEST-46-HOMED',
|
||||
'TEST-50-DISSECT',
|
||||
'TEST-52-HONORFIRSTSHUTDOWN',
|
||||
'TEST-53-TIMER',
|
||||
'TEST-53-ISSUE-16347',
|
||||
'TEST-54-CREDS',
|
||||
'TEST-55-OOMD',
|
||||
'TEST-58-REPART',
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
cat >/run/systemd/system/floodme@.service <<EOF
|
||||
[Service]
|
||||
ExecStart=true
|
||||
|
||||
@ -4,6 +4,8 @@
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
test_quotas() {
|
||||
|
||||
local directory="$1"
|
||||
@ -88,4 +90,6 @@ EOF
|
||||
|
||||
test_quotas "/var/lib/private" "StateDirectory=quotadir" "StateDirectoryQuota=1%"
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
touch /testok
|
||||
|
||||
@ -20,6 +20,8 @@ at_exit() {
|
||||
|
||||
trap at_exit EXIT
|
||||
|
||||
systemctl service-log-level systemd-importd debug
|
||||
|
||||
# Mount tmpfs over /var/lib/confexts to not pollute the image
|
||||
mkdir -p /var/lib/confexts
|
||||
mount -t tmpfs tmpfs /var/lib/confexts -o mode=755
|
||||
|
||||
@ -20,6 +20,8 @@ at_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
|
||||
systemctl edit --runtime --stdin 'systemd-nspawn@.service' --drop-in=debug.conf <<EOF
|
||||
[Service]
|
||||
|
||||
@ -11,6 +11,8 @@ if [[ "$(get_cgroup_hierarchy)" != unified ]]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
# Multiple level process tree, parent process stays up
|
||||
cat >/tmp/test19-exit-cgroup.sh <<EOF
|
||||
#!/usr/bin/env bash
|
||||
@ -96,3 +98,6 @@ systemd-run --wait \
|
||||
--property="Type=notify" \
|
||||
--property="ExitType=cgroup" \
|
||||
/tmp/test19-exit-cgroup-parentless.sh 'systemctl kill --signal 9 six'
|
||||
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
@ -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
|
||||
@ -5,6 +5,8 @@ set -o pipefail
|
||||
|
||||
# Test ExecReload= (PR #13098)
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
export SYSTEMD_PAGER=
|
||||
SERVICE_PATH="$(mktemp /etc/systemd/system/execreloadXXX.service)"
|
||||
SERVICE_NAME="${SERVICE_PATH##*/}"
|
||||
@ -55,3 +57,5 @@ systemctl status "$SERVICE_NAME"
|
||||
systemctl reload "$SERVICE_NAME"
|
||||
systemctl status "$SERVICE_NAME"
|
||||
systemctl stop "$SERVICE_NAME"
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
@ -4,6 +4,8 @@ set -eux
|
||||
|
||||
# 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 \
|
||||
-p ExecStopPost='touch /run/simple1' true
|
||||
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 \
|
||||
-p ExecStopPost='touch /run/idle2' false)
|
||||
test -f /run/idle2
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
@ -18,6 +18,8 @@ mkdir /tmp/test-extra-fd
|
||||
echo "Hello" > /tmp/test-extra-fd/1.txt
|
||||
echo "Extra" > /tmp/test-extra-fd/2.txt
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
# Open files and assign FD to variables
|
||||
exec {TEST_FD1}</tmp/test-extra-fd/1.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"
|
||||
|
||||
systemctl stop "$TEST_UNIT"
|
||||
|
||||
systemctl log-level info
|
||||
|
||||
@ -6,6 +6,9 @@ set -o pipefail
|
||||
|
||||
# Test JoinsNamespaceOf= with PrivateTmp=yes
|
||||
|
||||
systemd-analyze log-level debug
|
||||
systemd-analyze log-target journal
|
||||
|
||||
# simple case
|
||||
systemctl start TEST-23-UNIT-FILE-joins-namespace-of-1.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 stop TEST-23-UNIT-FILE-joins-namespace-of-6.service
|
||||
systemctl stop TEST-23-UNIT-FILE-joins-namespace-of-8.service
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
@ -5,6 +5,8 @@ set -o pipefail
|
||||
|
||||
# Test StandardOutput=file:
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
systemd-run --wait --unit=TEST-23-UNIT-FILE-standard-output-one \
|
||||
-p StandardOutput=file:/tmp/stdout \
|
||||
-p StandardError=file:/tmp/stderr \
|
||||
@ -54,3 +56,5 @@ EOF
|
||||
cmp /tmp/stderr <<EOF
|
||||
b
|
||||
EOF
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
@ -6,6 +6,9 @@ set -o pipefail
|
||||
|
||||
# Test OnSuccess= + Uphold= + PropagatesStopTo= + BindsTo=
|
||||
|
||||
systemd-analyze log-level debug
|
||||
systemd-analyze log-target journal
|
||||
|
||||
# Idea is this:
|
||||
# 1. we start TEST-23-UNIT-FILE-success.service
|
||||
# 2. which through OnSuccess= starts TEST-23-UNIT-FILE-fail.service,
|
||||
@ -99,3 +102,5 @@ for _ in {1..120}; do
|
||||
fi
|
||||
done
|
||||
[[ "$sigrtmin1" == 1 ]]
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
@ -5,6 +5,8 @@ set -o pipefail
|
||||
|
||||
# Test ExecXYZEx= service unit dbus hookups
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
declare -A property
|
||||
|
||||
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]}Ex" "$c" | grep -F "path=echo ; argv[]=echo \${$c} ; flags=no-env-expand"
|
||||
done
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
@ -11,6 +11,8 @@ set -o pipefail
|
||||
# wait this many secs for each test service to succeed in what is being tested
|
||||
MAX_SECS=60
|
||||
|
||||
systemctl log-level debug
|
||||
|
||||
# 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")
|
||||
|
||||
@ -95,3 +97,5 @@ EOF
|
||||
|
||||
systemctl disable "$UNIT_NAME"
|
||||
rm "$TMP_FILE" /run/systemd/system/{"$UNIT_NAME","$ONSUCCESS_UNIT_NAME"} "$FIFO_FILE"
|
||||
|
||||
systemctl log-level info
|
||||
|
||||
@ -14,6 +14,8 @@ at_exit() {
|
||||
|
||||
trap at_exit EXIT
|
||||
|
||||
systemctl log-level debug
|
||||
|
||||
# Existing files
|
||||
|
||||
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 0 systemd-run -p OpenFile=/run/missing/foo:missing-file:read-only,graceful --wait true
|
||||
|
||||
systemctl log-level info
|
||||
|
||||
@ -5,6 +5,8 @@ set -o pipefail
|
||||
|
||||
# Test OnSuccess=/OnFailure= in combination
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
# Start-up should fail, but the automatic restart should fix it
|
||||
(! systemctl start success-failure-test )
|
||||
|
||||
@ -43,3 +45,5 @@ done
|
||||
test "$(systemctl is-active success-failure-test-failure)" = "inactive"
|
||||
|
||||
systemctl stop success-failure-test success-failure-test-success
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
@ -5,6 +5,8 @@ set -o pipefail
|
||||
|
||||
# Test Type=exec
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
# Create a binary for which execve() will fail
|
||||
touch /tmp/brokenbinary
|
||||
chmod +x /tmp/brokenbinary
|
||||
@ -57,3 +59,5 @@ busctl call \
|
||||
sleep 0 true \
|
||||
sleep 2 sleep 1 true \
|
||||
0)
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
systemctl disable --now systemd-timesyncd.service
|
||||
|
||||
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
|
||||
systemctl daemon-reload
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
touch /testok
|
||||
|
||||
@ -10,6 +10,8 @@ set -o pipefail
|
||||
# kernels where the concept was still new.
|
||||
|
||||
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
|
||||
systemd-run --unit=oomtest.service \
|
||||
-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)"
|
||||
test "$RESULT" = "oom-kill"
|
||||
|
||||
systemd-analyze log-level info
|
||||
fi
|
||||
|
||||
touch /testok
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
test_directory() {
|
||||
local directory="$1"
|
||||
local path="$2"
|
||||
@ -237,4 +239,6 @@ if systemd-analyze compare-versions "$(uname -r)" ge 5.12; then
|
||||
test_check_idmapped_mounts_root
|
||||
fi
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
touch /testok
|
||||
|
||||
@ -21,6 +21,9 @@ at_exit() {
|
||||
|
||||
trap at_exit EXIT
|
||||
|
||||
systemd-analyze log-level debug
|
||||
systemd-analyze log-target journal
|
||||
|
||||
# Log files
|
||||
straceLog='strace.log'
|
||||
journalLog='journal.log'
|
||||
@ -349,4 +352,6 @@ fi
|
||||
rm -rf "$confDir"
|
||||
systemctl daemon-reload
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
touch /testok
|
||||
|
||||
@ -12,6 +12,8 @@ if [[ -n "${COVERAGE_BUILD_DIR:-}" ]]; then
|
||||
exit 77
|
||||
fi
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
unit=TEST-38-FREEZER-sleep.service
|
||||
|
||||
start_test_service() {
|
||||
|
||||
@ -13,9 +13,13 @@ fi
|
||||
|
||||
install_extension_images
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
runas testuser systemd-run --wait --user --unit=test-private-users \
|
||||
-p PrivateUsers=yes -P echo hello
|
||||
|
||||
runas testuser systemctl --user log-level debug
|
||||
|
||||
runas testuser systemd-run --wait --user --unit=test-private-tmp-innerfile \
|
||||
-p PrivateTmp=yes \
|
||||
-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
|
||||
fi
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
touch /testok
|
||||
|
||||
@ -2,6 +2,8 @@
|
||||
# SPDX-License-Identifier: LGPL-2.1-or-later
|
||||
set -eux
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
journalctl --list-namespaces -o json | jq .
|
||||
|
||||
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/no-hello-world)
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
touch /testok
|
||||
|
||||
@ -40,6 +40,9 @@ FSTYPE="$(stat --file-system --format "%T" /)"
|
||||
|
||||
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.
|
||||
mkdir -p /home
|
||||
mount -t tmpfs tmpfs /home -o size=290M
|
||||
@ -845,4 +848,6 @@ homectl inspect matchtest
|
||||
homectl inspect matchtest | grep "Area: quux3"
|
||||
homectl remove matchtest
|
||||
|
||||
systemd-analyze log-level info
|
||||
|
||||
touch /testok
|
||||
|
||||
@ -3,6 +3,8 @@
|
||||
set -ex
|
||||
set -o pipefail
|
||||
|
||||
systemd-analyze log-level debug
|
||||
|
||||
systemctl enable test-honor-first-shutdown.service
|
||||
systemctl start test-honor-first-shutdown.service
|
||||
|
||||
|
||||
@ -3,9 +3,10 @@
|
||||
set -eux
|
||||
set -o pipefail
|
||||
|
||||
: >/failed
|
||||
|
||||
# Reset host date to current time, 3 days in the past.
|
||||
date -s "-3 days"
|
||||
trap 'date -s "+3 days"' EXIT
|
||||
|
||||
# Run a timer for every 15 minutes.
|
||||
systemd-run --unit test-timer --on-calendar "*:0/15:0" true
|
||||
@ -16,12 +17,15 @@ now=$(date +%s)
|
||||
time_delta=$((next_elapsed - now))
|
||||
|
||||
# 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 " next_elapsed=${next_elapsed}"
|
||||
echo " now=${now}"
|
||||
echo " time_delta=${time_delta}"
|
||||
echo
|
||||
echo ''
|
||||
} >>/failed
|
||||
|
||||
exit 1
|
||||
if test ! -s /failed ; then
|
||||
rm -f /failed
|
||||
touch /testok
|
||||
fi
|
||||
@ -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
|
||||
@ -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
|
||||
@ -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
Loading…
x
Reference in New Issue
Block a user