From a3c4eb07106b29f7366113764cb1c8c4d6dd5646 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 24 Feb 2016 15:31:33 +0100 Subject: core: rework generator dir logic, move the dirs into LookupPaths structure MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit A long time ago – when generators where first introduced – the directories for them were randomly created via mkdtemp(). This was changed later so that they use fixed name directories now. Let's make use of this, and add the genrator dirs to the LookupPaths structure and into the unit file search path maintained in it. This has the benefit that the generator dirs are now normal part of the search path for all tools, and thus are shown in "systemctl list-unit-files" too. --- src/core/dbus-manager.c | 2 +- src/core/load-dropin.c | 2 +- src/core/load-dropin.h | 2 +- src/core/load-fragment.c | 2 +- src/core/manager.c | 142 +++++++++-------------------------------------- src/core/manager.h | 4 -- 6 files changed, 30 insertions(+), 124 deletions(-) (limited to 'src/core') diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 00372b92b4..739bd14b9e 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1924,7 +1924,7 @@ const sd_bus_vtable bus_manager_vtable[] = { SD_BUS_PROPERTY("Environment", "as", NULL, offsetof(Manager, environment), 0), SD_BUS_PROPERTY("ConfirmSpawn", "b", bus_property_get_bool, offsetof(Manager, confirm_spawn), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("ShowStatus", "b", bus_property_get_bool, offsetof(Manager, show_status), SD_BUS_VTABLE_PROPERTY_CONST), - SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.unit_path), SD_BUS_VTABLE_PROPERTY_CONST), + SD_BUS_PROPERTY("UnitPath", "as", NULL, offsetof(Manager, lookup_paths.search_path), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultStandardOutput", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_PROPERTY("DefaultStandardError", "s", bus_property_get_exec_output, offsetof(Manager, default_std_output), SD_BUS_VTABLE_PROPERTY_CONST), SD_BUS_WRITABLE_PROPERTY("RuntimeWatchdogUSec", "t", bus_property_get_usec, property_set_runtime_watchdog, offsetof(Manager, runtime_watchdog), 0), diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c index 22b71b6f5e..1c65055a3f 100644 --- a/src/core/load-dropin.c +++ b/src/core/load-dropin.c @@ -55,7 +55,7 @@ int unit_load_dropin(Unit *u) { SET_FOREACH(t, u->names, i) { char **p; - STRV_FOREACH(p, u->manager->lookup_paths.unit_path) { + STRV_FOREACH(p, u->manager->lookup_paths.search_path) { unit_file_process_dir(u->manager->unit_path_cache, *p, t, ".wants", UNIT_WANTS, add_dependency_consumer, u, NULL); unit_file_process_dir(u->manager->unit_path_cache, *p, t, ".requires", UNIT_REQUIRES, diff --git a/src/core/load-dropin.h b/src/core/load-dropin.h index d8a4aefbb3..942d26724e 100644 --- a/src/core/load-dropin.h +++ b/src/core/load-dropin.h @@ -25,7 +25,7 @@ /* Read service data supplementary drop-in directories */ static inline int unit_find_dropin_paths(Unit *u, char ***paths) { - return unit_file_find_dropin_paths(u->manager->lookup_paths.unit_path, + return unit_file_find_dropin_paths(u->manager->lookup_paths.search_path, u->manager->unit_path_cache, u->names, paths); diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index f1a874cfdf..3a77ceb551 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -3574,7 +3574,7 @@ static int load_from_path(Unit *u, const char *path) { } else { char **p; - STRV_FOREACH(p, u->manager->lookup_paths.unit_path) { + STRV_FOREACH(p, u->manager->lookup_paths.search_path) { /* Instead of opening the path right away, we manually * follow all symlinks and add their name to our unit diff --git a/src/core/manager.c b/src/core/manager.c index e739795e70..79dc77d50e 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1053,7 +1053,7 @@ static void manager_build_unit_path_cache(Manager *m) { /* This simply builds a list of files we know exist, so that * we don't always have to go to disk */ - STRV_FOREACH(i, m->lookup_paths.unit_path) { + STRV_FOREACH(i, m->lookup_paths.search_path) { struct dirent *de; d = opendir(*i); @@ -1116,18 +1116,13 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { assert(m); - dual_timestamp_get(&m->generators_start_timestamp); - r = manager_run_generators(m); - dual_timestamp_get(&m->generators_finish_timestamp); + r = lookup_paths_init(&m->lookup_paths, m->running_as, true, NULL); if (r < 0) return r; - r = lookup_paths_init( - &m->lookup_paths, m->running_as, true, - NULL, - m->generator_unit_path, - m->generator_unit_path_early, - m->generator_unit_path_late); + dual_timestamp_get(&m->generators_start_timestamp); + r = manager_run_generators(m); + dual_timestamp_get(&m->generators_finish_timestamp); if (r < 0) return r; @@ -2542,17 +2537,12 @@ int manager_reload(Manager *m) { manager_undo_generators(m); lookup_paths_free(&m->lookup_paths); - /* Find new unit paths */ - q = manager_run_generators(m); + q = lookup_paths_init(&m->lookup_paths, m->running_as, true, NULL); if (q < 0 && r >= 0) r = q; - q = lookup_paths_init( - &m->lookup_paths, m->running_as, true, - NULL, - m->generator_unit_path, - m->generator_unit_path_early, - m->generator_unit_path_late); + /* Find new unit paths */ + q = manager_run_generators(m); if (q < 0 && r >= 0) r = q; @@ -2732,77 +2722,6 @@ void manager_check_finished(Manager *m) { manager_invalidate_startup_units(m); } -static int create_generator_dir(Manager *m, char **generator, const char *name) { - char *p; - int r; - - assert(m); - assert(generator); - assert(name); - - if (*generator) - return 0; - - if (m->running_as == MANAGER_SYSTEM && getpid() == 1) { - /* systemd --system, not running --test */ - - p = strappend("/run/systemd/", name); - if (!p) - return log_oom(); - - r = mkdir_p_label(p, 0755); - if (r < 0) { - log_error_errno(r, "Failed to create generator directory %s: %m", p); - free(p); - return r; - } - } else if (m->running_as == MANAGER_USER) { - const char *s = NULL; - - s = getenv("XDG_RUNTIME_DIR"); - if (!s) - return -EINVAL; - p = strjoin(s, "/systemd/", name, NULL); - if (!p) - return log_oom(); - - r = mkdir_p_label(p, 0755); - if (r < 0) { - log_error_errno(r, "Failed to create generator directory %s: %m", p); - free(p); - return r; - } - } else { - /* systemd --system --test */ - - p = strjoin("/tmp/systemd-", name, ".XXXXXX", NULL); - if (!p) - return log_oom(); - - if (!mkdtemp(p)) { - log_error_errno(errno, "Failed to create generator directory %s: %m", p); - free(p); - return -errno; - } - } - - *generator = p; - return 0; -} - -static void trim_generator_dir(Manager *m, char **generator) { - assert(m); - assert(generator); - - if (!*generator) - return; - - if (rmdir(*generator) >= 0) - *generator = mfree(*generator); - - return; -} - static int manager_run_generators(Manager *m) { _cleanup_strv_free_ char **paths = NULL; const char *argv[5]; @@ -2821,62 +2740,53 @@ static int manager_run_generators(Manager *m) { /* Optimize by skipping the whole process by not creating output directories * if no generators are found. */ STRV_FOREACH(path, paths) { - r = access(*path, F_OK); - if (r == 0) + if (access(*path, F_OK) >= 0) goto found; if (errno != ENOENT) log_warning_errno(errno, "Failed to open generator directory %s: %m", *path); } + return 0; found: - r = create_generator_dir(m, &m->generator_unit_path, "generator"); + r = mkdir_p_label(m->lookup_paths.generator, 0755); if (r < 0) goto finish; - r = create_generator_dir(m, &m->generator_unit_path_early, "generator.early"); + r = mkdir_p_label(m->lookup_paths.generator_early, 0755); if (r < 0) goto finish; - r = create_generator_dir(m, &m->generator_unit_path_late, "generator.late"); + r = mkdir_p_label(m->lookup_paths.generator_late, 0755); if (r < 0) goto finish; argv[0] = NULL; /* Leave this empty, execute_directory() will fill something in */ - argv[1] = m->generator_unit_path; - argv[2] = m->generator_unit_path_early; - argv[3] = m->generator_unit_path_late; + argv[1] = m->lookup_paths.generator; + argv[2] = m->lookup_paths.generator_early; + argv[3] = m->lookup_paths.generator_late; argv[4] = NULL; RUN_WITH_UMASK(0022) execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC, (char**) argv); finish: - trim_generator_dir(m, &m->generator_unit_path); - trim_generator_dir(m, &m->generator_unit_path_early); - trim_generator_dir(m, &m->generator_unit_path_late); + /* Trim empty dirs */ + (void) rmdir(m->lookup_paths.generator); + (void) rmdir(m->lookup_paths.generator_early); + (void) rmdir(m->lookup_paths.generator_late); return r; } -static void remove_generator_dir(Manager *m, char **generator) { - assert(m); - assert(generator); - - if (!*generator) - return; - - strv_remove(m->lookup_paths.unit_path, *generator); - (void) rm_rf(*generator, REMOVE_ROOT); - - *generator = mfree(*generator); -} - static void manager_undo_generators(Manager *m) { assert(m); - remove_generator_dir(m, &m->generator_unit_path); - remove_generator_dir(m, &m->generator_unit_path_early); - remove_generator_dir(m, &m->generator_unit_path_late); + if (m->lookup_paths.generator) + (void) rm_rf(m->lookup_paths.generator, REMOVE_ROOT); + if (m->lookup_paths.generator_early) + (void) rm_rf(m->lookup_paths.generator_early, REMOVE_ROOT); + if (m->lookup_paths.generator_late) + (void) rm_rf(m->lookup_paths.generator_late, REMOVE_ROOT); } int manager_environment_add(Manager *m, char **minus, char **plus) { diff --git a/src/core/manager.h b/src/core/manager.h index 9803f73129..5471bd7a0d 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -162,10 +162,6 @@ struct Manager { dual_timestamp units_load_start_timestamp; dual_timestamp units_load_finish_timestamp; - char *generator_unit_path; - char *generator_unit_path_early; - char *generator_unit_path_late; - struct udev* udev; /* Data specific to the device subsystem */ -- cgit v1.2.1 From 7bfe3d44d008f46d65ebdf5adc0c847b45fd4ab2 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 24 Feb 2016 16:02:48 +0100 Subject: core: when enabling a generated unit file, return a clean error Let's be precise when the user tries to invoke an "enable" operation on a generated unit file. --- src/core/dbus-manager.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 739bd14b9e..e187e19d03 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1648,7 +1648,9 @@ static int method_enable_unit_files_generic( r = call(scope, runtime, NULL, l, force, &changes, &n_changes); if (r == -ESHUTDOWN) - return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked"); + return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked."); + if (r == -EADDRNOTAVAIL) + return sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED, "Unit file is generated."); if (r < 0) return r; @@ -1886,7 +1888,9 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd r = unit_file_add_dependency(scope, runtime, NULL, l, target, dep, force, &changes, &n_changes); if (r == -ESHUTDOWN) - return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked"); + return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked."); + if (r == -EADDRNOTAVAIL) + return sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED, "Unit file is generated."); if (r < 0) return r; -- cgit v1.2.1 From 463d0d15690c7abe2172a23ae23c5547693dd71f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 24 Feb 2016 21:24:23 +0100 Subject: core: remove ManagerRunningAs enum Previously, we had two enums ManagerRunningAs and UnitFileScope, that were mostly identical and converted from one to the other all the time. The latter had one more value UNIT_FILE_GLOBAL however. Let's simplify things, and remove ManagerRunningAs and replace it by UnitFileScope everywhere, thus making the translation unnecessary. Introduce two new macros MANAGER_IS_SYSTEM() and MANAGER_IS_USER() to simplify checking if we are running in one or the user context. --- src/core/automount.c | 2 +- src/core/busname.c | 4 +-- src/core/cgroup.c | 4 +-- src/core/dbus-manager.c | 54 ++++++++-------------------- src/core/dbus.c | 16 ++++----- src/core/device.c | 2 +- src/core/failure-action.c | 2 +- src/core/job.c | 2 +- src/core/load-fragment.c | 2 +- src/core/main.c | 44 +++++++++++------------ src/core/manager.c | 89 ++++++++++++++++++++++------------------------- src/core/manager.h | 9 +++-- src/core/mount.c | 11 +++--- src/core/path.c | 2 +- src/core/service.c | 4 +-- src/core/socket.c | 2 +- src/core/swap.c | 4 +-- src/core/timer.c | 4 +-- src/core/unit-printf.c | 2 +- src/core/unit.c | 18 +++++----- 20 files changed, 124 insertions(+), 153 deletions(-) (limited to 'src/core') diff --git a/src/core/automount.c b/src/core/automount.c index 5dc6fd98e7..7c55d7bc49 100644 --- a/src/core/automount.c +++ b/src/core/automount.c @@ -149,7 +149,7 @@ static int automount_add_default_dependencies(Automount *a) { if (!UNIT(a)->default_dependencies) return 0; - if (UNIT(a)->manager->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(UNIT(a)->manager)) return 0; r = unit_add_two_dependencies_by_name(UNIT(a), UNIT_BEFORE, UNIT_CONFLICTS, SPECIAL_UMOUNT_TARGET, NULL, true); diff --git a/src/core/busname.c b/src/core/busname.c index de2a21ccde..bbe61af4f0 100644 --- a/src/core/busname.c +++ b/src/core/busname.c @@ -149,7 +149,7 @@ static int busname_add_default_default_dependencies(BusName *n) { if (r < 0) return r; - if (UNIT(n)->manager->running_as == MANAGER_SYSTEM) { + if (MANAGER_IS_SYSTEM(UNIT(n)->manager)) { r = unit_add_two_dependencies_by_name(UNIT(n), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true); if (r < 0) return r; @@ -318,7 +318,7 @@ static int busname_open_fd(BusName *n) { if (n->starter_fd >= 0) return 0; - mode = UNIT(n)->manager->running_as == MANAGER_SYSTEM ? "system" : "user"; + mode = MANAGER_IS_SYSTEM(UNIT(n)->manager) ? "system" : "user"; n->starter_fd = bus_kernel_open_bus_fd(mode, &path); if (n->starter_fd < 0) return log_unit_warning_errno(UNIT(n), n->starter_fd, "Failed to open %s: %m", path ?: "kdbus"); diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 9c34928052..25cc6962f9 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -1265,7 +1265,7 @@ int manager_setup_cgroup(Manager *m) { * it. This is to support live upgrades from older systemd * versions where PID 1 was moved there. Also see * cg_get_root_path(). */ - if (!e && m->running_as == MANAGER_SYSTEM) { + if (!e && MANAGER_IS_SYSTEM(m)) { e = endswith(m->cgroup_root, "/" SPECIAL_SYSTEM_SLICE); if (!e) e = endswith(m->cgroup_root, "/system"); /* even more legacy */ @@ -1318,7 +1318,7 @@ int manager_setup_cgroup(Manager *m) { (void) sd_event_source_set_description(m->cgroup_inotify_event_source, "cgroup-inotify"); - } else if (m->running_as == MANAGER_SYSTEM) { + } else if (MANAGER_IS_SYSTEM(m)) { /* On the legacy hierarchy we only get * notifications via cgroup agents. (Which diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index e187e19d03..5fc3526751 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1187,7 +1187,7 @@ static int method_reboot(sd_bus_message *message, void *userdata, sd_bus_error * if (r < 0) return r; - if (m->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(m)) return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Reboot is only supported for system managers."); m->exit_code = MANAGER_REBOOT; @@ -1206,7 +1206,7 @@ static int method_poweroff(sd_bus_message *message, void *userdata, sd_bus_error if (r < 0) return r; - if (m->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(m)) return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Powering off is only supported for system managers."); m->exit_code = MANAGER_POWEROFF; @@ -1225,7 +1225,7 @@ static int method_halt(sd_bus_message *message, void *userdata, sd_bus_error *er if (r < 0) return r; - if (m->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(m)) return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Halt is only supported for system managers."); m->exit_code = MANAGER_HALT; @@ -1244,7 +1244,7 @@ static int method_kexec(sd_bus_message *message, void *userdata, sd_bus_error *e if (r < 0) return r; - if (m->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(m)) return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "KExec is only supported for system managers."); m->exit_code = MANAGER_KEXEC; @@ -1265,7 +1265,7 @@ static int method_switch_root(sd_bus_message *message, void *userdata, sd_bus_er if (r < 0) return r; - if (m->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(m)) return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Root switching is only supported by system manager."); r = sd_bus_message_read(message, "ss", &root, &init); @@ -1433,7 +1433,7 @@ static int method_set_exit_code(sd_bus_message *message, void *userdata, sd_bus_ if (r < 0) return r; - if (m->running_as == MANAGER_SYSTEM && detect_container() <= 0) + if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "ExitCode can only be set for user service managers or in containers."); m->return_value = code; @@ -1466,7 +1466,7 @@ static int method_list_unit_files(sd_bus_message *message, void *userdata, sd_bu if (!h) return -ENOMEM; - r = unit_file_get_list(m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, NULL, h); + r = unit_file_get_list(m->unit_file_scope, NULL, h); if (r < 0) goto fail; @@ -1498,7 +1498,6 @@ static int method_get_unit_file_state(sd_bus_message *message, void *userdata, s Manager *m = userdata; const char *name; UnitFileState state; - UnitFileScope scope; int r; assert(message); @@ -1514,9 +1513,7 @@ static int method_get_unit_file_state(sd_bus_message *message, void *userdata, s if (r < 0) return r; - scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; - - r = unit_file_get_state(scope, NULL, name, &state); + r = unit_file_get_state(m->unit_file_scope, NULL, name, &state); if (r < 0) return r; @@ -1526,7 +1523,6 @@ static int method_get_unit_file_state(sd_bus_message *message, void *userdata, s static int method_get_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) { _cleanup_free_ char *default_target = NULL; Manager *m = userdata; - UnitFileScope scope; int r; assert(message); @@ -1538,9 +1534,7 @@ static int method_get_default_target(sd_bus_message *message, void *userdata, sd if (r < 0) return r; - scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; - - r = unit_file_get_default(scope, NULL, &default_target); + r = unit_file_get_default(m->unit_file_scope, NULL, &default_target); if (r < 0) return r; @@ -1624,7 +1618,6 @@ static int method_enable_unit_files_generic( _cleanup_strv_free_ char **l = NULL; UnitFileChange *changes = NULL; unsigned n_changes = 0; - UnitFileScope scope; int runtime, force, r; assert(message); @@ -1644,9 +1637,7 @@ static int method_enable_unit_files_generic( if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ - scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; - - r = call(scope, runtime, NULL, l, force, &changes, &n_changes); + r = call(m->unit_file_scope, runtime, NULL, l, force, &changes, &n_changes); if (r == -ESHUTDOWN) return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked."); if (r == -EADDRNOTAVAIL) @@ -1688,7 +1679,6 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use unsigned n_changes = 0; Manager *m = userdata; UnitFilePresetMode mm; - UnitFileScope scope; int runtime, force, r; const char *mode; @@ -1717,9 +1707,7 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ - scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; - - r = unit_file_preset(scope, runtime, NULL, l, mm, force, &changes, &n_changes); + r = unit_file_preset(m->unit_file_scope, runtime, NULL, l, mm, force, &changes, &n_changes); if (r < 0) return r; @@ -1736,7 +1724,6 @@ static int method_disable_unit_files_generic( _cleanup_strv_free_ char **l = NULL; UnitFileChange *changes = NULL; unsigned n_changes = 0; - UnitFileScope scope; int r, runtime; assert(message); @@ -1750,15 +1737,13 @@ static int method_disable_unit_files_generic( if (r < 0) return r; - scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; - r = bus_verify_manage_unit_files_async(m, message, error); if (r < 0) return r; if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ - r = call(scope, runtime, NULL, l, &changes, &n_changes); + r = call(m->unit_file_scope, runtime, NULL, l, &changes, &n_changes); if (r < 0) return r; @@ -1777,7 +1762,6 @@ static int method_set_default_target(sd_bus_message *message, void *userdata, sd UnitFileChange *changes = NULL; unsigned n_changes = 0; Manager *m = userdata; - UnitFileScope scope; const char *name; int force, r; @@ -1798,9 +1782,7 @@ static int method_set_default_target(sd_bus_message *message, void *userdata, sd if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ - scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; - - r = unit_file_set_default(scope, NULL, name, force, &changes, &n_changes); + r = unit_file_set_default(m->unit_file_scope, NULL, name, force, &changes, &n_changes); if (r < 0) return r; @@ -1812,7 +1794,6 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, unsigned n_changes = 0; Manager *m = userdata; UnitFilePresetMode mm; - UnitFileScope scope; const char *mode; int force, runtime, r; @@ -1841,9 +1822,7 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, if (r == 0) return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ - scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; - - r = unit_file_preset_all(scope, runtime, NULL, mm, force, &changes, &n_changes); + r = unit_file_preset_all(m->unit_file_scope, runtime, NULL, mm, force, &changes, &n_changes); if (r < 0) { unit_file_changes_free(changes, n_changes); return r; @@ -1857,7 +1836,6 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd Manager *m = userdata; UnitFileChange *changes = NULL; unsigned n_changes = 0; - UnitFileScope scope; int runtime, force, r; char *target; char *type; @@ -1884,9 +1862,7 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd if (dep < 0) return -EINVAL; - scope = m->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER; - - r = unit_file_add_dependency(scope, runtime, NULL, l, target, dep, force, &changes, &n_changes); + r = unit_file_add_dependency(m->unit_file_scope, runtime, NULL, l, target, dep, force, &changes, &n_changes); if (r == -ESHUTDOWN) return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked."); if (r == -EADDRNOTAVAIL) diff --git a/src/core/dbus.c b/src/core/dbus.c index 413489373f..263955d874 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -112,7 +112,7 @@ static int signal_agent_released(sd_bus_message *message, void *userdata, sd_bus manager_notify_cgroup_empty(m, cgroup); /* if running as system-instance, forward under our name */ - if (m->running_as == MANAGER_SYSTEM && m->system_bus) { + if (MANAGER_IS_SYSTEM(m) && m->system_bus) { r = sd_bus_message_rewind(message, 1); if (r >= 0) r = sd_bus_send(m->system_bus, message, NULL); @@ -690,7 +690,7 @@ static int bus_on_connection(sd_event_source *s, int fd, uint32_t revents, void return 0; } - if (m->running_as == MANAGER_SYSTEM) { + if (MANAGER_IS_SYSTEM(m)) { /* When we run as system instance we get the Released * signal via a direct connection */ @@ -864,10 +864,10 @@ static int bus_init_api(Manager *m) { return 0; /* The API and system bus is the same if we are running in system mode */ - if (m->running_as == MANAGER_SYSTEM && m->system_bus) + if (MANAGER_IS_SYSTEM(m) && m->system_bus) bus = sd_bus_ref(m->system_bus); else { - if (m->running_as == MANAGER_SYSTEM) + if (MANAGER_IS_SYSTEM(m)) r = sd_bus_open_system(&bus); else r = sd_bus_open_user(&bus); @@ -907,7 +907,7 @@ static int bus_setup_system(Manager *m, sd_bus *bus) { assert(bus); /* On kdbus or if we are a user instance we get the Released message via the system bus */ - if (m->running_as == MANAGER_USER || m->kdbus_fd >= 0) { + if (MANAGER_IS_USER(m) || m->kdbus_fd >= 0) { r = sd_bus_add_match( bus, NULL, @@ -932,7 +932,7 @@ static int bus_init_system(Manager *m) { return 0; /* The API and system bus is the same if we are running in system mode */ - if (m->running_as == MANAGER_SYSTEM && m->api_bus) { + if (MANAGER_IS_SYSTEM(m) && m->api_bus) { m->system_bus = sd_bus_ref(m->api_bus); return 0; } @@ -983,7 +983,7 @@ static int bus_init_private(Manager *m) { if (m->kdbus_fd >= 0) return 0; - if (m->running_as == MANAGER_SYSTEM) { + if (MANAGER_IS_SYSTEM(m)) { /* We want the private bus only when running as init */ if (getpid() != 1) @@ -1082,7 +1082,7 @@ static void destroy_bus(Manager *m, sd_bus **bus) { /* Possibly flush unwritten data, but only if we are * unprivileged, since we don't want to sync here */ - if (m->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(m)) sd_bus_flush(*bus); /* And destroy the object */ diff --git a/src/core/device.c b/src/core/device.c index 0671620a3e..d01bec53d8 100644 --- a/src/core/device.c +++ b/src/core/device.c @@ -265,7 +265,7 @@ static int device_add_udev_wants(Unit *u, struct udev_device *dev) { assert(u); assert(dev); - property = u->manager->running_as == MANAGER_USER ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS"; + property = MANAGER_IS_USER(u->manager) ? "SYSTEMD_USER_WANTS" : "SYSTEMD_WANTS"; wants = udev_device_get_property_value(dev, property); if (!wants) return 0; diff --git a/src/core/failure-action.c b/src/core/failure-action.c index bb2bc3f399..d4aae4b6e7 100644 --- a/src/core/failure-action.c +++ b/src/core/failure-action.c @@ -47,7 +47,7 @@ int failure_action( if (action == FAILURE_ACTION_NONE) return -ECANCELED; - if (m->running_as == MANAGER_USER) { + if (!MANAGER_IS_SYSTEM(m)) { /* Downgrade all options to simply exiting if we run * in user mode */ diff --git a/src/core/job.c b/src/core/job.c index 5557a6a942..2e30431163 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -1156,7 +1156,7 @@ void job_shutdown_magic(Job *j) { if (j->type != JOB_START) return; - if (j->unit->manager->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(j->unit->manager)) return; if (!unit_has_name(j->unit, SPECIAL_SHUTDOWN_TARGET)) diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index 3a77ceb551..79f13f135d 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2495,7 +2495,7 @@ int config_parse_syscall_filter( /* Turn on NNP, but only if it wasn't configured explicitly * before, and only if we are in user mode. */ - if (!c->no_new_privileges_set && u->manager->running_as == MANAGER_USER) + if (!c->no_new_privileges_set && MANAGER_IS_USER(u->manager)) c->no_new_privileges = true; return 0; diff --git a/src/core/main.c b/src/core/main.c index 56df32426a..a428e345e0 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -94,7 +94,7 @@ static enum { ACTION_DONE } arg_action = ACTION_RUN; static char *arg_default_unit = NULL; -static ManagerRunningAs arg_running_as = _MANAGER_RUNNING_AS_INVALID; +static bool arg_system = false; static bool arg_dump_core = true; static int arg_crash_chvt = -1; static bool arg_crash_shell = false; @@ -688,11 +688,11 @@ static int parse_config_file(void) { const char *fn, *conf_dirs_nulstr; - fn = arg_running_as == MANAGER_SYSTEM ? + fn = arg_system ? PKGSYSCONFDIR "/system.conf" : PKGSYSCONFDIR "/user.conf"; - conf_dirs_nulstr = arg_running_as == MANAGER_SYSTEM ? + conf_dirs_nulstr = arg_system ? CONF_PATHS_NULSTR("systemd/system.conf.d") : CONF_PATHS_NULSTR("systemd/user.conf.d"); @@ -866,11 +866,11 @@ static int parse_argv(int argc, char *argv[]) { break; case ARG_SYSTEM: - arg_running_as = MANAGER_SYSTEM; + arg_system = true; break; case ARG_USER: - arg_running_as = MANAGER_USER; + arg_system = false; break; case ARG_TEST: @@ -1346,7 +1346,7 @@ int main(int argc, char *argv[]) { if (getpid() == 1 && detect_container() <= 0) { /* Running outside of a container as PID 1 */ - arg_running_as = MANAGER_SYSTEM; + arg_system = true; make_null_stdio(); log_set_target(LOG_TARGET_KMSG); log_open(); @@ -1430,7 +1430,7 @@ int main(int argc, char *argv[]) { } else if (getpid() == 1) { /* Running inside a container, as PID 1 */ - arg_running_as = MANAGER_SYSTEM; + arg_system = true; log_set_target(LOG_TARGET_CONSOLE); log_close_console(); /* force reopen of /dev/console */ log_open(); @@ -1443,7 +1443,7 @@ int main(int argc, char *argv[]) { kernel_timestamp = DUAL_TIMESTAMP_NULL; } else { /* Running as user instance */ - arg_running_as = MANAGER_USER; + arg_system = false; log_set_target(LOG_TARGET_AUTO); log_open(); @@ -1501,7 +1501,7 @@ int main(int argc, char *argv[]) { goto finish; } - if (arg_running_as == MANAGER_SYSTEM) { + if (arg_system) { r = parse_proc_cmdline(parse_proc_cmdline_item); if (r < 0) log_warning_errno(r, "Failed to parse kernel command line, ignoring: %m"); @@ -1522,14 +1522,14 @@ int main(int argc, char *argv[]) { goto finish; } - if (arg_running_as == MANAGER_USER && + if (!arg_system && arg_action == ACTION_RUN && sd_booted() <= 0) { log_error("Trying to run as user instance, but the system has not been booted with systemd."); goto finish; } - if (arg_running_as == MANAGER_SYSTEM && + if (arg_system && arg_action == ACTION_RUN && running_in_chroot() > 0) { log_error("Cannot be run in a chroot() environment."); @@ -1557,7 +1557,7 @@ int main(int argc, char *argv[]) { goto finish; } - if (arg_running_as == MANAGER_USER && + if (!arg_system && !getenv("XDG_RUNTIME_DIR")) { log_error("Trying to run as user instance, but $XDG_RUNTIME_DIR is not set."); goto finish; @@ -1580,7 +1580,7 @@ int main(int argc, char *argv[]) { if (arg_serialization) assert_se(fdset_remove(fds, fileno(arg_serialization)) >= 0); - if (arg_running_as == MANAGER_SYSTEM) + if (arg_system) /* Become a session leader if we aren't one yet. */ setsid(); @@ -1589,7 +1589,7 @@ int main(int argc, char *argv[]) { /* Reset the console, but only if this is really init and we * are freshly booted */ - if (arg_running_as == MANAGER_SYSTEM && arg_action == ACTION_RUN) { + if (arg_system && arg_action == ACTION_RUN) { /* If we are init, we connect stdin/stdout/stderr to * /dev/null and make sure we don't have a controlling @@ -1616,7 +1616,7 @@ int main(int argc, char *argv[]) { goto finish; } - if (arg_running_as == MANAGER_SYSTEM) { + if (arg_system) { int v; log_info(PACKAGE_STRING " running in %ssystem mode. (" SYSTEMD_FEATURES ")", @@ -1652,7 +1652,7 @@ int main(int argc, char *argv[]) { arg_action == ACTION_TEST ? " test" : "", getuid(), t); } - if (arg_running_as == MANAGER_SYSTEM && !skip_setup) { + if (arg_system && !skip_setup) { if (arg_show_status > 0) status_welcome(); @@ -1664,7 +1664,7 @@ int main(int argc, char *argv[]) { test_usr(); } - if (arg_running_as == MANAGER_SYSTEM && arg_runtime_watchdog > 0 && arg_runtime_watchdog != USEC_INFINITY) + if (arg_system && arg_runtime_watchdog > 0 && arg_runtime_watchdog != USEC_INFINITY) watchdog_set_timeout(&arg_runtime_watchdog); if (arg_timer_slack_nsec != NSEC_INFINITY) @@ -1694,12 +1694,12 @@ int main(int argc, char *argv[]) { } } - if (arg_running_as == MANAGER_USER) + if (!arg_system) /* Become reaper of our children */ if (prctl(PR_SET_CHILD_SUBREAPER, 1) < 0) log_warning_errno(errno, "Failed to make us a subreaper: %m"); - if (arg_running_as == MANAGER_SYSTEM) { + if (arg_system) { bump_rlimit_nofile(&saved_rlimit_nofile); if (empty_etc) { @@ -1711,7 +1711,7 @@ int main(int argc, char *argv[]) { } } - r = manager_new(arg_running_as, arg_action == ACTION_TEST, &m); + r = manager_new(arg_system ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, arg_action == ACTION_TEST, &m); if (r < 0) { log_emergency_errno(r, "Failed to allocate manager object: %m"); error_message = "Failed to allocate manager object"; @@ -1874,7 +1874,7 @@ int main(int argc, char *argv[]) { case MANAGER_EXIT: retval = m->return_value; - if (m->running_as == MANAGER_USER) { + if (MANAGER_IS_USER(m)) { log_debug("Exit."); goto finish; } @@ -1970,7 +1970,7 @@ finish: args[i++] = SYSTEMD_BINARY_PATH; if (switch_root_dir) args[i++] = "--switched-root"; - args[i++] = arg_running_as == MANAGER_SYSTEM ? "--system" : "--user"; + args[i++] = arg_system ? "--system" : "--user"; args[i++] = "--deserialize"; args[i++] = sfd; args[i++] = NULL; diff --git a/src/core/manager.c b/src/core/manager.c index 79dc77d50e..1412d6718a 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -491,7 +491,7 @@ static int manager_setup_signals(Manager *m) { if (r < 0) return r; - if (m->running_as == MANAGER_SYSTEM) + if (MANAGER_IS_SYSTEM(m)) return enable_special_signals(m); return 0; @@ -518,7 +518,7 @@ static void manager_clean_environment(Manager *m) { static int manager_default_environment(Manager *m) { assert(m); - if (m->running_as == MANAGER_SYSTEM) { + if (MANAGER_IS_SYSTEM(m)) { /* The system manager always starts with a clean * environment for its children. It does not import * the kernel or the parents exported variables. @@ -547,43 +547,36 @@ static int manager_default_environment(Manager *m) { } -int manager_new(ManagerRunningAs running_as, bool test_run, Manager **_m) { - - static const char * const unit_log_fields[_MANAGER_RUNNING_AS_MAX] = { - [MANAGER_SYSTEM] = "UNIT=", - [MANAGER_USER] = "USER_UNIT=", - }; - - static const char * const unit_log_format_strings[_MANAGER_RUNNING_AS_MAX] = { - [MANAGER_SYSTEM] = "UNIT=%s", - [MANAGER_USER] = "USER_UNIT=%s", - }; - +int manager_new(UnitFileScope scope, bool test_run, Manager **_m) { Manager *m; int r; assert(_m); - assert(running_as >= 0); - assert(running_as < _MANAGER_RUNNING_AS_MAX); + assert(IN_SET(scope, UNIT_FILE_SYSTEM, UNIT_FILE_USER)); m = new0(Manager, 1); if (!m) return -ENOMEM; -#ifdef ENABLE_EFI - if (running_as == MANAGER_SYSTEM && detect_container() <= 0) - boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp); -#endif - - m->running_as = running_as; + m->unit_file_scope = scope; m->exit_code = _MANAGER_EXIT_CODE_INVALID; m->default_timer_accuracy_usec = USEC_PER_MINUTE; m->default_tasks_accounting = true; m->default_tasks_max = UINT64_C(512); +#ifdef ENABLE_EFI + if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) + boot_timestamps(&m->userspace_timestamp, &m->firmware_timestamp, &m->loader_timestamp); +#endif + /* Prepare log fields we can use for structured logging */ - m->unit_log_field = unit_log_fields[running_as]; - m->unit_log_format_string = unit_log_format_strings[running_as]; + if (MANAGER_IS_SYSTEM(m)) { + m->unit_log_field = "UNIT="; + m->unit_log_format_string = "UNIT=%s"; + } else { + m->unit_log_field = "USER_UNIT="; + m->unit_log_format_string = "USER_UNIT=%s"; + } m->idle_pipe[0] = m->idle_pipe[1] = m->idle_pipe[2] = m->idle_pipe[3] = -1; @@ -694,7 +687,7 @@ static int manager_setup_notify(Manager *m) { fd_inc_rcvbuf(fd, NOTIFY_RCVBUF_SIZE); - if (m->running_as == MANAGER_SYSTEM) + if (MANAGER_IS_SYSTEM(m)) m->notify_socket = strdup("/run/systemd/notify"); else { const char *e; @@ -756,8 +749,8 @@ static int manager_setup_kdbus(Manager *m) { return -ESOCKTNOSUPPORT; m->kdbus_fd = bus_kernel_create_bus( - m->running_as == MANAGER_SYSTEM ? "system" : "user", - m->running_as == MANAGER_SYSTEM, &p); + MANAGER_IS_SYSTEM(m) ? "system" : "user", + MANAGER_IS_SYSTEM(m), &p); if (m->kdbus_fd < 0) return log_debug_errno(m->kdbus_fd, "Failed to set up kdbus: %m"); @@ -778,7 +771,7 @@ static int manager_connect_bus(Manager *m, bool reexecuting) { try_bus_connect = m->kdbus_fd >= 0 || reexecuting || - (m->running_as == MANAGER_USER && getenv("DBUS_SESSION_BUS_ADDRESS")); + (MANAGER_IS_USER(m) && getenv("DBUS_SESSION_BUS_ADDRESS")); /* Try to connect to the buses, if possible. */ return bus_init(m, try_bus_connect); @@ -1116,7 +1109,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { assert(m); - r = lookup_paths_init(&m->lookup_paths, m->running_as, true, NULL); + r = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, NULL); if (r < 0) return r; @@ -1739,7 +1732,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t } log_received_signal(sfsi.ssi_signo == SIGCHLD || - (sfsi.ssi_signo == SIGTERM && m->running_as == MANAGER_USER) + (sfsi.ssi_signo == SIGTERM && MANAGER_IS_USER(m)) ? LOG_DEBUG : LOG_INFO, &sfsi); @@ -1750,7 +1743,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t break; case SIGTERM: - if (m->running_as == MANAGER_SYSTEM) { + if (MANAGER_IS_SYSTEM(m)) { /* This is for compatibility with the * original sysvinit */ m->exit_code = MANAGER_REEXECUTE; @@ -1760,7 +1753,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t /* Fall through */ case SIGINT: - if (m->running_as == MANAGER_SYSTEM) { + if (MANAGER_IS_SYSTEM(m)) { /* If the user presses C-A-D more than * 7 times within 2s, we reboot @@ -1786,14 +1779,14 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t break; case SIGWINCH: - if (m->running_as == MANAGER_SYSTEM) + if (MANAGER_IS_SYSTEM(m)) manager_start_target(m, SPECIAL_KBREQUEST_TARGET, JOB_REPLACE); /* This is a nop on non-init */ break; case SIGPWR: - if (m->running_as == MANAGER_SYSTEM) + if (MANAGER_IS_SYSTEM(m)) manager_start_target(m, SPECIAL_SIGPWR_TARGET, JOB_REPLACE); /* This is a nop on non-init */ @@ -1901,7 +1894,7 @@ static int manager_dispatch_signal_fd(sd_event_source *source, int fd, uint32_t break; case 24: - if (m->running_as == MANAGER_USER) { + if (MANAGER_IS_USER(m)) { m->exit_code = MANAGER_EXIT; return 0; } @@ -2017,7 +2010,7 @@ int manager_loop(Manager *m) { while (m->exit_code == MANAGER_OK) { usec_t wait_usec; - if (m->runtime_watchdog > 0 && m->runtime_watchdog != USEC_INFINITY && m->running_as == MANAGER_SYSTEM) + if (m->runtime_watchdog > 0 && m->runtime_watchdog != USEC_INFINITY && MANAGER_IS_SYSTEM(m)) watchdog_ping(); if (!ratelimit_test(&rl)) { @@ -2042,7 +2035,7 @@ int manager_loop(Manager *m) { continue; /* Sleep for half the watchdog time */ - if (m->runtime_watchdog > 0 && m->runtime_watchdog != USEC_INFINITY && m->running_as == MANAGER_SYSTEM) { + if (m->runtime_watchdog > 0 && m->runtime_watchdog != USEC_INFINITY && MANAGER_IS_SYSTEM(m)) { wait_usec = m->runtime_watchdog / 2; if (wait_usec <= 0) wait_usec = 1; @@ -2113,7 +2106,7 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) { const char *msg; int audit_fd, r; - if (m->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(m)) return; audit_fd = get_audit_fd(); @@ -2159,7 +2152,7 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) { if (m->n_reloading > 0) return; - if (m->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(m)) return; if (detect_container() > 0) @@ -2203,7 +2196,7 @@ int manager_open_serialization(Manager *m, FILE **_f) { assert(_f); - path = m->running_as == MANAGER_SYSTEM ? "/run/systemd" : "/tmp"; + path = MANAGER_IS_SYSTEM(m) ? "/run/systemd" : "/tmp"; fd = open_tmpfile(path, O_RDWR|O_CLOEXEC); if (fd < 0) return -errno; @@ -2537,7 +2530,7 @@ int manager_reload(Manager *m) { manager_undo_generators(m); lookup_paths_free(&m->lookup_paths); - q = lookup_paths_init(&m->lookup_paths, m->running_as, true, NULL); + q = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, NULL); if (q < 0 && r >= 0) r = q; @@ -2616,7 +2609,7 @@ static void manager_notify_finished(Manager *m) { if (m->test_run) return; - if (m->running_as == MANAGER_SYSTEM && detect_container() <= 0) { + if (MANAGER_IS_SYSTEM(m) && detect_container() <= 0) { /* Note that m->kernel_usec.monotonic is always at 0, * and m->firmware_usec.monotonic and @@ -2733,7 +2726,7 @@ static int manager_run_generators(Manager *m) { if (m->test_run) return 0; - paths = generator_paths(m->running_as); + paths = generator_paths(m->unit_file_scope); if (!paths) return log_oom(); @@ -2851,7 +2844,7 @@ void manager_recheck_journal(Manager *m) { assert(m); - if (m->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(m)) return; u = manager_get_unit(m, SPECIAL_JOURNALD_SOCKET); @@ -2875,7 +2868,7 @@ void manager_set_show_status(Manager *m, ShowStatus mode) { assert(m); assert(IN_SET(mode, SHOW_STATUS_AUTO, SHOW_STATUS_NO, SHOW_STATUS_YES, SHOW_STATUS_TEMPORARY)); - if (m->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(m)) return; if (m->show_status != mode) @@ -2892,7 +2885,7 @@ void manager_set_show_status(Manager *m, ShowStatus mode) { static bool manager_get_show_status(Manager *m, StatusType type) { assert(m); - if (m->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(m)) return false; if (m->no_console_output) @@ -2914,7 +2907,7 @@ static bool manager_get_show_status(Manager *m, StatusType type) { void manager_set_first_boot(Manager *m, bool b) { assert(m); - if (m->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(m)) return; if (m->first_boot != (int) b) { @@ -2960,7 +2953,7 @@ Set *manager_get_units_requiring_mounts_for(Manager *m, const char *path) { const char *manager_get_runtime_prefix(Manager *m) { assert(m); - return m->running_as == MANAGER_SYSTEM ? + return MANAGER_IS_SYSTEM(m) ? "/run" : getenv("XDG_RUNTIME_DIR"); } diff --git a/src/core/manager.h b/src/core/manager.h index 5471bd7a0d..19eab958ea 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -140,6 +140,7 @@ struct Manager { sd_event_source *jobs_in_progress_event_source; + UnitFileScope unit_file_scope; LookupPaths lookup_paths; Set *unit_path_cache; @@ -224,7 +225,6 @@ struct Manager { unsigned n_in_gc_queue; /* Flags */ - ManagerRunningAs running_as; ManagerExitCode exit_code:5; bool dispatching_load_queue:1; @@ -300,10 +300,13 @@ struct Manager { const char *unit_log_field; const char *unit_log_format_string; - int first_boot; + int first_boot; /* tri-state */ }; -int manager_new(ManagerRunningAs running_as, bool test_run, Manager **m); +#define MANAGER_IS_SYSTEM(m) ((m)->unit_file_scope == UNIT_FILE_SYSTEM) +#define MANAGER_IS_USER(m) ((m)->unit_file_scope != UNIT_FILE_SYSTEM) + +int manager_new(UnitFileScope scope, bool test_run, Manager **m); Manager* manager_free(Manager *m); void manager_enumerate(Manager *m); diff --git a/src/core/mount.c b/src/core/mount.c index 0fd880df5d..74ab54bfd0 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -336,8 +336,7 @@ static int mount_add_device_links(Mount *m) { if (path_equal(m->where, "/")) return 0; - if (mount_is_auto(p) && !mount_is_automount(p) && - UNIT(m)->manager->running_as == MANAGER_SYSTEM) + if (mount_is_auto(p) && !mount_is_automount(p) && MANAGER_IS_SYSTEM(UNIT(m)->manager)) device_wants_mount = true; r = unit_add_node_link(UNIT(m), p->what, device_wants_mount, m->from_fragment ? UNIT_BINDS_TO : UNIT_REQUIRES); @@ -353,7 +352,7 @@ static int mount_add_quota_links(Mount *m) { assert(m); - if (UNIT(m)->manager->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(UNIT(m)->manager)) return 0; p = get_mount_parameters_fragment(m); @@ -400,7 +399,7 @@ static int mount_add_default_dependencies(Mount *m) { if (!UNIT(m)->default_dependencies) return 0; - if (UNIT(m)->manager->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(UNIT(m)->manager)) return 0; /* We do not add any default dependencies to /, /usr or @@ -1396,7 +1395,7 @@ static int mount_setup_unit( goto fail; } - if (m->running_as == MANAGER_SYSTEM) { + if (MANAGER_IS_SYSTEM(m)) { const char* target; target = mount_needs_network(options, fstype) ? SPECIAL_REMOTE_FS_TARGET : SPECIAL_LOCAL_FS_TARGET; @@ -1424,7 +1423,7 @@ static int mount_setup_unit( } } - if (m->running_as == MANAGER_SYSTEM && + if (MANAGER_IS_SYSTEM(m) && mount_needs_network(options, fstype)) { /* _netdev option may have shown up late, or on a * remount. Add remote-fs dependencies, even though diff --git a/src/core/path.c b/src/core/path.c index 426c4ad299..5e7b3eb234 100644 --- a/src/core/path.c +++ b/src/core/path.c @@ -318,7 +318,7 @@ static int path_add_default_dependencies(Path *p) { if (r < 0) return r; - if (UNIT(p)->manager->running_as == MANAGER_SYSTEM) { + if (MANAGER_IS_SYSTEM(UNIT(p)->manager)) { r = unit_add_two_dependencies_by_name(UNIT(p), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true); if (r < 0) return r; diff --git a/src/core/service.c b/src/core/service.c index c5cbf0f152..7aea6f7ff4 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -523,7 +523,7 @@ static int service_add_default_dependencies(Service *s) { /* Add a number of automatic dependencies useful for the * majority of services. */ - if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) { + if (MANAGER_IS_SYSTEM(UNIT(s)->manager)) { /* First, pull in the really early boot stuff, and * require it, so that we fail if we can't acquire * it. */ @@ -1211,7 +1211,7 @@ static int service_spawn( if (asprintf(our_env + n_env++, "MAINPID="PID_FMT, s->main_pid) < 0) return -ENOMEM; - if (UNIT(s)->manager->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(UNIT(s)->manager)) if (asprintf(our_env + n_env++, "MANAGERPID="PID_FMT, getpid()) < 0) return -ENOMEM; diff --git a/src/core/socket.c b/src/core/socket.c index dd515a17a5..65da0e3c5e 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -301,7 +301,7 @@ static int socket_add_default_dependencies(Socket *s) { if (r < 0) return r; - if (UNIT(s)->manager->running_as == MANAGER_SYSTEM) { + if (MANAGER_IS_SYSTEM(UNIT(s)->manager)) { r = unit_add_two_dependencies_by_name(UNIT(s), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true); if (r < 0) return r; diff --git a/src/core/swap.c b/src/core/swap.c index 11506d9ecb..c6502eb821 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -198,7 +198,7 @@ static int swap_add_device_links(Swap *s) { return 0; if (is_device_path(s->what)) - return unit_add_node_link(UNIT(s), s->what, UNIT(s)->manager->running_as == MANAGER_SYSTEM, UNIT_BINDS_TO); + return unit_add_node_link(UNIT(s), s->what, MANAGER_IS_SYSTEM(UNIT(s)->manager), UNIT_BINDS_TO); else /* File based swap devices need to be ordered after * systemd-remount-fs.service, since they might need a @@ -214,7 +214,7 @@ static int swap_add_default_dependencies(Swap *s) { if (!UNIT(s)->default_dependencies) return 0; - if (UNIT(s)->manager->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(UNIT(s)->manager)) return 0; if (detect_container() > 0) diff --git a/src/core/timer.c b/src/core/timer.c index 3d0bae16e5..a51a67ea11 100644 --- a/src/core/timer.c +++ b/src/core/timer.c @@ -109,7 +109,7 @@ static int timer_add_default_dependencies(Timer *t) { if (r < 0) return r; - if (UNIT(t)->manager->running_as == MANAGER_SYSTEM) { + if (MANAGER_IS_SYSTEM(UNIT(t)->manager)) { r = unit_add_two_dependencies_by_name(UNIT(t), UNIT_AFTER, UNIT_REQUIRES, SPECIAL_SYSINIT_TARGET, NULL, true); if (r < 0) return r; @@ -135,7 +135,7 @@ static int timer_setup_persistent(Timer *t) { if (!t->persistent) return 0; - if (UNIT(t)->manager->running_as == MANAGER_SYSTEM) { + if (MANAGER_IS_SYSTEM(UNIT(t)->manager)) { r = unit_require_mounts_for(UNIT(t), "/var/lib/systemd/timers"); if (r < 0) diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c index fc057d965c..40da52fcac 100644 --- a/src/core/unit-printf.c +++ b/src/core/unit-printf.c @@ -140,7 +140,7 @@ static int specifier_runtime(char specifier, void *data, void *userdata, char ** assert(u); - if (u->manager->running_as == MANAGER_SYSTEM) + if (MANAGER_IS_SYSTEM(u->manager)) e = "/run"; else { e = getenv("XDG_RUNTIME_DIR"); diff --git a/src/core/unit.c b/src/core/unit.c index 70175557f7..fbc2b0d74d 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -814,7 +814,7 @@ int unit_add_exec_dependencies(Unit *u, ExecContext *c) { return r; } - if (u->manager->running_as != MANAGER_SYSTEM) + if (!MANAGER_IS_SYSTEM(u->manager)) return 0; if (c->private_tmp) { @@ -2413,7 +2413,7 @@ int unit_set_default_slice(Unit *u) { if (!escaped) return -ENOMEM; - if (u->manager->running_as == MANAGER_SYSTEM) + if (MANAGER_IS_SYSTEM(u->manager)) b = strjoin("system-", escaped, ".slice", NULL); else b = strappend(escaped, ".slice"); @@ -2423,7 +2423,7 @@ int unit_set_default_slice(Unit *u) { slice_name = b; } else slice_name = - u->manager->running_as == MANAGER_SYSTEM && !unit_has_name(u, SPECIAL_INIT_SCOPE) + MANAGER_IS_SYSTEM(u->manager) && !unit_has_name(u, SPECIAL_INIT_SCOPE) ? SPECIAL_SYSTEM_SLICE : SPECIAL_ROOT_SLICE; @@ -2884,7 +2884,7 @@ int unit_add_node_link(Unit *u, const char *what, bool wants, UnitDependency dep return r; r = unit_add_two_dependencies(u, UNIT_AFTER, - u->manager->running_as == MANAGER_SYSTEM ? dep : UNIT_WANTS, + MANAGER_IS_SYSTEM(u->manager) ? dep : UNIT_WANTS, device, true); if (r < 0) return r; @@ -3158,7 +3158,7 @@ UnitFileState unit_get_unit_file_state(Unit *u) { if (u->unit_file_state < 0 && u->fragment_path) { r = unit_file_get_state( - u->manager->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, + u->manager->unit_file_scope, NULL, basename(u->fragment_path), &u->unit_file_state); @@ -3174,7 +3174,7 @@ int unit_get_unit_file_preset(Unit *u) { if (u->unit_file_preset < 0 && u->fragment_path) u->unit_file_preset = unit_file_query_preset( - u->manager->running_as == MANAGER_SYSTEM ? UNIT_FILE_SYSTEM : UNIT_FILE_USER, + u->manager->unit_file_scope, NULL, basename(u->fragment_path)); @@ -3225,7 +3225,7 @@ int unit_patch_contexts(Unit *u) { return -ENOMEM; } - if (u->manager->running_as == MANAGER_USER && + if (MANAGER_IS_USER(u->manager) && !ec->working_directory) { r = get_home_dir(&ec->working_directory); @@ -3237,7 +3237,7 @@ int unit_patch_contexts(Unit *u) { ec->working_directory_missing_ok = true; } - if (u->manager->running_as == MANAGER_USER && + if (MANAGER_IS_USER(u->manager) && (ec->syscall_whitelist || !set_isempty(ec->syscall_filter) || !set_isempty(ec->syscall_archs) || @@ -3318,7 +3318,7 @@ ExecRuntime *unit_get_exec_runtime(Unit *u) { static int unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode, bool transient, char **dir) { assert(u); - if (u->manager->running_as == MANAGER_USER) { + if (MANAGER_IS_USER(u->manager)) { int r; if (mode == UNIT_PERSISTENT && !transient) -- cgit v1.2.1 From 2c289ea8332a2c0777d8940058ff7a6293f59b6c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 24 Feb 2016 21:36:09 +0100 Subject: core: introduce MANAGER_IS_RELOADING() macro This replaces the old function call manager_is_reloading_or_reexecuting() which was used only at very few places. Use the new macro wherever we check whether we are reloading. This should hopefully make things a bit more readable, given the nature of Manager:n_reloading being a counter. --- src/core/job.c | 2 +- src/core/manager.c | 12 +++--------- src/core/manager.h | 4 ++-- src/core/scope.c | 6 +++--- src/core/service.c | 2 +- src/core/transaction.c | 2 +- src/core/unit.c | 12 ++++++------ 7 files changed, 17 insertions(+), 23 deletions(-) (limited to 'src/core') diff --git a/src/core/job.c b/src/core/job.c index 2e30431163..d9c5669c9f 100644 --- a/src/core/job.c +++ b/src/core/job.c @@ -137,7 +137,7 @@ void job_uninstall(Job *j) { /* Detach from next 'bigger' objects */ /* daemon-reload should be transparent to job observers */ - if (j->manager->n_reloading <= 0) + if (!MANAGER_IS_RELOADING(j->manager)) bus_job_send_removed_signal(j); *pj = NULL; diff --git a/src/core/manager.c b/src/core/manager.c index 1412d6718a..b3c3445f2c 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -2115,7 +2115,7 @@ void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success) { /* Don't generate audit events if the service was already * started and we're just deserializing */ - if (m->n_reloading > 0) + if (MANAGER_IS_RELOADING(m)) return; if (u->type != UNIT_SERVICE) @@ -2149,7 +2149,7 @@ void manager_send_unit_plymouth(Manager *m, Unit *u) { /* Don't generate plymouth events if the service was already * started and we're just deserializing */ - if (m->n_reloading > 0) + if (MANAGER_IS_RELOADING(m)) return; if (!MANAGER_IS_SYSTEM(m)) @@ -2572,12 +2572,6 @@ int manager_reload(Manager *m) { return r; } -bool manager_is_reloading_or_reexecuting(Manager *m) { - assert(m); - - return m->n_reloading != 0; -} - void manager_reset_failed(Manager *m) { Unit *u; Iterator i; @@ -2674,7 +2668,7 @@ static void manager_notify_finished(Manager *m) { void manager_check_finished(Manager *m) { assert(m); - if (m->n_reloading > 0) + if (MANAGER_IS_RELOADING(m)) return; /* Verify that we are actually running currently. Initially diff --git a/src/core/manager.h b/src/core/manager.h index 19eab958ea..17f84e6963 100644 --- a/src/core/manager.h +++ b/src/core/manager.h @@ -306,6 +306,8 @@ struct Manager { #define MANAGER_IS_SYSTEM(m) ((m)->unit_file_scope == UNIT_FILE_SYSTEM) #define MANAGER_IS_USER(m) ((m)->unit_file_scope != UNIT_FILE_SYSTEM) +#define MANAGER_IS_RELOADING(m) ((m)->n_reloading > 0) + int manager_new(UnitFileScope scope, bool test_run, Manager **m); Manager* manager_free(Manager *m); @@ -344,8 +346,6 @@ int manager_deserialize(Manager *m, FILE *f, FDSet *fds); int manager_reload(Manager *m); -bool manager_is_reloading_or_reexecuting(Manager *m) _pure_; - void manager_reset_failed(Manager *m); void manager_send_unit_audit(Manager *m, Unit *u, int type, bool success); diff --git a/src/core/scope.c b/src/core/scope.c index 361695c3f9..92a3aed331 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -138,7 +138,7 @@ static int scope_verify(Scope *s) { return 0; if (set_isempty(UNIT(s)->pids) && - !manager_is_reloading_or_reexecuting(UNIT(s)->manager) && + !MANAGER_IS_RELOADING(UNIT(s)->manager) && !unit_has_name(UNIT(s), SPECIAL_INIT_SCOPE)) { log_unit_error(UNIT(s), "Scope has no PIDs. Refusing."); return -EINVAL; @@ -154,7 +154,7 @@ static int scope_load(Unit *u) { assert(s); assert(u->load_state == UNIT_STUB); - if (!u->transient && !manager_is_reloading_or_reexecuting(u->manager)) + if (!u->transient && !MANAGER_IS_RELOADING(u->manager)) return -ENOENT; u->load_state = UNIT_LOADED; @@ -292,7 +292,7 @@ static int scope_start(Unit *u) { assert(s->state == SCOPE_DEAD); - if (!u->transient && !manager_is_reloading_or_reexecuting(u->manager)) + if (!u->transient && !MANAGER_IS_RELOADING(u->manager)) return -ENOENT; (void) unit_realize_cgroup(u); diff --git a/src/core/service.c b/src/core/service.c index 7aea6f7ff4..58084e2f82 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -920,7 +920,7 @@ static void service_set_state(Service *s, ServiceState state) { /* For the inactive states unit_notify() will trim the cgroup, * but for exit we have to do that ourselves... */ - if (state == SERVICE_EXITED && UNIT(s)->manager->n_reloading <= 0) + if (state == SERVICE_EXITED && !MANAGER_IS_RELOADING(UNIT(s)->manager)) unit_prune_cgroup(UNIT(s)); /* For remain_after_exit services, let's see if we can "release" the diff --git a/src/core/transaction.c b/src/core/transaction.c index c894001cf9..dad387749c 100644 --- a/src/core/transaction.c +++ b/src/core/transaction.c @@ -855,7 +855,7 @@ int transaction_add_job_and_dependencies( * This matters when jobs are spawned as part of coldplugging itself (see e. g. path_coldplug()). * This way, we "recursively" coldplug units, ensuring that we do not look at state of * not-yet-coldplugged units. */ - if (unit->manager->n_reloading > 0) + if (MANAGER_IS_RELOADING(unit->manager)) unit_coldplug(unit); /* log_debug("Pulling in %s/%s from %s/%s", */ diff --git a/src/core/unit.c b/src/core/unit.c index fbc2b0d74d..565704851b 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -483,7 +483,7 @@ void unit_free(Unit *u) { assert(u); - if (u->manager->n_reloading <= 0) + if (!MANAGER_IS_RELOADING(u->manager)) unit_remove_transient(u); bus_unit_send_removed_signal(u); @@ -1834,7 +1834,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su m = u->manager; /* Update timestamps for state changes */ - if (m->n_reloading <= 0) { + if (!MANAGER_IS_RELOADING(m)) { dual_timestamp_get(&u->state_change_timestamp); if (UNIT_IS_INACTIVE_OR_FAILED(os) && !UNIT_IS_INACTIVE_OR_FAILED(ns)) @@ -1941,7 +1941,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su } else unexpected = true; - if (m->n_reloading <= 0) { + if (!MANAGER_IS_RELOADING(m)) { /* If this state change happened without being * requested by a job, then let's retroactively start @@ -1978,7 +1978,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su if (u->type == UNIT_SERVICE && !UNIT_IS_ACTIVE_OR_RELOADING(os) && - m->n_reloading <= 0) { + !MANAGER_IS_RELOADING(m)) { /* Write audit record if we have just finished starting up */ manager_send_unit_audit(m, u, AUDIT_SERVICE_START, true); u->in_audit = true; @@ -1995,7 +1995,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su if (u->type == UNIT_SERVICE && UNIT_IS_INACTIVE_OR_FAILED(ns) && !UNIT_IS_INACTIVE_OR_FAILED(os) && - m->n_reloading <= 0) { + !MANAGER_IS_RELOADING(m)) { /* Hmm, if there was no start record written * write it now, so that we always have a nice @@ -2016,7 +2016,7 @@ void unit_notify(Unit *u, UnitActiveState os, UnitActiveState ns, bool reload_su manager_recheck_journal(m); unit_trigger_notify(u); - if (u->manager->n_reloading <= 0) { + if (!MANAGER_IS_RELOADING(u->manager)) { /* Maybe we finished startup and are now ready for * being stopped because unneeded? */ unit_check_unneeded(u); -- cgit v1.2.1 From 92dd7c49659a0bb4c8e081199e4ff4351f37397a Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 25 Feb 2016 00:30:32 +0100 Subject: core: reuse manager_get_runtime_prefix() at more places --- src/core/manager.c | 19 +++++++------------ src/core/unit-printf.c | 11 +++-------- 2 files changed, 10 insertions(+), 20 deletions(-) (limited to 'src/core') diff --git a/src/core/manager.c b/src/core/manager.c index b3c3445f2c..c72b46be30 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -676,6 +676,7 @@ static int manager_setup_notify(Manager *m) { .sa.sa_family = AF_UNIX, }; static const int one = 1; + const char *e; /* First free all secondary fields */ m->notify_socket = mfree(m->notify_socket); @@ -687,19 +688,13 @@ static int manager_setup_notify(Manager *m) { fd_inc_rcvbuf(fd, NOTIFY_RCVBUF_SIZE); - if (MANAGER_IS_SYSTEM(m)) - m->notify_socket = strdup("/run/systemd/notify"); - else { - const char *e; - - e = getenv("XDG_RUNTIME_DIR"); - if (!e) { - log_error_errno(errno, "XDG_RUNTIME_DIR is not set: %m"); - return -EINVAL; - } - - m->notify_socket = strappend(e, "/systemd/notify"); + e = manager_get_runtime_prefix(m); + if (!e) { + log_error("Failed to determine runtime prefix."); + return -EINVAL; } + + m->notify_socket = strappend(e, "/systemd/notify"); if (!m->notify_socket) return log_oom(); diff --git a/src/core/unit-printf.c b/src/core/unit-printf.c index 40da52fcac..f11df42af3 100644 --- a/src/core/unit-printf.c +++ b/src/core/unit-printf.c @@ -140,14 +140,9 @@ static int specifier_runtime(char specifier, void *data, void *userdata, char ** assert(u); - if (MANAGER_IS_SYSTEM(u->manager)) - e = "/run"; - else { - e = getenv("XDG_RUNTIME_DIR"); - if (!e) - return -EOPNOTSUPP; - } - + e = manager_get_runtime_prefix(u->manager); + if (!e) + return -EOPNOTSUPP; n = strdup(e); if (!n) return -ENOMEM; -- cgit v1.2.1 From 39591351391de3ef2fd23cc5aea5bdd6ab712db6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 25 Feb 2016 01:13:57 +0100 Subject: core: add a separate unit directory for transient units Previously, transient units were created below the normal runtime directory /run/systemd/system. With this change they are created in a special transient directory /run/systemd/transient, which only contains data for transient units. This clarifies the life-cycle of transient units, and makes clear they are distinct from user-provided runtime units. In particular, users may now extend transient units via /run/systemd/system, without systemd interfering with the life-cycle of these files. This change also adds code so that when a transient unit exits only the drop-ins in this new directory are removed, but nothing else. Fixes: #2139 --- src/core/manager.c | 6 ++++++ src/core/unit.c | 62 +++++++++++++++++++++++++----------------------------- 2 files changed, 35 insertions(+), 33 deletions(-) (limited to 'src/core') diff --git a/src/core/manager.c b/src/core/manager.c index c72b46be30..1bc7921abe 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -63,6 +63,7 @@ #include "manager.h" #include "missing.h" #include "mkdir.h" +#include "mkdir.h" #include "parse-util.h" #include "path-lookup.h" #include "path-util.h" @@ -1108,6 +1109,11 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { if (r < 0) return r; + /* Make sure the transient directory always exists, so that it remains in the search path */ + r = mkdir_p_label(m->lookup_paths.transient, 0755); + if (r < 0) + return r; + dual_timestamp_get(&m->generators_start_timestamp); r = manager_run_generators(m); dual_timestamp_get(&m->generators_finish_timestamp); diff --git a/src/core/unit.c b/src/core/unit.c index 565704851b..f6c9891aad 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -418,13 +418,22 @@ static void unit_remove_transient(Unit *u) { (void) unlink(u->fragment_path); STRV_FOREACH(i, u->dropin_paths) { - _cleanup_free_ char *p = NULL; + _cleanup_free_ char *p = NULL, *pp = NULL; - (void) unlink(*i); + p = dirname_malloc(*i); /* Get the drop-in directory from the drop-in file */ + if (!p) + continue; + + pp = dirname_malloc(p); /* Get the config directory from the drop-in directory */ + if (!pp) + continue; + + /* Only drop transient drop-ins */ + if (!path_equal(u->manager->lookup_paths.transient, pp)) + continue; - p = dirname_malloc(*i); - if (p) - (void) rmdir(p); + (void) unlink(*i); + (void) rmdir(p); } } @@ -3315,35 +3324,24 @@ ExecRuntime *unit_get_exec_runtime(Unit *u) { return *(ExecRuntime**) ((uint8_t*) u + offset); } -static int unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode, bool transient, char **dir) { +static const char* unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode) { assert(u); - if (MANAGER_IS_USER(u->manager)) { - int r; + if (u->transient) /* Redirect drop-ins for transient units always into the transient directory. */ + return u->manager->lookup_paths.transient; - if (mode == UNIT_PERSISTENT && !transient) - r = user_config_home(dir); - else - r = user_runtime_dir(dir); - if (r == 0) - return -ENOENT; + if (mode == UNIT_RUNTIME) + return u->manager->lookup_paths.runtime_config; - return r; - } + if (mode == UNIT_PERSISTENT) + return u->manager->lookup_paths.persistent_config; - if (mode == UNIT_PERSISTENT && !transient) - *dir = strdup("/etc/systemd/system"); - else - *dir = strdup("/run/systemd/system"); - if (!*dir) - return -ENOMEM; - - return 0; + return NULL; } int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) { - - _cleanup_free_ char *dir = NULL, *p = NULL, *q = NULL; + _cleanup_free_ char *p = NULL, *q = NULL; + const char *dir; int r; assert(u); @@ -3351,9 +3349,9 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) return 0; - r = unit_drop_in_dir(u, mode, u->transient, &dir); - if (r < 0) - return r; + dir = unit_drop_in_dir(u, mode); + if (!dir) + return -EINVAL; r = write_drop_in(dir, u->id, 50, name, data); if (r < 0) @@ -3398,7 +3396,7 @@ int unit_write_drop_in_format(Unit *u, UnitSetPropertiesMode mode, const char *n } int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) { - _cleanup_free_ char *ndata = NULL; + const char *ndata; assert(u); assert(name); @@ -3410,9 +3408,7 @@ int unit_write_drop_in_private(Unit *u, UnitSetPropertiesMode mode, const char * if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) return 0; - ndata = strjoin("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL); - if (!ndata) - return -ENOMEM; + ndata = strjoina("[", UNIT_VTABLE(u)->private_section, "]\n", data, NULL); return unit_write_drop_in(u, mode, name, ndata); } -- cgit v1.2.1 From cd64fd56134ef00cce0651e741d4ebda3791d97b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 25 Feb 2016 01:44:30 +0100 Subject: path-lookup: split out logic for mkdir/rmdir of generator dirs in their own functions --- src/core/manager.c | 15 ++------------- 1 file changed, 2 insertions(+), 13 deletions(-) (limited to 'src/core') diff --git a/src/core/manager.c b/src/core/manager.c index 1bc7921abe..d48b41d88f 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -2737,15 +2737,7 @@ static int manager_run_generators(Manager *m) { return 0; found: - r = mkdir_p_label(m->lookup_paths.generator, 0755); - if (r < 0) - goto finish; - - r = mkdir_p_label(m->lookup_paths.generator_early, 0755); - if (r < 0) - goto finish; - - r = mkdir_p_label(m->lookup_paths.generator_late, 0755); + r = lookup_paths_mkdir_generator(&m->lookup_paths); if (r < 0) goto finish; @@ -2759,10 +2751,7 @@ static int manager_run_generators(Manager *m) { execute_directories((const char* const*) paths, DEFAULT_TIMEOUT_USEC, (char**) argv); finish: - /* Trim empty dirs */ - (void) rmdir(m->lookup_paths.generator); - (void) rmdir(m->lookup_paths.generator_early); - (void) rmdir(m->lookup_paths.generator_late); + lookup_paths_trim_generator(&m->lookup_paths); return r; } -- cgit v1.2.1 From a14533430498bfaa91ba19b7fd0268bd2ef7d797 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 25 Feb 2016 02:32:19 +0100 Subject: core: rework logic to drop duplicate and non-existing items from search path Move this into a function of its own, so that we can run it after we ran the generators, so that it takes into account removed generator dirs. --- src/core/manager.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/core') diff --git a/src/core/manager.c b/src/core/manager.c index d48b41d88f..55f2f49a06 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1120,6 +1120,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { if (r < 0) return r; + lookup_paths_reduce(&m->lookup_paths); manager_build_unit_path_cache(m); /* If we will deserialize make sure that during enumeration @@ -2540,6 +2541,7 @@ int manager_reload(Manager *m) { if (q < 0 && r >= 0) r = q; + lookup_paths_reduce(&m->lookup_paths); manager_build_unit_path_cache(m); /* First, enumerate what we can from all config files */ -- cgit v1.2.1 From d7e0da1db2ac9e747893ef5f565c554eb246e3f4 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 26 Feb 2016 17:05:33 +0100 Subject: core: don't drop transient drop-ins when loading the rest Previously, when creating a transient unit, we'd first add the transient drop-ins to the unit, and then normally load any other drop-ins later on top of this, replacing the already loaded drop-ins. Let's not do this, after all the transient drop-ins area already in effect, let's just add what we find on disk, but not replace it. --- src/core/load-dropin.c | 13 +++++++++++-- 1 file changed, 11 insertions(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/load-dropin.c b/src/core/load-dropin.c index 1c65055a3f..f83fa09301 100644 --- a/src/core/load-dropin.c +++ b/src/core/load-dropin.c @@ -44,6 +44,7 @@ static int add_dependency_consumer( } int unit_load_dropin(Unit *u) { + _cleanup_strv_free_ char **l = NULL; Iterator i; char *t, **f; int r; @@ -63,11 +64,19 @@ int unit_load_dropin(Unit *u) { } } - u->dropin_paths = strv_free(u->dropin_paths); - r = unit_find_dropin_paths(u, &u->dropin_paths); + r = unit_find_dropin_paths(u, &l); if (r <= 0) return 0; + if (!u->dropin_paths) { + u->dropin_paths = l; + l = NULL; + } else { + r = strv_extend_strv(&u->dropin_paths, l, true); + if (r < 0) + return log_oom(); + } + STRV_FOREACH(f, u->dropin_paths) { config_parse(u->id, *f, NULL, UNIT_VTABLE(u)->sections, -- cgit v1.2.1 From 193dc81ee336ad07b92e7e945b458eb24f615f55 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 26 Feb 2016 17:58:37 +0100 Subject: core: don't reorder drop-ins when changing properties The drop-in order we present should actually show what we is in effect, hence let's not reorder it when writing changes. After all, just sorting alphabetically is going to break things, as it doesn't respect that /etc breaks /run breaks /usr... --- src/core/unit.c | 1 - 1 file changed, 1 deletion(-) (limited to 'src/core') diff --git a/src/core/unit.c b/src/core/unit.c index f6c9891aad..ac29353299 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -3365,7 +3365,6 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co if (r < 0) return r; - strv_sort(u->dropin_paths); strv_uniq(u->dropin_paths); u->dropin_mtime = now(CLOCK_REALTIME); -- cgit v1.2.1 From d063a527411ac9aa715bee59a9dcc59c877d2362 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 26 Feb 2016 18:28:45 +0100 Subject: core: modernize manager_build_unit_patch_cache() a bit --- src/core/manager.c | 23 ++++++++--------------- 1 file changed, 8 insertions(+), 15 deletions(-) (limited to 'src/core') diff --git a/src/core/manager.c b/src/core/manager.c index 55f2f49a06..b1f79e014e 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -49,6 +49,7 @@ #include "dbus-manager.h" #include "dbus-unit.h" #include "dbus.h" +#include "dirent-util.h" #include "env-util.h" #include "escape.h" #include "exit-status.h" @@ -1026,7 +1027,6 @@ static void manager_coldplug(Manager *m) { static void manager_build_unit_path_cache(Manager *m) { char **i; - _cleanup_closedir_ DIR *d = NULL; int r; assert(m); @@ -1035,29 +1035,27 @@ static void manager_build_unit_path_cache(Manager *m) { m->unit_path_cache = set_new(&string_hash_ops); if (!m->unit_path_cache) { - log_error("Failed to allocate unit path cache."); - return; + r = -ENOMEM; + goto fail; } /* This simply builds a list of files we know exist, so that * we don't always have to go to disk */ STRV_FOREACH(i, m->lookup_paths.search_path) { + _cleanup_closedir_ DIR *d = NULL; struct dirent *de; d = opendir(*i); if (!d) { if (errno != ENOENT) - log_error_errno(errno, "Failed to open directory %s: %m", *i); + log_warning_errno(errno, "Failed to open directory %s, ignoring: %m", *i); continue; } - while ((de = readdir(d))) { + FOREACH_DIRENT(de, d, r = -errno; goto fail) { char *p; - if (hidden_file(de->d_name)) - continue; - p = strjoin(streq(*i, "/") ? "" : *i, "/", de->d_name, NULL); if (!p) { r = -ENOMEM; @@ -1068,20 +1066,15 @@ static void manager_build_unit_path_cache(Manager *m) { if (r < 0) goto fail; } - - d = safe_closedir(d); } return; fail: - log_error_errno(r, "Failed to build unit path cache: %m"); - - set_free_free(m->unit_path_cache); - m->unit_path_cache = NULL; + log_warning_errno(r, "Failed to build unit path cache, proceeding without: %m"); + m->unit_path_cache = set_free_free(m->unit_path_cache); } - static void manager_distribute_fds(Manager *m, FDSet *fds) { Iterator i; Unit *u; -- cgit v1.2.1 From e4fca67ff02c44216780c5a61b1ab66cb6c09752 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 7 Mar 2016 19:07:30 +0100 Subject: install: introduce a new unit file state "transient" Now, that the search path logic knows the unit path for transient units we also can introduce an explicit unit file state "transient" that clarifies to the user what kind of unit file he is encountering. --- src/core/dbus-manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 5fc3526751..f0ee2fcb36 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1641,7 +1641,7 @@ static int method_enable_unit_files_generic( if (r == -ESHUTDOWN) return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked."); if (r == -EADDRNOTAVAIL) - return sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED, "Unit file is generated."); + return sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED, "Unit file is transient or generated."); if (r < 0) return r; @@ -1866,7 +1866,7 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd if (r == -ESHUTDOWN) return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked."); if (r == -EADDRNOTAVAIL) - return sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED, "Unit file is generated."); + return sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED, "Unit file is transient or generated."); if (r < 0) return r; -- cgit v1.2.1 From d8d410f4455238e30daa1775b469e31f34371f87 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2016 20:46:52 +0200 Subject: core: minor coding style fix --- src/core/dbus-execute.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/core') diff --git a/src/core/dbus-execute.c b/src/core/dbus-execute.c index 973a60187d..9dfca14914 100644 --- a/src/core/dbus-execute.c +++ b/src/core/dbus-execute.c @@ -837,9 +837,9 @@ int bus_exec_context_set_transient_property( if (mode != UNIT_CHECK) { - if (isempty(uu)) { + if (isempty(uu)) c->user = mfree(c->user); - } else { + else { char *t; t = strdup(uu); @@ -864,9 +864,9 @@ int bus_exec_context_set_transient_property( if (mode != UNIT_CHECK) { - if (isempty(gg)) { + if (isempty(gg)) c->group = mfree(c->group); - } else { + else { char *t; t = strdup(gg); -- cgit v1.2.1 From 07a7864324e146662cb06f49fc3cd666788e2e2f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2016 20:47:44 +0200 Subject: core: move flushing of generated unit files to path-lookup.c It's very similar to the mkdir and trim operations for the generator dirs, hence let's unify this at a single place. --- src/core/manager.c | 16 ++-------------- 1 file changed, 2 insertions(+), 14 deletions(-) (limited to 'src/core') diff --git a/src/core/manager.c b/src/core/manager.c index b1f79e014e..6ce3e404c9 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -100,7 +100,6 @@ static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32 static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata); static int manager_dispatch_run_queue(sd_event_source *source, void *userdata); static int manager_run_generators(Manager *m); -static void manager_undo_generators(Manager *m); static void manager_watch_jobs_in_progress(Manager *m) { usec_t next; @@ -930,7 +929,7 @@ Manager* manager_free(Manager *m) { * around */ manager_shutdown_cgroup(m, m->exit_code != MANAGER_REEXECUTE); - manager_undo_generators(m); + lookup_paths_flush_generator(&m->lookup_paths); bus_done(m); @@ -2522,7 +2521,7 @@ int manager_reload(Manager *m) { /* From here on there is no way back. */ manager_clear_jobs_and_units(m); - manager_undo_generators(m); + lookup_paths_flush_generator(&m->lookup_paths); lookup_paths_free(&m->lookup_paths); q = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, NULL); @@ -2750,17 +2749,6 @@ finish: return r; } -static void manager_undo_generators(Manager *m) { - assert(m); - - if (m->lookup_paths.generator) - (void) rm_rf(m->lookup_paths.generator, REMOVE_ROOT); - if (m->lookup_paths.generator_early) - (void) rm_rf(m->lookup_paths.generator_early, REMOVE_ROOT); - if (m->lookup_paths.generator_late) - (void) rm_rf(m->lookup_paths.generator_late, REMOVE_ROOT); -} - int manager_environment_add(Manager *m, char **minus, char **plus) { char **a = NULL, **b = NULL, **l; assert(m); -- cgit v1.2.1 From 9183df707bde9e83d838e7b5a05db0c5f4b55e6d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 6 Apr 2016 20:48:58 +0200 Subject: =?UTF-8?q?install:=20rename=20generator=5Fpaths()=20=E2=86=92=20g?= =?UTF-8?q?enerator=5Fbinary=5Fpaths()?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is too confusing, as this funciton returns the paths to the generator binaries, while usually when we refer to the just the "generator path" we mean the generated unit files. Let's clean this up. --- src/core/manager.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/core') diff --git a/src/core/manager.c b/src/core/manager.c index 6ce3e404c9..91fe9c2d5b 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -2715,7 +2715,7 @@ static int manager_run_generators(Manager *m) { if (m->test_run) return 0; - paths = generator_paths(m->unit_file_scope); + paths = generator_binary_paths(m->unit_file_scope); if (!paths) return log_oom(); -- cgit v1.2.1 From 4f4afc88ecd8ab9cfe9e1eeea7e3aeb937811937 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 7 Apr 2016 15:43:59 +0200 Subject: core: rework how transient unit files and property drop-ins work With this change the logic for placing transient unit files and drop-ins generated via "systemctl set-property" is reworked. The latter are now placed in the newly introduced "control" unit file directory. The fomer are now placed in the "transient" unit file directory. Note that the properties originally set when a transient unit was created will be written to and stay in the transient unit file directory, while later changes are done via drop-ins. This is preparation for a later "systemctl revert" addition, where existing drop-ins are flushed out, but the original transient definition is restored. --- src/core/scope.c | 25 ++++++++++++----------- src/core/slice.c | 1 + src/core/unit.c | 61 ++++++++++++++++++++++++++++++++++++++++++++++++++------ src/core/unit.h | 3 +++ 4 files changed, 72 insertions(+), 18 deletions(-) (limited to 'src/core') diff --git a/src/core/scope.c b/src/core/scope.c index 92a3aed331..7078d1f7e9 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -155,25 +155,26 @@ static int scope_load(Unit *u) { assert(u->load_state == UNIT_STUB); if (!u->transient && !MANAGER_IS_RELOADING(u->manager)) + /* Refuse to load non-transient scope units, but allow them while reloading. */ return -ENOENT; - u->load_state = UNIT_LOADED; - - r = unit_load_dropin(u); + r = unit_load_fragment_and_dropin_optional(u); if (r < 0) return r; - r = unit_patch_contexts(u); - if (r < 0) - return r; + if (u->load_state == UNIT_LOADED) { + r = unit_patch_contexts(u); + if (r < 0) + return r; - r = unit_set_default_slice(u); - if (r < 0) - return r; + r = unit_set_default_slice(u); + if (r < 0) + return r; - r = scope_add_default_dependencies(s); - if (r < 0) - return r; + r = scope_add_default_dependencies(s); + if (r < 0) + return r; + } return scope_verify(s); } diff --git a/src/core/slice.c b/src/core/slice.c index 667f61bde5..63a77c9bca 100644 --- a/src/core/slice.c +++ b/src/core/slice.c @@ -135,6 +135,7 @@ static int slice_load(Unit *u) { int r; assert(s); + assert(u->load_state == UNIT_STUB); r = unit_load_fragment_and_dropin_optional(u); if (r < 0) diff --git a/src/core/unit.c b/src/core/unit.c index ac29353299..c028f57f13 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -52,6 +52,7 @@ #include "stdio-util.h" #include "string-util.h" #include "strv.h" +#include "umask-util.h" #include "unit-name.h" #include "unit.h" #include "user-util.h" @@ -492,6 +493,9 @@ void unit_free(Unit *u) { assert(u); + if (u->transient_file) + fclose(u->transient_file); + if (!MANAGER_IS_RELOADING(u->manager)) unit_remove_transient(u); @@ -1231,6 +1235,15 @@ int unit_load(Unit *u) { if (u->load_state != UNIT_STUB) return 0; + if (u->transient_file) { + r = fflush_and_check(u->transient_file); + if (r < 0) + goto fail; + + fclose(u->transient_file); + u->transient_file = NULL; + } + if (UNIT_VTABLE(u)->load) { r = UNIT_VTABLE(u)->load(u); if (r < 0) @@ -3327,14 +3340,17 @@ ExecRuntime *unit_get_exec_runtime(Unit *u) { static const char* unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode) { assert(u); + if (!IN_SET(mode, UNIT_RUNTIME, UNIT_PERSISTENT)) + return NULL; + if (u->transient) /* Redirect drop-ins for transient units always into the transient directory. */ return u->manager->lookup_paths.transient; if (mode == UNIT_RUNTIME) - return u->manager->lookup_paths.runtime_config; + return u->manager->lookup_paths.runtime_control; if (mode == UNIT_PERSISTENT) - return u->manager->lookup_paths.persistent_config; + return u->manager->lookup_paths.persistent_control; return NULL; } @@ -3346,6 +3362,13 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co assert(u); + if (u->transient_file) { + /* When this is a transient unit file in creation, then let's not create a new drop-in but instead + * write to the transient unit file. */ + fputs(data, u->transient_file); + return 0; + } + if (!IN_SET(mode, UNIT_PERSISTENT, UNIT_RUNTIME)) return 0; @@ -3435,24 +3458,50 @@ int unit_write_drop_in_private_format(Unit *u, UnitSetPropertiesMode mode, const } int unit_make_transient(Unit *u) { + FILE *f; + char *path; + assert(u); if (!UNIT_VTABLE(u)->can_transient) return -EOPNOTSUPP; - u->load_state = UNIT_STUB; - u->load_error = 0; - u->transient = true; + path = strjoin(u->manager->lookup_paths.transient, "/", u->id, NULL); + if (!path) + return -ENOMEM; + + /* Let's open the file we'll write the transient settings into. This file is kept open as long as we are + * creating the transient, and is closed in unit_load(), as soon as we start loading the file. */ + + RUN_WITH_UMASK(0022) + f = fopen(path, "we"); + if (!f) { + free(path); + return -errno; + } + + if (u->transient_file) + fclose(u->transient_file); + u->transient_file = f; + + free(u->fragment_path); + u->fragment_path = path; - u->fragment_path = mfree(u->fragment_path); u->source_path = mfree(u->source_path); u->dropin_paths = strv_free(u->dropin_paths); u->fragment_mtime = u->source_mtime = u->dropin_mtime = 0; + u->load_state = UNIT_STUB; + u->load_error = 0; + u->transient = true; + unit_add_to_dbus_queue(u); unit_add_to_gc_queue(u); unit_add_to_load_queue(u); + fputs("# This is a transient unit file, created programmatically via the systemd API. Do not edit.\n", + u->transient_file); + return 0; } diff --git a/src/core/unit.h b/src/core/unit.h index 601e763ce2..cfdac852a5 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -95,6 +95,9 @@ struct Unit { usec_t source_mtime; usec_t dropin_mtime; + /* If this is a transient unit we are currently writing, this is where we are writing it to */ + FILE *transient_file; + /* If there is something to do with this unit, then this is the installed job for it */ Job *job; -- cgit v1.2.1 From 8612da973d30c5a9530fa1b6b3d449147b5a3324 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 7 Apr 2016 16:15:26 +0200 Subject: core: be more paranoid when mixing umask and fopen() Let's be extra careful with the umask when we use simple fopen(), as this creates files with 0777 by default. --- src/core/machine-id-setup.c | 3 +-- src/core/main.c | 4 +++- 2 files changed, 4 insertions(+), 3 deletions(-) (limited to 'src/core') diff --git a/src/core/machine-id-setup.c b/src/core/machine-id-setup.c index 7b25349c07..86da16c31e 100644 --- a/src/core/machine-id-setup.c +++ b/src/core/machine-id-setup.c @@ -259,9 +259,8 @@ int machine_id_setup(const char *root, sd_id128_t machine_id) { /* Hmm, we couldn't write it? So let's write it to * /run/machine-id as a replacement */ - RUN_WITH_UMASK(0022) { + RUN_WITH_UMASK(0022) r = write_string_file(run_machine_id, id, WRITE_STRING_FILE_CREATE); - } if (r < 0) { (void) unlink(run_machine_id); return log_error_errno(r, "Cannot write %s: %m", run_machine_id); diff --git a/src/core/main.c b/src/core/main.c index a428e345e0..2912608435 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -81,6 +81,7 @@ #include "strv.h" #include "switch-root.h" #include "terminal-util.h" +#include "umask-util.h" #include "user-util.h" #include "virt.h" #include "watchdog.h" @@ -1237,7 +1238,8 @@ static int write_container_id(void) { if (isempty(c)) return 0; - r = write_string_file("/run/systemd/container", c, WRITE_STRING_FILE_CREATE); + RUN_WITH_UMASK(0022) + r = write_string_file("/run/systemd/container", c, WRITE_STRING_FILE_CREATE); if (r < 0) return log_warning_errno(r, "Failed to write /run/systemd/container, ignoring: %m"); -- cgit v1.2.1 From 27c06cb516c3b87c34f2a1c2c227152997d05c8c Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 7 Apr 2016 16:53:37 +0200 Subject: core: rework reboot parameter logic a bit Always warn if something fails, and clarify that the involved utility functions do so in their name. Drop the REBOOT_PARAM_FILE macro. We don't do this for other flag file paths like this, so don't do this for this one either. The path isn't configurable anyway, hence let's make this easier to read by avoiding this one indirection. --- src/core/failure-action.c | 14 +++++++------- src/core/shutdown.c | 7 ++++++- 2 files changed, 13 insertions(+), 8 deletions(-) (limited to 'src/core') diff --git a/src/core/failure-action.c b/src/core/failure-action.c index d4aae4b6e7..ddae46190f 100644 --- a/src/core/failure-action.c +++ b/src/core/failure-action.c @@ -61,17 +61,17 @@ int failure_action( case FAILURE_ACTION_REBOOT: log_and_status(m, "Rebooting as result of failure."); - update_reboot_param_file(reboot_arg); - (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, - JOB_REPLACE_IRREVERSIBLY, NULL); + (void) update_reboot_parameter_and_warn(reboot_arg); + (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_REBOOT_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL); break; case FAILURE_ACTION_REBOOT_FORCE: log_and_status(m, "Forcibly rebooting as result of failure."); - update_reboot_param_file(reboot_arg); + (void) update_reboot_parameter_and_warn(reboot_arg); m->exit_code = MANAGER_REBOOT; + break; case FAILURE_ACTION_REBOOT_IMMEDIATE: @@ -79,9 +79,10 @@ int failure_action( sync(); - if (reboot_arg) { + if (!isempty(reboot_arg)) { log_info("Rebooting with argument '%s'.", reboot_arg); syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, reboot_arg); + log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m"); } log_info("Rebooting."); @@ -90,8 +91,7 @@ int failure_action( case FAILURE_ACTION_POWEROFF: log_and_status(m, "Powering off as result of failure."); - (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, - JOB_REPLACE_IRREVERSIBLY, NULL); + (void) manager_add_job_by_name_and_warn(m, JOB_START, SPECIAL_POWEROFF_TARGET, JOB_REPLACE_IRREVERSIBLY, NULL); break; case FAILURE_ACTION_POWEROFF_FORCE: diff --git a/src/core/shutdown.c b/src/core/shutdown.c index 96679c920f..e14755d84e 100644 --- a/src/core/shutdown.c +++ b/src/core/shutdown.c @@ -397,9 +397,14 @@ int main(int argc, char *argv[]) { if (!in_container) { _cleanup_free_ char *param = NULL; - if (read_one_line_file(REBOOT_PARAM_FILE, ¶m) >= 0) { + r = read_one_line_file("/run/systemd/reboot-param", ¶m); + if (r < 0) + log_warning_errno(r, "Failed to read reboot parameter file: %m"); + + if (!isempty(param)) { log_info("Rebooting with argument '%s'.", param); syscall(SYS_reboot, LINUX_REBOOT_MAGIC1, LINUX_REBOOT_MAGIC2, LINUX_REBOOT_CMD_RESTART2, param); + log_warning_errno(errno, "Failed to reboot with parameter, retrying without: %m"); } } -- cgit v1.2.1 From 4943d14306c3e456525fdb793e7f48efea5b9236 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 7 Apr 2016 18:48:01 +0200 Subject: systemctl: don't confuse sysv code with generated units The SysV compat code checks whether there's a native unit file before looking for a SysV init script. Since the newest rework generated units will show up in the unit path, and hence the checks ended up assuming that there always was a native unit file for each init script: the generated one. With this change the generated unit file directory is suppressed from the search path when this check is done, to avoid the confusion. --- src/core/manager.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/manager.c b/src/core/manager.c index 91fe9c2d5b..5601770670 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -1097,7 +1097,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) { assert(m); - r = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, NULL); + r = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, 0, NULL); if (r < 0) return r; @@ -2524,7 +2524,7 @@ int manager_reload(Manager *m) { lookup_paths_flush_generator(&m->lookup_paths); lookup_paths_free(&m->lookup_paths); - q = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, NULL); + q = lookup_paths_init(&m->lookup_paths, m->unit_file_scope, 0, NULL); if (q < 0 && r >= 0) r = q; -- cgit v1.2.1 From 6eb7c172b58d81a5f6c3998ce304a7324fc65050 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 8 Apr 2016 11:27:28 +0200 Subject: tree-wide: add new SIGNAL_VALID() macro-like function that validates signal numbers And port all code over to use it. --- src/core/dbus-kill.c | 4 ++-- src/core/dbus-unit.c | 5 +++-- src/core/unit.c | 4 ++-- 3 files changed, 7 insertions(+), 6 deletions(-) (limited to 'src/core') diff --git a/src/core/dbus-kill.c b/src/core/dbus-kill.c index fc50fafaad..0f54c6b84b 100644 --- a/src/core/dbus-kill.c +++ b/src/core/dbus-kill.c @@ -58,7 +58,7 @@ int bus_kill_context_set_transient_property( k = kill_mode_from_string(m); if (k < 0) - return -EINVAL; + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Kill mode '%s' not known.", m); if (mode != UNIT_CHECK) { c->kill_mode = k; @@ -75,7 +75,7 @@ int bus_kill_context_set_transient_property( if (r < 0) return r; - if (sig <= 0 || sig >= _NSIG) + if (!SIGNAL_VALID(sig)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal %i out of range", sig); if (mode != UNIT_CHECK) { diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index b351f6a2c2..c507265070 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -27,6 +27,7 @@ #include "locale-util.h" #include "log.h" #include "selinux-access.h" +#include "signal-util.h" #include "special.h" #include "string-util.h" #include "strv.h" @@ -547,7 +548,7 @@ int bus_unit_method_kill(sd_bus_message *message, void *userdata, sd_bus_error * return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid who argument %s", swho); } - if (signo <= 0 || signo >= _NSIG) + if (!SIGNAL_VALID(signo)) return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Signal number out of range."); r = bus_verify_manage_units_async_full( @@ -1002,7 +1003,6 @@ int bus_unit_queue_job( type = JOB_TRY_RELOAD; } - if (type == JOB_STOP && (u->load_state == UNIT_NOT_FOUND || u->load_state == UNIT_ERROR) && unit_active_state(u) == UNIT_INACTIVE) @@ -1259,6 +1259,7 @@ int bus_unit_set_properties( } int bus_unit_check_load_state(Unit *u, sd_bus_error *error) { + assert(u); if (u->load_state == UNIT_LOADED) return 0; diff --git a/src/core/unit.c b/src/core/unit.c index c028f57f13..a8174e6041 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -47,6 +47,7 @@ #include "path-util.h" #include "process-util.h" #include "set.h" +#include "signal-util.h" #include "special.h" #include "stat-util.h" #include "stdio-util.h" @@ -3062,8 +3063,7 @@ bool unit_active_or_pending(Unit *u) { int unit_kill(Unit *u, KillWho w, int signo, sd_bus_error *error) { assert(u); assert(w >= 0 && w < _KILL_WHO_MAX); - assert(signo > 0); - assert(signo < _NSIG); + assert(SIGNAL_VALID(signo)); if (!UNIT_VTABLE(u)->kill) return -EOPNOTSUPP; -- cgit v1.2.1 From 344ca7556bf6c1c8727c19a0eb8751a27dc0a85f Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 8 Apr 2016 18:00:36 +0200 Subject: core,systemctl: add new "systemctl revert" command This allows dropping all user configuration and reverting back to the vendor default of a unit file. It basically undoes what "systemctl edit", "systemctl set-property" and "systemctl mask" do. --- src/core/dbus-manager.c | 28 ++++++++++++++++++++++++++++ src/core/org.freedesktop.systemd1.conf | 4 ++++ 2 files changed, 32 insertions(+) (limited to 'src/core') diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index f0ee2fcb36..41f27ec26b 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1758,6 +1758,33 @@ static int method_unmask_unit_files(sd_bus_message *message, void *userdata, sd_ return method_disable_unit_files_generic(message, userdata, "enable", unit_file_unmask, error); } +static int method_revert_unit_files(sd_bus_message *message, void *userdata, sd_bus_error *error) { + _cleanup_strv_free_ char **l = NULL; + UnitFileChange *changes = NULL; + unsigned n_changes = 0; + Manager *m = userdata; + int r; + + assert(message); + assert(m); + + r = sd_bus_message_read_strv(message, &l); + if (r < 0) + return r; + + r = bus_verify_manage_unit_files_async(m, message, error); + if (r < 0) + return r; + if (r == 0) + return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ + + r = unit_file_revert(m->unit_file_scope, NULL, l, &changes, &n_changes); + if (r < 0) + return r; + + return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); +} + static int method_set_default_target(sd_bus_message *message, void *userdata, sd_bus_error *error) { UnitFileChange *changes = NULL; unsigned n_changes = 0; @@ -2005,6 +2032,7 @@ const sd_bus_vtable bus_manager_vtable[] = { SD_BUS_METHOD("PresetUnitFilesWithMode", "assbb", "ba(sss)", method_preset_unit_files_with_mode, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("MaskUnitFiles", "asbb", "a(sss)", method_mask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("UnmaskUnitFiles", "asb", "a(sss)", method_unmask_unit_files, SD_BUS_VTABLE_UNPRIVILEGED), + SD_BUS_METHOD("RevertUnitFiles", "as", "a(sss)", method_revert_unit_files, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("SetDefaultTarget", "sb", "a(sss)", method_set_default_target, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("GetDefaultTarget", NULL, "s", method_get_default_target, SD_BUS_VTABLE_UNPRIVILEGED), SD_BUS_METHOD("PresetAllUnitFiles", "sbb", "a(sss)", method_preset_all_unit_files, SD_BUS_VTABLE_UNPRIVILEGED), diff --git a/src/core/org.freedesktop.systemd1.conf b/src/core/org.freedesktop.systemd1.conf index 6a7a37ee92..f78eedbd6e 100644 --- a/src/core/org.freedesktop.systemd1.conf +++ b/src/core/org.freedesktop.systemd1.conf @@ -174,6 +174,10 @@ send_interface="org.freedesktop.systemd1.Manager" send_member="LinkUnitFiles"/> + + -- cgit v1.2.1 From e20b2a867ac5ac7ff6d43898fb83bc78f730909e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 8 Apr 2016 18:10:32 +0200 Subject: core: when creating a drop-in snippet, add a comment explaining this to it --- src/core/unit.c | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) (limited to 'src/core') diff --git a/src/core/unit.c b/src/core/unit.c index a8174e6041..fb4f3ddff6 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -3357,7 +3357,7 @@ static const char* unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode) { int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, const char *data) { _cleanup_free_ char *p = NULL, *q = NULL; - const char *dir; + const char *dir, *prefixed; int r; assert(u); @@ -3376,7 +3376,10 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co if (!dir) return -EINVAL; - r = write_drop_in(dir, u->id, 50, name, data); + prefixed = strjoina("# This is a drop-in unit file extension, created via \"systemctl set-property\" or an equivalent operation. Do not edit.\n", + data); + + r = write_drop_in(dir, u->id, 50, name, prefixed); if (r < 0) return r; -- cgit v1.2.1 From 815b09d39b74a9ece31b7d7ef45f8f00784b8d8b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 8 Apr 2016 18:13:02 +0200 Subject: core: optimize unit_write_drop_in a bit There's no point in first determining the drop-in file name path, then forgetting it again, and then determining it again. Instead, just generated it once, and then write to ti directly. --- src/core/unit.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'src/core') diff --git a/src/core/unit.c b/src/core/unit.c index fb4f3ddff6..08f3288776 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -3379,17 +3379,19 @@ int unit_write_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name, co prefixed = strjoina("# This is a drop-in unit file extension, created via \"systemctl set-property\" or an equivalent operation. Do not edit.\n", data); - r = write_drop_in(dir, u->id, 50, name, prefixed); + r = drop_in_file(dir, u->id, 50, name, &p, &q); if (r < 0) return r; - r = drop_in_file(dir, u->id, 50, name, &p, &q); + (void) mkdir_p(p, 0755); + r = write_string_file_atomic_label(q, prefixed); if (r < 0) return r; - r = strv_extend(&u->dropin_paths, q); + r = strv_push(&u->dropin_paths, q); if (r < 0) return r; + q = NULL; strv_uniq(u->dropin_paths); -- cgit v1.2.1 From 8e20adcaa0cf06a85d36e2fda35fa1d70d5d63c8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 11 Apr 2016 17:57:05 +0200 Subject: core: make sure we generate a nicer error when a linked unit is attempted to be enabled We don't allow using config symlinks to enable units, but the error message we printed was awful. Fix that, and generate a more readable error. Fixes #3010. --- src/core/dbus-manager.c | 35 ++++++++++++++++++++--------------- 1 file changed, 20 insertions(+), 15 deletions(-) (limited to 'src/core') diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 41f27ec26b..0939a55182 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1607,6 +1607,19 @@ fail: return r; } +static int install_error(sd_bus_error *error, int c) { + assert(c < 0); + + if (c == -ESHUTDOWN) + return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked."); + if (c == -EADDRNOTAVAIL) + return sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED, "Unit file is transient or generated."); + if (c == -ELOOP) + return sd_bus_error_setf(error, BUS_ERROR_UNIT_LINKED, "Refusing to operate on linked unit file."); + + return c; +} + static int method_enable_unit_files_generic( sd_bus_message *message, Manager *m, @@ -1638,12 +1651,8 @@ static int method_enable_unit_files_generic( return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ r = call(m->unit_file_scope, runtime, NULL, l, force, &changes, &n_changes); - if (r == -ESHUTDOWN) - return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked."); - if (r == -EADDRNOTAVAIL) - return sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED, "Unit file is transient or generated."); if (r < 0) - return r; + return install_error(error, r); return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes); } @@ -1709,7 +1718,7 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use r = unit_file_preset(m->unit_file_scope, runtime, NULL, l, mm, force, &changes, &n_changes); if (r < 0) - return r; + return install_error(error, r); return reply_unit_file_changes_and_free(m, message, r, changes, n_changes); } @@ -1745,7 +1754,7 @@ static int method_disable_unit_files_generic( r = call(m->unit_file_scope, runtime, NULL, l, &changes, &n_changes); if (r < 0) - return r; + return install_error(error, r); return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); } @@ -1780,7 +1789,7 @@ static int method_revert_unit_files(sd_bus_message *message, void *userdata, sd_ r = unit_file_revert(m->unit_file_scope, NULL, l, &changes, &n_changes); if (r < 0) - return r; + return install_error(error, r); return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); } @@ -1811,7 +1820,7 @@ static int method_set_default_target(sd_bus_message *message, void *userdata, sd r = unit_file_set_default(m->unit_file_scope, NULL, name, force, &changes, &n_changes); if (r < 0) - return r; + return install_error(error, r); return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); } @@ -1852,7 +1861,7 @@ static int method_preset_all_unit_files(sd_bus_message *message, void *userdata, r = unit_file_preset_all(m->unit_file_scope, runtime, NULL, mm, force, &changes, &n_changes); if (r < 0) { unit_file_changes_free(changes, n_changes); - return r; + return install_error(error, r); } return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); @@ -1890,12 +1899,8 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd return -EINVAL; r = unit_file_add_dependency(m->unit_file_scope, runtime, NULL, l, target, dep, force, &changes, &n_changes); - if (r == -ESHUTDOWN) - return sd_bus_error_setf(error, BUS_ERROR_UNIT_MASKED, "Unit file is masked."); - if (r == -EADDRNOTAVAIL) - return sd_bus_error_setf(error, BUS_ERROR_UNIT_GENERATED, "Unit file is transient or generated."); if (r < 0) - return r; + return install_error(error, r); return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); } -- cgit v1.2.1 From f9ba08fb4fcd64aaf6896d8a5b586180f244fcb7 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Mon, 11 Apr 2016 18:20:02 +0200 Subject: core: keep track of the mtime of the transient unit file we wrote Otherwise "systemctl status" will immediately report that our unit file is out of date. --- src/core/unit.c | 2 ++ 1 file changed, 2 insertions(+) (limited to 'src/core') diff --git a/src/core/unit.c b/src/core/unit.c index 08f3288776..fb88260d23 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -1243,6 +1243,8 @@ int unit_load(Unit *u) { fclose(u->transient_file); u->transient_file = NULL; + + u->dropin_mtime = now(CLOCK_REALTIME); } if (UNIT_VTABLE(u)->load) { -- cgit v1.2.1 From 99ef0330e15db969f7b096cedeecf63a09efbe86 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 12 Apr 2016 13:51:06 +0200 Subject: core: make sure we always free the list of changes --- src/core/dbus-manager.c | 24 ++++++++++++++++++------ 1 file changed, 18 insertions(+), 6 deletions(-) (limited to 'src/core') diff --git a/src/core/dbus-manager.c b/src/core/dbus-manager.c index 0939a55182..2392ed6c16 100644 --- a/src/core/dbus-manager.c +++ b/src/core/dbus-manager.c @@ -1651,8 +1651,10 @@ static int method_enable_unit_files_generic( return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ r = call(m->unit_file_scope, runtime, NULL, l, force, &changes, &n_changes); - if (r < 0) + if (r < 0) { + unit_file_changes_free(changes, n_changes); return install_error(error, r); + } return reply_unit_file_changes_and_free(m, message, carries_install_info ? r : -1, changes, n_changes); } @@ -1717,8 +1719,10 @@ static int method_preset_unit_files_with_mode(sd_bus_message *message, void *use return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ r = unit_file_preset(m->unit_file_scope, runtime, NULL, l, mm, force, &changes, &n_changes); - if (r < 0) + if (r < 0) { + unit_file_changes_free(changes, n_changes); return install_error(error, r); + } return reply_unit_file_changes_and_free(m, message, r, changes, n_changes); } @@ -1753,8 +1757,10 @@ static int method_disable_unit_files_generic( return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ r = call(m->unit_file_scope, runtime, NULL, l, &changes, &n_changes); - if (r < 0) + if (r < 0) { + unit_file_changes_free(changes, n_changes); return install_error(error, r); + } return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); } @@ -1788,8 +1794,10 @@ static int method_revert_unit_files(sd_bus_message *message, void *userdata, sd_ return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ r = unit_file_revert(m->unit_file_scope, NULL, l, &changes, &n_changes); - if (r < 0) + if (r < 0) { + unit_file_changes_free(changes, n_changes); return install_error(error, r); + } return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); } @@ -1819,8 +1827,10 @@ static int method_set_default_target(sd_bus_message *message, void *userdata, sd return 1; /* No authorization for now, but the async polkit stuff will call us again when it has it */ r = unit_file_set_default(m->unit_file_scope, NULL, name, force, &changes, &n_changes); - if (r < 0) + if (r < 0) { + unit_file_changes_free(changes, n_changes); return install_error(error, r); + } return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); } @@ -1899,8 +1909,10 @@ static int method_add_dependency_unit_files(sd_bus_message *message, void *userd return -EINVAL; r = unit_file_add_dependency(m->unit_file_scope, runtime, NULL, l, target, dep, force, &changes, &n_changes); - if (r < 0) + if (r < 0) { + unit_file_changes_free(changes, n_changes); return install_error(error, r); + } return reply_unit_file_changes_and_free(m, message, -1, changes, n_changes); } -- cgit v1.2.1