Drop support for sysvinit scripts

As announced by a few releases now, finally drop support for
sysvinit scripts.
Keep rc-local generator for now, as it's really a distinct
feature even though from the same era.
This commit is contained in:
Luca Boccassi
2026-01-06 10:34:02 +01:00
parent 5b3a86f6c3
commit 986fee6217
28 changed files with 8 additions and 1874 deletions
-1
View File
@@ -36,7 +36,6 @@ systemctl_extract_sources = files(
'systemctl-daemon-reload.c',
'systemctl-logind.c',
'systemctl-start-unit.c',
'systemctl-sysv-compat.c',
'systemctl-util.c',
'systemctl.c',
)
-5
View File
@@ -19,7 +19,6 @@
#include "systemctl-daemon-reload.h"
#include "systemctl-enable.h"
#include "systemctl-start-unit.h"
#include "systemctl-sysv-compat.h"
#include "systemctl-util.h"
#include "unit-name.h"
#include "verbs.h"
@@ -97,10 +96,6 @@ int verb_enable(int argc, char *argv[], void *userdata) {
if (r < 0)
return r;
r = enable_sysv_units(verb, names);
if (r < 0)
return r;
/* If the operation was fully executed by the SysV compat, let's finish early */
if (strv_isempty(names)) {
if (arg_no_reload || install_client_side() != INSTALL_CLIENT_SIDE_NO)
+1 -9
View File
@@ -12,7 +12,6 @@
#include "strv.h"
#include "systemctl.h"
#include "systemctl-is-enabled.h"
#include "systemctl-sysv-compat.h"
#include "systemctl-util.h"
static int show_installation_targets_client_side(const char *name) {
@@ -68,20 +67,13 @@ static int show_installation_targets(sd_bus *bus, const char *name) {
int verb_is_enabled(int argc, char *argv[], void *userdata) {
_cleanup_strv_free_ char **names = NULL;
bool not_found, enabled;
bool not_found = true, enabled = false;
int r;
r = mangle_names("to check", strv_skip(argv, 1), &names);
if (r < 0)
return r;
r = enable_sysv_units(argv[0], names);
if (r < 0)
return r;
not_found = r == 0; /* Doesn't have SysV support or SYSV_UNIT_NOT_FOUND */
enabled = r == SYSV_UNIT_ENABLED;
if (install_client_side() != INSTALL_CLIENT_SIDE_NO)
STRV_FOREACH(name, names) {
UnitFileState state;
-167
View File
@@ -1,167 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#include <stdlib.h>
#include <unistd.h>
#include "env-util.h"
#include "install.h"
#include "log.h"
#include "path-lookup.h"
#include "path-util.h"
#include "pidref.h"
#include "process-util.h"
#include "string-util.h"
#include "strv.h"
#include "systemctl.h"
#include "systemctl-sysv-compat.h"
int enable_sysv_units(const char *verb, char **args) {
int r = 0;
#if HAVE_SYSV_COMPAT
_cleanup_(lookup_paths_done) LookupPaths paths = {};
unsigned f = 0;
SysVUnitEnableState enable_state = SYSV_UNIT_NOT_FOUND;
/* Processes all SysV units, and reshuffles the array so that afterwards only the native units remain */
if (arg_runtime_scope != RUNTIME_SCOPE_SYSTEM)
return 0;
if (getenv_bool("SYSTEMCTL_SKIP_SYSV") > 0)
return 0;
if (!STR_IN_SET(verb,
"enable",
"disable",
"is-enabled"))
return 0;
r = lookup_paths_init_or_warn(&paths, arg_runtime_scope, LOOKUP_PATHS_EXCLUDE_GENERATED, arg_root);
if (r < 0)
return r;
r = 0;
while (args[f]) {
const char *argv[] = {
LIBEXECDIR "/systemd-sysv-install",
NULL, /* --root= */
NULL, /* verb */
NULL, /* service */
NULL,
};
_cleanup_free_ char *p = NULL, *q = NULL, *l = NULL, *v = NULL, *b = NULL;
bool found_native = false, found_sysv;
const char *name;
unsigned c = 1;
int j;
name = args[f++];
if (!endswith(name, ".service"))
continue;
if (path_is_absolute(name))
continue;
j = unit_file_exists(arg_runtime_scope, &paths, name);
if (j < 0 && !IN_SET(j, -ELOOP, -ERFKILL, -EADDRNOTAVAIL))
return log_error_errno(j, "Failed to look up unit file state: %m");
found_native = j != 0;
/* If we have both a native unit and a SysV script, enable/disable them both (below); for
* is-enabled, prefer the native unit */
if (found_native && streq(verb, "is-enabled"))
continue;
p = path_join(arg_root, SYSTEM_SYSVINIT_PATH, name);
if (!p)
return log_oom();
p[strlen(p) - STRLEN(".service")] = 0;
found_sysv = access(p, F_OK) >= 0;
if (!found_sysv)
continue;
if (!arg_quiet) {
if (found_native)
log_info("Synchronizing state of %s with SysV service script with %s.", name, argv[0]);
else
log_info("%s is not a native service, redirecting to systemd-sysv-install.", name);
}
if (!isempty(arg_root)) {
q = strjoin("--root=", arg_root);
if (!q)
return log_oom();
argv[c++] = q;
}
/* Let's copy the verb, since it's still pointing directly into the original argv[] array we
* got passed, but safe_fork() is likely going to rewrite that for the new child */
v = strdup(verb);
if (!v)
return log_oom();
j = path_extract_filename(p, &b);
if (j < 0)
return log_error_errno(j, "Failed to extract file name from '%s': %m", p);
argv[c++] = v;
argv[c++] = b;
argv[c] = NULL;
l = strv_join((char**)argv, " ");
if (!l)
return log_oom();
if (!arg_quiet)
log_info("Executing: %s", l);
_cleanup_(pidref_done) PidRef pidref = PIDREF_NULL;
j = pidref_safe_fork("(sysv-install)", FORK_RESET_SIGNALS|FORK_DEATHSIG_SIGTERM|FORK_RLIMIT_NOFILE_SAFE|FORK_LOG, &pidref);
if (j < 0)
return j;
if (j == 0) {
/* Child */
execv(argv[0], (char**) argv);
log_error_errno(errno, "Failed to execute %s: %m", argv[0]);
_exit(EXIT_FAILURE);
}
j = pidref_wait_for_terminate_and_check("sysv-install", &pidref, WAIT_LOG_ABNORMAL);
if (j < 0)
return j;
if (streq(verb, "is-enabled")) {
if (j == EXIT_SUCCESS) {
if (!arg_quiet)
puts("enabled");
enable_state = SYSV_UNIT_ENABLED;
} else {
if (!arg_quiet)
puts("disabled");
if (enable_state != SYSV_UNIT_ENABLED)
enable_state = SYSV_UNIT_DISABLED;
}
} else if (j != EXIT_SUCCESS)
return -EBADE; /* We don't warn here, under the assumption the script already showed an explanation */
if (found_native)
continue;
/* Remove this entry, so that we don't try enabling it as native unit */
assert(f > 0);
f--;
assert(args[f] == name);
strv_remove(args + f, name);
}
if (streq(verb, "is-enabled"))
return enable_state;
#endif
return r;
}
-10
View File
@@ -1,10 +0,0 @@
/* SPDX-License-Identifier: LGPL-2.1-or-later */
#pragma once
typedef enum SysVUnitEnableState {
SYSV_UNIT_NOT_FOUND = 0,
SYSV_UNIT_DISABLED,
SYSV_UNIT_ENABLED,
} SysVUnitEnableState;
int enable_sysv_units(const char *verb, char **args);
@@ -1,51 +0,0 @@
#!/bin/sh
# SPDX-License-Identifier: MIT-0
#
# This script is called by "systemctl enable/disable" when the given unit is a
# SysV init.d script. It needs to call the distribution's mechanism for
# enabling/disabling those, such as chkconfig, update-rc.d, or similar. This
# can optionally take a --root argument for enabling a SysV init script
# in a chroot or similar.
set -e
usage() {
echo "Usage: $0 [--root=path] enable|disable|is-enabled <sysv script name>" >&2
exit 1
}
unset ROOT
# parse options
eval set -- "$(getopt -o r: --long root: -- "$@")"
while true; do
case "$1" in
-r|--root)
ROOT="$2"
shift 2 ;;
--) shift ; break ;;
*) usage ;;
esac
done
NAME="$2"
[ -n "$NAME" ] || usage
case "$1" in
enable)
# call the command to enable SysV init script $NAME here
# (consider optional $ROOT)
echo "IMPLEMENT ME: enabling SysV init.d script $NAME"
;;
disable)
# call the command to disable SysV init script $NAME here
# (consider optional $ROOT)
echo "IMPLEMENT ME: disabling SysV init.d script $NAME"
;;
is-enabled)
# exit with 0 if $NAME is enabled, non-zero if it is disabled
# (consider optional $ROOT)
echo "IMPLEMENT ME: checking SysV init.d script $NAME"
;;
*)
usage ;;
esac