chiark / gitweb /
service: when after startup only one process is in a service's cgroup, assume it...
authorLennart Poettering <lennart@poettering.net>
Wed, 27 Oct 2010 01:16:49 +0000 (03:16 +0200)
committerLennart Poettering <lennart@poettering.net>
Wed, 27 Oct 2010 01:16:49 +0000 (03:16 +0200)
TODO
src/cgroup.c
src/cgroup.h
src/service.c
src/systemctl.c

diff --git a/TODO b/TODO
index f41dd3c..ecd5ff8 100644 (file)
--- a/TODO
+++ b/TODO
@@ -66,8 +66,6 @@
 
 * parse early boot time env var from dracut
 
-* fix serialization of timers
-
 * add switch to disable pull in retroactively
 
 * cryptsetup
index d64ab63..8b2ad5b 100644 (file)
@@ -397,3 +397,54 @@ char *cgroup_bonding_to_string(CGroupBonding *b) {
 
         return r;
 }
+
+pid_t cgroup_bonding_search_main_pid(CGroupBonding *b) {
+        FILE *f;
+        pid_t pid = 0, npid;
+        int r;
+
+        assert(b);
+
+        if (!b->only_us)
+                return 0;
+
+        if ((r = cg_enumerate_processes(b->controller, b->path, &f)) < 0)
+                return 0;
+
+        while ((r = cg_read_pid(f, &npid)) > 0)  {
+
+                if (npid == pid)
+                        continue;
+
+                if (pid != 0) {
+                        /* Dang, there's more than one PID in this
+                         * group, so we don't know what process is the
+                         * main process. */
+                        pid = 0;
+                        break;
+                }
+
+                pid = npid;
+        }
+
+        fclose(f);
+
+        return pid;
+}
+
+pid_t cgroup_bonding_search_main_pid_list(CGroupBonding *first) {
+        CGroupBonding *b;
+        pid_t pid;
+
+        /* Try to find a main pid from this cgroup, but checking if
+         * there's only one PID in the cgroup and returning it. Later
+         * on we might want to add additional, smarter heuristics
+         * here. */
+
+        LIST_FOREACH(by_unit, b, first)
+                if ((pid = cgroup_bonding_search_main_pid(b)) != 0)
+                        return pid;
+
+        return 0;
+
+}
index e38d7e7..d6d5c86 100644 (file)
@@ -71,6 +71,9 @@ CGroupBonding *cgroup_bonding_find_list(CGroupBonding *first, const char *contro
 
 char *cgroup_bonding_to_string(CGroupBonding *b);
 
+pid_t cgroup_bonding_search_main_pid(CGroupBonding *b);
+pid_t cgroup_bonding_search_main_pid_list(CGroupBonding *b);
+
 #include "manager.h"
 
 int manager_setup_cgroup(Manager *m);
index 46d7bbb..5cf7896 100644 (file)
@@ -1220,6 +1220,30 @@ static int service_load_pid_file(Service *s) {
         return 0;
 }
 
+static int service_search_main_pid(Service *s) {
+        pid_t pid;
+        int r;
+
+        assert(s);
+
+        if (s->main_pid_known)
+                return 0;
+
+        assert(s->main_pid <= 0);
+
+        if ((pid = cgroup_bonding_search_main_pid_list(s->meta.cgroup_bondings)) <= 0)
+                return -ENOENT;
+
+        if ((r = service_set_main_pid(s, pid)) < 0)
+                return r;
+
+        if ((r = unit_watch_pid(UNIT(s), pid)) < 0)
+                /* FIXME: we need to do something here */
+                return r;
+
+        return 0;
+}
+
 static int service_get_sockets(Service *s, Set **_set) {
         Set *set;
         Iterator i;
@@ -2595,8 +2619,8 @@ static void service_sigchld_event(Unit *u, pid_t pid, int code, int status) {
                                  * START_POST script */
 
                                 if (success) {
-                                        if (s->pid_file)
-                                                service_load_pid_file(s);
+                                        service_load_pid_file(s);
+                                        service_search_main_pid(s);
 
                                         service_enter_start_post(s);
                                 } else
index 9316ad0..d710bcf 100644 (file)
@@ -4047,7 +4047,7 @@ static int systemctl_help(void) {
                "                      pending\n"
                "  -q --quiet          Suppress output\n"
                "     --no-block       Do not wait until operation finished\n"
-               "     --system          Connect to system bus\n"
+               "     --system         Connect to system bus\n"
                "     --session        Connect to session bus\n"
                "     --order          When generating graph for dot, show only order\n"
                "     --require        When generating graph for dot, show only requirement\n"