]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/core/socket.c
core: move pid watch/unwatch logic of the service manager to pidfd
[thirdparty/systemd.git] / src / core / socket.c
index 03c41b4049a70d67c63ff8de6ed766defa06d641..e5b2e8ae762ac2bddc8618323372b00609d6b508 100644 (file)
@@ -113,7 +113,7 @@ static void socket_unwatch_control_pid(Socket *s) {
         if (!pidref_is_set(&s->control_pid))
                 return;
 
-        unit_unwatch_pid(UNIT(s), s->control_pid.pid);
+        unit_unwatch_pidref(UNIT(s), &s->control_pid);
         pidref_done(&s->control_pid);
 }
 
@@ -1462,14 +1462,22 @@ static int socket_address_listen_do(
                 log_unit_error_errno(u, error, fmt, strna(_t));  \
         })
 
-static int fork_needed(const SocketAddress *address, const ExecContext *context) {
+static int fork_needed(const SocketAddress *address, Socket *s) {
         int r;
 
         assert(address);
-        assert(context);
+        assert(s);
 
         /* Check if we need to do the cgroup or netns stuff. If not we can do things much simpler. */
 
+        /* If there are any NFTSet= directives with cgroup source, we need the cgroup */
+        Unit *u = UNIT(s);
+        CGroupContext *c = unit_get_cgroup_context(u);
+        if (c)
+                FOREACH_ARRAY(nft_set, c->nft_set_context.sets, c->nft_set_context.n_sets)
+                        if (nft_set->source == NFT_SET_SOURCE_CGROUP)
+                                return true;
+
         if (IN_SET(address->sockaddr.sa.sa_family, AF_INET, AF_INET6)) {
                 r = bpf_firewall_supported();
                 if (r < 0)
@@ -1478,7 +1486,7 @@ static int fork_needed(const SocketAddress *address, const ExecContext *context)
                         return true;
         }
 
-        return exec_needs_network_namespace(context);
+        return exec_needs_network_namespace(&s->exec_context);
 }
 
 static int socket_address_listen_in_cgroup(
@@ -1498,7 +1506,7 @@ static int socket_address_listen_in_cgroup(
          * the socket is actually properly attached to the unit's cgroup for the purpose of BPF filtering and
          * such. */
 
-        r = fork_needed(address, &s->exec_context);
+        r = fork_needed(address, s);
         if (r < 0)
                 return r;
         if (r == 0) {
@@ -1857,7 +1865,7 @@ static int socket_coldplug(Unit *u) {
                    SOCKET_FINAL_SIGKILL,
                    SOCKET_CLEANING)) {
 
-                r = unit_watch_pid(UNIT(s), s->control_pid.pid, /* exclusive= */ false);
+                r = unit_watch_pidref(UNIT(s), &s->control_pid, /* exclusive= */ false);
                 if (r < 0)
                         return r;
 
@@ -1946,7 +1954,7 @@ static int socket_spawn(Socket *s, ExecCommand *c, PidRef *ret_pid) {
         if (r < 0)
                 return r;
 
-        r = unit_watch_pid(UNIT(s), pidref.pid, /* exclusive= */ true);
+        r = unit_watch_pidref(UNIT(s), &pidref, /* exclusive= */ true);
         if (r < 0)
                 return r;
 
@@ -2016,7 +2024,7 @@ static int socket_chown(Socket *s, PidRef *ret_pid) {
                 _exit(EXIT_SUCCESS);
         }
 
-        r = unit_watch_pid(UNIT(s), pid.pid, /* exclusive= */ true);
+        r = unit_watch_pidref(UNIT(s), &pid, /* exclusive= */ true);
         if (r < 0)
                 return r;