Commit 980900c1 authored by Tom Gundersen's avatar Tom Gundersen Committed by Lennart Poettering
Browse files

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).

v2: simplified after suggestion from Lennart
parent 5bfcc1c6
......@@ -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,66 @@ 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_stripped = 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) {
if (!(arch_daemons_stripped = strchr(arch_daemons, '(')))
arch_daemons_stripped = arch_daemons;
else
arch_daemons_stripped++; /* strip start paren */
arch_daemons_stripped[strcspn(arch_daemons_stripped, ")")] = 0; /* strip end paren */
if (!(arch_daemons_split = strv_split_quoted(arch_daemons_stripped))) {
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 +2860,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]);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment