]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
manager: if called with compat telinit interface, tell users to update
authorZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Sun, 31 May 2026 10:29:01 +0000 (12:29 +0200)
committerZbigniew Jędrzejewski-Szmek <zbyszek@amutable.com>
Mon, 1 Jun 2026 10:19:03 +0000 (12:19 +0200)
In https://bugzilla.redhat.com/show_bug.cgi?id=2479961 a user
reported that they are confused that 'init 6' and such commands
do not work anymore. We removed support for the whole interface,
but it's likely that such commands persist in various scripts
and finger memories. Let's give a helpful hint that this inteface
is gone and what to use instead.

src/core/main.c
src/shared/pretty-print.c
src/shared/pretty-print.h

index 7815691133c6677403713af93eaadb00d8893de6..419316e25f311faf1b9f942ae0c78bbbc38b1fa0 100644 (file)
@@ -89,6 +89,7 @@
 #include "parse-util.h"
 #include "path-util.h"
 #include "pidfd-util.h"
+#include "pretty-print.h"
 #include "proc-cmdline.h"
 #include "process-util.h"
 #include "random-util.h"
@@ -1004,6 +1005,31 @@ static void set_manager_settings(Manager *m) {
         m->restrict_filesystem_access = arg_restrict_filesystem_access;
 }
 
+static int redirect_telinit(char *argv[], char **args) {
+        /* Check if we are invoked through the legacy interface, where init would be symlinked as telinit
+         * and allow users to call 'init 0' and such. If we detect such use, tell the user that this is not
+         * supported anymore. */
+
+        if (getpid_cached() == 1 || !invoked_as(argv, "init"))
+                return 0;
+
+        /* Check if the user specified one of the telinit commands in args. */
+        if (!strv_overlap(args,
+                          STRV_MAKE("0", "1", "2", "3", "4", "5", "6",
+                                    "s", "S", "q", "Q", "u", "U")))
+                return 0;
+
+        _cleanup_free_ char *a = NULL, *b = NULL, *c = NULL;
+        (void) terminal_urlify_man_full("shutdown", "8", /* suffix= */ NULL, &a);
+        (void) terminal_urlify_man_full("reboot", "8", /* suffix= */ NULL, &b);
+        (void) terminal_urlify_man_full("systemctl", "1", /* suffix= */ NULL, &c);
+
+        return log_error_errno(SYNTHETIC_ERRNO(EOPNOTSUPP),
+                               "Program 'systemd' called as 'init' with a legacy telinit command.\n"
+                               "Call %s, %s, or %s instead.",
+                               strnull(a), strnull(b), strnull(c));
+}
+
 static int parse_argv(int argc, char *argv[]) {
         bool user_arg_seen = false;
         int r;
@@ -1234,6 +1260,10 @@ static int parse_argv(int argc, char *argv[]) {
                         return 0;
                 }
 
+        r = redirect_telinit(argv, option_parser_get_args(&opts));
+        if (r < 0)
+                return r;
+
         if (option_parser_get_n_args(&opts) > 0 && getpid_cached() != 1)
                 /* Hmm, when we aren't run as init system let's complain about excess arguments */
                 return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Excess arguments.");
index 3328293c5d256d34c855a16c1bf008e88b59395d..c5ace49f608a0bf3515789a9f5bcadcf690cb9a3 100644 (file)
@@ -177,11 +177,11 @@ int terminal_urlify_path(const char *path, const char *text, char **ret) {
         return terminal_urlify(url, text, ret);
 }
 
-int terminal_urlify_man(const char *page, const char *section, char **ret) {
+int terminal_urlify_man_full(const char *page, const char *section, const char *suffix, char **ret) {
         const char *url, *text;
 
         url = strjoina("man:", page, "(", section, ")");
-        text = strjoina(page, "(", section, ") man page");
+        text = strjoina(page, "(", section, ")", suffix);
 
         return terminal_urlify(url, text, ret);
 }
index 6b759dd34694567c3f4a10ca26c3abe4246cf92e..44cc692011d4be81b0346e0e951f5797ff5b9cf1 100644 (file)
@@ -21,7 +21,10 @@ bool urlify_enabled(void);
 
 int terminal_urlify(const char *url, const char *text, char **ret);
 int terminal_urlify_path(const char *path, const char *text, char **ret);
-int terminal_urlify_man(const char *page, const char *section, char **ret);
+int terminal_urlify_man_full(const char *page, const char *section, const char *suffix, char **ret);
+static inline int terminal_urlify_man(const char *page, const char *section, char **ret) {
+        return terminal_urlify_man_full(page, section, " man page", ret);
+}
 
 typedef enum CatFlags {
         CAT_CONFIG_OFF          = 0,