]> git.ipfire.org Git - thirdparty/systemd.git/blobdiff - src/systemctl/systemctl.c
systemctl: add service-watchdogs command
[thirdparty/systemd.git] / src / systemctl / systemctl.c
index c8c22b25912489e8b1f753b9a9314ab294546fa5..a771c75f5f33bae36f2d358b55073615a37eca2e 100644 (file)
@@ -3,15 +3,12 @@
 #include <errno.h>
 #include <fcntl.h>
 #include <getopt.h>
-#include <locale.h>
 #include <stdbool.h>
 #include <stddef.h>
 #include <stdio.h>
-#include <string.h>
 #include <sys/mount.h>
 #include <sys/prctl.h>
 #include <sys/reboot.h>
-#include <sys/socket.h>
 #include <unistd.h>
 
 #include "sd-bus.h"
@@ -239,22 +236,16 @@ static void release_busses(void) {
                 buses[w] = sd_bus_flush_close_unref(buses[w]);
 }
 
-static void ask_password_agent_open_if_enabled(void) {
+static void ask_password_agent_open_maybe(void) {
         /* Open the password agent as a child process if necessary */
 
         if (arg_dry_run)
                 return;
 
-        if (!arg_ask_password)
-                return;
-
         if (arg_scope != UNIT_FILE_SYSTEM)
                 return;
 
-        if (arg_transport != BUS_TRANSPORT_LOCAL)
-                return;
-
-        ask_password_agent_open();
+        ask_password_agent_open_if_enabled(arg_transport, arg_ask_password);
 }
 
 static void polkit_agent_open_maybe(void) {
@@ -807,7 +798,6 @@ static int expand_names(sd_bus *bus, char **names, const char* suffix, char ***r
         return 0;
 }
 
-
 static int list_units(int argc, char *argv[], void *userdata) {
         _cleanup_free_ UnitInfo *unit_infos = NULL;
         _cleanup_(message_set_freep) Set *replies = NULL;
@@ -3075,7 +3065,7 @@ static int start_unit(int argc, char *argv[], void *userdata) {
         if (r < 0)
                 return r;
 
-        ask_password_agent_open_if_enabled();
+        ask_password_agent_open_maybe();
         polkit_agent_open_maybe();
 
         if (arg_action == ACTION_SYSTEMCTL) {
@@ -4180,7 +4170,6 @@ static void print_status_info(
         const char *path;
         char **t, **t2;
         int r;
-        bool is_timer;
 
         assert(i);
 
@@ -4210,24 +4199,24 @@ static void print_status_info(
                 path = formatted_path;
 
         if (!isempty(i->load_error))
-                printf("   Loaded: %s%s%s (Reason: %s)\n",
+                printf("     Loaded: %s%s%s (Reason: %s)\n",
                        on, strna(i->load_state), off, i->load_error);
         else if (path && !isempty(i->unit_file_state) && !isempty(i->unit_file_preset) &&
                  !STR_IN_SET(i->unit_file_state, "generated", "transient"))
-                printf("   Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
+                printf("     Loaded: %s%s%s (%s; %s; vendor preset: %s)\n",
                        on, strna(i->load_state), off, path, i->unit_file_state, i->unit_file_preset);
         else if (path && !isempty(i->unit_file_state))
-                printf("   Loaded: %s%s%s (%s; %s)\n",
+                printf("     Loaded: %s%s%s (%s; %s)\n",
                        on, strna(i->load_state), off, path, i->unit_file_state);
         else if (path)
-                printf("   Loaded: %s%s%s (%s)\n",
+                printf("     Loaded: %s%s%s (%s)\n",
                        on, strna(i->load_state), off, path);
         else
-                printf("   Loaded: %s%s%s\n",
+                printf("     Loaded: %s%s%s\n",
                        on, strna(i->load_state), off);
 
         if (i->transient)
-                printf("Transient: yes\n");
+                printf("  Transient: yes\n");
 
         if (!strv_isempty(i->dropin_paths)) {
                 _cleanup_free_ char *dir = NULL;
@@ -4239,8 +4228,8 @@ static void print_status_info(
                         const char *df;
 
                         if (!dir || last) {
-                                printf(dir ? "           " :
-                                             "  Drop-In: ");
+                                printf(dir ? "             " :
+                                             "    Drop-In: ");
 
                                 dir = mfree(dir);
 
@@ -4251,7 +4240,7 @@ static void print_status_info(
                                 }
 
                                 printf("%s\n"
-                                       "           %s", dir,
+                                       "             %s", dir,
                                        special_glyph(SPECIAL_GLYPH_TREE_RIGHT));
                         }
 
@@ -4268,10 +4257,10 @@ static void print_status_info(
 
         ss = streq_ptr(i->active_state, i->sub_state) ? NULL : i->sub_state;
         if (ss)
-                printf("   Active: %s%s (%s)%s",
+                printf("     Active: %s%s (%s)%s",
                        active_on, strna(i->active_state), ss, active_off);
         else
-                printf("   Active: %s%s%s",
+                printf("     Active: %s%s%s",
                        active_on, strna(i->active_state), active_off);
 
         if (!isempty(i->result) && !streq(i->result, "success"))
@@ -4292,28 +4281,19 @@ static void print_status_info(
         else
                 printf("\n");
 
-        is_timer = endswith(i->id, ".timer");
+        STRV_FOREACH(t, i->triggered_by) {
+                UnitActiveState state = _UNIT_ACTIVE_STATE_INVALID;
 
-        if (!is_timer && !strv_isempty(i->triggered_by)) {
-                char **trigger;
-                bool first = true;
+                (void) get_state_one_unit(bus, *t, &state);
+                format_active_state(unit_active_state_to_string(state), &on, &off);
 
-                printf("   TriggeredBy:");
-                STRV_FOREACH(trigger, i->triggered_by) {
-                        UnitActiveState state = _UNIT_ACTIVE_STATE_INVALID;
-
-                        (void) get_state_one_unit(bus, *trigger, &state);
-                        format_active_state(unit_active_state_to_string(state), &on, &off);
-                        if (first) {
-                                printf(" %s%s%s %s\n", on, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE), off, *trigger);
-                                first = false;
-                        } else {
-                                printf("                %s%s%s %s\n", on, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE), off, *trigger);
-                        }
-                }
+                printf("%s %s%s%s %s\n",
+                       t == i->triggered_by ? "TriggeredBy:" : "            ",
+                       on, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE), off,
+                       *t);
         }
 
-        if (is_timer) {
+        if (endswith(i->id, ".timer")) {
                 char tstamp1[FORMAT_TIMESTAMP_RELATIVE_MAX],
                      tstamp2[FORMAT_TIMESTAMP_MAX];
                 const char *next_rel_time, *next_time;
@@ -4321,7 +4301,7 @@ static void print_status_info(
                                            i->next_elapse_monotonic};
                 usec_t next_elapse;
 
-                printf("  Trigger: ");
+                printf("    Trigger: ");
 
                 dual_timestamp_get(&nw);
                 next_elapse = calc_next_elapse(&nw, &next);
@@ -4334,23 +4314,16 @@ static void print_status_info(
                         printf("n/a\n");
         }
 
-        if (!strv_isempty(i->triggers)) {
-                char **trigger;
-                bool first = true;
+        STRV_FOREACH(t, i->triggers) {
+                UnitActiveState state = _UNIT_ACTIVE_STATE_INVALID;
 
-                printf(" Triggers:");
-                STRV_FOREACH(trigger, i->triggers) {
-                        UnitActiveState state = _UNIT_ACTIVE_STATE_INVALID;
+                (void) get_state_one_unit(bus, *t, &state);
+                format_active_state(unit_active_state_to_string(state), &on, &off);
 
-                        (void) get_state_one_unit(bus, *trigger, &state);
-                        format_active_state(unit_active_state_to_string(state), &on, &off);
-                        if (first) {
-                                printf(" %s%s%s %s\n", on, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE), off, *trigger);
-                                first = false;
-                        } else {
-                                printf("                %s%s%s %s\n", on, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE), off, *trigger);
-                        }
-                }
+                printf("%s %s%s%s %s\n",
+                       t == i->triggers ? "   Triggers:" : "            ",
+                       on, special_glyph(SPECIAL_GLYPH_BLACK_CIRCLE), off,
+                       *t);
         }
 
         if (!i->condition_result && i->condition_timestamp > 0) {
@@ -4360,7 +4333,7 @@ static void print_status_info(
                 s1 = format_timestamp_relative(since1, sizeof(since1), i->condition_timestamp);
                 s2 = format_timestamp(since2, sizeof(since2), i->condition_timestamp);
 
-                printf("Condition: start %scondition failed%s at %s%s%s\n",
+                printf("  Condition: start %scondition failed%s at %s%s%s\n",
                        ansi_highlight_yellow(), ansi_normal(),
                        s2, s1 ? "; " : "", strempty(s1));
 
@@ -4370,7 +4343,7 @@ static void print_status_info(
 
                 LIST_FOREACH(conditions, c, i->conditions)
                         if (c->tristate < 0)
-                                printf("           %s %s=%s%s%s was not met\n",
+                                printf("             %s %s=%s%s%s was not met\n",
                                        --n ? special_glyph(SPECIAL_GLYPH_TREE_BRANCH) : special_glyph(SPECIAL_GLYPH_TREE_RIGHT),
                                        c->name,
                                        c->trigger ? "|" : "",
@@ -4382,24 +4355,24 @@ static void print_status_info(
                 s1 = format_timestamp_relative(since1, sizeof(since1), i->assert_timestamp);
                 s2 = format_timestamp(since2, sizeof(since2), i->assert_timestamp);
 
-                printf("   Assert: start %sassertion failed%s at %s%s%s\n",
+                printf("     Assert: start %sassertion failed%s at %s%s%s\n",
                        ansi_highlight_red(), ansi_normal(),
                        s2, s1 ? "; " : "", strempty(s1));
                 if (i->failed_assert_trigger)
-                        printf("           none of the trigger assertions were met\n");
+                        printf("             none of the trigger assertions were met\n");
                 else if (i->failed_assert)
-                        printf("           %s=%s%s was not met\n",
+                        printf("             %s=%s%s was not met\n",
                                i->failed_assert,
                                i->failed_assert_negate ? "!" : "",
                                i->failed_assert_parameter);
         }
 
         if (i->sysfs_path)
-                printf("   Device: %s\n", i->sysfs_path);
+                printf("     Device: %s\n", i->sysfs_path);
         if (i->where)
-                printf("    Where: %s\n", i->where);
+                printf("      Where: %s\n", i->where);
         if (i->what)
-                printf("     What: %s\n", i->what);
+                printf("       What: %s\n", i->what);
 
         STRV_FOREACH(t, i->documentation) {
                 _cleanup_free_ char *formatted = NULL;
@@ -4410,16 +4383,16 @@ static void print_status_info(
                 else
                         q = *t;
 
-                printf(" %*s %s\n", 9, t == i->documentation ? "Docs:" : "", q);
+                printf("   %*s %s\n", 9, t == i->documentation ? "Docs:" : "", q);
         }
 
         STRV_FOREACH_PAIR(t, t2, i->listen)
-                printf(" %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
+                printf("   %*s %s (%s)\n", 9, t == i->listen ? "Listen:" : "", *t2, *t);
 
         if (i->accept) {
-                printf(" Accepted: %u; Connected: %u;", i->n_accepted, i->n_connections);
+                printf("   Accepted: %u; Connected: %u;", i->n_accepted, i->n_connections);
                 if (i->n_refused)
-                        printf(" Refused: %u", i->n_refused);
+                        printf("   Refused: %u", i->n_refused);
                 printf("\n");
         }
 
@@ -4437,7 +4410,7 @@ static void print_status_info(
                         continue;
 
                 argv = strv_join(p->argv, " ");
-                printf("  Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
+                printf("    Process: "PID_FMT" %s=%s ", p->pid, p->name, strna(argv));
 
                 good = is_clean_exit(p->code, p->status, EXIT_CLEAN_DAEMON, NULL);
                 if (!good) {
@@ -4474,7 +4447,7 @@ static void print_status_info(
 
         if (i->main_pid > 0 || i->control_pid > 0) {
                 if (i->main_pid > 0) {
-                        printf(" Main PID: "PID_FMT, i->main_pid);
+                        printf("   Main PID: "PID_FMT, i->main_pid);
 
                         if (i->running) {
 
@@ -4526,14 +4499,14 @@ static void print_status_info(
         }
 
         if (i->status_text)
-                printf("   Status: \"%s\"\n", i->status_text);
+                printf("     Status: \"%s\"\n", i->status_text);
         if (i->status_errno > 0)
-                printf("    Error: %i (%s)\n", i->status_errno, strerror_safe(i->status_errno));
+                printf("      Error: %i (%s)\n", i->status_errno, strerror_safe(i->status_errno));
 
         if (i->ip_ingress_bytes != (uint64_t) -1 && i->ip_egress_bytes != (uint64_t) -1) {
                 char buf_in[FORMAT_BYTES_MAX], buf_out[FORMAT_BYTES_MAX];
 
-                printf("       IP: %s in, %s out\n",
+                printf("         IP: %s in, %s out\n",
                         format_bytes(buf_in, sizeof(buf_in), i->ip_ingress_bytes),
                         format_bytes(buf_out, sizeof(buf_out), i->ip_egress_bytes));
         }
@@ -4541,13 +4514,13 @@ static void print_status_info(
         if (i->io_read_bytes != UINT64_MAX && i->io_write_bytes != UINT64_MAX) {
                 char buf_in[FORMAT_BYTES_MAX], buf_out[FORMAT_BYTES_MAX];
 
-                printf("       IO: %s read, %s written\n",
+                printf("         IO: %s read, %s written\n",
                         format_bytes(buf_in, sizeof(buf_in), i->io_read_bytes),
                         format_bytes(buf_out, sizeof(buf_out), i->io_write_bytes));
         }
 
         if (i->tasks_current != (uint64_t) -1) {
-                printf("    Tasks: %" PRIu64, i->tasks_current);
+                printf("      Tasks: %" PRIu64, i->tasks_current);
 
                 if (i->tasks_max != (uint64_t) -1)
                         printf(" (limit: %" PRIu64 ")\n", i->tasks_max);
@@ -4558,7 +4531,7 @@ static void print_status_info(
         if (i->memory_current != (uint64_t) -1) {
                 char buf[FORMAT_BYTES_MAX];
 
-                printf("   Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
+                printf("     Memory: %s", format_bytes(buf, sizeof(buf), i->memory_current));
 
                 if (i->memory_min > 0 || i->memory_low > 0 ||
                     i->memory_high != CGROUP_LIMIT_MAX || i->memory_max != CGROUP_LIMIT_MAX ||
@@ -4598,7 +4571,7 @@ static void print_status_info(
 
         if (i->cpu_usage_nsec != (uint64_t) -1) {
                 char buf[FORMAT_TIMESPAN_MAX];
-                printf("      CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
+                printf("        CPU: %s\n", format_timespan(buf, sizeof(buf), i->cpu_usage_nsec / NSEC_PER_USEC, USEC_PER_MSEC));
         }
 
         if (i->control_group) {
@@ -4606,7 +4579,7 @@ static void print_status_info(
                 static const char prefix[] = "           ";
                 unsigned c;
 
-                printf("   CGroup: %s\n", i->control_group);
+                printf("     CGroup: %s\n", i->control_group);
 
                 c = columns();
                 if (c > sizeof(prefix) - 1)
@@ -6370,6 +6343,145 @@ static int switch_root(int argc, char *argv[], void *userdata) {
         return 0;
 }
 
+static int log_level(int argc, char *argv[], void *userdata) {
+        sd_bus *bus;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        int r;
+
+        r = acquire_bus(BUS_MANAGER, &bus);
+        if (r < 0)
+                return r;
+
+        if (argc == 1) {
+                _cleanup_free_ char *level = NULL;
+
+                r = sd_bus_get_property_string(
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "LogLevel",
+                                &error,
+                                &level);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to get log level: %s", bus_error_message(&error, r));
+
+                puts(level);
+
+        } else {
+                assert(argc == 2);
+
+                r = sd_bus_set_property(
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "LogLevel",
+                                &error,
+                                "s",
+                                argv[1]);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to set log level: %s", bus_error_message(&error, r));
+        }
+
+        return 0;
+}
+
+static int log_target(int argc, char *argv[], void *userdata) {
+        sd_bus *bus;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        int r;
+
+        r = acquire_bus(BUS_MANAGER, &bus);
+        if (r < 0)
+                return r;
+
+        if (argc == 1) {
+                _cleanup_free_ char *target = NULL;
+
+                r = sd_bus_get_property_string(
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "LogTarget",
+                                &error,
+                                &target);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to get log target: %s", bus_error_message(&error, r));
+
+                puts(target);
+
+        } else {
+                assert(argc == 2);
+
+                r = sd_bus_set_property(
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "LogTarget",
+                                &error,
+                                "s",
+                                argv[1]);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to set log target: %s", bus_error_message(&error, r));
+        }
+
+        return 0;
+}
+
+static int service_watchdogs(int argc, char *argv[], void *userdata) {
+        sd_bus *bus;
+        _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
+        int b, r;
+
+        assert(argv);
+
+        r = acquire_bus(BUS_MANAGER, &bus);
+        if (r < 0)
+                return r;
+
+        if (argc == 1) {
+                /* get ServiceWatchdogs */
+                r = sd_bus_get_property_trivial(
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "ServiceWatchdogs",
+                                &error,
+                                'b',
+                                &b);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to get service-watchdog state: %s", bus_error_message(&error, r));
+
+                printf("%s\n", yes_no(!!b));
+
+        } else {
+                /* set ServiceWatchdogs */
+                assert(argc == 2);
+
+                b = parse_boolean(argv[1]);
+                if (b < 0)
+                        return log_error_errno(b, "Failed to parse service-watchdogs argument: %m");
+
+                r = sd_bus_set_property(
+                                bus,
+                                "org.freedesktop.systemd1",
+                                "/org/freedesktop/systemd1",
+                                "org.freedesktop.systemd1.Manager",
+                                "ServiceWatchdogs",
+                                &error,
+                                "b",
+                                b);
+                if (r < 0)
+                        return log_error_errno(r, "Failed to set service-watchdog state: %s", bus_error_message(&error, r));
+        }
+
+        return 0;
+}
+
 static int set_environment(int argc, char *argv[], void *userdata) {
         _cleanup_(sd_bus_error_free) sd_bus_error error = SD_BUS_ERROR_NULL;
         _cleanup_(sd_bus_message_unrefp) sd_bus_message *m = NULL;
@@ -7721,9 +7833,9 @@ static int systemctl_help(void) {
         if (r < 0)
                 return log_oom();
 
-        printf("%5$s%1$s [OPTIONS...] {COMMAND} ...\n\n"
-               "Query or send control commands to the systemd manager.%6$s\n\n"
-               "%3$sUnit Commands:%4$s\n"
+        printf("%1$s [OPTIONS...] COMMAND ...\n\n"
+               "%5$sQuery or send control commands to the system manager.%6$s\n"
+               "\n%3$sUnit Commands:%4$s\n"
                "  list-units [PATTERN...]             List units currently in memory\n"
                "  list-sockets [PATTERN...]           List socket units currently in memory,\n"
                "                                      ordered by address\n"
@@ -7754,8 +7866,8 @@ static int systemctl_help(void) {
                "                                      units\n"
                "  list-dependencies [UNIT]            Recursively show units which are required\n"
                "                                      or wanted by this unit or by which this\n"
-               "                                      unit is required or wanted\n\n"
-               "%3$sUnit File Commands:%4$s\n"
+               "                                      unit is required or wanted\n"
+               "\n%3$sUnit File Commands:%4$s\n"
                "  list-unit-files [PATTERN...]        List installed unit files\n"
                "  enable [UNIT...|PATH...]            Enable one or more unit files\n"
                "  disable UNIT...                     Disable one or more unit files\n"
@@ -7777,21 +7889,24 @@ static int systemctl_help(void) {
                "                                      on specified one or more units\n"
                "  edit UNIT...                        Edit one or more unit files\n"
                "  get-default                         Get the name of the default target\n"
-               "  set-default TARGET                  Set the default target\n\n"
-               "%3$sMachine Commands:%4$s\n"
+               "  set-default TARGET                  Set the default target\n"
+               "\n%3$sMachine Commands:%4$s\n"
                "  list-machines [PATTERN...]          List local containers and host\n\n"
-               "%3$sJob Commands:%4$s\n"
+               "\n%3$sJob Commands:%4$s\n"
                "  list-jobs [PATTERN...]              List jobs\n"
-               "  cancel [JOB...]                     Cancel all, one, or more jobs\n\n"
-               "%3$sEnvironment Commands:%4$s\n"
+               "  cancel [JOB...]                     Cancel all, one, or more jobs\n"
+               "\n%3$sEnvironment Commands:%4$s\n"
                "  show-environment                    Dump environment\n"
                "  set-environment VARIABLE=VALUE...   Set one or more environment variables\n"
                "  unset-environment VARIABLE...       Unset one or more environment variables\n"
                "  import-environment [VARIABLE...]    Import all or some environment variables\n\n"
-               "%3$sManager Lifecycle Commands:%4$s\n"
+               "\n%3$sManager State Commands:%4$s\n"
                "  daemon-reload                       Reload systemd manager configuration\n"
-               "  daemon-reexec                       Reexecute systemd manager\n\n"
-               "%3$sSystem Commands:%4$s\n"
+               "  daemon-reexec                       Reexecute systemd manager\n"
+               "  log-level [LEVEL]                   Get/set logging threshold for manager\n"
+               "  log-target [TARGET]                 Get/set logging target for manager\n"
+               "  service-watchdogs [BOOL]            Get/set service watchdog state\n"
+               "\n%3$sSystem Commands:%4$s\n"
                "  is-system-running                   Check whether system is fully running\n"
                "  default                             Enter system default mode\n"
                "  rescue                              Enter system rescue mode\n"
@@ -7807,7 +7922,7 @@ static int systemctl_help(void) {
                "  hybrid-sleep                        Hibernate and suspend the system\n"
                "  suspend-then-hibernate              Suspend the system, wake after a period of\n"
                "                                      time and put it into hibernate\n"
-               "\nOptions\n"
+               "\n%3$sOptions:%4$s\n"
                "  -h --help           Show this help\n"
                "     --version        Show package version\n"
                "     --system         Connect to system manager\n"
@@ -7886,8 +8001,9 @@ static int halt_help(void) {
         if (r < 0)
                 return log_oom();
 
-        printf("%s [OPTIONS...]%s\n\n"
-               "%s the system.\n\n"
+        printf("%s [OPTIONS...]%s\n"
+               "\n%s%s the system.%s\n"
+               "\nOptions:\n"
                "     --help      Show this help\n"
                "     --halt      Halt the machine\n"
                "  -p --poweroff  Switch off the machine\n"
@@ -7898,10 +8014,12 @@ static int halt_help(void) {
                "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
                "\nSee the %s for details.\n"
                , program_invocation_short_name
-               , arg_action == ACTION_REBOOT   ? " [ARG]" : "",
-                 arg_action == ACTION_REBOOT   ? "Reboot" :
+               , arg_action == ACTION_REBOOT   ? " [ARG]" : ""
+               , ansi_highlight()
+               , arg_action == ACTION_REBOOT   ? "Reboot" :
                  arg_action == ACTION_POWEROFF ? "Power off" :
                                                  "Halt"
+               , ansi_normal()
                , link
         );
 
@@ -7916,8 +8034,9 @@ static int shutdown_help(void) {
         if (r < 0)
                 return log_oom();
 
-        printf("%s [OPTIONS...] [TIME] [WALL...]\n\n"
-               "Shut down the system.\n\n"
+        printf("%s [OPTIONS...] [TIME] [WALL...]\n"
+               "\n%sShut down the system.%s\n"
+               "\nOptions:\n"
                "     --help      Show this help\n"
                "  -H --halt      Halt the machine\n"
                "  -P --poweroff  Power-off the machine\n"
@@ -7928,6 +8047,7 @@ static int shutdown_help(void) {
                "  -c             Cancel a pending shutdown\n"
                "\nSee the %s for details.\n"
                , program_invocation_short_name
+               , ansi_highlight(), ansi_normal()
                , link
         );
 
@@ -7942,19 +8062,21 @@ static int telinit_help(void) {
         if (r < 0)
                 return log_oom();
 
-        printf("%s [OPTIONS...] {COMMAND}\n\n"
-               "Send control commands to the init daemon.\n\n"
-               "     --help      Show this help\n"
-               "     --no-wall   Don't send wall message before halt/power-off/reboot\n\n"
-               "Commands:\n"
+        printf("%s [OPTIONS...] COMMAND\n\n"
+               "%sSend control commands to the init daemon.%s\n"
+               "\nCommands:\n"
                "  0              Power-off the machine\n"
                "  6              Reboot the machine\n"
                "  2, 3, 4, 5     Start runlevelX.target unit\n"
                "  1, s, S        Enter rescue mode\n"
                "  q, Q           Reload init daemon configuration\n"
                "  u, U           Reexecute init daemon\n"
+               "\nOptions:\n"
+               "     --help      Show this help\n"
+               "     --no-wall   Don't send wall message before halt/power-off/reboot\n"
                "\nSee the %s for details.\n"
                , program_invocation_short_name
+               , ansi_highlight(), ansi_normal()
                , link
         );
 
@@ -7969,11 +8091,13 @@ static int runlevel_help(void) {
         if (r < 0)
                 return log_oom();
 
-        printf("%s [OPTIONS...]\n\n"
-               "Prints the previous and current runlevel of the init system.\n\n"
+        printf("%s [OPTIONS...]\n"
+               "\n%sPrints the previous and current runlevel of the init system.%s\n"
+               "\nOptions:\n"
                "     --help      Show this help\n"
                "\nSee the %s for details.\n"
                , program_invocation_short_name
+               , ansi_highlight(), ansi_normal()
                , link
         );
 
@@ -8552,7 +8676,7 @@ static int systemctl_parse_argv(int argc, char *argv[]) {
                         /* Output an error mimicking getopt, and print a hint afterwards */
                         log_error("%s: invalid option -- '.'", program_invocation_name);
                         log_notice("Hint: to specify units starting with a dash, use \"--\":\n"
-                                   "      %s [OPTIONS...] {COMMAND} -- -.%s ...",
+                                   "      %s [OPTIONS...] COMMAND -- -.%s ...",
                                    program_invocation_name, optarg ?: "mount");
                         _fallthrough_;
 
@@ -8973,73 +9097,76 @@ _pure_ static int action_to_runlevel(void) {
 static int systemctl_main(int argc, char *argv[]) {
         static const Verb verbs[] = {
                 { "list-units",            VERB_ANY, VERB_ANY, VERB_DEFAULT|VERB_ONLINE_ONLY, list_units },
-                { "list-unit-files",       VERB_ANY, VERB_ANY, 0,                list_unit_files      },
-                { "list-sockets",          VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_sockets         },
-                { "list-timers",           VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_timers          },
-                { "list-jobs",             VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_jobs            },
-                { "list-machines",         VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_machines        },
-                { "clear-jobs",            VERB_ANY, 1,        VERB_ONLINE_ONLY, trivial_method       },
-                { "cancel",                VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, cancel_job           },
-                { "start",                 2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit           },
-                { "stop",                  2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit           },
-                { "condstop",              2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit           }, /* For compatibility with ALTLinux */
-                { "reload",                2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit           },
-                { "restart",               2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit           },
-                { "try-restart",           2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit           },
-                { "reload-or-restart",     2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit           },
-                { "reload-or-try-restart", 2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit           }, /* For compatibility with old systemctl <= 228 */
-                { "try-reload-or-restart", 2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit           },
-                { "force-reload",          2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit           }, /* For compatibility with SysV */
-                { "condreload",            2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit           }, /* For compatibility with ALTLinux */
-                { "condrestart",           2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit           }, /* For compatibility with RH */
-                { "isolate",               2,        2,        VERB_ONLINE_ONLY, start_unit           },
-                { "kill",                  2,        VERB_ANY, VERB_ONLINE_ONLY, kill_unit            },
-                { "clean",                 2,        VERB_ANY, VERB_ONLINE_ONLY, clean_unit           },
-                { "is-active",             2,        VERB_ANY, VERB_ONLINE_ONLY, check_unit_active    },
-                { "check",                 2,        VERB_ANY, VERB_ONLINE_ONLY, check_unit_active    }, /* deprecated alias of is-active */
-                { "is-failed",             2,        VERB_ANY, VERB_ONLINE_ONLY, check_unit_failed    },
-                { "show",                  VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show                 },
-                { "cat",                   2,        VERB_ANY, VERB_ONLINE_ONLY, cat                  },
-                { "status",                VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show                 },
-                { "help",                  VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show                 },
-                { "daemon-reload",         VERB_ANY, 1,        VERB_ONLINE_ONLY, daemon_reload        },
-                { "daemon-reexec",         VERB_ANY, 1,        VERB_ONLINE_ONLY, daemon_reload        },
-                { "show-environment",      VERB_ANY, 1,        VERB_ONLINE_ONLY, show_environment     },
-                { "set-environment",       2,        VERB_ANY, VERB_ONLINE_ONLY, set_environment      },
-                { "unset-environment",     2,        VERB_ANY, VERB_ONLINE_ONLY, set_environment      },
-                { "import-environment",    VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, import_environment   },
-                { "halt",                  VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
-                { "poweroff",              VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
-                { "reboot",                VERB_ANY, 2,        VERB_ONLINE_ONLY, start_system_special },
-                { "kexec",                 VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
-                { "suspend",               VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
-                { "hibernate",             VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
-                { "hybrid-sleep",          VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
-                { "suspend-then-hibernate",VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
-                { "default",               VERB_ANY, 1,        VERB_ONLINE_ONLY, start_special        },
-                { "rescue",                VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
-                { "emergency",             VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special },
-                { "exit",                  VERB_ANY, 2,        VERB_ONLINE_ONLY, start_special        },
-                { "reset-failed",          VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, reset_failed         },
-                { "enable",                2,        VERB_ANY, 0,                enable_unit          },
-                { "disable",               2,        VERB_ANY, 0,                enable_unit          },
-                { "is-enabled",            2,        VERB_ANY, 0,                unit_is_enabled      },
-                { "reenable",              2,        VERB_ANY, 0,                enable_unit          },
-                { "preset",                2,        VERB_ANY, 0,                enable_unit          },
-                { "preset-all",            VERB_ANY, 1,        0,                preset_all           },
-                { "mask",                  2,        VERB_ANY, 0,                enable_unit          },
-                { "unmask",                2,        VERB_ANY, 0,                enable_unit          },
-                { "link",                  2,        VERB_ANY, 0,                enable_unit          },
-                { "revert",                2,        VERB_ANY, 0,                enable_unit          },
-                { "switch-root",           2,        VERB_ANY, VERB_ONLINE_ONLY, switch_root          },
-                { "list-dependencies",     VERB_ANY, 2,        VERB_ONLINE_ONLY, list_dependencies    },
-                { "set-default",           2,        2,        0,                set_default          },
-                { "get-default",           VERB_ANY, 1,        0,                get_default          },
-                { "set-property",          3,        VERB_ANY, VERB_ONLINE_ONLY, set_property         },
-                { "is-system-running",     VERB_ANY, 1,        0,                is_system_running    },
-                { "add-wants",             3,        VERB_ANY, 0,                add_dependency       },
-                { "add-requires",          3,        VERB_ANY, 0,                add_dependency       },
-                { "edit",                  2,        VERB_ANY, VERB_ONLINE_ONLY, edit                 },
+                { "list-unit-files",       VERB_ANY, VERB_ANY, 0,                list_unit_files         },
+                { "list-sockets",          VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_sockets            },
+                { "list-timers",           VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_timers             },
+                { "list-jobs",             VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_jobs               },
+                { "list-machines",         VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, list_machines           },
+                { "clear-jobs",            VERB_ANY, 1,        VERB_ONLINE_ONLY, trivial_method          },
+                { "cancel",                VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, cancel_job              },
+                { "start",                 2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit              },
+                { "stop",                  2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit              },
+                { "condstop",              2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit              }, /* For compatibility with ALTLinux */
+                { "reload",                2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit              },
+                { "restart",               2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit              },
+                { "try-restart",           2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit              },
+                { "reload-or-restart",     2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit              },
+                { "reload-or-try-restart", 2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit              }, /* For compatibility with old systemctl <= 228 */
+                { "try-reload-or-restart", 2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit              },
+                { "force-reload",          2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit              }, /* For compatibility with SysV */
+                { "condreload",            2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit              }, /* For compatibility with ALTLinux */
+                { "condrestart",           2,        VERB_ANY, VERB_ONLINE_ONLY, start_unit              }, /* For compatibility with RH */
+                { "isolate",               2,        2,        VERB_ONLINE_ONLY, start_unit              },
+                { "kill",                  2,        VERB_ANY, VERB_ONLINE_ONLY, kill_unit               },
+                { "clean",                 2,        VERB_ANY, VERB_ONLINE_ONLY, clean_unit              },
+                { "is-active",             2,        VERB_ANY, VERB_ONLINE_ONLY, check_unit_active       },
+                { "check",                 2,        VERB_ANY, VERB_ONLINE_ONLY, check_unit_active       }, /* deprecated alias of is-active */
+                { "is-failed",             2,        VERB_ANY, VERB_ONLINE_ONLY, check_unit_failed       },
+                { "show",                  VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show                    },
+                { "cat",                   2,        VERB_ANY, VERB_ONLINE_ONLY, cat                     },
+                { "status",                VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show                    },
+                { "help",                  VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, show                    },
+                { "daemon-reload",         VERB_ANY, 1,        VERB_ONLINE_ONLY, daemon_reload           },
+                { "daemon-reexec",         VERB_ANY, 1,        VERB_ONLINE_ONLY, daemon_reload           },
+                { "log-level",             VERB_ANY, 2,        0,                log_level               },
+                { "log-target",            VERB_ANY, 2,        0,                log_target              },
+                { "service-watchdogs",     VERB_ANY, 2,        0,                service_watchdogs       },
+                { "show-environment",      VERB_ANY, 1,        VERB_ONLINE_ONLY, show_environment        },
+                { "set-environment",       2,        VERB_ANY, VERB_ONLINE_ONLY, set_environment         },
+                { "unset-environment",     2,        VERB_ANY, VERB_ONLINE_ONLY, set_environment         },
+                { "import-environment",    VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, import_environment      },
+                { "halt",                  VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special    },
+                { "poweroff",              VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special    },
+                { "reboot",                VERB_ANY, 2,        VERB_ONLINE_ONLY, start_system_special    },
+                { "kexec",                 VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special    },
+                { "suspend",               VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special    },
+                { "hibernate",             VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special    },
+                { "hybrid-sleep",          VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special    },
+                { "suspend-then-hibernate",VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special    },
+                { "default",               VERB_ANY, 1,        VERB_ONLINE_ONLY, start_special           },
+                { "rescue",                VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special    },
+                { "emergency",             VERB_ANY, 1,        VERB_ONLINE_ONLY, start_system_special    },
+                { "exit",                  VERB_ANY, 2,        VERB_ONLINE_ONLY, start_special           },
+                { "reset-failed",          VERB_ANY, VERB_ANY, VERB_ONLINE_ONLY, reset_failed            },
+                { "enable",                2,        VERB_ANY, 0,                enable_unit             },
+                { "disable",               2,        VERB_ANY, 0,                enable_unit             },
+                { "is-enabled",            2,        VERB_ANY, 0,                unit_is_enabled         },
+                { "reenable",              2,        VERB_ANY, 0,                enable_unit             },
+                { "preset",                2,        VERB_ANY, 0,                enable_unit             },
+                { "preset-all",            VERB_ANY, 1,        0,                preset_all              },
+                { "mask",                  2,        VERB_ANY, 0,                enable_unit             },
+                { "unmask",                2,        VERB_ANY, 0,                enable_unit             },
+                { "link",                  2,        VERB_ANY, 0,                enable_unit             },
+                { "revert",                2,        VERB_ANY, 0,                enable_unit             },
+                { "switch-root",           2,        VERB_ANY, VERB_ONLINE_ONLY, switch_root             },
+                { "list-dependencies",     VERB_ANY, 2,        VERB_ONLINE_ONLY, list_dependencies       },
+                { "set-default",           2,        2,        0,                set_default             },
+                { "get-default",           VERB_ANY, 1,        0,                get_default             },
+                { "set-property",          3,        VERB_ANY, VERB_ONLINE_ONLY, set_property            },
+                { "is-system-running",     VERB_ANY, 1,        0,                is_system_running       },
+                { "add-wants",             3,        VERB_ANY, 0,                add_dependency          },
+                { "add-requires",          3,        VERB_ANY, 0,                add_dependency          },
+                { "edit",                  2,        VERB_ANY, VERB_ONLINE_ONLY, edit                    },
                 {}
         };