Skip to content

Commit f1f0ba5

Browse files
committed
tmpfiles: add --exclude-prefix and -E flags
Add support for the --exclude-prefix=PATH option to skip rules whose path starts with the specified prefix. The option can be specified multiple times to exclude multiple path prefixes. The -E flag is a shortcut for: --exclude-prefix=/dev --exclude-prefix=/proc \ --exclude-prefix=/run --exclude-prefix=/sys This is useful to avoid creating files below virtual or memory-backed file system mount points.
1 parent dacda5a commit f1f0ba5

File tree

1 file changed

+46
-6
lines changed

1 file changed

+46
-6
lines changed

src/tmpfiles.c

Lines changed: 46 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,26 @@ int create_flag = 0;
5050
int clean_flag = 0;
5151
int remove_flag = 0;
5252

53+
#define MAX_EXCLUDES 32
54+
static const char *exclude_prefixes[MAX_EXCLUDES];
55+
static int num_excludes;
56+
57+
static void add_exclude_prefix(const char *prefix)
58+
{
59+
if (num_excludes < MAX_EXCLUDES)
60+
exclude_prefixes[num_excludes++] = prefix;
61+
}
62+
63+
static int excluded(const char *path)
64+
{
65+
for (int i = 0; i < num_excludes; i++) {
66+
if (!strncmp(path, exclude_prefixes[i], strlen(exclude_prefixes[i])))
67+
return 1;
68+
}
69+
70+
return 0;
71+
}
72+
5373
static int is_dir_empty(const char *path)
5474
{
5575
struct dirent **namelist = NULL;
@@ -413,6 +433,8 @@ static void tmpfiles(char *line)
413433
errx(1, "Path name specifiers unsupported, skipping.");
414434
return;
415435
}
436+
if (excluded(path))
437+
return;
416438

417439
token = strtok(NULL, "\t ");
418440
if (token) {
@@ -752,6 +774,8 @@ static int usage(int rc)
752774
" -C, --clean Clean files and directories based on age\n"
753775
" -c, --create Create files and directories\n"
754776
" -d, --debug Show developer debug messages\n"
777+
" -E Exclude /dev, /proc, /run, and /sys\n"
778+
" --exclude-prefix=PFX Ignore rules for paths starting with PFX\n"
755779
" -r, --remove Remove files and directories marked for removal\n"
756780
" -h, --help This help text\n"
757781
"\n"
@@ -762,20 +786,25 @@ static int usage(int rc)
762786
return rc;
763787
}
764788

789+
enum {
790+
OPT_EXCLUDE_PREFIX = 256,
791+
};
792+
765793
int main(int argc, char *argv[])
766794
{
767795
struct option long_options[] = {
768-
{ "clean", 0, NULL, 'C' },
769-
{ "create", 0, NULL, 'c' },
770-
{ "debug", 0, NULL, 'd' },
771-
{ "remove", 0, NULL, 'r' },
772-
{ "help", 0, NULL, 'h' },
796+
{ "clean", 0, NULL, 'C' },
797+
{ "create", 0, NULL, 'c' },
798+
{ "debug", 0, NULL, 'd' },
799+
{ "exclude-prefix", 1, NULL, OPT_EXCLUDE_PREFIX },
800+
{ "remove", 0, NULL, 'r' },
801+
{ "help", 0, NULL, 'h' },
773802
{ NULL, 0, NULL, 0 }
774803
};
775804

776805
int c;
777806

778-
while ((c = getopt_long(argc, argv, "Ccdrh?", long_options, NULL)) != EOF) {
807+
while ((c = getopt_long(argc, argv, "CcdrEh?", long_options, NULL)) != EOF) {
779808
switch(c) {
780809
case 'C':
781810
clean_flag = 1;
@@ -789,6 +818,17 @@ int main(int argc, char *argv[])
789818
debug = 1;
790819
break;
791820

821+
case 'E':
822+
add_exclude_prefix("/dev");
823+
add_exclude_prefix("/proc");
824+
add_exclude_prefix("/run");
825+
add_exclude_prefix("/sys");
826+
break;
827+
828+
case OPT_EXCLUDE_PREFIX:
829+
add_exclude_prefix(optarg);
830+
break;
831+
792832
case 'r':
793833
remove_flag = 1;
794834
break;

0 commit comments

Comments
 (0)