1
1
mirror of https://github.com/systemd/systemd-stable.git synced 2024-12-23 17:34:00 +03:00

tmpfiles: add new 'e' action which cleans up a dir without creating it

I wanted to add a config line that would empty a directory
without creating it if doesn't exist. Existing actions don't allow
this.

v2: properly add 'e' to needs_glob() and takes_ownership()
This commit is contained in:
Zbigniew Jędrzejewski-Szmek 2016-04-20 00:06:25 -04:00
parent 4b743d679b
commit df8dee85da
2 changed files with 36 additions and 42 deletions

View File

@ -168,6 +168,12 @@
of the directory will be removed when <option>--remove</option> is used.
</para></listitem>
</varlistentry>
<varlistentry>
<term><varname>e</varname></term>
<listitem><para>Similar to <varname>d</varname>, but the directory will not be
created if it does not exist. Lines of this type accept shell-style globs in
place of normal path names.</para></listitem>
</varlistentry>
<varlistentry>
@ -581,7 +587,7 @@
unconditionally.</para>
<para>The age field only applies to lines starting with
<varname>d</varname>, <varname>D</varname>,
<varname>d</varname>, <varname>D</varname>, <varname>e</varname>,
<varname>v</varname>, <varname>q</varname>,
<varname>Q</varname>, <varname>C</varname>, <varname>x</varname>
and <varname>X</varname>. If omitted or set to
@ -658,7 +664,21 @@ d /var/tmp 1777 root root 30d
<programlisting># /usr/lib/tmpfiles.d/abrt.conf
d /var/tmp/abrt 0755 abrt abrt -
</programlisting>
</example>
<example>
<title>Apply clean up during boot and based on time</title>
<programlisting># /usr/lib/tmpfiles.d/dnf.conf
r! /var/cache/dnf/*/*/download_lock.pid
r! /var/cache/dnf/*/*/metadata_lock.pid
r! /var/lib/dnf/rpmdb_lock.pid
e /var/chache/dnf/ - - - 30d
</programlisting>
<para>The lock files will be removed during boot. Any files and directories in
<filename>/var/chache/dnf/</filename> will be removed after they have not been
accessed in 30 days.</para>
</example>
</refsect1>

View File

@ -94,6 +94,7 @@ typedef enum ItemType {
/* These ones take globs */
WRITE_FILE = 'w',
EMPTY_DIRECTORY = 'e',
SET_XATTR = 't',
RECURSIVE_SET_XATTR = 'T',
SET_ACL = 'a',
@ -179,6 +180,7 @@ static bool needs_glob(ItemType t) {
IGNORE_DIRECTORY_PATH,
REMOVE_PATH,
RECURSIVE_REMOVE_PATH,
EMPTY_DIRECTORY,
ADJUST_MODE,
RELABEL_PATH,
RECURSIVE_RELABEL_PATH,
@ -195,6 +197,7 @@ static bool takes_ownership(ItemType t) {
CREATE_FILE,
TRUNCATE_FILE,
CREATE_DIRECTORY,
EMPTY_DIRECTORY,
TRUNCATE_DIRECTORY,
CREATE_SUBVOLUME,
CREATE_SUBVOLUME_INHERIT_QUOTA,
@ -1217,7 +1220,6 @@ static int create_item(Item *i) {
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
RUN_WITH_UMASK(0000)
mkdir_parents_label(i->path, 0755);
@ -1289,6 +1291,9 @@ static int create_item(Item *i) {
log_debug("Quota for subvolume \"%s\" already in place, no change made.", i->path);
}
/* fall through */
case EMPTY_DIRECTORY:
r = path_set_perms(i, i->path);
if (q < 0)
return q;
@ -1298,7 +1303,6 @@ static int create_item(Item *i) {
break;
case CREATE_FIFO:
RUN_WITH_UMASK(0000) {
mac_selinux_create_file_prepare(i->path, S_IFIFO);
r = mkfifo(i->path, i->mode);
@ -1535,47 +1539,20 @@ static int remove_item_instance(Item *i, const char *instance) {
}
static int remove_item(Item *i) {
int r = 0;
assert(i);
log_debug("Running remove action for entry %c %s", (char) i->type, i->path);
switch (i->type) {
case CREATE_FILE:
case TRUNCATE_FILE:
case CREATE_DIRECTORY:
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
case CREATE_FIFO:
case CREATE_SYMLINK:
case CREATE_CHAR_DEVICE:
case CREATE_BLOCK_DEVICE:
case IGNORE_PATH:
case IGNORE_DIRECTORY_PATH:
case ADJUST_MODE:
case RELABEL_PATH:
case RECURSIVE_RELABEL_PATH:
case WRITE_FILE:
case COPY_FILES:
case SET_XATTR:
case RECURSIVE_SET_XATTR:
case SET_ACL:
case RECURSIVE_SET_ACL:
case SET_ATTRIBUTE:
case RECURSIVE_SET_ATTRIBUTE:
break;
case REMOVE_PATH:
case TRUNCATE_DIRECTORY:
case RECURSIVE_REMOVE_PATH:
r = glob_item(i, remove_item_instance, false);
break;
}
return glob_item(i, remove_item_instance, false);
return r;
default:
return 0;
}
}
static int clean_item_instance(Item *i, const char* instance) {
@ -1630,8 +1607,6 @@ static int clean_item_instance(Item *i, const char* instance) {
}
static int clean_item(Item *i) {
int r = 0;
assert(i);
log_debug("Running clean action for entry %c %s", (char) i->type, i->path);
@ -1641,19 +1616,17 @@ static int clean_item(Item *i) {
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
case EMPTY_DIRECTORY:
case TRUNCATE_DIRECTORY:
case IGNORE_PATH:
case COPY_FILES:
clean_item_instance(i, i->path);
break;
return 0;
case IGNORE_DIRECTORY_PATH:
r = glob_item(i, clean_item_instance, false);
break;
return glob_item(i, clean_item_instance, false);
default:
break;
return 0;
}
return r;
}
static int process_item_array(ItemArray *array);
@ -1879,6 +1852,7 @@ static int parse_line(const char *fname, unsigned line, const char *buffer) {
case CREATE_SUBVOLUME:
case CREATE_SUBVOLUME_INHERIT_QUOTA:
case CREATE_SUBVOLUME_NEW_QUOTA:
case EMPTY_DIRECTORY:
case TRUNCATE_DIRECTORY:
case CREATE_FIFO:
case IGNORE_PATH: