core: add support for expanding state/cache/log directory root in unit files
authorLennart Poettering <lennart@poettering.net>
Wed, 11 Oct 2017 12:02:36 +0000 (14:02 +0200)
committerLennart Poettering <lennart@poettering.net>
Thu, 26 Oct 2017 15:59:09 +0000 (17:59 +0200)
This augments %t which already resolves to the runtime directory root, and
should be useful for units that want to pass any of these paths in
command line arguments.

Example:

ExecStart=/usr/bin/mydaemon --datadir=%S/mydaemon

Why not expose a specifier resolving directly to the configured
state/runtime/cache/log dir? Three reasons:

1. Specifiers should be independent of configuration of the unit itself,
   and StateDirectory= and friends are unit configuration.  See
   03fc9c723cfc59467a7fccc305f34273f8564b25 and related work.

2. We permit multiple StateDirectory= values per unit, and it hence
   wouldn't be clear which one is passed.

3. We already have %t for the runtime directory root, and we should
   continue with the same scheme.

man/systemd.unit.xml
src/core/unit-printf.c

index 043c4ed..ab7613d 100644 (file)
           </row>
           <row>
       <entry><literal>%t</literal></entry>
-      <entry>Runtime directory</entry>
+      <entry>Runtime directory root</entry>
       <entry>This is either <filename>/run</filename> (for the system manager) or the path <literal>$XDG_RUNTIME_DIR</literal> resolves to (for user managers).</entry>
           </row>
           <row>
+      <entry><literal>%S</literal></entry>
+      <entry>State directory root </entry>
+      <entry>This is either <filename>/var/lib</filename> (for the system manager) or the path <literal>$XDG_CONFIG_HOME</literal> resolves to (for user managers).</entry>
+          </row>
+          <row>
+      <entry><literal>%C</literal></entry>
+      <entry>Cache directory root </entry>
+      <entry>This is either <filename>/var/cache</filename> (for the system manager) or the path <literal>$XDG_CACHE_HOME</literal> resolves to (for user managers).</entry>
+          </row>
+          <row>
+      <entry><literal>%L</literal></entry>
+      <entry>Logs directory root </entry>
+      <entry>This is either <filename>/var/log</filename> (for the system manager) or the path <literal>$XDG_CONFIG_HOME</literal> resolves to with <filename>/log</filename> appended (for user managers).</entry>
+          </row>
+          <row>
       <entry><literal>%u</literal></entry>
       <entry>User name</entry>
       <entry>This is the name of the user running the service manager instance. In case of the system manager this resolves to <literal>root</literal>.</entry>
index 0480ec6..8088d01 100644 (file)
@@ -143,13 +143,13 @@ static int specifier_cgroup_slice(char specifier, void *data, void *userdata, ch
         return 0;
 }
 
-static int specifier_runtime(char specifier, void *data, void *userdata, char **ret) {
+static int specifier_special_directory(char specifier, void *data, void *userdata, char **ret) {
         Unit *u = userdata;
         char *n = NULL;
 
         assert(u);
 
-        n = strdup(u->manager->prefix[EXEC_DIRECTORY_RUNTIME]);
+        n = strdup(u->manager->prefix[PTR_TO_UINT(data)]);
         if (!n)
                 return -ENOMEM;
 
@@ -244,10 +244,15 @@ int unit_full_printf(Unit *u, const char *format, char **ret) {
          * (which are likely not suitable for unescaped inclusion in unit names):
          *
          * %f: the unescaped instance if set, otherwise the id unescaped as path
+         *
          * %c: cgroup path of unit (deprecated)
          * %r: where units in this slice are placed in the cgroup tree (deprecated)
          * %R: the root of this systemd's instance tree (deprecated)
-         * %t: the runtime directory to place sockets in (e.g. "/run" or $XDG_RUNTIME_DIR)
+         *
+         * %t: the runtime directory root (e.g. /run or $XDG_RUNTIME_DIR)
+         * %S: the state directory root (e.g. /var/lib or $XDG_CONFIG_HOME)
+         * %C: the cache directory root (e.g. /var/cache or $XDG_CACHE_HOME)
+         * %L: the log directory root (e.g. /var/log or $XDG_CONFIG_HOME/log)
          *
          * %h: the homedir of the running user
          * %s: the shell of the running user
@@ -271,7 +276,10 @@ int unit_full_printf(Unit *u, const char *format, char **ret) {
                 { 'c', specifier_cgroup,              NULL },
                 { 'r', specifier_cgroup_slice,        NULL },
                 { 'R', specifier_cgroup_root,         NULL },
-                { 't', specifier_runtime,             NULL },
+                { 't', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_RUNTIME) },
+                { 'S', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_STATE) },
+                { 'C', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_CACHE) },
+                { 'L', specifier_special_directory,   UINT_TO_PTR(EXEC_DIRECTORY_LOGS) },
 
                 { 'U', specifier_user_id,             NULL },
                 { 'u', specifier_user_name,           NULL },