chiark / gitweb /
machined: keep track of the initial leader PID of a machine
authorLennart Poettering <lennart@poettering.net>
Wed, 6 Nov 2013 01:03:04 +0000 (02:03 +0100)
committerLennart Poettering <lennart@poettering.net>
Wed, 6 Nov 2013 01:31:35 +0000 (02:31 +0100)
This way we can without races always determine the machine for a leader
PID. This allows machine managers to query the machine for a forked off
container/VM  without a race where the child might already have died
before we could read the cgroup information from /proc/$PID/cgroup.

src/login/logind-core.c
src/machine/machine.c
src/machine/machined.c
src/machine/machined.h

index 6506f22..9c31bf8 100644 (file)
@@ -348,7 +348,7 @@ int manager_get_session_by_pid(Manager *m, pid_t pid, Session **session) {
 
         r = cg_pid_get_unit(pid, &unit);
         if (r < 0)
-                return r;
+                return 0;
 
         s = hashmap_get(m->session_units, unit);
         if (!s)
@@ -371,7 +371,7 @@ int manager_get_user_by_pid(Manager *m, pid_t pid, User **user) {
 
         r = cg_pid_get_slice(pid, &unit);
         if (r < 0)
-                return r;
+                return 0;
 
         u = hashmap_get(m->user_units, unit);
         if (!u)
index a33a111..cf3ef15 100644 (file)
@@ -85,6 +85,9 @@ void machine_free(Machine *m) {
 
         hashmap_remove(m->manager->machines, m->name);
 
+        if (m->leader > 0)
+                hashmap_remove_value(m->manager->machine_leaders, UINT_TO_PTR(m->leader), m);
+
         sd_bus_message_unref(m->create_message);
 
         free(m->name);
@@ -263,6 +266,10 @@ int machine_start(Machine *m, sd_bus_message *properties, sd_bus_error *error) {
         if (m->started)
                 return 0;
 
+        r = hashmap_put(m->manager->machine_leaders, UINT_TO_PTR(m->leader), m);
+        if (r < 0)
+                return r;
+
         /* Create cgroup */
         r = machine_start_scope(m, properties, error);
         if (r < 0)
index 25de0d5..a5f5293 100644 (file)
@@ -46,8 +46,9 @@ Manager *manager_new(void) {
 
         m->machines = hashmap_new(string_hash_func, string_compare_func);
         m->machine_units = hashmap_new(string_hash_func, string_compare_func);
+        m->machine_leaders = hashmap_new(trivial_hash_func, trivial_compare_func);
 
-        if (!m->machines || !m->machine_units) {
+        if (!m->machines || !m->machine_units || !m->machine_leaders) {
                 manager_free(m);
                 return NULL;
         }
@@ -71,6 +72,7 @@ void manager_free(Manager *m) {
 
         hashmap_free(m->machines);
         hashmap_free(m->machine_units);
+        hashmap_free(m->machine_leaders);
 
         sd_bus_unref(m->bus);
         sd_event_unref(m->event);
@@ -108,9 +110,10 @@ int manager_get_machine_by_pid(Manager *m, pid_t pid, Machine **machine) {
 
         r = cg_pid_get_unit(pid, &unit);
         if (r < 0)
-                return r;
+                mm = hashmap_get(m->machine_leaders, UINT_TO_PTR(pid));
+        else
+                mm = hashmap_get(m->machine_units, unit);
 
-        mm = hashmap_get(m->machine_units, unit);
         if (!mm)
                 return 0;
 
index dfb63bd..3f07d4d 100644 (file)
@@ -40,6 +40,7 @@ struct Manager {
 
         Hashmap *machines;
         Hashmap *machine_units;
+        Hashmap *machine_leaders;
 
         LIST_HEAD(Machine, machine_gc_queue);
 };