Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP

Loading…

systemd socket activation support #6

Merged
merged 3 commits into from

2 participants

@falconindy

Hi, I've patched fcgiwrap to support systemd's [1] socket activation model. Sadly, the amount of code in configure.ac trumps the minimal effort needed for this in the actual application. If desirable, I can provide example configuration to be installed with fcgiwrap if its built with systemd support. These would be generic enough that they'll work on any Linux install using systemd.

[1] http://freedesktop.org/wiki/Software/systemd

falconindy added some commits
@falconindy falconindy split listen() logic into separate function 0c93fa9
@falconindy falconindy Add support for socket activation via systemd
This prevents the need for starting fcgiwrap explicitly, or using a
tool such as spawn-fcgi. The type of socket does not matter, we merely
accept a single FD passed from pid 1 and listen on it.
9836d6d
@falconindy falconindy Cleanup -Wmissing-prototypes compiler warnings 3468d79
@gnosek gnosek merged commit 7f583a0 into gnosek:master
@gnosek
Owner

Thanks! If you have an usable systemd config file, I can merge that too.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Commits on Aug 20, 2012
  1. @falconindy
  2. @falconindy

    Add support for socket activation via systemd

    falconindy authored
    This prevents the need for starting fcgiwrap explicitly, or using a
    tool such as spawn-fcgi. The type of socket does not matter, we merely
    accept a single FD passed from pid 1 and listen on it.
  3. @falconindy
This page is out of date. Refresh to see the latest.
Showing with 59 additions and 24 deletions.
  1. +1 −1  Makefile.in
  2. +17 −0 configure.ac
  3. +41 −23 fcgiwrap.c
View
2  Makefile.in
@@ -11,7 +11,7 @@ install: all
install -m 644 fcgiwrap.8 $(man8dir)
fcgiwrap: fcgiwrap.c
- @CC@ @AM_CFLAGS@ fcgiwrap.c -o fcgiwrap -lfcgi @LDFLAGS@
+ @CC@ @AM_CFLAGS@ fcgiwrap.c -o fcgiwrap -lfcgi @systemd_LIBS@ @LDFLAGS@
#>+ 21
clean:
View
17 configure.ac
@@ -14,6 +14,7 @@ AC_SUBST([AM_CFLAGS])
# Checks for programs.
AC_PROG_CC
+PKG_PROG_PKG_CONFIG
# Create the config.h.
AC_CONFIG_HEADERS([config.h])
@@ -21,6 +22,22 @@ AC_CONFIG_HEADERS([config.h])
# Checks for libraries.
AC_CHECK_LIB([fcgi], [FCGX_Init],, [AC_MSG_ERROR([FastCGI library is missing])])
+# systemd support.
+AC_ARG_WITH([systemd],
+ AS_HELP_STRING([--with-systemd], [support systemd socket activation]),
+ [], [with_systemd=check])
+have_systemd=no
+if test "x$with_systemd" != "xno"; then
+ PKG_CHECK_MODULES(systemd, [libsystemd-daemon],
+ [AC_DEFINE(HAVE_SYSTEMD, 1, [Define if systemd is available])
+ have_systemd=yes],
+ have_systemd=no)
+ if test "x$have_systemd" = xno -a "x$with_systemd" = xyes; then
+ AC_MSG_ERROR([systemd support requested but libraries not found])
+ fi
+fi
+AM_CONDITIONAL(HAVE_LIBSSL, [test "x$have_systemd" = "xyes"])
+
# Checks for header files.
AC_CHECK_HEADERS([fcntl.h],, [AC_MSG_ERROR([fcntl.h header missing])])
AC_CHECK_HEADERS([limits.h stdlib.h string.h unistd.h],, [AC_MSG_ERROR([at least one important system header file is missing])])
View
64 fcgiwrap.c
@@ -47,6 +47,10 @@
#include <sys/un.h>
#include <netinet/in.h>
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
/* glibc doesn't seem to export it */
#ifndef UNIX_PATH_MAX
#define UNIX_PATH_MAX 108
@@ -344,7 +348,7 @@ static void fcgi_pass(struct fcgi_context *fc)
fcgi_finish(fc, "reading CGI reply (no response received)");
}
-int check_file_perms(const char *path)
+static int check_file_perms(const char *path)
{
struct stat ls;
struct stat fs;
@@ -374,7 +378,7 @@ int check_file_perms(const char *path)
}
}
-char *get_cgi_filename() /* and fixup environment */
+static char *get_cgi_filename(void) /* and fixup environment */
{
int buflen = 1, docrootlen;
char *buf = NULL;
@@ -457,7 +461,7 @@ static int blacklisted_env(const char *var_name, const char *var_name_end)
return 0;
}
-static void inherit_environment()
+static void inherit_environment(void)
{
char * const * p;
char *q;
@@ -491,7 +495,7 @@ static void error_403(const char *reason, const char *filename)
exit(99);
}
-static void handle_fcgi_request()
+static void handle_fcgi_request(void)
{
int pipe_in[2];
int pipe_out[2];
@@ -638,13 +642,35 @@ static void prefork(int nchildren)
}
}
-int setup_socket(char *url) {
+static int listen_on_fd(int fd) {
+ int one = 1;
+
+ if (listen(fd, 511) < 0) {
+ perror("Failed to listen");
+ return -1;
+ }
+ if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one) < 0) {
+ perror("Failed to enable SO_REUSEADDR");
+ return -1;
+ }
+ if (dup2(fd, 0) < 0) {
+ perror("Failed to move socket to fd 0");
+ return -1;
+ }
+ if (close(fd) < 0) {
+ perror("Failed to close original socket");
+ return -1;
+ }
+
+ return 0;
+}
+
+static int setup_socket(char *url) {
char *p = url;
char *q;
int fd;
int port;
size_t sockaddr_size;
- int one = 1;
union {
struct sockaddr sa;
@@ -718,24 +744,8 @@ int setup_socket(char *url) {
perror("Failed to bind");
return -1;
}
- if (listen(fd, 511) < 0) {
- perror("Failed to listen");
- return -1;
- }
- if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &one, sizeof one) < 0) {
- perror("Failed to enable SO_REUSEADDR");
- return -1;
- }
- if (dup2(fd, 0) < 0) {
- perror("Failed to move socket to fd 0");
- return -1;
- }
- if (close(fd) < 0) {
- perror("Failed to close original socket");
- return -1;
- }
- return 0;
+ return listen_on_fd(fd);
}
int main(int argc, char **argv)
@@ -782,6 +792,14 @@ int main(int argc, char **argv)
}
}
+#ifdef HAVE_SYSTEMD
+ if (sd_listen_fds(true) > 0) {
+ /* systemd woke us up. we should never see more than one FD passed to us. */
+ if (listen_on_fd(SD_LISTEN_FDS_START) < 0) {
+ return 1;
+ }
+ } else
+#endif
if (socket_url) {
if (setup_socket(socket_url) < 0) {
return 1;
Something went wrong with that request. Please try again.