chiark / gitweb /
tmpfiles: when processing lines, always process prefixes before suffixes
authorLennart Poettering <lennart@poettering.net>
Tue, 10 Jun 2014 23:37:35 +0000 (01:37 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 10 Jun 2014 23:37:35 +0000 (01:37 +0200)
If two lines refer to paths that are suffix and prefix of each other,
then always process the prefix first, the suffix second. In all other
cases strictly process rules in the order they appear in the files.

This makes creating /var/run as symlink to /run a lot more fun, since it
is automatically created first.

man/tmpfiles.d.xml
src/tmpfiles/tmpfiles.c

index 76cae39aae4345583ccbd3aef69e529eab603a81..5d8c2b5b3297a0c673e78106c267a746bb0e8a8e 100644 (file)
                 of the directories they reside in. If multiple files
                 specify the same path, the entry in the file with the
                 lexicographically earliest name will be applied, all
-                all other conflicting entries logged as errors.</para>
+                all other conflicting entries will be logged as
+                errors. When two lines are prefix and suffix of each
+                other, then the prefix is always processed first, the
+                suffix later. Otherwise the files/directories are
+                processed in the order they are listed.</para>
 
                 <para>If the administrator wants to disable a
                 configuration file supplied by the vendor, the
index d68693f829589d9c8b1c9596cc1a1221ef35e68f..c6121bccf3641fb25a43dc9fd79b4194fe00bcd5 100644 (file)
@@ -101,6 +101,8 @@ typedef struct Item {
         bool age_set:1;
 
         bool keep_first_level:1;
+
+        bool done:1;
 } Item;
 
 static bool arg_create = false;
@@ -977,9 +979,23 @@ static int clean_item(Item *i) {
 
 static int process_item(Item *i) {
         int r, q, p;
+        char prefix[PATH_MAX];
 
         assert(i);
 
+        if (i->done)
+                return 0;
+
+        i->done = true;
+
+        PATH_FOREACH_PREFIX(prefix, i->path) {
+                Item *j;
+
+                j = hashmap_get(items, prefix);
+                if (j)
+                        process_item(j);
+        }
+
         r = arg_create ? create_item(i) : 0;
         q = arg_remove ? remove_item(i) : 0;
         p = arg_clean ? clean_item(i) : 0;