You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
181 lines
5.3 KiB
181 lines
5.3 KiB
11 years ago
|
From 171ac321f1e97a60fbda3858c4c84d60d0b7dacb Mon Sep 17 00:00:00 2001
|
||
|
From: Alec Leamas <alec@tests.notat.diaspora.com>
|
||
|
Date: Wed, 9 Oct 2013 20:57:12 +0200
|
||
|
Subject: [PATCH 104/105] Add systemd socket activation support.
|
||
|
|
||
|
Since systemd was introduced lirc clients have had problems at
|
||
|
startup when trying to connect to the lircd socket before it's
|
||
|
created. The root cause is the aggressive parallell boot performed
|
||
|
by systemd.
|
||
|
|
||
|
The solution is to add socket activation. In this mode, the socket
|
||
|
is created by systemd and handed over to lircd at startup. The patch
|
||
|
implements this. It should be reasonably transparent.
|
||
|
|
||
|
At configure time it enables systemd support if it's available,
|
||
|
otherwise it's silently ignored.
|
||
|
|
||
|
In runtime lircd looks for and uses a socket handed over by systemd.
|
||
|
If there is no such socket it proceeds as normal.
|
||
|
|
||
|
Adds a dependency on pkg-config for the PKG_CHECK_MODULES macro.
|
||
|
---
|
||
|
configure.ac | 7 +++++
|
||
|
daemons/lircd.c | 94 ++++++++++++++++++++++++++++++++++-----------------------
|
||
|
2 files changed, 63 insertions(+), 38 deletions(-)
|
||
|
|
||
|
diff --git a/configure.ac b/configure.ac
|
||
|
index af28e4f..7df186a 100644
|
||
|
--- a/configure.ac
|
||
|
+++ b/configure.ac
|
||
|
@@ -232,6 +232,9 @@ AH_TEMPLATE([HAVE_SCSI],
|
||
|
AH_TEMPLATE([HAVE_SOUNDCARD],
|
||
|
[defined if soundcard API is available])
|
||
|
|
||
|
+AH_TEMPLATE([HAVE_SYSTEMD],
|
||
|
+ [defined if systemd API is available])
|
||
|
+
|
||
|
AH_TEMPLATE([HAVE_VSYSLOG],
|
||
|
[define if you have vsyslog( prio, fmt, va_arg )])
|
||
|
|
||
|
@@ -414,6 +417,10 @@ AC_CHECK_HEADERS(linux/i2c-dev.h,[
|
||
|
]
|
||
|
)
|
||
|
|
||
|
+PKG_CHECK_MODULES([SYSTEMD],[libsystemd-daemon],[AC_DEFINE(HAVE_SYSTEMD)],[true])
|
||
|
+CFLAGS="$CFLAGS $SYSTEMD_CFLAGS"
|
||
|
+LIBS="$LIBS $SYSTEMD_LIBS"
|
||
|
+
|
||
|
dnl here we see what driver the user wants.
|
||
|
|
||
|
AC_ARG_WITH(driver,
|
||
|
diff --git a/daemons/lircd.c b/daemons/lircd.c
|
||
|
index 8ace7af..9cde69b 100644
|
||
|
--- a/daemons/lircd.c
|
||
|
+++ b/daemons/lircd.c
|
||
|
@@ -63,6 +63,10 @@
|
||
|
#include "input_map.h"
|
||
|
#endif
|
||
|
|
||
|
+#ifdef HAVE_SYSTEMD
|
||
|
+#include "systemd/sd-daemon.h"
|
||
|
+#endif
|
||
|
+
|
||
|
#if defined __APPLE__ || defined __FreeBSD__
|
||
|
#include <sys/ioctl.h>
|
||
|
#endif
|
||
|
@@ -855,6 +859,7 @@ void start_server(mode_t permission, int nodaemon)
|
||
|
int ret;
|
||
|
int new = 1;
|
||
|
int fd;
|
||
|
+ int n;
|
||
|
|
||
|
/* create pid lockfile in /var/run */
|
||
|
if ((fd = open(pidfile, O_RDWR | O_CREAT, 0644)) == -1 || (pidf = fdopen(fd, "r+")) == NULL) {
|
||
|
@@ -881,51 +886,64 @@ void start_server(mode_t permission, int nodaemon)
|
||
|
(void)ftruncate(fileno(pidf), ftell(pidf));
|
||
|
|
||
|
/* create socket */
|
||
|
- sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||
|
- if (sockfd == -1) {
|
||
|
- fprintf(stderr, "%s: could not create socket\n", progname);
|
||
|
- perror(progname);
|
||
|
+ sockfd = -1;
|
||
|
+#ifdef HAVE_SYSTEMD
|
||
|
+ n = sd_listen_fds(0);
|
||
|
+ if (n > 1) {
|
||
|
+ fprintf(stderr, "Too many file descriptors received.\n");
|
||
|
goto start_server_failed0;
|
||
|
- }
|
||
|
+ exit(1);
|
||
|
+ }
|
||
|
+ else if (n == 1)
|
||
|
+ sockfd = SD_LISTEN_FDS_START + 0;
|
||
|
+#endif
|
||
|
+ if (sockfd == -1) {
|
||
|
+ sockfd = socket(AF_UNIX, SOCK_STREAM, 0);
|
||
|
+ if (sockfd == -1) {
|
||
|
+ fprintf(stderr, "%s: could not create socket\n", progname);
|
||
|
+ perror(progname);
|
||
|
+ goto start_server_failed0;
|
||
|
+ }
|
||
|
|
||
|
- /*
|
||
|
- get owner, permissions, etc.
|
||
|
- so new socket can be the same since we
|
||
|
- have to delete the old socket.
|
||
|
- */
|
||
|
- ret = stat(lircdfile, &s);
|
||
|
- if (ret == -1 && errno != ENOENT) {
|
||
|
- fprintf(stderr, "%s: could not get file information for %s\n", progname, lircdfile);
|
||
|
- perror(progname);
|
||
|
- goto start_server_failed1;
|
||
|
- }
|
||
|
- if (ret != -1) {
|
||
|
- new = 0;
|
||
|
- ret = unlink(lircdfile);
|
||
|
- if (ret == -1) {
|
||
|
- fprintf(stderr, "%s: could not delete %s\n", progname, lircdfile);
|
||
|
- perror(NULL);
|
||
|
+ /*
|
||
|
+ get owner, permissions, etc.
|
||
|
+ so new socket can be the same since we
|
||
|
+ have to delete the old socket.
|
||
|
+ */
|
||
|
+ ret = stat(lircdfile, &s);
|
||
|
+ if (ret == -1 && errno != ENOENT) {
|
||
|
+ fprintf(stderr, "%s: could not get file information for %s\n", progname, lircdfile);
|
||
|
+ perror(progname);
|
||
|
goto start_server_failed1;
|
||
|
}
|
||
|
- }
|
||
|
+ if (ret != -1) {
|
||
|
+ new = 0;
|
||
|
+ ret = unlink(lircdfile);
|
||
|
+ if (ret == -1) {
|
||
|
+ fprintf(stderr, "%s: could not delete %s\n", progname, lircdfile);
|
||
|
+ perror(NULL);
|
||
|
+ goto start_server_failed1;
|
||
|
+ }
|
||
|
+ }
|
||
|
|
||
|
- serv_addr.sun_family = AF_UNIX;
|
||
|
- strcpy(serv_addr.sun_path, lircdfile);
|
||
|
- if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) {
|
||
|
- fprintf(stderr, "%s: could not assign address to socket\n", progname);
|
||
|
- perror(progname);
|
||
|
- goto start_server_failed1;
|
||
|
- }
|
||
|
+ serv_addr.sun_family = AF_UNIX;
|
||
|
+ strcpy(serv_addr.sun_path, lircdfile);
|
||
|
+ if (bind(sockfd, (struct sockaddr *)&serv_addr, sizeof(serv_addr)) == -1) {
|
||
|
+ fprintf(stderr, "%s: could not assign address to socket\n", progname);
|
||
|
+ perror(progname);
|
||
|
+ goto start_server_failed1;
|
||
|
+ }
|
||
|
|
||
|
- if (new ? chmod(lircdfile, permission)
|
||
|
- : (chmod(lircdfile, s.st_mode) == -1 || chown(lircdfile, s.st_uid, s.st_gid) == -1)
|
||
|
- ) {
|
||
|
- fprintf(stderr, "%s: could not set file permissions\n", progname);
|
||
|
- perror(progname);
|
||
|
- goto start_server_failed1;
|
||
|
- }
|
||
|
+ if (new ? chmod(lircdfile, permission)
|
||
|
+ : (chmod(lircdfile, s.st_mode) == -1 || chown(lircdfile, s.st_uid, s.st_gid) == -1)
|
||
|
+ ) {
|
||
|
+ fprintf(stderr, "%s: could not set file permissions\n", progname);
|
||
|
+ perror(progname);
|
||
|
+ goto start_server_failed1;
|
||
|
+ }
|
||
|
|
||
|
- listen(sockfd, 3);
|
||
|
+ listen(sockfd, 3);
|
||
|
+ }
|
||
|
nolinger(sockfd);
|
||
|
|
||
|
if (useuinput) {
|
||
|
--
|
||
|
1.8.3.1
|
||
|
|