Hi,

here's a couple of patches to improve busybox compatibility with
systemd:
- 0001 adds a minimal sd-daemon implementation to libbb
- 0002 implements socket activation for syslogd
- 0003 implements hwclock --systz
- 0004 adds example systemd units for a number of busybox applets

The sd-daemon stuff is a stripped-down version of the reference
implementation shipped with systemd, with only the bare minimum required
to make syslogd work (i.e. AF_UNIX socket activation). hwclock --systz
is based on the util-linux-ng implementation.

make bloatcheck for syslogd:

function                                             old     new   delta
sd_listen_fds                                          -     287    +287
.rodata                                           145677  145844    +167
xsystemd_unix_socket                                   -      88     +88
create_socket                                        154     175     +21
------------------------------------------------------------------------------
(add/remove: 3/0 grow/shrink: 2/0 up/down: 563/0)             Total: 563
bytes
   text    data     bss     dec     hex filename
 921266    4114    9536  934916   e4404 busybox_old
 922241    4114    9536  935891   e47d3 busybox_unstripped

and for hwclock:

function                                             old     new   delta
hwclock_main                                         345     461    +116
.rodata                                           145902  145945     +43
packed_usage                                       27401   27424     +23
static.hwclock_longopts                               53      61      +8
------------------------------------------------------------------------------
(add/remove: 0/0 grow/shrink: 4/0 up/down: 190/0)             Total: 190
bytes
   text    data     bss     dec     hex filename
 922188    4114    9568  935870   e47be busybox_old
 922347    4114    9568  936029   e485d busybox_unstripped

Please review - this is my first contribution to busybox, so let me know
if I've done something stupid :)

Regards,
Davide
>From 04a91949e46db799e67ec775d8349414abde1a34 Mon Sep 17 00:00:00 2001
From: Davide Cavalca <[email protected]>
Date: Sun, 16 Jan 2011 10:39:08 +0100
Subject: [PATCH 1/4] libbb: add minimal sd-daemon implementation


Signed-off-by: Davide Cavalca <[email protected]>
---
 include/sd-daemon.h |   36 +++++++++++
 libbb/sd-daemon.c   |  164 +++++++++++++++++++++++++++++++++++++++++++++++++++
 2 files changed, 200 insertions(+), 0 deletions(-)
 create mode 100644 include/sd-daemon.h
 create mode 100644 libbb/sd-daemon.c

diff --git a/include/sd-daemon.h b/include/sd-daemon.h
new file mode 100644
index 0000000..f605c52
--- /dev/null
+++ b/include/sd-daemon.h
@@ -0,0 +1,36 @@
+/*
+ * Copyright (C) 2011 Davide Cavalca <[email protected]>
+ *
+ * Based on http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.h
+ * Copyright 2010 Lennart Poettering
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#ifndef BB_SD_DAEMON_H
+#define BB_SD_DAEMON_H
+
+#define SD_LISTEN_FDS_START 3
+
+int sd_listen_fds(void);
+int xsystemd_unix_socket(const char *path);
+
+#endif
diff --git a/libbb/sd-daemon.c b/libbb/sd-daemon.c
new file mode 100644
index 0000000..2237e19
--- /dev/null
+++ b/libbb/sd-daemon.c
@@ -0,0 +1,164 @@
+/*
+ * Copyright (C) 2011 Davide Cavalca <[email protected]>
+ *
+ * Based on http://cgit.freedesktop.org/systemd/tree/src/sd-daemon.c
+ * Copyright 2010 Lennart Poettering
+ *
+ * Permission is hereby granted, free of charge, to any person
+ * obtaining a copy of this software and associated documentation files
+ * (the "Software"), to deal in the Software without restriction,
+ * including without limitation the rights to use, copy, modify, merge,
+ * publish, distribute, sublicense, and/or sell copies of the Software,
+ * and to permit persons to whom the Software is furnished to do so,
+ * subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice shall be
+ * included in all copies or substantial portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS
+ * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
+ * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+ * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+ * SOFTWARE.
+ */
+
+#include <sys/un.h>
+
+#include "libbb.h"
+#include "sd-daemon.h"
+
+int sd_listen_fds(void) {
+	int fd;
+	const char *e;
+	char *p = NULL;
+	unsigned long l;
+
+	if (!(e = getenv("LISTEN_PID")))
+		return 0;
+
+	errno = 0;
+	l = strtoul(e, &p, 10);
+
+	if (errno != 0)
+		return -errno;
+
+	if (!p || *p || l <= 0)
+		return -EINVAL;
+
+	/* Is this for us? */
+	if (getpid() != (pid_t) l)
+		return 0;
+
+	if (!(e = getenv("LISTEN_FDS")))
+		return 0;
+
+	errno = 0;
+	l = strtoul(e, &p, 10);
+
+	if (errno != 0)
+		return -errno;
+
+	if (!p || *p)
+		return -EINVAL;
+
+	for (fd = SD_LISTEN_FDS_START; fd < SD_LISTEN_FDS_START + (int) l; fd ++) {
+		int flags;
+
+		if ((flags = fcntl(fd, F_GETFD)) < 0)
+			return -errno;
+
+		if (flags & FD_CLOEXEC)
+			continue;
+
+		if (fcntl(fd, F_SETFD, flags | FD_CLOEXEC) < 0)
+			return -errno;
+	}
+
+	return (int) l;
+}
+
+static int sd_is_socket_internal(int fd, int type) {
+	struct stat st_fd;
+
+	if (fd < 0 || type < 0)
+		return -EINVAL;
+
+	if (fstat(fd, &st_fd) < 0)
+		return -errno;
+
+	if (!S_ISSOCK(st_fd.st_mode))
+		return 0;
+
+	if (type != 0) {
+		int other_type = 0;
+		socklen_t l = sizeof(other_type);
+
+		if (getsockopt(fd, SOL_SOCKET, SO_TYPE, &other_type, &l) < 0)
+			return -errno;
+
+		if (l != sizeof(other_type))
+			return -EINVAL;
+
+		if (other_type != type)
+			return 0;
+	}
+
+	return 1;
+}
+
+union sockaddr_union {
+        struct sockaddr sa;
+        struct sockaddr_in in4;
+        struct sockaddr_in6 in6;
+        struct sockaddr_un un;
+        struct sockaddr_storage storage;
+};
+
+static int sd_is_socket_unix(int fd, int type, const char *path) {
+	union sockaddr_union sockaddr;
+	socklen_t l;
+	int r;
+
+	if ((r = sd_is_socket_internal(fd, type)) <= 0)
+		return r;
+
+	memset(&sockaddr, 0, sizeof(sockaddr));
+	l = sizeof(sockaddr);
+
+	if (getsockname(fd, &sockaddr.sa, &l) < 0)
+		return -errno;
+
+	if (l < sizeof(sa_family_t))
+		return -EINVAL;
+
+	if (sockaddr.sa.sa_family != AF_UNIX)
+		return 0;
+
+	return (l >= offsetof(struct sockaddr_un, sun_path) + 1) &&
+		memcmp(path, sockaddr.un.sun_path, 1) == 0;
+}
+
+int xsystemd_unix_socket(const char *path) {
+	int r = sd_listen_fds();
+
+	if (r < 0)
+		bb_error_msg_and_die ("Failed to acquire systemd socket");
+	if (r > 1)
+		bb_error_msg_and_die ("Wrong number of systemd sockets passed");
+	if (r == 1) {
+		int fd = SD_LISTEN_FDS_START;
+
+		r = sd_is_socket_unix(fd, SOCK_DGRAM, path);
+		if (r < 0)
+			bb_error_msg_and_die ("Failed to verify systemd socket type");
+		if (!r)
+			bb_error_msg_and_die ("Passed systemd socket of wrong type");
+
+		return fd;
+	}
+
+	return -1;
+}
-- 
1.7.2.3

>From dabbfb2070c1223b8b439334eea4613d6328219b Mon Sep 17 00:00:00 2001
From: Davide Cavalca <[email protected]>
Date: Sun, 16 Jan 2011 10:40:58 +0100
Subject: [PATCH 2/4] syslogd: conditional systemd support


Signed-off-by: Davide Cavalca <[email protected]>
---
 libbb/Kbuild.src    |    2 ++
 sysklogd/Config.src |    8 ++++++++
 sysklogd/syslogd.c  |    8 ++++++++
 3 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/libbb/Kbuild.src b/libbb/Kbuild.src
index 0fa1451..119e0ad 100644
--- a/libbb/Kbuild.src
+++ b/libbb/Kbuild.src
@@ -160,6 +160,8 @@ lib-$(CONFIG_IOSTAT) += get_cpu_count.o
 lib-$(CONFIG_MPSTAT) += get_cpu_count.o
 lib-$(CONFIG_POWERTOP) += get_cpu_count.o
 
+lib-$(CONFIG_FEATURE_SYSLOGD_SYSTEMD) += sd-daemon.o
+
 # We shouldn't build xregcomp.c if we don't need it - this ensures we don't
 # require regex.h to be in the include dir even if we don't need it thereby
 # allowing us to build busybox even if uclibc regex support is disabled.
diff --git a/sysklogd/Config.src b/sysklogd/Config.src
index 1e59872..a9af225 100644
--- a/sysklogd/Config.src
+++ b/sysklogd/Config.src
@@ -22,6 +22,14 @@ config SYSLOGD
 	  wrong. And something almost always will go wrong if
 	  you wait long enough....
 
+config FEATURE_SYSLOGD_SYSTEMD
+	bool "Enable systemd socket activation support"
+	default n
+	depends on SYSLOGD && PLATFORM_LINUX
+	help
+	  This makes syslogd compliant to the systemd's New-Style Daemons
+	  guidelines and implements socket-based activation.
+
 config FEATURE_ROTATE_LOGFILE
 	bool "Rotate message files"
 	default y
diff --git a/sysklogd/syslogd.c b/sysklogd/syslogd.c
index fb73095..1837413 100644
--- a/sysklogd/syslogd.c
+++ b/sysklogd/syslogd.c
@@ -34,6 +34,9 @@
 #include <sys/shm.h>
 #endif
 
+#if ENABLE_FEATURE_SYSLOGD_SYSTEMD
+#include "sd-daemon.h"
+#endif
 
 #define DEBUG 0
 
@@ -512,6 +515,11 @@ static NOINLINE int create_socket(void)
 	int sock_fd;
 	char *dev_log_name;
 
+#if ENABLE_FEATURE_SYSLOGD_SYSTEMD
+	if ((sock_fd = xsystemd_unix_socket("/dev/log")) != -1)
+		return sock_fd;
+#endif
+	
 	memset(&sunx, 0, sizeof(sunx));
 	sunx.sun_family = AF_UNIX;
 
-- 
1.7.2.3

>From fbb5187b2823fba696fb1dae73c03280d97b3ee1 Mon Sep 17 00:00:00 2001
From: Davide Cavalca <[email protected]>
Date: Sun, 16 Jan 2011 15:48:15 +0100
Subject: [PATCH 3/4] hwclock: implement --systz


Signed-off-by: Davide Cavalca <[email protected]>
---
 include/usage.src.h  |    5 +++--
 util-linux/hwclock.c |   29 ++++++++++++++++++++++++++---
 2 files changed, 29 insertions(+), 5 deletions(-)

diff --git a/include/usage.src.h b/include/usage.src.h
index a4776a2..ca47137 100644
--- a/include/usage.src.h
+++ b/include/usage.src.h
@@ -1597,12 +1597,12 @@ INSERT
 
 #define hwclock_trivial_usage \
 	IF_FEATURE_HWCLOCK_LONG_OPTIONS( \
-       "[-r|--show] [-s|--hctosys] [-w|--systohc]" \
+       "[-r|--show] [-s|--hctosys] [-w|--systohc] [-t|--systz]" \
        " [-l|--localtime] [-u|--utc]" \
        " [-f FILE]" \
 	) \
 	IF_NOT_FEATURE_HWCLOCK_LONG_OPTIONS( \
-       "[-r] [-s] [-w] [-l] [-u] [-f FILE]" \
+       "[-r] [-s] [-w] [-t] [-l] [-u] [-f FILE]" \
 	)
 #define hwclock_full_usage "\n\n" \
        "Query and set hardware clock (RTC)\n" \
@@ -1610,6 +1610,7 @@ INSERT
      "\n	-r	Show hardware clock time" \
      "\n	-s	Set system time from hardware clock" \
      "\n	-w	Set hardware clock to system time" \
+     "\n	-t	Set the system time based on the current timezone" \
      "\n	-u	Hardware clock is in UTC" \
      "\n	-l	Hardware clock is in local time" \
      "\n	-f FILE	Use specified device (e.g. /dev/rtc2)" \
diff --git a/util-linux/hwclock.c b/util-linux/hwclock.c
index 922dd05..ad022c5 100644
--- a/util-linux/hwclock.c
+++ b/util-linux/hwclock.c
@@ -223,12 +223,32 @@ static void from_sys_clock(const char **pp_rtcname, int utc)
 		close(rtc);
 }
 
+static void set_system_clock_timezone(int utc)
+{
+	struct timeval tv;
+	struct tm *broken;
+	struct timezone tz;
+
+	gettimeofday(&tv, NULL);
+	broken = localtime(&tv.tv_sec);
+	tz.tz_minuteswest = timezone/60;
+	if (broken->tm_isdst)
+		tz.tz_minuteswest -= 60;
+	tz.tz_dsttime = 0;
+	gettimeofday(&tv, NULL);
+	if (!utc)
+		tv.tv_sec += tz.tz_minuteswest * 60;
+	if (settimeofday(&tv, &tz))
+		bb_perror_msg_and_die("settimeofday");
+}
+
 #define HWCLOCK_OPT_LOCALTIME   0x01
 #define HWCLOCK_OPT_UTC         0x02
 #define HWCLOCK_OPT_SHOW        0x04
 #define HWCLOCK_OPT_HCTOSYS     0x08
 #define HWCLOCK_OPT_SYSTOHC     0x10
-#define HWCLOCK_OPT_RTCFILE     0x20
+#define HWCLOCK_OPT_SYSTZ       0x20
+#define HWCLOCK_OPT_RTCFILE     0x40
 
 int hwclock_main(int argc, char **argv) MAIN_EXTERNALLY_VISIBLE;
 int hwclock_main(int argc UNUSED_PARAM, char **argv)
@@ -244,12 +264,13 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv)
 		"show\0"      No_argument "r"
 		"hctosys\0"   No_argument "s"
 		"systohc\0"   No_argument "w"
+		"systz\0"     No_argument "t"
 		"file\0"      Required_argument "f"
 		;
 	applet_long_options = hwclock_longopts;
 #endif
-	opt_complementary = "r--ws:w--rs:s--wr:l--u:u--l";
-	opt = getopt32(argv, "lurswf:", &rtcname);
+	opt_complementary = "r--wst:w--rst:s--wrt:t--rswt:l--u:u--l";
+	opt = getopt32(argv, "lurswtf:", &rtcname);
 
 	/* If -u or -l wasn't given check if we are using utc */
 	if (opt & (HWCLOCK_OPT_UTC | HWCLOCK_OPT_LOCALTIME))
@@ -261,6 +282,8 @@ int hwclock_main(int argc UNUSED_PARAM, char **argv)
 		to_sys_clock(&rtcname, utc);
 	else if (opt & HWCLOCK_OPT_SYSTOHC)
 		from_sys_clock(&rtcname, utc);
+	else if (opt & HWCLOCK_OPT_SYSTZ)
+		set_system_clock_timezone(utc);
 	else
 		/* default HWCLOCK_OPT_SHOW */
 		show_clock(&rtcname, utc);
-- 
1.7.2.3

>From d1c569411bf0a64cad366d336d65400fa2384d13 Mon Sep 17 00:00:00 2001
From: Davide Cavalca <[email protected]>
Date: Sun, 16 Jan 2011 17:05:43 +0100
Subject: [PATCH 4/4] examples: add systemd units for some applets


Signed-off-by: Davide Cavalca <[email protected]>
---
 examples/systemd/acpid.service    |    9 +++++++++
 examples/systemd/crond.service    |    9 +++++++++
 examples/systemd/klogd.service    |    9 +++++++++
 examples/systemd/syslogd.service  |   10 ++++++++++
 examples/systemd/[email protected] |    7 +++++++
 5 files changed, 44 insertions(+), 0 deletions(-)
 create mode 100644 examples/systemd/acpid.service
 create mode 100644 examples/systemd/crond.service
 create mode 100644 examples/systemd/klogd.service
 create mode 100644 examples/systemd/syslogd.service
 create mode 100644 examples/systemd/[email protected]

diff --git a/examples/systemd/acpid.service b/examples/systemd/acpid.service
new file mode 100644
index 0000000..5397420
--- /dev/null
+++ b/examples/systemd/acpid.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=ACPI Event Daemon
+After=syslog.target
+
+[Service]
+ExecStart=/sbin/acpid -d
+
+[Install]
+WantedBy=multi-user.target
diff --git a/examples/systemd/crond.service b/examples/systemd/crond.service
new file mode 100644
index 0000000..9eba329
--- /dev/null
+++ b/examples/systemd/crond.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Command Scheduler
+After=syslog.target
+
+[Service]
+ExecStart=/usr/sbin/crond -fS
+
+[Install]
+WantedBy=multi-user.target
diff --git a/examples/systemd/klogd.service b/examples/systemd/klogd.service
new file mode 100644
index 0000000..0208a0f
--- /dev/null
+++ b/examples/systemd/klogd.service
@@ -0,0 +1,9 @@
+[Unit]
+Description=Kernel Logger Daemon
+After=syslog.target
+
+[Service]
+ExecStart=/sbin/klogd -n
+
+[Install]
+WantedBy=multi-user.target
diff --git a/examples/systemd/syslogd.service b/examples/systemd/syslogd.service
new file mode 100644
index 0000000..9ff7174
--- /dev/null
+++ b/examples/systemd/syslogd.service
@@ -0,0 +1,10 @@
+[Unit]
+Description=System Logger Daemon
+
+[Service]
+ExecStartPre=/bin/systemctl stop systemd-syslog-kmsg.service
+ExecStart=/sbin/syslogd -n -C10240
+Sockets=syslog.socket
+
+[Install]
+WantedBy=multi-user.target
diff --git a/examples/systemd/[email protected] b/examples/systemd/[email protected]
new file mode 100644
index 0000000..e0897eb
--- /dev/null
+++ b/examples/systemd/[email protected]
@@ -0,0 +1,7 @@
+[Unit]
+Description=Telnet Per-Connection Server
+After=syslog.target
+
+[Service]
+ExecStart=/usr/sbin/telnetd -i
+StandardInput=socket
-- 
1.7.2.3

_______________________________________________
busybox mailing list
[email protected]
http://lists.busybox.net/mailman/listinfo/busybox

Reply via email to