return r;
}
- if (MANAGER_IS_SYSTEM(m) && test_run_flags == 0) {
- r = mkdir_label("/run/systemd/units", 0755);
+ if (test_run_flags == 0) {
+ if (MANAGER_IS_SYSTEM(m))
+ r = mkdir_label("/run/systemd/units", 0755);
+ else {
+ _cleanup_free_ char *units_path = NULL;
+ r = xdg_user_runtime_dir(&units_path, "/systemd/units");
+ if (r < 0)
+ return r;
+ r = mkdir_p_label(units_path, 0755);
+ }
+
if (r < 0 && r != -EEXIST)
return r;
}
}
}
+static int unit_get_invocation_path(Unit *u, char **ret) {
+ char *p;
+ int r;
+
+ assert(u);
+ assert(ret);
+
+ if (MANAGER_IS_SYSTEM(u->manager))
+ p = strjoin("/run/systemd/units/invocation:", u->id);
+ else {
+ _cleanup_free_ char *user_path = NULL;
+ r = xdg_user_runtime_dir(&user_path, "/systemd/units/invocation:");
+ if (r < 0)
+ return r;
+ p = strjoin(user_path, u->id);
+ }
+
+ if (!p)
+ return -ENOMEM;
+
+ *ret = p;
+ return 0;
+}
+
static int unit_export_invocation_id(Unit *u) {
- const char *p;
+ _cleanup_free_ char *p = NULL;
int r;
assert(u);
if (sd_id128_is_null(u->invocation_id))
return 0;
- p = strjoina("/run/systemd/units/invocation:", u->id);
+ r = unit_get_invocation_path(u, &p);
+ if (r < 0)
+ return log_unit_debug_errno(u, r, "Failed to get invocation path: %m");
+
r = symlink_atomic(u->invocation_id_string, p);
if (r < 0)
return log_unit_debug_errno(u, r, "Failed to create invocation ID symlink %s: %m", p);
if (!u->id)
return;
- if (!MANAGER_IS_SYSTEM(u->manager))
- return;
-
if (MANAGER_IS_TEST_RUN(u->manager))
return;
(void) unit_export_invocation_id(u);
+ if (!MANAGER_IS_SYSTEM(u->manager))
+ return;
+
c = unit_get_exec_context(u);
if (c) {
(void) unit_export_log_level_max(u, c);
if (!u->id)
return;
- if (!MANAGER_IS_SYSTEM(u->manager))
- return;
-
/* Undoes the effect of unit_export_state() */
if (u->exported_invocation_id) {
- p = strjoina("/run/systemd/units/invocation:", u->id);
- (void) unlink(p);
-
- u->exported_invocation_id = false;
+ _cleanup_free_ char *invocation_path = NULL;
+ int r = unit_get_invocation_path(u, &invocation_path);
+ if (r >= 0) {
+ (void) unlink(invocation_path);
+ u->exported_invocation_id = false;
+ }
}
+ if (!MANAGER_IS_SYSTEM(u->manager))
+ return;
+
if (u->exported_log_level_max) {
p = strjoina("/run/systemd/units/log-level-max:", u->id);
(void) unlink(p);
Server *s,
ClientContext *c) {
- _cleanup_free_ char *value = NULL;
- const char *p;
+ _cleanup_free_ char *p = NULL, *value = NULL;
int r;
assert(s);
assert(c);
- /* Read the invocation ID of a unit off a unit. PID 1 stores it in a per-unit symlink in /run/systemd/units/ */
+ /* Read the invocation ID of a unit off a unit.
+ * PID 1 stores it in a per-unit symlink in /run/systemd/units/
+ * User managers store it in a per-unit symlink under /run/user/<uid>/systemd/units/ */
if (!c->unit)
return 0;
- p = strjoina("/run/systemd/units/invocation:", c->unit);
+ if (c->user_unit) {
+ r = asprintf(&p, "/run/user/" UID_FMT "/systemd/units/invocation:%s", c->owner_uid, c->user_unit);
+ if (r < 0)
+ return r;
+ } else {
+ p = strjoin("/run/systemd/units/invocation:", c->unit);
+ if (!p)
+ return -ENOMEM;
+ }
+
r = readlink_malloc(p, &value);
if (r < 0)
return r;