From: Yu Watanabe Date: Sun, 20 Apr 2025 19:17:45 +0000 (+0900) Subject: core,initctl,systemctl: kill /dev/initctl support X-Git-Tag: v258-rc1~58^2~5 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=8ba48d4bf8b021369b535307665a8576c460a3ff;p=thirdparty%2Fsystemd.git core,initctl,systemctl: kill /dev/initctl support This also kills support for controlling system state through /sbin/init, initctl, and telinit. --- diff --git a/LICENSES/README.md b/LICENSES/README.md index 1df87508fb2..55203e98257 100644 --- a/LICENSES/README.md +++ b/LICENSES/README.md @@ -38,9 +38,7 @@ The following exceptions apply: verbatim from the Linux kernel source tree and are licensed under **GPL-2.0 WITH Linux-syscall-note** and are used within the scope of the Linux-syscall-note exception provisions - * the following sources are licensed under the **LGPL-2.0-or-later** license: - - src/basic/utf8.c - - src/shared/initreq.h + * the src/basic/utf8.c source is licensed under the **LGPL-2.0-or-later** license. * the src/basic/include/linux/bpf_insn.h header is copied from the Linux kernel source tree and is licensed under either **BSD-2-Clause** or **GPL-2.0-only**, and thus is included in the systemd build under the BSD-2-Clause license. diff --git a/man/rules/meson.build b/man/rules/meson.build index 38d608db482..246a059fa5a 100644 --- a/man/rules/meson.build +++ b/man/rules/meson.build @@ -997,10 +997,6 @@ manpages = [ ['systemd-import-generator', '8', [], ''], ['systemd-importd.service', '8', ['systemd-importd'], 'ENABLE_IMPORTD'], ['systemd-inhibit', '1', [], ''], - ['systemd-initctl.service', - '8', - ['systemd-initctl', 'systemd-initctl.socket'], - 'HAVE_SYSV_COMPAT'], ['systemd-integritysetup-generator', '8', [], 'HAVE_LIBCRYPTSETUP'], ['systemd-integritysetup@.service', '8', @@ -1248,7 +1244,6 @@ manpages = [ ['sysupdate.d', '5', [], 'ENABLE_SYSUPDATE'], ['sysupdate.features', '5', [], 'ENABLE_SYSUPDATE'], ['sysusers.d', '5', [], 'ENABLE_SYSUSERS'], - ['telinit', '8', [], 'HAVE_SYSV_COMPAT'], ['timedatectl', '1', [], 'ENABLE_TIMEDATECTL'], ['timesyncd.conf', '5', ['timesyncd.conf.d'], 'ENABLE_TIMESYNCD'], ['tmpfiles.d', '5', [], ''], diff --git a/man/systemd-initctl.service.xml b/man/systemd-initctl.service.xml deleted file mode 100644 index ad0d49de483..00000000000 --- a/man/systemd-initctl.service.xml +++ /dev/null @@ -1,49 +0,0 @@ - - - - - - - - systemd-initctl.service - systemd - - - - systemd-initctl.service - 8 - - - - systemd-initctl.service - systemd-initctl.socket - systemd-initctl - /dev/initctl compatibility - - - - systemd-initctl.service - systemd-initctl.socket - /usr/lib/systemd/systemd-initctl - - - - Description - - systemd-initctl is a system service - that implements compatibility with the - /dev/initctl FIFO file system object, as - implemented by the SysV init system. - systemd-initctl is automatically activated on - request and terminates itself when it is unused. - - - - See Also - - systemd1 - - - - diff --git a/man/telinit.xml b/man/telinit.xml deleted file mode 100644 index 7ffd8cd9b72..00000000000 --- a/man/telinit.xml +++ /dev/null @@ -1,151 +0,0 @@ - - - - - - - - telinit - systemd - - - - telinit - 8 - - - - telinit - Change SysV runlevel - - - - - telinit OPTIONS COMMAND - - - - - Description - - telinit may be used to change the SysV - system runlevel. Since the concept of SysV runlevels is obsolete - the runlevel requests will be transparently translated into - systemd unit activation requests. - - - - - Options - - The following options are understood: - - - - - - - - - - - - Do not send wall message before - reboot/halt/power-off. - - - - The following commands are understood: - - - - 0 - - Power-off the machine. This is translated into - an activation request for poweroff.target - and is equivalent to systemctl - poweroff. - - - - 6 - - Reboot the machine. This is translated into an - activation request for reboot.target and - is equivalent to systemctl - reboot. - - - - 2 - 3 - 4 - 5 - - Change the SysV runlevel. This is translated - into an activation request for - runlevel2.target, - runlevel3.target, … and is equivalent - to systemctl isolate runlevel2.target, - systemctl isolate runlevel3.target, - … - - - - 1 - s - S - - Change into system rescue mode. This is - translated into an activation request for - rescue.target and is equivalent to - systemctl rescue. - - - - q - Q - - Reload daemon configuration. This is - equivalent to systemctl - daemon-reload. - - - - u - U - - Serialize state, reexecute daemon and - deserialize state again. This is equivalent to - systemctl daemon-reexec. - - - - - - - Exit status - - On success, 0 is returned, a non-zero failure - code otherwise. - - - - Notes - - This is a legacy command available for compatibility only. - It should not be used anymore, as the concept of runlevels is - obsolete. - - - - See Also - - systemd1 - systemctl1 - wall1 - - - diff --git a/meson.build b/meson.build index f5362ece8a7..ac0ac59132c 100644 --- a/meson.build +++ b/meson.build @@ -2319,7 +2319,6 @@ subdir('src/hostname') subdir('src/hwdb') subdir('src/id128') subdir('src/import') -subdir('src/initctl') subdir('src/integritysetup') subdir('src/journal') subdir('src/journal-remote') diff --git a/src/core/main.c b/src/core/main.c index 668b103d6f3..6c44b4e00fd 100644 --- a/src/core/main.c +++ b/src/core/main.c @@ -1591,23 +1591,6 @@ static int fixup_environment(void) { return 0; } -static void redirect_telinit(int argc, char *argv[]) { - - /* This is compatibility support for SysV, where calling init as a user is identical to telinit. */ - -#if HAVE_SYSV_COMPAT - if (getpid_cached() == 1) - return; - - if (!invoked_as(argv, "init")) - return; - - execv(SYSTEMCTL_BINARY_PATH, argv); - log_error_errno(errno, "Failed to execute %s: %m", SYSTEMCTL_BINARY_PATH); - exit(EXIT_FAILURE); -#endif -} - static int become_shutdown(int objective, int retval) { static const char* const table[_MANAGER_OBJECTIVE_MAX] = { [MANAGER_EXIT] = "exit", @@ -3041,9 +3024,6 @@ int main(int argc, char *argv[]) { assert_se(argc > 0 && !isempty(argv[0])); - /* SysV compatibility: redirect init → telinit */ - redirect_telinit(argc, argv); - /* Take timestamps early on */ dual_timestamp_from_monotonic(&kernel_timestamp, 0); dual_timestamp_now(&userspace_timestamp); diff --git a/src/initctl/initctl.c b/src/initctl/initctl.c deleted file mode 100644 index a387fb0d283..00000000000 --- a/src/initctl/initctl.c +++ /dev/null @@ -1,351 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#include -#include -#include -#include -#include -#include - -#include "sd-bus.h" -#include "sd-daemon.h" - -#include "alloc-util.h" -#include "bus-error.h" -#include "bus-locator.h" -#include "bus-util.h" -#include "constants.h" -#include "daemon-util.h" -#include "fd-util.h" -#include "initreq.h" -#include "list.h" -#include "log.h" -#include "main-func.h" -#include "reboot-util.h" -#include "special.h" -#include "time-util.h" - -#define SERVER_FD_MAX 16 -#define TIMEOUT_MSEC ((int) (DEFAULT_EXIT_USEC/USEC_PER_MSEC)) - -typedef struct Fifo Fifo; - -typedef struct Server { - int epoll_fd; - - LIST_HEAD(Fifo, fifos); - unsigned n_fifos; - - sd_bus *bus; - - bool quit; -} Server; - -struct Fifo { - Server *server; - - int fd; - - struct init_request buffer; - size_t bytes_read; - - LIST_FIELDS(Fifo, fifo); -}; - -static const char *translate_runlevel(int runlevel, bool *isolate) { - static const struct { - const int runlevel; - const char *special; - bool isolate; - } table[] = { - { '0', SPECIAL_POWEROFF_TARGET, false }, - { '1', SPECIAL_RESCUE_TARGET, true }, - { 's', SPECIAL_RESCUE_TARGET, true }, - { 'S', SPECIAL_RESCUE_TARGET, true }, - { '2', SPECIAL_MULTI_USER_TARGET, true }, - { '3', SPECIAL_MULTI_USER_TARGET, true }, - { '4', SPECIAL_MULTI_USER_TARGET, true }, - { '5', SPECIAL_GRAPHICAL_TARGET, true }, - { '6', SPECIAL_REBOOT_TARGET, false }, - }; - - assert(isolate); - - FOREACH_ELEMENT(i, table) - if (i->runlevel == runlevel) { - *isolate = i->isolate; - if (runlevel == '6' && kexec_loaded()) - return SPECIAL_KEXEC_TARGET; - return i->special; - } - - return NULL; -} - -static int change_runlevel(Server *s, int runlevel) { - const char *target; - _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL; - const char *mode; - bool isolate = false; - int r; - - assert(s); - - target = translate_runlevel(runlevel, &isolate); - if (!target) { - log_warning("Got request for unknown runlevel %c, ignoring.", runlevel); - return 0; - } - - if (isolate) - mode = "isolate"; - else - mode = "replace-irreversibly"; - - log_debug("Requesting %s/start/%s", target, mode); - - r = bus_call_method(s->bus, bus_systemd_mgr, "StartUnit", &error, NULL, "ss", target, mode); - if (r < 0) - return log_error_errno(r, "Failed to change runlevel: %s", bus_error_message(&error, r)); - - return 0; -} - -static void request_process(Server *s, const struct init_request *req) { - assert(s); - assert(req); - - if (req->magic != INIT_MAGIC) { - log_error("Got initctl request with invalid magic. Ignoring."); - return; - } - - switch (req->cmd) { - - case INIT_CMD_RUNLVL: - if (!isprint(req->runlevel)) - log_error("Got invalid runlevel. Ignoring."); - else - switch (req->runlevel) { - - /* we are async anyway, so just use kill for reexec/reload */ - case 'u': - case 'U': - if (kill(1, SIGTERM) < 0) - log_error_errno(errno, "kill() failed: %m"); - - /* The bus connection will be - * terminated if PID 1 is reexecuted, - * hence let's just exit here, and - * rely on that we'll be restarted on - * the next request */ - s->quit = true; - break; - - case 'q': - case 'Q': - if (kill(1, SIGHUP) < 0) - log_error_errno(errno, "kill() failed: %m"); - break; - - default: - (void) change_runlevel(s, req->runlevel); - } - return; - - case INIT_CMD_POWERFAIL: - case INIT_CMD_POWERFAILNOW: - case INIT_CMD_POWEROK: - log_warning("Received UPS/power initctl request. This is not implemented in systemd. Upgrade your UPS daemon!"); - return; - - case INIT_CMD_CHANGECONS: - log_warning("Received console change initctl request. This is not implemented in systemd."); - return; - - case INIT_CMD_SETENV: - case INIT_CMD_UNSETENV: - log_warning("Received environment initctl request. This is not implemented in systemd."); - return; - - default: - log_warning("Received unknown initctl request. Ignoring."); - return; - } -} - -static int fifo_process(Fifo *f) { - ssize_t l; - - assert(f); - - errno = EIO; - l = read(f->fd, - ((uint8_t*) &f->buffer) + f->bytes_read, - sizeof(f->buffer) - f->bytes_read); - if (l <= 0) { - if (errno == EAGAIN) - return 0; - - return log_warning_errno(errno, "Failed to read from fifo: %m"); - } - - f->bytes_read += l; - assert(f->bytes_read <= sizeof(f->buffer)); - - if (f->bytes_read == sizeof(f->buffer)) { - request_process(f->server, &f->buffer); - f->bytes_read = 0; - } - - return 0; -} - -static Fifo* fifo_free(Fifo *f) { - if (!f) - return NULL; - - if (f->server) { - assert(f->server->n_fifos > 0); - f->server->n_fifos--; - LIST_REMOVE(fifo, f->server->fifos, f); - } - - if (f->fd >= 0) { - if (f->server) - (void) epoll_ctl(f->server->epoll_fd, EPOLL_CTL_DEL, f->fd, NULL); - - safe_close(f->fd); - } - - return mfree(f); -} -DEFINE_TRIVIAL_CLEANUP_FUNC(Fifo*, fifo_free); - -static void server_done(Server *s) { - assert(s); - - while (s->fifos) - fifo_free(s->fifos); - - s->epoll_fd = safe_close(s->epoll_fd); - s->bus = sd_bus_flush_close_unref(s->bus); -} - -static int server_init(Server *s, unsigned n_sockets) { - int r; - - /* This function will leave s partially initialized on failure. Caller needs to clean up. */ - - assert(s); - assert(n_sockets > 0); - - s->epoll_fd = epoll_create1(EPOLL_CLOEXEC); - if (s->epoll_fd < 0) - return log_error_errno(errno, "Failed to create epoll object: %m"); - - for (unsigned i = 0; i < n_sockets; i++) { - _cleanup_(fifo_freep) Fifo *f = NULL; - int fd = SD_LISTEN_FDS_START + i; - - r = sd_is_fifo(fd, NULL); - if (r < 0) - return log_error_errno(r, "Failed to determine file descriptor type: %m"); - if (!r) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), "Wrong file descriptor type."); - - f = new0(Fifo, 1); - if (!f) - return log_oom(); - - struct epoll_event ev = { - .events = EPOLLIN, - .data.ptr = f, - }; - - if (epoll_ctl(s->epoll_fd, EPOLL_CTL_ADD, fd, &ev) < 0) - return log_error_errno(errno, "Failed to add fifo fd to epoll object: %m"); - - f->fd = fd; - f->server = s; - LIST_PREPEND(fifo, s->fifos, TAKE_PTR(f)); - s->n_fifos++; - } - - r = bus_connect_system_systemd(&s->bus); - if (r < 0) - return log_error_errno(r, "Failed to get D-Bus connection: %m"); - - return 0; -} - -static int process_event(Server *s, struct epoll_event *ev) { - int r; - _cleanup_(fifo_freep) Fifo *f = NULL; - - assert(s); - assert(ev); - - if (!(ev->events & EPOLLIN)) - return log_info_errno(SYNTHETIC_ERRNO(EIO), - "Got invalid event from epoll. (3)"); - - f = (Fifo*) ev->data.ptr; - r = fifo_process(f); - if (r < 0) - return log_info_errno(r, "Got error on fifo: %m"); - - TAKE_PTR(f); - - return 0; -} - -static int run(int argc, char *argv[]) { - _cleanup_(server_done) Server server = { .epoll_fd = -EBADF }; - _unused_ _cleanup_(notify_on_cleanup) const char *notify_stop = NULL; - int r, n; - - if (argc > 1) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "This program does not take arguments."); - - log_setup(); - - umask(0022); - - n = sd_listen_fds(true); - if (n < 0) - return log_error_errno(n, "Failed to read listening file descriptors from environment: %m"); - - if (n <= 0 || n > SERVER_FD_MAX) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "No or too many file descriptors passed."); - - r = server_init(&server, (unsigned) n); - if (r < 0) - return r; - - notify_stop = notify_start(NOTIFY_READY_MESSAGE, NOTIFY_STOPPING_MESSAGE); - - while (!server.quit) { - struct epoll_event event; - int k; - - k = epoll_wait(server.epoll_fd, &event, 1, TIMEOUT_MSEC); - if (k < 0) { - if (errno == EINTR) - continue; - return log_error_errno(errno, "epoll_wait() failed: %m"); - } - if (k == 0) - break; - - r = process_event(&server, &event); - if (r < 0) - return r; - } - - return 0; -} - -DEFINE_MAIN_FUNCTION(run); diff --git a/src/initctl/meson.build b/src/initctl/meson.build deleted file mode 100644 index c9fddc99031..00000000000 --- a/src/initctl/meson.build +++ /dev/null @@ -1,9 +0,0 @@ -# SPDX-License-Identifier: LGPL-2.1-or-later - -executables += [ - libexec_template + { - 'name' : 'systemd-initctl', - 'conditions' : ['HAVE_SYSV_COMPAT'], - 'sources' : files('initctl.c'), - }, -] diff --git a/src/shared/initreq.h b/src/shared/initreq.h deleted file mode 100644 index 8d2e08c6c9f..00000000000 --- a/src/shared/initreq.h +++ /dev/null @@ -1,59 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.0-or-later */ -/* - * Copyright (C) 1995-2004 Miquel van Smoorenburg - * Version: @(#)initreq.h 1.28 31-Mar-2004 MvS - */ - -#pragma once - -#include "forward.h" - -#if defined(__FreeBSD_kernel__) -# define INIT_FIFO "/etc/.initctl" -#else -# define INIT_FIFO "/dev/initctl" -#endif - -#define INIT_MAGIC 0x03091969 -#define INIT_CMD_START 0 -#define INIT_CMD_RUNLVL 1 -#define INIT_CMD_POWERFAIL 2 -#define INIT_CMD_POWERFAILNOW 3 -#define INIT_CMD_POWEROK 4 -#define INIT_CMD_BSD 5 -#define INIT_CMD_SETENV 6 -#define INIT_CMD_UNSETENV 7 - -#define INIT_CMD_CHANGECONS 12345 -/* - * This is what BSD 4.4 uses when talking to init. - * Linux doesn't use this right now. - */ -struct init_request_bsd { - char gen_id[8]; /* Beats me.. telnetd uses "fe" */ - char tty_id[16]; /* Tty name minus /dev/tty */ - char host[HOST_NAME_MAX]; /* Hostname */ - char term_type[16]; /* Terminal type */ - int signal; /* Signal to send */ - int pid; /* Process to send to */ - char exec_name[128]; /* Program to execute */ - char reserved[128]; /* For future expansion. */ -}; - -/* - * Because of legacy interfaces, "runlevel" and "sleeptime" - * aren't in a separate struct in the union. - * - * The weird sizes are because init expects the whole - * struct to be 384 bytes. - */ -struct init_request { - int magic; /* Magic number */ - int cmd; /* What kind of request */ - int runlevel; /* Runlevel to change to */ - int sleeptime; /* Time between TERM and KILL */ - union { - struct init_request_bsd bsd; - char data[368]; - } i; -}; diff --git a/src/systemctl/meson.build b/src/systemctl/meson.build index ca83fc89370..2e207966da8 100644 --- a/src/systemctl/meson.build +++ b/src/systemctl/meson.build @@ -33,7 +33,6 @@ systemctl_sources = files( systemctl_extract_sources = files( 'systemctl-compat-halt.c', 'systemctl-compat-shutdown.c', - 'systemctl-compat-telinit.c', 'systemctl-daemon-reload.c', 'systemctl-logind.c', 'systemctl-start-unit.c', @@ -73,8 +72,7 @@ executables += [ }, ] -foreach alias : (['halt', 'poweroff', 'reboot', 'shutdown'] + - (conf.get('HAVE_SYSV_COMPAT') == 1 ? ['telinit'] : [])) +foreach alias : ['halt', 'poweroff', 'reboot', 'shutdown'] install_symlink(alias, pointing_to : sbin_to_bin + 'systemctl', install_dir : sbindir) diff --git a/src/systemctl/systemctl-compat-halt.c b/src/systemctl/systemctl-compat-halt.c index c360a8d0073..614216fd085 100644 --- a/src/systemctl/systemctl-compat-halt.c +++ b/src/systemctl/systemctl-compat-halt.c @@ -11,7 +11,6 @@ #include "reboot-util.h" #include "systemctl.h" #include "systemctl-compat-halt.h" -#include "systemctl-compat-telinit.h" #include "systemctl-logind.h" #include "systemctl-start-unit.h" #include "systemctl-util.h" @@ -171,7 +170,7 @@ int halt_main(void) { arg_no_block = true; if (!arg_dry_run) - return start_with_fallback(); + return verb_start(0, NULL, NULL); } r = must_be_root(); diff --git a/src/systemctl/systemctl-compat-telinit.c b/src/systemctl/systemctl-compat-telinit.c deleted file mode 100644 index c8794ef2559..00000000000 --- a/src/systemctl/systemctl-compat-telinit.c +++ /dev/null @@ -1,214 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ - -#include -#include - -#include "alloc-util.h" -#include "fd-util.h" -#include "initreq.h" -#include "io-util.h" -#include "log.h" -#include "pretty-print.h" -#include "strv.h" -#include "systemctl.h" -#include "systemctl-compat-telinit.h" -#include "systemctl-daemon-reload.h" -#include "systemctl-start-unit.h" - -static int telinit_help(void) { - _cleanup_free_ char *link = NULL; - int r; - - r = terminal_urlify_man("telinit", "8", &link); - if (r < 0) - return log_oom(); - - printf("%s [OPTIONS...] COMMAND\n\n" - "%sSend control commands to the init daemon.%s\n" - "\nCommands:\n" - " 0 Power-off the machine\n" - " 6 Reboot the machine\n" - " 2, 3, 4, 5 Start runlevelX.target unit\n" - " 1, s, S Enter rescue mode\n" - " q, Q Reload init daemon configuration\n" - " u, U Reexecute init daemon\n" - "\nOptions:\n" - " --help Show this help\n" - " --no-wall Don't send wall message before halt/power-off/reboot\n" - "\nSee the %s for details.\n", - program_invocation_short_name, - ansi_highlight(), - ansi_normal(), - link); - - return 0; -} - -int telinit_parse_argv(int argc, char *argv[]) { - enum { - ARG_HELP = 0x100, - ARG_NO_WALL - }; - - static const struct option options[] = { - { "help", no_argument, NULL, ARG_HELP }, - { "no-wall", no_argument, NULL, ARG_NO_WALL }, - {} - }; - - static const struct { - char from; - enum action to; - } table[] = { - { '0', ACTION_POWEROFF }, - { '6', ACTION_REBOOT }, - { '1', ACTION_RESCUE }, - { '2', ACTION_RUNLEVEL2 }, - { '3', ACTION_RUNLEVEL3 }, - { '4', ACTION_RUNLEVEL4 }, - { '5', ACTION_RUNLEVEL5 }, - { 's', ACTION_RESCUE }, - { 'S', ACTION_RESCUE }, - { 'q', ACTION_RELOAD }, - { 'Q', ACTION_RELOAD }, - { 'u', ACTION_REEXEC }, - { 'U', ACTION_REEXEC } - }; - - unsigned i; - int c; - - assert(argc >= 0); - assert(argv); - - while ((c = getopt_long(argc, argv, "", options, NULL)) >= 0) - switch (c) { - - case ARG_HELP: - return telinit_help(); - - case ARG_NO_WALL: - arg_no_wall = true; - break; - - case '?': - return -EINVAL; - - default: - assert_not_reached(); - } - - if (optind >= argc) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "%s: required argument missing.", - program_invocation_short_name); - - if (optind + 1 < argc) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Too many arguments."); - - if (strlen(argv[optind]) != 1) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Expected single character argument."); - - for (i = 0; i < ELEMENTSOF(table); i++) - if (table[i].from == argv[optind][0]) - break; - - if (i >= ELEMENTSOF(table)) - return log_error_errno(SYNTHETIC_ERRNO(EINVAL), - "Unknown command '%s'.", argv[optind]); - - arg_action = table[i].to; - - optind++; - - return 1; -} - -#if HAVE_SYSV_COMPAT -static int talk_initctl(char rl) { - _cleanup_close_ int fd = -EBADF; - const char *path; - int r; - - /* Try to switch to the specified SysV runlevel. Returns == 0 if the operation does not apply on this - * system, and > 0 on success. */ - - if (rl == 0) - return 0; - - FOREACH_STRING(_path, "/run/initctl", "/dev/initctl") { - path = _path; - - fd = open(path, O_WRONLY|O_NONBLOCK|O_CLOEXEC|O_NOCTTY); - if (fd < 0 && errno != ENOENT) - return log_error_errno(errno, "Failed to open %s: %m", path); - if (fd >= 0) - break; - } - if (fd < 0) - return 0; - - struct init_request request = { - .magic = INIT_MAGIC, - .sleeptime = 0, - .cmd = INIT_CMD_RUNLVL, - .runlevel = rl, - }; - - r = loop_write(fd, &request, sizeof(request)); - if (r < 0) - return log_error_errno(r, "Failed to write to %s: %m", path); - - return 1; -} - -static int action_to_runlevel(void) { - static const char table[_ACTION_MAX] = { - [ACTION_HALT] = '0', - [ACTION_POWEROFF] = '0', - [ACTION_REBOOT] = '6', - [ACTION_RUNLEVEL2] = '2', - [ACTION_RUNLEVEL3] = '3', - [ACTION_RUNLEVEL4] = '4', - [ACTION_RUNLEVEL5] = '5', - [ACTION_RESCUE] = '1' - }; - - assert(arg_action >= 0 && arg_action < _ACTION_MAX); - return table[arg_action]; -} -#endif - -int start_with_fallback(void) { - int r; - - /* First, try systemd via D-Bus. */ - r = verb_start(0, NULL, NULL); - if (r == 0) - return 0; - -#if HAVE_SYSV_COMPAT - /* Nothing else worked, so let's try /dev/initctl */ - if (talk_initctl(action_to_runlevel()) > 0) - return 0; -#endif - - return log_error_errno(r, "Failed to talk to init daemon: %m"); -} - -int reload_with_fallback(void) { - - assert(IN_SET(arg_action, ACTION_RELOAD, ACTION_REEXEC)); - - /* First, try systemd via D-Bus */ - if (daemon_reload(arg_action, /* graceful= */ true) > 0) - return 0; - - /* That didn't work, so let's try signals */ - if (kill(1, arg_action == ACTION_RELOAD ? SIGHUP : SIGTERM) < 0) - return log_error_errno(errno, "kill() failed: %m"); - - return 0; -} diff --git a/src/systemctl/systemctl-compat-telinit.h b/src/systemctl/systemctl-compat-telinit.h deleted file mode 100644 index 1a2bcd44052..00000000000 --- a/src/systemctl/systemctl-compat-telinit.h +++ /dev/null @@ -1,6 +0,0 @@ -/* SPDX-License-Identifier: LGPL-2.1-or-later */ -#pragma once - -int telinit_parse_argv(int argc, char *argv[]); -int start_with_fallback(void); -int reload_with_fallback(void); diff --git a/src/systemctl/systemctl-main.c b/src/systemctl/systemctl-main.c index 2e2dcd3e550..c0596cfb861 100644 --- a/src/systemctl/systemctl-main.c +++ b/src/systemctl/systemctl-main.c @@ -16,7 +16,6 @@ #include "systemctl-cancel-job.h" #include "systemctl-clean-or-freeze.h" #include "systemctl-compat-halt.h" -#include "systemctl-compat-telinit.h" #include "systemctl-daemon-reload.h" #include "systemctl-edit.h" #include "systemctl-enable.h" @@ -213,19 +212,6 @@ static int run(int argc, char *argv[]) { r = halt_main(); break; - case ACTION_RUNLEVEL2: - case ACTION_RUNLEVEL3: - case ACTION_RUNLEVEL4: - case ACTION_RUNLEVEL5: - case ACTION_RESCUE: - r = start_with_fallback(); - break; - - case ACTION_RELOAD: - case ACTION_REEXEC: - r = reload_with_fallback(); - break; - case ACTION_CANCEL_SHUTDOWN: r = logind_cancel_shutdown(); break; @@ -235,6 +221,9 @@ static int run(int argc, char *argv[]) { r = logind_show_shutdown(); break; + case ACTION_RESCUE: + case ACTION_RELOAD: + case ACTION_REEXEC: case ACTION_EXIT: case ACTION_SLEEP: case ACTION_SUSPEND: diff --git a/src/systemctl/systemctl-start-unit.c b/src/systemctl/systemctl-start-unit.c index 7ff5548ba85..aa0882f7579 100644 --- a/src/systemctl/systemctl-start-unit.c +++ b/src/systemctl/systemctl-start-unit.c @@ -232,10 +232,6 @@ const struct action_metadata action_table[_ACTION_MAX] = { [ACTION_REBOOT] = { SPECIAL_REBOOT_TARGET, "reboot", "replace-irreversibly" }, [ACTION_KEXEC] = { SPECIAL_KEXEC_TARGET, "kexec", "replace-irreversibly" }, [ACTION_SOFT_REBOOT] = { SPECIAL_SOFT_REBOOT_TARGET, "soft-reboot", "replace-irreversibly" }, - [ACTION_RUNLEVEL2] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" }, - [ACTION_RUNLEVEL3] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" }, - [ACTION_RUNLEVEL4] = { SPECIAL_MULTI_USER_TARGET, NULL, "isolate" }, - [ACTION_RUNLEVEL5] = { SPECIAL_GRAPHICAL_TARGET, NULL, "isolate" }, [ACTION_RESCUE] = { SPECIAL_RESCUE_TARGET, "rescue", "isolate" }, [ACTION_EMERGENCY] = { SPECIAL_EMERGENCY_TARGET, "emergency", "isolate" }, [ACTION_DEFAULT] = { SPECIAL_DEFAULT_TARGET, "default", "isolate" }, diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c index 439e11699f3..2eaf62a4105 100644 --- a/src/systemctl/systemctl.c +++ b/src/systemctl/systemctl.c @@ -25,7 +25,6 @@ #include "systemctl.h" #include "systemctl-compat-halt.h" #include "systemctl-compat-shutdown.h" -#include "systemctl-compat-telinit.h" #include "systemctl-logind.h" #include "time-util.h" @@ -1123,24 +1122,6 @@ int systemctl_dispatch_parse_argv(int argc, char *argv[]) { } else if (invoked_as(argv, "shutdown")) { arg_action = ACTION_POWEROFF; return shutdown_parse_argv(argc, argv); - - } else if (invoked_as(argv, "init")) { - - /* Matches invocations as "init" as well as "telinit", which are synonymous when run - * as PID != 1 on SysV. - * - * On SysV "telinit" was the official command to communicate with PID 1, but "init" would - * redirect itself to "telinit" if called with PID != 1. We follow the same logic here still, - * though we add one level of indirection, as we implement "telinit" in "systemctl". Hence, - * for us if you invoke "init" you get "systemd", but it will execve() "systemctl" - * immediately with argv[] unmodified if PID is != 1. If you invoke "telinit" you directly - * get "systemctl". In both cases we shall do the same thing, which is why we do - * invoked_as(argv, "init") here, as a quick way to match both. - * - * Also see redirect_telinit() in src/core/main.c. */ - - arg_action = _ACTION_INVALID; /* telinit_parse_argv() will figure out the actual action we'll execute */ - return telinit_parse_argv(argc, argv); } arg_action = ACTION_SYSTEMCTL; diff --git a/src/systemctl/systemctl.h b/src/systemctl/systemctl.h index 91702d1252d..5cbdfea48c2 100644 --- a/src/systemctl/systemctl.h +++ b/src/systemctl/systemctl.h @@ -16,10 +16,6 @@ enum action { ACTION_HIBERNATE, ACTION_HYBRID_SLEEP, ACTION_SUSPEND_THEN_HIBERNATE, - ACTION_RUNLEVEL2, - ACTION_RUNLEVEL3, - ACTION_RUNLEVEL4, - ACTION_RUNLEVEL5, ACTION_RESCUE, ACTION_EMERGENCY, ACTION_DEFAULT, diff --git a/tools/command_ignorelist b/tools/command_ignorelist index 6639fb08bd0..72544ae0ddf 100644 --- a/tools/command_ignorelist +++ b/tools/command_ignorelist @@ -400,15 +400,6 @@ systemd.xml ./refsect1[title="Kernel Command Line"]/variablelist/varlistentry[te systemd.xml ./refsect1[title="Kernel Command Line"]/variablelist/varlistentry[term="systemd.setenv="] systemd.xml ./refsect1[title="Files"]/variablelist/varlistentry[term="/run/systemd/notify"] systemd.xml ./refsect1[title="Files"]/variablelist/varlistentry[term="/run/systemd/private"] -systemd.xml ./refsect1[title="Files"]/variablelist/varlistentry[term="/dev/initctl"] -telinit.xml ./refsect1[title="Options"]/variablelist[1]/varlistentry[term="--help"] -telinit.xml ./refsect1[title="Options"]/variablelist[1]/varlistentry[term="--no-wall"] -telinit.xml ./refsect1[title="Options"]/variablelist[2]/varlistentry[term="0"] -telinit.xml ./refsect1[title="Options"]/variablelist[2]/varlistentry[term="6"] -telinit.xml ./refsect1[title="Options"]/variablelist[2]/varlistentry[term="2"] -telinit.xml ./refsect1[title="Options"]/variablelist[2]/varlistentry[term="1"] -telinit.xml ./refsect1[title="Options"]/variablelist[2]/varlistentry[term="q"] -telinit.xml ./refsect1[title="Options"]/variablelist[2]/varlistentry[term="u"] tmpfiles.d.xml ./refsect1[title="Configuration File Format"]/refsect2[title="Type"]/variablelist/varlistentry[term="f"] tmpfiles.d.xml ./refsect1[title="Configuration File Format"]/refsect2[title="Type"]/variablelist/varlistentry[term="w"] tmpfiles.d.xml ./refsect1[title="Configuration File Format"]/refsect2[title="Type"]/variablelist/varlistentry[term="d"] diff --git a/units/meson.build b/units/meson.build index 3f3b047f3c1..bc67a6ee8ab 100644 --- a/units/meson.build +++ b/units/meson.build @@ -412,15 +412,6 @@ units = [ 'conditions' : ['ENABLE_IMPORTD'], 'symlinks' : ['sysinit.target.wants/'], }, - { - 'file' : 'systemd-initctl.service.in', - 'conditions' : ['HAVE_SYSV_COMPAT'], - }, - { - 'file' : 'systemd-initctl.socket', - 'conditions' : ['HAVE_SYSV_COMPAT'], - 'symlinks' : ['sockets.target.wants/'], - }, { 'file' : 'systemd-journal-catalog-update.service', 'symlinks' : ['sysinit.target.wants/'], diff --git a/units/systemd-initctl.service.in b/units/systemd-initctl.service.in deleted file mode 100644 index 6a19058186c..00000000000 --- a/units/systemd-initctl.service.in +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: LGPL-2.1-or-later -# -# This file is part of systemd. -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -[Unit] -Description=initctl Compatibility Daemon -Documentation=man:systemd-initctl.service(8) -DefaultDependencies=no - -[Service] -ExecStart={{LIBEXECDIR}}/systemd-initctl -NoNewPrivileges=yes -NotifyAccess=all -SystemCallArchitectures=native diff --git a/units/systemd-initctl.socket b/units/systemd-initctl.socket deleted file mode 100644 index 410213162da..00000000000 --- a/units/systemd-initctl.socket +++ /dev/null @@ -1,19 +0,0 @@ -# SPDX-License-Identifier: LGPL-2.1-or-later -# -# This file is part of systemd. -# -# systemd is free software; you can redistribute it and/or modify it -# under the terms of the GNU Lesser General Public License as published by -# the Free Software Foundation; either version 2.1 of the License, or -# (at your option) any later version. - -[Unit] -Description=initctl Compatibility Named Pipe -Documentation=man:systemd-initctl.socket(8) -DefaultDependencies=no -Before=sockets.target - -[Socket] -ListenFIFO=/run/initctl -Symlinks=/dev/initctl -SocketMode=0600