chiark / gitweb /
socket: make service to start on incoming traffic configurable
authorLennart Poettering <lennart@poettering.net>
Thu, 30 Sep 2010 00:19:12 +0000 (02:19 +0200)
committerLennart Poettering <lennart@poettering.net>
Tue, 5 Oct 2010 17:50:00 +0000 (19:50 +0200)
man/systemd.socket.xml
src/load-fragment.c
src/socket.c

index a7b8228aa0b6d7c5bb9fca0ba92052173a4e4c32..78d379de92e587a59c7db467bab5cbd2d743289c 100644 (file)
                                 <citerefentry><refentrytitle>systemd.service</refentrytitle><manvolnum>5</manvolnum></citerefentry>
                                 for details.</para></listitem>
                         </varlistentry>
                                 <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>
 
                 </variablelist>
         </refsect1>
 
index 4395fb280c45154a839559474c9c17ed2ba931a0..eba3fdbdfdc9f088510a6278228404544a1c918b 100644 (file)
@@ -1226,6 +1226,40 @@ static int config_parse_path_unit(
         return 0;
 }
 
         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,
 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"  },
                 { "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"   },
                 EXEC_CONTEXT_CONFIG_ITEMS(u->socket.exec_context, "Socket"),
 
                 { "What",                   config_parse_string,          &u->mount.parameters_fragment.what,              "Mount"   },
index aacf9bed9f1f50f106db3cd78b322461fc689ef8..bbb54f6308777388a023174b956f3f3e883b9583 100644 (file)
@@ -212,6 +212,11 @@ static int socket_verify(Socket *s) {
                 return -EINVAL;
         }
 
                 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;
         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 (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;
 
                         if ((r = unit_add_dependency(u, UNIT_BEFORE, UNIT(s->service), true)) < 0)
                                 return r;