From 322aafc99739dd509a95110045cbba4f327e3f4e Mon Sep 17 00:00:00 2001 From: Vincent Bernat Date: Mon, 7 Jan 2013 00:53:01 +0100 Subject: [PATCH] debian: add systemd support Provides a lldpd.service file and let `lldpd` notify systemd when it is ready using the notification socket. --- NEWS | 2 +- debian/lldpd.install | 1 + debian/lldpd.service | 15 ++++++++++++ src/daemon/lldpd.c | 54 +++++++++++++++++++++++++++++++++++++++++++- 4 files changed, 70 insertions(+), 2 deletions(-) create mode 100644 debian/lldpd.install create mode 100644 debian/lldpd.service diff --git a/NEWS b/NEWS index 924a7b0a..5f4e8acc 100644 --- a/NEWS +++ b/NEWS @@ -1,6 +1,6 @@ lldpd (0.7.1) * Features - + Upstart support. + + Upstart and systemd support. + Remove Unix socket when there is no process listening. lldpd (0.7.0) diff --git a/debian/lldpd.install b/debian/lldpd.install new file mode 100644 index 00000000..9c21c90b --- /dev/null +++ b/debian/lldpd.install @@ -0,0 +1 @@ +debian/lldpd.service lib/systemd/system/ diff --git a/debian/lldpd.service b/debian/lldpd.service new file mode 100644 index 00000000..aee82876 --- /dev/null +++ b/debian/lldpd.service @@ -0,0 +1,15 @@ +[Unit] +Description=LLDP daemon +Documentation=man:lldpd(8) + +[Service] +Type=notify +NotifyAccess=main +EnvironmentFile=-/etc/default/lldpd +ExecStart=/usr/sbin/lldpd $DAEMON_ARGS +ExecStartPre=mkdir -p /var/run/lldpd/etc +ExecStartPre=cp /etc/localtime /var/run/lldpd/etc/localtime +Restart=on-failure + +[Install] +WantedBy=multi-user.target diff --git a/src/daemon/lldpd.c b/src/daemon/lldpd.c index 27a80a7c..46ea049d 100644 --- a/src/daemon/lldpd.c +++ b/src/daemon/lldpd.c @@ -1026,12 +1026,63 @@ static const struct intint filters[] = { static int lldpd_started_by_upstart() { +#ifdef HOST_OS_LINUX const char *upstartjob = getenv("UPSTART_JOB"); if (!(upstartjob && !strcmp(upstartjob, "lldpd"))) return 0; log_debug("main", "running with upstart, don't fork but stop"); raise(SIGSTOP); return 1; +#else + return 0; +#endif +} + +/** + * Tell if we have been started by systemd. + */ +static int +lldpd_started_by_systemd() +{ +#ifdef HOST_OS_LINUX + int fd = -1; + const char *notifysocket = getenv("NOTIFY_SOCKET"); + if (!notifysocket || + !strchr("@/", notifysocket[0]) || + strlen(notifysocket) < 2) + return 0; + + log_debug("main", "running with systemd, don't fork but signal ready"); + if ((fd = socket(AF_UNIX, SOCK_DGRAM|SOCK_CLOEXEC, 0)) < 0) { + log_warn("main", "unable to open systemd notification socket %s", + notifysocket); + return 0; + } + + struct sockaddr_un su = { .sun_family = AF_UNIX }; + strlcpy(su.sun_path, notifysocket, sizeof(su.sun_path)); + if (notifysocket[0] == '@') su.sun_path[0] = 0; + + struct iovec iov = { + .iov_base = "READY=1", + .iov_len = strlen(iov.iov_base) + }; + struct msghdr hdr = { + .msg_name = &su, + .msg_namelen = offsetof(struct sockaddr_un, sun_path) + strlen(notifysocket), + .msg_iov = &iov, + .msg_iovlen = 1 + }; + if (sendmsg(fd, &hdr, MSG_NOSIGNAL) < 0) { + log_warn("main", "unable to send notification to systemd"); + close(fd); + return 0; + } + close(fd); + return 1; +#else + return 0; +#endif } int @@ -1224,7 +1275,8 @@ lldpd_main(int argc, char *argv[]) signal(SIGPIPE, SIG_IGN); /* Daemonization, unless started by upstart or debug */ - if (!lldpd_started_by_upstart() && !debug) { + if (!lldpd_started_by_upstart() && !lldpd_started_by_systemd() && + !debug) { int pid; char *spid; log_debug("main", "daemonize"); -- 2.39.5