From eaa3adbe699074e3d8099262c395ff468c9bad6e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2024 10:15:02 +0200 Subject: [PATCH 01/10] tmpfiles: sort needs_purge line list in same order as enum defines them --- src/tmpfiles/tmpfiles.c | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 807925f199..1805cfb8a1 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -396,20 +396,20 @@ static int user_config_paths(char*** ret) { static bool needs_purge(ItemType t) { return IN_SET(t, - COPY_FILES, - TRUNCATE_FILE, CREATE_FILE, - WRITE_FILE, - EMPTY_DIRECTORY, + TRUNCATE_FILE, + CREATE_DIRECTORY, + TRUNCATE_DIRECTORY, CREATE_SUBVOLUME, CREATE_SUBVOLUME_INHERIT_QUOTA, CREATE_SUBVOLUME_NEW_QUOTA, + CREATE_FIFO, + CREATE_SYMLINK, CREATE_CHAR_DEVICE, CREATE_BLOCK_DEVICE, - CREATE_SYMLINK, - CREATE_FIFO, - CREATE_DIRECTORY, - TRUNCATE_DIRECTORY); + COPY_FILES, + WRITE_FILE, + EMPTY_DIRECTORY); } static bool needs_glob(ItemType t) { From edeceb80a91e8400e8c22f08a41045a2ba270fe6 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2024 09:54:33 +0200 Subject: [PATCH 02/10] tmpfiles: honour --dry-run when removing directories --- src/tmpfiles/tmpfiles.c | 14 ++++++++++---- 1 file changed, 10 insertions(+), 4 deletions(-) diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 1805cfb8a1..3b3489ee62 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -3024,10 +3024,16 @@ static int remove_recursive( return r; if (remove_instance) { - log_debug("Removing directory \"%s\".", instance); - r = RET_NERRNO(rmdir(instance)); - if (r < 0 && !IN_SET(r, -ENOENT, -ENOTEMPTY)) - return log_error_errno(r, "Failed to remove %s: %m", instance); + log_action("Would remove", "Removing", "%s directory \"%s\".", instance); + if (!arg_dry_run) { + r = RET_NERRNO(rmdir(instance)); + if (r < 0) { + bool fatal = !IN_SET(r, -ENOENT, -ENOTEMPTY); + log_full_errno(fatal ? LOG_ERR : LOG_DEBUG, r, "Failed to remove %s: %m", instance); + if (fatal) + return r; + } + } } return 0; } From 41064a3c97c9a53c97bbe8a1de799a82c4374a2d Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2024 09:55:20 +0200 Subject: [PATCH 03/10] tmpfiles: insist on at least one configuration file being specified on --purge Also, extend the man page explanation substantially, matching more closely what --create says. Fixes: #33349 --- man/systemd-tmpfiles.xml | 26 ++++++++++++++++++++------ src/tmpfiles/tmpfiles.c | 4 ++++ 2 files changed, 24 insertions(+), 6 deletions(-) diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml index 9767aead85..2a494b9c5c 100644 --- a/man/systemd-tmpfiles.xml +++ b/man/systemd-tmpfiles.xml @@ -151,12 +151,26 @@ - If this option is passed, all files and directories created by a - tmpfiles.d/ entry will be deleted. Keep in mind that by default, - /home is created by systemd-tmpfiles - (see /usr/lib/tmpfiles.d/home.conf). Therefore it is recommended - to first run systemd-tmpfiles --dry-run --purge to be certain which files - and directories will be deleted. + + 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, + v, q, Q, p, + L, c, b, C, + w, e. If this switch is used at least one + tmpfiles.d/ file (or - for standard input) must be + specified on the command line or the invocation will be refused, for safety reasons (as otherwise + much of the installed system files might be removed). + + The primary usecase for this option is to automatically remove files and directories that + originally have been created on behalf of an installed packaged at package removal time. + + It is recommended to first run this command in combination with + (see below) to verify which files and directories will be deleted. + + Warning! This is is usually not the command you want! In most cases + is what you are looking for. diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 3b3489ee62..9895e94696 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -4344,6 +4344,10 @@ static int parse_argv(int argc, char *argv[]) { return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "You need to specify at least one of --clean, --create, --remove, or --purge."); + if (FLAGS_SET(arg_operation, OPERATION_PURGE) && optind >= argc) + return log_error_errno(SYNTHETIC_ERRNO(EINVAL), + "Refusing --purge without specification of a configuration file."); + if (arg_replace && arg_cat_flags != CAT_CONFIG_OFF) return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Option --replace= is not supported with --cat-config/--tldr."); From 69d76823ce6e9c307184946ed55b207eb728e625 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2024 09:56:15 +0200 Subject: [PATCH 04/10] tmpfiles: move --purge to command section in --help text where it belongs Also, make contrast between --remove and --purge clearer: one deletes files marked for deletion, the other deletes files marked for creation. --- src/tmpfiles/tmpfiles.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 9895e94696..80aa274f20 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -4148,7 +4148,9 @@ static int help(void) { "\n%3$sCommands:%4$s\n" " --create Create files and directories\n" " --clean Clean up files and directories\n" - " --remove Remove files and directories\n" + " --remove Remove files and directories marked for removal\n" + " --purge Delete files and directories marked for creation in\n" + " specified configuration files (careful!)\n" " -h --help Show this help\n" " --version Show package version\n" "\n%3$sOptions:%4$s\n" @@ -4157,7 +4159,6 @@ static int help(void) { " --tldr Show non-comment parts of configuration\n" " --boot Execute actions only safe at boot\n" " --graceful Quietly ignore unknown users or groups\n" - " --purge Delete all files owned by the configuration files\n" " --prefix=PATH Only apply rules with the specified prefix\n" " --exclude-prefix=PATH Ignore rules with the specified prefix\n" " -E Ignore rules prefixed with /dev, /proc, /run, /sys\n" From 6f77039e97eb6eddfd6129660b39920204458151 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2024 09:55:32 +0200 Subject: [PATCH 05/10] tmpfiles: remove pointless empty line --- src/tmpfiles/tmpfiles.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 80aa274f20..ca163fd5f7 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -204,7 +204,6 @@ static OperationMask arg_operation = 0; static bool arg_boot = false; static bool arg_graceful = false; static PagerFlags arg_pager_flags = 0; - static char **arg_include_prefixes = NULL; static char **arg_exclude_prefixes = NULL; static char *arg_root = NULL; From 4f25330d871498f3a3538c8d494624d92e829f3e Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2024 09:55:48 +0200 Subject: [PATCH 06/10] tmpfiles: improve debug logging around O_NOATIME fallback --- src/tmpfiles/tmpfiles.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index ca163fd5f7..e3eca2ef27 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -547,14 +547,13 @@ static DIR* xopendirat_nomod(int dirfd, const char *path) { return dir; if (!IN_SET(errno, ENOENT, ELOOP)) - log_debug_errno(errno, "Cannot open %sdirectory \"%s\": %m", dirfd == AT_FDCWD ? "" : "sub", path); - - if (errno != EPERM) + log_debug_errno(errno, "Cannot open %sdirectory \"%s\" with O_NOATIME: %m", dirfd == AT_FDCWD ? "" : "sub", path); + if (!ERRNO_IS_PRIVILEGE(errno)) return NULL; dir = xopendirat(dirfd, path, O_NOFOLLOW); if (!dir) - log_debug_errno(errno, "Cannot open %sdirectory \"%s\": %m", dirfd == AT_FDCWD ? "" : "sub", path); + log_debug_errno(errno, "Cannot open %sdirectory \"%s\" with or without O_NOATIME: %m", dirfd == AT_FDCWD ? "" : "sub", path); return dir; } From 2a3766303699b4f26026ecab7a90922455f9abed Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2024 09:56:36 +0200 Subject: [PATCH 07/10] tmpfiles: make --tldr help text symmetric to --cat-config --- src/tmpfiles/tmpfiles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index e3eca2ef27..f378cdf1ee 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -4154,7 +4154,7 @@ static int help(void) { "\n%3$sOptions:%4$s\n" " --user Execute user configuration\n" " --cat-config Show configuration files\n" - " --tldr Show non-comment parts of configuration\n" + " --tldr Show non-comment parts of configuration files\n" " --boot Execute actions only safe at boot\n" " --graceful Quietly ignore unknown users or groups\n" " --prefix=PATH Only apply rules with the specified prefix\n" From 6718998d1e5e88c2a045037fa052022f1b8880d5 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2024 09:56:49 +0200 Subject: [PATCH 08/10] tmpfiles: suffix --replace= properly with = in comment --- src/tmpfiles/tmpfiles.c | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index f378cdf1ee..12ef71f080 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -4645,12 +4645,10 @@ static int run(int argc, char *argv[]) { if (!c.items || !c.globs) return log_oom(); - /* If command line arguments are specified along with --replace, read all - * configuration files and insert the positional arguments at the specified - * place. Otherwise, if command line arguments are specified, execute just - * them, and finally, without --replace= or any positional arguments, just - * read configuration and execute it. - */ + /* If command line arguments are specified along with --replace=, read all configuration files and + * insert the positional arguments at the specified place. Otherwise, if command line arguments are + * specified, execute just them, and finally, without --replace= or any positional arguments, just + * read configuration and execute it. */ if (arg_replace || optind >= argc) r = read_config_files(&c, config_dirs, argv + optind, &invalid_config); else From d7d41a6a7681892b108ef7f73bb3b93ca99c289b Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2024 10:00:16 +0200 Subject: [PATCH 09/10] tmpfiles: mention that --create also adjusts files/directories in --help text --- src/tmpfiles/tmpfiles.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 12ef71f080..5841db293e 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -4144,7 +4144,7 @@ static int help(void) { printf("%1$s COMMAND [OPTIONS...] [CONFIGURATION FILE...]\n" "\n%2$sCreate, delete, and clean up files and directories.%4$s\n" "\n%3$sCommands:%4$s\n" - " --create Create files and directories\n" + " --create Create and adjust files and directories\n" " --clean Clean up files and directories\n" " --remove Remove files and directories marked for removal\n" " --purge Delete files and directories marked for creation in\n" From c142a8fbcb589733f1b56500bd5a83aa605c5902 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Tue, 18 Jun 2024 10:27:06 +0200 Subject: [PATCH 10/10] man: suffix tmpfiles.d with /, as per coding style --- man/systemd-tmpfiles.xml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/man/systemd-tmpfiles.xml b/man/systemd-tmpfiles.xml index 2a494b9c5c..c3942e5b6e 100644 --- a/man/systemd-tmpfiles.xml +++ b/man/systemd-tmpfiles.xml @@ -177,7 +177,7 @@ - Execute "user" configuration, i.e. tmpfiles.d + Execute "user" configuration, i.e. tmpfiles.d/ files in user configuration directories.