From c6dd36b65caa9acc03a8e77b7db752574cf36eb4 Mon Sep 17 00:00:00 2001 From: Felipe Sateler Date: Fri, 11 Nov 2016 23:28:06 -0300 Subject: [PATCH] systemctl: resolve symlinks when finding unit paths (#4545) Otherwise we think the alias is the real unit, and may edit/cat the wrong unit. Before this patch: $ systemctl edit autovt@ # creates dropin in /etc/systemd/system/autovt@.service.d $ systemctl cat autovt@ | grep @.service # /lib/systemd/system/autovt@.service # that serial gettys are covered by serial-getty@.service, not this # /etc/systemd/system/autovt@.service.d/override.conf $ systemctl cat getty@ | grep @.service # /lib/systemd/system/getty@.service # that serial gettys are covered by serial-getty@.service, not this After this patch $ systemctl edit autovt@ # creates dropin in /etc/systemd/system/getty@.service.d $ systemctl cat autovt@ | grep @.service # /usr/lib/systemd/system/getty@.service # that serial gettys are covered by serial-getty@.service, not this # /etc/systemd/system/getty@.service.d/override.conf systemctl cat getty@ | grep @.service # /usr/lib/systemd/system/getty@.service # that serial gettys are covered by serial-getty@.service, not this # /etc/systemd/system/getty@.service.d/override.conf --- src/systemctl/systemctl.c | 31 +++++++++++++++++++------------ 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 8a9a47a..49a97ff 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -2432,17 +2432,24 @@ static int unit_file_find_path(LookupPaths *lp, const char *unit_name, char **un assert(unit_path); STRV_FOREACH(p, lp->search_path) { - _cleanup_free_ char *path; + _cleanup_free_ char *path = NULL, *lpath = NULL; + int r; path = path_join(arg_root, *p, unit_name); if (!path) return log_oom(); - if (access(path, F_OK) == 0) { - *unit_path = path; - path = NULL; - return 1; - } + r = chase_symlinks(path, arg_root, &lpath); + if (r == -ENOENT) + continue; + if (r == -ENOMEM) + return log_oom(); + if (r < 0) + return log_error_errno(r, "Failed to access path '%s': %m", path); + + *unit_path = lpath; + lpath = NULL; + return 1; } return 0; @@ -2509,10 +2516,6 @@ static int unit_find_paths( if (!names) return log_oom(); - r = set_put(names, unit_name); - if (r < 0) - return log_error_errno(r, "Failed to add unit name: %m"); - r = unit_file_find_path(lp, unit_name, &path); if (r < 0) return r; @@ -2530,6 +2533,10 @@ static int unit_find_paths( } } + r = set_put(names, basename(path)); + if (r < 0) + return log_error_errno(r, "Failed to add unit name: %m"); + if (dropin_paths) { r = unit_file_find_dropin_paths(lp->search_path, NULL, names, &dropins); if (r < 0) @@ -6735,9 +6742,9 @@ static int find_paths_to_edit(sd_bus *bus, char **names, char ***paths) { if (path) { if (arg_full) - r = unit_file_create_copy(&lp, *name, path, &new_path, &tmp_path); + r = unit_file_create_copy(&lp, basename(path), path, &new_path, &tmp_path); else - r = unit_file_create_new(&lp, *name, ".d/override.conf", &new_path, &tmp_path); + r = unit_file_create_new(&lp, basename(path), ".d/override.conf", &new_path, &tmp_path); } else r = unit_file_create_new(&lp, *name, NULL, &new_path, &tmp_path); if (r < 0) -- 2.7.4