summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--man/systemd.socket.xml12
-rw-r--r--src/load-fragment.c35
-rw-r--r--src/socket.c11
3 files changed, 56 insertions, 2 deletions
diff --git a/man/systemd.socket.xml b/man/systemd.socket.xml
index a7b8228aa0..78d379de92 100644
--- a/man/systemd.socket.xml
+++ b/man/systemd.socket.xml
@@ -518,6 +518,18 @@
<citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
for details.</para></listitem>
</varlistentry>
+
+ <varlistentry>
+ <term><varname>Service=</varname></term>
+ <listitem><para>Specifies the service
+ unit name to activate on incoming
+ traffic. This defaults to the service
+ that bears the same name as the socket
+ (ignoring the different suffixes). In
+ most cases it should not be necessary
+ to use this option.</para></listitem>
+ </varlistentry>
+
</variablelist>
</refsect1>
diff --git a/src/load-fragment.c b/src/load-fragment.c
index 4395fb280c..eba3fdbdfd 100644
--- a/src/load-fragment.c
+++ b/src/load-fragment.c
@@ -1226,6 +1226,40 @@ static int config_parse_path_unit(
return 0;
}
+static int config_parse_socket_service(
+ const char *filename,
+ unsigned line,
+ const char *section,
+ const char *lvalue,
+ const char *rvalue,
+ void *data,
+ void *userdata) {
+
+ Socket *s = data;
+ int r;
+ DBusError error;
+
+ assert(filename);
+ assert(lvalue);
+ assert(rvalue);
+ assert(data);
+
+ dbus_error_init(&error);
+
+ if (endswith(rvalue, ".service")) {
+ log_error("[%s:%u] Unit must be of type serivce, ignoring: %s", filename, line, rvalue);
+ return 0;
+ }
+
+ if ((r = manager_load_unit(s->meta.manager, rvalue, NULL, &error, (Unit**) &s->service)) < 0) {
+ log_error("[%s:%u] Failed to load unit %s, ignoring: %s", filename, line, rvalue, bus_error(&error, r));
+ dbus_error_free(&error);
+ return 0;
+ }
+
+ return 0;
+}
+
static int config_parse_env_file(
const char *filename,
unsigned line,
@@ -1654,6 +1688,7 @@ static int load_from_path(Unit *u, const char *path) {
{ "PipeSize", config_parse_size, &u->socket.pipe_size, "Socket" },
{ "FreeBind", config_parse_bool, &u->socket.free_bind, "Socket" },
{ "TCPCongestion", config_parse_string, &u->socket.tcp_congestion, "Socket" },
+ { "Service", config_parse_socket_service, &u->socket, "Socket" },
EXEC_CONTEXT_CONFIG_ITEMS(u->socket.exec_context, "Socket"),
{ "What", config_parse_string, &u->mount.parameters_fragment.what, "Mount" },
diff --git a/src/socket.c b/src/socket.c
index aacf9bed9f..bbb54f6308 100644
--- a/src/socket.c
+++ b/src/socket.c
@@ -212,6 +212,11 @@ static int socket_verify(Socket *s) {
return -EINVAL;
}
+ if (s->accept && s->service) {
+ log_error("Explicit service configuration for accepting sockets not supported on %s. Refusing.", s->meta.id);
+ return -EINVAL;
+ }
+
if (s->exec_context.pam_name && s->exec_context.kill_mode != KILL_CONTROL_GROUP) {
log_error("%s has PAM enabled. Kill mode must be set to 'control-group'. Refusing.", s->meta.id);
return -EINVAL;
@@ -315,8 +320,10 @@ static int socket_load(Unit *u) {
if (u->meta.load_state == UNIT_LOADED) {
if (have_non_accept_socket(s)) {
- if ((r = unit_load_related_unit(u, ".service", (Unit**) &s->service)) < 0)
- return r;
+
+ if (!s->service)
+ if ((r = unit_load_related_unit(u, ".service", (Unit**) &s->service)) < 0)
+ return r;
if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(s->service), true)) < 0)
return r;