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