Hi Lennart,

[sorry for sending it twice, forgot to include the ML]

On Mon, Sep 20, 2010 at 11:19 PM, Lennart Poettering
<lenn...@poettering.net> wrote:
> On Sun, 19.09.10 21:25, Tom Gundersen (t...@jklm.no) wrote:
>> +#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;
>> +                     }
>> +             }
>
> Looks like this could be simplified as:
>
> arch_daemons[strcspn(arch_daemons, ")"] = 0;

Yes, you are right.

>> +             for (i=0; i < strlen(arch_daemons); i++) { /* find position of 
>> start paren */
>> +                     if (arch_daemons[i] == '(') {
>> +                             i++;
>> +                             break;
>> +                     }
>> +             }
>
> Similarly here:
>
> if (!(p = strchr(arch_deamons, '('))))
>        p = arch_daemons;
>
> And then just use p from then on.

Can't use p as it's the wrong type and this would still include the
leading '(', but I got your point.

> Otherwise looks fine!

Great. Here is an updated patch.

Cheers,

Tom
From 0542f996bb298c14332ad746734250e0181b651f 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).

v2: simplified after suggestion from Lennart
---
 src/service.c |   64 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 files changed, 64 insertions(+), 0 deletions(-)

diff --git a/src/service.c b/src/service.c
index df0d400..cd22b72 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,64 @@ 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[strcspn(arch_daemons, ")")] = 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 +2858,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.3

_______________________________________________
systemd-devel mailing list
systemd-devel@lists.freedesktop.org
http://lists.freedesktop.org/mailman/listinfo/systemd-devel

Reply via email to