dcavalca / rpms / systemd

Forked from rpms/systemd 2 years ago
Clone
Zbigniew Jędrzejewski-Szmek 4f9456
From 7bd1311e54a418b1532d3931b9af70f8aabf4ece Mon Sep 17 00:00:00 2001
Zbigniew Jędrzejewski-Szmek 4f9456
From: Lennart Poettering <lennart@poettering.net>
Zbigniew Jędrzejewski-Szmek 4f9456
Date: Thu, 6 Mar 2014 02:19:06 +0100
Zbigniew Jędrzejewski-Szmek 4f9456
Subject: [PATCH] util: add timeout to generator execution
Zbigniew Jędrzejewski-Szmek 4f9456
Zbigniew Jędrzejewski-Szmek 4f9456
(cherry picked from commit aa62a8936f5983770e90b791083d55107659f7a1)
Zbigniew Jędrzejewski-Szmek 4f9456
(cherry picked from commit d66226bce64620543d21675ae610ecfeb9395e2a
Zbigniew Jędrzejewski-Szmek 4f9456
                and commit 5e2f14e62b43f713bade20dd9f55db525ac43859)
Zbigniew Jędrzejewski-Szmek 4f9456
Zbigniew Jędrzejewski-Szmek 4f9456
Conflicts:
Zbigniew Jędrzejewski-Szmek 4f9456
	src/core/manager.c
Zbigniew Jędrzejewski-Szmek 4f9456
---
Zbigniew Jędrzejewski-Szmek 4f9456
 src/core/manager.c   |   5 +-
Zbigniew Jędrzejewski-Szmek 4f9456
 src/core/shutdown.c  |   2 +-
Zbigniew Jędrzejewski-Szmek 4f9456
 src/shared/hashmap.h |   8 +++
Zbigniew Jędrzejewski-Szmek 4f9456
 src/shared/util.c    | 162 +++++++++++++++++++++++++++------------------------
Zbigniew Jędrzejewski-Szmek 4f9456
 src/shared/util.h    |   2 +-
Zbigniew Jędrzejewski-Szmek 4f9456
 src/sleep/sleep.c    |  14 +++--
Zbigniew Jędrzejewski-Szmek 4f9456
 6 files changed, 108 insertions(+), 85 deletions(-)
Zbigniew Jędrzejewski-Szmek 4f9456
Zbigniew Jędrzejewski-Szmek 4f9456
diff --git a/src/core/manager.c b/src/core/manager.c
Zbigniew Jędrzejewski-Szmek 4f9456
index 58c17ab..3a38fab 100644
Zbigniew Jędrzejewski-Szmek 4f9456
--- a/src/core/manager.c
Zbigniew Jędrzejewski-Szmek 4f9456
+++ b/src/core/manager.c
Zbigniew Jędrzejewski-Szmek 4f9456
@@ -2661,9 +2661,8 @@ void manager_run_generators(Manager *m) {
Zbigniew Jędrzejewski-Szmek 4f9456
         argv[3] = m->generator_unit_path_late;
Zbigniew Jędrzejewski-Szmek 4f9456
         argv[4] = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-        RUN_WITH_UMASK(0022) {
Zbigniew Jędrzejewski-Szmek 4f9456
-                execute_directory(generator_path, d, (char**) argv);
Zbigniew Jędrzejewski-Szmek 4f9456
-        }
Zbigniew Jędrzejewski-Szmek 4f9456
+        RUN_WITH_UMASK(0022)
Zbigniew Jędrzejewski-Szmek 4f9456
+                execute_directory(generator_path, d, DEFAULT_TIMEOUT_USEC, (char**) argv);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
         trim_generator_dir(m, &m->generator_unit_path);
Zbigniew Jędrzejewski-Szmek 4f9456
         trim_generator_dir(m, &m->generator_unit_path_early);
Zbigniew Jędrzejewski-Szmek 4f9456
diff --git a/src/core/shutdown.c b/src/core/shutdown.c
Zbigniew Jędrzejewski-Szmek 4f9456
index 5e0f3ce..68960b1 100644
Zbigniew Jędrzejewski-Szmek 4f9456
--- a/src/core/shutdown.c
Zbigniew Jędrzejewski-Szmek 4f9456
+++ b/src/core/shutdown.c
Zbigniew Jędrzejewski-Szmek 4f9456
@@ -294,7 +294,7 @@ int main(int argc, char *argv[]) {
Zbigniew Jędrzejewski-Szmek 4f9456
         arguments[0] = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
         arguments[1] = argv[1];
Zbigniew Jędrzejewski-Szmek 4f9456
         arguments[2] = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
-        execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, arguments);
Zbigniew Jędrzejewski-Szmek 4f9456
+        execute_directory(SYSTEM_SHUTDOWN_PATH, NULL, DEFAULT_TIMEOUT_USEC, arguments);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
         if (!in_container && !in_initrd() &&
Zbigniew Jędrzejewski-Szmek 4f9456
             access("/run/initramfs/shutdown", X_OK) == 0) {
Zbigniew Jędrzejewski-Szmek 4f9456
diff --git a/src/shared/hashmap.h b/src/shared/hashmap.h
Zbigniew Jędrzejewski-Szmek 4f9456
index 3d4f672..b912af8 100644
Zbigniew Jędrzejewski-Szmek 4f9456
--- a/src/shared/hashmap.h
Zbigniew Jędrzejewski-Szmek 4f9456
+++ b/src/shared/hashmap.h
Zbigniew Jędrzejewski-Szmek 4f9456
@@ -24,6 +24,7 @@
Zbigniew Jędrzejewski-Szmek 4f9456
 #include <stdbool.h>
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
 #include "macro.h"
Zbigniew Jędrzejewski-Szmek 4f9456
+#include "util.h"
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
 /* Pretty straightforward hash table implementation. As a minor
Zbigniew Jędrzejewski-Szmek 4f9456
  * optimization a NULL hashmap object will be treated as empty hashmap
Zbigniew Jędrzejewski-Szmek 4f9456
@@ -104,3 +105,10 @@ char **hashmap_get_strv(Hashmap *h);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
 #define HASHMAP_FOREACH_BACKWARDS(e, h, i) \
Zbigniew Jędrzejewski-Szmek 4f9456
         for ((i) = ITERATOR_LAST, (e) = hashmap_iterate_backwards((h), &(i), NULL); (e); (e) = hashmap_iterate_backwards((h), &(i), NULL))
Zbigniew Jędrzejewski-Szmek 4f9456
+
Zbigniew Jędrzejewski-Szmek 4f9456
+DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free);
Zbigniew Jędrzejewski-Szmek 4f9456
+DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free);
Zbigniew Jędrzejewski-Szmek 4f9456
+DEFINE_TRIVIAL_CLEANUP_FUNC(Hashmap*, hashmap_free_free_free);
Zbigniew Jędrzejewski-Szmek 4f9456
+#define _cleanup_hashmap_free_ _cleanup_(hashmap_freep)
Zbigniew Jędrzejewski-Szmek 4f9456
+#define _cleanup_hashmap_free_free_ _cleanup_(hashmap_free_freep)
Zbigniew Jędrzejewski-Szmek 4f9456
+#define _cleanup_hashmap_free_free_free_ _cleanup_(hashmap_free_free_freep)
Zbigniew Jędrzejewski-Szmek 4f9456
diff --git a/src/shared/util.c b/src/shared/util.c
Zbigniew Jędrzejewski-Szmek 4f9456
index 1329854..bec339b 100644
Zbigniew Jędrzejewski-Szmek 4f9456
--- a/src/shared/util.c
Zbigniew Jędrzejewski-Szmek 4f9456
+++ b/src/shared/util.c
Zbigniew Jędrzejewski-Szmek 4f9456
@@ -3740,111 +3740,123 @@ bool dirent_is_file_with_suffix(const struct dirent *de, const char *suffix) {
Zbigniew Jędrzejewski-Szmek 4f9456
         return endswith(de->d_name, suffix);
Zbigniew Jędrzejewski-Szmek 4f9456
 }
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-void execute_directory(const char *directory, DIR *d, char *argv[]) {
Zbigniew Jędrzejewski-Szmek 4f9456
-        DIR *_d = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
-        struct dirent *de;
Zbigniew Jędrzejewski-Szmek 4f9456
-        Hashmap *pids = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
+void execute_directory(const char *directory, DIR *d, usec_t timeout, char *argv[]) {
Zbigniew Jędrzejewski-Szmek 4f9456
+        pid_t executor_pid;
Zbigniew Jędrzejewski-Szmek 4f9456
+        int r;
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
         assert(directory);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-        /* Executes all binaries in a directory in parallel and
Zbigniew Jędrzejewski-Szmek 4f9456
-         * waits for them to finish. */
Zbigniew Jędrzejewski-Szmek 4f9456
+        /* Executes all binaries in a directory in parallel and waits
Zbigniew Jędrzejewski-Szmek 4f9456
+         * for them to finish. Optionally a timeout is applied. */
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-        if (!d) {
Zbigniew Jędrzejewski-Szmek 4f9456
-                if (!(_d = opendir(directory))) {
Zbigniew Jędrzejewski-Szmek 4f9456
+        executor_pid = fork();
Zbigniew Jędrzejewski-Szmek 4f9456
+        if (executor_pid < 0) {
Zbigniew Jędrzejewski-Szmek 4f9456
+                log_error("Failed to fork: %m");
Zbigniew Jędrzejewski-Szmek 4f9456
+                return;
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                        if (errno == ENOENT)
Zbigniew Jędrzejewski-Szmek 4f9456
-                                return;
Zbigniew Jędrzejewski-Szmek 4f9456
+        } else if (executor_pid == 0) {
Zbigniew Jędrzejewski-Szmek 4f9456
+                _cleanup_hashmap_free_free_ Hashmap *pids = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
+                _cleanup_closedir_ DIR *_d = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
+                struct dirent *de;
Zbigniew Jędrzejewski-Szmek 4f9456
+                sigset_t ss;
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                        log_error("Failed to enumerate directory %s: %m", directory);
Zbigniew Jędrzejewski-Szmek 4f9456
-                        return;
Zbigniew Jędrzejewski-Szmek 4f9456
-                }
Zbigniew Jędrzejewski-Szmek 4f9456
+                /* We fork this all off from a child process so that
Zbigniew Jędrzejewski-Szmek 4f9456
+                 * we can somewhat cleanly make use of SIGALRM to set
Zbigniew Jędrzejewski-Szmek 4f9456
+                 * a time limit */
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                d = _d;
Zbigniew Jędrzejewski-Szmek 4f9456
-        }
Zbigniew Jędrzejewski-Szmek 4f9456
+                reset_all_signal_handlers();
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-        if (!(pids = hashmap_new(trivial_hash_func, trivial_compare_func))) {
Zbigniew Jędrzejewski-Szmek 4f9456
-                log_error("Failed to allocate set.");
Zbigniew Jędrzejewski-Szmek 4f9456
-                goto finish;
Zbigniew Jędrzejewski-Szmek 4f9456
-        }
Zbigniew Jędrzejewski-Szmek 4f9456
+                assert_se(sigemptyset(&ss) == 0);
Zbigniew Jędrzejewski-Szmek 4f9456
+                assert_se(sigprocmask(SIG_SETMASK, &ss, NULL) == 0);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-        while ((de = readdir(d))) {
Zbigniew Jędrzejewski-Szmek 4f9456
-                char *path;
Zbigniew Jędrzejewski-Szmek 4f9456
-                pid_t pid;
Zbigniew Jędrzejewski-Szmek 4f9456
-                int k;
Zbigniew Jędrzejewski-Szmek 4f9456
+                assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                if (!dirent_is_file(de))
Zbigniew Jędrzejewski-Szmek 4f9456
-                        continue;
Zbigniew Jędrzejewski-Szmek 4f9456
+                if (!d) {
Zbigniew Jędrzejewski-Szmek 4f9456
+                        d = _d = opendir(directory);
Zbigniew Jędrzejewski-Szmek 4f9456
+                        if (!d) {
Zbigniew Jędrzejewski-Szmek 4f9456
+                                if (errno == ENOENT)
Zbigniew Jędrzejewski-Szmek 4f9456
+                                        _exit(EXIT_SUCCESS);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
Zbigniew Jędrzejewski-Szmek 4f9456
-                        log_oom();
Zbigniew Jędrzejewski-Szmek 4f9456
-                        continue;
Zbigniew Jędrzejewski-Szmek 4f9456
+                                log_error("Failed to enumerate directory %s: %m", directory);
Zbigniew Jędrzejewski-Szmek 4f9456
+                                _exit(EXIT_FAILURE);
Zbigniew Jędrzejewski-Szmek 4f9456
+                        }
Zbigniew Jędrzejewski-Szmek 4f9456
                 }
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                if ((pid = fork()) < 0) {
Zbigniew Jędrzejewski-Szmek 4f9456
-                        log_error("Failed to fork: %m");
Zbigniew Jędrzejewski-Szmek 4f9456
-                        free(path);
Zbigniew Jędrzejewski-Szmek 4f9456
-                        continue;
Zbigniew Jędrzejewski-Szmek 4f9456
+                pids = hashmap_new(NULL, NULL);
Zbigniew Jędrzejewski-Szmek 4f9456
+                if (!pids) {
Zbigniew Jędrzejewski-Szmek 4f9456
+                        log_oom();
Zbigniew Jędrzejewski-Szmek 4f9456
+                        _exit(EXIT_FAILURE);
Zbigniew Jędrzejewski-Szmek 4f9456
                 }
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                if (pid == 0) {
Zbigniew Jędrzejewski-Szmek 4f9456
-                        char *_argv[2];
Zbigniew Jędrzejewski-Szmek 4f9456
-                        /* Child */
Zbigniew Jędrzejewski-Szmek 4f9456
+                FOREACH_DIRENT(de, d, break) {
Zbigniew Jędrzejewski-Szmek 4f9456
+                        _cleanup_free_ char *path = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
+                        pid_t pid;
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                        if (!argv) {
Zbigniew Jędrzejewski-Szmek 4f9456
-                                _argv[0] = path;
Zbigniew Jędrzejewski-Szmek 4f9456
-                                _argv[1] = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
-                                argv = _argv;
Zbigniew Jędrzejewski-Szmek 4f9456
-                        } else
Zbigniew Jędrzejewski-Szmek 4f9456
-                                argv[0] = path;
Zbigniew Jędrzejewski-Szmek 4f9456
+                        if (!dirent_is_file(de))
Zbigniew Jędrzejewski-Szmek 4f9456
+                                continue;
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                        execv(path, argv);
Zbigniew Jędrzejewski-Szmek 4f9456
+                        if (asprintf(&path, "%s/%s", directory, de->d_name) < 0) {
Zbigniew Jędrzejewski-Szmek 4f9456
+                                log_oom();
Zbigniew Jędrzejewski-Szmek 4f9456
+                                _exit(EXIT_FAILURE);
Zbigniew Jędrzejewski-Szmek 4f9456
+                        }
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                        log_error("Failed to execute %s: %m", path);
Zbigniew Jędrzejewski-Szmek 4f9456
-                        _exit(EXIT_FAILURE);
Zbigniew Jędrzejewski-Szmek 4f9456
-                }
Zbigniew Jędrzejewski-Szmek 4f9456
+                        pid = fork();
Zbigniew Jędrzejewski-Szmek 4f9456
+                        if (pid < 0) {
Zbigniew Jędrzejewski-Szmek 4f9456
+                                log_error("Failed to fork: %m");
Zbigniew Jędrzejewski-Szmek 4f9456
+                                continue;
Zbigniew Jędrzejewski-Szmek 4f9456
+                        } else if (pid == 0) {
Zbigniew Jędrzejewski-Szmek 4f9456
+                                char *_argv[2];
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                log_debug("Spawned %s as %lu", path, (unsigned long) pid);
Zbigniew Jędrzejewski-Szmek 4f9456
+                                assert_se(prctl(PR_SET_PDEATHSIG, SIGTERM) == 0);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                if ((k = hashmap_put(pids, UINT_TO_PTR(pid), path)) < 0) {
Zbigniew Jędrzejewski-Szmek 4f9456
-                        log_error("Failed to add PID to set: %s", strerror(-k));
Zbigniew Jędrzejewski-Szmek 4f9456
-                        free(path);
Zbigniew Jędrzejewski-Szmek 4f9456
-                }
Zbigniew Jędrzejewski-Szmek 4f9456
-        }
Zbigniew Jędrzejewski-Szmek 4f9456
+                                if (!argv) {
Zbigniew Jędrzejewski-Szmek 4f9456
+                                        _argv[0] = path;
Zbigniew Jędrzejewski-Szmek 4f9456
+                                        _argv[1] = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
+                                        argv = _argv;
Zbigniew Jędrzejewski-Szmek 4f9456
+                                } else
Zbigniew Jędrzejewski-Szmek 4f9456
+                                        argv[0] = path;
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-        while (!hashmap_isempty(pids)) {
Zbigniew Jędrzejewski-Szmek 4f9456
-                pid_t pid = PTR_TO_UINT(hashmap_first_key(pids));
Zbigniew Jędrzejewski-Szmek 4f9456
-                siginfo_t si = {};
Zbigniew Jędrzejewski-Szmek 4f9456
-                char *path;
Zbigniew Jędrzejewski-Szmek 4f9456
+                                execv(path, argv);
Zbigniew Jędrzejewski-Szmek 4f9456
+                                log_error("Failed to execute %s: %m", path);
Zbigniew Jędrzejewski-Szmek 4f9456
+                                _exit(EXIT_FAILURE);
Zbigniew Jędrzejewski-Szmek 4f9456
+                        }
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                if (waitid(P_PID, pid, &si, WEXITED) < 0) {
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                        if (errno == EINTR)
Zbigniew Jędrzejewski-Szmek 4f9456
-                                continue;
Zbigniew Jędrzejewski-Szmek 4f9456
+                        log_debug("Spawned %s as %lu.", path, (long unsigned) pid);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                        log_error("waitid() failed: %m");
Zbigniew Jędrzejewski-Szmek 4f9456
-                        goto finish;
Zbigniew Jędrzejewski-Szmek 4f9456
+                        r = hashmap_put(pids, UINT_TO_PTR(pid), path);
Zbigniew Jędrzejewski-Szmek 4f9456
+                        if (r < 0) {
Zbigniew Jędrzejewski-Szmek 4f9456
+                                log_oom();
Zbigniew Jędrzejewski-Szmek 4f9456
+                                _exit(EXIT_FAILURE);
Zbigniew Jędrzejewski-Szmek 4f9456
+                        }
Zbigniew Jędrzejewski-Szmek 4f9456
+
Zbigniew Jędrzejewski-Szmek 4f9456
+                        path = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
                 }
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                if ((path = hashmap_remove(pids, UINT_TO_PTR(si.si_pid)))) {
Zbigniew Jędrzejewski-Szmek 4f9456
-                        if (!is_clean_exit(si.si_code, si.si_status, NULL)) {
Zbigniew Jędrzejewski-Szmek 4f9456
-                                if (si.si_code == CLD_EXITED)
Zbigniew Jędrzejewski-Szmek 4f9456
-                                        log_error("%s exited with exit status %i.", path, si.si_status);
Zbigniew Jędrzejewski-Szmek 4f9456
-                                else
Zbigniew Jędrzejewski-Szmek 4f9456
-                                        log_error("%s terminated by signal %s.", path, signal_to_string(si.si_status));
Zbigniew Jędrzejewski-Szmek 4f9456
-                        } else
Zbigniew Jędrzejewski-Szmek 4f9456
-                                log_debug("%s exited successfully.", path);
Zbigniew Jędrzejewski-Szmek 4f9456
+                /* Abort execution of this process after the
Zbigniew Jędrzejewski-Szmek 4f9456
+                 * timout. We simply rely on SIGALRM as default action
Zbigniew Jędrzejewski-Szmek 4f9456
+                 * terminating the process, and turn on alarm(). */
Zbigniew Jędrzejewski-Szmek 4f9456
+
Zbigniew Jędrzejewski-Szmek 4f9456
+                if (timeout != (usec_t) -1)
Zbigniew Jędrzejewski-Szmek 4f9456
+                        alarm((timeout + USEC_PER_SEC - 1) / USEC_PER_SEC);
Zbigniew Jędrzejewski-Szmek 4f9456
+
Zbigniew Jędrzejewski-Szmek 4f9456
+                while (!hashmap_isempty(pids)) {
Zbigniew Jędrzejewski-Szmek 4f9456
+                        _cleanup_free_ char *path = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
+                        pid_t pid;
Zbigniew Jędrzejewski-Szmek 4f9456
+
Zbigniew Jędrzejewski-Szmek 4f9456
+                        pid = PTR_TO_UINT(hashmap_first_key(pids));
Zbigniew Jędrzejewski-Szmek 4f9456
+                        assert(pid > 0);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-                        free(path);
Zbigniew Jędrzejewski-Szmek 4f9456
+                        path = hashmap_remove(pids, UINT_TO_PTR(pid));
Zbigniew Jędrzejewski-Szmek 4f9456
+                        assert(path);
Zbigniew Jędrzejewski-Szmek 4f9456
+
Zbigniew Jędrzejewski-Szmek 4f9456
+                        wait_for_terminate_and_warn(path, pid);
Zbigniew Jędrzejewski-Szmek 4f9456
                 }
Zbigniew Jędrzejewski-Szmek 4f9456
-        }
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-finish:
Zbigniew Jędrzejewski-Szmek 4f9456
-        if (_d)
Zbigniew Jędrzejewski-Szmek 4f9456
-                closedir(_d);
Zbigniew Jędrzejewski-Szmek 4f9456
+                _exit(EXIT_SUCCESS);
Zbigniew Jędrzejewski-Szmek 4f9456
+        }
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-        if (pids)
Zbigniew Jędrzejewski-Szmek 4f9456
-                hashmap_free_free(pids);
Zbigniew Jędrzejewski-Szmek 4f9456
+        wait_for_terminate_and_warn(directory, executor_pid);
Zbigniew Jędrzejewski-Szmek 4f9456
 }
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
 int kill_and_sigcont(pid_t pid, int sig) {
Zbigniew Jędrzejewski-Szmek 4f9456
diff --git a/src/shared/util.h b/src/shared/util.h
Zbigniew Jędrzejewski-Szmek 4f9456
index 02621a7..47a3dc9 100644
Zbigniew Jędrzejewski-Szmek 4f9456
--- a/src/shared/util.h
Zbigniew Jędrzejewski-Szmek 4f9456
+++ b/src/shared/util.h
Zbigniew Jędrzejewski-Szmek 4f9456
@@ -432,7 +432,7 @@ bool tty_is_console(const char *tty) _pure_;
Zbigniew Jędrzejewski-Szmek 4f9456
 int vtnr_from_tty(const char *tty);
Zbigniew Jędrzejewski-Szmek 4f9456
 const char *default_term_for_tty(const char *tty);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-void execute_directory(const char *directory, DIR *_d, char *argv[]);
Zbigniew Jędrzejewski-Szmek 4f9456
+void execute_directory(const char *directory, DIR *_d, usec_t timeout, char *argv[]);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
 int kill_and_sigcont(pid_t pid, int sig);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
diff --git a/src/sleep/sleep.c b/src/sleep/sleep.c
Zbigniew Jędrzejewski-Szmek 4f9456
index c228cb6..8e847db 100644
Zbigniew Jędrzejewski-Szmek 4f9456
--- a/src/sleep/sleep.c
Zbigniew Jędrzejewski-Szmek 4f9456
+++ b/src/sleep/sleep.c
Zbigniew Jędrzejewski-Szmek 4f9456
@@ -25,14 +25,15 @@
Zbigniew Jędrzejewski-Szmek 4f9456
 #include <string.h>
Zbigniew Jędrzejewski-Szmek 4f9456
 #include <getopt.h>
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
-#include "systemd/sd-id128.h"
Zbigniew Jędrzejewski-Szmek 4f9456
-#include "systemd/sd-messages.h"
Zbigniew Jędrzejewski-Szmek 4f9456
+#include "sd-id128.h"
Zbigniew Jędrzejewski-Szmek 4f9456
+#include "sd-messages.h"
Zbigniew Jędrzejewski-Szmek 4f9456
 #include "log.h"
Zbigniew Jędrzejewski-Szmek 4f9456
 #include "util.h"
Zbigniew Jędrzejewski-Szmek 4f9456
 #include "strv.h"
Zbigniew Jędrzejewski-Szmek 4f9456
 #include "fileio.h"
Zbigniew Jędrzejewski-Szmek 4f9456
 #include "build.h"
Zbigniew Jędrzejewski-Szmek 4f9456
 #include "sleep-config.h"
Zbigniew Jędrzejewski-Szmek 4f9456
+#include "def.h"
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
 static char* arg_verb = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
@@ -41,9 +42,12 @@ static int write_mode(char **modes) {
Zbigniew Jędrzejewski-Szmek 4f9456
         char **mode;
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
         STRV_FOREACH(mode, modes) {
Zbigniew Jędrzejewski-Szmek 4f9456
-                int k = write_string_file("/sys/power/disk", *mode);
Zbigniew Jędrzejewski-Szmek 4f9456
+                int k;
Zbigniew Jędrzejewski-Szmek 4f9456
+
Zbigniew Jędrzejewski-Szmek 4f9456
+                k = write_string_file("/sys/power/disk", *mode);
Zbigniew Jędrzejewski-Szmek 4f9456
                 if (k == 0)
Zbigniew Jędrzejewski-Szmek 4f9456
                         return 0;
Zbigniew Jędrzejewski-Szmek 4f9456
+
Zbigniew Jędrzejewski-Szmek 4f9456
                 log_debug("Failed to write '%s' to /sys/power/disk: %s",
Zbigniew Jędrzejewski-Szmek 4f9456
                           *mode, strerror(-k));
Zbigniew Jędrzejewski-Szmek 4f9456
                 if (r == 0)
Zbigniew Jędrzejewski-Szmek 4f9456
@@ -106,7 +110,7 @@ static int execute(char **modes, char **states) {
Zbigniew Jędrzejewski-Szmek 4f9456
         arguments[1] = (char*) "pre";
Zbigniew Jędrzejewski-Szmek 4f9456
         arguments[2] = arg_verb;
Zbigniew Jędrzejewski-Szmek 4f9456
         arguments[3] = NULL;
Zbigniew Jędrzejewski-Szmek 4f9456
-        execute_directory(SYSTEM_SLEEP_PATH, NULL, arguments);
Zbigniew Jędrzejewski-Szmek 4f9456
+        execute_directory(SYSTEM_SLEEP_PATH, NULL, DEFAULT_TIMEOUT_USEC, arguments);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
         log_struct(LOG_INFO,
Zbigniew Jędrzejewski-Szmek 4f9456
                    MESSAGE_ID(SD_MESSAGE_SLEEP_START),
Zbigniew Jędrzejewski-Szmek 4f9456
@@ -125,7 +129,7 @@ static int execute(char **modes, char **states) {
Zbigniew Jędrzejewski-Szmek 4f9456
                    NULL);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
         arguments[1] = (char*) "post";
Zbigniew Jędrzejewski-Szmek 4f9456
-        execute_directory(SYSTEM_SLEEP_PATH, NULL, arguments);
Zbigniew Jędrzejewski-Szmek 4f9456
+        execute_directory(SYSTEM_SLEEP_PATH, NULL, DEFAULT_TIMEOUT_USEC, arguments);
Zbigniew Jędrzejewski-Szmek 4f9456
 
Zbigniew Jędrzejewski-Szmek 4f9456
         return r;
Zbigniew Jędrzejewski-Szmek 4f9456
 }