From: Mike Yuan Date: Fri, 12 Jan 2024 13:30:49 +0000 (+0800) Subject: logind-session: use Requires= for user{,-runtime-dir}@.service X-Git-Tag: v256-rc1~844^2~2 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=52bcc872b5f97a14a9b4e4e383f45bb3066e1643;p=thirdparty%2Fsystemd.git logind-session: use Requires= for user{,-runtime-dir}@.service Since we do require these basic user services, let's make the dependency stronger. Note that logind should enqueue start jobs for these already in user_start(), so mostly just paranoia. --- diff --git a/src/login/logind-dbus.c b/src/login/logind-dbus.c index 2f57cadc6d8..b87edb15dce 100644 --- a/src/login/logind-dbus.c +++ b/src/login/logind-dbus.c @@ -4247,12 +4247,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 *extra_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; @@ -4260,13 +4260,13 @@ 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) return r; - r = sd_bus_message_append(m, "ss", strempty(scope), "fail"); + r = sd_bus_message_append(m, "ss", scope, "fail"); if (r < 0) return r; @@ -4286,13 +4286,17 @@ 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; + + r = sd_bus_message_append(m, "(sv)", "After", "as", 1, *i); if (r < 0) return r; } - STRV_FOREACH(i, after) { + STRV_FOREACH(i, extra_after) { r = sd_bus_message_append(m, "(sv)", "After", "as", 1, *i); if (r < 0) return r; @@ -4344,7 +4348,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 c9d59231d4c..61ce035a482 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 *extra_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 cc6e84a7c7d..787855a7b59 100644 --- a/src/login/logind-session.c +++ b/src/login/logind-session.c @@ -718,6 +718,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); @@ -726,59 +728,45 @@ 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_unit, - SESSION_CLASS_WANTS_SERVICE_MANAGER(s->class) ? s->user->service_manager_unit : 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_unit, - SESSION_CLASS_IS_EARLY(s->class) ? STRV_IGNORE : "systemd-user-sessions.service", - s->user->service_manager_unit); - 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_unit, + SESSION_CLASS_WANTS_SERVICE_MANAGER(s->class) ? s->user->service_manager_unit : NULL), + /* We usually want to order session scopes after systemd-user-sessions.service + * since the 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. */ + STRV_MAKE_CONST("systemd-logind.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; }