]> git.ipfire.org Git - thirdparty/systemd.git/commitdiff
homed: make sure our worker processes finish before we exit
authorLennart Poettering <lennart@poettering.net>
Fri, 18 Sep 2020 16:53:12 +0000 (18:53 +0200)
committerLennart Poettering <lennart@poettering.net>
Fri, 18 Sep 2020 20:35:36 +0000 (22:35 +0200)
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
src/home/homed-home.h
src/home/homed-manager.c

index c7156c0d5070403a2a70f143f4945b7c32d17950..55041735453d12522a9763311ec5d84bb5d97ec2 100644 (file)
@@ -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",
index b638c6cbb1be7d276190940cbf5220b3df6c6162..97879940df201a8937cbe40e8d22d5ff7421f06c 100644 (file)
@@ -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);
index 711f178c55568dba33762e51d9b8eacbd5deb262..049003241606efdfa250cd219e1faf2aecec69db 100644 (file)
@@ -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);