tmpfiles: add %D specifier resolution

systemd-tmpfiles now resolves the %D specifier to /usr/share
(for the system manager) or $XDG_DATA_HOME (for the user manager).

Closes: https://github.com/systemd/systemd/issues/42010
Signed-off-by: Skye Soss <skye@soss.website>
This commit is contained in:
Skye Soss
2026-06-21 18:20:53 +01:00
committed by Luca Boccassi
parent 1a8a470048
commit a4f7c9589e
5 changed files with 18 additions and 5 deletions
+5
View File
@@ -27,6 +27,11 @@
<entry>Operating system build ID</entry>
<entry>The operating system build identifier of the running system, as read from the <varname>BUILD_ID=</varname> field of <filename>/etc/os-release</filename>. If not set, resolves to an empty string. See <citerefentry><refentrytitle>os-release</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more information.</entry>
</row>
<row id='D'>
<entry><literal>%D</literal></entry>
<entry>Shared data directory</entry>
<entry>This is either <filename>/usr/share/</filename> (for the system manager) or the path <literal>$XDG_DATA_HOME</literal> resolves to (for user managers).</entry>
</row>
<row id='H'>
<entry><literal>%H</literal></entry>
<entry>Host name</entry>
+1 -5
View File
@@ -2452,11 +2452,7 @@
<entry>Credentials directory</entry>
<entry>This is the value of the <literal>$CREDENTIALS_DIRECTORY</literal> environment variable if available. See section "Credentials" in <citerefentry><refentrytitle>systemd.exec</refentrytitle><manvolnum>5</manvolnum></citerefentry> for more information.</entry>
</row>
<row>
<entry><literal>%D</literal></entry>
<entry>Shared data directory</entry>
<entry>This is either <filename>/usr/share/</filename> (for the system manager) or the path <literal>$XDG_DATA_HOME</literal> resolves to (for user managers).</entry>
</row>
<xi:include href="standard-specifiers.xml" xpointer="D"/>
<row>
<entry><literal>%E</literal></entry>
<entry>Configuration directory root</entry>
+1
View File
@@ -778,6 +778,7 @@ d /tmp/foo/bar - - - bmA:1h -</programlisting></para>
<entry>System or user cache directory</entry>
<entry>In <option>--user</option> mode, this is the same as <varname>$XDG_CACHE_HOME</varname>, and <filename>/var/cache</filename> otherwise.</entry>
</row>
<xi:include href="standard-specifiers.xml" xpointer="D"/>
<row>
<entry><literal>%g</literal></entry>
<entry>User group</entry>
+4
View File
@@ -205,6 +205,7 @@ typedef enum DirectoryType {
DIRECTORY_STATE,
DIRECTORY_CACHE,
DIRECTORY_LOGS,
DIRECTORY_SHARED,
_DIRECTORY_TYPE_MAX,
} DirectoryType;
@@ -293,6 +294,7 @@ static int specifier_directory(
[DIRECTORY_STATE] = { SD_PATH_SYSTEM_STATE_PRIVATE },
[DIRECTORY_CACHE] = { SD_PATH_SYSTEM_STATE_CACHE },
[DIRECTORY_LOGS] = { SD_PATH_SYSTEM_STATE_LOGS },
[DIRECTORY_SHARED] = { SD_PATH_SYSTEM_SHARED },
};
static const struct table_entry paths_user[] = {
@@ -300,6 +302,7 @@ static int specifier_directory(
[DIRECTORY_STATE] = { SD_PATH_USER_STATE_PRIVATE },
[DIRECTORY_CACHE] = { SD_PATH_USER_STATE_CACHE },
[DIRECTORY_LOGS] = { SD_PATH_USER_STATE_PRIVATE, "log" },
[DIRECTORY_SHARED] = { SD_PATH_USER_SHARED },
};
const struct table_entry *paths;
@@ -3907,6 +3910,7 @@ static int parse_line(
{ 'h', specifier_user_home, NULL },
{ 'C', specifier_directory, UINT_TO_PTR(DIRECTORY_CACHE) },
{ 'D', specifier_directory, UINT_TO_PTR(DIRECTORY_SHARED) },
{ 'L', specifier_directory, UINT_TO_PTR(DIRECTORY_LOGS) },
{ 'S', specifier_directory, UINT_TO_PTR(DIRECTORY_STATE) },
{ 't', specifier_directory, UINT_TO_PTR(DIRECTORY_RUNTIME) },
+7
View File
@@ -160,6 +160,13 @@ def test_valid_specifiers(*, user):
xdg_cache_home if user else '/var/cache',
user=user) # fmt: skip
xdg_data_home = os.getenv('XDG_DATA_HOME')
if xdg_data_home is None and user:
xdg_data_home = os.path.join(home, '.local/share')
test_content('f {} - - - - %D',
xdg_data_home if user else '/usr/share',
user=user) # fmt: skip
test_content('f {} - - - - %L',
os.path.join(xdg_state_home, 'log') if user else '/var/log',
user=user) # fmt: skip