803fb7
From 1f8b1e35e3ec80c50201403171b7375ff14c808c Mon Sep 17 00:00:00 2001
803fb7
From: Michal Sekletar <msekletar@users.noreply.github.com>
803fb7
Date: Tue, 26 Jul 2016 14:25:52 +0200
803fb7
Subject: [PATCH] systemctl: allow disable on the unit file path, but warn
803fb7
 about it (#3806)
803fb7
803fb7
systemd now returns an error when it is asked to perform disable on the
803fb7
unit file path. In the past this was allowed, but systemd never really
803fb7
considered an actual content of the [Install] section of the unit
803fb7
file. Instead it performed disable on the unit name, i.e. purged all
803fb7
symlinks pointing to the given unit file (undo of implicit link action
803fb7
done by systemd when enable is called on the unit file path) and all
803fb7
symlinks that have the same basename as the given unit file.
803fb7
803fb7
However, to notice that [Install] info of the file is not consulted one
803fb7
must create additional symlinks manually. I argue that in most cases
803fb7
users do not create such links. Let's be nice to our users and don't
803fb7
break existing scripts that expect disable to work with the unit file
803fb7
path.
803fb7
803fb7
Fixes #3706.
803fb7
803fb7
IMPORTANT
803fb7
=========
803fb7
Note that in this downstream backport we actually pass false to
803fb7
normalize_names(), hence it will not produce any warning when full path
803fb7
is passed in. This is because we need to preserve behavior compatible
803fb7
with prior systemd versions shipped in RHEL.
803fb7
803fb7
Cherry-picked from: 1d3c86c06fca8311923fcf81af0ab0bbb66e1edd
803fb7
Resolves: #1348208
803fb7
---
803fb7
 src/systemctl/systemctl.c | 29 +++++++++++++++++++++++++++++
803fb7
 1 file changed, 29 insertions(+)
803fb7
803fb7
diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
803fb7
index b7496c006..58998185c 100644
803fb7
--- a/src/systemctl/systemctl.c
803fb7
+++ b/src/systemctl/systemctl.c
803fb7
@@ -5333,6 +5333,29 @@ static int mangle_names(char **original_names, char ***mangled_names) {
803fb7
         return 0;
803fb7
 }
803fb7
 
803fb7
+static int normalize_names(char **names, bool warn_if_path) {
803fb7
+        char **u;
803fb7
+        bool was_path = false;
803fb7
+
803fb7
+        STRV_FOREACH(u, names) {
803fb7
+                int r;
803fb7
+
803fb7
+                if (!is_path(*u))
803fb7
+                        continue;
803fb7
+
803fb7
+                r = free_and_strdup(u, basename(*u));
803fb7
+                if (r < 0)
803fb7
+                        return log_error_errno(r, "Failed to normalize unit file path: %m");
803fb7
+
803fb7
+                was_path = true;
803fb7
+        }
803fb7
+
803fb7
+        if (warn_if_path && was_path)
803fb7
+                log_warning("Warning: Can't execute disable on the unit file path. Proceeding with the unit name.");
803fb7
+
803fb7
+        return 0;
803fb7
+}
803fb7
+
803fb7
 static int enable_unit(sd_bus *bus, char **args) {
803fb7
         _cleanup_strv_free_ char **names = NULL;
803fb7
         const char *verb = args[0];
803fb7
@@ -5357,6 +5380,12 @@ static int enable_unit(sd_bus *bus, char **args) {
803fb7
         if (strv_isempty(names))
803fb7
                 return 0;
803fb7
 
803fb7
+        if (streq(verb, "disable")) {
803fb7
+                r = normalize_names(names, false);
803fb7
+                if (r < 0)
803fb7
+                        return r;
803fb7
+        }
803fb7
+
803fb7
         if (!bus || avoid_bus()) {
803fb7
                 if (streq(verb, "enable")) {
803fb7
                         r = unit_file_enable(arg_scope, arg_runtime, arg_root, names, arg_force, &changes, &n_changes);