diff --git a/man/systemd-system.conf.xml b/man/systemd-system.conf.xml index 075666ac6b..0811e1909e 100644 --- a/man/systemd-system.conf.xml +++ b/man/systemd-system.conf.xml @@ -31,7 +31,9 @@ /etc/systemd/system.conf.d/*.conf, /run/systemd/system.conf.d/*.conf, /usr/lib/systemd/system.conf.d/*.conf - /etc/systemd/user.conf, + + ~/.config/systemd/user.conf, + /etc/systemd/user.conf, /etc/systemd/user.conf.d/*.conf, /run/systemd/user.conf.d/*.conf, /usr/lib/systemd/user.conf.d/*.conf @@ -40,16 +42,16 @@ Description - When run as a system instance, systemd interprets the - configuration file system.conf and the files - in system.conf.d directories; when run as a - user instance, systemd interprets the configuration file - user.conf and the files in - user.conf.d directories. These configuration - files contain a few settings controlling basic manager - operations. See - systemd.syntax7 - for a general description of the syntax. + When run as a system instance, systemd interprets the configuration file + system.conf and the files in system.conf.d directories; when + run as a user instance, it interprets the configuration file user.conf (either in + the home directory of the user, or if not found, under /etc/systemd/) and the files + in user.conf.d directories. These configuration files contain a few settings + controlling basic manager operations. + + See + systemd.syntax7 for a + general description of the syntax. diff --git a/src/core/main.c b/src/core/main.c index f29449d691..2237925209 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -163,6 +163,36 @@ static char **saved_env = NULL; static int parse_configuration(const struct rlimit *saved_rlimit_nofile, const struct rlimit *saved_rlimit_memlock); +static int manager_find_user_config_paths(char ***ret_files, char ***ret_dirs) { + _cleanup_free_ char *base = NULL; + _cleanup_strv_free_ char **files = NULL, **dirs = NULL; + int r; + + r = xdg_user_config_dir(&base, "/systemd"); + if (r < 0) + return r; + + r = strv_extendf(&files, "%s/user.conf", base); + if (r < 0) + return r; + + r = strv_extend(&files, PKGSYSCONFDIR "/user.conf"); + if (r < 0) + return r; + + r = strv_consume(&dirs, TAKE_PTR(base)); + if (r < 0) + return r; + + r = strv_extend_strv(&dirs, CONF_PATHS_STRV("systemd"), false); + if (r < 0) + return r; + + *ret_files = TAKE_PTR(files); + *ret_dirs = TAKE_PTR(dirs); + return 0; +} + _noreturn_ static void freeze_or_exit_or_reboot(void) { /* If we are running in a container, let's prefer exiting, after all we can propagate an exit code to @@ -668,26 +698,34 @@ static int parse_config_file(void) { {} }; - const char *fn, *conf_dirs_nulstr; + _cleanup_strv_free_ char **_free_files = NULL, **_free_dirs = NULL; - fn = arg_system ? - PKGSYSCONFDIR "/system.conf" : - PKGSYSCONFDIR "/user.conf"; + const char *const *files, *const *dirs, *suffix; + int r; - conf_dirs_nulstr = arg_system ? - CONF_PATHS_NULSTR("systemd/system.conf.d") : - CONF_PATHS_NULSTR("systemd/user.conf.d"); + if (arg_system) { + files = STRV_MAKE_CONST(PKGSYSCONFDIR "/system.conf"); + dirs = (const char* const*) CONF_PATHS_STRV("systemd"); + suffix = "system.conf.d"; + } else { + r = manager_find_user_config_paths(&_free_files, &_free_dirs); + if (r < 0) + return log_error_errno(r, "Failed to determine config file paths: %m"); + files = (const char* const*) _free_files; + dirs = (const char* const*) _free_dirs; + suffix = "user.conf.d"; + } - (void) config_parse_many_nulstr( - fn, conf_dirs_nulstr, + (void) config_parse_many( + files, dirs, suffix, "Manager\0", config_item_table_lookup, items, CONFIG_PARSE_WARN, NULL, NULL); - /* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we used USEC_INFINITY - * like everywhere else. */ + /* Traditionally "0" was used to turn off the default unit timeouts. Fix this up so that we use + * USEC_INFINITY like everywhere else. */ if (arg_default_timeout_start_usec <= 0) arg_default_timeout_start_usec = USEC_INFINITY; if (arg_default_timeout_stop_usec <= 0)