|
|
8d419f |
From 78105a206a21133f87f5982f29d7aa3c4cc72b0d Mon Sep 17 00:00:00 2001
|
|
|
8d419f |
From: =?UTF-8?q?Zbigniew=20J=C4=99drzejewski-Szmek?= <zbyszek@in.waw.pl>
|
|
|
8d419f |
Date: Wed, 16 Mar 2022 09:28:46 +0100
|
|
|
8d419f |
Subject: [PATCH] shared/install: skip unnecessary chasing of symlinks in
|
|
|
8d419f |
disable
|
|
|
8d419f |
|
|
|
8d419f |
We use the symlink source name and destination names to decide whether to remove
|
|
|
8d419f |
the symlink. But if the source name is enough to decide to remove the symlink,
|
|
|
8d419f |
we'd still look up the destination for no good reason. This is a slow operation,
|
|
|
8d419f |
let's skip it.
|
|
|
8d419f |
|
|
|
8d419f |
(cherry picked from commit 7a6c73dabf6451d6ef22d0cdfbb1749a77450d5b)
|
|
|
8d419f |
|
|
|
8d419f |
Related: #2082131
|
|
|
8d419f |
---
|
|
|
8d419f |
src/shared/install.c | 43 +++++++++++++++++++++++++------------------
|
|
|
8d419f |
1 file changed, 25 insertions(+), 18 deletions(-)
|
|
|
8d419f |
|
|
|
8d419f |
diff --git a/src/shared/install.c b/src/shared/install.c
|
|
|
8d419f |
index ad0238ab50..08a9892260 100644
|
|
|
8d419f |
--- a/src/shared/install.c
|
|
|
8d419f |
+++ b/src/shared/install.c
|
|
|
8d419f |
@@ -599,8 +599,7 @@ static int remove_marked_symlinks_fd(
|
|
|
8d419f |
r = q;
|
|
|
8d419f |
|
|
|
8d419f |
} else if (de->d_type == DT_LNK) {
|
|
|
8d419f |
- _cleanup_free_ char *p = NULL, *dest = NULL;
|
|
|
8d419f |
- const char *rp;
|
|
|
8d419f |
+ _cleanup_free_ char *p = NULL;
|
|
|
8d419f |
bool found;
|
|
|
8d419f |
int q;
|
|
|
8d419f |
|
|
|
8d419f |
@@ -612,24 +611,32 @@ static int remove_marked_symlinks_fd(
|
|
|
8d419f |
return -ENOMEM;
|
|
|
8d419f |
path_simplify(p);
|
|
|
8d419f |
|
|
|
8d419f |
- q = chase_symlinks(p, lp->root_dir, CHASE_NONEXISTENT, &dest, NULL);
|
|
|
8d419f |
- if (q == -ENOENT)
|
|
|
8d419f |
- continue;
|
|
|
8d419f |
- if (q < 0) {
|
|
|
8d419f |
- log_debug_errno(q, "Failed to resolve symlink \"%s\": %m", p);
|
|
|
8d419f |
- unit_file_changes_add(changes, n_changes, q, p, NULL);
|
|
|
8d419f |
+ /* We remove all links pointing to a file or path that is marked, as well as all
|
|
|
8d419f |
+ * files sharing the same name as a file that is marked. Do path chasing only if
|
|
|
8d419f |
+ * we don't already know that we want to remove the symlink. */
|
|
|
8d419f |
+ found = set_contains(remove_symlinks_to, de->d_name);
|
|
|
8d419f |
|
|
|
8d419f |
- if (r == 0)
|
|
|
8d419f |
- r = q;
|
|
|
8d419f |
- continue;
|
|
|
8d419f |
- }
|
|
|
8d419f |
+ if (!found) {
|
|
|
8d419f |
+ _cleanup_free_ char *dest = NULL;
|
|
|
8d419f |
+
|
|
|
8d419f |
+
|
|
|
8d419f |
+ q = chase_symlinks(p, lp->root_dir, CHASE_NONEXISTENT, &dest, NULL);
|
|
|
8d419f |
+ if (q == -ENOENT)
|
|
|
8d419f |
+ continue;
|
|
|
8d419f |
+ if (q < 0) {
|
|
|
8d419f |
+ log_debug_errno(q, "Failed to resolve symlink \"%s\": %m", p);
|
|
|
8d419f |
+ unit_file_changes_add(changes, n_changes, q, p, NULL);
|
|
|
8d419f |
|
|
|
8d419f |
- /* We remove all links pointing to a file or path that is marked, as well as all files sharing
|
|
|
8d419f |
- * the same name as a file that is marked. */
|
|
|
8d419f |
+ if (r == 0)
|
|
|
8d419f |
+ r = q;
|
|
|
8d419f |
+ continue;
|
|
|
8d419f |
+ }
|
|
|
8d419f |
+
|
|
|
8d419f |
+ found = set_contains(remove_symlinks_to, dest) ||
|
|
|
8d419f |
+ set_contains(remove_symlinks_to, basename(dest));
|
|
|
8d419f |
+
|
|
|
8d419f |
+ }
|
|
|
8d419f |
|
|
|
8d419f |
- found = set_contains(remove_symlinks_to, dest) ||
|
|
|
8d419f |
- set_contains(remove_symlinks_to, basename(dest)) ||
|
|
|
8d419f |
- set_contains(remove_symlinks_to, de->d_name);
|
|
|
8d419f |
|
|
|
8d419f |
if (!found)
|
|
|
8d419f |
continue;
|
|
|
8d419f |
@@ -650,7 +657,7 @@ static int remove_marked_symlinks_fd(
|
|
|
8d419f |
/* Now, remember the full path (but with the root prefix removed) of
|
|
|
8d419f |
* the symlink we just removed, and remove any symlinks to it, too. */
|
|
|
8d419f |
|
|
|
8d419f |
- rp = skip_root(lp->root_dir, p);
|
|
|
8d419f |
+ const char *rp = skip_root(lp->root_dir, p);
|
|
|
8d419f |
q = mark_symlink_for_removal(&remove_symlinks_to, rp ?: p);
|
|
|
8d419f |
if (q < 0)
|
|
|
8d419f |
return q;
|