diff --git a/NEWS b/NEWS index 81b6380cedf..915d61abe30 100644 --- a/NEWS +++ b/NEWS @@ -2,6 +2,15 @@ systemd System and Service Manager CHANGES WITH 257 in spe: + Incompatible changes: + + * The --purge switch of systemd-tmpfiles (which was added in v256) has + been reworked: it will now only apply to tmpfiles.d/ lines marked + with the new "$" flag. This is an incompatible change, and means any + tmpfiles.d/ files which shall be used together with --purge need to + be updated accordingly. This change has been made to make it harder + to accidentally delete too many files when using --purge incorrectly. + Announcements of Future Feature Removals and Incompatible Changes: * Support for automatic flushing of the nscd user/group database caches diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml index f3108b53d9c..b7b4d0dca68 100644 --- a/man/systemd-tmpfiles.xml +++ b/man/systemd-tmpfiles.xml @@ -152,10 +152,11 @@ - If this option is passed, all files and directories marked for - creation by the tmpfiles.d/ files specified on the command - line will be deleted. Specifically, this acts on all files and directories - marked with f, F, d, D, + If this option is passed, all files and directories declared for + creation and marked with the $ character by the + tmpfiles.d/ files specified on the command line will be + deleted. Specifically, this acts on all files and directories marked with + f, F, d, D, v, q, Q, p, L, c, b, C, w, e. If this switch is used at least one diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index 15027def605..a721c1e66d4 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -539,6 +539,10 @@ w- /proc/sys/vm/swappiness - - - - 10 service, the line is silently skipped. If ^ and ~ are combined Base64 decoding is applied to the credential contents. + If the dollar sign ($) is used, the file becomes subject to removal when + systemd-tmpfiles is invoked with the switch. Lines without + this character are unaffected by that switch. + Note that for all line types that result in creation of any kind of file node (i.e. f, d/D/v/q/Q, diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 59b48492ab7..16f831bc262 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -170,6 +170,8 @@ typedef struct Item { bool try_replace:1; + bool purge:1; + OperationMask done; } Item; @@ -3046,6 +3048,9 @@ static int purge_item(Context *c, Item *i) { if (!needs_purge(i->type)) return 0; + if (!i->purge) + return 0; + log_debug("Running purge action for entry %c %s", (char) i->type, i->path); if (needs_glob(i->type)) @@ -3602,7 +3607,7 @@ static int parse_line( ItemArray *existing; OrderedHashmap *h; bool append_or_force = false, boot = false, allow_failure = false, try_replace = false, - unbase64 = false, from_cred = false, missing_user_or_group = false; + unbase64 = false, from_cred = false, missing_user_or_group = false, purge = false; int r; assert(fname); @@ -3668,6 +3673,8 @@ static int parse_line( unbase64 = true; else if (action[pos] == '^' && !from_cred) from_cred = true; + else if (action[pos] == '$' && !purge) + purge = true; else { *invalid_config = true; return log_syntax(NULL, LOG_ERR, fname, line, SYNTHETIC_ERRNO(EBADMSG), @@ -3684,6 +3691,7 @@ static int parse_line( i.append_or_force = append_or_force; i.allow_failure = allow_failure; i.try_replace = try_replace; + i.purge = purge; r = specifier_printf(path, PATH_MAX-1, specifier_table, arg_root, NULL, &i.path); if (ERRNO_IS_NOINFO(r)) @@ -3838,6 +3846,12 @@ static int parse_line( "Unknown command type '%c'.", (char) i.type); } + if (i.purge && !needs_purge(i.type)) { + *invalid_config = true; + return log_syntax(NULL, LOG_ERR, fname, line, SYNTHETIC_ERRNO(EBADMSG), + "Purge flag '$' combined with line type '%c' which does not support purging.", (char) i.type); + } + if (!should_include_path(i.path)) return 0; diff --git a/test/units/TEST-22-TMPFILES.18.sh b/test/units/TEST-22-TMPFILES.18.sh index 5d24197c813..c81f6bd0ef5 100755 --- a/test/units/TEST-22-TMPFILES.18.sh +++ b/test/units/TEST-22-TMPFILES.18.sh @@ -9,26 +9,39 @@ set -o pipefail export SYSTEMD_LOG_LEVEL=debug c=' -d /tmp/somedir -f /tmp/somedir/somefile - - - - baz +d$ /tmp/somedir +f$ /tmp/somedir/somefile - - - - baz +f /tmp/someotherfile - - - - qux ' systemd-tmpfiles --create - <<<"$c" test -f /tmp/somedir/somefile grep -q baz /tmp/somedir/somefile +grep -q qux /tmp/someotherfile systemd-tmpfiles --purge --dry-run - <<<"$c" test -f /tmp/somedir/somefile grep -q baz /tmp/somedir/somefile +grep -q qux /tmp/someotherfile systemd-tmpfiles --purge - <<<"$c" test ! -f /tmp/somedir/somefile test ! -d /tmp/somedir/ +grep -q qux /tmp/someotherfile systemd-tmpfiles --create --purge --dry-run - <<<"$c" test ! -f /tmp/somedir/somefile test ! -d /tmp/somedir/ +grep -q qux /tmp/someotherfile systemd-tmpfiles --create --purge - <<<"$c" test -f /tmp/somedir/somefile grep -q baz /tmp/somedir/somefile +grep -q qux /tmp/someotherfile + +systemd-tmpfiles --purge - <<<"$c" +test ! -f /tmp/somedir/somefile +test ! -d /tmp/somedir/ +grep -q qux /tmp/someotherfile + +rm /tmp/someotherfile