[PATCH] Allow disable of SysV init/rcN.d support at compile time.

Gustavo Sverzut Barbieri barbieri at profusion.mobi
Wed Sep 8 07:35:08 PDT 2010


This patch adds a cpp definition HAVE_SYSV_COMPAT that is used to
isolate code dealing with /etc/init.d and /etc/rcN.d for systems where
it does not make sense (one that does not use sysv or one that is fully
systemd native).

The patch tries to be as little intrusive as possible, however in
order to minimize the number of #ifdef'ed regions I've reordered some
code in path-lookup.c:lookup_paths_init() where all code dealing with
sysv is now isolated under running_as == MANAGER_SYSTEM as well.
---
 configure.ac       |   17 ++++++---
 src/build.h        |    8 ++++-
 src/dbus-manager.c |    2 +
 src/path-lookup.c  |  102 ++++++++++++++++++++++++++++------------------------
 src/path-lookup.h  |    2 +
 src/service.c      |   41 ++++++++++++++++-----
 6 files changed, 109 insertions(+), 63 deletions(-)

diff --git a/configure.ac b/configure.ac
index ba9bbf8..30b291f 100644
--- a/configure.ac
+++ b/configure.ac
@@ -310,7 +310,8 @@ case $with_distro in
                 M4_DISTRO_FLAG=-DTARGET_ARCH=1
                 ;;
         gentoo)
-                SYSTEM_SYSVRCND_PATH=/etc
+                SYSTEM_SYSVINIT_PATH=
+                SYSTEM_SYSVRCND_PATH=
                 SPECIAL_SYSLOG_SERVICE=syslog-ng.service
                 AC_DEFINE(TARGET_GENTOO, [], [Target is Gentoo])
                 M4_DISTRO_FLAG=-DTARGET_GENTOO=1
@@ -322,10 +323,6 @@ case $with_distro in
                 M4_DISTRO_FLAG=-DTARGET_SLACKWARE=1
                 ;;
         other)
-                AS_IF([test "x$with_sysvinit_path" = "x"],
-                        [AC_MSG_ERROR([With --distro=other, you must pass --with-sysvinit-path= to configure])])
-                AS_IF([test "x$with_sysvrcd_path" = "x"],
-                        [AC_MSG_ERROR([With --distro=other, you must pass --with-sysvrcd-path= to configure])])
                 AS_IF([test "x$with_syslog_service" = "x"],
                         [AC_MSG_ERROR([With --distro=other, you must pass --with-syslog-service= to configure])])
                 ;;
@@ -357,6 +354,15 @@ AC_SUBST(SYSTEM_SYSVRCND_PATH)
 AC_SUBST(SPECIAL_SYSLOG_SERVICE)
 AC_SUBST(M4_DISTRO_FLAG)
 
+if test "x${SYSTEM_SYSVINIT_PATH}" != "x" -a "x${SYSTEM_SYSVRCND_PATH}" != "x"; then
+        AC_DEFINE(HAVE_SYSV_COMPAT, [], [SysV init scripts and rcN.d links are supported.])
+        SYSTEM_SYSV_COMPAT="enabled"
+elif test "x${SYSTEM_SYSVINIT_PATH}" != "x" -o "x${SYSTEM_SYSVRCND_PATH}" != "x"; then
+        AC_MSG_ERROR([*** You need both --with-sysvinit-path=PATH and --with-sysvrcd-path=PATH to enable SysV compatibility support, or both empty to disable it.])
+else
+        SYSTEM_SYSV_COMPAT="disabled"
+fi
+
 AM_CONDITIONAL(TARGET_FEDORA, test x"$with_distro" = xfedora)
 AM_CONDITIONAL(TARGET_SUSE, test x"$with_distro" = xsuse)
 AM_CONDITIONAL(TARGET_DEBIAN, test x"$with_distro" = xdebian)
@@ -416,6 +422,7 @@ echo "
         $PACKAGE_NAME $VERSION
 
         Distribution:            ${with_distro}
+        SysV compatibility:      ${SYSTEM_SYSV_COMPAT}
         SysV init scripts:       ${SYSTEM_SYSVINIT_PATH}
         SysV rc?.d directories:  ${SYSTEM_SYSVRCND_PATH}
         Syslog service:          ${SPECIAL_SYSLOG_SERVICE}
diff --git a/src/build.h b/src/build.h
index 5cb69be..b7f647a 100644
--- a/src/build.h
+++ b/src/build.h
@@ -46,6 +46,12 @@
 #define _SELINUX_FEATURE_ "-SELINUX"
 #endif
 
-#define SYSTEMD_FEATURES _PAM_FEATURE_ " " _LIBWRAP_FEATURE_ " " _AUDIT_FEATURE_ " " _SELINUX_FEATURE_
+#ifdef HAVE_SYSV
+#define _SYSVINIT_FEATURE_ "+SYSVINIT"
+#else
+#define _SYSVINIT_FEATURE_ "-SYSVINIT"
+#endif
+
+#define SYSTEMD_FEATURES _PAM_FEATURE_ " " _LIBWRAP_FEATURE_ " " _AUDIT_FEATURE_ " " _SELINUX_FEATURE_ " " _SYSVINIT_FEATURE_
 
 #endif
diff --git a/src/dbus-manager.c b/src/dbus-manager.c
index cffa547..f268e10 100644
--- a/src/dbus-manager.c
+++ b/src/dbus-manager.c
@@ -250,8 +250,10 @@ static DBusHandlerResult bus_manager_message_handler(DBusConnection *connection,
                 { "org.freedesktop.systemd1.Manager", "ShowStatus",    bus_property_append_bool,      "b",  &m->show_status    },
                 { "org.freedesktop.systemd1.Manager", "SysVConsole",   bus_property_append_bool,      "b",  &m->sysv_console   },
                 { "org.freedesktop.systemd1.Manager", "UnitPath",      bus_property_append_strv,      "as", m->lookup_paths.unit_path },
+#ifdef HAVE_SYSV_COMPAT
                 { "org.freedesktop.systemd1.Manager", "SysVInitPath",  bus_property_append_strv,      "as", m->lookup_paths.sysvinit_path },
                 { "org.freedesktop.systemd1.Manager", "SysVRcndPath",  bus_property_append_strv,      "as", m->lookup_paths.sysvrcnd_path },
+#endif
                 { "org.freedesktop.systemd1.Manager", "NotifySocket",  bus_property_append_string,    "s",  m->notify_socket   },
                 { "org.freedesktop.systemd1.Manager", "ControlGroupHierarchy", bus_property_append_string, "s", m->cgroup_hierarchy },
                 { "org.freedesktop.systemd1.Manager", "MountAuto",     bus_property_append_bool,      "b",  &m->mount_auto     },
diff --git a/src/path-lookup.c b/src/path-lookup.c
index 28336eb..258252a 100644
--- a/src/path-lookup.c
+++ b/src/path-lookup.c
@@ -191,7 +191,26 @@ int lookup_paths_init(LookupPaths *p, ManagerRunningAs running_as) {
                                 return -ENOMEM;
         }
 
+        if (p->unit_path)
+                if (!strv_path_canonicalize(p->unit_path))
+                        return -ENOMEM;
+
+        strv_uniq(p->unit_path);
+
+        if (!strv_isempty(p->unit_path)) {
+
+                if (!(t = strv_join(p->unit_path, "\n\t")))
+                        return -ENOMEM;
+                log_debug("Looking for unit files in:\n\t%s", t);
+                free(t);
+        } else {
+                log_debug("Ignoring unit files.");
+                strv_free(p->unit_path);
+                p->unit_path = NULL;
+        }
+
         if (running_as == MANAGER_SYSTEM) {
+#ifdef HAVE_SYSV_COMPAT
                 /* /etc/init.d/ compatibility does not matter to users */
 
                 if ((e = getenv("SYSTEMD_SYSVINIT_PATH")))
@@ -219,60 +238,46 @@ int lookup_paths_init(LookupPaths *p, ManagerRunningAs running_as) {
                                               NULL)))
                                 return -ENOMEM;
                 }
-        }
-
-        if (p->unit_path)
-                if (!strv_path_canonicalize(p->unit_path))
-                        return -ENOMEM;
-
-        if (p->sysvinit_path)
-                if (!strv_path_canonicalize(p->sysvinit_path))
-                        return -ENOMEM;
 
-        if (p->sysvrcnd_path)
-                if (!strv_path_canonicalize(p->sysvrcnd_path))
-                        return -ENOMEM;
-
-        strv_uniq(p->unit_path);
-        strv_uniq(p->sysvinit_path);
-        strv_uniq(p->sysvrcnd_path);
+                if (p->sysvinit_path)
+                        if (!strv_path_canonicalize(p->sysvinit_path))
+                                return -ENOMEM;
 
-        if (!strv_isempty(p->unit_path)) {
+                if (p->sysvrcnd_path)
+                        if (!strv_path_canonicalize(p->sysvrcnd_path))
+                                return -ENOMEM;
 
-                if (!(t = strv_join(p->unit_path, "\n\t")))
-                        return -ENOMEM;
-                log_debug("Looking for unit files in:\n\t%s", t);
-                free(t);
-        } else {
-                log_debug("Ignoring unit files.");
-                strv_free(p->unit_path);
-                p->unit_path = NULL;
-        }
+                strv_uniq(p->sysvinit_path);
+                strv_uniq(p->sysvrcnd_path);
 
-        if (!strv_isempty(p->sysvinit_path)) {
+                if (!strv_isempty(p->sysvinit_path)) {
 
-                if (!(t = strv_join(p->sysvinit_path, "\n\t")))
-                        return -ENOMEM;
+                        if (!(t = strv_join(p->sysvinit_path, "\n\t")))
+                                return -ENOMEM;
 
-                log_debug("Looking for SysV init scripts in:\n\t%s", t);
-                free(t);
-        } else {
-                log_debug("Ignoring SysV init scripts.");
-                strv_free(p->sysvinit_path);
-                p->sysvinit_path = NULL;
-        }
+                        log_debug("Looking for SysV init scripts in:\n\t%s", t);
+                        free(t);
+                } else {
+                        log_debug("Ignoring SysV init scripts.");
+                        strv_free(p->sysvinit_path);
+                        p->sysvinit_path = NULL;
+                }
 
-        if (!strv_isempty(p->sysvrcnd_path)) {
+                if (!strv_isempty(p->sysvrcnd_path)) {
 
-                if (!(t = strv_join(p->sysvrcnd_path, "\n\t")))
-                        return -ENOMEM;
+                        if (!(t = strv_join(p->sysvrcnd_path, "\n\t")))
+                                return -ENOMEM;
 
-                log_debug("Looking for SysV rcN.d links in:\n\t%s", t);
-                free(t);
-        } else {
-                log_debug("Ignoring SysV rcN.d links.");
-                strv_free(p->sysvrcnd_path);
-                p->sysvrcnd_path = NULL;
+                        log_debug("Looking for SysV rcN.d links in:\n\t%s", t);
+                        free(t);
+                } else {
+                        log_debug("Ignoring SysV rcN.d links.");
+                        strv_free(p->sysvrcnd_path);
+                        p->sysvrcnd_path = NULL;
+                }
+#else
+                log_debug("Disabled SysV init scripts and rcN.d links support");
+#endif
         }
 
         return 0;
@@ -282,8 +287,11 @@ void lookup_paths_free(LookupPaths *p) {
         assert(p);
 
         strv_free(p->unit_path);
+        p->unit_path = NULL;
+
+#ifdef HAVE_SYSV_COMPAT
         strv_free(p->sysvinit_path);
         strv_free(p->sysvrcnd_path);
-
-        p->unit_path = p->sysvinit_path = p->sysvrcnd_path = NULL;
+        p->sysvinit_path = p->sysvrcnd_path = NULL;
+#endif
 }
diff --git a/src/path-lookup.h b/src/path-lookup.h
index f53aa21..dca8b55 100644
--- a/src/path-lookup.h
+++ b/src/path-lookup.h
@@ -24,8 +24,10 @@
 
 typedef struct LookupPaths {
         char **unit_path;
+#ifdef HAVE_SYSV_COMPAT
         char **sysvinit_path;
         char **sysvrcnd_path;
+#endif
 } LookupPaths;
 
 #include "manager.h"
diff --git a/src/service.c b/src/service.c
index efa5277..efd1266 100644
--- a/src/service.c
+++ b/src/service.c
@@ -44,6 +44,7 @@ typedef enum RunlevelType {
         RUNLEVEL_SYSINIT
 } RunlevelType;
 
+#ifdef HAVE_SYSV_COMPAT
 static const struct {
         const char *path;
         const char *target;
@@ -80,6 +81,7 @@ static const struct {
 #define RUNLEVELS_UP "12345"
 /* #define RUNLEVELS_DOWN "06" */
 /* #define RUNLEVELS_BOOT "bBsS" */
+#endif
 
 static const UnitActiveState state_translation_table[_SERVICE_STATE_MAX] = {
         [SERVICE_DEAD] = UNIT_INACTIVE,
@@ -108,7 +110,9 @@ static void service_init(Unit *u) {
         s->timeout_usec = DEFAULT_TIMEOUT_USEC;
         s->restart_usec = DEFAULT_RESTART_USEC;
         s->timer_watch.type = WATCH_INVALID;
+#ifdef HAVE_SYSV_COMPAT
         s->sysv_start_priority = -1;
+#endif
         s->socket_fd = -1;
 
         exec_context_init(&s->exec_context);
@@ -189,11 +193,13 @@ static void service_done(Unit *u) {
         free(s->pid_file);
         s->pid_file = NULL;
 
+#ifdef HAVE_SYSV_COMPAT
         free(s->sysv_path);
         s->sysv_path = NULL;
 
         free(s->sysv_runlevels);
         s->sysv_runlevels = NULL;
+#endif
 
         free(s->status_text);
         s->status_text = NULL;
@@ -219,6 +225,7 @@ static void service_done(Unit *u) {
         unit_unwatch_timer(u, &s->timer_watch);
 }
 
+#ifdef HAVE_SYSV_COMPAT
 static char *sysv_translate_name(const char *name) {
         char *r;
 
@@ -823,6 +830,7 @@ static int service_load_sysv(Service *s) {
 
         return 0;
 }
+#endif
 
 static int service_add_bus_name(Service *s) {
         char *n;
@@ -904,10 +912,12 @@ static int service_load(Unit *u) {
         if ((r = unit_load_fragment(u)) < 0)
                 return r;
 
+#ifdef HAVE_SYSV_COMPAT
         /* Load a classic init script as a fallback, if we couldn't find anything */
         if (u->meta.load_state == UNIT_STUB)
                 if ((r = service_load_sysv(s)) < 0)
                         return r;
+#endif
 
         /* Still nothing found? Then let's give up */
         if (u->meta.load_state == UNIT_STUB)
@@ -926,8 +936,10 @@ static int service_load(Unit *u) {
                 if ((r = unit_add_default_cgroup(u)) < 0)
                         return r;
 
+#ifdef HAVE_SYSV_COMPAT
                 if ((r = sysv_fix_order(s)) < 0)
                         return r;
+#endif
 
                 if (s->bus_name) {
                         if ((r = service_add_bus_name(s)) < 0)
@@ -1015,6 +1027,7 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
                 exec_command_dump_list(s->exec_command[c], f, prefix2);
         }
 
+#ifdef HAVE_SYSV_COMPAT
         if (s->sysv_path)
                 fprintf(f,
                         "%sSysV Init Script Path: %s\n"
@@ -1032,6 +1045,7 @@ static void service_dump(Unit *u, FILE *f, const char *prefix) {
         if (s->sysv_runlevels)
                 fprintf(f, "%sSysVRunLevels: %s\n",
                         prefix, s->sysv_runlevels);
+#endif
 
         if (s->status_text)
                 fprintf(f, "%sStatus Text: %s\n",
@@ -2297,9 +2311,11 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
         assert(s);
         assert(pid >= 0);
 
+#ifdef HAVE_SYSV_COMPAT
         if (s->sysv_path)
                 success = is_clean_exit_lsb(code, status);
         else
+#endif
                 success = is_clean_exit(code, status);
 
         if (s->main_pid == pid) {
@@ -2667,19 +2683,20 @@ static void service_notify_message(Unit *u, pid_t pid, char **tags) {
 }
 
 static int service_enumerate(Manager *m) {
-        char **p;
-        unsigned i;
         DIR *d = NULL;
         char *path = NULL, *fpath = NULL, *name = NULL;
-        Set *runlevel_services[ELEMENTSOF(rcnd_table)], *shutdown_services = NULL;
-        Unit *service;
-        Iterator j;
         int r;
 
         assert(m);
 
-        zero(runlevel_services);
+#ifdef HAVE_SYSV_COMPAT
+        Set *runlevel_services[ELEMENTSOF(rcnd_table)], *shutdown_services = NULL;
+        Unit *service;
+        Iterator j;
+        unsigned i;
+        char **p;
 
+        zero(runlevel_services);
         STRV_FOREACH(p, m->lookup_paths.sysvrcnd_path)
                 for (i = 0; i < ELEMENTSOF(rcnd_table); i ++) {
                         struct dirent *de;
@@ -2772,6 +2789,7 @@ static int service_enumerate(Manager *m) {
                                 }
                         }
                 }
+#endif
 
         /* Now we loaded all stubs and are aware of the lowest
         start-up priority for all services, not let's actually load
@@ -2779,6 +2797,7 @@ static int service_enumerate(Manager *m) {
         actually native now */
         manager_dispatch_load_queue(m);
 
+#ifdef HAVE_SYSV_COMPAT
         /* If this is a native service, rely on native ways to pull in
          * a service, don't pull it in via sysv rcN.d links. */
         for (i = 0; i < ELEMENTSOF(rcnd_table); i ++)
@@ -2808,17 +2827,19 @@ static int service_enumerate(Manager *m) {
                 if ((r = unit_add_two_dependencies_by_name_inverse(service, UNIT_AFTER, UNIT_CONFLICTS, SPECIAL_SHUTDOWN_TARGET, NULL, true)) < 0)
                         goto finish;
         }
+#endif
 
         r = 0;
 
+#ifdef HAVE_SYSV_COMPAT
 finish:
-        free(path);
-        free(fpath);
-        free(name);
-
         for (i = 0; i < ELEMENTSOF(rcnd_table); i++)
                 set_free(runlevel_services[i]);
         set_free(shutdown_services);
+#endif
+        free(path);
+        free(fpath);
+        free(name);
 
         if (d)
                 closedir(d);
-- 
1.7.1



More information about the systemd-devel mailing list