]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
Drop support for sysvinit scripts 39770/head
authorLuca Boccassi <luca.boccassi@gmail.com>
Mon, 17 Nov 2025 14:44:18 +0000 (14:44 +0000)
committerLuca Boccassi <luca.boccassi@gmail.com>
Tue, 6 Jan 2026 09:34:02 +0000 (10:34 +0100)
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.

28 files changed:
.github/ISSUE_TEMPLATE/bug_report.yml
.github/ISSUE_TEMPLATE/feature_request.yml
LICENSES/README.md
docs/DISTRO_PORTING.md
docs/ENVIRONMENT.md
docs/sysvinit/README.in [deleted file]
docs/sysvinit/meson.build [deleted file]
man/rules/meson.build
man/systemd-sysv-generator.xml [deleted file]
man/systemd.generator.xml
man/systemd.service.xml
meson.build
meson_options.txt
mkosi/mkosi.images/build/mkosi.conf.d/arch/mkosi.build.chroot
mkosi/mkosi.images/build/mkosi.conf.d/opensuse/mkosi.build.chroot
src/basic/build.c
src/systemctl/meson.build
src/systemctl/systemctl-enable.c
src/systemctl/systemctl-is-enabled.c
src/systemctl/systemctl-sysv-compat.c [deleted file]
src/systemctl/systemctl-sysv-compat.h [deleted file]
src/systemctl/systemd-sysv-install.SKELETON [deleted file]
src/sysv-generator/meson.build [deleted file]
src/sysv-generator/sysv-generator.c [deleted file]
test/meson.build
test/sysv-generator-test.py [deleted file]
test/units/TEST-26-SYSTEMCTL.sh
tmpfiles.d/legacy.conf.in

index 416cb76f4013617d435a5a22552db5b336bc2df7..1997e3bc7f1e96e1c6be4aa95316c4d8b0efe3c0 100644 (file)
@@ -133,7 +133,6 @@ body:
         - 'systemd-sysctl'
         - 'systemd-sysext'
         - 'systemd-sysusers'
-        - 'systemd-sysv-generator'
         - 'systemd-timedate'
         - 'systemd-timesync'
         - 'systemd-tmpfiles'
index fc66c1ab43f5cb095bf072d6fcf357c2186a9506..f6f8ac0f75210a04cb4812e4525d74970e1f15b7 100644 (file)
@@ -74,7 +74,6 @@ body:
         - 'systemd-sysctl'
         - 'systemd-sysext'
         - 'systemd-sysusers'
-        - 'systemd-sysv-generator'
         - 'systemd-timedate'
         - 'systemd-timesync'
         - 'systemd-tmpfiles'
index f25e82119f1ce0b3ffe592238c757fc712796431..5522a08e109109c204e2283b190d048ece2b23a9 100644 (file)
@@ -56,7 +56,6 @@ The following exceptions apply:
    - src/basic/siphash24.h
  * the following sources are licensed under the **MIT-0** license:
    - all examples under man/
-   - src/systemctl/systemd-sysv-install.SKELETON
    - config files and examples under /network
  * the following sources are under **Public Domain** (LicenseRef-murmurhash2-public-domain):
    - src/basic/MurmurHash2.c
index aeccf0df7c7b79eb5bd267c18243aaa1ed5ee6b2..fc25d91d70c9b49408e3d1b844a4825908dfe7aa 100644 (file)
@@ -13,8 +13,6 @@ You need to make the follow changes to adapt systemd to your distribution:
 
 1. Find the right configure parameters for:
 
-   * `-Dsysvinit-path=`
-   * `-Dsysvrcnd-path=`
    * `-Drc-local=`
    * `-Dloadkeys-path=`
    * `-Dsetfont-path=`
index b64d8b0f20b695d354b6afd51b587ad52e3f8024..5897ede77c96476ffcef0e9354036b6d80d7516e 100644 (file)
@@ -449,14 +449,6 @@ All tools:
   as a child process by another tool, such as package managers running it in a
   postinstall script.
 
-`systemd-sysv-generator`:
-
-* `$SYSTEMD_SYSVINIT_PATH` — Controls where `systemd-sysv-generator` looks for
-  SysV init scripts.
-
-* `$SYSTEMD_SYSVRCND_PATH` — Controls where `systemd-sysv-generator` looks for
-  SysV init script runlevel link farms.
-
 systemd tests:
 
 * `$SYSTEMD_TEST_DATA` — override the location of test data. This is useful if
diff --git a/docs/sysvinit/README.in b/docs/sysvinit/README.in
deleted file mode 100644 (file)
index ace1aba..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-You are looking for the traditional init scripts in {{ SYSTEM_SYSVINIT_PATH }},
-and they are gone?
-
-Here's an explanation on what's going on:
-
-You are running a systemd-based OS where traditional init scripts have
-been replaced by native systemd services files. Service files provide
-very similar functionality to init scripts. To make use of service
-files simply invoke "systemctl", which will output a list of all
-currently running services (and other units). Use "systemctl
-list-unit-files" to get a listing of all known unit files, including
-stopped, disabled and masked ones. Use "systemctl start
-foobar.service" and "systemctl stop foobar.service" to start or stop a
-service, respectively. For further details, please refer to
-systemctl(1).
-
-Note that traditional init scripts continue to function on a systemd
-system. An init script {{ SYSTEM_SYSVINIT_PATH }}/foobar is implicitly mapped
-into a service unit foobar.service during system initialization.
-
-Thank you!
-
-Further reading:
-        man:systemctl(1)
-        man:systemd(1)
-        https://0pointer.de/blog/projects/systemd-for-admins-3.html
-        https://systemd.io/INCOMPATIBILITIES
diff --git a/docs/sysvinit/meson.build b/docs/sysvinit/meson.build
deleted file mode 100644 (file)
index 9dd9ac8..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-custom_target(
-        input : 'README.in',
-        output : 'README',
-        command : [jinja2_cmdline, '@INPUT@', '@OUTPUT@'],
-        install : conf.get('HAVE_SYSV_COMPAT') == 1,
-        install_dir : sysvinit_path)
index 6bc89398c830534be62a80767414b9ba2a508cbe..4868a227090f7af1809aca647f5b1b446c47f2e0 100644 (file)
@@ -1190,7 +1190,6 @@ manpages = [
   ['systemd-sysupdated'],
   'ENABLE_SYSUPDATED'],
  ['systemd-sysusers', '8', ['systemd-sysusers.service'], ''],
- ['systemd-sysv-generator', '8', [], 'HAVE_SYSV_COMPAT'],
  ['systemd-time-wait-sync.service',
   '8',
   ['systemd-time-wait-sync'],
diff --git a/man/systemd-sysv-generator.xml b/man/systemd-sysv-generator.xml
deleted file mode 100644 (file)
index f5a9889..0000000
+++ /dev/null
@@ -1,68 +0,0 @@
-<?xml version="1.0"?>
-<!--*-nxml-*-->
-<!DOCTYPE refentry PUBLIC "-//OASIS//DTD DocBook XML V4.5//EN"
-  "http://www.oasis-open.org/docbook/xml/4.5/docbookx.dtd">
-<!-- SPDX-License-Identifier: LGPL-2.1-or-later -->
-<refentry id="systemd-sysv-generator" conditional="HAVE_SYSV_COMPAT">
-
-  <refentryinfo>
-    <title>systemd-sysv-generator</title>
-    <productname>systemd</productname>
-  </refentryinfo>
-
-  <refmeta>
-    <refentrytitle>systemd-sysv-generator</refentrytitle>
-    <manvolnum>8</manvolnum>
-  </refmeta>
-
-  <refnamediv>
-    <refname>systemd-sysv-generator</refname>
-    <refpurpose>Unit generator for SysV init scripts</refpurpose>
-  </refnamediv>
-
-  <refsynopsisdiv>
-    <para><filename>/usr/lib/systemd/system-generators/systemd-sysv-generator</filename></para>
-  </refsynopsisdiv>
-
-  <refsect1>
-    <title>Description</title>
-
-    <para><emphasis>Note: this component is deprecated and scheduled for removal. Please replace remaining
-    SysV init scripts with native unit files.</emphasis></para>
-
-    <para><filename>systemd-sysv-generator</filename> is a generator that creates wrapper .service units for
-    <ulink url="https://savannah.nongnu.org/projects/sysvinit">System V init</ulink> scripts in
-    <filename>/etc/init.d/*</filename> at boot and when configuration of the system manager is reloaded. This
-    allows <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry> to
-    support them similarly to native units.</para>
-
-    <para><ulink
-    url="http://refspecs.linuxbase.org/LSB_3.1.1/LSB-Core-generic/LSB-Core-generic/iniscrptact.html">LSB
-    headers</ulink> in SysV init scripts are interpreted, and the ordering specified in the header is turned
-    into dependencies between the generated unit and other units. The LSB facilities
-    <literal>$remote_fs</literal>, <literal>$network</literal>, <literal>$named</literal>,
-    <literal>$portmap</literal>, <literal>$time</literal> are supported and will be turned into dependencies
-    on specific native systemd targets.  See
-    <citerefentry><refentrytitle>systemd.special</refentrytitle><manvolnum>7</manvolnum></citerefentry> for
-    more details.</para>
-
-    <para>Note that compatibility is quite comprehensive but not 100%, for more details see <ulink
-    url="https://systemd.io/INCOMPATIBILITIES">Compatibility with SysV</ulink>.</para>
-
-    <para><command>systemd</command> does not support SysV scripts as part of early boot, so all wrapper
-    units are ordered after <filename>basic.target</filename>.</para>
-
-    <para><filename>systemd-sysv-generator</filename> implements
-    <citerefentry><refentrytitle>systemd.generator</refentrytitle><manvolnum>7</manvolnum></citerefentry>.</para>
-  </refsect1>
-
-  <refsect1>
-    <title>See Also</title>
-    <para><simplelist type="inline">
-      <member><citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
-      <member><citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
-      <member><citerefentry><refentrytitle>systemd.target</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
-    </simplelist></para>
-  </refsect1>
-
-</refentry>
index 589c057dd94658a149d42cc1b867b36a01d7264c..47bb970a5502d8637fd15c7d1ef693b7a1460a0f 100644 (file)
@@ -407,7 +407,6 @@ find $dir</programlisting>
       <member><citerefentry><refentrytitle>systemd-hibernate-resume-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
       <member><citerefentry><refentrytitle>systemd-rc-local-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
       <member><citerefentry><refentrytitle>systemd-system-update-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
-      <member><citerefentry><refentrytitle>systemd-sysv-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
       <member><citerefentry><refentrytitle>systemd-xdg-autostart-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry></member>
       <member><citerefentry><refentrytitle>systemd.unit</refentrytitle><manvolnum>5</manvolnum></citerefentry></member>
       <member><citerefentry><refentrytitle>systemctl</refentrytitle><manvolnum>1</manvolnum></citerefentry></member>
index 2ddeeafcec842b6ca659196984a6f256668a768c..603dc8f68d4e945cba56a9a3f4a747a1f30a636a 100644 (file)
     which configure resource control settings for the processes of the
     service.</para>
 
-    <para>If SysV init compat is enabled, systemd automatically creates service units that wrap SysV init
-    scripts (the service name is the same as the name of the script, with a <literal>.service</literal>
-    suffix added); see
-    <citerefentry><refentrytitle>systemd-sysv-generator</refentrytitle><manvolnum>8</manvolnum></citerefentry>.
-    </para>
-
     <para>The <citerefentry><refentrytitle>systemd-run</refentrytitle><manvolnum>1</manvolnum></citerefentry>
     command allows creating <filename>.service</filename> and <filename>.scope</filename> units dynamically
     and transiently from the command line.</para>
index de685fe9ce053919046773ac6a67f6f7c300b242..89f9f0fd695adc2a51ba54f6b1e98b5d00b99449 100644 (file)
@@ -90,10 +90,6 @@ conf.set10('HAVE_SPLIT_BIN', split_bin,
 
 have_standalone_binaries = get_option('standalone-binaries')
 
-sysvinit_path = get_option('sysvinit-path')
-sysvrcnd_path = get_option('sysvrcnd-path')
-conf.set10('HAVE_SYSV_COMPAT', sysvinit_path != '' and sysvrcnd_path != '',
-           description : 'SysV init scripts and rcN.d links are supported')
 sysvrclocal_path = get_option('rc-local')
 conf.set10('HAVE_SYSV_RC_LOCAL', sysvrclocal_path != '')
 conf.set10('CREATE_LOG_DIRS', get_option('create-log-dirs'))
@@ -303,8 +299,6 @@ conf.set_quoted('SYSTEM_GENERATOR_DIR',                       systemgeneratordir
 conf.set_quoted('SYSTEM_PRESET_DIR',                          systempresetdir)
 conf.set_quoted('SYSTEM_SHUTDOWN_PATH',                       systemshutdowndir)
 conf.set_quoted('SYSTEM_SLEEP_PATH',                          systemsleepdir)
-conf.set_quoted('SYSTEM_SYSVINIT_PATH',                       sysvinit_path)
-conf.set_quoted('SYSTEM_SYSVRCND_PATH',                       sysvrcnd_path)
 conf.set_quoted('SYSTEM_SYSVRCLOCAL_PATH',                    sysvrclocal_path)
 conf.set_quoted('SYSUSERS_DIR',                               sysusersdir)
 conf.set_quoted('TMPFILES_DIR',                               tmpfilesdir)
@@ -2431,7 +2425,6 @@ subdir('src/system-update-generator')
 subdir('src/systemctl')
 subdir('src/sysupdate')
 subdir('src/sysusers')
-subdir('src/sysv-generator')
 subdir('src/timedate')
 subdir('src/timesync')
 subdir('src/tmpfiles')
@@ -2792,7 +2785,6 @@ subdir('test')
 
 #####################################################################
 
-subdir('docs/sysvinit')
 subdir('docs/var-log')
 subdir('hwdb.d')
 subdir('man')
@@ -3023,8 +3015,6 @@ summary({
         'sysconf directory'                         : sysconfdir,
         'include directory'                         : includedir,
         'lib directory'                             : libdir,
-        'SysV init scripts'                         : sysvinit_path,
-        'SysV rc?.d directories'                    : sysvrcnd_path,
         'SysV rc.local script'                      : sysvrclocal_path,
         'PAM modules directory'                     : pamlibdir,
         'PAM configuration directory'               : pamconfdir,
index e43c0a21c4e0d1fb2bf7742385ed40218a793d82..c555b9ebdc4f0d9f63f7254d933f4280f5490ff4 100644 (file)
@@ -41,10 +41,10 @@ option('static-libudev', type : 'combo',
 option('standalone-binaries', type : 'boolean', value : false,
        description : 'also build standalone versions of supported binaries')
 
-option('sysvinit-path', type : 'string', value : '/etc/init.d',
-       description : 'the directory where the SysV init scripts are located')
-option('sysvrcnd-path', type : 'string', value : '/etc/rc.d',
-       description : 'the base directory for SysV rcN.d directories')
+option('sysvinit-path', type : 'string', value : '/etc/init.d', deprecated : true,
+       description : 'This option is deprecated and will be removed in a future release')
+option('sysvrcnd-path', type : 'string', value : '/etc/rc.d', deprecated : true,
+       description : 'This option is deprecated and will be removed in a future release')
 option('rc-local', type : 'string', value : '/etc/rc.local',
        description : 'path to SysV rc.local script')
 option('initrd', type : 'boolean',
index 910a7a0c479c57505c7b76ff194d34fe01cb5c66..76fdece83baab02c304d3359afeb42868e398805 100755 (executable)
@@ -59,6 +59,8 @@ EOF
 TS="${SOURCE_DATE_EPOCH:-$(date +%s)}"
 
 sed "pkg/$PKG_SUBDIR/PKGBUILD" \
+    --expression "/-Dsysvinit-path=/d" \
+    --expression "/-Dsysvrcnd-path=/d" \
     --expression "s/^pkgver=.*/pkgver=$(cat meson.version)/" \
     --expression "s/^pkgrel=.*/pkgrel=$(date "+%Y%m%d%H%M%S" --date "@$TS")/" >/tmp/PKGBUILD
 mount --bind /tmp/PKGBUILD "pkg/$PKG_SUBDIR/PKGBUILD"
index 2d34be043d3182161cc573f5e73ab9db232ea88d..efbc4670dcf50b38b03b05c5ba4f6629ca36e0e7 100755 (executable)
@@ -26,6 +26,7 @@ while read -r filelist; do
         -e 's/\.gz$//; /systemd-cgroups-agent/d; s/import-pubring.gpg/import-pubring.pgp/' \
         -e '/(initctl|runlevel|telinit)/ d' \
         -e 's/systemd-quotacheck.service.8/systemd-quotacheck@.service.8/' \
+        -e '/systemd-sysv-generator/d' \
         "$filelist" >"/tmp/$(basename "$filelist")"
     mount --bind "/tmp/$(basename "$filelist")" "$filelist"
 done < <(find "pkg/$PKG_SUBDIR${GIT_SUBDIR:+/$GIT_SUBDIR}" -name "files.*")
index f5695eeb9323d5180da259efbeddd479bfa50cfc..213ccca5f4e6659f670518f20780d9d1013f8bf5 100644 (file)
@@ -232,12 +232,6 @@ const char* const systemd_features =
         " -UTMP"
 #endif
 
-#if HAVE_SYSV_COMPAT
-        " +SYSVINIT"
-#else
-        " -SYSVINIT"
-#endif
-
 #if HAVE_LIBARCHIVE
         " +LIBARCHIVE"
 #else
index 820214919f02b4c59210a08a073724a0fd5ce3ef..2ce11c8f48d0ad61ebf11ced3a1369085079bee2 100644 (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',
 )
index 2903d76929e03905c9f9e40443ba3af112261f11..904a3a8234d26268c690eed0944b2836260da10c 100644 (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)
index da028b1385ca5d0809f359f82ce9173ff577e85e..77b8cac5f01ebdb37378c6787ac15c803ac45f2d 100644 (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;
diff --git a/src/systemctl/systemctl-sysv-compat.c b/src/systemctl/systemctl-sysv-compat.c
deleted file mode 100644 (file)
index adc73c3..0000000
+++ /dev/null
@@ -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;
-}
diff --git a/src/systemctl/systemctl-sysv-compat.h b/src/systemctl/systemctl-sysv-compat.h
deleted file mode 100644 (file)
index 72e823f..0000000
+++ /dev/null
@@ -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);
diff --git a/src/systemctl/systemd-sysv-install.SKELETON b/src/systemctl/systemd-sysv-install.SKELETON
deleted file mode 100755 (executable)
index cb58d82..0000000
+++ /dev/null
@@ -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
diff --git a/src/sysv-generator/meson.build b/src/sysv-generator/meson.build
deleted file mode 100644 (file)
index 4e89439..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-# SPDX-License-Identifier: LGPL-2.1-or-later
-
-executables += [
-        generator_template + {
-                'name' : 'systemd-sysv-generator',
-                'conditions' : ['HAVE_SYSV_COMPAT'],
-                'sources' : files('sysv-generator.c'),
-        },
-]
diff --git a/src/sysv-generator/sysv-generator.c b/src/sysv-generator/sysv-generator.c
deleted file mode 100644 (file)
index e11edef..0000000
+++ /dev/null
@@ -1,937 +0,0 @@
-/* SPDX-License-Identifier: LGPL-2.1-or-later */
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <unistd.h>
-
-#include "sd-messages.h"
-
-#include "alloc-util.h"
-#include "dirent-util.h"
-#include "exit-status.h"
-#include "extract-word.h"
-#include "fd-util.h"
-#include "fileio.h"
-#include "generator.h"
-#include "glyph-util.h"
-#include "hashmap.h"
-#include "hexdecoct.h"
-#include "initrd-util.h"
-#include "install.h"
-#include "log.h"
-#include "path-lookup.h"
-#include "path-util.h"
-#include "set.h"
-#include "special.h"
-#include "specifier.h"
-#include "stat-util.h"
-#include "string-util.h"
-#include "strv.h"
-#include "unit-name.h"
-
-/* 🚨 Note: this generator is deprecated! Please do not add new features! Instead, please port remaining SysV
- * scripts over to native unit files! Thank you! 🚨 */
-
-static const struct {
-        const char *path;
-        const char *target;
-} rcnd_table[] = {
-        /* Standard SysV runlevels for start-up */
-        { "rc1.d",  SPECIAL_RESCUE_TARGET     },
-        { "rc2.d",  SPECIAL_MULTI_USER_TARGET },
-        { "rc3.d",  SPECIAL_MULTI_USER_TARGET },
-        { "rc4.d",  SPECIAL_MULTI_USER_TARGET },
-        { "rc5.d",  SPECIAL_GRAPHICAL_TARGET  },
-
-        /* We ignore the SysV runlevels for shutdown here, as SysV services get default dependencies anyway, and that
-         * means they are shut down anyway at system power off if running. */
-};
-
-static const char *arg_dest = NULL;
-
-typedef struct SysvStub {
-        char *name;
-        char *path;
-        char *description;
-        int sysv_start_priority;
-        char *pid_file;
-        char **before;
-        char **after;
-        char **wants;
-        char **wanted_by;
-        bool has_lsb;
-        bool reload;
-        bool loaded;
-} SysvStub;
-
-static SysvStub* sysvstub_free(SysvStub *s) {
-        if (!s)
-                return NULL;
-
-        free(s->name);
-        free(s->path);
-        free(s->description);
-        free(s->pid_file);
-        strv_free(s->before);
-        strv_free(s->after);
-        strv_free(s->wants);
-        strv_free(s->wanted_by);
-        return mfree(s);
-}
-DEFINE_TRIVIAL_CLEANUP_FUNC(SysvStub*, sysvstub_free);
-
-DEFINE_PRIVATE_HASH_OPS_WITH_VALUE_DESTRUCTOR(
-                sysvstub_hash_ops,
-                char, string_hash_func, string_compare_func,
-                SysvStub, sysvstub_free);
-
-static int add_alias(const char *service, const char *alias) {
-        _cleanup_free_ char *link = NULL;
-
-        assert(service);
-        assert(alias);
-
-        link = path_join(arg_dest, alias);
-        if (!link)
-                return -ENOMEM;
-
-        if (symlink(service, link) < 0) {
-                if (errno == EEXIST)
-                        return 0;
-
-                return -errno;
-        }
-
-        return 1;
-}
-
-static int generate_unit_file(SysvStub *s) {
-        _cleanup_free_ char *path_escaped = NULL, *unit = NULL;
-        _cleanup_fclose_ FILE *f = NULL;
-        int r;
-
-        assert(s);
-
-        if (!s->loaded)
-                return 0;
-
-        path_escaped = specifier_escape(s->path);
-        if (!path_escaped)
-                return log_oom();
-
-        unit = path_join(arg_dest, s->name);
-        if (!unit)
-                return log_oom();
-
-        /* We might already have a symlink with the same name from a Provides:,
-         * or from backup files like /etc/init.d/foo.bak. Real scripts always win,
-         * so remove an existing link */
-        if (is_symlink(unit) > 0) {
-                log_warning("Overwriting existing symlink %s with real service.", unit);
-                (void) unlink(unit);
-        }
-
-        f = fopen(unit, "wxe");
-        if (!f)
-                return log_error_errno(errno, "Failed to create unit file %s: %m", unit);
-
-        fprintf(f,
-                "# Automatically generated by systemd-sysv-generator\n\n"
-                "[Unit]\n"
-                "Documentation=man:systemd-sysv-generator(8)\n"
-                "SourcePath=%s\n",
-                path_escaped);
-
-        if (s->description) {
-                _cleanup_free_ char *t = NULL;
-
-                t = specifier_escape(s->description);
-                if (!t)
-                        return log_oom();
-
-                fprintf(f, "Description=%s\n", t);
-        }
-
-        STRV_FOREACH(p, s->before)
-                fprintf(f, "Before=%s\n", *p);
-        STRV_FOREACH(p, s->after)
-                fprintf(f, "After=%s\n", *p);
-        STRV_FOREACH(p, s->wants)
-                fprintf(f, "Wants=%s\n", *p);
-
-        fprintf(f,
-                "\n[Service]\n"
-                "Type=forking\n"
-                "Restart=no\n"
-                "TimeoutSec=5min\n"
-                "IgnoreSIGPIPE=no\n"
-                "KillMode=process\n"
-                "GuessMainPID=no\n"
-                "RemainAfterExit=%s\n",
-                yes_no(!s->pid_file));
-
-        if (s->pid_file) {
-                _cleanup_free_ char *t = NULL;
-
-                t = specifier_escape(s->pid_file);
-                if (!t)
-                        return log_oom();
-
-                fprintf(f, "PIDFile=%s\n", t);
-        }
-
-        /* Consider two special LSB exit codes a clean exit */
-        if (s->has_lsb)
-                fprintf(f,
-                        "SuccessExitStatus=%i %i\n",
-                        EXIT_NOTINSTALLED,
-                        EXIT_NOTCONFIGURED);
-
-        fprintf(f,
-                "ExecStart=%s start\n"
-                "ExecStop=%s stop\n",
-                path_escaped, path_escaped);
-
-        if (s->reload)
-                fprintf(f, "ExecReload=%s reload\n", path_escaped);
-
-        r = fflush_and_check(f);
-        if (r < 0)
-                return log_error_errno(r, "Failed to write unit %s: %m", unit);
-
-        STRV_FOREACH(p, s->wanted_by)
-                (void) generator_add_symlink(arg_dest, *p, "wants", s->name);
-
-        return 1;
-}
-
-static bool usage_contains_reload(const char *line) {
-        return (strcasestr(line, "{reload|") ||
-                strcasestr(line, "{reload}") ||
-                strcasestr(line, "{reload\"") ||
-                strcasestr(line, "|reload|") ||
-                strcasestr(line, "|reload}") ||
-                strcasestr(line, "|reload\""));
-}
-
-static char *sysv_translate_name(const char *name) {
-        _cleanup_free_ char *c = NULL;
-        char *res;
-
-        c = strdup(name);
-        if (!c)
-                return NULL;
-
-        res = endswith(c, ".sh");
-        if (res)
-                *res = 0;
-
-        if (unit_name_mangle(c, 0, &res) < 0)
-                return NULL;
-
-        return res;
-}
-
-static int sysv_translate_facility(SysvStub *s, unsigned line, const char *name, char **ret) {
-
-        /* We silently ignore the $ prefix here. According to the LSB
-         * spec it simply indicates whether something is a
-         * standardized name or a distribution-specific one. Since we
-         * just follow what already exists and do not introduce new
-         * uses or names we don't care who introduced a new name. */
-
-        static const char * const table[] = {
-                /* LSB defined facilities */
-                "local_fs",             NULL,
-                "network",              SPECIAL_NETWORK_ONLINE_TARGET,
-                "named",                SPECIAL_NSS_LOOKUP_TARGET,
-                "portmap",              SPECIAL_RPCBIND_TARGET,
-                "remote_fs",            SPECIAL_REMOTE_FS_TARGET,
-                "syslog",               NULL,
-                "time",                 SPECIAL_TIME_SYNC_TARGET,
-        };
-
-        _cleanup_free_ char *filename = NULL;
-        const char *n;
-        char *e, *m;
-        int r;
-
-        assert(name);
-        assert(s);
-        assert(ret);
-
-        r = path_extract_filename(s->path, &filename);
-        if (r < 0)
-                return log_error_errno(r, "Failed to extract file name from path '%s': %m", s->path);
-
-        n = *name == '$' ? name + 1 : name;
-
-        for (size_t i = 0; i < ELEMENTSOF(table); i += 2) {
-                if (!streq(table[i], n))
-                        continue;
-
-                if (!table[i+1]) {
-                        *ret = NULL;
-                        return 0;
-                }
-
-                m = strdup(table[i+1]);
-                if (!m)
-                        return log_oom();
-
-                *ret = m;
-                return 1;
-        }
-
-        /* If we don't know this name, fallback heuristics to figure
-         * out whether something is a target or a service alias. */
-
-        /* Facilities starting with $ are most likely targets */
-        if (*name == '$')  {
-                r = unit_name_build(n, NULL, ".target", ret);
-                if (r < 0)
-                        return log_error_errno(r, "[%s:%u] Could not build name for facility %s: %m", s->path, line, name);
-
-                return 1;
-        }
-
-        /* Strip ".sh" suffix from file name for comparison */
-        e = endswith(filename, ".sh");
-        if (e)
-                *e = '\0';
-
-        /* Names equaling the file name of the services are redundant */
-        if (streq_ptr(n, filename)) {
-                *ret = NULL;
-                return 0;
-        }
-
-        /* Everything else we assume to be normal service names */
-        m = sysv_translate_name(n);
-        if (!m)
-                return log_oom();
-
-        *ret = m;
-        return 1;
-}
-
-static int handle_provides(SysvStub *s, unsigned line, const char *full_text, const char *text) {
-        int r;
-
-        assert(s);
-        assert(full_text);
-        assert(text);
-
-        for (;;) {
-                _cleanup_free_ char *word = NULL, *m = NULL;
-
-                r = extract_first_word(&text, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RELAX);
-                if (r < 0)
-                        return log_error_errno(r, "[%s:%u] Failed to parse word from provides string: %m", s->path, line);
-                if (r == 0)
-                        break;
-
-                r = sysv_translate_facility(s, line, word, &m);
-                if (r <= 0) /* continue on error */
-                        continue;
-
-                switch (unit_name_to_type(m)) {
-
-                case UNIT_SERVICE:
-                        log_debug("Adding Provides: alias '%s' for '%s'", m, s->name);
-                        r = add_alias(s->name, m);
-                        if (r < 0)
-                                log_warning_errno(r, "[%s:%u] Failed to add LSB Provides name %s, ignoring: %m", s->path, line, m);
-                        break;
-
-                case UNIT_TARGET:
-
-                        /* NB: SysV targets which are provided by a
-                         * service are pulled in by the services, as
-                         * an indication that the generic service is
-                         * now available. This is strictly one-way.
-                         * The targets do NOT pull in SysV services! */
-
-                        r = strv_extend(&s->before, m);
-                        if (r < 0)
-                                return log_oom();
-
-                        r = strv_extend(&s->wants, m);
-                        if (r < 0)
-                                return log_oom();
-
-                        if (streq(m, SPECIAL_NETWORK_ONLINE_TARGET)) {
-                                r = strv_extend(&s->before, SPECIAL_NETWORK_TARGET);
-                                if (r < 0)
-                                        return log_oom();
-                                r = strv_extend(&s->wants, SPECIAL_NETWORK_TARGET);
-                                if (r < 0)
-                                        return log_oom();
-                        }
-
-                        break;
-
-                case _UNIT_TYPE_INVALID:
-                        log_warning("Unit name '%s' is invalid", m);
-                        break;
-
-                default:
-                        log_warning("Unknown unit type for unit '%s'", m);
-                }
-        }
-
-        return 0;
-}
-
-static int handle_dependencies(SysvStub *s, unsigned line, const char *full_text, const char *text) {
-        int r;
-
-        assert(s);
-        assert(full_text);
-        assert(text);
-
-        for (;;) {
-                _cleanup_free_ char *word = NULL, *m = NULL;
-                bool is_before;
-
-                r = extract_first_word(&text, &word, NULL, EXTRACT_UNQUOTE|EXTRACT_RELAX);
-                if (r < 0)
-                        return log_error_errno(r, "[%s:%u] Failed to parse word from provides string: %m", s->path, line);
-                if (r == 0)
-                        break;
-
-                r = sysv_translate_facility(s, line, word, &m);
-                if (r <= 0) /* continue on error */
-                        continue;
-
-                is_before = startswith_no_case(full_text, "X-Start-Before:");
-
-                if (streq(m, SPECIAL_NETWORK_ONLINE_TARGET) && !is_before) {
-                        /* the network-online target is special, as it needs to be actively pulled in */
-                        r = strv_extend(&s->after, m);
-                        if (r < 0)
-                                return log_oom();
-
-                        r = strv_extend(&s->wants, m);
-                } else
-                        r = strv_extend(is_before ? &s->before : &s->after, m);
-                if (r < 0)
-                        return log_oom();
-        }
-
-        return 0;
-}
-
-static int load_sysv(SysvStub *s) {
-        _cleanup_fclose_ FILE *f = NULL;
-        unsigned line = 0;
-        int r;
-        enum {
-                NORMAL,
-                DESCRIPTION,
-                LSB,
-                LSB_DESCRIPTION,
-                USAGE_CONTINUATION
-        } state = NORMAL;
-        _cleanup_free_ char *short_description = NULL, *long_description = NULL, *chkconfig_description = NULL;
-        char *description;
-        bool supports_reload = false;
-
-        assert(s);
-
-        f = fopen(s->path, "re");
-        if (!f) {
-                if (errno == ENOENT)
-                        return 0;
-
-                return log_error_errno(errno, "Failed to open %s: %m", s->path);
-        }
-
-        log_debug("Loading SysV script %s", s->path);
-
-        for (;;) {
-                _cleanup_free_ char *l = NULL;
-
-                r = read_stripped_line(f, LONG_LINE_MAX, &l);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to read configuration file '%s': %m", s->path);
-                if (r == 0)
-                        break;
-
-                line++;
-
-                if (l[0] != '#') {
-                        /* Try to figure out whether this init script supports
-                         * the reload operation. This heuristic looks for
-                         * "Usage" lines which include the reload option. */
-                        if (state == USAGE_CONTINUATION ||
-                            (state == NORMAL && strcasestr(l, "usage"))) {
-                                if (usage_contains_reload(l)) {
-                                        supports_reload = true;
-                                        state = NORMAL;
-                                } else if (endswith(l, "\\"))
-                                        state = USAGE_CONTINUATION;
-                                else
-                                        state = NORMAL;
-                        }
-
-                        continue;
-                }
-
-                if (state == NORMAL && streq(l, "### BEGIN INIT INFO")) {
-                        state = LSB;
-                        s->has_lsb = true;
-                        continue;
-                }
-
-                if (IN_SET(state, LSB_DESCRIPTION, LSB) && streq(l, "### END INIT INFO")) {
-                        state = NORMAL;
-                        continue;
-                }
-
-                char *t = l + 1;
-                t += strspn(t, WHITESPACE);
-
-                if (state == NORMAL) {
-
-                        /* Try to parse Red Hat style description */
-
-                        if (startswith_no_case(t, "description:")) {
-
-                                size_t k;
-                                const char *j;
-
-                                k = strlen(t);
-                                if (k > 0 && t[k-1] == '\\') {
-                                        state = DESCRIPTION;
-                                        t[k-1] = 0;
-                                }
-
-                                j = empty_to_null(strstrip(t+12));
-
-                                r = free_and_strdup(&chkconfig_description, j);
-                                if (r < 0)
-                                        return log_oom();
-
-                        } else if (startswith_no_case(t, "pidfile:")) {
-                                const char *fn;
-
-                                state = NORMAL;
-
-                                fn = strstrip(t+8);
-                                if (!path_is_absolute(fn)) {
-                                        log_error("[%s:%u] PID file not absolute. Ignoring.", s->path, line);
-                                        continue;
-                                }
-
-                                r = free_and_strdup(&s->pid_file, fn);
-                                if (r < 0)
-                                        return log_oom();
-                        }
-
-                } else if (state == DESCRIPTION) {
-
-                        /* Try to parse Red Hat style description
-                         * continuation */
-
-                        size_t k;
-                        const char *j;
-
-                        k = strlen(t);
-                        if (k > 0 && t[k-1] == '\\')
-                                t[k-1] = 0;
-                        else
-                                state = NORMAL;
-
-                        j = strstrip(t);
-                        if (!isempty(j) && !strextend_with_separator(&chkconfig_description, " ", j))
-                                return log_oom();
-
-                } else if (IN_SET(state, LSB, LSB_DESCRIPTION)) {
-
-                        if (startswith_no_case(t, "Provides:")) {
-                                state = LSB;
-
-                                r = handle_provides(s, line, t, t + 9);
-                                if (r < 0)
-                                        return r;
-
-                        } else if (startswith_no_case(t, "Required-Start:") ||
-                                   startswith_no_case(t, "Should-Start:") ||
-                                   startswith_no_case(t, "X-Start-Before:") ||
-                                   startswith_no_case(t, "X-Start-After:")) {
-
-                                state = LSB;
-
-                                r = handle_dependencies(s, line, t, strchr(t, ':') + 1);
-                                if (r < 0)
-                                        return r;
-
-                        } else if (startswith_no_case(t, "Description:")) {
-                                const char *j;
-
-                                state = LSB_DESCRIPTION;
-
-                                j = empty_to_null(strstrip(t+12));
-
-                                r = free_and_strdup(&long_description, j);
-                                if (r < 0)
-                                        return log_oom();
-
-                        } else if (startswith_no_case(t, "Short-Description:")) {
-                                const char *j;
-
-                                state = LSB;
-
-                                j = empty_to_null(strstrip(t+18));
-
-                                r = free_and_strdup(&short_description, j);
-                                if (r < 0)
-                                        return log_oom();
-
-                        } else if (state == LSB_DESCRIPTION) {
-
-                                if (startswith(l, "#\t") || startswith(l, "#  ")) {
-                                        const char *j;
-
-                                        j = strstrip(t);
-                                        if (!isempty(j) && !strextend_with_separator(&long_description, " ", j))
-                                                return log_oom();
-                                } else
-                                        state = LSB;
-                        }
-                }
-        }
-
-        s->reload = supports_reload;
-
-        /* We use the long description only if
-         * no short description is set. */
-
-        if (short_description)
-                description = short_description;
-        else if (chkconfig_description)
-                description = chkconfig_description;
-        else if (long_description)
-                description = long_description;
-        else
-                description = NULL;
-
-        if (description) {
-                char *d;
-
-                d = strjoin(s->has_lsb ? "LSB: " : "SYSV: ", description);
-                if (!d)
-                        return log_oom();
-
-                s->description = d;
-        }
-
-        s->loaded = true;
-        return 0;
-}
-
-static int fix_order(SysvStub *s, Hashmap *all_services) {
-        SysvStub *other;
-        int r;
-
-        assert(s);
-
-        if (!s->loaded)
-                return 0;
-
-        if (s->sysv_start_priority < 0)
-                return 0;
-
-        HASHMAP_FOREACH(other, all_services) {
-                if (s == other)
-                        continue;
-
-                if (!other->loaded)
-                        continue;
-
-                if (other->sysv_start_priority < 0)
-                        continue;
-
-                /* If both units have modern headers we don't care
-                 * about the priorities */
-                if (s->has_lsb && other->has_lsb)
-                        continue;
-
-                if (other->sysv_start_priority < s->sysv_start_priority) {
-                        r = strv_extend(&s->after, other->name);
-                        if (r < 0)
-                                return log_oom();
-
-                } else if (other->sysv_start_priority > s->sysv_start_priority) {
-                        r = strv_extend(&s->before, other->name);
-                        if (r < 0)
-                                return log_oom();
-                } else
-                        continue;
-
-                /* FIXME: Maybe we should compare the name here lexicographically? */
-        }
-
-        return 0;
-}
-
-static int acquire_search_path(const char *def, const char *envvar, char ***ret) {
-        _cleanup_strv_free_ char **l = NULL;
-        const char *e;
-        int r;
-
-        assert(def);
-        assert(envvar);
-
-        e = getenv(envvar);
-        if (e) {
-                r = path_split_and_make_absolute(e, &l);
-                if (r < 0)
-                        return log_error_errno(r, "Failed to make $%s search path absolute: %m", envvar);
-        }
-
-        if (strv_isempty(l)) {
-                strv_free(l);
-
-                l = strv_new(def);
-                if (!l)
-                        return log_oom();
-        }
-
-        if (!path_strv_resolve_uniq(l, NULL))
-                return log_oom();
-
-        *ret = TAKE_PTR(l);
-
-        return 0;
-}
-
-static int enumerate_sysv(const LookupPaths *lp, Hashmap *all_services) {
-        _cleanup_strv_free_ char **sysvinit_path = NULL;
-        int r;
-
-        assert(lp);
-
-        r = acquire_search_path(SYSTEM_SYSVINIT_PATH, "SYSTEMD_SYSVINIT_PATH", &sysvinit_path);
-        if (r < 0)
-                return r;
-
-        STRV_FOREACH(path, sysvinit_path) {
-                _cleanup_closedir_ DIR *d = NULL;
-
-                d = opendir(*path);
-                if (!d) {
-                        if (errno != ENOENT)
-                                log_warning_errno(errno, "Opening %s failed, ignoring: %m", *path);
-                        continue;
-                }
-
-                FOREACH_DIRENT(de, d, log_error_errno(errno, "Failed to enumerate directory %s, ignoring: %m", *path)) {
-                        _cleanup_free_ char *fpath = NULL, *name = NULL;
-                        _cleanup_(sysvstub_freep) SysvStub *service = NULL;
-                        struct stat st;
-
-                        if (fstatat(dirfd(d), de->d_name, &st, 0) < 0) {
-                                log_warning_errno(errno, "stat() failed on %s/%s, ignoring: %m", *path, de->d_name);
-                                continue;
-                        }
-
-                        if (!(st.st_mode & S_IXUSR))
-                                continue;
-
-                        if (!S_ISREG(st.st_mode))
-                                continue;
-
-                        name = sysv_translate_name(de->d_name);
-                        if (!name)
-                                return log_oom();
-
-                        if (hashmap_contains(all_services, name))
-                                continue;
-
-                        r = unit_file_exists(RUNTIME_SCOPE_SYSTEM, lp, name);
-                        if (r < 0 && !IN_SET(r, -ELOOP, -ERFKILL, -EADDRNOTAVAIL)) {
-                                log_debug_errno(r, "Failed to detect whether %s exists, skipping: %m", name);
-                                continue;
-                        } else if (r != 0) {
-                                log_debug("Native unit for %s already exists, skipping.", name);
-                                continue;
-                        }
-
-                        fpath = path_join(*path, de->d_name);
-                        if (!fpath)
-                                return log_oom();
-
-                        log_struct(LOG_WARNING,
-                                   LOG_MESSAGE("SysV service '%s' lacks a native systemd unit file, "
-                                               "automatically generating a unit file for compatibility.\n"
-                                               "Please update package to include a native systemd unit file.\n"
-                                               "%s This compatibility logic is deprecated, expect removal soon. %s",
-                                               fpath,
-                                               glyph(GLYPH_WARNING_SIGN),
-                                               glyph(GLYPH_WARNING_SIGN)),
-                                   LOG_MESSAGE_ID(SD_MESSAGE_SYSV_GENERATOR_DEPRECATED_STR),
-                                   LOG_ITEM("SYSVSCRIPT=%s", fpath),
-                                   LOG_ITEM("UNIT=%s", name));
-
-                        service = new(SysvStub, 1);
-                        if (!service)
-                                return log_oom();
-
-                        *service = (SysvStub) {
-                                .sysv_start_priority = -1,
-                                .name = TAKE_PTR(name),
-                                .path = TAKE_PTR(fpath),
-                        };
-
-                        r = hashmap_put(all_services, service->name, service);
-                        if (r < 0)
-                                return log_oom();
-
-                        TAKE_PTR(service);
-                }
-        }
-
-        return 0;
-}
-
-static int set_dependencies_from_rcnd(const LookupPaths *lp, Hashmap *all_services) {
-        Set *runlevel_services[ELEMENTSOF(rcnd_table)] = {};
-        _cleanup_strv_free_ char **sysvrcnd_path = NULL;
-        SysvStub *service;
-        int r;
-
-        assert(lp);
-
-        r = acquire_search_path(SYSTEM_SYSVRCND_PATH, "SYSTEMD_SYSVRCND_PATH", &sysvrcnd_path);
-        if (r < 0)
-                return r;
-
-        STRV_FOREACH(p, sysvrcnd_path)
-                for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i++) {
-                        _cleanup_closedir_ DIR *d = NULL;
-                        _cleanup_free_ char *path = NULL;
-
-                        path = path_join(*p, rcnd_table[i].path);
-                        if (!path) {
-                                r = log_oom();
-                                goto finish;
-                        }
-
-                        d = opendir(path);
-                        if (!d) {
-                                if (errno != ENOENT)
-                                        log_warning_errno(errno, "Opening %s failed, ignoring: %m", path);
-
-                                continue;
-                        }
-
-                        FOREACH_DIRENT(de, d, log_warning_errno(errno, "Failed to enumerate directory %s, ignoring: %m", path)) {
-                                _cleanup_free_ char *name = NULL, *fpath = NULL;
-                                int a, b;
-
-                                if (de->d_name[0] != 'S')
-                                        continue;
-
-                                if (strlen(de->d_name) < 4)
-                                        continue;
-
-                                a = undecchar(de->d_name[1]);
-                                b = undecchar(de->d_name[2]);
-
-                                if (a < 0 || b < 0)
-                                        continue;
-
-                                fpath = path_join(*p, de->d_name);
-                                if (!fpath) {
-                                        r = log_oom();
-                                        goto finish;
-                                }
-
-                                name = sysv_translate_name(de->d_name + 3);
-                                if (!name) {
-                                        r = log_oom();
-                                        goto finish;
-                                }
-
-                                service = hashmap_get(all_services, name);
-                                if (!service) {
-                                        log_debug("Ignoring %s symlink in %s, not generating %s.", de->d_name, rcnd_table[i].path, name);
-                                        continue;
-                                }
-
-                                service->sysv_start_priority = MAX(a*10 + b, service->sysv_start_priority);
-
-                                r = set_ensure_put(&runlevel_services[i], NULL, service);
-                                if (r < 0) {
-                                        log_oom();
-                                        goto finish;
-                                }
-                        }
-                }
-
-        for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i++)
-                SET_FOREACH(service, runlevel_services[i]) {
-                        r = strv_extend(&service->before, rcnd_table[i].target);
-                        if (r < 0) {
-                                log_oom();
-                                goto finish;
-                        }
-                        r = strv_extend(&service->wanted_by, rcnd_table[i].target);
-                        if (r < 0) {
-                                log_oom();
-                                goto finish;
-                        }
-                }
-
-        r = 0;
-
-finish:
-        for (unsigned i = 0; i < ELEMENTSOF(rcnd_table); i++)
-                set_free(runlevel_services[i]);
-
-        return r;
-}
-
-static int run(const char *dest, const char *dest_early, const char *dest_late) {
-        _cleanup_hashmap_free_ Hashmap *all_services = NULL;
-        _cleanup_(lookup_paths_done) LookupPaths lp = {};
-        SysvStub *service;
-        int r;
-
-        if (in_initrd()) {
-                log_debug("Skipping generator, running in the initrd.");
-                return EXIT_SUCCESS;
-        }
-
-        assert_se(arg_dest = dest_late);
-
-        r = lookup_paths_init_or_warn(&lp, RUNTIME_SCOPE_SYSTEM, LOOKUP_PATHS_EXCLUDE_GENERATED, NULL);
-        if (r < 0)
-                return r;
-
-        all_services = hashmap_new(&sysvstub_hash_ops);
-        if (!all_services)
-                return log_oom();
-
-        r = enumerate_sysv(&lp, all_services);
-        if (r < 0)
-                return r;
-
-        r = set_dependencies_from_rcnd(&lp, all_services);
-        if (r < 0)
-                return r;
-
-        HASHMAP_FOREACH(service, all_services)
-                (void) load_sysv(service);
-
-        HASHMAP_FOREACH(service, all_services) {
-                (void) fix_order(service, all_services);
-                (void) generate_unit_file(service);
-        }
-
-        return 0;
-}
-
-DEFINE_MAIN_GENERATOR_FUNCTION(run);
index 7e8c3296ab598ae6858e9d051eda59d43f57e8f9..b1d5421f671846f76e0c0aa2152dfb27ec40efc6 100644 (file)
@@ -65,16 +65,6 @@ endif
 
 ############################################################
 
-if want_tests != 'false' and conf.get('HAVE_SYSV_COMPAT') == 1
-        exe = executables_by_name.get('systemd-sysv-generator')
-        test('sysv-generator-test',
-             files('sysv-generator-test.py'),
-             depends : exe,
-             suite : 'sysv')
-endif
-
-############################################################
-
 if want_tests != 'false' and conf.get('HAVE_BLKID') == 1
         exe = executables_by_name.get('bootctl')
         test('test-bootctl-json',
diff --git a/test/sysv-generator-test.py b/test/sysv-generator-test.py
deleted file mode 100755 (executable)
index 24fafba..0000000
+++ /dev/null
@@ -1,413 +0,0 @@
-#!/usr/bin/env python3
-# SPDX-License-Identifier: LGPL-2.1-or-later
-#
-# systemd-sysv-generator integration test
-#
-# © 2015 Canonical Ltd.
-# Author: Martin Pitt <martin.pitt@ubuntu.com>
-
-import collections
-import os
-import shutil
-import subprocess
-import sys
-import tempfile
-import unittest
-
-from configparser import RawConfigParser
-from glob import glob
-
-sysv_generator = './systemd-sysv-generator'
-
-class MultiDict(collections.OrderedDict):
-    def __setitem__(self, key, value):
-        if isinstance(value, list) and key in self:
-            self[key].extend(value)
-        else:
-            super(MultiDict, self).__setitem__(key, value)
-
-class SysvGeneratorTest(unittest.TestCase):
-    def setUp(self):
-        self.workdir = tempfile.mkdtemp(prefix='sysv-gen-test.')
-        self.init_d_dir = os.path.join(self.workdir, 'init.d')
-        os.mkdir(self.init_d_dir)
-        self.rcnd_dir = self.workdir
-        self.unit_dir = os.path.join(self.workdir, 'systemd')
-        os.mkdir(self.unit_dir)
-        self.out_dir = os.path.join(self.workdir, 'output')
-        os.mkdir(self.out_dir)
-
-    def tearDown(self):
-        shutil.rmtree(self.workdir)
-
-    #
-    # Helper methods
-    #
-
-    def run_generator(self, expect_error=False):
-        '''Run sysv-generator.
-
-        Fail if stderr contains any "Fail", unless expect_error is True.
-        Return (stderr, filename -> ConfigParser) pair with output to stderr and
-        parsed generated units.
-        '''
-        env = os.environ.copy()
-        # We might debug log about errors that aren't actually fatal so let's bump the log level to info to
-        # prevent those logs from interfering with the test.
-        env['SYSTEMD_LOG_LEVEL'] = 'info'
-        env['SYSTEMD_LOG_TARGET'] = 'console'
-        env['SYSTEMD_SYSVINIT_PATH'] = self.init_d_dir
-        env['SYSTEMD_SYSVRCND_PATH'] = self.rcnd_dir
-        env['SYSTEMD_UNIT_PATH'] = self.unit_dir
-        gen = subprocess.Popen(
-            [sysv_generator, 'ignored', 'ignored', self.out_dir],
-            stdout=subprocess.PIPE, stderr=subprocess.PIPE,
-            universal_newlines=True, env=env)
-        (out, err) = gen.communicate()
-        if not expect_error:
-            self.assertFalse('Fail' in err, err)
-        self.assertEqual(gen.returncode, 0, err)
-
-        results = {}
-        for service in glob(self.out_dir + '/*.service'):
-            if os.path.islink(service):
-                continue
-            try:
-                # for python3 we need here strict=False to parse multiple
-                # lines with the same key
-                cp = RawConfigParser(dict_type=MultiDict, strict=False)
-            except TypeError:
-                # RawConfigParser in python2 does not have the strict option
-                # but it allows multiple lines with the same key by default
-                cp = RawConfigParser(dict_type=MultiDict)
-            cp.optionxform = lambda o: o  # don't lower-case option names
-            with open(service) as f:
-                cp.read_file(f)
-            results[os.path.basename(service)] = cp
-
-        return (err, results)
-
-    def add_sysv(self, fname, keys, enable=False, prio=1):
-        '''Create a SysV init script with the given keys in the LSB header
-
-        There are sensible default values for all fields.
-        If enable is True, links will be created in the rcN.d dirs. In that
-        case, the priority can be given with "prio" (default to 1).
-
-        Return path of generated script.
-        '''
-        name_without_sh = fname.endswith('.sh') and fname[:-3] or fname
-        keys.setdefault('Provides', name_without_sh)
-        keys.setdefault('Required-Start', '$local_fs')
-        keys.setdefault('Required-Stop', keys['Required-Start'])
-        keys.setdefault('Default-Start', '2 3 4 5')
-        keys.setdefault('Default-Stop', '0 1 6')
-        keys.setdefault('Short-Description', 'test {} service'.format(name_without_sh))
-        keys.setdefault('Description', 'long description for test {} service'.format(name_without_sh))
-        script = os.path.join(self.init_d_dir, fname)
-        with open(script, 'w') as f:
-            f.write('#!/bin/init-d-interpreter\n### BEGIN INIT INFO\n')
-            for k, v in keys.items():
-                if v is not None:
-                    f.write('#{:>20} {}\n'.format(k + ':', v))
-            f.write('### END INIT INFO\ncode --goes here\n')
-        os.chmod(script, 0o755)
-
-        if enable:
-            def make_link(prefix, runlevel):
-                d = os.path.join(self.rcnd_dir, 'rc{}.d'.format(runlevel))
-                if not os.path.isdir(d):
-                    os.mkdir(d)
-                os.symlink('../init.d/' + fname, os.path.join(d, prefix + fname))
-
-            for rl in keys['Default-Start'].split():
-                make_link('S%02i' % prio, rl)
-            for rl in keys['Default-Stop'].split():
-                make_link('K%02i' % (99 - prio), rl)
-
-        return script
-
-    def assert_enabled(self, unit, targets):
-        '''assert that a unit is enabled in precisely the given targets'''
-
-        all_targets = ['multi-user', 'graphical']
-
-        # should be enabled
-        for target in all_targets:
-            link = os.path.join(self.out_dir, '{}.target.wants'.format(target), unit)
-            if target in targets:
-                unit_file = os.readlink(link)
-                # os.path.exists() will fail on a dangling symlink
-                self.assertTrue(os.path.exists(link))
-                self.assertEqual(os.path.basename(unit_file), unit)
-            else:
-                self.assertFalse(os.path.exists(link),
-                                 '{} unexpectedly exists'.format(link))
-
-    #
-    # test cases
-    #
-
-    def test_nothing(self):
-        '''no input files'''
-
-        results = self.run_generator()[1]
-        self.assertEqual(results, {})
-        self.assertEqual(os.listdir(self.out_dir), [])
-
-    def test_simple_disabled(self):
-        '''simple service without dependencies, disabled'''
-
-        self.add_sysv('foo', {}, enable=False)
-        err, results = self.run_generator()
-        self.assertEqual(len(results), 1)
-
-        # no enablement links or other stuff
-        self.assertEqual(os.listdir(self.out_dir), ['foo.service'])
-
-        s = results['foo.service']
-        self.assertEqual(s.sections(), ['Unit', 'Service'])
-        self.assertEqual(s.get('Unit', 'Description'), 'LSB: test foo service')
-        # $local_fs does not need translation, don't expect any dependency
-        # fields here
-        self.assertEqual(set(s.options('Unit')),
-                         set(['Documentation', 'SourcePath', 'Description']))
-
-        self.assertEqual(s.get('Service', 'Type'), 'forking')
-        init_script = os.path.join(self.init_d_dir, 'foo')
-        self.assertEqual(s.get('Service', 'ExecStart'),
-                         '{} start'.format(init_script))
-        self.assertEqual(s.get('Service', 'ExecStop'),
-                         '{} stop'.format(init_script))
-
-        self.assertNotIn('Overwriting', err)
-
-    def test_simple_enabled_all(self):
-        '''simple service without dependencies, enabled in all runlevels'''
-
-        self.add_sysv('foo', {}, enable=True)
-        err, results = self.run_generator()
-        self.assertEqual(list(results), ['foo.service'])
-        self.assert_enabled('foo.service', ['multi-user', 'graphical'])
-        self.assertNotIn('Overwriting', err)
-
-    def test_simple_escaped(self):
-        '''simple service without dependencies, that requires escaping the name'''
-
-        self.add_sysv('foo+', {})
-        self.add_sysv('foo-admin', {})
-        err, results = self.run_generator()
-        self.assertEqual(set(results), {'foo-admin.service', 'foo\\x2b.service'})
-        self.assertNotIn('Overwriting', err)
-
-    def test_simple_enabled_some(self):
-        '''simple service without dependencies, enabled in some runlevels'''
-
-        self.add_sysv('foo', {'Default-Start': '2 4'}, enable=True)
-        err, results = self.run_generator()
-        self.assertEqual(list(results), ['foo.service'])
-        self.assert_enabled('foo.service', ['multi-user'])
-
-    def test_lsb_macro_dep_single(self):
-        '''single LSB macro dependency: $network'''
-
-        self.add_sysv('foo', {'Required-Start': '$network'})
-        s = self.run_generator()[1]['foo.service']
-        self.assertEqual(set(s.options('Unit')),
-                         set(['Documentation', 'SourcePath', 'Description', 'After', 'Wants']))
-        self.assertEqual(s.get('Unit', 'After'), 'network-online.target')
-        self.assertEqual(s.get('Unit', 'Wants'), 'network-online.target')
-
-    def test_lsb_macro_dep_multi(self):
-        '''multiple LSB macro dependencies'''
-
-        self.add_sysv('foo', {'Required-Start': '$named $portmap'})
-        s = self.run_generator()[1]['foo.service']
-        self.assertEqual(set(s.options('Unit')),
-                         set(['Documentation', 'SourcePath', 'Description', 'After']))
-        self.assertEqual(s.get('Unit', 'After').split(), ['nss-lookup.target', 'rpcbind.target'])
-
-    def test_lsb_deps(self):
-        '''LSB header dependencies to other services'''
-
-        # also give symlink priorities here; they should be ignored
-        self.add_sysv('foo', {'Required-Start': 'must1 must2',
-                              'Should-Start': 'may1 ne_may2'},
-                      enable=True, prio=40)
-        self.add_sysv('must1', {}, enable=True, prio=10)
-        self.add_sysv('must2', {}, enable=True, prio=15)
-        self.add_sysv('may1', {}, enable=True, prio=20)
-        # do not create ne_may2
-        err, results = self.run_generator()
-        self.assertEqual(sorted(results),
-                         ['foo.service', 'may1.service', 'must1.service', 'must2.service'])
-
-        # foo should depend on all of them
-        self.assertEqual(sorted(results['foo.service'].get('Unit', 'After').split()),
-                         ['may1.service', 'must1.service', 'must2.service', 'ne_may2.service'])
-
-        # other services should not depend on each other
-        self.assertFalse(results['must1.service'].has_option('Unit', 'After'))
-        self.assertFalse(results['must2.service'].has_option('Unit', 'After'))
-        self.assertFalse(results['may1.service'].has_option('Unit', 'After'))
-
-    def test_symlink_prio_deps(self):
-        '''script without LSB headers use rcN.d priority'''
-
-        # create two init.d scripts without LSB header and enable them with
-        # startup priorities
-        for prio, name in [(10, 'provider'), (15, 'consumer')]:
-            with open(os.path.join(self.init_d_dir, name), 'w') as f:
-                f.write('#!/bin/init-d-interpreter\ncode --goes here\n')
-                os.fchmod(f.fileno(), 0o755)
-
-            d = os.path.join(self.rcnd_dir, 'rc2.d')
-            if not os.path.isdir(d):
-                os.mkdir(d)
-            os.symlink('../init.d/' + name, os.path.join(d, 'S{:>2}{}'.format(prio, name)))
-
-        err, results = self.run_generator()
-        self.assertEqual(sorted(results), ['consumer.service', 'provider.service'])
-        self.assertFalse(results['provider.service'].has_option('Unit', 'After'))
-        self.assertEqual(results['consumer.service'].get('Unit', 'After'),
-                         'provider.service')
-
-    def test_multiple_provides(self):
-        '''multiple Provides: names'''
-
-        self.add_sysv('foo', {'Provides': 'foo bar baz'})
-        err, results = self.run_generator()
-        self.assertEqual(list(results), ['foo.service'])
-        self.assertEqual(set(results['foo.service'].options('Unit')),
-                         set(['Documentation', 'SourcePath', 'Description']))
-        # should create symlinks for the alternative names
-        for f in ['bar.service', 'baz.service']:
-            self.assertEqual(os.readlink(os.path.join(self.out_dir, f)),
-                             'foo.service')
-        self.assertNotIn('Overwriting', err)
-
-    def test_provides_escaped(self):
-        '''a script that Provides: a name that requires escaping'''
-
-        self.add_sysv('foo', {'Provides': 'foo foo+'})
-        err, results = self.run_generator()
-        self.assertEqual(list(results), ['foo.service'])
-        self.assertEqual(os.readlink(os.path.join(self.out_dir, 'foo\\x2b.service')),
-                         'foo.service')
-        self.assertNotIn('Overwriting', err)
-
-    def test_same_provides_in_multiple_scripts(self):
-        '''multiple init.d scripts provide the same name'''
-
-        self.add_sysv('foo', {'Provides': 'foo common'}, enable=True, prio=1)
-        self.add_sysv('bar', {'Provides': 'bar common'}, enable=True, prio=2)
-        err, results = self.run_generator()
-        self.assertEqual(sorted(results), ['bar.service', 'foo.service'])
-        # should create symlink for the alternative name for either unit
-        self.assertIn(os.readlink(os.path.join(self.out_dir, 'common.service')),
-                      ['foo.service', 'bar.service'])
-
-    def test_provide_other_script(self):
-        '''init.d scripts provides the name of another init.d script'''
-
-        self.add_sysv('foo', {'Provides': 'foo bar'}, enable=True)
-        self.add_sysv('bar', {'Provides': 'bar'}, enable=True)
-        err, results = self.run_generator()
-        self.assertEqual(sorted(results), ['bar.service', 'foo.service'])
-        # we do expect an overwrite here, bar.service should overwrite the
-        # alias link from foo.service
-        self.assertIn('Overwriting', err)
-
-    def test_nonexecutable_script(self):
-        '''ignores non-executable init.d script'''
-
-        os.chmod(self.add_sysv('foo', {}), 0o644)
-        err, results = self.run_generator()
-        self.assertEqual(results, {})
-
-    def test_sh_suffix(self):
-        '''init.d script with .sh suffix'''
-
-        self.add_sysv('foo.sh', {}, enable=True)
-        err, results = self.run_generator()
-        s = results['foo.service']
-
-        self.assertEqual(s.sections(), ['Unit', 'Service'])
-        # should not have a .sh
-        self.assertEqual(s.get('Unit', 'Description'), 'LSB: test foo service')
-
-        # calls correct script with .sh
-        init_script = os.path.join(self.init_d_dir, 'foo.sh')
-        self.assertEqual(s.get('Service', 'ExecStart'),
-                         '{} start'.format(init_script))
-        self.assertEqual(s.get('Service', 'ExecStop'),
-                         '{} stop'.format(init_script))
-
-        self.assert_enabled('foo.service', ['multi-user', 'graphical'])
-
-    def test_sh_suffix_with_provides(self):
-        '''init.d script with .sh suffix and Provides:'''
-
-        self.add_sysv('foo.sh', {'Provides': 'foo bar'})
-        err, results = self.run_generator()
-        # ensure we don't try to create a symlink to itself
-        self.assertNotIn('itself', err)
-        self.assertEqual(list(results), ['foo.service'])
-        self.assertEqual(results['foo.service'].get('Unit', 'Description'),
-                         'LSB: test foo service')
-
-        # should create symlink for the alternative name
-        self.assertEqual(os.readlink(os.path.join(self.out_dir, 'bar.service')),
-                         'foo.service')
-
-    def test_hidden_files(self):
-        '''init.d script with hidden file suffix'''
-
-        script = self.add_sysv('foo', {}, enable=True)
-        # backup files (not enabled in rcN.d/)
-        shutil.copy(script, script + '.dpkg-new')
-        shutil.copy(script, script + '.dpkg-dist')
-        shutil.copy(script, script + '.swp')
-        shutil.copy(script, script + '.rpmsave')
-
-        err, results = self.run_generator()
-        self.assertEqual(list(results), ['foo.service'])
-
-        self.assert_enabled('foo.service', ['multi-user', 'graphical'])
-
-    def test_backup_file(self):
-        '''init.d script with backup file'''
-
-        script = self.add_sysv('foo', {}, enable=True)
-        # backup files (not enabled in rcN.d/)
-        shutil.copy(script, script + '.bak')
-        shutil.copy(script, script + '.old')
-        shutil.copy(script, script + '.tmp')
-        shutil.copy(script, script + '.new')
-
-        err, results = self.run_generator()
-        print(err)
-        self.assertEqual(sorted(results), ['foo.service', 'foo.tmp.service'])
-
-        # ensure we don't try to create a symlink to itself
-        self.assertNotIn('itself', err)
-
-        self.assert_enabled('foo.service', ['multi-user', 'graphical'])
-        self.assert_enabled('foo.bak.service', [])
-        self.assert_enabled('foo.old.service', [])
-
-    def test_existing_native_unit(self):
-        '''existing native unit'''
-
-        with open(os.path.join(self.unit_dir, 'foo.service'), 'w') as f:
-            f.write('[Unit]\n')
-
-        self.add_sysv('foo.sh', {'Provides': 'foo bar'}, enable=True)
-        err, results = self.run_generator()
-        self.assertEqual(list(results), [])
-        # no enablement or alias links, as native unit is disabled
-        self.assertEqual(os.listdir(self.out_dir), [])
-
-
-if __name__ == '__main__':
-    unittest.main(testRunner=unittest.TextTestRunner(stream=sys.stdout, verbosity=2))
index 88e37fd4eb035096e2e2724fdd6ac55c9da5cb8d..f18357075a5a4623a0df8acc67c3fa37ad98dced 100755 (executable)
@@ -449,118 +449,6 @@ systemctl unset-environment IMPORT_THIS IMPORT_THIS_TOO
 (! systemctl show-environment | grep "^IMPORT_THIS=")
 (! systemctl show-environment | grep "^IMPORT_THIS_TOO=")
 
-# test for sysv-generator (issue #24990)
-if [[ -x /usr/lib/systemd/system-generators/systemd-sysv-generator ]]; then
-    # This is configurable via -Dsysvinit-path=, but we can't get the value
-    # at runtime, so let's just support the two most common paths for now.
-    [[ -d /etc/rc.d/init.d ]] && SYSVINIT_PATH="/etc/rc.d/init.d" || SYSVINIT_PATH="/etc/init.d"
-
-    # OpenSUSE leaves sysvinit-path enabled, which means systemd-sysv-generator is built
-    # but may not create the directory if there's no services that use it.
-    mkdir -p "$SYSVINIT_PATH"
-
-    # invalid dependency
-    cat >"${SYSVINIT_PATH:?}/issue-24990" <<\EOF
-#!/usr/bin/env bash
-
-### BEGIN INIT INFO
-# Provides:test1 test2
-# Required-Start:test1 $remote_fs $network
-# Required-Stop:test1 $remote_fs $network
-# Description:Test
-# Short-Description: Test
-### END INIT INFO
-
-case "$1" in
-    start)
-        echo "Starting issue-24990.service"
-        sleep 1000 &
-        ;;
-    stop)
-        echo "Stopping issue-24990.service"
-        sleep 10 &
-        ;;
-    *)
-        echo "Usage: service test {start|stop|restart|status}"
-        ;;
-esac
-EOF
-
-    chmod +x "$SYSVINIT_PATH/issue-24990"
-    systemctl daemon-reload
-    [[ -L /run/systemd/generator.late/test1.service ]]
-    [[ -L /run/systemd/generator.late/test2.service ]]
-    assert_eq "$(readlink -f /run/systemd/generator.late/test1.service)" "/run/systemd/generator.late/issue-24990.service"
-    assert_eq "$(readlink -f /run/systemd/generator.late/test2.service)" "/run/systemd/generator.late/issue-24990.service"
-    output=$(systemctl cat issue-24990)
-    assert_in "SourcePath=$SYSVINIT_PATH/issue-24990" "$output"
-    assert_in "Description=LSB: Test" "$output"
-    assert_in "After=test1.service" "$output"
-    assert_in "After=remote-fs.target" "$output"
-    assert_in "After=network-online.target" "$output"
-    assert_in "Wants=network-online.target" "$output"
-    assert_in "ExecStart=$SYSVINIT_PATH/issue-24990 start" "$output"
-    assert_in "ExecStop=$SYSVINIT_PATH/issue-24990 stop" "$output"
-    systemctl status issue-24990 || :
-    systemctl show issue-24990
-    assert_not_in "issue-24990.service" "$(systemctl show --property=After --value)"
-    assert_not_in "issue-24990.service" "$(systemctl show --property=Before --value)"
-
-    if ! systemctl is-active network-online.target; then
-        systemctl start network-online.target
-    fi
-
-    systemctl restart issue-24990
-    systemctl stop issue-24990
-
-    # valid dependency
-    cat >"$SYSVINIT_PATH/issue-24990" <<\EOF
-#!/usr/bin/env bash
-
-### BEGIN INIT INFO
-# Provides:test1 test2
-# Required-Start:$remote_fs
-# Required-Stop:$remote_fs
-# Description:Test
-# Short-Description: Test
-### END INIT INFO
-
-case "$1" in
-    start)
-        echo "Starting issue-24990.service"
-        sleep 1000 &
-        ;;
-    stop)
-        echo "Stopping issue-24990.service"
-        sleep 10 &
-        ;;
-    *)
-        echo "Usage: service test {start|stop|restart|status}"
-        ;;
-esac
-EOF
-
-    chmod +x "$SYSVINIT_PATH/issue-24990"
-    systemctl daemon-reload
-    [[ -L /run/systemd/generator.late/test1.service ]]
-    [[ -L /run/systemd/generator.late/test2.service ]]
-    assert_eq "$(readlink -f /run/systemd/generator.late/test1.service)" "/run/systemd/generator.late/issue-24990.service"
-    assert_eq "$(readlink -f /run/systemd/generator.late/test2.service)" "/run/systemd/generator.late/issue-24990.service"
-    output=$(systemctl cat issue-24990)
-    assert_in "SourcePath=$SYSVINIT_PATH/issue-24990" "$output"
-    assert_in "Description=LSB: Test" "$output"
-    assert_in "After=remote-fs.target" "$output"
-    assert_in "ExecStart=$SYSVINIT_PATH/issue-24990 start" "$output"
-    assert_in "ExecStop=$SYSVINIT_PATH/issue-24990 stop" "$output"
-    systemctl status issue-24990 || :
-    systemctl show issue-24990
-    assert_not_in "issue-24990.service" "$(systemctl show --property=After --value)"
-    assert_not_in "issue-24990.service" "$(systemctl show --property=Before --value)"
-
-    systemctl restart issue-24990
-    systemctl stop issue-24990
-fi
-
 # %J in WantedBy= causes ABRT (#26467)
 cat >/run/systemd/system/test-WantedBy.service <<EOF
 [Service]
index cdef21fa9b3b68119f23a300ade5dc5d35df5e26..7036c12b7c67299665dbb78e401e2201a6de1022 100644 (file)
@@ -16,9 +16,3 @@ L /var/lock - - - - ../run/lock
 {% if CREATE_LOG_DIRS %}
 L$ /var/log/README - - - - ../..{{DOC_DIR}}/README.logs
 {% endif %}
-
-{% if HAVE_SYSV_COMPAT %}
-# /run/lock/subsys is used for serializing SysV service execution, and
-# hence without use on SysV-less systems.
-d /run/lock/subsys 0755 root root -
-{% endif %}