aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2021-07-14 13:27:40 +0300
committerGeorge Kiagiadakis <george.kiagiadakis@collabora.com>2021-07-28 13:19:02 +0300
commitb6f553a33e751ad51abf036ab0ce7b01ee99e39a (patch)
treecde6ad9709084103d826ba57b4ba2a84f0060275
parent4ad92cc00f6beb6e29c36b7c8316df9b7360903d (diff)
server: add systemd units + socket-activation support
Signed-off-by: George Kiagiadakis <george.kiagiadakis@collabora.com>
-rw-r--r--lib/meson.build2
-rw-r--r--lib/receiver.c83
-rw-r--r--meson.build11
-rw-r--r--meson_options.txt2
-rw-r--r--src/meson.build10
-rw-r--r--src/pipewire-ic-ipc.service22
-rw-r--r--src/pipewire-ic-ipc.socket12
7 files changed, 119 insertions, 23 deletions
diff --git a/lib/meson.build b/lib/meson.build
index 787bc4f..c0ae401 100644
--- a/lib/meson.build
+++ b/lib/meson.build
@@ -28,7 +28,7 @@ install_headers(icipc_lib_headers,
icipc_lib = library('icipc-' + icipc_api_version,
icipc_lib_sources,
install: true,
- dependencies : [threads_dep],
+ dependencies : [threads_dep, libsystemd_dep],
soversion: icipc_so_version,
version: meson.project_version(),
)
diff --git a/lib/receiver.c b/lib/receiver.c
index 9b34494..e039ced 100644
--- a/lib/receiver.c
+++ b/lib/receiver.c
@@ -8,13 +8,20 @@
#include <stdlib.h>
#include <stdio.h>
-#include <unistd.h>
#include <sys/socket.h>
#include <sys/un.h>
#include <sys/epoll.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
#include <string.h>
#include <errno.h>
#include <assert.h>
+
+#ifdef HAVE_SYSTEMD
+#include <systemd/sd-daemon.h>
+#endif
+
#include "private.h"
#include "receiver.h"
#include "icipc.h"
@@ -24,6 +31,7 @@
struct icipc_receiver {
struct sockaddr_un addr;
int socket_fd;
+ bool activated;
uint8_t *buffer_read;
size_t buffer_size;
@@ -116,28 +124,60 @@ struct icipc_receiver *icipc_receiver_new(
/* set address */
self->addr.sun_family = AF_LOCAL;
- res =
- icipc_construct_socket_path(path, self->addr.sun_path,
- sizeof(self->addr.sun_path));
+ res = icipc_construct_socket_path(path, self->addr.sun_path,
+ sizeof(self->addr.sun_path));
if (res < 0)
goto error;
- unlink(self->addr.sun_path);
-
- /* create socket */
- self->socket_fd =
- socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
- if (self->socket_fd < 0)
- goto error;
-
- /* bind socket */
- if (bind(self->socket_fd, (struct sockaddr *)&self->addr,
- sizeof(self->addr)) != 0)
- goto error;
-
- /* listen socket */
- if (listen(self->socket_fd, MAX_SENDERS) != 0)
- goto error;
+#ifdef HAVE_SYSTEMD
+ {
+ int i, n = sd_listen_fds(0);
+ for (i = 0; i < n; ++i) {
+ if (sd_is_socket_unix(SD_LISTEN_FDS_START + i,
+ SOCK_STREAM, 1,
+ self->addr.sun_path, 0) > 0) {
+ self->socket_fd = SD_LISTEN_FDS_START + i;
+ self->activated = true;
+ icipc_log_info("receiver %p: Found socket "
+ "activation socket for '%s'",
+ self, self->addr.sun_path);
+ break;
+ }
+ }
+ }
+#endif
+
+ if (self->socket_fd < 0) {
+ struct stat socket_stat;
+
+ /* create socket */
+ self->socket_fd =
+ socket(PF_LOCAL, SOCK_STREAM | SOCK_CLOEXEC | SOCK_NONBLOCK, 0);
+ if (self->socket_fd < 0)
+ goto error;
+
+ if (stat(self->addr.sun_path, &socket_stat) < 0) {
+ if (errno != ENOENT) {
+ res = -errno;
+ icipc_log_error("receiver %p: stat %s failed "
+ "with error: %m",
+ self, self->addr.sun_path);
+ goto error;
+ }
+ } else if (socket_stat.st_mode & S_IWUSR ||
+ socket_stat.st_mode & S_IWGRP) {
+ unlink(self->addr.sun_path);
+ }
+
+ /* bind socket */
+ if (bind(self->socket_fd, (struct sockaddr *)&self->addr,
+ sizeof(self->addr)) != 0)
+ goto error;
+
+ /* listen socket */
+ if (listen(self->socket_fd, MAX_SENDERS) != 0)
+ goto error;
+ }
/* alloc buffer read */
self->buffer_size = buffer_size;
@@ -174,7 +214,8 @@ void icipc_receiver_free(struct icipc_receiver *self) {
icipc_epoll_thread_destroy(&self->epoll_thread);
free(self->buffer_read);
close(self->socket_fd);
- unlink(self->addr.sun_path);
+ if (!self->activated)
+ unlink(self->addr.sun_path);
free(self);
}
diff --git a/meson.build b/meson.build
index 0359271..259e94e 100644
--- a/meson.build
+++ b/meson.build
@@ -9,7 +9,12 @@ project('icipc', ['c'],
)
threads_dep = dependency('threads', required: true)
-pipewire_dep = dependency('libpipewire-0.3', required: get_option('server'))
+libsystemd_dep = dependency('libsystemd', required: get_option('systemd'))
+
+if get_option('server')
+ pipewire_dep = dependency('libpipewire-0.3', required: true)
+ systemd_dep = dependency('systemd', required: get_option('systemd'))
+endif
pkgconfig = import('pkgconfig')
cc = meson.get_compiler('c')
@@ -35,6 +40,10 @@ common_flags = [
add_project_arguments(cc.get_supported_arguments(common_flags), language: 'c')
add_project_arguments('-D_GNU_SOURCE', language: 'c')
+if libsystemd_dep.found()
+ add_project_arguments('-DHAVE_SYSTEMD', language: 'c')
+endif
+
subdir('lib')
subdir('src')
subdir('tests')
diff --git a/meson_options.txt b/meson_options.txt
index 503d1d7..7058453 100644
--- a/meson_options.txt
+++ b/meson_options.txt
@@ -2,3 +2,5 @@ option('server', type : 'boolean', value : 'true',
description: 'Build the server-side (requires pipewire dep)')
option('client', type : 'boolean', value : 'true',
description: 'Build the client-side (no dependencies)')
+option('systemd', type: 'feature', value: 'auto',
+ description: 'Enable systemd integration')
diff --git a/src/meson.build b/src/meson.build
index 7ef8754..3e3f916 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -16,4 +16,14 @@ if get_option('server')
install_dir : pipewire_dep.get_variable(pkgconfig: 'moduledir'),
dependencies : [icipc_dep, pipewire_dep],
)
+
+ if systemd_dep.found() and libsystemd_dep.found()
+ systemd_system_services_dir = systemd_dep.get_pkgconfig_variable(
+ 'systemdsystemunitdir',
+ define_variable: ['prefix', get_option('prefix')])
+
+ install_data(
+ sources: ['pipewire-ic-ipc.socket', 'pipewire-ic-ipc.service'],
+ install_dir: systemd_system_services_dir)
+ endif
endif
diff --git a/src/pipewire-ic-ipc.service b/src/pipewire-ic-ipc.service
new file mode 100644
index 0000000..f961f6c
--- /dev/null
+++ b/src/pipewire-ic-ipc.service
@@ -0,0 +1,22 @@
+[Unit]
+Description=PipeWire AGL Instrument Cluster IPC
+After=pipewire.socket
+
+[Service]
+LockPersonality=yes
+MemoryDenyWriteExecute=yes
+NoNewPrivileges=yes
+RestrictNamespaces=yes
+SystemCallArchitectures=native
+SystemCallFilter=@system-service
+Type=simple
+ExecStart=pipewire -c pipewire-ic-ipc.conf
+Restart=on-failure
+RuntimeDirectory=pipewire
+RuntimeDirectoryPreserve=yes
+User=pipewire
+Environment=PIPEWIRE_RUNTIME_DIR=%t/pipewire
+
+[Install]
+Also=pipewire-ic-ipc.socket
+WantedBy=default.target
diff --git a/src/pipewire-ic-ipc.socket b/src/pipewire-ic-ipc.socket
new file mode 100644
index 0000000..3877d4a
--- /dev/null
+++ b/src/pipewire-ic-ipc.socket
@@ -0,0 +1,12 @@
+[Unit]
+Description=PipeWire AGL Instrument Cluster IPC
+
+[Socket]
+Priority=6
+ListenStream=%t/pipewire/icipc-0
+SocketUser=pipewire
+SocketGroup=pipewire
+SocketMode=0660
+
+[Install]
+WantedBy=sockets.target