[systemd-devel] [PATCH 1/4] manager: print a warning after 2/3 of the start timeout

Zbigniew Jędrzejewski-Szmek zbyszek at in.waw.pl
Sat Oct 25 12:43:24 PDT 2014


---
This could use some more polishing, but is useful as is I think...

 src/core/manager.c | 67 ++++++++++++++++++++++++++++++++++++++++++++++++++++--
 src/core/manager.h |  1 +
 2 files changed, 66 insertions(+), 2 deletions(-)

diff --git a/src/core/manager.c b/src/core/manager.c
index b790d18bbe..7917afdbb1 100644
--- a/src/core/manager.c
+++ b/src/core/manager.c
@@ -92,6 +92,45 @@ static int manager_dispatch_idle_pipe_fd(sd_event_source *source, int fd, uint32
 static int manager_dispatch_jobs_in_progress(sd_event_source *source, usec_t usec, void *userdata);
 static int manager_dispatch_run_queue(sd_event_source *source, void *userdata);
 
+static int manager_log_running_jobs(Manager *m) {
+        unsigned n;
+
+        assert(m);
+
+        n = hashmap_size(m->jobs);
+
+        if (n > 0) {
+                unsigned i = 0;
+                _cleanup_strv_free_ char **strv;
+                _cleanup_free_ char *all = NULL;
+
+                Iterator it;
+                Job *j;
+
+                strv = new(char*, n + 1);
+                if (!strv)
+                        return log_oom();
+
+                HASHMAP_FOREACH(j, m->jobs, it) {
+                        strv[i] = strjoin(j->unit->id, "/", job_type_to_string(j->type),
+                                          "/", job_state_to_string(j->state), NULL);
+                        if (!strv[i])
+                                return log_oom();
+                        i++;
+                }
+                strv[i] = NULL;
+
+                all = strv_join(strv, ",\n\t");
+                if (!all)
+                        return log_oom();
+
+                log_info("Active jobs (%u running):\n\t%s.", m->n_running_jobs, all);
+        } else
+                log_info("No jobs seem to be running.");
+
+        return 0;
+}
+
 static int manager_watch_jobs_in_progress(Manager *m) {
         usec_t next;
 
@@ -1015,15 +1054,39 @@ static int manager_distribute_fds(Manager *m, FDSet *fds) {
 
 static int on_start_timeout(sd_event_source *s, usec_t usec, void *userdata) {
         Manager *m = userdata;
+        int r;
 
         assert(s);
         assert(m);
 
+        if (!m->start_timeout_warned) {
+                log_warning("2/3 of the start timeout have passed.");
+                m->start_timeout_warned = true;
+
+                (void) manager_log_running_jobs(m);
+
+                r = sd_event_source_set_time(m->start_timeout_event_source,
+                                             now(CLOCK_MONOTONIC) + m->start_timeout_usec / 3);
+                if (r >= 0) {
+                        r = sd_event_source_set_enabled(m->start_timeout_event_source, SD_EVENT_ONESHOT);
+                        if (r >= 0)
+                                return 0;
+                }
+
+                log_error("Failed to postpone start timeout event, taking immediate action: %s",
+                          strerror(-r));
+        }
+
         m->start_timeout_event_source = sd_event_source_unref(m->start_timeout_event_source);
 
-        log_error("Startup timed out.");
+        log_error("Startup timed out, performing %s%s%s.",
+                  failure_action_to_string(m->start_timeout_action),
+                  m->start_timeout_reboot_arg ? "/" : "",
+                  strempty(m->start_timeout_reboot_arg));
+        (void) manager_log_running_jobs(m);
 
         failure_action(m, m->start_timeout_action, m->start_timeout_reboot_arg);
+
         return 0;
 }
 
@@ -1108,7 +1171,7 @@ int manager_startup(Manager *m, FILE *serialization, FDSet *fds) {
                                         m->event,
                                         &m->start_timeout_event_source,
                                         CLOCK_MONOTONIC,
-                                        now(CLOCK_MONOTONIC) + m->start_timeout_usec, 0,
+                                        now(CLOCK_MONOTONIC) + m->start_timeout_usec / 3 * 2, 0,
                                         on_start_timeout, m);
                         if (r < 0)
                                 log_error("Failed to add start timeout event: %s", strerror(-r));
diff --git a/src/core/manager.h b/src/core/manager.h
index 8e3c146b42..4db6433a2b 100644
--- a/src/core/manager.h
+++ b/src/core/manager.h
@@ -290,6 +290,7 @@ struct Manager {
         sd_event_source *start_timeout_event_source;
         FailureAction start_timeout_action;
         char *start_timeout_reboot_arg;
+        bool start_timeout_warned;
 };
 
 int manager_new(SystemdRunningAs running_as, bool test_run, Manager **m);
-- 
1.9.3



More information about the systemd-devel mailing list