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;
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;
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;
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) {
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);
}
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);
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;
}