From 9796a9fbad5bae4d66bb40d848f6245d1ee327d8 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Fri, 18 Sep 2020 18:53:12 +0200 Subject: [PATCH] homed: make sure our worker processes finish before we exit When exiting, let's explicitly wait for our worker processes to finish first. That's useful if unmounting of /home/ is scheduled to happen right after homed is down, as we then can be sure that the home directories are properly unmounted and detached by the time homed is fully terminated (otherwise it might happen that our worker gets killed by the service manager, thus leaving the home directory and its backing devices up/left for auto-clean which might be async). Likely fixes #16842 --- src/home/homed-home.c | 13 +++++++++++++ src/home/homed-home.h | 2 ++ src/home/homed-manager.c | 5 +++++ 3 files changed, 20 insertions(+) diff --git a/src/home/homed-home.c b/src/home/homed-home.c index c7156c0d50..5504173545 100644 --- a/src/home/homed-home.c +++ b/src/home/homed-home.c @@ -2739,6 +2739,19 @@ int home_set_current_message(Home *h, sd_bus_message *m) { return 1; } +int home_wait_for_worker(Home *h) { + assert(h); + + if (h->worker_pid <= 0) + return 0; + + log_info("Worker process for home %s is still running while exiting. Waiting for it to finish.", h->user_name); + (void) wait_for_terminate(h->worker_pid, NULL); + (void) hashmap_remove_value(h->manager->homes_by_worker_pid, PID_TO_PTR(h->worker_pid), h); + h->worker_pid = 0; + return 1; +} + static const char* const home_state_table[_HOME_STATE_MAX] = { [HOME_UNFIXATED] = "unfixated", [HOME_ABSENT] = "absent", diff --git a/src/home/homed-home.h b/src/home/homed-home.h index b638c6cbb1..97879940df 100644 --- a/src/home/homed-home.h +++ b/src/home/homed-home.h @@ -165,5 +165,7 @@ int home_auto_login(Home *h, char ***ret_seats); int home_set_current_message(Home *h, sd_bus_message *m); +int home_wait_for_worker(Home *h); + const char *home_state_to_string(HomeState state); HomeState home_state_from_string(const char *s); diff --git a/src/home/homed-manager.c b/src/home/homed-manager.c index 711f178c55..0490032416 100644 --- a/src/home/homed-manager.c +++ b/src/home/homed-manager.c @@ -232,8 +232,13 @@ int manager_new(Manager **ret) { } Manager* manager_free(Manager *m) { + Home *h; + assert(m); + HASHMAP_FOREACH(h, m->homes_by_worker_pid) + (void) home_wait_for_worker(h); + hashmap_free(m->homes_by_uid); hashmap_free(m->homes_by_name); hashmap_free(m->homes_by_worker_pid);