machinectl.c revision bb4a228207815df88cdf68acd9e46ec19e0d3e30
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek This file is part of systemd.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek Copyright 2013 Lennart Poettering
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek systemd is free software; you can redistribute it and/or modify it
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek under the terms of the GNU Lesser General Public License as published by
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek the Free Software Foundation; either version 2.1 of the License, or
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek (at your option) any later version.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek systemd is distributed in the hope that it will be useful, but
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek WITHOUT ANY WARRANTY; without even the implied warranty of
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek Lesser General Public License for more details.
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek You should have received a copy of the GNU Lesser General Public License
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek along with systemd; If not, see <http://www.gnu.org/licenses/>.
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekstatic char **arg_property = NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekstatic bool arg_all = false;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekstatic bool arg_full = false;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekstatic bool arg_no_pager = false;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekstatic bool arg_legend = true;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekstatic const char *arg_kill_who = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic bool arg_read_only = false;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic bool arg_mkdir = false;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic bool arg_quiet = false;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic bool arg_ask_password = true;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic OutputMode arg_output = OUTPUT_SHORT;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic void pager_open_if_enabled(void) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekstatic void polkit_agent_open_if_enabled(void) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek /* Open the polkit agent as a child process if necessary */
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (arg_transport != BUS_TRANSPORT_LOCAL)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekstatic OutputFlags get_output_flags(void) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek !arg_quiet * OUTPUT_WARN_CUTOFF;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekstatic int compare_machine_info(const void *a, const void *b) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek const MachineInfo *x = a, *y = b;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek return strcmp(x->name, y->name);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmekstatic int list_machines(int argc, char *argv[], void *userdata) {
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek size_t max_name = strlen("MACHINE"), max_class = strlen("CLASS"), max_service = strlen("SERVICE");
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek _cleanup_free_ MachineInfo *machines = NULL;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek const char *name, *class, *service, *object;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek size_t n_machines = 0, n_allocated = 0, j;
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek log_error("Could not get machines: %s", bus_error_message(&error, -r));
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssso)");
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek while ((r = sd_bus_message_read(reply, "(ssso)", &name, &class, &service, &object)) > 0) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!GREEDY_REALLOC(machines, n_allocated, n_machines + 1))
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek machines[n_machines].name = name;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek machines[n_machines].class = class;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek machines[n_machines].service = service;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = sd_bus_message_exit_container(reply);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek qsort_safe(machines, n_machines, sizeof(MachineInfo), compare_machine_info);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek for (j = 0; j < n_machines; j++)
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek (int) max_name, machines[j].name,
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek (int) max_class, machines[j].class,
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek (int) max_service, machines[j].service);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek printf("\n%zu machines listed.\n", n_machines);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int compare_image_info(const void *a, const void *b) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek const ImageInfo *x = a, *y = b;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek return strcmp(x->name, y->name);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int list_images(int argc, char *argv[], void *userdata) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek size_t max_name = strlen("NAME"), max_type = strlen("TYPE"), max_size = strlen("SIZE"), max_crtime = strlen("CREATED"), max_mtime = strlen("MODIFIED");
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek _cleanup_free_ ImageInfo *images = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek size_t n_images = 0, n_allocated = 0, j;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek const char *name, *type, *object;
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek log_error("Could not get images: %s", bus_error_message(&error, -r));
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssbttto)");
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek while ((r = sd_bus_message_read(reply, "(ssbttto)", &name, &type, &read_only, &crtime, &mtime, &size, &object)) > 0) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek char buf[MAX(FORMAT_TIMESTAMP_MAX, FORMAT_BYTES_MAX)];
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!GREEDY_REALLOC(images, n_allocated, n_images + 1))
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek images[n_images].read_only = read_only;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek images[n_images].crtime = crtime;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek l = strlen(strna(format_timestamp(buf, sizeof(buf), crtime)));
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek l = strlen(strna(format_timestamp(buf, sizeof(buf), mtime)));
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek l = strlen(strna(format_bytes(buf, sizeof(buf), size)));
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = sd_bus_message_exit_container(reply);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek qsort_safe(images, n_images, sizeof(ImageInfo), compare_image_info);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek printf("%-*s %-*s %-3s %-*s %-*s %-*s\n",
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek for (j = 0; j < n_images; j++) {
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek char crtime_buf[FORMAT_TIMESTAMP_MAX], mtime_buf[FORMAT_TIMESTAMP_MAX], size_buf[FORMAT_BYTES_MAX];
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek printf("%-*s %-*s %s%-3s%s %-*s %-*s %-*s\n",
8201af08fa09c2bd0f005fbe262f27e2c5bd2d86Zbigniew Jędrzejewski-Szmek images[j].read_only ? ansi_highlight_red() : "", yes_no(images[j].read_only), images[j].read_only ? ansi_highlight_off() : "",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek (int) max_size, strna(format_bytes(size_buf, sizeof(size_buf), images[j].size)),
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek (int) max_crtime, strna(format_timestamp(crtime_buf, sizeof(crtime_buf), images[j].crtime)),
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek (int) max_mtime, strna(format_timestamp(mtime_buf, sizeof(mtime_buf), images[j].mtime)));
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek printf("\n%zu images listed.\n", n_images);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek _cleanup_free_ char *path = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (arg_transport == BUS_TRANSPORT_REMOTE)
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek path = unit_dbus_path_from_name(unit);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek endswith(unit, ".scope") ? "org.freedesktop.systemd1.Scope" : "org.freedesktop.systemd1.Service",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek log_error("Failed to query ControlGroup: %s", bus_error_message(&error, -r));
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek r = sd_bus_message_read(reply, "s", &cgroup);
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, false) != 0 && leader <= 0)
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, get_output_flags());
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmekstatic int print_addresses(sd_bus *bus, const char *name, int ifi, const char *prefix, const char *prefix2) {
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek "GetMachineAddresses",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = sd_bus_message_enter_container(reply, 'a', "(iay)");
5bc891206dd8eb4e4df58f502b0184b8426caf22Zbigniew Jędrzejewski-Szmek while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
5bc891206dd8eb4e4df58f502b0184b8426caf22Zbigniew Jędrzejewski-Szmek char buffer[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)];
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek r = sd_bus_message_read(reply, "i", &family);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = sd_bus_message_read_array(reply, 'y', &a, &sz);
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek fputs(inet_ntop(family, a, buffer, sizeof(buffer)), stdout);
a3152e7655231b94fa7b9582906fb86ab00b9c99Zbigniew Jędrzejewski-Szmek if (family == AF_INET6 && ifi > 0)
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek r = sd_bus_message_exit_container(reply);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = sd_bus_message_exit_container(reply);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int print_os_release(sd_bus *bus, const char *name, const char *prefix) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek const char *k, *v, *pretty = NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "GetMachineOSRelease",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = sd_bus_message_enter_container(reply, 'a', "{ss}");
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek while ((r = sd_bus_message_read(reply, "{ss}", &k, &v)) > 0) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = sd_bus_message_exit_container(reply);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek printf("%s%s\n", prefix, pretty);
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmektypedef struct MachineStatusInfo {
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek struct dual_timestamp timestamp;
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmekstatic void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
36f822c4bd077f9121757e24b6516e5c7ada63b5Zbigniew Jędrzejewski-Szmek char since2[FORMAT_TIMESTAMP_MAX], *s2;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (!sd_id128_equal(i->id, SD_ID128_NULL))
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id));
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp.realtime);
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering s2 = format_timestamp(since2, sizeof(since2), i->timestamp.realtime);
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering printf("\t Leader: %u", (unsigned) i->leader);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek printf("\t Service: %s", i->service);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek printf("\t Class: %s\n", i->class);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek printf("\t Root: %s\n", i->root_directory);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek for (c = 0; c < i->n_netif; c++) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek if (if_indextoname(i->netif[c], name)) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek print_addresses(bus, i->name, ifi,
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek print_os_release(bus, i->name, "\t OS: ");
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek printf("\t Unit: %s\n", i->unit);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek show_unit_cgroup(bus, i->unit, i->leader);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek if (arg_transport == BUS_TRANSPORT_LOCAL) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek get_output_flags() | OUTPUT_BEGIN_NEWLINE,
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmekstatic int map_netif(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek MachineStatusInfo *i = userdata;
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek assert_cc(sizeof(int32_t) == sizeof(int));
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek r = sd_bus_message_read_array(m, SD_BUS_TYPE_INT32, &v, &l);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek i->n_netif = l / sizeof(int32_t);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmekstatic int show_machine_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek static const struct bus_properties_map map[] = {
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek { "Name", "s", NULL, offsetof(MachineStatusInfo, name) },
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek { "Class", "s", NULL, offsetof(MachineStatusInfo, class) },
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek { "Service", "s", NULL, offsetof(MachineStatusInfo, service) },
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek { "Unit", "s", NULL, offsetof(MachineStatusInfo, unit) },
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek { "RootDirectory", "s", NULL, offsetof(MachineStatusInfo, root_directory) },
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek { "Leader", "u", NULL, offsetof(MachineStatusInfo, leader) },
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek { "Timestamp", "t", NULL, offsetof(MachineStatusInfo, timestamp.realtime) },
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek { "TimestampMonotonic", "t", NULL, offsetof(MachineStatusInfo, timestamp.monotonic) },
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek { "Id", "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek { "NetworkInterfaces", "ai", map_netif, 0 },
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek return log_error_errno(r, "Could not get properties: %m");
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek print_machine_status_info(bus, &info);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmekstatic int show_machine_properties(sd_bus *bus, const char *path, bool *new_line) {
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_all);
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering log_error_errno(r, "Could not get properties: %m");
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poetteringstatic int show_machine(int argc, char *argv[], void *userdata) {
dad29dff1925a114e20d4eb7b47fca23c4f25fd7Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek bool properties, new_line = false;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek properties = !strstr(argv[0], "status");
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek /* If no argument is specified, inspect the manager
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek r = show_machine_properties(bus, "/org/freedesktop/machine1", &new_line);
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek "org.freedesktop.machine1",
7449bc1f34c206e3ff8e274cd74e2db950d492a1Zbigniew Jędrzejewski-Szmek "org.freedesktop.machine1.Manager",
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = sd_bus_message_read(reply, "o", &path);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = show_machine_properties(bus, path, &new_line);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek r = show_machine_info(argv[0], bus, path, &new_line);
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmekstatic void print_image_status_info(sd_bus *bus, ImageStatusInfo *i) {
4015ac5c321f34784f73bd91ae9d7855ed663e5eLennart Poettering char ts_relative[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
29fc0ddcd737af906986d4029579d4dfe838ba02Zbigniew Jędrzejewski-Szmek char ts_absolute[FORMAT_TIMESTAMP_MAX], *s2;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek char bs_exclusive[FORMAT_BYTES_MAX], *s4;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek printf("\t Type: %s\n", i->type);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek printf("\t Path: %s\n", i->path);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek i->read_only ? ansi_highlight_red() : "",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek i->read_only ? "read-only" : "writable",
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek i->read_only ? ansi_highlight_off() : "");
722b6795655149a68277b3cffeba711e1d440e5aZbigniew Jędrzejewski-Szmek s1 = format_timestamp_relative(ts_relative, sizeof(ts_relative), i->crtime);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek s2 = format_timestamp(ts_absolute, sizeof(ts_absolute), i->crtime);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek printf("\t Created: %s; %s\n", s2, s1);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek s1 = format_timestamp_relative(ts_relative, sizeof(ts_relative), i->mtime);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek s2 = format_timestamp(ts_absolute, sizeof(ts_absolute), i->mtime);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek printf("\tModified: %s; %s\n", s2, s1);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek s3 = format_bytes(bs, sizeof(bs), i->size);
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek s4 = i->size_exclusive != i->size ? format_bytes(bs_exclusive, sizeof(bs_exclusive), i->size_exclusive) : NULL;
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek printf("\t Size: %s (exclusive: %s)\n", s3, s4);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek s3 = format_bytes(bs, sizeof(bs), i->limit);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek s4 = i->limit_exclusive != i->limit ? format_bytes(bs_exclusive, sizeof(bs_exclusive), i->limit_exclusive) : NULL;
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek printf("\t Limit: %s (exclusive: %s)\n", s3, s4);
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmekstatic int show_image_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek static const struct bus_properties_map map[] = {
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek { "Name", "s", NULL, offsetof(ImageStatusInfo, name) },
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek { "Path", "s", NULL, offsetof(ImageStatusInfo, path) },
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek { "Type", "s", NULL, offsetof(ImageStatusInfo, type) },
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek { "ReadOnly", "b", NULL, offsetof(ImageStatusInfo, read_only) },
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek { "CreationTimestamp", "t", NULL, offsetof(ImageStatusInfo, crtime) },
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek { "ModificationTimestamp", "t", NULL, offsetof(ImageStatusInfo, mtime) },
eacbb4d33e2bb5c54311544851140efe3dd0f774Zbigniew Jędrzejewski-Szmek { "Size", "t", NULL, offsetof(ImageStatusInfo, size) },
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek { "Limit", "t", NULL, offsetof(ImageStatusInfo, limit) },
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek { "SizeExclusive", "t", NULL, offsetof(ImageStatusInfo, size_exclusive) },
3d090cc6f34e5970765dd1e7ee5e648a056d180dZbigniew Jędrzejewski-Szmek { "LimitExclusive", "t", NULL, offsetof(ImageStatusInfo, limit_exclusive) },
path,
map,
&info);
if (*new_line)
*new_line = true;
if (*new_line)
*new_line = true;
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
&reply,
return bus_log_parse_error(r);
if (properties)
if (!arg_kill_who)
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
const char *object;
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
&reply,
return bus_log_parse_error(r);
r = sd_bus_get_property(
bus,
&error,
&reply2,
return bus_log_parse_error(r);
char *dest, *host_path, *container_path, *host_dirname, *host_basename, *container_dirname, *container_basename, *t;
bool copy_from;
return -EINVAL;
if (child < 0)
if (child == 0) {
int containerfd;
int mntfd;
if (mntfd < 0) {
if (containerfd < 0) {
if (copy_from)
return -EIO;
return -EIO;
const char *dest;
return -EINVAL;
return -ENOTSUP;
mount_slave_created = true;
goto finish;
mount_slave_mounted = true;
goto finish;
goto finish;
mount_tmp_created = true;
goto finish;
mount_tmp_mounted = true;
if (arg_read_only)
goto finish;
goto finish;
mount_outside_created = true;
goto finish;
mount_outside_mounted = true;
mount_tmp_mounted = false;
mount_tmp_created = false;
mount_slave_mounted = false;
mount_slave_created = false;
if (child < 0) {
goto finish;
if (child == 0) {
const char *mount_inside;
int mntfd;
if (mntfd < 0) {
if (arg_mkdir)
goto finish;
r = -EIO;
goto finish;
r = -EIO;
goto finish;
if (mount_tmp_mounted)
if (mount_tmp_created)
if (mount_slave_mounted)
if (mount_slave_created)
static int on_machine_removed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
assert(m);
if (*forward) {
char last_char = 0;
bool machine_died;
return -ENOTSUP;
"path='/org/freedesktop/machine1',",
"/org/freedesktop/machine1",
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_parse_error(r);
if (machine_died)
return ret;
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
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);
" 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;
return -EINVAL;
log_open();
goto finish;
goto finish;
pager_close();