]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
systemctl: downgrade or silence warnings for --now
authorZbigniew Jędrzejewski-Szmek <zbyszek@in.waw.pl>
Sun, 26 Oct 2025 10:57:56 +0000 (11:57 +0100)
committerLuca Boccassi <luca.boccassi@gmail.com>
Thu, 6 Nov 2025 21:26:42 +0000 (21:26 +0000)
When calling systemctl enable/disable/reenable --now, we'd always fail with
error when operating offline. This seemly overly restricitive. In particular,
if systemd is not running at all, the service is not running either, so
complaining that we can't stop it is completely unnecessary. But even when
operating in a chroot where systemd is not running, let's just emit a warning
and return success. It's fairly common to have installation or package scripts
which do such calls and not starting/restarting the service in those scenarios
is the desired and expected operation. (If --now is called in combination
with --global or --root=, keep returning an error.)

Also make the messages nicer. I was adding some docs to tell the user to run
'systemctl enable --now', and checked how the command can fail, and the error
message that the user might see in some common scenarios was too complicated.
Split it up to be nicer.

(cherry picked from commit 77a1cc8fa09c264991d147ec71d70a4b5d2a553e)

src/systemctl/systemctl-enable.c

index 177e4aaa84bf91243955cdd0c7aadfed79d8363d..c760b917f628057643068b312e856d3b213228d7 100644 (file)
@@ -334,7 +334,7 @@ int verb_enable(int argc, char *argv[], void *userdata) {
         if (arg_now) {
                 _cleanup_strv_free_ char **new_args = NULL;
                 const char *start_verb;
-                bool accept_path, prohibit_templates;
+                bool accept_path, prohibit_templates, dead_ok = false;
 
                 if (streq(verb, "enable")) {
                         start_verb = "start";
@@ -344,6 +344,7 @@ int verb_enable(int argc, char *argv[], void *userdata) {
                         start_verb = "stop";
                         accept_path = false;
                         prohibit_templates = false;
+                        dead_ok = true;  /* If the service is not running anyway, no need to stop it. */
                 } else if (streq(verb, "reenable")) {
                         /* Note that we use try-restart here. This matches the semantics of reenable better,
                          * and allows us to glob template units. */
@@ -354,9 +355,20 @@ int verb_enable(int argc, char *argv[], void *userdata) {
                         return log_error_errno(SYNTHETIC_ERRNO(EINVAL),
                                                "--now can only be used with verb enable, disable, reenable, or mask.");
 
-                if (install_client_side() != INSTALL_CLIENT_SIDE_NO)
-                        return log_error_errno(SYNTHETIC_ERRNO(EREMOTE),
-                                               "--now cannot be used when systemd is not running or in conjunction with --root=/--global, refusing.");
+                switch (install_client_side()) {
+                case INSTALL_CLIENT_SIDE_NO:
+                        break;
+                case INSTALL_CLIENT_SIDE_OVERRIDE:
+                case INSTALL_CLIENT_SIDE_OFFLINE:
+                case INSTALL_CLIENT_SIDE_NOT_BOOTED:
+                        if (!dead_ok)
+                                log_warning("Cannot %s unit with --now when systemd is not running, ignoring.", start_verb);
+                        return 0;
+                case INSTALL_CLIENT_SIDE_ARG_ROOT:
+                        return log_error_errno(SYNTHETIC_ERRNO(EREMOTE), "--now cannot be used with --root=.");
+                case INSTALL_CLIENT_SIDE_GLOBAL_SCOPE:
+                        return log_error_errno(SYNTHETIC_ERRNO(EREMOTE), "--now cannot be used with --global.");
+                }
 
                 assert(bus);