Zbigniew Jędrzejewski-Szmek 696e2f
From bfcaa19428a32234356fde460ef556c23bf80f4a Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 696e2f
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
Zbigniew Jędrzejewski-Szmek 696e2f
Date: Sat, 13 Aug 2016 01:27:21 -0400
Zbigniew Jędrzejewski-Szmek 696e2f
Subject: [PATCH] shared/install: when creating symlinks, keep existing
Zbigniew Jędrzejewski-Szmek 696e2f
 relative symlinks
Zbigniew Jędrzejewski-Szmek 696e2f
MIME-Version: 1.0
Zbigniew Jędrzejewski-Szmek 696e2f
Content-Type: text/plain; charset=UTF-8
Zbigniew Jędrzejewski-Szmek 696e2f
Content-Transfer-Encoding: 8bit
Zbigniew Jędrzejewski-Szmek 696e2f
Zbigniew Jędrzejewski-Szmek 696e2f
Running preset-all on a system installed from rpms or even created
Zbigniew Jędrzejewski-Szmek 696e2f
using make install would remove and recreate a lot of symlinks, changing
Zbigniew Jędrzejewski-Szmek 696e2f
relative to absolute symlinks. In general relative symlinks are nicer,
Zbigniew Jędrzejewski-Szmek 696e2f
so there is no reason to change them, and those spurious changes were
Zbigniew Jędrzejewski-Szmek 696e2f
obscuring more interesting stuff.
Zbigniew Jędrzejewski-Szmek 696e2f
Zbigniew Jędrzejewski-Szmek 696e2f
$ make install DESTDIR=/var/tmp/inst1
Zbigniew Jędrzejewski-Szmek 696e2f
Zbigniew Jędrzejewski-Szmek 696e2f
$ systemctl preset-all --root=/var/tmp/inst1
Zbigniew Jędrzejewski-Szmek 696e2f
(before)
Zbigniew Jędrzejewski-Szmek 696e2f
Removed /var/tmp/inst1/etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/ctrl-alt-del.target → /usr/lib/systemd/system/exit.target.
Zbigniew Jędrzejewski-Szmek 696e2f
Removed /var/tmp/inst1/etc/systemd/system/multi-user.target.wants/remote-fs.target.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/multi-user.target.wants/remote-fs.target → /usr/lib/systemd/system/remote-fs.target.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/multi-user.target.wants/machines.target → /usr/lib/systemd/system/machines.target.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/sockets.target.wants/systemd-journal-remote.socket → /usr/lib/systemd/system/systemd-journal-remote.socket.
Zbigniew Jędrzejewski-Szmek 696e2f
Removed /var/tmp/inst1/etc/systemd/system/sockets.target.wants/systemd-networkd.socket.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/sockets.target.wants/systemd-networkd.socket → /usr/lib/systemd/system/systemd-networkd.socket.
Zbigniew Jędrzejewski-Szmek 696e2f
Removed /var/tmp/inst1/etc/systemd/system/getty.target.wants/getty@tty1.service.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/getty.target.wants/getty@tty1.service → /usr/lib/systemd/system/getty@.service.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/multi-user.target.wants/systemd-journal-upload.service → /usr/lib/systemd/system/systemd-journal-upload.service.
Zbigniew Jędrzejewski-Szmek 696e2f
Removed /var/tmp/inst1/etc/systemd/system/sysinit.target.wants/systemd-timesyncd.service.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/sysinit.target.wants/systemd-timesyncd.service → /usr/lib/systemd/system/systemd-timesyncd.service.
Zbigniew Jędrzejewski-Szmek 696e2f
Removed /var/tmp/inst1/etc/systemd/system/multi-user.target.wants/systemd-resolved.service.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/multi-user.target.wants/systemd-resolved.service → /usr/lib/systemd/system/systemd-resolved.service.
Zbigniew Jędrzejewski-Szmek 696e2f
Removed /var/tmp/inst1/etc/systemd/system/multi-user.target.wants/systemd-networkd.service.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/multi-user.target.wants/systemd-networkd.service → /usr/lib/systemd/system/systemd-networkd.service.
Zbigniew Jędrzejewski-Szmek 696e2f
Zbigniew Jędrzejewski-Szmek 696e2f
(after)
Zbigniew Jędrzejewski-Szmek 696e2f
Removed /var/tmp/inst1/etc/systemd/system/network-online.target.wants/systemd-networkd-wait-online.service.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/ctrl-alt-del.target → /usr/lib/systemd/system/exit.target.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/multi-user.target.wants/machines.target → /usr/lib/systemd/system/machines.target.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/sockets.target.wants/systemd-journal-remote.socket → /usr/lib/systemd/system/systemd-journal-remote.socket.
Zbigniew Jędrzejewski-Szmek 696e2f
Created symlink /var/tmp/inst1/etc/systemd/system/multi-user.target.wants/systemd-journal-upload.service → /usr/lib/systemd/system/systemd-journal-upload.service.
Zbigniew Jędrzejewski-Szmek 696e2f
Zbigniew Jędrzejewski-Szmek 696e2f
(cherry picked from commit 25ea92778d5f4339e07c152a99d16223f43ad681)
Zbigniew Jędrzejewski-Szmek 696e2f
---
Zbigniew Jędrzejewski-Szmek 696e2f
 src/shared/install.c | 23 +++++++++++++++++++++--
Zbigniew Jędrzejewski-Szmek 696e2f
 1 file changed, 21 insertions(+), 2 deletions(-)
Zbigniew Jędrzejewski-Szmek 696e2f
Zbigniew Jędrzejewski-Szmek 696e2f
diff --git a/src/shared/install.c b/src/shared/install.c
Zbigniew Jędrzejewski-Szmek 696e2f
index 8c45725f5a..9ce8e4d390 100644
Zbigniew Jędrzejewski-Szmek 696e2f
--- a/src/shared/install.c
Zbigniew Jędrzejewski-Szmek 696e2f
+++ b/src/shared/install.c
Zbigniew Jędrzejewski-Szmek 696e2f
@@ -393,6 +393,21 @@ void unit_file_dump_changes(int r, const char *verb, const UnitFileChange *chang
Zbigniew Jędrzejewski-Szmek 696e2f
                 log_error_errno(r, "Failed to %s: %m.", verb);
Zbigniew Jędrzejewski-Szmek 696e2f
 }
Zbigniew Jędrzejewski-Szmek 696e2f
 
Zbigniew Jędrzejewski-Szmek 696e2f
+/**
Zbigniew Jędrzejewski-Szmek 696e2f
+ * Checks if two paths or symlinks from wd are the same, when root is the root of the filesystem.
Zbigniew Jędrzejewski-Szmek 696e2f
+ * wc should be the full path in the host file system.
Zbigniew Jędrzejewski-Szmek 696e2f
+ */
Zbigniew Jędrzejewski-Szmek 696e2f
+static bool chroot_symlinks_same(const char *root, const char *wd, const char *a, const char *b) {
Zbigniew Jędrzejewski-Szmek 696e2f
+        assert(path_is_absolute(wd));
Zbigniew Jędrzejewski-Szmek 696e2f
+
Zbigniew Jędrzejewski-Szmek 696e2f
+        /* This will give incorrect results if the paths are relative and go outside
Zbigniew Jędrzejewski-Szmek 696e2f
+         * of the chroot. False negatives are possible. */
Zbigniew Jędrzejewski-Szmek 696e2f
+
Zbigniew Jędrzejewski-Szmek 696e2f
+        a = strjoina(path_is_absolute(a) ? root : wd, "/", a);
Zbigniew Jędrzejewski-Szmek 696e2f
+        b = strjoina(path_is_absolute(b) ? root : wd, "/", b);
Zbigniew Jędrzejewski-Szmek 696e2f
+        return path_equal_or_files_same(a, b);
Zbigniew Jędrzejewski-Szmek 696e2f
+}
Zbigniew Jędrzejewski-Szmek 696e2f
+
Zbigniew Jędrzejewski-Szmek 696e2f
 static int create_symlink(
Zbigniew Jędrzejewski-Szmek 696e2f
                 const LookupPaths *paths,
Zbigniew Jędrzejewski-Szmek 696e2f
                 const char *old_path,
Zbigniew Jędrzejewski-Szmek 696e2f
@@ -401,7 +416,7 @@ static int create_symlink(
Zbigniew Jędrzejewski-Szmek 696e2f
                 UnitFileChange **changes,
Zbigniew Jędrzejewski-Szmek 696e2f
                 unsigned *n_changes) {
Zbigniew Jędrzejewski-Szmek 696e2f
 
Zbigniew Jędrzejewski-Szmek 696e2f
-        _cleanup_free_ char *dest = NULL;
Zbigniew Jędrzejewski-Szmek 696e2f
+        _cleanup_free_ char *dest = NULL, *dirname = NULL;
Zbigniew Jędrzejewski-Szmek 696e2f
         const char *rp;
Zbigniew Jędrzejewski-Szmek 696e2f
         int r;
Zbigniew Jędrzejewski-Szmek 696e2f
 
Zbigniew Jędrzejewski-Szmek 696e2f
@@ -442,7 +457,11 @@ static int create_symlink(
Zbigniew Jędrzejewski-Szmek 696e2f
                 return r;
Zbigniew Jędrzejewski-Szmek 696e2f
         }
Zbigniew Jędrzejewski-Szmek 696e2f
 
Zbigniew Jędrzejewski-Szmek 696e2f
-        if (path_equal(dest, old_path))
Zbigniew Jędrzejewski-Szmek 696e2f
+        dirname = dirname_malloc(new_path);
Zbigniew Jędrzejewski-Szmek 696e2f
+        if (!dirname)
Zbigniew Jędrzejewski-Szmek 696e2f
+                return -ENOMEM;
Zbigniew Jędrzejewski-Szmek 696e2f
+
Zbigniew Jędrzejewski-Szmek 696e2f
+        if (chroot_symlinks_same(paths->root_dir, dirname, dest, old_path))
Zbigniew Jędrzejewski-Szmek 696e2f
                 return 1;
Zbigniew Jędrzejewski-Szmek 696e2f
 
Zbigniew Jędrzejewski-Szmek 696e2f
         if (!force) {