diff options
author | Felipe Sateler <fsateler@users.noreply.github.com> | 2016-11-11 23:28:06 -0300 |
---|---|---|
committer | Zbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl> | 2016-11-11 21:28:06 -0500 |
commit | c6dd36b65caa9acc03a8e77b7db752574cf36eb4 (patch) | |
tree | 122d9a897b8d228fabb708941bfb8bdaff1516ca | |
parent | f40771a58025b79b1eab554e68647d397392ea37 (diff) |
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
-rw-r--r-- | src/systemctl/systemctl.c | 31 |
1 files changed, 19 insertions, 12 deletions
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 8a9a47a88e..49a97ff268 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) |