machinectl.c revision 813c65c34beae2eed1f93d9317f97d7e806389f5
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek This file is part of systemd.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Copyright 2013 Lennart Poettering
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (at your option) any later version.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic char **arg_property = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic bool arg_all = false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic bool arg_full = false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic bool arg_no_pager = false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic bool arg_legend = true;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic const char *arg_kill_who = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic bool arg_read_only = false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic bool arg_mkdir = false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic bool arg_quiet = false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic bool arg_ask_password = true;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic OutputMode arg_output = OUTPUT_SHORT;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic bool arg_force = false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic ImportVerify arg_verify = IMPORT_VERIFY_SIGNATURE;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic const char* arg_dkr_index_url = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic void pager_open_if_enabled(void) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic void polkit_agent_open_if_enabled(void) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Open the polkit agent as a child process if necessary */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (arg_transport != BUS_TRANSPORT_LOCAL)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic OutputFlags get_output_flags(void) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek !arg_quiet * OUTPUT_WARN_CUTOFF;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int compare_machine_info(const void *a, const void *b) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const MachineInfo *x = a, *y = b;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return strcmp(x->name, y->name);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int list_machines(int argc, char *argv[], void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek size_t max_name = strlen("MACHINE"), max_class = strlen("CLASS"), max_service = strlen("SERVICE");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_free_ MachineInfo *machines = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const char *name, *class, *service, *object;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek size_t n_machines = 0, n_allocated = 0, j;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Could not get machines: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_enter_container(reply, 'a', "(ssso)");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek while ((r = sd_bus_message_read(reply, "(ssso)", &name, &class, &service, &object)) > 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!GREEDY_REALLOC(machines, n_allocated, n_machines + 1))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek machines[n_machines].name = name;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek machines[n_machines].class = class;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek machines[n_machines].service = service;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_exit_container(reply);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek qsort_safe(machines, n_machines, sizeof(MachineInfo), compare_machine_info);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (j = 0; j < n_machines; j++)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (int) max_name, machines[j].name,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (int) max_class, machines[j].class,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (int) max_service, machines[j].service);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\n%zu machines listed.\n", n_machines);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int compare_image_info(const void *a, const void *b) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const ImageInfo *x = a, *y = b;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return strcmp(x->name, y->name);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int list_images(int argc, char *argv[], void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek size_t max_name = strlen("NAME"), max_type = strlen("TYPE"), max_size = strlen("USAGE"), max_crtime = strlen("CREATED"), max_mtime = strlen("MODIFIED");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_free_ ImageInfo *images = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek size_t n_images = 0, n_allocated = 0, j;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const char *name, *type, *object;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Could not get images: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssbttto)");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek while ((r = sd_bus_message_read(reply, "(ssbttto)", &name, &type, &read_only, &crtime, &mtime, &size, &object)) > 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char buf[MAX(FORMAT_TIMESTAMP_MAX, FORMAT_BYTES_MAX)];
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!GREEDY_REALLOC(images, n_allocated, n_images + 1))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek images[n_images].read_only = read_only;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek images[n_images].crtime = crtime;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek l = strlen(strna(format_timestamp(buf, sizeof(buf), crtime)));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek l = strlen(strna(format_timestamp(buf, sizeof(buf), mtime)));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek l = strlen(strna(format_bytes(buf, sizeof(buf), size)));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_exit_container(reply);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek qsort_safe(images, n_images, sizeof(ImageInfo), compare_image_info);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("%-*s %-*s %-3s %-*s %-*s %-*s\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (j = 0; j < n_images; j++) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char crtime_buf[FORMAT_TIMESTAMP_MAX], mtime_buf[FORMAT_TIMESTAMP_MAX], size_buf[FORMAT_BYTES_MAX];
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("%-*s %-*s %s%-3s%s %-*s %-*s %-*s\n",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek images[j].read_only ? ansi_highlight_red() : "", yes_no(images[j].read_only), images[j].read_only ? ansi_highlight_off() : "",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (int) max_size, strna(format_bytes(size_buf, sizeof(size_buf), images[j].size)),
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (int) max_crtime, strna(format_timestamp(crtime_buf, sizeof(crtime_buf), images[j].crtime)),
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek (int) max_mtime, strna(format_timestamp(mtime_buf, sizeof(mtime_buf), images[j].mtime)));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\n%zu images listed.\n", n_images);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
7d73c1343be02a59b17de0cd34375deeb815d89cLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_free_ char *path = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (arg_transport == BUS_TRANSPORT_REMOTE)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek path = unit_dbus_path_from_name(unit);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek endswith(unit, ".scope") ? "org.freedesktop.systemd1.Scope" : "org.freedesktop.systemd1.Service",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Failed to query ControlGroup: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_read(reply, "s", &cgroup);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, false) != 0 && leader <= 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, get_output_flags());
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int print_addresses(sd_bus *bus, const char *name, int ifi, const char *prefix, const char *prefix2) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "GetMachineAddresses",
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek r = sd_bus_message_enter_container(reply, 'a', "(iay)");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char buffer[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)];
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_read(reply, "i", &family);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_read_array(reply, 'y', &a, &sz);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fputs(inet_ntop(family, a, buffer, sizeof(buffer)), stdout);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (family == AF_INET6 && ifi > 0)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_exit_container(reply);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_exit_container(reply);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int print_os_release(sd_bus *bus, const char *name, const char *prefix) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const char *k, *v, *pretty = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "GetMachineOSRelease",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_enter_container(reply, 'a', "{ss}");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek while ((r = sd_bus_message_read(reply, "{ss}", &k, &v)) > 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_exit_container(reply);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("%s%s\n", prefix, pretty);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmektypedef struct MachineStatusInfo {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek struct dual_timestamp timestamp;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char since2[FORMAT_TIMESTAMP_MAX], *s2;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!sd_id128_equal(i->id, SD_ID128_NULL))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp.realtime);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s2 = format_timestamp(since2, sizeof(since2), i->timestamp.realtime);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Since: %s; %s\n", s2, s1);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Leader: %u", (unsigned) i->leader);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek get_process_comm(i->leader, &t);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Service: %s", i->service);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Class: %s\n", i->class);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Root: %s\n", i->root_directory);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek for (c = 0; c < i->n_netif; c++) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (if_indextoname(i->netif[c], name)) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek print_addresses(bus, i->name, ifi,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Unit: %s\n", i->unit);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (arg_transport == BUS_TRANSPORT_LOCAL) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek get_output_flags() | OUTPUT_BEGIN_NEWLINE,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int map_netif(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek MachineStatusInfo *i = userdata;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek assert_cc(sizeof(int32_t) == sizeof(int));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_read_array(m, SD_BUS_TYPE_INT32, &v, &l);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int show_machine_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek static const struct bus_properties_map map[] = {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "Name", "s", NULL, offsetof(MachineStatusInfo, name) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "Class", "s", NULL, offsetof(MachineStatusInfo, class) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "Service", "s", NULL, offsetof(MachineStatusInfo, service) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "Unit", "s", NULL, offsetof(MachineStatusInfo, unit) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "RootDirectory", "s", NULL, offsetof(MachineStatusInfo, root_directory) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "Leader", "u", NULL, offsetof(MachineStatusInfo, leader) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "Timestamp", "t", NULL, offsetof(MachineStatusInfo, timestamp.realtime) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "TimestampMonotonic", "t", NULL, offsetof(MachineStatusInfo, timestamp.monotonic) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "Id", "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "NetworkInterfaces", "ai", map_netif, 0 },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(r, "Could not get properties: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek print_machine_status_info(bus, &info);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int show_machine_properties(sd_bus *bus, const char *path, bool *new_line) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_all);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error_errno(r, "Could not get properties: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int show_machine(int argc, char *argv[], void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek bool properties, new_line = false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek properties = !strstr(argv[0], "status");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* If no argument is specified, inspect the manager
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = show_machine_properties(bus, "/org/freedesktop/machine1", &new_line);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek r = sd_bus_message_read(reply, "o", &path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = show_machine_properties(bus, path, &new_line);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = show_machine_info(argv[0], bus, path, &new_line);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic void print_image_status_info(sd_bus *bus, ImageStatusInfo *i) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char ts_relative[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char ts_absolute[FORMAT_TIMESTAMP_MAX], *s2;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char bs_exclusive[FORMAT_BYTES_MAX], *s4;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Type: %s\n", i->type);
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek printf("\t Path: %s\n", i->path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek i->read_only ? ansi_highlight_red() : "",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek i->read_only ? "read-only" : "writable",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek i->read_only ? ansi_highlight_off() : "");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s1 = format_timestamp_relative(ts_relative, sizeof(ts_relative), i->crtime);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s2 = format_timestamp(ts_absolute, sizeof(ts_absolute), i->crtime);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Created: %s; %s\n", s2, s1);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s1 = format_timestamp_relative(ts_relative, sizeof(ts_relative), i->mtime);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s2 = format_timestamp(ts_absolute, sizeof(ts_absolute), i->mtime);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\tModified: %s; %s\n", s2, s1);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s3 = format_bytes(bs, sizeof(bs), i->usage);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s4 = i->usage_exclusive != i->usage ? format_bytes(bs_exclusive, sizeof(bs_exclusive), i->usage_exclusive) : NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Usage: %s (exclusive: %s)\n", s3, s4);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s3 = format_bytes(bs, sizeof(bs), i->limit);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s4 = i->limit_exclusive != i->limit ? format_bytes(bs_exclusive, sizeof(bs_exclusive), i->limit_exclusive) : NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Limit: %s (exclusive: %s)\n", s3, s4);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int show_image_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek static const struct bus_properties_map map[] = {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "Name", "s", NULL, offsetof(ImageStatusInfo, name) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "Path", "s", NULL, offsetof(ImageStatusInfo, path) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "Type", "s", NULL, offsetof(ImageStatusInfo, type) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "ReadOnly", "b", NULL, offsetof(ImageStatusInfo, read_only) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "CreationTimestamp", "t", NULL, offsetof(ImageStatusInfo, crtime) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "ModificationTimestamp", "t", NULL, offsetof(ImageStatusInfo, mtime) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "Usage", "t", NULL, offsetof(ImageStatusInfo, usage) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "Limit", "t", NULL, offsetof(ImageStatusInfo, limit) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "UsageExclusive", "t", NULL, offsetof(ImageStatusInfo, usage_exclusive) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "LimitExclusive", "t", NULL, offsetof(ImageStatusInfo, limit_exclusive) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(r, "Could not get properties: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek print_image_status_info(bus, &info);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int show_image_properties(sd_bus *bus, const char *path, bool *new_line) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_all);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error_errno(r, "Could not get properties: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int show_image(int argc, char *argv[], void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek bool properties, new_line = false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek properties = !strstr(argv[0], "status");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* If no argument is specified, inspect the manager
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = show_image_properties(bus, "/org/freedesktop/machine1", &new_line);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Could not get path to image: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_read(reply, "o", &path);
93b73b064c663d6248bebfbbbd82989b5ca10fc5Lennart Poettering r = show_image_properties(bus, path, &new_line);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = show_image_info(argv[0], bus, path, &new_line);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int kill_machine(int argc, char *argv[], void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "ssi", argv[i], arg_kill_who, arg_signal);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Could not kill machine: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int reboot_machine(int argc, char *argv[], void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek arg_signal = SIGINT; /* sysvinit + systemd */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return kill_machine(argc, argv, userdata);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int poweroff_machine(int argc, char *argv[], void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek arg_signal = SIGRTMIN+4; /* only systemd */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return kill_machine(argc, argv, userdata);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int terminate_machine(int argc, char *argv[], void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "TerminateMachine",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Could not terminate machine: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int machine_get_leader(sd_bus *bus, const char *name, pid_t *ret) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *reply2 = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_read(reply, "o", &object);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Machine",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(r, "Failed to retrieve PID of leader: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_read(reply2, "u", &leader);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int copy_files(int argc, char *argv[], void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char *dest, *host_path, *container_path, *host_dirname, *host_basename, *container_dirname, *container_basename, *t;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_close_ int hostfd = -1;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek copy_from = streq(argv[0], "copy-from");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek host_path = strdupa(copy_from ? dest : argv[2]);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek container_path = strdupa(copy_from ? argv[2] : dest);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!path_is_absolute(container_path)) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Container path not absolute.");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek host_dirname = dirname(host_path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek container_basename = basename(t);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek container_dirname = dirname(container_path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = machine_get_leader(bus, argv[1], &leader);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek hostfd = open(host_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(errno, "Failed to open source directory: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(errno, "Failed to fork(): %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek q = procfs_file_alloca(leader, "ns/mnt");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error_errno(errno, "Failed to open mount namespace of leader: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (setns(mntfd, CLONE_NEWNS) < 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error_errno(errno, "Failed to join namespace of leader: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek containerfd = open(container_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error_errno(errno, "Failed top open destination directory: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = copy_tree_at(containerfd, container_basename, hostfd, host_basename, true);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = copy_tree_at(hostfd, host_basename, containerfd, container_basename, true);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error_errno(errno, "Failed to copy tree: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = wait_for_terminate(child, &si);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(r, "Failed to wait for client: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Client died abnormally.");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (si.si_status != EXIT_SUCCESS)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int bind_mount(int argc, char *argv[], void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek char mount_slave[] = "/tmp/propagate.XXXXXX", *mount_tmp, *mount_outside, *p;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek bool mount_slave_created = false, mount_slave_mounted = false,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek mount_tmp_created = false, mount_tmp_mounted = false,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek mount_outside_created = false, mount_outside_mounted = false;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* One day, when bind mounting /proc/self/fd/n works across
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * namespace boundaries we should rework this logic to make
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * use of it... */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Destination path not absolute.");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek p = strappenda("/run/systemd/nspawn/propagate/", argv[1], "/");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Container does not allow propagation of mount points.");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = machine_get_leader(bus, argv[1], &leader);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Our goal is to install a new bind mount into the container,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek possibly read-only. This is irritatingly complex
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek unfortunately, currently.
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek First, we start by creating a private playground in /tmp,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek that we can mount MS_SLAVE. (Which is necessary, since
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek MS_MOUNT cannot be applied to mounts with MS_SHARED parent
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(errno, "Failed to create playground: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (mount(mount_slave, mount_slave, NULL, MS_BIND, NULL) < 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = log_error_errno(errno, "Failed to make bind mount: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (mount(NULL, mount_slave, NULL, MS_SLAVE, NULL) < 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = log_error_errno(errno, "Failed to remount slave: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Second, we mount the source directory to a directory inside
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek of our MS_SLAVE playground. */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek mount_tmp = strappenda(mount_slave, "/mount");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (mkdir(mount_tmp, 0700) < 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = log_error_errno(errno, "Failed to create temporary mount: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (mount(argv[2], mount_tmp, NULL, MS_BIND, NULL) < 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = log_error_errno(errno, "Failed to overmount: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Third, we remount the new bind mount read-only if requested. */
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek if (mount(NULL, mount_tmp, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = log_error_errno(errno, "Failed to mark read-only: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Fourth, we move the new bind mount into the propagation
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * directory. This way it will appear there read-only
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * right-away. */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek mount_outside = strappenda("/run/systemd/nspawn/propagate/", argv[1], "/XXXXXX");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = log_error_errno(errno, "Cannot create propagation directory: %m");
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek if (mount(mount_tmp, mount_outside, NULL, MS_MOVE, NULL) < 0) {
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek r = log_error_errno(errno, "Failed to move: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = log_error_errno(errno, "Failed to fork(): %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek q = procfs_file_alloca(leader, "ns/mnt");
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error_errno(errno, "Failed to open mount namespace of leader: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (setns(mntfd, CLONE_NEWNS) < 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error_errno(errno, "Failed to join namespace of leader: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* Fifth, move the mount to the right place inside */
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek mount_inside = strappenda("/run/systemd/nspawn/incoming/", basename(mount_outside));
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek if (mount(mount_inside, dest, NULL, MS_MOVE, NULL) < 0) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error_errno(errno, "Failed to mount: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = wait_for_terminate(child, &si);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error_errno(r, "Failed to wait for client: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Client died abnormally.");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (si.si_status != EXIT_SUCCESS) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int on_machine_removed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek PTYForward ** forward = (PTYForward**) userdata;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* If the forwarder is already initialized, tell it to
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * exit on the next vhangup(), so that we still flush
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek * out what might be queued and exit then. */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = pty_forward_set_ignore_vhangup(*forward, false);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error_errno(r, "Failed to set ignore_vhangup flag: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek /* On error, or when the forwarder is not initialized yet, quit immediately */
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek sd_event_exit(sd_bus_get_event(bus), EXIT_FAILURE);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int login_machine(int argc, char *argv[], void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_(pty_forward_freep) PTYForward *forward = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_event_unref_ sd_event *event = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (arg_transport != BUS_TRANSPORT_LOCAL &&
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek arg_transport != BUS_TRANSPORT_MACHINE) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Login only supported on local machines.");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(r, "Failed to get event loop: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_attach_event(bus, event, 0);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(r, "Failed to attach bus to event loop: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek match = strappenda("type='signal',"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "sender='org.freedesktop.machine1',"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "path='/org/freedesktop/machine1',",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "interface='org.freedesktop.machine1.Manager',"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "member='MachineRemoved',"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_add_match(bus, &slot, match, on_machine_removed, &forward);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(r, "Failed to add machine removal match: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_new_method_call(bus,
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "OpenMachineLogin");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_append(m, "s", argv[1]);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_call(bus, m, 0, &error, &reply);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Failed to get machine PTY: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_read(reply, "hs", &master, &pty);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek sigprocmask_many(SIG_BLOCK, SIGWINCH, SIGTERM, SIGINT, -1);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_info("Connected to machine %s. Press ^] three times within 1s to exit session.", argv[1]);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = pty_forward_new(event, master, true, &forward);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(r, "Failed to create PTY forwarder: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(r, "Failed to run event loop: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek pty_forward_get_last_char(forward, &last_char);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek machine_died = pty_forward_get_ignore_vhangup(forward) == 0;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek forward = pty_forward_free(forward);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_info("Machine %s terminated.", argv[1]);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_info("Connection to machine %s terminated.", argv[1]);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek sd_event_get_exit_code(event, &ret);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int remove_image(int argc, char *argv[], void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Could not remove image: %s", bus_error_message(&error, -r));
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
return -EINVAL;
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
return log_oom();
const char *object;
return -EINVAL;
return log_oom();
if (!unit)
return log_oom();
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_parse_error(r);
return log_oom();
int carries_install_info = 0;
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
method);
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_create_error(r);
return -EINVAL;
return log_oom();
if (!unit)
return log_oom();
return bus_log_create_error(r);
r = sd_bus_message_close_container(m);
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_parse_error(r);
m = sd_bus_message_unref(m);
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
return bus_log_create_error(r);
return bus_log_create_error(r);
typedef struct PullContext {
const char *path;
int result;
} PullContext;
const char *line;
unsigned priority;
assert(m);
static int match_transfer_removed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
assert(m);
assert(c);
PullContext c = {
assert(m);
return bus_log_create_error(r);
r = sd_bus_add_match(
bus,
"path='/org/freedesktop/import1'",
match_transfer_removed, &c);
r = sd_bus_add_match(
bus,
match_log_message, &c);
return bus_log_parse_error(r);
if (c.result >= 0)
return -EINVAL;
local = l;
if (local) {
return -EINVAL;
bus,
"/org/freedesktop/import1",
return bus_log_create_error(r);
return bus_log_create_error(r);
return -EINVAL;
local = l;
if (local) {
return -EINVAL;
bus,
"/org/freedesktop/import1",
return bus_log_create_error(r);
return bus_log_create_error(r);
return -EINVAL;
if (tag) {
tag++;
return -EINVAL;
return -EINVAL;
if (local)
local++;
if (local) {
return -EINVAL;
bus,
"/org/freedesktop/import1",
return bus_log_create_error(r);
tag,
return bus_log_create_error(r);
typedef struct TransferInfo {
const char *type;
const char *remote;
const char *local;
} TransferInfo;
static int compare_transfer_info(const void *a, const void *b) {
const TransferInfo *x = a, *y = b;
r = sd_bus_call_method(
bus,
"/org/freedesktop/import1",
&error,
&reply,
NULL);
return bus_log_parse_error(r);
size_t l;
return log_oom();
if (l > max_type)
max_type = l;
if (l > max_remote)
max_remote = l;
if (l > max_local)
max_local = l;
n_transfers ++;
return bus_log_parse_error(r);
return bus_log_parse_error(r);
if (arg_legend)
for (j = 0; j < n_transfers; j++)
if (arg_legend)
r = sd_bus_call_method(
bus,
"/org/freedesktop/import1",
&error,
NULL,
" show NAME... Show properties of one or more VMs/containers\n"
" terminate NAME... Terminate one or more VMs/containers\n"
case ARG_VERSION:
return log_oom();
arg_all = true;
arg_all = true;
arg_full = true;
return -EINVAL;
if (arg_output < 0) {
return -EINVAL;
case ARG_NO_PAGER:
arg_no_pager = true;
case ARG_NO_LEGEND:
arg_legend = false;
case ARG_KILL_WHO:
if (arg_signal < 0) {
return -EINVAL;
case ARG_NO_ASK_PASSWORD:
arg_ask_password = false;
case ARG_READ_ONLY:
arg_read_only = true;
case ARG_MKDIR:
arg_mkdir = true;
arg_quiet = true;
case ARG_VERIFY:
if (arg_verify < 0) {
return -EINVAL;
case ARG_FORCE:
arg_force = true;
case ARG_DKR_INDEX_URL:
return -EINVAL;
return -EINVAL;
log_open();
goto finish;
goto finish;
pager_close();