conf: adopt the systemd semantics for per-service directories

Aaron Andersen points out in the #492 discussion that the *Directory
settings carry more contract than create-and-chown: per-directory
modes, specific ownership rules, and cleanup toggles.  Without them
config-dir was chowned to the service user, which systemd never does,
an existing directory with drifted ownership was left wrong, and the
runtime directory could not survive a restart.

Now matching systemd.exec(5), and where the man page is vague, the
code in setup_exec_directory():

  - each directory takes a matching -mode key, octal with the leading
    zero, default 0755.  The mode of the named directory is locked
    down again on every start, also when it already exists
  - config-dir is created but never chowned
  - the contents of an existing directory are left alone as long as
    the owner is right; on drift everything under it is chowned back
  - runtime-dir-preserve = no | restart | yes maps
    RuntimeDirectoryPreserve=.  A service still qualified to run when
    the runtime directory would be removed is restarting, not
    stopping, which is what svc_enabled() answers

The dir mechanics move to mksubsysd(), taking resolved ids, with
mksubsys() reduced to a name-resolving wrapper for the dbus plugin.
The child resolves uid/gid once for both directory setup and
privilege drop.

The symlink form, RuntimeDirectory=foo:bar, is not adopted.

Signed-off-by: Joachim Wiberg <troglobit@gmail.com>
This commit is contained in:
Joachim Wiberg committed 2026-07-30 15:23:38 +02:00
1 parent f0d7257374
commit 6b03a1ec8f
8 files changed
+191 -44

No files matched your search

+6
View File
@@ -201,11 +201,17 @@ typedef struct svc {
/* Directories set up for the service, block format only, the
* name is resolved under a fixed base, e.g. /run/NAME */
#define NUM_SVCDIRS 5
char runtime_dir[MAX_ARG_LEN];
char state_dir[MAX_ARG_LEN];
char cache_dir[MAX_ARG_LEN];
char logs_dir[MAX_ARG_LEN];
char config_dir[MAX_ARG_LEN];
mode_t dir_mode[NUM_SVCDIRS];
#define SVC_DIR_PRESERVE_NO 0 /* remove runtime-dir on stop */
#define SVC_DIR_PRESERVE_RESTART 1 /* keep it across restarts */
#define SVC_DIR_PRESERVE_YES 2 /* never remove it */
char dir_preserve;
/* Command, arguments and service description */
char cmd[MAX_CMD_LEN];