machinectl.c revision 84f6181c2ac99a0514ca5e0c8fc8c8e284caf789
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;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poetteringstatic bool arg_full = false;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic bool arg_no_pager = false;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic bool arg_ask_password = true;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poetteringstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void pager_open_if_enabled(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Cache result before we open the pager */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int list_machines(sd_bus *bus, char **args, unsigned n) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *name, *class, *service, *object;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned k = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "org.freedesktop.machine1.Manager",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "ListMachines",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Could not get machines: %s", bus_error_message(&error, -r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 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) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen printf("%-32s %-9s %-16s\n", name, class, service);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_exit_container(reply);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse reply: %s", strerror(-r));
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poetteringstatic int show_scope_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;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_transport == BUS_TRANSPORT_REMOTE)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "ControlGroup",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_error("Failed to query ControlGroup: %s", bus_error_message(&error, -r));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = sd_bus_message_read(reply, "s", &cgroup);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_error("Failed to parse reply: %s", strerror(-r));
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, false) != 0 && leader <= 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, output_flags);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringstatic void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!sd_id128_equal(i->id, SD_ID128_NULL))
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id));
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering s2 = format_timestamp(since2, sizeof(since2), i->timestamp);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("\t Leader: %u", (unsigned) i->leader);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen } else if (i->class)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering printf("\t Root: %s\n", i->root_directory);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering show_scope_cgroup(bus, i->scope, i->leader);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringstatic int show_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering static const struct bus_properties_map map[] = {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering { "Name", "s", NULL, offsetof(MachineStatusInfo, name) },
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering { "Class", "s", NULL, offsetof(MachineStatusInfo, class) },
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering { "Service", "s", NULL, offsetof(MachineStatusInfo, service) },
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering { "Scope", "s", NULL, offsetof(MachineStatusInfo, scope) },
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering { "RootDirectory", "s", NULL, offsetof(MachineStatusInfo, root_directory) },
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering { "Leader", "u", NULL, offsetof(MachineStatusInfo, leader) },
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering { "Timestamp", "t", NULL, offsetof(MachineStatusInfo, timestamp) },
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering { "Id", "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering "org.freedesktop.machine1",
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering log_error("Could not get properties: %s", strerror(-r));
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poetteringstatic int show_properties(sd_bus *bus, const char *path, bool *new_line) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = bus_print_all_properties(bus, path, arg_property, arg_all);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_error("Could not get properties: %s", strerror(-r));
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringstatic int show(sd_bus *bus, char **args, unsigned n) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering /* If no argument is specified, inspect the manager
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = show_properties(bus, "/org/freedesktop/machine1", &new_line);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_error("Failed to query properties: %s", strerror(-r));
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering for (i = 1; i < n; i++) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "org.freedesktop.machine1",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "org.freedesktop.machine1.Manager",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_message_read(reply, "o", &path);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_error("Failed to parse reply: %s", strerror(-r));
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = show_properties(bus, path, &new_line);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = show_info(args[0], bus, path, &new_line);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poetteringstatic int kill_machine(sd_bus *bus, char **args, unsigned n) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering for (i = 1; i < n; i++) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "org.freedesktop.machine1",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "org.freedesktop.machine1.Manager",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "KillMachine",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "ssi", args[i], arg_kill_who, arg_signal);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering log_error("Could not kill machine: %s", bus_error_message(&error, -r));
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poetteringstatic int terminate_machine(sd_bus *bus, char **args, unsigned n) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering for (i = 1; i < n; i++) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "org.freedesktop.machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1.Manager",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "TerminateMachine",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_error("Could not terminate machine: %s", bus_error_message(&error, -r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int openpt_in_namespace(pid_t pid, int flags) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_close_ int nsfd = -1, rootfd = -1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_free_ char *ns = NULL, *root = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_close_pipe_ int sock[2] = { -1, -1 };
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = asprintf(&ns, "/proc/%lu/ns/mnt", (unsigned long) pid);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering nsfd = open(ns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = asprintf(&root, "/proc/%lu/root", (unsigned long) pid);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering rootfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sock) < 0)
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (recvmsg(sock[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg))
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (r < 0 || si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS || master < 0) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return r < 0 ? r : -EIO;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int login_machine(sd_bus *bus, char **args, unsigned n) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *reply2 = NULL, *reply3 = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_bus_unref_ sd_bus *container_bus = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_transport != BUS_TRANSPORT_LOCAL) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Login only support on local machines.");
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering "org.freedesktop.machine1",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "org.freedesktop.machine1.Manager",
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (r < 0) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = sd_bus_message_read(reply, "o", &path);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_error("Failed to parse reply: %s", strerror(-r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "org.freedesktop.machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1.Machine",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Failed to retrieve PID of leader: %s", strerror(-r));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = sd_bus_message_read(reply2, "u", &leader);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse reply: %s", strerror(-r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering master = openpt_in_namespace(leader, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_error("Failed to acquire pseudo tty: %s", strerror(-master));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_bus_open_system_container(args[1], &container_bus);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Failed to get container bus: %s", strerror(-r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen getty = strjoin("container-getty@", p, ".service", NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.systemd1.Manager",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_error("Failed to start getty service: %s", bus_error_message(&error, r));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering sigset_add_many(&mask, SIGWINCH, SIGTERM, SIGINT, -1);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_info("Connected to container %s. Press ^] three times within 1s to exit session.", args[1]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to process pseudo tty: %s", strerror(-r));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_info("Connection to container %s terminated.", args[1]);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int help(void) {
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"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " --no-pager Do not pipe output into a pager\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " --no-ask-password Don't prompt for password\n"
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering " -H --host=[USER@]HOST Operate on remote host\n"
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering " -M --machine=CONTAINER Operate on local container\n"
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering " -p --property=NAME Show only properties by this name\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -a --all Show all properties, including empty ones\n"
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering " -l --full Do not ellipsize output\n"
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering " --kill-who=WHO Who to send signal to\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -s --signal=SIGNAL Which signal to send\n\n"
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering " list List running VMs and containers\n"
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering " status [NAME...] Show VM/container status\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " show [NAME...] Show properties of one or more VMs/containers\n"
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering " terminate [NAME...] Terminate one or more VMs/containers\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " kill [NAME...] Send signal to processes of a VM/container\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " login [NAME] Get a login prompt on a container\n",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering { "version", no_argument, NULL, ARG_VERSION },
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering { "property", required_argument, NULL, 'p' },
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering { "no-pager", no_argument, NULL, ARG_NO_PAGER },
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering { "kill-who", required_argument, NULL, ARG_KILL_WHO },
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering { "signal", required_argument, NULL, 's' },
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering { "host", required_argument, NULL, 'H' },
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering { "machine", required_argument, NULL, 'M' },
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering while ((c = getopt_long(argc, argv, "hp:als:H:M:", options, NULL)) >= 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* If the user asked for a particular
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering * property, show it to him, even if it is
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering arg_signal = signal_from_string_try_harder(optarg);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error("Failed to parse signal string %s.", optarg);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poetteringstatic int machinectl_main(sd_bus *bus, int argc, char *argv[]) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering static const struct {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering int (* const dispatch)(sd_bus *bus, char **args, unsigned n);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering { "terminate", MORE, 2, terminate_machine },
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering /* Special rule: no arguments means "list-sessions" */
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error("Unknown operation %s", argv[optind]);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error("Invalid number of arguments.");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering assert_not_reached("Unknown comparison operator.");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return verbs[i].dispatch(bus, argv + optind, left);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = bus_open_transport(arg_transport, arg_host, false, &bus);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error("Failed to create bus connection: %s", strerror(-r));