diff options
author | Lennart Poettering <lennart@poettering.net> | 2013-11-06 02:03:04 +0100 |
---|---|---|
committer | Lennart Poettering <lennart@poettering.net> | 2013-11-06 02:31:35 +0100 |
commit | d3e84ddb885e9d5f0ae9930eb905910e3a81f157 (patch) | |
tree | 06f15d176ed35af4b825e901e73d8c8629473963 | |
parent | cd6f997f71c3aba16aa08226d423d14cbc787f82 (diff) |
machined: keep track of the initial leader PID of a machine
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.
-rw-r--r-- | src/login/logind-core.c | 4 | ||||
-rw-r--r-- | src/machine/machine.c | 7 | ||||
-rw-r--r-- | src/machine/machined.c | 9 | ||||
-rw-r--r-- | src/machine/machined.h | 1 |
4 files changed, 16 insertions, 5 deletions
diff --git a/src/login/logind-core.c b/src/login/logind-core.c index 6506f22f36..9c31bf8a80 100644 --- a/src/login/logind-core.c +++ b/src/login/logind-core.c @@ -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) diff --git a/src/machine/machine.c b/src/machine/machine.c index a33a111043..cf3ef15456 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -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) diff --git a/src/machine/machined.c b/src/machine/machined.c index 25de0d5d46..a5f529384b 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -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; diff --git a/src/machine/machined.h b/src/machine/machined.h index dfb63bd7f1..3f07d4dd8e 100644 --- a/src/machine/machined.h +++ b/src/machine/machined.h @@ -40,6 +40,7 @@ struct Manager { Hashmap *machines; Hashmap *machine_units; + Hashmap *machine_leaders; LIST_HEAD(Machine, machine_gc_queue); }; |