100 lines
3.3 KiB
Diff
100 lines
3.3 KiB
Diff
From 428a9f6f1d0396b9eacde2b38d667cbe3f15eb55 Mon Sep 17 00:00:00 2001
|
|
From: Franck Bui <fbui@suse.com>
|
|
Date: Mon, 16 Nov 2020 15:12:21 +0100
|
|
Subject: [PATCH] core: serialize u->pids until the processes have been moved
|
|
to the scope cgroup
|
|
|
|
Otherwise if a daemon-reload happens somewhere between the enqueue of the job
|
|
start for the scope unit and scope_start() then u->pids might be lost and none
|
|
of the processes specified by "PIDs=" will be moved into the scope cgroup.
|
|
---
|
|
src/core/scope.c | 37 +++++++++++++++++++++++++++++++++++--
|
|
1 file changed, 35 insertions(+), 2 deletions(-)
|
|
|
|
diff --git a/src/core/scope.c b/src/core/scope.c
|
|
index a4db272f93..a372f8d726 100644
|
|
--- a/src/core/scope.c
|
|
+++ b/src/core/scope.c
|
|
@@ -8,6 +8,7 @@
|
|
#include "dbus-unit.h"
|
|
#include "load-dropin.h"
|
|
#include "log.h"
|
|
+#include "process-util.h"
|
|
#include "scope.h"
|
|
#include "serialize.h"
|
|
#include "special.h"
|
|
@@ -235,8 +236,18 @@ static int scope_coldplug(Unit *u) {
|
|
if (r < 0)
|
|
return r;
|
|
|
|
- if (!IN_SET(s->deserialized_state, SCOPE_DEAD, SCOPE_FAILED))
|
|
- (void) unit_enqueue_rewatch_pids(u);
|
|
+ if (!IN_SET(s->deserialized_state, SCOPE_DEAD, SCOPE_FAILED)) {
|
|
+ if (u->pids) {
|
|
+ void *pidp;
|
|
+
|
|
+ SET_FOREACH(pidp, u->pids) {
|
|
+ r = unit_watch_pid(u, PTR_TO_PID(pidp), false);
|
|
+ if (r < 0 && r != -EEXIST)
|
|
+ return r;
|
|
+ }
|
|
+ } else
|
|
+ (void) unit_enqueue_rewatch_pids(u);
|
|
+ }
|
|
|
|
bus_scope_track_controller(s);
|
|
|
|
@@ -366,6 +377,10 @@ static int scope_start(Unit *u) {
|
|
return r;
|
|
}
|
|
|
|
+ /* Now u->pids have been moved into the scope cgroup, it's not needed
|
|
+ * anymore. */
|
|
+ u->pids = set_free(u->pids);
|
|
+
|
|
s->result = SCOPE_SUCCESS;
|
|
|
|
scope_set_state(s, SCOPE_RUNNING);
|
|
@@ -427,6 +442,7 @@ static int scope_get_timeout(Unit *u, usec_t *timeout) {
|
|
|
|
static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
|
|
Scope *s = SCOPE(u);
|
|
+ void *pidp;
|
|
|
|
assert(s);
|
|
assert(f);
|
|
@@ -438,6 +454,9 @@ static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
|
|
if (s->controller)
|
|
(void) serialize_item(f, "controller", s->controller);
|
|
|
|
+ SET_FOREACH(pidp, u->pids)
|
|
+ serialize_item_format(f, "pids", PID_FMT, PTR_TO_PID(pidp));
|
|
+
|
|
return 0;
|
|
}
|
|
|
|
@@ -473,6 +492,20 @@ static int scope_deserialize_item(Unit *u, const char *key, const char *value, F
|
|
if (r < 0)
|
|
return log_oom();
|
|
|
|
+ } else if (streq(key, "pids")) {
|
|
+ pid_t pid;
|
|
+
|
|
+ if (parse_pid(value, &pid) < 0)
|
|
+ log_unit_debug(u, "Failed to parse pids value: %s", value);
|
|
+ else {
|
|
+ r = set_ensure_allocated(&u->pids, NULL);
|
|
+ if (r < 0)
|
|
+ return r;
|
|
+
|
|
+ r = set_put(u->pids, PID_TO_PTR(pid));
|
|
+ if (r < 0)
|
|
+ return r;
|
|
+ }
|
|
} else
|
|
log_unit_debug(u, "Unknown serialization key: %s", key);
|
|
|
|
--
|
|
2.23.0
|
|
|