]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
logind-session: use Requires= for user{,-runtime-dir}@.service
authorMike Yuan <me@yhndnzj.com>
Fri, 12 Jan 2024 13:30:49 +0000 (21:30 +0800)
committerMike Yuan <me@yhndnzj.com>
Thu, 15 Feb 2024 11:23:52 +0000 (19:23 +0800)
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.

src/login/logind-dbus.c
src/login/logind-dbus.h
src/login/logind-session.c

index 2f57cadc6d8b8978e3572a25914a88d55cfee3fe..b87edb15dce971edb7b5281573511f96f86d0841 100644 (file)
@@ -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) {
index c9d59231d4cc1ba8895d02b96f015cf4519d3a91..61ce035a4822a3328db080250c495b061c8ad913 100644 (file)
@@ -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);
index cc6e84a7c7dda48c92e2082ac480337c19b2f608..787855a7b596787b45e939cfca53f8d51a96a03d 100644 (file)
@@ -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;
 }