Zbigniew Jędrzejewski-Szmek 62fe94
From 718880ba0d557a045e2f969e141cbd59e78c76f4 Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 62fe94
From: Steven Allen <steven@stebalien.com>
Zbigniew Jędrzejewski-Szmek 62fe94
Date: Sun, 28 Sep 2014 14:54:25 -0700
Zbigniew Jędrzejewski-Szmek 62fe94
Subject: [PATCH] add a transient user unit directory
Zbigniew Jędrzejewski-Szmek 62fe94
Zbigniew Jędrzejewski-Szmek 62fe94
This patch adds a transient user unit directory under
Zbigniew Jędrzejewski-Szmek 62fe94
`$XDG_RUNTIME_DIR/systemd/user/` and stores transient user-instance
Zbigniew Jędrzejewski-Szmek 62fe94
units (such as those created by `systemd-run --user`) under there
Zbigniew Jędrzejewski-Szmek 62fe94
instead of putting them in $XDG_CONFIG_HOME/systemd/user/.
Zbigniew Jędrzejewski-Szmek 62fe94
Zbigniew Jędrzejewski-Szmek 62fe94
Fixes https://bugs.freedesktop.org/show_bug.cgi?id=67331
Zbigniew Jędrzejewski-Szmek 62fe94
---
Zbigniew Jędrzejewski-Szmek 62fe94
 src/core/unit.c          |  8 ++++++--
Zbigniew Jędrzejewski-Szmek 62fe94
 src/shared/install.c     | 37 +++++++++++++++++++------------------
Zbigniew Jędrzejewski-Szmek 62fe94
 src/shared/path-lookup.c | 32 ++++++++++++++++++++++++++++++--
Zbigniew Jędrzejewski-Szmek 62fe94
 src/shared/path-lookup.h |  1 +
Zbigniew Jędrzejewski-Szmek 62fe94
 4 files changed, 56 insertions(+), 22 deletions(-)
Zbigniew Jędrzejewski-Szmek 62fe94
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/core/unit.c b/src/core/unit.c
Zbigniew Jędrzejewski-Szmek 62fe94
index 5978e21f56..8a7df01284 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/core/unit.c
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/core/unit.c
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -3080,7 +3080,11 @@ static int unit_drop_in_dir(Unit *u, UnitSetPropertiesMode mode, bool transient,
Zbigniew Jędrzejewski-Szmek 62fe94
         if (u->manager->running_as == SYSTEMD_USER) {
Zbigniew Jędrzejewski-Szmek 62fe94
                 int r;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-                r = user_config_home(dir);
Zbigniew Jędrzejewski-Szmek 62fe94
+                if (mode == UNIT_PERSISTENT && !transient)
Zbigniew Jędrzejewski-Szmek 62fe94
+                        r = user_config_home(dir);
Zbigniew Jędrzejewski-Szmek 62fe94
+                else
Zbigniew Jędrzejewski-Szmek 62fe94
+                        r = user_runtime(dir);
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
                 if (r == 0)
Zbigniew Jędrzejewski-Szmek 62fe94
                         return -ENOENT;
Zbigniew Jędrzejewski-Szmek 62fe94
                 return r;
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -3228,7 +3232,7 @@ int unit_make_transient(Unit *u) {
Zbigniew Jędrzejewski-Szmek 62fe94
         if (u->manager->running_as == SYSTEMD_USER) {
Zbigniew Jędrzejewski-Szmek 62fe94
                 _cleanup_free_ char *c = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-                r = user_config_home(&c);
Zbigniew Jędrzejewski-Szmek 62fe94
+                r = user_runtime(&c);
Zbigniew Jędrzejewski-Szmek 62fe94
                 if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
                         return r;
Zbigniew Jędrzejewski-Szmek 62fe94
                 if (r == 0)
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/shared/install.c b/src/shared/install.c
Zbigniew Jędrzejewski-Szmek 62fe94
index 61e572bdf3..302b5237a6 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/shared/install.c
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/shared/install.c
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -105,10 +105,14 @@ static int get_config_path(UnitFileScope scope, bool runtime, const char *root_d
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         case UNIT_FILE_USER:
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-                if (root_dir || runtime)
Zbigniew Jędrzejewski-Szmek 62fe94
+                if (root_dir)
Zbigniew Jędrzejewski-Szmek 62fe94
                         return -EINVAL;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-                r = user_config_home(&p);
Zbigniew Jędrzejewski-Szmek 62fe94
+                if (runtime)
Zbigniew Jędrzejewski-Szmek 62fe94
+                        r = user_runtime(&p);
Zbigniew Jędrzejewski-Szmek 62fe94
+                else
Zbigniew Jędrzejewski-Szmek 62fe94
+                        r = user_config_home(&p);
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
                 if (r <= 0)
Zbigniew Jędrzejewski-Szmek 62fe94
                         return r < 0 ? r : -ENOENT;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -527,36 +531,33 @@ static int find_symlinks_in_scope(
Zbigniew Jędrzejewski-Szmek 62fe94
                 UnitFileState *state) {
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         int r;
Zbigniew Jędrzejewski-Szmek 62fe94
-        _cleanup_free_ char *path2 = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
+        _cleanup_free_ char *path = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
         bool same_name_link_runtime = false, same_name_link = false;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         assert(scope >= 0);
Zbigniew Jędrzejewski-Szmek 62fe94
         assert(scope < _UNIT_FILE_SCOPE_MAX);
Zbigniew Jędrzejewski-Szmek 62fe94
         assert(name);
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-        if (scope == UNIT_FILE_SYSTEM || scope == UNIT_FILE_GLOBAL) {
Zbigniew Jędrzejewski-Szmek 62fe94
-                _cleanup_free_ char *path = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-                /* First look in runtime config path */
Zbigniew Jędrzejewski-Szmek 62fe94
-                r = get_config_path(scope, true, root_dir, &path);
Zbigniew Jędrzejewski-Szmek 62fe94
-                if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
-                        return r;
Zbigniew Jędrzejewski-Szmek 62fe94
+        /* First look in runtime config path */
Zbigniew Jędrzejewski-Szmek 62fe94
+        r = get_config_path(scope, true, root_dir, &path);
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
+                return r;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-                r = find_symlinks(name, path, &same_name_link_runtime);
Zbigniew Jędrzejewski-Szmek 62fe94
-                if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
-                        return r;
Zbigniew Jędrzejewski-Szmek 62fe94
-                else if (r > 0) {
Zbigniew Jędrzejewski-Szmek 62fe94
-                        *state = UNIT_FILE_ENABLED_RUNTIME;
Zbigniew Jędrzejewski-Szmek 62fe94
-                        return r;
Zbigniew Jędrzejewski-Szmek 62fe94
-                }
Zbigniew Jędrzejewski-Szmek 62fe94
+        r = find_symlinks(name, path, &same_name_link_runtime);
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
+                return r;
Zbigniew Jędrzejewski-Szmek 62fe94
+        else if (r > 0) {
Zbigniew Jędrzejewski-Szmek 62fe94
+                *state = UNIT_FILE_ENABLED_RUNTIME;
Zbigniew Jędrzejewski-Szmek 62fe94
+                return r;
Zbigniew Jędrzejewski-Szmek 62fe94
         }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         /* Then look in the normal config path */
Zbigniew Jędrzejewski-Szmek 62fe94
-        r = get_config_path(scope, false, root_dir, &path2);
Zbigniew Jędrzejewski-Szmek 62fe94
+        r = get_config_path(scope, false, root_dir, &path);
Zbigniew Jędrzejewski-Szmek 62fe94
         if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
                 return r;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
-        r = find_symlinks(name, path2, &same_name_link);
Zbigniew Jędrzejewski-Szmek 62fe94
+        r = find_symlinks(name, path, &same_name_link);
Zbigniew Jędrzejewski-Szmek 62fe94
         if (r < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
                 return r;
Zbigniew Jędrzejewski-Szmek 62fe94
         else if (r > 0) {
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/shared/path-lookup.c b/src/shared/path-lookup.c
Zbigniew Jędrzejewski-Szmek 62fe94
index 40fb0b8b4a..3a6e117d28 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/shared/path-lookup.c
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/shared/path-lookup.c
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -61,6 +61,23 @@ int user_config_home(char **config_home) {
Zbigniew Jędrzejewski-Szmek 62fe94
         return 0;
Zbigniew Jędrzejewski-Szmek 62fe94
 }
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
+int user_runtime(char **user_runtime_path) {
Zbigniew Jędrzejewski-Szmek 62fe94
+        const char *e;
Zbigniew Jędrzejewski-Szmek 62fe94
+        char *r;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        e = getenv("XDG_RUNTIME_DIR");
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (e) {
Zbigniew Jędrzejewski-Szmek 62fe94
+                r = strappend(e, "/systemd/user");
Zbigniew Jędrzejewski-Szmek 62fe94
+                if (!r)
Zbigniew Jędrzejewski-Szmek 62fe94
+                        return -ENOMEM;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+                *user_runtime_path = r;
Zbigniew Jędrzejewski-Szmek 62fe94
+                return 1;
Zbigniew Jędrzejewski-Szmek 62fe94
+        }
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        return 0;
Zbigniew Jędrzejewski-Szmek 62fe94
+}
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
 static char** user_dirs(
Zbigniew Jędrzejewski-Szmek 62fe94
                 const char *generator,
Zbigniew Jędrzejewski-Szmek 62fe94
                 const char *generator_early,
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -69,10 +86,11 @@ static char** user_dirs(
Zbigniew Jędrzejewski-Szmek 62fe94
         const char * const config_unit_paths[] = {
Zbigniew Jędrzejewski-Szmek 62fe94
                 USER_CONFIG_UNIT_PATH,
Zbigniew Jędrzejewski-Szmek 62fe94
                 "/etc/systemd/user",
Zbigniew Jędrzejewski-Szmek 62fe94
-                "/run/systemd/user",
Zbigniew Jędrzejewski-Szmek 62fe94
                 NULL
Zbigniew Jędrzejewski-Szmek 62fe94
         };
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
+        const char * const runtime_unit_path = "/run/systemd/user";
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
         const char * const data_unit_paths[] = {
Zbigniew Jędrzejewski-Szmek 62fe94
                 "/usr/local/lib/systemd/user",
Zbigniew Jędrzejewski-Szmek 62fe94
                 "/usr/local/share/systemd/user",
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -83,7 +101,7 @@ static char** user_dirs(
Zbigniew Jędrzejewski-Szmek 62fe94
         };
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         const char *home, *e;
Zbigniew Jędrzejewski-Szmek 62fe94
-        _cleanup_free_ char *config_home = NULL, *data_home = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
+        _cleanup_free_ char *config_home = NULL, *user_runtime_dir = NULL, *data_home = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
         _cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
         char **r = NULL;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -99,6 +117,9 @@ static char** user_dirs(
Zbigniew Jędrzejewski-Szmek 62fe94
         if (user_config_home(&config_home) < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
                 goto fail;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (user_runtime(&user_runtime_dir) < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
+                goto fail;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
         home = getenv("HOME");
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
         e = getenv("XDG_CONFIG_DIRS");
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -141,6 +162,13 @@ static char** user_dirs(
Zbigniew Jędrzejewski-Szmek 62fe94
                 if (strv_extend(&r, config_home) < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
                         goto fail;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (user_runtime_dir)
Zbigniew Jędrzejewski-Szmek 62fe94
+                if (strv_extend(&r, user_runtime_dir) < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
+                        goto fail;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
+        if (strv_extend(&r, runtime_unit_path) < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
+                goto fail;
Zbigniew Jędrzejewski-Szmek 62fe94
+
Zbigniew Jędrzejewski-Szmek 62fe94
         if (!strv_isempty(config_dirs))
Zbigniew Jędrzejewski-Szmek 62fe94
                 if (strv_extend_strv_concat(&r, config_dirs, "/systemd/user") < 0)
Zbigniew Jędrzejewski-Szmek 62fe94
                         goto fail;
Zbigniew Jędrzejewski-Szmek 62fe94
diff --git a/src/shared/path-lookup.h b/src/shared/path-lookup.h
Zbigniew Jędrzejewski-Szmek 62fe94
index 4bbd47ec39..8da076a30b 100644
Zbigniew Jędrzejewski-Szmek 62fe94
--- a/src/shared/path-lookup.h
Zbigniew Jędrzejewski-Szmek 62fe94
+++ b/src/shared/path-lookup.h
Zbigniew Jędrzejewski-Szmek 62fe94
@@ -39,6 +39,7 @@ typedef enum SystemdRunningAs {
Zbigniew Jędrzejewski-Szmek 62fe94
 } SystemdRunningAs;
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
 int user_config_home(char **config_home);
Zbigniew Jędrzejewski-Szmek 62fe94
+int user_runtime(char **user_runtime_path);
Zbigniew Jędrzejewski-Szmek 62fe94
 
Zbigniew Jędrzejewski-Szmek 62fe94
 int lookup_paths_init(LookupPaths *p,
Zbigniew Jędrzejewski-Szmek 62fe94
                       SystemdRunningAs running_as,