diff options
Diffstat (limited to 'src/core')
-rw-r--r-- | src/core/cgroup.c | 5 | ||||
-rw-r--r-- | src/core/dbus-unit.c | 37 | ||||
-rw-r--r-- | src/core/dbus.c | 2 | ||||
-rw-r--r-- | src/core/load-fragment.c | 27 | ||||
-rw-r--r-- | src/core/main.c | 3 | ||||
-rw-r--r-- | src/core/manager.c | 2 | ||||
-rw-r--r-- | src/core/mount.c | 2 | ||||
-rw-r--r-- | src/core/scope.c | 2 | ||||
-rw-r--r-- | src/core/service.c | 2 | ||||
-rw-r--r-- | src/core/socket.c | 2 | ||||
-rw-r--r-- | src/core/swap.c | 2 | ||||
-rw-r--r-- | src/core/unit.c | 91 | ||||
-rw-r--r-- | src/core/unit.h | 7 |
13 files changed, 95 insertions, 89 deletions
diff --git a/src/core/cgroup.c b/src/core/cgroup.c index 6474e08bd2..c26807ba2b 100644 --- a/src/core/cgroup.c +++ b/src/core/cgroup.c @@ -806,12 +806,9 @@ static void unit_queue_siblings(Unit *u) { } int unit_realize_cgroup(Unit *u) { - CGroupContext *c; - assert(u); - c = unit_get_cgroup_context(u); - if (!c) + if (!UNIT_HAS_CGROUP_CONTEXT(u)) return 0; /* So, here's the deal: when realizing the cgroups for this diff --git a/src/core/dbus-unit.c b/src/core/dbus-unit.c index 42bb653cc1..1e6291e762 100644 --- a/src/core/dbus-unit.c +++ b/src/core/dbus-unit.c @@ -965,38 +965,39 @@ static int bus_unit_set_transient_property( return 1; - } else if (streq(name, "Slice") && unit_get_cgroup_context(u)) { + } else if (streq(name, "Slice")) { + Unit *slice; const char *s; + if (!UNIT_HAS_CGROUP_CONTEXT(u)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "The slice property is only available for units with control groups."); + if (u->type == UNIT_SLICE) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Slice may not be set for slice units."); + r = sd_bus_message_read(message, "s", &s); if (r < 0) return r; - if (!unit_name_is_valid(s, UNIT_NAME_PLAIN) || !endswith(s, ".slice")) - return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid slice name %s", s); + if (!unit_name_is_valid(s, UNIT_NAME_PLAIN)) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid unit name '%s'", s); - if (isempty(s)) { - if (mode != UNIT_CHECK) { - unit_ref_unset(&u->slice); - unit_remove_drop_in(u, mode, name); - } - } else { - Unit *slice; + r = manager_load_unit(u->manager, s, NULL, error, &slice); + if (r < 0) + return r; + + if (slice->type != UNIT_SLICE) + return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Unit name '%s' is not a slice", s); - r = manager_load_unit(u->manager, s, NULL, error, &slice); + if (mode != UNIT_CHECK) { + r = unit_set_slice(u, slice); if (r < 0) return r; - if (slice->type != UNIT_SLICE) - return -EINVAL; - - if (mode != UNIT_CHECK) { - unit_ref_set(&u->slice, slice); - unit_write_drop_in_private_format(u, mode, name, "Slice=%s\n", s); - } + unit_write_drop_in_private_format(u, mode, name, "Slice=%s\n", s); } return 1; + } else if (STR_IN_SET(name, "Requires", "RequiresOverridable", "Requisite", "RequisiteOverridable", diff --git a/src/core/dbus.c b/src/core/dbus.c index d091aa5419..7ad16aa42b 100644 --- a/src/core/dbus.c +++ b/src/core/dbus.c @@ -381,7 +381,7 @@ static int bus_unit_cgroup_find(sd_bus *bus, const char *path, const char *inter if (!streq_ptr(interface, unit_dbus_interface_from_type(u->type))) return 0; - if (!unit_get_cgroup_context(u)) + if (!UNIT_HAS_CGROUP_CONTEXT(u)) return 0; *found = u; diff --git a/src/core/load-fragment.c b/src/core/load-fragment.c index b3bf8bdb40..745291c5c6 100644 --- a/src/core/load-fragment.c +++ b/src/core/load-fragment.c @@ -2602,7 +2602,7 @@ int config_parse_unit_slice( void *userdata) { _cleanup_free_ char *k = NULL; - Unit *u = userdata, *slice; + Unit *u = userdata, *slice = NULL; int r; assert(filename); @@ -2611,29 +2611,23 @@ int config_parse_unit_slice( assert(u); r = unit_name_printf(u, rvalue, &k); - if (r < 0) - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); - if (!k) { - k = strdup(rvalue); - if (!k) - return log_oom(); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to resolve unit specifiers on %s. Ignoring.", rvalue); + return 0; } r = manager_load_unit(u->manager, k, NULL, NULL, &slice); if (r < 0) { - log_syntax(unit, LOG_ERR, filename, line, -r, - "Failed to load slice unit %s. Ignoring.", k); + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to load slice unit %s. Ignoring.", k); return 0; } - if (slice->type != UNIT_SLICE) { - log_syntax(unit, LOG_ERR, filename, line, EINVAL, - "Slice unit %s is not a slice. Ignoring.", k); + r = unit_set_slice(u, slice); + if (r < 0) { + log_syntax(unit, LOG_ERR, filename, line, r, "Failed to assign slice %s to unit %s. Ignoring.", slice->id, u->id); return 0; } - unit_ref_set(&u->slice, slice); return 0; } @@ -3603,6 +3597,11 @@ int unit_load_fragment(Unit *u) { assert(u->load_state == UNIT_STUB); assert(u->id); + if (u->transient) { + u->load_state = UNIT_LOADED; + return 0; + } + /* First, try to find the unit under its id. We always look * for unit files in the default directories, to make it easy * to override things by placing things in /etc/systemd/system */ diff --git a/src/core/main.c b/src/core/main.c index 87b97aa883..e232be88c0 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1391,8 +1391,7 @@ int main(int argc, char *argv[]) { /* clear the kernel timestamp, * because we are not PID 1 */ - kernel_timestamp.monotonic = 0ULL; - kernel_timestamp.realtime = 0ULL; + kernel_timestamp = DUAL_TIMESTAMP_NULL; } /* Initialize default unit */ diff --git a/src/core/manager.c b/src/core/manager.c index ecea89c377..ede2a9910d 100644 --- a/src/core/manager.c +++ b/src/core/manager.c @@ -250,8 +250,8 @@ static int manager_dispatch_ask_password_fd(sd_event_source *source, static void manager_close_ask_password(Manager *m) { assert(m); - m->ask_password_inotify_fd = safe_close(m->ask_password_inotify_fd); m->ask_password_event_source = sd_event_source_unref(m->ask_password_event_source); + m->ask_password_inotify_fd = safe_close(m->ask_password_inotify_fd); m->have_ask_password = -EINVAL; } diff --git a/src/core/mount.c b/src/core/mount.c index 7e19e66a51..2b81d17b9c 100644 --- a/src/core/mount.c +++ b/src/core/mount.c @@ -521,7 +521,7 @@ static int mount_add_extras(Mount *m) { if (r < 0) return r; - r = unit_add_default_slice(u, &m->cgroup_context); + r = unit_set_default_slice(u); if (r < 0) return r; diff --git a/src/core/scope.c b/src/core/scope.c index bf89936153..c594ab5294 100644 --- a/src/core/scope.c +++ b/src/core/scope.c @@ -164,7 +164,7 @@ static int scope_load(Unit *u) { if (r < 0) return r; - r = unit_add_default_slice(u, &s->cgroup_context); + r = unit_set_default_slice(u); if (r < 0) return r; diff --git a/src/core/service.c b/src/core/service.c index 097e7c710c..3c4232417d 100644 --- a/src/core/service.c +++ b/src/core/service.c @@ -556,7 +556,7 @@ static int service_add_extras(Service *s) { if (r < 0) return r; - r = unit_add_default_slice(UNIT(s), &s->cgroup_context); + r = unit_set_default_slice(UNIT(s)); if (r < 0) return r; diff --git a/src/core/socket.c b/src/core/socket.c index aa65c5b7a0..1014fad626 100644 --- a/src/core/socket.c +++ b/src/core/socket.c @@ -345,7 +345,7 @@ static int socket_add_extras(Socket *s) { if (r < 0) return r; - r = unit_add_default_slice(u, &s->cgroup_context); + r = unit_set_default_slice(u); if (r < 0) return r; } diff --git a/src/core/swap.c b/src/core/swap.c index 349fd6f7b9..4f3ddc9f04 100644 --- a/src/core/swap.c +++ b/src/core/swap.c @@ -326,7 +326,7 @@ static int swap_load(Unit *u) { if (r < 0) return r; - r = unit_add_default_slice(u, &s->cgroup_context); + r = unit_set_default_slice(u); if (r < 0) return r; diff --git a/src/core/unit.c b/src/core/unit.c index 43a5ca1064..5f602bdf5f 100644 --- a/src/core/unit.c +++ b/src/core/unit.c @@ -405,17 +405,17 @@ static void unit_remove_transient(Unit *u) { return; if (u->fragment_path) - unlink(u->fragment_path); + (void) unlink(u->fragment_path); STRV_FOREACH(i, u->dropin_paths) { _cleanup_free_ char *p = NULL; int r; - unlink(*i); + (void) unlink(*i); r = path_get_parent(*i, &p); if (r >= 0) - rmdir(p); + (void) rmdir(p); } } @@ -1122,7 +1122,7 @@ static int unit_add_target_dependencies(Unit *u) { static int unit_add_slice_dependencies(Unit *u) { assert(u); - if (!unit_get_cgroup_context(u)) + if (!UNIT_HAS_CGROUP_CONTEXT(u)) return 0; if (UNIT_ISSET(u->slice)) @@ -2424,14 +2424,42 @@ char *unit_default_cgroup_path(Unit *u) { return strjoin(u->manager->cgroup_root, "/", escaped, NULL); } -int unit_add_default_slice(Unit *u, CGroupContext *c) { +int unit_set_slice(Unit *u, Unit *slice) { + assert(u); + assert(slice); + + /* Sets the unit slice if it has not been set before. Is extra + * careful, to only allow this for units that actually have a + * cgroup context. Also, we don't allow to set this for slices + * (since the parent slice is derived from the name). Make + * sure the unit we set is actually a slice. */ + + if (!UNIT_HAS_CGROUP_CONTEXT(u)) + return -EOPNOTSUPP; + + if (u->type == UNIT_SLICE) + return -EINVAL; + + if (slice->type != UNIT_SLICE) + return -EINVAL; + + if (UNIT_DEREF(u->slice) == slice) + return 0; + + if (UNIT_ISSET(u->slice)) + return -EBUSY; + + unit_ref_set(&u->slice, slice); + return 1; +} + +int unit_set_default_slice(Unit *u) { _cleanup_free_ char *b = NULL; const char *slice_name; Unit *slice; int r; assert(u); - assert(c); if (UNIT_ISSET(u->slice)) return 0; @@ -2471,8 +2499,7 @@ int unit_add_default_slice(Unit *u, CGroupContext *c) { if (r < 0) return r; - unit_ref_set(&u->slice, slice); - return 0; + return unit_set_slice(u, slice); } const char *unit_slice_name(Unit *u) { @@ -3108,17 +3135,17 @@ int unit_kill_common( int r = 0; - if (who == KILL_MAIN && main_pid <= 0) { + if (who == KILL_MAIN) { if (main_pid < 0) return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no main processes", unit_type_to_string(u->type)); - else + else if (main_pid == 0) return sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No main process to kill"); } - if (who == KILL_CONTROL && control_pid <= 0) { + if (who == KILL_CONTROL) { if (control_pid < 0) return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_PROCESS, "%s units have no control processes", unit_type_to_string(u->type)); - else + else if (control_pid == 0) return sd_bus_error_set_const(error, BUS_ERROR_NO_SUCH_PROCESS, "No control process to kill"); } @@ -3317,6 +3344,8 @@ 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) { int r; @@ -3324,9 +3353,9 @@ static int unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode, bool transient, r = user_config_home(dir); else r = user_runtime_dir(dir); - if (r == 0) return -ENOENT; + return r; } @@ -3340,8 +3369,7 @@ static int unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode, bool transient, return 0; } -static int unit_drop_in_file(Unit *u, - UnitSetPropertiesMode mode, const char *name, char **p, char **q) { +static int unit_drop_in_file(Unit *u, UnitSetPropertiesMode mode, const char *name, char **p, char **q) { _cleanup_free_ char *dir = NULL; int r; @@ -3475,40 +3503,17 @@ int unit_remove_drop_in(Unit *u, UnitSetPropertiesMode mode, const char *name) { } int unit_make_transient(Unit *u) { - int r; - assert(u); + if (!UNIT_VTABLE(u)->can_transient) + return -EOPNOTSUPP; + u->load_state = UNIT_STUB; u->load_error = 0; u->transient = true; + u->fragment_path = mfree(u->fragment_path); - free(u->fragment_path); - u->fragment_path = NULL; - - if (u->manager->running_as == MANAGER_USER) { - _cleanup_free_ char *c = NULL; - - r = user_runtime_dir(&c); - if (r < 0) - return r; - if (r == 0) - return -ENOENT; - - u->fragment_path = strjoin(c, "/", u->id, NULL); - if (!u->fragment_path) - return -ENOMEM; - - mkdir_p(c, 0755); - } else { - u->fragment_path = strappend("/run/systemd/system/", u->id); - if (!u->fragment_path) - return -ENOMEM; - - mkdir_p("/run/systemd/system", 0755); - } - - return write_string_file_atomic_label(u->fragment_path, "# Transient stub"); + return 0; } int unit_kill_context( diff --git a/src/core/unit.h b/src/core/unit.h index f53b7f6da1..bc26653247 100644 --- a/src/core/unit.h +++ b/src/core/unit.h @@ -439,6 +439,10 @@ extern const UnitVTable * const unit_vtable[_UNIT_TYPE_MAX]; /* For casting the various unit types into a unit */ #define UNIT(u) (&(u)->meta) +#define UNIT_HAS_EXEC_CONTEXT(u) (UNIT_VTABLE(u)->exec_context_offset > 0) +#define UNIT_HAS_CGROUP_CONTEXT(u) (UNIT_VTABLE(u)->cgroup_context_offset > 0) +#define UNIT_HAS_KILL_CONTEXT(u) (UNIT_VTABLE(u)->kill_context_offset > 0) + #define UNIT_TRIGGER(u) ((Unit*) set_first((u)->dependencies[UNIT_TRIGGERS])) DEFINE_CAST(SERVICE, Service); @@ -490,7 +494,8 @@ int unit_load_fragment_and_dropin(Unit *u); int unit_load_fragment_and_dropin_optional(Unit *u); int unit_load(Unit *unit); -int unit_add_default_slice(Unit *u, CGroupContext *c); +int unit_set_slice(Unit *u, Unit *slice); +int unit_set_default_slice(Unit *u); const char *unit_description(Unit *u) _pure_; |