On Sun, Sep 19, 2010 at 2:25 PM, Tom Gundersen <t...@jklm.no> wrote: > This patch should allow SystemD to be a drop-in replacement for SysV > init on Arch (modulo some minor bugs), as long as one uses a recent > kernel and dbus from [testing].
Turns out I missed a bug. This version should also work in case there is no DAEMONS array in /etc/rc.conf. Cheers, Tom
From d6956e52edc9759a8190727bea406513e8fb47ea Mon Sep 17 00:00:00 2001 From: Tom Gundersen <t...@jklm.no> Date: Sat, 18 Sep 2010 23:45:00 +0100 Subject: [PATCH] service: start Arch daemons Arch does not use proper SysV runlevels. Instead /etc/rc.conf contains an array of daemons to load in a multi-user runlevel, and some dependencies between them. This patch enables this behaviour in SystemD (only when compiled with Arch support), which allows SystemD to be a drop in replacement on Arch (modulo some minor bugs). --- src/service.c | 72 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 72 insertions(+), 0 deletions(-) diff --git a/src/service.c b/src/service.c index df0d400..383c569 100644 --- a/src/service.c +++ b/src/service.c @@ -231,6 +231,11 @@ static char *sysv_translate_name(const char *name) { else if (endswith(name, ".sh")) /* Drop Debian-style .sh suffix */ strcpy(stpcpy(r, name) - 3, ".service"); +#ifdef TARGET_ARCH + else if (startswith(name, "@")) + /* Drop Arch-style background prefix */ + strcpy(stpcpy(r, name + 1), ".service"); +#endif else /* Normal init scripts */ strcpy(stpcpy(r, name), ".service"); @@ -2658,9 +2663,72 @@ static int service_enumerate(Manager *m) { Unit *service; Iterator j; int r; +#ifdef TARGET_ARCH + Unit *previous = NULL; + char *arch_daemons = NULL; + char **arch_daemons_split = NULL; +#endif assert(m); +#ifdef TARGET_ARCH + if ((r = parse_env_file("/etc/rc.conf", NEWLINE, + "DAEMONS", &arch_daemons, + NULL)) < 0) { + if (r != -ENOENT) + log_warning("Failed to read /etc/rc.conf: %s", strerror(-r)); + } + else if (arch_daemons) { + for (i=0; i < strlen(arch_daemons); i++) { /* strip of end paren */ + if (arch_daemons[i] == ')') { + arch_daemons[i] = 0; + break; + } + } + for (i=0; i < strlen(arch_daemons); i++) { /* find position of start paren */ + if (arch_daemons[i] == '(') { + i++; + break; + } + } + if (i == strlen(arch_daemons)) /* no start paren found */ + i = 0; + + if (!(arch_daemons_split = strv_split_quoted(arch_daemons + i))) { + r = -ENOMEM; + goto finish; + } + + STRV_FOREACH(p, arch_daemons_split) { + + free(name); + + if (**p == '!') /* daemons prefixed with ! are disabled, so ignore them */ + continue; + + if (!(name = sysv_translate_name(*p))) { + r = -ENOMEM; + goto finish; + } + + if ((r = manager_load_unit_prepare(m, name, NULL, NULL, &service)) < 0) { + log_warning("Failed to prepare unit %s: %s", name, strerror(-r)); + continue; + } + + if ((r = unit_add_two_dependencies_by_name_inverse(service, UNIT_AFTER, UNIT_WANTS, "multi-user.target", NULL, true)) < 0) + goto finish; + + if (previous) + if ((r = unit_add_dependency(service, UNIT_AFTER, previous, true)) < 0) + goto finish; + + if (**p != '@') /* daemons prefixed with @ can be started in the background */ + previous = service; + } + } +#endif + zero(runlevel_services); STRV_FOREACH(p, m->lookup_paths.sysvrcnd_path) @@ -2798,6 +2866,10 @@ finish: free(path); free(fpath); free(name); +#ifdef TARGET_ARCH + free(arch_daemons); + free(arch_daemons_split); +#endif for (i = 0; i < ELEMENTSOF(rcnd_table); i++) set_free(runlevel_services[i]); -- 1.7.2.3
_______________________________________________ systemd-devel mailing list systemd-devel@lists.freedesktop.org http://lists.freedesktop.org/mailman/listinfo/systemd-devel