[systemd-commits] 7 commits - TODO man/machinectl.xml src/core src/machine src/systemctl

Lennart Poettering lennart at kemper.freedesktop.org
Mon Mar 17 20:49:05 PDT 2014


 TODO                        |    4 --
 man/machinectl.xml          |   72 +++++++++++++++++++++++--------------
 src/core/mount-setup.c      |   24 +++++++++---
 src/machine/machine.c       |   10 ++++-
 src/machine/machinectl.c    |   85 +++++++++-----------------------------------
 src/machine/machined-dbus.c |    4 +-
 src/machine/machined.h      |    2 -
 src/systemctl/systemctl.c   |   71 +++++++++++++++++++++++++-----------
 8 files changed, 144 insertions(+), 128 deletions(-)

New commits:
commit 1dba654b27918c22e413ac5b3c19301f1ff86ad2
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Mar 18 04:44:39 2014 +0100

    machinectl: reimplement machinectl's "reboot" verb on top of "kill", and add new verb "poweroff"
    
    There's really no point to send the reboot SIGINT from machinectl
    directly, if machined can do that anyway. This saves code, and
    makes machinectl network transparent for these verbs. And while we are
    at it we can easily add a "poweroff" verb in addition to "reboot". Yay!

diff --git a/man/machinectl.xml b/man/machinectl.xml
index 89dca9c..2f2e257 100644
--- a/man/machinectl.xml
+++ b/man/machinectl.xml
@@ -203,14 +203,45 @@
                         </varlistentry>
 
                         <varlistentry>
-                                <term><command>terminate</command> <replaceable>ID</replaceable>...</term>
+                                <term><command>login</command> <replaceable>ID</replaceable></term>
 
-                                <listitem><para>Terminates a virtual
-                                machine or container. This kills all
-                                processes of the virtual machine or
-                                container and deallocates all
-                                resources attached to that
-                                instance.</para></listitem>
+                                <listitem><para>Open a terminal login
+                                session to a container. This will
+                                create a TTY connection to a specific
+                                container and asks for the execution of a
+                                getty on it. Note that this is only
+                                supported for containers running
+                                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+                                as init system.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>reboot</command> <replaceable>ID</replaceable>...</term>
+
+                                <listitem><para>Reboot one or more
+                                containers. This will trigger a reboot
+                                by sending SIGINT to the container's
+                                init process, which is roughly
+                                equivalent to pressing Ctrl+Alt+Del on
+                                a non-containerized system, and is
+                                compatible with containers running any
+                                init system.</para></listitem>
+                        </varlistentry>
+
+                        <varlistentry>
+                                <term><command>poweroff</command> <replaceable>ID</replaceable>...</term>
+
+                                <listitem><para>Power off one or more
+                                containers. This will trigger a reboot
+                                by sending SIGRTMIN+4 to the
+                                container's init process, which causes
+                                systemd-compatible init systems to
+                                shut down cleanly. This operation does
+                                not work on containers that do not run
+                                a
+                                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>-compatible
+                                init system, such as
+                                sysvinit.</para></listitem>
                         </varlistentry>
 
                         <varlistentry>
@@ -229,29 +260,16 @@
                         </varlistentry>
 
                         <varlistentry>
-                                <term><command>reboot</command> <replaceable>ID</replaceable>...</term>
+                                <term><command>terminate</command> <replaceable>ID</replaceable>...</term>
 
-                                <listitem><para>Reboot one or more
-                                containers. This will trigger a reboot
-                                by sending SIGINT to the container's
-                                init process, which is roughly
-                                equivalent to pressing Ctrl+Alt+Del on
-                                a non-containerized
-                                system.</para></listitem>
+                                <listitem><para>Terminates a virtual
+                                machine or container. This kills all
+                                processes of the virtual machine or
+                                container and deallocates all
+                                resources attached to that
+                                instance.</para></listitem>
                         </varlistentry>
 
-                        <varlistentry>
-                                <term><command>login</command> <replaceable>ID</replaceable></term>
-
-                                <listitem><para>Open a terminal login
-                                session to a container. This will
-                                create a TTY connection to a specific
-                                container and asks for the execution of a
-                                getty on it. Note that this is only
-                                supported for containers running
-                                <citerefentry><refentrytitle>systemd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
-                                as init system.</para></listitem>
-                        </varlistentry>
                 </variablelist>
 
         </refsect1>
diff --git a/src/machine/machinectl.c b/src/machine/machinectl.c
index 32f862d..2183d5c 100644
--- a/src/machine/machinectl.c
+++ b/src/machine/machinectl.c
@@ -370,91 +370,42 @@ static int kill_machine(sd_bus *bus, char **args, unsigned n) {
         return 0;
 }
 
-static int terminate_machine(sd_bus *bus, char **args, unsigned n) {
-        _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
-        unsigned i;
-
-        assert(args);
+static int reboot_machine(sd_bus *bus, char **args, unsigned n) {
+        arg_kill_who = "leader";
+        arg_signal = SIGINT; /* sysvinit + systemd */
 
-        for (i = 1; i < n; i++) {
-                int r;
+        return kill_machine(bus, args, n);
+}
 
-                r = sd_bus_call_method(
-                                bus,
-                                "org.freedesktop.machine1",
-                                "/org/freedesktop/machine1",
-                                "org.freedesktop.machine1.Manager",
-                                "TerminateMachine",
-                                &error,
-                                NULL,
-                                "s", args[i]);
-                if (r < 0) {
-                        log_error("Could not terminate machine: %s", bus_error_message(&error, -r));
-                        return r;
-                }
-        }
+static int poweroff_machine(sd_bus *bus, char **args, unsigned n) {
+        arg_kill_who = "leader";
+        arg_signal = SIGRTMIN+4; /* only systemd */
 
-        return 0;
+        return kill_machine(bus, args, n);
 }
 
-static int reboot_machine(sd_bus *bus, char **args, unsigned n) {
+static int terminate_machine(sd_bus *bus, char **args, unsigned n) {
         _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
         unsigned i;
-        int r;
 
         assert(args);
 
-        if (arg_transport != BUS_TRANSPORT_LOCAL) {
-                log_error("Reboot only supported on local machines.");
-                return -ENOTSUP;
-        }
-
         for (i = 1; i < n; i++) {
-                _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *reply2 = NULL;
-                const char *path;
-                uint32_t leader;
+                int r;
 
                 r = sd_bus_call_method(
                                 bus,
                                 "org.freedesktop.machine1",
                                 "/org/freedesktop/machine1",
                                 "org.freedesktop.machine1.Manager",
-                                "GetMachine",
+                                "TerminateMachine",
                                 &error,
-                                &reply,
+                                NULL,
                                 "s", args[i]);
-
-                if (r < 0) {
-                        log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
-                        return r;
-                }
-
-                r = sd_bus_message_read(reply, "o", &path);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                r = sd_bus_get_property(
-                                bus,
-                                "org.freedesktop.machine1",
-                                path,
-                                "org.freedesktop.machine1.Machine",
-                                "Leader",
-                                &error,
-                                &reply2,
-                                "u");
                 if (r < 0) {
-                        log_error("Failed to retrieve PID of leader: %s", strerror(-r));
+                        log_error("Could not terminate machine: %s", bus_error_message(&error, -r));
                         return r;
                 }
-
-                r = sd_bus_message_read(reply2, "u", &leader);
-                if (r < 0)
-                        return bus_log_parse_error(r);
-
-                if (kill(leader, SIGINT) < 0) {
-                        log_error("Failed to kill init process " PID_FMT ": %m", (pid_t) leader);
-                        return -errno;
-                }
         }
 
         return 0;
@@ -687,10 +638,11 @@ static int help(void) {
                "  list                   List running VMs and containers\n"
                "  status NAME...         Show VM/container status\n"
                "  show NAME...           Show properties of one or more VMs/containers\n"
-               "  terminate NAME...      Terminate one or more VMs/containers\n"
-               "  kill NAME...           Send signal to processes of a VM/container\n"
+               "  login NAME             Get a login prompt on a container\n"
+               "  poweroff NAME...       Power off one or more containers\n"
                "  reboot NAME...         Reboot one or more containers\n"
-               "  login NAME             Get a login prompt on a container\n",
+               "  kill NAME...           Send signal to processes of a VM/container\n"
+               "  terminate NAME...      Terminate one or more VMs/containers\n",
                program_invocation_short_name);
 
         return 0;
@@ -814,6 +766,7 @@ static int machinectl_main(sd_bus *bus, int argc, char *argv[]) {
                 { "show",                  MORE,   1, show              },
                 { "terminate",             MORE,   2, terminate_machine },
                 { "reboot",                MORE,   2, reboot_machine    },
+                { "poweroff",              MORE,   2, poweroff_machine  },
                 { "kill",                  MORE,   2, kill_machine      },
                 { "login",                 MORE,   2, login_machine     },
         };

commit de58a50e24a0d55e3bbcc77f8f6170a7322acf52
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Mar 18 04:43:08 2014 +0100

    machined: fix Kill() bus call on machine objects when "what" is specified as "leader"

diff --git a/src/machine/machine.c b/src/machine/machine.c
index 4596a80..9a5cc9a 100644
--- a/src/machine/machine.c
+++ b/src/machine/machine.c
@@ -410,7 +410,15 @@ int machine_kill(Machine *m, KillWho who, int signo) {
         if (!m->unit)
                 return -ESRCH;
 
-        return manager_kill_unit(m->manager, m->unit, who, signo, NULL);
+        if (who == KILL_LEADER) {
+                /* If we shall simply kill the leader, do so directly */
+
+                if (kill(m->leader, signo) < 0)
+                        return -errno;
+        }
+
+        /* Otherwise make PID 1 do it for us, for the entire cgroup */
+        return manager_kill_unit(m->manager, m->unit, signo, NULL);
 }
 
 static const char* const machine_class_table[_MACHINE_CLASS_MAX] = {
diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c
index 09d28bb..9473105 100644
--- a/src/machine/machined-dbus.c
+++ b/src/machine/machined-dbus.c
@@ -655,7 +655,7 @@ int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, c
         return 1;
 }
 
-int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error) {
+int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_error *error) {
         assert(manager);
         assert(unit);
 
@@ -667,7 +667,7 @@ int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo
                         "KillUnit",
                         error,
                         NULL,
-                        "ssi", unit, who == KILL_LEADER ? "main" : "all", signo);
+                        "ssi", unit, "all", signo);
 }
 
 int manager_unit_is_active(Manager *manager, const char *unit) {
diff --git a/src/machine/machined.h b/src/machine/machined.h
index d4b581b..2dba303 100644
--- a/src/machine/machined.h
+++ b/src/machine/machined.h
@@ -67,6 +67,6 @@ int match_job_removed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_b
 
 int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, sd_bus_message *more_properties, sd_bus_error *error, char **job);
 int manager_stop_unit(Manager *manager, const char *unit, sd_bus_error *error, char **job);
-int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, sd_bus_error *error);
+int manager_kill_unit(Manager *manager, const char *unit, int signo, sd_bus_error *error);
 int manager_unit_is_active(Manager *manager, const char *unit);
 int manager_job_is_active(Manager *manager, const char *path);

commit df23374071f497831c4d25076a12b1da41054271
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Mar 18 03:53:59 2014 +0100

    update TODO

diff --git a/TODO b/TODO
index 454239b..99cbb9f 100644
--- a/TODO
+++ b/TODO
@@ -35,8 +35,6 @@ Features:
 
 * maybe add DefaultTimerAccuracySec= as global config option to set AccuracySec='s default value in .timer units
 
-* mount /sys/fs/cgroup read-only (but leave the subdirs writable)
-
 * gpt-auto-generator:
   - Support LUKS for root devices
   - Define new partition type for encrypted swap? Support probed LUKS for encrypted swap?
@@ -53,8 +51,6 @@ Features:
 
 * add an "input" group to udev logic and add all input devices to it
 
-* libsystemd-login: implement getpeer_unit(), get_peer_slice(), ...
-
 * machined: provide calls GetMachineByAddress() on the manager
   interface to get the machine for a local IP address, and
   GetAddress() on the Machine interface to get the Address for a

commit 679142ce4a8def7da43c4d3b2a02bae8c0d21175
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Mar 18 04:06:54 2014 +0100

    core: remount /sys/fs/cgroup/ read-only after we mounted all controllers
    
    Given that glibc searches for /dev/shm by just looking for any tmpfs we
    should be more careful with providing tmpfs instances arbitrary code
    might end up writing to.

diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
index c6d3f4b..147333a 100644
--- a/src/core/mount-setup.c
+++ b/src/core/mount-setup.c
@@ -338,6 +338,10 @@ int mount_cgroup_controllers(char ***join_controllers) {
                 }
         }
 
+        /* Now that we mounted everything, let's make the tmpfs the
+         * cgroup file systems are mounted into read-only. */
+        mount("tmpfs", "/sys/fs/cgroup", "tmpfs", MS_REMOUNT|MS_NOSUID|MS_NOEXEC|MS_NODEV|MS_STRICTATIME|MS_RDONLY, "mode=755");
+
         return 0;
 }
 

commit a641dcd9bf05418d6a6c165e1c0cff615b4a0f47
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Mar 18 04:06:36 2014 +0100

    cgroup: it's not OK to invoke alloca() in loops

diff --git a/src/core/mount-setup.c b/src/core/mount-setup.c
index 387030a..c6d3f4b 100644
--- a/src/core/mount-setup.c
+++ b/src/core/mount-setup.c
@@ -216,10 +216,10 @@ int mount_setup_early(void) {
 }
 
 int mount_cgroup_controllers(char ***join_controllers) {
-        int r;
-        char buf[LINE_MAX];
         _cleanup_set_free_free_ Set *controllers = NULL;
         _cleanup_fclose_ FILE *f;
+        char buf[LINE_MAX];
+        int r;
 
         /* Mount all available cgroup controllers that are built into the kernel. */
 
@@ -262,6 +262,7 @@ int mount_cgroup_controllers(char ***join_controllers) {
         }
 
         for (;;) {
+                _cleanup_free_ char *options = NULL, *controller = NULL, *where = NULL;
                 MountPoint p = {
                         .what = "cgroup",
                         .type = "cgroup",
@@ -269,7 +270,6 @@ int mount_cgroup_controllers(char ***join_controllers) {
                         .mode = MNT_IN_CONTAINER,
                 };
                 char ***k = NULL;
-                _cleanup_free_ char *options = NULL, *controller;
 
                 controller = set_steal_first(controllers);
                 if (!controller)
@@ -286,7 +286,7 @@ int mount_cgroup_controllers(char ***join_controllers) {
                         for (i = *k, j = *k; *i; i++) {
 
                                 if (!streq(*i, controller)) {
-                                        char _cleanup_free_ *t;
+                                        _cleanup_free_ char *t;
 
                                         t = set_remove(controllers, *i);
                                         if (!t) {
@@ -308,7 +308,11 @@ int mount_cgroup_controllers(char ***join_controllers) {
                         controller = NULL;
                 }
 
-                p.where = strappenda("/sys/fs/cgroup/", options);
+                where = strappend("/sys/fs/cgroup/", options);
+                if (!where)
+                        return log_oom();
+
+                p.where = where;
                 p.options = options;
 
                 r = mount_one(&p, true);
@@ -319,7 +323,11 @@ int mount_cgroup_controllers(char ***join_controllers) {
                         char **i;
 
                         for (i = *k; *i; i++) {
-                                char *t = strappenda("/sys/fs/cgroup/", *i);
+                                _cleanup_free_ char *t = NULL;
+
+                                t = strappend("/sys/fs/cgroup/", *i);
+                                if (!t)
+                                        return log_oom();
 
                                 r = symlink(options, t);
                                 if (r < 0 && errno != EEXIST) {

commit 50933da01b71d3f5a0b869731fc41ce89881db69
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Mar 18 03:53:02 2014 +0100

    systemctl: sort local host entry before container in list-machines output

diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 8ef3c08..5a5681b 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -1582,7 +1582,7 @@ static int compare_machine_info(const void *a, const void *b) {
         const struct machine_info *u = a, *v = b;
 
         if (u->is_host != v->is_host)
-                return u->is_host > v->is_host ? 1 : -1;
+                return u->is_host > v->is_host ? -1 : 1;
 
         return strcasecmp(u->name, v->name);
 }

commit 90c3f79dc74229134818e78cb97d315e28ee93b5
Author: Lennart Poettering <lennart at poettering.net>
Date:   Tue Mar 18 03:51:24 2014 +0100

    systemctl: prefix list-units and list-machines output with a circle indicating a failure state
    
    (Subject to --no-legend)

diff --git a/src/systemctl/systemctl.c b/src/systemctl/systemctl.c
index 45833da..8ef3c08 100644
--- a/src/systemctl/systemctl.c
+++ b/src/systemctl/systemctl.c
@@ -341,7 +341,7 @@ static bool output_show_unit(const UnitInfo *u, char **patterns) {
 }
 
 static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
-        unsigned id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
+        unsigned circle_len = 0, id_len, max_id_len, load_len, active_len, sub_len, job_len, desc_len;
         const UnitInfo *u;
         unsigned n_shown = 0;
         int job_count = 0;
@@ -363,13 +363,18 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
                         job_len = MAX(job_len, strlen(u->job_type));
                         job_count++;
                 }
+
+                if (!arg_no_legend &&
+                    (streq(u->active_state, "failed") ||
+                     STR_IN_SET(u->load_state, "error", "not-found", "masked")))
+                        circle_len = 2;
         }
 
         if (!arg_full && original_stdout_is_tty) {
                 unsigned basic_len;
 
                 id_len = MIN(max_id_len, 25u);
-                basic_len = 5 + id_len + 5 + active_len + sub_len;
+                basic_len = circle_len + 5 + id_len + 5 + active_len + sub_len;
 
                 if (job_count)
                         basic_len += job_len + 1;
@@ -397,11 +402,17 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
 
         for (u = unit_infos; u < unit_infos + c; u++) {
                 _cleanup_free_ char *e = NULL, *j = NULL;
-                const char *on_loaded, *off_loaded, *on = "";
-                const char *on_active, *off_active, *off = "";
+                const char *on_loaded = "", *off_loaded = "";
+                const char *on_active = "", *off_active = "";
+                const char *on_circle = "", *off_circle = "";
                 const char *id;
+                bool circle = false;
 
                 if (!n_shown && !arg_no_legend) {
+
+                        if (circle_len > 0)
+                                fputs("  ", stdout);
+
                         printf("%-*s %-*s %-*s %-*s ",
                                id_len, "UNIT",
                                load_len, "LOAD",
@@ -419,18 +430,18 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
 
                 n_shown++;
 
-                if (streq(u->load_state, "error") ||
-                    streq(u->load_state, "not-found")) {
-                        on_loaded = on = ansi_highlight_red();
-                        off_loaded = off = ansi_highlight_off();
-                } else
-                        on_loaded = off_loaded = "";
+                if (STR_IN_SET(u->load_state, "error", "not-found", "masked")) {
+                        on_loaded = ansi_highlight_red();
+                        on_circle = ansi_highlight_yellow();
+                        off_loaded = off_circle = ansi_highlight_off();
+                        circle = true;
+                }
 
                 if (streq(u->active_state, "failed")) {
-                        on_active = on = ansi_highlight_red();
-                        off_active = off = ansi_highlight_off();
-                } else
-                        on_active = off_active = "";
+                        on_circle = on_active = ansi_highlight_red();
+                        off_circle = off_active = ansi_highlight_off();
+                        circle = true;
+                }
 
                 if (u->machine) {
                         j = strjoin(u->machine, ":", u->id, NULL);
@@ -449,8 +460,11 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
                         id = e;
                 }
 
+                if (circle_len > 0)
+                        printf("%s%s%s", on_circle, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : "  ", off_circle);
+
                 printf("%s%-*s%s %s%-*s%s %s%-*s %-*s%s %-*s",
-                       on, id_len, id, off,
+                       on_active, id_len, id, off_active,
                        on_loaded, load_len, u->load_state, off_loaded,
                        on_active, active_len, u->active_state,
                        sub_len, u->sub_state, off_active,
@@ -466,7 +480,8 @@ static int output_units_list(const UnitInfo *unit_infos, unsigned c) {
                 const char *on, *off;
 
                 if (n_shown) {
-                        puts("\nLOAD   = Reflects whether the unit definition was properly loaded.\n"
+                        puts("\n"
+                             "LOAD   = Reflects whether the unit definition was properly loaded.\n"
                              "ACTIVE = The high-level unit activation state, i.e. generalization of SUB.\n"
                              "SUB    = The low-level unit activation state, values depend on unit type.");
                         puts(job_count ? "JOB    = Pending job for the unit.\n" : "");
@@ -1670,6 +1685,7 @@ static int get_machine_list(
 static void output_machines_list(struct machine_info *machine_infos, unsigned n) {
         struct machine_info *m;
         unsigned
+                circle_len = 0,
                 namelen = sizeof("NAME") - 1,
                 statelen = sizeof("STATE") - 1,
                 failedlen = sizeof("FAILED") - 1,
@@ -1682,26 +1698,36 @@ static void output_machines_list(struct machine_info *machine_infos, unsigned n)
                 statelen = MAX(statelen, m->state ? strlen(m->state) : 0);
                 failedlen = MAX(failedlen, DECIMAL_STR_WIDTH(m->n_failed_units));
                 jobslen = MAX(jobslen, DECIMAL_STR_WIDTH(m->n_jobs));
+
+                if (!arg_no_legend && !streq_ptr(m->state, "running"))
+                        circle_len = 2;
         }
 
-        if (!arg_no_legend)
+        if (!arg_no_legend) {
+                if (circle_len > 0)
+                        fputs("  ", stdout);
+
                 printf("%-*s %-*s %-*s %-*s\n",
                          namelen, "NAME",
                         statelen, "STATE",
                        failedlen, "FAILED",
                          jobslen, "JOBS");
+        }
 
         for (m = machine_infos; m < machine_infos + n; m++) {
-                const char *on_state, *off_state, *on_failed, *off_failed;
+                const char *on_state = "", *off_state = "";
+                const char *on_failed = "", *off_failed = "";
+                bool circle = false;
 
                 if (streq_ptr(m->state, "degraded")) {
                         on_state = ansi_highlight_red();
                         off_state = ansi_highlight_off();
+                        circle = true;
                 } else if (!streq_ptr(m->state, "running")) {
                         on_state = ansi_highlight_yellow();
                         off_state = ansi_highlight_off();
-                } else
-                        on_state = off_state = "";
+                        circle = true;
+                }
 
                 if (m->n_failed_units > 0) {
                         on_failed = ansi_highlight_red();
@@ -1709,6 +1735,9 @@ static void output_machines_list(struct machine_info *machine_infos, unsigned n)
                 } else
                         on_failed = off_failed = "";
 
+                if (circle_len > 0)
+                        printf("%s%s%s", on_state, circle ? draw_special_char(DRAW_BLACK_CIRCLE) : "  ", off_state);
+
                 if (m->is_host)
                         printf("%-*s (host) %s%-*s%s %s%*u%s %*u\n",
                                (int) (namelen - (sizeof(" (host)")-1)), strna(m->name),



More information about the systemd-commits mailing list