We would not consider symlinks in /etc/systemd/user/*.{wants,requires}/
towards the user unit being "enabled", because the symlinks were not
located in "config" paths. But this is confusing to users, since those units
are clearly enabled and will be started. So let's muddle the definition of
enablement a bit to include the paths only accessible to root when looking for
enabled user units.
Fixes #4432.
}
static int find_symlinks_in_scope(
}
static int find_symlinks_in_scope(
const LookupPaths *paths,
UnitFileInstallInfo *i,
bool match_name,
const LookupPaths *paths,
UnitFileInstallInfo *i,
bool match_name,
+ /* look for globally enablement of user units */
+ if (scope == UNIT_FILE_USER && path_is_user_config_dir(*p)) {
+ *state = UNIT_FILE_ENABLED;
+ return 1;
+ }
+
r = path_is_runtime(paths, *p, false);
if (r < 0)
return r;
r = path_is_runtime(paths, *p, false);
if (r < 0)
return r;
/* Check if any of the Alias= symlinks have been created.
* We ignore other aliases, and only check those that would
* be created by systemctl enable for this unit. */
/* Check if any of the Alias= symlinks have been created.
* We ignore other aliases, and only check those that would
* be created by systemctl enable for this unit. */
- r = find_symlinks_in_scope(paths, i, true, &state);
+ r = find_symlinks_in_scope(scope, paths, i, true, &state);
if (r < 0)
return r;
if (r > 0)
if (r < 0)
return r;
if (r > 0)
/* Check if the file is known under other names. If it is,
* it might be in use. Report that as UNIT_FILE_INDIRECT. */
/* Check if the file is known under other names. If it is,
* it might be in use. Report that as UNIT_FILE_INDIRECT. */
- r = find_symlinks_in_scope(paths, i, false, &state);
+ r = find_symlinks_in_scope(scope, paths, i, false, &state);
if (r < 0)
return r;
if (r > 0)
if (r < 0)
return r;
if (r > 0)
+static const char* const user_data_unit_paths[] = {
+ "/usr/local/lib/systemd/user",
+ "/usr/local/share/systemd/user",
+ USER_DATA_UNIT_PATH,
+ "/usr/lib/systemd/user",
+ "/usr/share/systemd/user",
+ NULL
+};
+
+static const char* const user_config_unit_paths[] = {
+ USER_CONFIG_UNIT_PATH,
+ "/etc/systemd/user",
+ NULL
+};
+
static char** user_dirs(
const char *persistent_config,
const char *runtime_config,
static char** user_dirs(
const char *persistent_config,
const char *runtime_config,
const char *persistent_control,
const char *runtime_control) {
const char *persistent_control,
const char *runtime_control) {
- const char * const config_unit_paths[] = {
- USER_CONFIG_UNIT_PATH,
- "/etc/systemd/user",
- NULL
- };
-
- const char * const data_unit_paths[] = {
- "/usr/local/lib/systemd/user",
- "/usr/local/share/systemd/user",
- USER_DATA_UNIT_PATH,
- "/usr/lib/systemd/user",
- "/usr/share/systemd/user",
- NULL
- };
-
_cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
_cleanup_free_ char *data_home = NULL;
_cleanup_strv_free_ char **res = NULL;
_cleanup_strv_free_ char **config_dirs = NULL, **data_dirs = NULL;
_cleanup_free_ char *data_home = NULL;
_cleanup_strv_free_ char **res = NULL;
if (strv_extend(&res, persistent_config) < 0)
return NULL;
if (strv_extend(&res, persistent_config) < 0)
return NULL;
- if (strv_extend_strv(&res, (char**) config_unit_paths, false) < 0)
+ if (strv_extend_strv(&res, (char**) user_config_unit_paths, false) < 0)
return NULL;
if (strv_extend(&res, runtime_config) < 0)
return NULL;
if (strv_extend(&res, runtime_config) < 0)
if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0)
return NULL;
if (strv_extend_strv_concat(&res, data_dirs, "/systemd/user") < 0)
return NULL;
- if (strv_extend_strv(&res, (char**) data_unit_paths, false) < 0)
+ if (strv_extend_strv(&res, (char**) user_data_unit_paths, false) < 0)
return NULL;
if (strv_extend(&res, generator_late) < 0)
return NULL;
if (strv_extend(&res, generator_late) < 0)
+bool path_is_user_data_dir(const char *path) {
+ assert(path);
+
+ return strv_contains((char**) user_data_unit_paths, path);
+}
+
+bool path_is_user_config_dir(const char *path) {
+ assert(path);
+
+ return strv_contains((char**) user_config_unit_paths, path);
+}
+
static int acquire_generator_dirs(
UnitFileScope scope,
const char *tempdir,
static int acquire_generator_dirs(
UnitFileScope scope,
const char *tempdir,
};
int lookup_paths_init(LookupPaths *p, UnitFileScope scope, LookupPathsFlags flags, const char *root_dir);
};
int lookup_paths_init(LookupPaths *p, UnitFileScope scope, LookupPathsFlags flags, const char *root_dir);
+bool path_is_user_data_dir(const char *path);
+bool path_is_user_config_dir(const char *path);
int lookup_paths_reduce(LookupPaths *p);
int lookup_paths_reduce(LookupPaths *p);