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)