From a5c08598384d44ad3bce24ff63ab320b3b3e5292 Mon Sep 17 00:00:00 2001
From: huangkaibin <huangkaibin@huawei.com>
Date: Wed, 31 Jan 2018 22:28:36 +0800
Subject: [PATCH] systemd-core: Serialize pids for scope unit when it is not
 started

1. when a scope unit is initialized, and daemon-reload is performed before it is started,
pids (generally comes from dbus) belog to this scope will not be attached to the cgroup of this scope,
because these pids are not serialized and are lost during daemon-reload.
2. this patch fix this problem by serializing scope pids when the state of the scope is DEAD(the init state).
---
 src/core/scope.c | 33 +++++++++++++++++++++++++++++++++
 1 file changed, 33 insertions(+)

diff --git a/src/core/scope.c b/src/core/scope.c
index ae6614f..8d96ee1 100644
--- a/src/core/scope.c
+++ b/src/core/scope.c
@@ -194,6 +194,8 @@ static int scope_load(Unit *u) {
 
 static int scope_coldplug(Unit *u) {
         Scope *s = SCOPE(u);
+        Iterator i;
+        void *pidp = NULL;
         int r;
 
         assert(s);
@@ -214,6 +216,12 @@ static int scope_coldplug(Unit *u) {
         bus_scope_track_controller(s);
 
         scope_set_state(s, s->deserialized_state);
+        if (s->state == SCOPE_DEAD && !u->cgroup_path && !set_isempty(u->pids)) {
+                SET_FOREACH(pidp, u->pids, i) {
+                        log_unit_info(u, "Rewatch pid from serialized pids. unit: %s, pid: %u", u->id, PTR_TO_UINT32(pidp));
+                        unit_watch_pid(u, PTR_TO_UINT32(pidp));
+                }
+        }
         return 0;
 }
 
@@ -396,6 +404,8 @@ static int scope_get_timeout(Unit *u, usec_t *timeout) {
 }
 
 static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
+        Iterator i;
+        void *pidp = NULL;
         Scope *s = SCOPE(u);
 
         assert(s);
@@ -408,6 +418,14 @@ static int scope_serialize(Unit *u, FILE *f, FDSet *fds) {
         if (s->controller)
                 unit_serialize_item(u, f, "controller", s->controller);
 
+        /*serialize pids when scope is not started*/
+        if (s->state == SCOPE_DEAD && !u->cgroup_path && !set_isempty(u->pids)) {
+                SET_FOREACH(pidp, u->pids, i) {
+                        log_unit_info(u, "scope is not started yet, pids are serialized. unit: %s, pid: %u", u->id, PTR_TO_UINT32(pidp));
+                        unit_serialize_item_format(u, f, "scope_pids", PID_FMT, PTR_TO_UINT32(pidp));
+                }
+        }
+
         return 0;
 }
 
@@ -443,6 +461,21 @@ static int scope_deserialize_item(Unit *u, const char *key, const char *value, F
                 if (r < 0)
                         log_oom();
 
+        } else if (streq(key, "scope_pids")) {
+                pid_t pid;
+
+                if (parse_pid(value, &pid) < 0)
+                        log_unit_debug(u, "Failed to parse scope-pid value %s.", value);
+                else {
+                        if(!u->pids) {
+                                r = set_ensure_allocated(&u->pids, NULL);
+                                if (r < 0)
+                                        return r;
+                        }
+                        r = set_put(u->pids, pid);
+                        if (r < 0)
+                                return r;
+                }
         } else
                 log_unit_debug(u, "Unknown serialization key: %s", key);
 
-- 
1.8.3.1

