From 24f3a374b9588a6e409ba58b40bdd684050decf3 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Wed, 20 Jun 2012 09:05:50 +0200 Subject: [PATCH] tmpfiles: exclude the first level directories in /run/user from automatic clean up It's logind's job to maintain those user dirs, so avoid automatic clean up for them. However, we do cover everything within them. --- TODO | 11 +++++++++++ man/tmpfiles.d.xml | 6 ++++++ src/tmpfiles/tmpfiles.c | 39 ++++++++++++++++++++++++++++++++------- tmpfiles.d/systemd.conf | 2 +- 4 files changed, 50 insertions(+), 8 deletions(-) diff --git a/TODO b/TODO index 736068195..13174e430 100644 --- a/TODO +++ b/TODO @@ -26,6 +26,17 @@ Bugfixes: rename enum "ManagerRunningAs" to "SystemdRunningAs" and move it to shared/ Features: + +* readahead: merge the three tools into one binary + +* systemctl: when stopping a service which has triggres and warning about it actually check the TriggeredBy= deps fields + +* send SIGPWR to upower on resume so that it can send out its dbus signal for compat + +* vtconsole: don't override kernel cmdline utf8 override setting + +* journal: hook up with EFI firmware log, new kmsg logic + * falconindy: allow unescaped pathes for mount units, like "systmectl status /.mount"? * handle C-A-Del in logind, like the power/suspend buttons? diff --git a/man/tmpfiles.d.xml b/man/tmpfiles.d.xml index 75d4bcd69..8776068a1 100644 --- a/man/tmpfiles.d.xml +++ b/man/tmpfiles.d.xml @@ -267,6 +267,12 @@ L /tmp/foobar - - - - /dev/null The age field only applies to lines starting with d, D and x. If omitted or set to - no automatic clean-up is done. + + If the age field starts with a tilde + character (~) the clean-up is only applied to + files and directories one level inside the + directory specified, but not the files and + directories immediately inside it. diff --git a/src/tmpfiles/tmpfiles.c b/src/tmpfiles/tmpfiles.c index 6e0c093a8..841d16352 100644 --- a/src/tmpfiles/tmpfiles.c +++ b/src/tmpfiles/tmpfiles.c @@ -89,6 +89,8 @@ typedef struct Item { bool gid_set:1; bool mode_set:1; bool age_set:1; + + bool keep_first_level:1; } Item; static Hashmap *items = NULL, *globs = NULL; @@ -100,7 +102,7 @@ static bool arg_remove = false; static const char *arg_prefix = NULL; -static const char *conf_file_dirs[] = { +static const char * const conf_file_dirs[] = { "/etc/tmpfiles.d", "/run/tmpfiles.d", "/usr/local/lib/tmpfiles.d", @@ -216,7 +218,8 @@ static int dir_cleanup( usec_t cutoff, dev_t rootdev, bool mountpoint, - int maxdepth) + int maxdepth, + bool keep_this_level) { struct dirent *dent; struct timespec times[2]; @@ -289,13 +292,23 @@ static int dir_cleanup( continue; } - q = dir_cleanup(sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1); + q = dir_cleanup(sub_path, sub_dir, &s, cutoff, rootdev, false, maxdepth-1, false); closedir(sub_dir); if (q < 0) r = q; } + /* Note: if you are wondering why we don't + * support the sticky bit for excluding + * directories from cleaning like we do it for + * other file system objects: well, the sticky + * bit already has a meaning for directories, + * so we don't want to overload that. */ + + if (keep_this_level) + continue; + /* Ignore ctime, we change it when deleting */ age = MAX(timespec_load(&s.st_mtim), timespec_load(&s.st_atim)); @@ -337,6 +350,11 @@ static int dir_cleanup( if (S_ISCHR(s.st_mode) || S_ISBLK(s.st_mode)) continue; + /* Keep files on this level around if this is + * requested */ + if (keep_this_level) + continue; + age = MAX3(timespec_load(&s.st_mtim), timespec_load(&s.st_atim), timespec_load(&s.st_ctim)); @@ -425,7 +443,7 @@ static int clean_item(Item *i) { mountpoint = s.st_dev != ps.st_dev || (s.st_dev == ps.st_dev && s.st_ino == ps.st_ino); - r = dir_cleanup(i->path, d, &s, cutoff, s.st_dev, mountpoint, MAX_DEPTH); + r = dir_cleanup(i->path, d, &s, cutoff, s.st_dev, mountpoint, MAX_DEPTH, i->keep_first_level); finish: if (d) @@ -1094,7 +1112,14 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) { i->type == TRUNCATE_DIRECTORY ? 0755 : 0644; if (age && !streq(age, "-")) { - if (parse_usec(age, &i->age) < 0) { + const char *a = age; + + if (*a == '~') { + i->keep_first_level = true; + a++; + } + + if (parse_usec(a, &i->age) < 0) { log_error("[%s:%u] Invalid age '%s'.", fname, line, age); r = -EBADMSG; goto finish; @@ -1320,7 +1345,7 @@ int main(int argc, char *argv[]) { for (j = optind; j < argc; j++) { char *fragment; - fragment = resolve_fragment(argv[j], conf_file_dirs); + fragment = resolve_fragment(argv[j], (const char**) conf_file_dirs); if (!fragment) { log_error("Failed to find a %s file: %m", argv[j]); r = EXIT_FAILURE; @@ -1335,7 +1360,7 @@ int main(int argc, char *argv[]) { char **files, **f; r = conf_files_list_strv(&files, ".conf", - (const char **)conf_file_dirs); + (const char **) conf_file_dirs); if (r < 0) { log_error("Failed to enumerate tmpfiles.d files: %s", strerror(-r)); r = EXIT_FAILURE; diff --git a/tmpfiles.d/systemd.conf b/tmpfiles.d/systemd.conf index 28362e86b..d415f6840 100644 --- a/tmpfiles.d/systemd.conf +++ b/tmpfiles.d/systemd.conf @@ -7,7 +7,7 @@ # See tmpfiles.d(5) for details -d /run/user 0755 root root 10d +d /run/user 0755 root root ~10d F /run/utmp 0664 root utmp - f /var/log/wtmp 0664 root utmp - -- 2.30.2