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