machinectl.c revision b6e676ce41508e2aeea22202fc8f234126177f52
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;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchukstatic bool arg_quiet = false;
7f1ad696a273703789b624fe0b209fb63e953016Lennart Poetteringstatic 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 void pager_open_if_enabled(void) {
2c5859afecee81e345fc9526b1083bf79990ffb8Daniel Mackstatic 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",
0371ca0dac1d70b2e5060a3c4e6fbbc2bdbd8671Florian Weimer 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;
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew Jędrzejewski-Szmek r = sd_bus_message_exit_container(reply);
348ced909724a1331b85d57aede80a102a00e428Zbigniew Jędrzejewski-Szmek qsort_safe(machines, n_machines, sizeof(MachineInfo), compare_machine_info);
670b110c3b59dfa335ac43065b2038400d1d04a9Zbigniew 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));
ed375bebf46c1251f4baa170b39ee93761dbdb19Zbigniew 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)));
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek r = sd_bus_message_exit_container(reply);
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek qsort_safe(images, n_images, sizeof(ImageInfo), compare_image_info);
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek printf("%-*s %-*s %-3s %-*s %-*s %-*s\n",
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek for (j = 0; j < n_images; j++) {
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek char crtime_buf[FORMAT_TIMESTAMP_MAX], mtime_buf[FORMAT_TIMESTAMP_MAX], size_buf[FORMAT_BYTES_MAX];
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew 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);
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmekstatic int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
fc55baee9964a118afbddbf82b8e667a0ad80b99Zbigniew Jędrzejewski-Szmek _cleanup_free_ char *path = NULL;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk endswith(unit, ".scope") ? "org.freedesktop.systemd1.Scope" : "org.freedesktop.systemd1.Service",
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk "ControlGroup",
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering log_error("Failed to query ControlGroup: %s", bus_error_message(&error, -r));
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk r = sd_bus_message_read(reply, "s", &cgroup);
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew Jędrzejewski-Szmek if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, false) != 0 && leader <= 0)
63c8666b824e8762ffb73647e1caee165dfbc868Zbigniew 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;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "GetMachineAddresses",
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(iay)");
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering const void *a;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering char buffer[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)];
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering r = sd_bus_message_read(reply, "i", &family);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering r = sd_bus_message_read_array(reply, 'y', &a, &sz);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering fputs(inet_ntop(family, a, buffer, sizeof(buffer)), stdout);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering r = sd_bus_message_exit_container(reply);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering r = sd_bus_message_exit_container(reply);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poetteringstatic int print_os_release(sd_bus *bus, const char *name, const char *prefix) {
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = 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) {
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering 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;
e40ec7aec5e64cd0cfa5fc556d6a9747229b5794Zbigniew Jędrzejewski-Szmek if (!sd_id128_equal(i->id, SD_ID128_NULL))
e40ec7aec5e64cd0cfa5fc556d6a9747229b5794Zbigniew 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);
e40ec7aec5e64cd0cfa5fc556d6a9747229b5794Zbigniew Jędrzejewski-Szmek printf("\t Leader: %u", (unsigned) i->leader);
e40ec7aec5e64cd0cfa5fc556d6a9747229b5794Zbigniew Jędrzejewski-Szmek get_process_comm(i->leader, &t);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Service: %s", i->service);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek printf("\t Class: %s\n", i->class);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Root: %s\n", i->root_directory);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek for (c = 0; c < i->n_netif; c++) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek if (if_indextoname(i->netif[c], name)) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek print_addresses(bus, i->name, ifi,
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek print_os_release(bus, i->name, "\t OS: ");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Unit: %s\n", i->unit);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek show_unit_cgroup(bus, i->unit, i->leader);
c2457105d76e3daf159f554a9bafb9751b23d756Holger Hans Peter Freyther if (arg_transport == BUS_TRANSPORT_LOCAL) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew 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) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek MachineStatusInfo *i = userdata;
968f319679d9069af037240d0c3bcd126181cdacZbigniew 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);
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmekstatic int show_machine_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering 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) },
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering { "Service", "s", NULL, offsetof(MachineStatusInfo, service) },
de0671ee7fe465e108f62dcbbbe9366f81dd9e9aZbigniew Jędrzejewski-Szmek { "Unit", "s", NULL, offsetof(MachineStatusInfo, unit) },
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering { "RootDirectory", "s", NULL, offsetof(MachineStatusInfo, root_directory) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "Leader", "u", NULL, offsetof(MachineStatusInfo, leader) },
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering { "Timestamp", "t", NULL, offsetof(MachineStatusInfo, timestamp.realtime) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "TimestampMonotonic", "t", NULL, offsetof(MachineStatusInfo, timestamp.monotonic) },
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering { "Id", "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
7027ff61a34a12487712b382a061c654acc3a679Lennart Poettering { "NetworkInterfaces", "ai", map_netif, 0 },
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering "org.freedesktop.machine1",
ae018d9bc900d6355dea4af05119b49c67945184Lennart Poettering return log_error_errno(r, "Could not get properties: %m");
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poetteringstatic int show_machine_properties(sd_bus *bus, const char *path, bool *new_line) {
ef1673d16907726d83bdff2e57b5261997a85020Mirco Tischler 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");
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poetteringstatic int show_machine(int argc, char *argv[], void *userdata) {
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
d682b3a7e7c7c2941a4d3e193f1e330dbc9fae89Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek bool properties, new_line = false;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek /* If no argument is specified, inspect the manager
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = show_machine_properties(bus, "/org/freedesktop/machine1", &new_line);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = sd_bus_message_read(reply, "o", &path);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = show_machine_properties(bus, path, &new_line);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek r = show_machine_info(argv[0], bus, path, &new_line);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmekstatic void print_image_status_info(sd_bus *bus, ImageStatusInfo *i) {
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek char ts_relative[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek char ts_absolute[FORMAT_TIMESTAMP_MAX], *s2;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek char bs_exclusive[FORMAT_BYTES_MAX], *s4;
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek printf("\t Type: %s\n", i->type);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek printf("\t Path: %s\n", i->path);
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering i->read_only ? ansi_highlight_red() : "",
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek i->read_only ? ansi_highlight_off() : "");
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek s1 = format_timestamp_relative(ts_relative, sizeof(ts_relative), i->crtime);
19cace379f3f680d3201cd257ab3ca6708b2d45dLennart Poettering s2 = format_timestamp(ts_absolute, sizeof(ts_absolute), i->crtime);
968f319679d9069af037240d0c3bcd126181cdacZbigniew 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 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;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering printf("\t Usage: %s (exclusive: %s)\n", s3, s4);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek s3 = format_bytes(bs, sizeof(bs), i->limit);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering 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);
759c945a43577d56e85a927f15e7d9aaa94a4e4aColin Waltersstatic int show_image_info(sd_bus *bus, const char *path, bool *new_line) {
40adcda869bda55f44b57fd3a2bd71d006dfb51bLennart Poettering static const struct bus_properties_map map[] = {
40adcda869bda55f44b57fd3a2bd71d006dfb51bLennart Poettering { "Name", "s", NULL, offsetof(ImageStatusInfo, name) },
40adcda869bda55f44b57fd3a2bd71d006dfb51bLennart Poettering { "Path", "s", NULL, offsetof(ImageStatusInfo, path) },
82499507b369fea3033a74c22813bf423301aef4Lennart Poettering { "Type", "s", NULL, offsetof(ImageStatusInfo, type) },
82499507b369fea3033a74c22813bf423301aef4Lennart Poettering { "ReadOnly", "b", NULL, offsetof(ImageStatusInfo, read_only) },
82499507b369fea3033a74c22813bf423301aef4Lennart Poettering { "CreationTimestamp", "t", NULL, offsetof(ImageStatusInfo, crtime) },
8a0889dfdafa3054c894e54852d8a9e3a7e8390bLennart Poettering { "ModificationTimestamp", "t", NULL, offsetof(ImageStatusInfo, mtime) },
da4993920cdf5527b8528f0a483b54ab3cbc1971Kay Sievers { "Usage", "t", NULL, offsetof(ImageStatusInfo, usage) },
da4993920cdf5527b8528f0a483b54ab3cbc1971Kay Sievers { "Limit", "t", NULL, offsetof(ImageStatusInfo, limit) },
759c945a43577d56e85a927f15e7d9aaa94a4e4aColin Walters { "UsageExclusive", "t", NULL, offsetof(ImageStatusInfo, usage_exclusive) },
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering { "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 void print_pool_status_info(sd_bus *bus, PoolStatusInfo *i) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek printf("\t Path: %s\n", i->path);
968f319679d9069af037240d0c3bcd126181cdacZbigniew Jędrzejewski-Szmek s = format_bytes(bs, sizeof(bs), i->usage);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int show_pool_info(sd_bus *bus) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek static const struct bus_properties_map map[] = {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "PoolPath", "s", NULL, offsetof(PoolStatusInfo, path) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "PoolUsage", "t", NULL, offsetof(PoolStatusInfo, usage) },
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek { "PoolLimit", "t", NULL, offsetof(PoolStatusInfo, limit) },
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_pool_status_info(bus, &info);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int show_image_properties(sd_bus *bus, const char *path, bool *new_line) {
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew 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 /* 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",
433dd100442e8197868def975c6fd38b48dc6439Lukas Nykryn if (r < 0) {
433dd100442e8197868def975c6fd38b48dc6439Lukas Nykryn 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);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = show_image_properties(bus, path, &new_line);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = show_image_info(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);
fbb634117d0b0ebd5b105e65b141e75ae9af7f8fLennart Poetteringstatic 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;
fbb634117d0b0ebd5b105e65b141e75ae9af7f8fLennart Poettering "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
00a168618906bea43c3c57e20b9152582c324bf8Olivier Brunel "TerminateMachine",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Could not terminate machine: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int copy_files(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 copy_from = streq(argv[0], "copy-from");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek copy_from ? "CopyFromMachine" : "CopyToMachine",
253f59dff9c93ee1d2c33444b5715e42bc1c6889Lennart Poettering log_error("Failed to copy: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int bind_mount(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 "BindMountMachine",
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering log_error("Failed to bind mount: %s", bus_error_message(&error, -r));
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringstatic int on_machine_removed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering PTYForward ** forward = (PTYForward**) userdata;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering /* If the forwarder is already initialized, tell it to
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering * exit on the next vhangup(), so that we still flush
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering * out what might be queued and exit then. */
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = pty_forward_set_ignore_vhangup(*forward, false);
bdd13f6be4b588568683a1ab54f421fc6a636dbbZbigniew Jędrzejewski-Szmek log_error_errno(r, "Failed to set ignore_vhangup flag: %m");
bdd13f6be4b588568683a1ab54f421fc6a636dbbZbigniew Jędrzejewski-Szmek /* On error, or when the forwarder is not initialized yet, quit immediately */
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sd_event_exit(sd_bus_get_event(bus), EXIT_FAILURE);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringstatic int login_machine(int argc, char *argv[], void *userdata) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering _cleanup_(pty_forward_freep) PTYForward *forward = NULL;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering _cleanup_event_unref_ sd_event *event = NULL;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (arg_transport != BUS_TRANSPORT_LOCAL &&
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering arg_transport != BUS_TRANSPORT_MACHINE) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Login only supported on local machines.");
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering 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 = strjoina("type='signal',"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "sender='org.freedesktop.machine1',"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "path='/org/freedesktop/machine1',",
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering "interface='org.freedesktop.machine1.Manager',"
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering "member='MachineRemoved',"
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = sd_bus_add_match(bus, &slot, match, on_machine_removed, &forward);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return log_error_errno(r, "Failed to add machine removal match: %m");
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering "org.freedesktop.machine1",
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering "org.freedesktop.machine1.Manager",
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering "OpenMachineLogin",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Failed to get machine PTY: %s", bus_error_message(&error, -r));
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = sd_bus_message_read(reply, "hs", &master, &pty);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sigprocmask_many(SIG_BLOCK, SIGWINCH, SIGTERM, SIGINT, -1);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering log_info("Connected to machine %s. Press ^] three times within 1s to exit session.", argv[1]);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = pty_forward_new(event, master, true, false, &forward);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return log_error_errno(r, "Failed to create PTY forwarder: %m");
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering return log_error_errno(r, "Failed to run event loop: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek pty_forward_get_last_char(forward, &last_char);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering machine_died = pty_forward_get_ignore_vhangup(forward) == 0;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering log_info("Machine %s terminated.", argv[1]);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_info("Connection to machine %s terminated.", argv[1]);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringstatic int remove_image(int argc, char *argv[], void *userdata) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4daf54a851e4fb7ed1a13c3117bba12528fd2c7fZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
6203e07a83214a55bb1f88508fcda2005c601deaLennart Poettering "org.freedesktop.machine1.Manager",
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering log_error("Could not remove image: %s", bus_error_message(&error, -r));
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poetteringstatic int rename_image(int argc, char *argv[], void *userdata) {
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
151b9b9662a90455262ce575a8a8ae74bf4ff336Lennart Poettering "RenameImage",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Could not rename image: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int clone_image(int argc, char *argv[], void *userdata) {
74df0fca09b3c31ed19e14ba80f996fdff772417Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
db91ea32aa223d1b087d99811226a9c59a1bb281Zbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "ssb", argv[1], argv[2], arg_read_only);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Could not clone image: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int read_only_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 int b = true, r;
40b71e89bae4e51768db4dc50ec64c1e9c96eec4Sebastian Thorarensen log_error("Failed to parse boolean argument: %s", argv[2]);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "MarkImageReadOnly",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Could not mark image read-only: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int start_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_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = bus_wait_for_jobs_new(bus, &w);
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk _cleanup_free_ char *e = NULL, *unit = NULL;
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk log_error("Invalid machine name %s.", argv[i]);
d07f7b9ef2835c290d6beadebd17d15308608eeaLennart Poettering unit = unit_name_build("systemd-nspawn", e, ".service");
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering "org.freedesktop.systemd1.Manager",
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk log_error("Failed to start unit: %s", bus_error_message(&error, -r));
6a0f1f6d5af7c7300d3db7a0ba2b068f8abd222bLennart Poettering r = sd_bus_message_read(reply, "o", &object);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poetteringstatic int enable_machine(int argc, char *argv[], void *userdata) {
26687bf8a907009dedcff79346860ed41511405eOleksii Shevchuk _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering method = streq(argv[0], "enable") ? "EnableUnitFiles" : "DisableUnitFiles";
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "org.freedesktop.systemd1.Manager",
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering r = sd_bus_message_open_container(m, 'a', "s");
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering _cleanup_free_ char *e = NULL, *unit = NULL;
28def94cc8fd4394b20e2155d7130166662343c4Dave Reisner log_error("Invalid machine name %s.", argv[i]);
28def94cc8fd4394b20e2155d7130166662343c4Dave Reisner unit = unit_name_build("systemd-nspawn", e, ".service");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_append(m, "bb", false, false);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_append(m, "b", false);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering r = sd_bus_call(bus, m, 0, &error, &reply);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Failed to enable or disable unit: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_read(reply, "b", carries_install_info);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.systemd1.Manager",
d288f79fb4a2fe4a93cf99f74dacd2cebd3f2440Zbigniew Jędrzejewski-Szmek log_error("Failed to reload daemon: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int match_log_message(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const char **our_path = userdata, *line;
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering r = sd_bus_message_read(m, "us", &priority, &line);
f9a810bedacf1da7c505c1786a2416d592665926Lennart Poettering if (!streq_ptr(*our_path, sd_bus_message_get_path(m)))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (arg_quiet && LOG_PRI(priority) >= LOG_INFO)
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int match_transfer_removed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *error) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const char **our_path = userdata, *path, *result;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_read(m, "uos", &id, &path, &result);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!streq_ptr(*our_path, path))
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek sd_event_exit(sd_bus_get_event(bus), !streq_ptr(result, "done"));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int transfer_signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_info("Continuing download in the background. Use \"machinectl cancel-transfer %" PRIu32 "\" to abort transfer.", PTR_TO_UINT32(userdata));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek sd_event_exit(sd_event_source_get_event(s), EINTR);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int pull_image_common(sd_bus *bus, sd_bus_message *m) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_slot_unref_ sd_bus_slot *slot_job_removed = NULL, *slot_log_message = NULL;
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_event_unref_ sd_event* event = NULL;
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);
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering return log_error_errno(r, "Failed to attach bus to event loop: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "type='signal',"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "sender='org.freedesktop.import1',"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "interface='org.freedesktop.import1.Manager',"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "member='TransferRemoved',"
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "path='/org/freedesktop/import1'",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(r, "Failed to install match: %m");
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering "type='signal',"
e9174f29c7e3ee45137537b126458718913a3ec5Lennart Poettering "sender='org.freedesktop.import1',"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "interface='org.freedesktop.import1.Transfer',"
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering "member='LogMessage'",
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(r, "Failed to install match: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_call(bus, m, 0, &error, &reply);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Failed acquire image: %s", bus_error_message(&error, -r));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_read(reply, "uo", &id, &path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek sigprocmask_many(SIG_BLOCK, SIGTERM, SIGINT, -1);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_info("Enqueued transfer job %u. Press C-c to continue download in background.", id);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek sd_event_add_signal(event, NULL, SIGINT, transfer_signal_handler, UINT32_TO_PTR(id));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek sd_event_add_signal(event, NULL, SIGTERM, transfer_signal_handler, UINT32_TO_PTR(id));
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(r, "Failed to run event loop: %m");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmekstatic int import_tar(int argc, char *argv[], void *userdata) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *m = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek const char *local = NULL, *path = NULL;
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (isempty(path) || streq(path, "-"))
0c24bb2346b6b6232d67aacd5236b56ea4989de4Lennart Poettering log_error("Need either path or local name.");
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek if (!machine_name_is_valid(local)) {
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek log_error("Local name %s is not a suitable machine name.", local);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek fd = open(path, O_RDONLY|O_CLOEXEC|O_NOCTTY);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek return log_error_errno(errno, "Failed to open %s: %m", path);
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek r = sd_bus_message_new_method_call(
d025f1e4dca8fc1436aff76f9e6185fe3e728daaZbigniew Jędrzejewski-Szmek "org.freedesktop.import1",
"/org/freedesktop/import1",
return bus_log_create_error(r);
return bus_log_create_error(r);
else if (path)
if (!local) {
return -EINVAL;
return log_oom();
return -EINVAL;
if (path) {
if (fd < 0)
bus,
"/org/freedesktop/import1",
return bus_log_create_error(r);
return bus_log_create_error(r);
return -EINVAL;
local = l;
if (local) {
return log_oom();
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 log_oom();
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;
double progress;
} TransferInfo;
static int compare_transfer_info(const void *a, const void *b) {
const TransferInfo *x = a, *y = b;
double progress;
r = sd_bus_call_method(
bus,
"/org/freedesktop/import1",
&error,
&reply,
NULL);
return bus_log_parse_error(r);
while ((r = sd_bus_message_read(reply, "(usssdo)", &id, &type, &remote, &local, &progress, &object)) > 0) {
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,
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&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();