]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
shared/install: do not require /dev/null to be present in chroots 15955/head
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 5 Jul 2020 18:03:48 +0000 (20:03 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 5 Jul 2020 18:06:22 +0000 (20:06 +0200)
This partially undoes the parent commit. We follow the symlink and
if it appears to be a symlink to /dev/null, even if /dev/null is not
present, we treat it as such. The addition of creation of /dev/null
in the test is reverted.

src/shared/install.c
src/test/test-install-root.c

index 0f2d407a36afd55780534145edd93bc4a0df42b6..fb5e166ff016ea673b469d173a686a27f53fd102 100644 (file)
@@ -1236,8 +1236,7 @@ static int unit_file_load(
                                                "%s: unit type %s cannot be templated, ignoring.", path, unit_type_to_string(type));
 
                 if (!(flags & SEARCH_LOAD)) {
-                        r = lstat(path, &st);
-                        if (r < 0)
+                        if (lstat(path, &st) < 0)
                                 return -errno;
 
                         if (null_or_empty(&st))
@@ -1324,6 +1323,7 @@ static int unit_file_load_or_readlink(
                 const char *path,
                 const char *root_dir,
                 SearchFlags flags) {
+        _cleanup_free_ char *resolved = NULL;
         struct stat st;
         int r;
 
@@ -1331,15 +1331,27 @@ static int unit_file_load_or_readlink(
         if (r != -ELOOP || (flags & SEARCH_DROPIN))
                 return r;
 
-        r = chase_symlinks_and_stat(path, root_dir, CHASE_WARN, NULL, &st, NULL);
-        if (r > 0 && null_or_empty(&st))
+        r = chase_symlinks(path, root_dir, CHASE_WARN | CHASE_NONEXISTENT, &resolved, NULL);
+        if (r >= 0 &&
+            root_dir &&
+            path_equal_ptr(path_startswith(resolved, root_dir), "dev/null"))
+                /* When looking under root_dir, we can't expect /dev/ to be mounted,
+                 * so let's see if the path is a (possibly dangling) symlink to /dev/null. */
+                info->type = UNIT_FILE_TYPE_MASKED;
+
+        else if (r > 0 &&
+                 stat(resolved, &st) >= 0 &&
+                 null_or_empty(&st))
+
                 info->type = UNIT_FILE_TYPE_MASKED;
+
         else {
                 _cleanup_free_ char *target = NULL;
                 const char *bn;
                 UnitType a, b;
 
-                /* This is a symlink, let's read it. */
+                /* This is a symlink, let's read it. We read the link again, because last time
+                 * we followed the link until resolution, and here we need to do one step. */
 
                 r = readlink_malloc(path, &target);
                 if (r < 0)
index d437686baebc214971b2b37347eb9504ddfaa03e..f309160889798e410250776f70e29112360bda2f 100644 (file)
@@ -1245,12 +1245,6 @@ int main(int argc, char *argv[]) {
         p = strjoina(root, "/usr/lib/systemd/system-preset/");
         assert_se(mkdir_p(p, 0755) >= 0);
 
-        p = strjoina(root, "/dev/");
-        assert_se(mkdir_p(p, 0755) >= 0);
-
-        p = strjoina(root, "/dev/null");
-        assert_se(touch(p) >= 0);
-
         test_basic_mask_and_enable(root);
         test_linked_units(root);
         test_default(root);