a9339c
From 50ce13182e07af7f240c61d03bf113e86a269917 Mon Sep 17 00:00:00 2001
a9339c
From: Michal Schmidt <mschmidt@redhat.com>
a9339c
Date: Tue, 21 Jul 2015 14:54:24 +0200
a9339c
Subject: [PATCH] core: try harder to get job completion messages too
a9339c
a9339c
This is similar to "core: always try harder to get unit status
a9339c
message format string", but for job completion status messages.
a9339c
It makes generic status messages applicable for printing to the console.
a9339c
And it rewrites the functions in a more table-based style.
a9339c
a9339c
(cherry picked from commit aa49ab5f22c0fdc7a5381d4e452f40705f3d7bf8)
a9339c
a9339c
Related: #1506256
a9339c
---
a9339c
 src/core/job.c | 192 ++++++++++++++++++++-------------------------------------
a9339c
 1 file changed, 68 insertions(+), 124 deletions(-)
a9339c
a9339c
diff --git a/src/core/job.c b/src/core/job.c
a9339c
index 612caa604..f371f914d 100644
a9339c
--- a/src/core/job.c
a9339c
+++ b/src/core/job.c
a9339c
@@ -622,156 +622,100 @@ int job_run_and_invalidate(Job *j) {
a9339c
 }
a9339c
 
a9339c
 _pure_ static const char *job_get_status_message_format(Unit *u, JobType t, JobResult result) {
a9339c
+        const char *format;
a9339c
         const UnitStatusMessageFormats *format_table;
a9339c
+        static const char *const generic_finished_start_job[_JOB_RESULT_MAX] = {
a9339c
+                [JOB_DONE]        = "Started %s.",
a9339c
+                [JOB_TIMEOUT]     = "Timed out starting %s.",
a9339c
+                [JOB_FAILED]      = "Failed to start %s.",
a9339c
+                [JOB_DEPENDENCY]  = "Dependency failed for %s.",
a9339c
+                [JOB_ASSERT]      = "Assertion failed for %s.",
a9339c
+                [JOB_UNSUPPORTED] = "Starting of %s not supported.",
a9339c
+        };
a9339c
+        static const char *const generic_finished_stop_job[_JOB_RESULT_MAX] = {
a9339c
+                [JOB_DONE]        = "Stopped %s.",
a9339c
+                [JOB_FAILED]      = "Stopped (with error) %s.",
a9339c
+                [JOB_TIMEOUT]     = "Timed out stoppping %s.",
a9339c
+        };
a9339c
+        static const char *const generic_finished_reload_job[_JOB_RESULT_MAX] = {
a9339c
+                [JOB_DONE]        = "Reloaded %s.",
a9339c
+                [JOB_FAILED]      = "Reload failed for %s.",
a9339c
+                [JOB_TIMEOUT]     = "Timed out reloading %s.",
a9339c
+        };
a9339c
+        /* When verify-active detects the unit is inactive, report it.
a9339c
+         * Most likely a DEPEND warning from a requisiting unit will
a9339c
+         * occur next and it's nice to see what was requisited. */
a9339c
+        static const char *const generic_finished_verify_active_job[_JOB_RESULT_MAX] = {
a9339c
+                [JOB_SKIPPED]     = "%s is not active.",
a9339c
+        };
a9339c
 
a9339c
         assert(u);
a9339c
         assert(t >= 0);
a9339c
         assert(t < _JOB_TYPE_MAX);
a9339c
 
a9339c
-        format_table = &UNIT_VTABLE(u)->status_message_formats;
a9339c
-        if (!format_table)
a9339c
-                return NULL;
a9339c
+        if (t == JOB_START || t == JOB_STOP || t == JOB_RESTART) {
a9339c
+                format_table = &UNIT_VTABLE(u)->status_message_formats;
a9339c
+                if (format_table) {
a9339c
+                        format = t == JOB_START ? format_table->finished_start_job[result] :
a9339c
+                                                  format_table->finished_stop_job[result];
a9339c
+                        if (format)
a9339c
+                                return format;
a9339c
+                }
a9339c
+        }
a9339c
 
a9339c
+        /* Return generic strings */
a9339c
         if (t == JOB_START)
a9339c
-                return format_table->finished_start_job[result];
a9339c
+                return generic_finished_start_job[result];
a9339c
         else if (t == JOB_STOP || t == JOB_RESTART)
a9339c
-                return format_table->finished_stop_job[result];
a9339c
-
a9339c
-        return NULL;
a9339c
-}
a9339c
-
a9339c
-_pure_ static const char *job_get_status_message_format_try_harder(Unit *u, JobType t, JobResult result) {
a9339c
-        const char *format;
a9339c
-
a9339c
-        assert(u);
a9339c
-        assert(t >= 0);
a9339c
-        assert(t < _JOB_TYPE_MAX);
a9339c
-
a9339c
-        format = job_get_status_message_format(u, t, result);
a9339c
-        if (format)
a9339c
-                return format;
a9339c
-
a9339c
-        /* Return generic strings */
a9339c
-        if (t == JOB_START) {
a9339c
-                if (result == JOB_DONE)
a9339c
-                        return "Started %s.";
a9339c
-                else if (result == JOB_TIMEOUT)
a9339c
-                        return "Timed out starting %s.";
a9339c
-                else if (result == JOB_FAILED)
a9339c
-                        return "Failed to start %s.";
a9339c
-                else if (result == JOB_DEPENDENCY)
a9339c
-                        return "Dependency failed for %s.";
a9339c
-                else if (result == JOB_ASSERT)
a9339c
-                        return "Assertion failed for %s.";
a9339c
-                else if (result == JOB_UNSUPPORTED)
a9339c
-                        return "Starting of %s not supported.";
a9339c
-        } else if (t == JOB_STOP || t == JOB_RESTART) {
a9339c
-                if (result == JOB_DONE)
a9339c
-                        return "Stopped %s.";
a9339c
-                else if (result == JOB_FAILED)
a9339c
-                        return "Stopped (with error) %s.";
a9339c
-                else if (result == JOB_TIMEOUT)
a9339c
-                        return "Timed out stoppping %s.";
a9339c
-        } else if (t == JOB_RELOAD) {
a9339c
-                if (result == JOB_DONE)
a9339c
-                        return "Reloaded %s.";
a9339c
-                else if (result == JOB_FAILED)
a9339c
-                        return "Reload failed for %s.";
a9339c
-                else if (result == JOB_TIMEOUT)
a9339c
-                        return "Timed out reloading %s.";
a9339c
-        }
a9339c
+                return generic_finished_stop_job[result];
a9339c
+        else if (t == JOB_RELOAD)
a9339c
+                return generic_finished_reload_job[result];
a9339c
+        else if (t == JOB_VERIFY_ACTIVE)
a9339c
+                return generic_finished_verify_active_job[result];
a9339c
 
a9339c
         return NULL;
a9339c
 }
a9339c
 
a9339c
 static void job_print_status_message(Unit *u, JobType t, JobResult result) {
a9339c
         const char *format;
a9339c
+        static const char* const job_result_status_table[_JOB_RESULT_MAX] = {
a9339c
+                [JOB_DONE]        = ANSI_GREEN_ON            "  OK  " ANSI_HIGHLIGHT_OFF,
a9339c
+                [JOB_TIMEOUT]     = ANSI_HIGHLIGHT_RED_ON    " TIME " ANSI_HIGHLIGHT_OFF,
a9339c
+                [JOB_FAILED]      = ANSI_HIGHLIGHT_RED_ON    "FAILED" ANSI_HIGHLIGHT_OFF,
a9339c
+                [JOB_DEPENDENCY]  = ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF,
a9339c
+                [JOB_SKIPPED]     = ANSI_HIGHLIGHT_ON        " INFO " ANSI_HIGHLIGHT_OFF,
a9339c
+                [JOB_ASSERT]      = ANSI_HIGHLIGHT_YELLOW_ON "ASSERT" ANSI_HIGHLIGHT_OFF,
a9339c
+                [JOB_UNSUPPORTED] = ANSI_HIGHLIGHT_YELLOW_ON "UNSUPP" ANSI_HIGHLIGHT_OFF,
a9339c
+        };
a9339c
 
a9339c
         assert(u);
a9339c
         assert(t >= 0);
a9339c
         assert(t < _JOB_TYPE_MAX);
a9339c
 
a9339c
-        DISABLE_WARNING_FORMAT_NONLITERAL;
a9339c
-
a9339c
-        if (t == JOB_START) {
a9339c
-                format = job_get_status_message_format(u, t, result);
a9339c
-                if (!format)
a9339c
-                        return;
a9339c
-
a9339c
-                switch (result) {
a9339c
-
a9339c
-                case JOB_DONE:
a9339c
-                        if (u->condition_result)
a9339c
-                                unit_status_printf(u, ANSI_GREEN_ON "  OK  " ANSI_HIGHLIGHT_OFF, format);
a9339c
-                        break;
a9339c
-
a9339c
-                case JOB_TIMEOUT:
a9339c
-                        manager_flip_auto_status(u->manager, true);
a9339c
-                        unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format);
a9339c
-                        break;
a9339c
-
a9339c
-                case JOB_FAILED: {
a9339c
-                        _cleanup_free_ char *quoted = NULL;
a9339c
-
a9339c
-                        quoted = shell_maybe_quote(u->id);
a9339c
-
a9339c
-                        manager_flip_auto_status(u->manager, true);
a9339c
-                        unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON "FAILED" ANSI_HIGHLIGHT_OFF, format);
a9339c
-                        manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL, "See 'systemctl status %s' for details.", strna(quoted));
a9339c
-                        break;
a9339c
-                }
a9339c
-
a9339c
-                case JOB_DEPENDENCY:
a9339c
-                        manager_flip_auto_status(u->manager, true);
a9339c
-                        unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "DEPEND" ANSI_HIGHLIGHT_OFF, format);
a9339c
-                        break;
a9339c
-
a9339c
-                case JOB_ASSERT:
a9339c
-                        manager_flip_auto_status(u->manager, true);
a9339c
-                        unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "ASSERT" ANSI_HIGHLIGHT_OFF, format);
a9339c
-                        break;
a9339c
-
a9339c
-                case JOB_UNSUPPORTED:
a9339c
-                        manager_flip_auto_status(u->manager, true);
a9339c
-                        unit_status_printf(u, ANSI_HIGHLIGHT_YELLOW_ON "UNSUPP" ANSI_HIGHLIGHT_OFF, format);
a9339c
-                        break;
a9339c
-
a9339c
-                default:
a9339c
-                        ;
a9339c
-                }
a9339c
-
a9339c
-        } else if (t == JOB_STOP || t == JOB_RESTART) {
a9339c
-
a9339c
-                format = job_get_status_message_format(u, t, result);
a9339c
-                if (!format)
a9339c
-                        return;
a9339c
+        /* Reload status messages have traditionally not been printed to console. */
a9339c
+        if (t == JOB_RELOAD)
a9339c
+                return;
a9339c
 
a9339c
-                switch (result) {
a9339c
+        if (t == JOB_START && result == JOB_DONE && !u->condition_result)
a9339c
+                return;
a9339c
 
a9339c
-                case JOB_TIMEOUT:
a9339c
-                        manager_flip_auto_status(u->manager, true);
a9339c
-                        unit_status_printf(u, ANSI_HIGHLIGHT_RED_ON " TIME " ANSI_HIGHLIGHT_OFF, format);
a9339c
-                        break;
a9339c
+        format = job_get_status_message_format(u, t, result);
a9339c
+        if (!format)
a9339c
+                return;
a9339c
 
a9339c
-                case JOB_DONE:
a9339c
-                case JOB_FAILED:
a9339c
-                        unit_status_printf(u, ANSI_GREEN_ON "  OK  " ANSI_HIGHLIGHT_OFF, format);
a9339c
-                        break;
a9339c
+        if (result != JOB_DONE)
a9339c
+                manager_flip_auto_status(u->manager, true);
a9339c
 
a9339c
-                default:
a9339c
-                        ;
a9339c
-                }
a9339c
+        DISABLE_WARNING_FORMAT_NONLITERAL;
a9339c
+        unit_status_printf(u, job_result_status_table[result], format);
a9339c
+        REENABLE_WARNING;
a9339c
 
a9339c
-        } else if (t == JOB_VERIFY_ACTIVE) {
a9339c
+        if (t == JOB_START && result == JOB_FAILED) {
a9339c
+                _cleanup_free_ char *quoted = shell_maybe_quote(u->id);
a9339c
 
a9339c
-                /* When verify-active detects the unit is inactive, report it.
a9339c
-                 * Most likely a DEPEND warning from a requisiting unit will
a9339c
-                 * occur next and it's nice to see what was requisited. */
a9339c
-                if (result == JOB_SKIPPED)
a9339c
-                        unit_status_printf(u, ANSI_HIGHLIGHT_ON " INFO " ANSI_HIGHLIGHT_OFF, "%s is not active.");
a9339c
+                manager_status_printf(u->manager, STATUS_TYPE_NORMAL, NULL,
a9339c
+                                      "See 'systemctl status %s' for details.", strna(quoted));
a9339c
         }
a9339c
-
a9339c
-        REENABLE_WARNING;
a9339c
 }
a9339c
 
a9339c
 static void job_log_status_message(Unit *u, JobType t, JobResult result) {
a9339c
@@ -788,7 +732,7 @@ static void job_log_status_message(Unit *u, JobType t, JobResult result) {
a9339c
         if (log_on_console())
a9339c
                 return;
a9339c
 
a9339c
-        format = job_get_status_message_format_try_harder(u, t, result);
a9339c
+        format = job_get_status_message_format(u, t, result);
a9339c
         if (!format)
a9339c
                 return;
a9339c