923a60
From fd8580a8f42b1e10d75f43229b203fb889260b71 Mon Sep 17 00:00:00 2001
923a60
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Nykr=C3=BDn?= <lnykryn@redhat.com>
923a60
Date: Sat, 16 Jul 2016 21:04:13 +0200
923a60
Subject: [PATCH] manager: don't skip sigchld handler for main and control pid
923a60
 for services (#3738)
923a60
923a60
During stop when service has one "regular" pid one main pid and one
923a60
control pid and the sighld for the regular one is processed first the
923a60
unit_tidy_watch_pids will skip the main and control pid and does not
923a60
remove them from u->pids(). But then we skip the sigchld event because we
923a60
already did one in the iteration and there are two pids in u->pids.
923a60
923a60
v2: Use general unit_main_pid() and unit_control_pid() instead of
923a60
reaching directly to service structure.
923a60
Cherry-picked from: ccc2c98e1b0c06861577632440b996ca16cefd53
923a60
Resolves: #1342173
923a60
---
923a60
 src/core/busname.c | 10 ++++++++++
923a60
 src/core/manager.c |  5 ++++-
923a60
 src/core/mount.c   | 10 ++++++++++
923a60
 src/core/service.c | 19 +++++++++++++++++++
923a60
 src/core/socket.c  | 10 ++++++++++
923a60
 src/core/swap.c    | 10 ++++++++++
923a60
 src/core/unit.c    | 18 ++++++++++++++++++
923a60
 src/core/unit.h    |  9 +++++++++
923a60
 8 files changed, 90 insertions(+), 1 deletion(-)
923a60
923a60
diff --git a/src/core/busname.c b/src/core/busname.c
923a60
index 43d7607a30..f626ba96d0 100644
923a60
--- a/src/core/busname.c
923a60
+++ b/src/core/busname.c
923a60
@@ -997,6 +997,14 @@ static const char* const busname_state_table[_BUSNAME_STATE_MAX] = {
923a60
 
923a60
 DEFINE_STRING_TABLE_LOOKUP(busname_state, BusNameState);
923a60
 
923a60
+static int busname_control_pid(Unit *u) {
923a60
+        BusName *n = BUSNAME(u);
923a60
+
923a60
+        assert(n);
923a60
+
923a60
+        return n->control_pid;
923a60
+}
923a60
+
923a60
 static const char* const busname_result_table[_BUSNAME_RESULT_MAX] = {
923a60
         [BUSNAME_SUCCESS] = "success",
923a60
         [BUSNAME_FAILURE_RESOURCES] = "resources",
923a60
@@ -1047,6 +1055,8 @@ const UnitVTable busname_vtable = {
923a60
 
923a60
         .supported = busname_supported,
923a60
 
923a60
+        .control_pid = busname_control_pid,
923a60
+
923a60
         .bus_interface = "org.freedesktop.systemd1.BusName",
923a60
         .bus_vtable = bus_busname_vtable,
923a60
 
923a60
diff --git a/src/core/manager.c b/src/core/manager.c
923a60
index d168777d26..5da8365938 100644
923a60
--- a/src/core/manager.c
923a60
+++ b/src/core/manager.c
923a60
@@ -1760,7 +1760,10 @@ static void invoke_sigchld_event(Manager *m, Unit *u, siginfo_t *si) {
923a60
         unit_unwatch_pid(u, si->si_pid);
923a60
 
923a60
         if (UNIT_VTABLE(u)->sigchld_event) {
923a60
-                if (set_size(u->pids) <= 1 || iteration != u->sigchldgen) {
923a60
+                if (set_size(u->pids) <= 1 ||
923a60
+                    iteration != u->sigchldgen ||
923a60
+                    unit_main_pid(u) == si->si_pid ||
923a60
+                    unit_control_pid(u) == si->si_pid) {
923a60
                         UNIT_VTABLE(u)->sigchld_event(u, si->si_pid, si->si_code, si->si_status);
923a60
                         u->sigchldgen = iteration;
923a60
                 } else
923a60
diff --git a/src/core/mount.c b/src/core/mount.c
923a60
index fe967bc039..3fbdb7dafb 100644
923a60
--- a/src/core/mount.c
923a60
+++ b/src/core/mount.c
923a60
@@ -1877,6 +1877,14 @@ static const char* const mount_state_table[_MOUNT_STATE_MAX] = {
923a60
 
923a60
 DEFINE_STRING_TABLE_LOOKUP(mount_state, MountState);
923a60
 
923a60
+static int mount_control_pid(Unit *u) {
923a60
+        Mount *m = MOUNT(u);
923a60
+
923a60
+        assert(m);
923a60
+
923a60
+        return m->control_pid;
923a60
+}
923a60
+
923a60
 static const char* const mount_exec_command_table[_MOUNT_EXEC_COMMAND_MAX] = {
923a60
         [MOUNT_EXEC_MOUNT] = "ExecMount",
923a60
         [MOUNT_EXEC_UNMOUNT] = "ExecUnmount",
923a60
@@ -1938,6 +1946,8 @@ const UnitVTable mount_vtable = {
923a60
 
923a60
         .reset_failed = mount_reset_failed,
923a60
 
923a60
+        .control_pid = mount_control_pid,
923a60
+
923a60
         .bus_interface = "org.freedesktop.systemd1.Mount",
923a60
         .bus_vtable = bus_mount_vtable,
923a60
         .bus_set_property = bus_mount_set_property,
923a60
diff --git a/src/core/service.c b/src/core/service.c
923a60
index c76713b1ce..babd3c52ae 100644
923a60
--- a/src/core/service.c
923a60
+++ b/src/core/service.c
923a60
@@ -3068,6 +3068,22 @@ static const char* const service_state_table[_SERVICE_STATE_MAX] = {
923a60
 
923a60
 DEFINE_STRING_TABLE_LOOKUP(service_state, ServiceState);
923a60
 
923a60
+static int service_main_pid(Unit *u) {
923a60
+        Service *s = SERVICE(u);
923a60
+
923a60
+        assert(s);
923a60
+
923a60
+        return s->main_pid;
923a60
+}
923a60
+
923a60
+static int service_control_pid(Unit *u) {
923a60
+        Service *s = SERVICE(u);
923a60
+
923a60
+        assert(s);
923a60
+
923a60
+        return s->control_pid;
923a60
+}
923a60
+
923a60
 static const char* const service_restart_table[_SERVICE_RESTART_MAX] = {
923a60
         [SERVICE_RESTART_NO] = "no",
923a60
         [SERVICE_RESTART_ON_SUCCESS] = "on-success",
923a60
@@ -3178,6 +3194,9 @@ const UnitVTable service_vtable = {
923a60
         .notify_cgroup_empty = service_notify_cgroup_empty_event,
923a60
         .notify_message = service_notify_message,
923a60
 
923a60
+        .main_pid = service_main_pid,
923a60
+        .control_pid = service_control_pid,
923a60
+
923a60
         .bus_name_owner_change = service_bus_name_owner_change,
923a60
 
923a60
         .bus_interface = "org.freedesktop.systemd1.Service",
923a60
diff --git a/src/core/socket.c b/src/core/socket.c
923a60
index bc677a20f8..771af0d241 100644
923a60
--- a/src/core/socket.c
923a60
+++ b/src/core/socket.c
923a60
@@ -2648,6 +2648,14 @@ static const char* const socket_state_table[_SOCKET_STATE_MAX] = {
923a60
 
923a60
 DEFINE_STRING_TABLE_LOOKUP(socket_state, SocketState);
923a60
 
923a60
+static int socket_control_pid(Unit *u) {
923a60
+        Socket *s = SOCKET(u);
923a60
+
923a60
+        assert(s);
923a60
+
923a60
+        return s->control_pid;
923a60
+}
923a60
+
923a60
 static const char* const socket_exec_command_table[_SOCKET_EXEC_COMMAND_MAX] = {
923a60
         [SOCKET_EXEC_START_PRE] = "StartPre",
923a60
         [SOCKET_EXEC_START_CHOWN] = "StartChown",
923a60
@@ -2713,6 +2721,8 @@ const UnitVTable socket_vtable = {
923a60
 
923a60
         .reset_failed = socket_reset_failed,
923a60
 
923a60
+        .control_pid = socket_control_pid,
923a60
+
923a60
         .bus_interface = "org.freedesktop.systemd1.Socket",
923a60
         .bus_vtable = bus_socket_vtable,
923a60
         .bus_set_property = bus_socket_set_property,
923a60
diff --git a/src/core/swap.c b/src/core/swap.c
923a60
index 34a2c406d8..42f995990c 100644
923a60
--- a/src/core/swap.c
923a60
+++ b/src/core/swap.c
923a60
@@ -1426,6 +1426,14 @@ static const char* const swap_state_table[_SWAP_STATE_MAX] = {
923a60
 
923a60
 DEFINE_STRING_TABLE_LOOKUP(swap_state, SwapState);
923a60
 
923a60
+static int swap_control_pid(Unit *u) {
923a60
+        Swap *s = SWAP(u);
923a60
+
923a60
+        assert(s);
923a60
+
923a60
+        return s->control_pid;
923a60
+}
923a60
+
923a60
 static const char* const swap_exec_command_table[_SWAP_EXEC_COMMAND_MAX] = {
923a60
         [SWAP_EXEC_ACTIVATE] = "ExecActivate",
923a60
         [SWAP_EXEC_DEACTIVATE] = "ExecDeactivate",
923a60
@@ -1487,6 +1495,8 @@ const UnitVTable swap_vtable = {
923a60
 
923a60
         .reset_failed = swap_reset_failed,
923a60
 
923a60
+        .control_pid = swap_control_pid,
923a60
+
923a60
         .bus_interface = "org.freedesktop.systemd1.Swap",
923a60
         .bus_vtable = bus_swap_vtable,
923a60
         .bus_set_property = bus_swap_set_property,
923a60
diff --git a/src/core/unit.c b/src/core/unit.c
923a60
index d62135d878..0e90d130a4 100644
923a60
--- a/src/core/unit.c
923a60
+++ b/src/core/unit.c
923a60
@@ -3674,6 +3674,24 @@ int unit_setup_exec_runtime(Unit *u) {
923a60
         return exec_runtime_make(rt, unit_get_exec_context(u), u->id);
923a60
 }
923a60
 
923a60
+pid_t unit_control_pid(Unit *u) {
923a60
+        assert(u);
923a60
+
923a60
+        if (UNIT_VTABLE(u)->control_pid)
923a60
+                return UNIT_VTABLE(u)->control_pid(u);
923a60
+
923a60
+        return 0;
923a60
+}
923a60
+
923a60
+pid_t unit_main_pid(Unit *u) {
923a60
+        assert(u);
923a60
+
923a60
+        if (UNIT_VTABLE(u)->main_pid)
923a60
+                return UNIT_VTABLE(u)->main_pid(u);
923a60
+
923a60
+        return 0;
923a60
+}
923a60
+
923a60
 static const char* const unit_active_state_table[_UNIT_ACTIVE_STATE_MAX] = {
923a60
         [UNIT_ACTIVE] = "active",
923a60
         [UNIT_RELOADING] = "reloading",
923a60
diff --git a/src/core/unit.h b/src/core/unit.h
923a60
index d936457776..35287a5b75 100644
923a60
--- a/src/core/unit.h
923a60
+++ b/src/core/unit.h
923a60
@@ -399,6 +399,12 @@ struct UnitVTable {
923a60
 
923a60
         int (*get_timeout)(Unit *u, uint64_t *timeout);
923a60
 
923a60
+        /* Returns the main PID if there is any defined, or 0. */
923a60
+        pid_t (*main_pid)(Unit *u);
923a60
+
923a60
+        /* Returns the main PID if there is any defined, or 0. */
923a60
+        pid_t (*control_pid)(Unit *u);
923a60
+
923a60
         /* This is called for each unit type and should be used to
923a60
          * enumerate existing devices and load them. However,
923a60
          * everything that is loaded here should still stay in
923a60
@@ -610,6 +616,9 @@ int unit_make_transient(Unit *u);
923a60
 
923a60
 int unit_require_mounts_for(Unit *u, const char *path);
923a60
 
923a60
+pid_t unit_control_pid(Unit *u);
923a60
+pid_t unit_main_pid(Unit *u);
923a60
+
923a60
 const char *unit_active_state_to_string(UnitActiveState i) _const_;
923a60
 UnitActiveState unit_active_state_from_string(const char *s) _pure_;
923a60