machinectl.c revision 8c841f21f5042b11acc91cc1b039cb162cbbe8f4
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);
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen return bus_log_parse_error(r);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int show_scope_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart 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 if (arg_transport == BUS_TRANSPORT_REMOTE)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "ControlGroup",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_error("Failed to query ControlGroup: %s", bus_error_message(&error, -r));
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_bus_message_read(reply, "s", &cgroup);
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);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering } else if (i->class)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("\t Root: %s\n", i->root_directory);
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) },
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering { "Service", "s", NULL, offsetof(MachineStatusInfo, service) },
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering { "Scope", "s", NULL, offsetof(MachineStatusInfo, scope) },
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering { "RootDirectory", "s", NULL, offsetof(MachineStatusInfo, root_directory) },
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering { "Leader", "u", NULL, offsetof(MachineStatusInfo, leader) },
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering { "Timestamp", "t", NULL, offsetof(MachineStatusInfo, timestamp) },
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering { "Id", "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering "org.freedesktop.machine1",
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering log_error("Could not get properties: %s", strerror(-r));
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringstatic int show_properties(sd_bus *bus, const char *path, bool *new_line) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = bus_print_all_properties(bus, "org.freedesktop.machine1", 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;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering /* If no argument is specified, inspect the manager
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = show_properties(bus, "/org/freedesktop/machine1", &new_line);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering for (i = 1; i < n; i++) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "org.freedesktop.machine1",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart 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 r = show_properties(bus, path, &new_line);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart 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) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering for (i = 1; i < n; i++) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1.Manager",
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "TerminateMachine",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Could not terminate machine: %s", bus_error_message(&error, -r));
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poetteringstatic int openpt_in_namespace(pid_t pid, int flags) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering _cleanup_close_pipe_ int pair[2] = { -1, -1 };
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = namespace_open(pid, &pidnsfd, &mntnsfd, &rootfd);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = namespace_enter(pidnsfd, mntnsfd, rootfd);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (recvmsg(pair[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);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (r < 0 || si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS || master < 0) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return r < 0 ? r : -EIO;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poetteringstatic int login_machine(sd_bus *bus, char **args, unsigned n) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *reply2 = NULL, *reply3 = NULL;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek _cleanup_bus_unref_ sd_bus *container_bus = NULL;
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek _cleanup_close_ int master = -1;
a6c616024db23fef34152c1432892824a07799ccLennart Poettering log_error("Login only support on local machines.");
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "org.freedesktop.machine1",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "org.freedesktop.machine1.Manager",
a6c616024db23fef34152c1432892824a07799ccLennart Poettering 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 "org.freedesktop.machine1",
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "org.freedesktop.machine1.Machine",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to retrieve PID of leader: %s", strerror(-r));
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers master = openpt_in_namespace(leader, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to acquire pseudo tty: %s", strerror(-master));
27e72d6b22890ba4a8cbc05c49667cd1cccf1461Simon Peeters r = sd_bus_open_system_container(args[1], &container_bus);
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error("Failed to get container bus: %s", strerror(-r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering getty = strjoin("container-getty@", p, ".service", NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.systemd1.Manager",
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers 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);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_info("Connected to container %s. Press ^] three times within 1s to exit session.", args[1]);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Failed to process pseudo tty: %s", strerror(-r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_info("Connection to container %s terminated.", args[1]);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poetteringstatic int help(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("%s [OPTIONS...] {COMMAND} ...\n\n"
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "Send control commands to or query the virtual machine and container registration manager.\n\n"
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers " -h --help Show this help\n"
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers " --version Show package version\n"
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering " --no-pager Do not pipe output into a pager\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " --no-ask-password Don't prompt for password\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " -H --host=[USER@]HOST Operate on remote host\n"
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers " -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"
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering " -l --full Do not ellipsize output\n"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen " --kill-who=WHO Who to send signal to\n"
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering " -s --signal=SIGNAL Which signal to send\n\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " list List running VMs and containers\n"
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering " status NAME... Show VM/container status\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " show NAME... Show properties of one or more VMs/containers\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart 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[]) {
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 },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "kill-who", required_argument, NULL, ARG_KILL_WHO },
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering { "signal", required_argument, NULL, 's' },
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering { "host", required_argument, NULL, 'H' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "machine", required_argument, NULL, 'M' },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering while ((c = getopt_long(argc, argv, "hp:als:H:M:", options, NULL)) >= 0) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering /* If the user asked for a particular
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering * property, show it to him, even if it is
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering arg_signal = signal_from_string_try_harder(optarg);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error("Failed to parse signal string %s.", optarg);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int machinectl_main(sd_bus *bus, int argc, char *argv[]) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering static const struct {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering int (* const dispatch)(sd_bus *bus, char **args, unsigned n);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "terminate", MORE, 2, terminate_machine },
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering /* Special rule: no arguments means "list" */
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error("Unknown operation %s", argv[optind]);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error("Invalid number of arguments.");
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering assert_not_reached("Unknown comparison operator.");
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return verbs[i].dispatch(bus, argv + optind, left);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering r = bus_open_transport(arg_transport, arg_host, false, &bus);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error("Failed to create bus connection: %s", strerror(-r));