diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 99b9da6ba1080..bab340d4d11be 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -4180,12 +4180,12 @@ int manager_start_scope( const PidRef *pidref, const char *slice, const char *description, - char **wants, - char **after, + const char* const *requires, + const char* const *after, const char *requires_mounts_for, sd_bus_message *more_properties, sd_bus_error *error, - char **job) { + char **ret_job) { _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL, *reply = NULL; int r; @@ -4193,7 +4193,7 @@ int manager_start_scope( assert(manager); assert(scope); assert(pidref_is_set(pidref)); - assert(job); + assert(ret_job); r = bus_message_new_method_call(manager->bus, &m, bus_systemd_mgr, "StartTransientUnit"); if (r < 0) @@ -4219,8 +4219,8 @@ int manager_start_scope( return r; } - STRV_FOREACH(i, wants) { - r = sd_bus_message_append(m, "(sv)", "Wants", "as", 1, *i); + STRV_FOREACH(i, requires) { + r = sd_bus_message_append(m, "(sv)", "Requires", "as", 1, *i); if (r < 0) return r; } @@ -4277,7 +4277,7 @@ int manager_start_scope( if (r < 0) return r; - return strdup_job(reply, job); + return strdup_job(reply, ret_job); } int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job) { diff --git a/src/login/logind-dbus.h b/src/login/logind-dbus.h index c9d59231d4cc1..8d8385c504169 100644 --- a/src/login/logind-dbus.h +++ b/src/login/logind-dbus.h @@ -24,7 +24,18 @@ int match_reloading(sd_bus_message *message, void *userdata, sd_bus_error *error int manager_send_changed(Manager *manager, const char *property, ...) _sentinel_; -int manager_start_scope(Manager *manager, const char *scope, const PidRef *pidref, const char *slice, const char *description, char **wants, char **after, const char *requires_mounts_for, sd_bus_message *more_properties, sd_bus_error *error, char **job); +int manager_start_scope( + Manager *manager, + const char *scope, + const PidRef *pidref, + const char *slice, + const char *description, + const char* const *requires, + const char* const *after, + const char *requires_mounts_for, + sd_bus_message *more_properties, + sd_bus_error *error, + char **ret_job); int manager_start_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job); int manager_stop_unit(Manager *manager, const char *unit, const char *job_mode, sd_bus_error *error, char **job); int manager_abandon_scope(Manager *manager, const char *scope, sd_bus_error *error); diff --git a/src/login/logind-session.c b/src/login/logind-session.c index 69dc52ad66ce0..c3f58805c27ca 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -717,6 +717,8 @@ int session_activate(Session *s) { } static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_error *error) { + _cleanup_free_ char *scope = NULL; + const char *description; int r; assert(s); @@ -725,59 +727,46 @@ static int session_start_scope(Session *s, sd_bus_message *properties, sd_bus_er if (!SESSION_CLASS_WANTS_SCOPE(s->class)) return 0; - if (!s->scope) { - _cleanup_strv_free_ char **wants = NULL, **after = NULL; - _cleanup_free_ char *scope = NULL; - const char *description; - - s->scope_job = mfree(s->scope_job); - - scope = strjoin("session-", s->id, ".scope"); - if (!scope) - return log_oom(); - - description = strjoina("Session ", s->id, " of User ", s->user->user_record->user_name); - - /* These two have StopWhenUnneeded= set, hence add a dep towards them */ - wants = strv_new(s->user->runtime_dir_service, - SESSION_CLASS_WANTS_SERVICE_MANAGER(s->class) ? s->user->service : STRV_IGNORE); - if (!wants) - return log_oom(); - - /* We usually want to order session scopes after systemd-user-sessions.service since the - * latter unit is used as login session barrier for unprivileged users. However the barrier - * doesn't apply for root as sysadmin should always be able to log in (and without waiting - * for any timeout to expire) in case something goes wrong during the boot process. Since - * ordering after systemd-user-sessions.service and the user instance is optional we make use - * of STRV_IGNORE with strv_new() to skip these order constraints when needed. */ - after = strv_new("systemd-logind.service", - s->user->runtime_dir_service, - SESSION_CLASS_IS_EARLY(s->class) ? STRV_IGNORE : "systemd-user-sessions.service", - s->user->service); - if (!after) - return log_oom(); - - r = manager_start_scope( - s->manager, - scope, - &s->leader, - s->user->slice, - description, - wants, - after, - user_record_home_directory(s->user->user_record), - properties, - error, - &s->scope_job); - if (r < 0) - return log_error_errno(r, "Failed to start session scope %s: %s", - scope, bus_error_message(error, r)); + if (s->scope) + goto finish; - s->scope = TAKE_PTR(scope); - } + s->scope_job = mfree(s->scope_job); - (void) hashmap_put(s->manager->session_units, s->scope, s); + scope = strjoin("session-", s->id, ".scope"); + if (!scope) + return log_oom(); + + description = strjoina("Session ", s->id, " of User ", s->user->user_record->user_name); + + r = manager_start_scope( + s->manager, + scope, + &s->leader, + s->user->slice, + description, + /* These should have been pulled in explicitly in user_start(). Just to be sure. */ + STRV_MAKE_CONST(s->user->runtime_dir_service, + SESSION_CLASS_WANTS_SERVICE_MANAGER(s->class) ? s->user->service : NULL), + /* We usually want to order session scopes after systemd-user-sessions.service since the + * latter unit is used as login session barrier for unprivileged users. However the barrier + * doesn't apply for root as sysadmin should always be able to log in (and without waiting + * for any timeout to expire) in case something goes wrong during the boot process. Since + * ordering after systemd-user-sessions.service and the user instance is optional we make use + * of STRV_IGNORE with strv_new() to skip these order constraints when needed. */ + STRV_MAKE_CONST("systemd-logind.service", s->user->service, + SESSION_CLASS_IS_EARLY(s->class) ? NULL : "systemd-user-sessions.service"), + user_record_home_directory(s->user->user_record), + properties, + error, + &s->scope_job); + if (r < 0) + return log_error_errno(r, "Failed to start session scope %s: %s", + scope, bus_error_message(error, r)); + s->scope = TAKE_PTR(scope); + +finish: + (void) hashmap_put(s->manager->session_units, s->scope, s); return 0; }