machinectl.c revision f48e75cb9a8112d35855c44a156934f2ee0edb2e
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2013 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_all = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_full = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_no_pager = false;
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersenstatic bool arg_legend = true;
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poetteringstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void pager_open_if_enabled(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Cache result before we open the pager */
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int list_machines(sd_bus *bus, char **args, unsigned n) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned k = 0;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "org.freedesktop.machine1",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "org.freedesktop.machine1.Manager",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "ListMachines",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Could not get machines: %s", bus_error_message(&error, -r));
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen printf("%-32s %-9s %-16s\n", "MACHINE", "CONTAINER", "SERVICE");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssso)");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen while ((r = sd_bus_message_read(reply, "(ssso)", &name, &class, &service, &object)) > 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("%-32s %-9s %-16s\n", name, class, service);
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen printf("\n%u machines listed.\n", k);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poetteringstatic int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering if (arg_transport == BUS_TRANSPORT_REMOTE)
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering endswith(unit, ".scope") ? "org.freedesktop.systemd1.Scope" : "org.freedesktop.systemd1.Service",
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering "ControlGroup",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Failed to query ControlGroup: %s", bus_error_message(&error, -r));
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering r = sd_bus_message_read(reply, "s", &cgroup);
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, false) != 0 && leader <= 0)
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, output_flags);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poetteringstatic int print_addresses(sd_bus *bus, const char *name, int ifi, const char *prefix, const char *prefix2) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "org.freedesktop.machine1",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "org.freedesktop.machine1.Manager",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "GetMachineAddresses",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(yay)");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering while ((r = sd_bus_message_enter_container(reply, 'r', "yay")) > 0) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering unsigned char family;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering const void *a;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering char buffer[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)];
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_message_read(reply, "y", &family);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_message_read_array(reply, 'y', &a, &sz);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fputs(inet_ntop(family, a, buffer, sizeof(buffer)), stdout);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_message_exit_container(reply);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_message_exit_container(reply);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poetteringstatic int print_os_release(sd_bus *bus, const char *name, const char *prefix) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "org.freedesktop.machine1",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "org.freedesktop.machine1.Manager",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "GetMachineOSRelease",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "{ss}");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering while ((r = sd_bus_message_read(reply, "{ss}", &k, &v)) > 0) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = sd_bus_message_exit_container(reply);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!sd_id128_equal(i->id, SD_ID128_NULL))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s2 = format_timestamp(since2, sizeof(since2), i->timestamp);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Leader: %u", (unsigned) i->leader);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else if (i->class)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Root: %s\n", i->root_directory);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering for (c = 0; c < i->n_netif; c++) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "\t Address: ",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering print_os_release(bus, i->name, "\t OS: ");
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering show_unit_cgroup(bus, i->unit, i->leader);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poetteringstatic int map_netif(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering const void *v;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert_cc(sizeof(int32_t) == sizeof(int));
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering r = sd_bus_message_read_array(m, SD_BUS_TYPE_INT32, &v, &l);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sieversstatic int show_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers static const struct bus_properties_map map[] = {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Name", "s", NULL, offsetof(MachineStatusInfo, name) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Class", "s", NULL, offsetof(MachineStatusInfo, class) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Service", "s", NULL, offsetof(MachineStatusInfo, service) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Unit", "s", NULL, offsetof(MachineStatusInfo, unit) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "RootDirectory", "s", NULL, offsetof(MachineStatusInfo, root_directory) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Leader", "u", NULL, offsetof(MachineStatusInfo, leader) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Timestamp", "t", NULL, offsetof(MachineStatusInfo, timestamp) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Id", "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "NetworkInterfaces", "ai", map_netif, 0 },
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "org.freedesktop.machine1",
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_error("Could not get properties: %s", strerror(-r));
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sieversstatic int show_properties(sd_bus *bus, const char *path, bool *new_line) {
27e72d6b22890ba4a8cbc05c49667cd1cccf1461Simon Peeters r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_all);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_error("Could not get properties: %s", strerror(-r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int show(sd_bus *bus, char **args, unsigned n) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers /* If no argument is specified, inspect the manager
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = show_properties(bus, "/org/freedesktop/machine1", &new_line);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (i = 1; i < n; i++) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "org.freedesktop.machine1",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "org.freedesktop.machine1.Manager",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "GetMachine",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int kill_machine(sd_bus *bus, char **args, unsigned n) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (i = 1; i < n; i++) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "org.freedesktop.machine1",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "org.freedesktop.machine1.Manager",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "KillMachine",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Could not kill machine: %s", bus_error_message(&error, -r));
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poetteringstatic int reboot_machine(sd_bus *bus, char **args, unsigned n) {
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering arg_signal = SIGINT; /* sysvinit + systemd */
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poetteringstatic int poweroff_machine(sd_bus *bus, char **args, unsigned n) {
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering arg_signal = SIGRTMIN+4; /* only systemd */
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poetteringstatic int terminate_machine(sd_bus *bus, char **args, unsigned n) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering for (i = 1; i < n; i++) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering "org.freedesktop.machine1",
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering "org.freedesktop.machine1.Manager",
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering "TerminateMachine",
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering log_error("Could not terminate machine: %s", bus_error_message(&error, -r));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic int openpt_in_namespace(pid_t pid, int flags) {
3d94f76c99da13e5603831d0b278f8c8c21bcb02Lennart Poettering _cleanup_close_pair_ int pair[2] = { -1, -1 };
a4475f577bd0daf762d6c3b4e58bc484e0cb74afLennart Poettering _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1;
34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1Zbigniew Jędrzejewski-Szmek .msg_controllen = sizeof(control),
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &rootfd);
bc9fd78c7bfc39881e19457e476393635f8b0442Lennart Poettering if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = namespace_enter(pidnsfd, mntnsfd, -1, rootfd);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
bc9fd78c7bfc39881e19457e476393635f8b0442Lennart Poettering if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
bc9fd78c7bfc39881e19457e476393635f8b0442Lennart Poettering if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg))
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic int login_machine(sd_bus *bus, char **args, unsigned n) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *reply2 = NULL, *reply3 = NULL;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _cleanup_bus_unref_ sd_bus *container_bus = NULL;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (arg_transport != BUS_TRANSPORT_LOCAL) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering log_error("Login only supported on local machines.");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "org.freedesktop.machine1",
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "org.freedesktop.machine1.Manager",
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_bus_message_read(reply, "o", &path);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "org.freedesktop.machine1",
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "org.freedesktop.machine1.Machine",
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Failed to retrieve PID of leader: %s", strerror(-r));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_bus_message_read(reply2, "u", &leader);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering master = openpt_in_namespace(leader, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Failed to acquire pseudo tty: %s", strerror(-master));
3db729cb8e6822114e9323f4041dcdc080f2fb3cJason A. Donenfeld r = sd_bus_open_system_container(&container_bus, args[1]);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Failed to get container bus: %s", strerror(-r));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering getty = strjoin("container-getty@", p, ".service", NULL);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "org.freedesktop.systemd1.Manager",
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Failed to start getty service: %s", bus_error_message(&error, r));
a6c616024db23fef34152c1432892824a07799ccLennart Poettering container_bus = sd_bus_unref(container_bus);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering sigset_add_many(&mask, SIGWINCH, SIGTERM, SIGINT, -1);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_info("Connected to container %s. Press ^] three times within 1s to exit session.", args[1]);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Failed to process pseudo tty: %s", strerror(-r));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_info("Connection to container %s terminated.", args[1]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int help(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("%s [OPTIONS...] {COMMAND} ...\n\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "Send control commands to or query the virtual machine and container registration manager.\n\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -h --help Show this help\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " --version Show package version\n"
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering " --no-pager Do not pipe output into a pager\n"
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen " --no-legend Do not show the headers and footers\n"
53755121e1c8ebd3db0330bc82965ecf9a986449Lennart Poettering " -H --host=[USER@]HOST Operate on remote host\n"
53755121e1c8ebd3db0330bc82965ecf9a986449Lennart Poettering " -M --machine=CONTAINER Operate on local container\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -p --property=NAME Show only properties by this name\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -a --all Show all properties, including empty ones\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -l --full Do not ellipsize output\n"
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering " --kill-who=WHO Who to send signal to\n"
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering " -s --signal=SIGNAL Which signal to send\n\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " list List running VMs and containers\n"
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmek " status NAME... Show VM/container status\n"
4f8f66cb4236783cd3cbee97fefc9aaa8469ac08Zbigniew Jędrzejewski-Szmek " show NAME... Show properties of one or more VMs/containers\n"
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering " login NAME Get a login prompt on a container\n"
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering " poweroff NAME... Power off one or more containers\n"
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering " reboot NAME... Reboot one or more containers\n"
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering " kill NAME... Send signal to processes of a VM/container\n"
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering " terminate NAME... Terminate one or more VMs/containers\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "version", no_argument, NULL, ARG_VERSION },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "property", required_argument, NULL, 'p' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "no-pager", no_argument, NULL, ARG_NO_PAGER },
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "kill-who", required_argument, NULL, ARG_KILL_WHO },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "signal", required_argument, NULL, 's' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "host", required_argument, NULL, 'H' },
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering { "machine", required_argument, NULL, 'M' },
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering while ((c = getopt_long(argc, argv, "hp:als:H:M:", options, NULL)) >= 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* If the user asked for a particular
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * property, show it to him, even if it is
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_signal = signal_from_string_try_harder(optarg);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse signal string %s.", optarg);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic int machinectl_main(sd_bus *bus, int argc, char *argv[]) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering static const struct {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen int (* const dispatch)(sd_bus *bus, char **args, unsigned n);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "terminate", MORE, 2, terminate_machine },
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering { "poweroff", MORE, 2, poweroff_machine },
46e65dcc3a522b5e992e165b5e61d14254026859Lennart Poettering /* Special rule: no arguments means "list" */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Unknown operation %s", argv[optind]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Invalid number of arguments.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_not_reached("Unknown comparison operator.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return verbs[i].dispatch(bus, argv + optind, left);
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering r = bus_open_transport(arg_transport, arg_host, false, &bus);
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering log_error("Failed to create bus connection: %s", strerror(-r));