machinectl.c revision c19de71113f956809995fc68817e055e9f61f607
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering/***
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering This file is part of systemd.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Copyright 2013 Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is free software; you can redistribute it and/or modify it
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering under the terms of the GNU Lesser General Public License as published by
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering (at your option) any later version.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering systemd is distributed in the hope that it will be useful, but
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering Lesser General Public License for more details.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering You should have received a copy of the GNU Lesser General Public License
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering***/
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
8bdbb8d9cbe1d35708385573d70984ab4533812dLennart Poettering#include <sys/socket.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <unistd.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <errno.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <string.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <getopt.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <pwd.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <locale.h>
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering#include <fcntl.h>
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering#include <netinet/in.h>
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering#include <arpa/inet.h>
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering#include <net/if.h>
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering#include <sys/mount.h>
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering#include <libgen.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#undef basename
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#include "sd-bus.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "log.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "macro.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "pager.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#include "spawn-polkit-agent.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#include "bus-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "bus-error.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "build.h"
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#include "strv.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "unit-name.h"
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering#include "cgroup-show.h"
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering#include "logs-show.h"
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering#include "cgroup-util.h"
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering#include "ptyfwd.h"
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering#include "event-util.h"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering#include "path-util.h"
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering#include "mkdir.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "copy.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "verbs.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic char **arg_property = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_all = false;
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersenstatic bool arg_full = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_no_pager = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_legend = true;
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poetteringstatic const char *arg_kill_who = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int arg_signal = SIGTERM;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic char *arg_host = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_read_only = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_mkdir = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_quiet = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_ask_password = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic unsigned arg_lines = 10;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic OutputMode arg_output = OUTPUT_SHORT;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void pager_open_if_enabled(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_no_pager)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen pager_open(false);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic void polkit_agent_open_if_enabled(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Open the polkit agent as a child process if necessary */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (!arg_ask_password)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_transport != BUS_TRANSPORT_LOCAL)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen polkit_agent_open();
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic OutputFlags get_output_flags(void) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen arg_all * OUTPUT_SHOW_ALL |
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen arg_full * OUTPUT_FULL_WIDTH |
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen (!on_tty() || pager_have()) * OUTPUT_FULL_WIDTH |
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen on_tty() * OUTPUT_COLOR |
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering !arg_quiet * OUTPUT_WARN_CUTOFF;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersentypedef struct MachineInfo {
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen const char *name;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *class;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen const char *service;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen} MachineInfo;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int compare_machine_info(const void *a, const void *b) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen const MachineInfo *x = a, *y = b;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return strcmp(x->name, y->name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int list_machines(int argc, char *argv[], void *userdata) {
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen size_t max_name = strlen("MACHINE"), max_class = strlen("CLASS"), max_service = strlen("SERVICE");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering _cleanup_free_ MachineInfo *machines = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *name, *class, *service, *object;
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen size_t n_machines = 0, n_allocated = 0, j;
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen sd_bus *bus = userdata;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering pager_open_if_enabled();
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_bus_call_method(
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering bus,
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering "org.freedesktop.machine1",
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering "/org/freedesktop/machine1",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "org.freedesktop.machine1.Manager",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "ListMachines",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering &error,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering &reply,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_error("Could not get machines: %s", bus_error_message(&error, -r));
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssso)");
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return bus_log_parse_error(r);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering while ((r = sd_bus_message_read(reply, "(ssso)", &name, &class, &service, &object)) > 0) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering size_t l;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (!GREEDY_REALLOC(machines, n_allocated, n_machines + 1))
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return log_oom();
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering machines[n_machines].name = name;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering machines[n_machines].class = class;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering machines[n_machines].service = service;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering l = strlen(name);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (l > max_name)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering max_name = l;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering l = strlen(class);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (l > max_class)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering max_class = l;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering l = strlen(service);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (l > max_service)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering max_service = l;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering n_machines ++;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return bus_log_parse_error(r);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_bus_message_exit_container(reply);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (r < 0)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return bus_log_parse_error(r);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering qsort_safe(machines, n_machines, sizeof(MachineInfo), compare_machine_info);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (arg_legend)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("%-*s %-*s %-*s\n",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering (int) max_name, "MACHINE",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering (int) max_class, "CLASS",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering (int) max_service, "SERVICE");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering for (j = 0; j < n_machines; j++)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("%-*s %-*s %-*s\n",
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering (int) max_name, machines[j].name,
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering (int) max_class, machines[j].class,
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering (int) max_service, machines[j].service);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (arg_legend)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering printf("\n%zu machines listed.\n", n_machines);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return 0;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering}
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringtypedef struct ImageInfo {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering const char *name;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering const char *type;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering bool read_only;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering usec_t crtime;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering usec_t mtime;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering uint64_t size;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering} ImageInfo;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poetteringstatic int compare_image_info(const void *a, const void *b) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering const ImageInfo *x = a, *y = b;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return strcmp(x->name, y->name);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringstatic int list_images(int argc, char *argv[], void *userdata) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering size_t max_name = strlen("NAME"), max_type = strlen("TYPE"), max_size = strlen("USAGE"), max_crtime = strlen("CREATED"), max_mtime = strlen("MODIFIED");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering _cleanup_free_ ImageInfo *images = NULL;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering size_t n_images = 0, n_allocated = 0, j;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering const char *name, *type, *object;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering sd_bus *bus = userdata;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering uint64_t crtime, mtime, size;
6389e747d5b09b18e00d85b9b13c1be2ff884015Lennart Poettering int read_only, r;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering assert(bus);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering pager_open_if_enabled();
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_bus_call_method(
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering bus,
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering "org.freedesktop.machine1",
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering "/org/freedesktop/machine1",
8937e7b68940d0fa0d0aab90eb7425fa7dccebc9Lennart Poettering "org.freedesktop.machine1.Manager",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "ListImages",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering &error,
8937e7b68940d0fa0d0aab90eb7425fa7dccebc9Lennart Poettering &reply,
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering "");
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (r < 0) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_error("Could not get images: %s", bus_error_message(&error, -r));
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssbttto)");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return bus_log_parse_error(r);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering while ((r = sd_bus_message_read(reply, "(ssbttto)", &name, &type, &read_only, &crtime, &mtime, &size, &object)) > 0) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering char buf[MAX(FORMAT_TIMESTAMP_MAX, FORMAT_BYTES_MAX)];
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering size_t l;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (name[0] == '.' && !arg_all)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen continue;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (!GREEDY_REALLOC(images, n_allocated, n_images + 1))
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return log_oom();
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering images[n_images].name = name;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering images[n_images].type = type;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering images[n_images].read_only = read_only;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering images[n_images].crtime = crtime;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering images[n_images].mtime = mtime;
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering images[n_images].size = size;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering l = strlen(name);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (l > max_name)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering max_name = l;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering l = strlen(type);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering if (l > max_type)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering max_type = l;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (crtime != 0) {
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering l = strlen(strna(format_timestamp(buf, sizeof(buf), crtime)));
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering if (l > max_crtime)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering max_crtime = l;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (mtime != 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen l = strlen(strna(format_timestamp(buf, sizeof(buf), mtime)));
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (l > max_mtime)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering max_mtime = l;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering }
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering if (size != (uint64_t) -1) {
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering l = strlen(strna(format_bytes(buf, sizeof(buf), size)));
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (l > max_size)
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering max_size = l;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering }
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering n_images++;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering }
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering if (r < 0)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return bus_log_parse_error(r);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = sd_bus_message_exit_container(reply);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return bus_log_parse_error(r);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering qsort_safe(images, n_images, sizeof(ImageInfo), compare_image_info);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (arg_legend)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering printf("%-*s %-*s %-3s %-*s %-*s %-*s\n",
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering (int) max_name, "NAME",
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering (int) max_type, "TYPE",
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering "RO",
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering (int) max_size, "USAGE",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering (int) max_crtime, "CREATED",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering (int) max_mtime, "MODIFIED");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering for (j = 0; j < n_images; j++) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering char crtime_buf[FORMAT_TIMESTAMP_MAX], mtime_buf[FORMAT_TIMESTAMP_MAX], size_buf[FORMAT_BYTES_MAX];
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering printf("%-*s %-*s %s%-3s%s %-*s %-*s %-*s\n",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering (int) max_name, images[j].name,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering (int) max_type, images[j].type,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering images[j].read_only ? ansi_highlight_red() : "", yes_no(images[j].read_only), images[j].read_only ? ansi_highlight_off() : "",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering (int) max_size, strna(format_bytes(size_buf, sizeof(size_buf), images[j].size)),
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering (int) max_crtime, strna(format_timestamp(crtime_buf, sizeof(crtime_buf), images[j].crtime)),
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering (int) max_mtime, strna(format_timestamp(mtime_buf, sizeof(mtime_buf), images[j].mtime)));
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (arg_legend)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering printf("\n%zu images listed.\n", n_images);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 0;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringstatic int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering _cleanup_free_ char *path = NULL;
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering const char *cgroup;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering int r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering unsigned c;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(bus);
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering assert(unit);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (arg_transport == BUS_TRANSPORT_REMOTE)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 0;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering path = unit_dbus_path_from_name(unit);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (!path)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return log_oom();
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering r = sd_bus_get_property(
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering bus,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "org.freedesktop.systemd1",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering path,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering endswith(unit, ".scope") ? "org.freedesktop.systemd1.Scope" : "org.freedesktop.systemd1.Service",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "ControlGroup",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering &error,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering &reply,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "s");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_error("Failed to query ControlGroup: %s", bus_error_message(&error, -r));
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_message_read(reply, "s", &cgroup);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return bus_log_parse_error(r);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (isempty(cgroup))
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 0;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, false) != 0 && leader <= 0)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return 0;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering c = columns();
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (c > 18)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering c -= 18;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering else
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering c = 0;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, get_output_flags());
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return 0;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering}
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poetteringstatic int print_addresses(sd_bus *bus, const char *name, int ifi, const char *prefix, const char *prefix2) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering int r;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(bus);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(name);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(prefix);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(prefix2);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = sd_bus_call_method(bus,
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "org.freedesktop.machine1",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "/org/freedesktop/machine1",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "org.freedesktop.machine1.Manager",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "GetMachineAddresses",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering NULL,
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering &reply,
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "s", name);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (r < 0)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return r;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(iay)");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (r < 0)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return bus_log_parse_error(r);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering int family;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering const void *a;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering size_t sz;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering char buffer[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)];
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_read(reply, "i", &family);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return bus_log_parse_error(r);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = sd_bus_message_read_array(reply, 'y', &a, &sz);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (r < 0)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return bus_log_parse_error(r);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fputs(prefix, stdout);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fputs(inet_ntop(family, a, buffer, sizeof(buffer)), stdout);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (family == AF_INET6 && ifi > 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("%%%i", ifi);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fputc('\n', stdout);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_exit_container(reply);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return bus_log_parse_error(r);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (prefix != prefix2)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering prefix = prefix2;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return bus_log_parse_error(r);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_exit_container(reply);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return bus_log_parse_error(r);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int print_os_release(sd_bus *bus, const char *name, const char *prefix) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *k, *v, *pretty = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(prefix);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_call_method(bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/org/freedesktop/machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1.Manager",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "GetMachineOSRelease",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering &reply,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "s", name);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "{ss}");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return bus_log_parse_error(r);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering while ((r = sd_bus_message_read(reply, "{ss}", &k, &v)) > 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (streq(k, "PRETTY_NAME"))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pretty = v;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return bus_log_parse_error(r);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering r = sd_bus_message_exit_container(reply);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (r < 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return bus_log_parse_error(r);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (pretty)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering printf("%s%s\n", prefix, pretty);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return 0;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering}
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poetteringtypedef struct MachineStatusInfo {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering char *name;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering sd_id128_t id;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering char *class;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering char *service;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering char *unit;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering char *root_directory;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering pid_t leader;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering struct dual_timestamp timestamp;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering int *netif;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering unsigned n_netif;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering} MachineStatusInfo;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringstatic void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering char since2[FORMAT_TIMESTAMP_MAX], *s2;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering int ifi = -1;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering assert(bus);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering assert(i);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fputs(strna(i->name), stdout);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (!sd_id128_equal(i->id, SD_ID128_NULL))
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id));
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering else
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering putchar('\n');
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp.realtime);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering s2 = format_timestamp(since2, sizeof(since2), i->timestamp.realtime);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (s1)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering printf("\t Since: %s; %s\n", s2, s1);
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek else if (s2)
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek printf("\t Since: %s\n", s2);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (i->leader > 0) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering _cleanup_free_ char *t = NULL;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering printf("\t Leader: %u", (unsigned) i->leader);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering get_process_comm(i->leader, &t);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (t)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering printf(" (%s)", t);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
a6c616024db23fef34152c1432892824a07799ccLennart Poettering putchar('\n');
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (i->service) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering printf("\t Service: %s", i->service);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (i->class)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering printf("; class %s", i->class);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering putchar('\n');
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering } else if (i->class)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers printf("\t Class: %s\n", i->class);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
a6c616024db23fef34152c1432892824a07799ccLennart Poettering if (i->root_directory)
a6c616024db23fef34152c1432892824a07799ccLennart Poettering printf("\t Root: %s\n", i->root_directory);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (i->n_netif > 0) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering unsigned c;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fputs("\t Iface:", stdout);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (c = 0; c < i->n_netif; c++) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers char name[IF_NAMESIZE+1] = "";
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (if_indextoname(i->netif[c], name)) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers fputc(' ', stdout);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers fputs(name, stdout);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (ifi < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ifi = i->netif[c];
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ifi = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf(" %i", i->netif[c]);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers fputc('\n', stdout);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering print_addresses(bus, i->name, ifi,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "\t Address: ",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "\t ");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers print_os_release(bus, i->name, "\t OS: ");
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (i->unit) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\t Unit: %s\n", i->unit);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers show_unit_cgroup(bus, i->unit, i->leader);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (arg_transport == BUS_TRANSPORT_LOCAL) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering show_journal_by_unit(
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering stdout,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers i->unit,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers arg_output,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering 0,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers i->timestamp.monotonic,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen arg_lines,
27e72d6b22890ba4a8cbc05c49667cd1cccf1461Simon Peeters 0,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen get_output_flags() | OUTPUT_BEGIN_NEWLINE,
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt SD_JOURNAL_LOCAL_ONLY,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering true,
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering}
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int map_netif(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering MachineStatusInfo *i = userdata;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers size_t l;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering const void *v;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_cc(sizeof(int32_t) == sizeof(int));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_read_array(m, SD_BUS_TYPE_INT32, &v, &l);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r == 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EBADMSG;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen i->n_netif = l / sizeof(int32_t);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers i->netif = memdup(v, l);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!i->netif)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -ENOMEM;
8c841f21f5042b11acc91cc1b039cb162cbbe8f4Djalal Harouni
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int show_machine_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering static const struct bus_properties_map map[] = {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen { "Name", "s", NULL, offsetof(MachineStatusInfo, name) },
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen { "Class", "s", NULL, offsetof(MachineStatusInfo, class) },
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen { "Service", "s", NULL, offsetof(MachineStatusInfo, service) },
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen { "Unit", "s", NULL, offsetof(MachineStatusInfo, unit) },
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen { "RootDirectory", "s", NULL, offsetof(MachineStatusInfo, root_directory) },
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen { "Leader", "u", NULL, offsetof(MachineStatusInfo, leader) },
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen { "Timestamp", "t", NULL, offsetof(MachineStatusInfo, timestamp.realtime) },
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen { "TimestampMonotonic", "t", NULL, offsetof(MachineStatusInfo, timestamp.monotonic) },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "Id", "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen { "NetworkInterfaces", "ai", map_netif, 0 },
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen {}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen };
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen MachineStatusInfo info = {};
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen int r;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering assert(verb);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(bus);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers assert(path);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(new_line);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = bus_map_all_properties(bus,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering "org.freedesktop.machine1",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering path,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering map,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering &info);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return log_error_errno(r, "Could not get properties: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (*new_line)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\n");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering *new_line = true;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering print_machine_status_info(bus, &info);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering free(info.name);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering free(info.class);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering free(info.service);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering free(info.unit);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering free(info.root_directory);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering free(info.netif);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering}
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poetteringstatic int show_machine_properties(sd_bus *bus, const char *path, bool *new_line) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(bus);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(path);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(new_line);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (*new_line)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\n");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering *new_line = true;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_all);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_error_errno(r, "Could not get properties: %m");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering}
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poetteringstatic int show_machine(int argc, char *argv[], void *userdata) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering bool properties, new_line = false;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering sd_bus *bus = userdata;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int r = 0, i;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(bus);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering properties = !strstr(argv[0], "status");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering pager_open_if_enabled();
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (properties && argc <= 1) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering /* If no argument is specified, inspect the manager
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering * itself */
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = show_machine_properties(bus, "/org/freedesktop/machine1", &new_line);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering for (i = 1; i < argc; i++) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering const char *path = NULL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = sd_bus_call_method(
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering bus,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering "org.freedesktop.machine1",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering "/org/freedesktop/machine1",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering "org.freedesktop.machine1.Manager",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering "GetMachine",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering &error,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering &reply,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering "s", argv[i]);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r < 0) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = sd_bus_message_read(reply, "o", &path);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r < 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return bus_log_parse_error(r);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (properties)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = show_machine_properties(bus, path, &new_line);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering else
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering r = show_machine_info(argv[0], bus, path, &new_line);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering}
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poetteringtypedef struct ImageStatusInfo {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering char *name;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering char *path;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering char *type;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int read_only;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering usec_t crtime;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering usec_t mtime;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering uint64_t usage;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering uint64_t limit;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering uint64_t usage_exclusive;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering uint64_t limit_exclusive;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering} ImageStatusInfo;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poetteringstatic void print_image_status_info(sd_bus *bus, ImageStatusInfo *i) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering char ts_relative[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering char ts_absolute[FORMAT_TIMESTAMP_MAX], *s2;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering char bs[FORMAT_BYTES_MAX], *s3;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering char bs_exclusive[FORMAT_BYTES_MAX], *s4;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(bus);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(i);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (i->name) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering fputs(i->name, stdout);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering putchar('\n');
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (i->type)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\t Type: %s\n", i->type);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (i->path)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\t Path: %s\n", i->path);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\t RO: %s%s%s\n",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering i->read_only ? ansi_highlight_red() : "",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering i->read_only ? "read-only" : "writable",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering i->read_only ? ansi_highlight_off() : "");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering s1 = format_timestamp_relative(ts_relative, sizeof(ts_relative), i->crtime);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering s2 = format_timestamp(ts_absolute, sizeof(ts_absolute), i->crtime);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s1 && s2)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\t Created: %s; %s\n", s2, s1);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering else if (s2)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\t Created: %s\n", s2);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering s1 = format_timestamp_relative(ts_relative, sizeof(ts_relative), i->mtime);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering s2 = format_timestamp(ts_absolute, sizeof(ts_absolute), i->mtime);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s1 && s2)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\tModified: %s; %s\n", s2, s1);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering else if (s2)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\tModified: %s\n", s2);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering s3 = format_bytes(bs, sizeof(bs), i->usage);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering s4 = i->usage_exclusive != i->usage ? format_bytes(bs_exclusive, sizeof(bs_exclusive), i->usage_exclusive) : NULL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s3 && s4)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\t Usage: %s (exclusive: %s)\n", s3, s4);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering else if (s3)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\t Usage: %s\n", s3);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering s3 = format_bytes(bs, sizeof(bs), i->limit);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering s4 = i->limit_exclusive != i->limit ? format_bytes(bs_exclusive, sizeof(bs_exclusive), i->limit_exclusive) : NULL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (s3 && s4)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\t Limit: %s (exclusive: %s)\n", s3, s4);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering else if (s3)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering printf("\t Limit: %s\n", s3);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sieversstatic int show_image_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering static const struct bus_properties_map map[] = {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "Name", "s", NULL, offsetof(ImageStatusInfo, name) },
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen { "Path", "s", NULL, offsetof(ImageStatusInfo, path) },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "Type", "s", NULL, offsetof(ImageStatusInfo, type) },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "ReadOnly", "b", NULL, offsetof(ImageStatusInfo, read_only) },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "CreationTimestamp", "t", NULL, offsetof(ImageStatusInfo, crtime) },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "ModificationTimestamp", "t", NULL, offsetof(ImageStatusInfo, mtime) },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "Usage", "t", NULL, offsetof(ImageStatusInfo, usage) },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "Limit", "t", NULL, offsetof(ImageStatusInfo, limit) },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "UsageExclusive", "t", NULL, offsetof(ImageStatusInfo, usage_exclusive) },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "LimitExclusive", "t", NULL, offsetof(ImageStatusInfo, limit_exclusive) },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering {}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering };
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen ImageStatusInfo info = {};
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering int r;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(verb);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(bus);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(path);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(new_line);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = bus_map_all_properties(bus,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "org.freedesktop.machine1",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen path,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering map,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen &info);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Could not get properties: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (*new_line)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\n");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering *new_line = true;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering print_image_status_info(bus, &info);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering free(info.name);
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering free(info.path);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering free(info.type);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering return r;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int show_image_properties(sd_bus *bus, const char *path, bool *new_line) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(bus);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering assert(path);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(new_line);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering if (*new_line)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering printf("\n");
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering *new_line = true;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_all);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering if (r < 0)
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering log_error_errno(r, "Could not get properties: %m");
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering return r;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering}
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poetteringstatic int show_image(int argc, char *argv[], void *userdata) {
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering bool properties, new_line = false;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering sd_bus *bus = userdata;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering int r = 0, i;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering assert(bus);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering properties = !strstr(argv[0], "status");
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering pager_open_if_enabled();
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (properties && argc <= 1) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* If no argument is specified, inspect the manager
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering * itself */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = show_image_properties(bus, "/org/freedesktop/machine1", &new_line);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering for (i = 1; i < argc; i++) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering const char *path = NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = sd_bus_call_method(
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering bus,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering "org.freedesktop.machine1",
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering "/org/freedesktop/machine1",
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering "org.freedesktop.machine1.Manager",
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering "GetImage",
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering &error,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering &reply,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering "s", argv[i]);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error("Could not get path to image: %s", bus_error_message(&error, -r));
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = sd_bus_message_read(reply, "o", &path);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return bus_log_parse_error(r);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (properties)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = show_image_properties(bus, path, &new_line);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering else
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = show_image_info(argv[0], bus, path, &new_line);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering}
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int kill_machine(int argc, char *argv[], void *userdata) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering sd_bus *bus = userdata;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int i;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering assert(bus);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering polkit_agent_open_if_enabled();
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (!arg_kill_who)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering arg_kill_who = "all";
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering for (i = 1; i < argc; i++) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering int r;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering r = sd_bus_call_method(
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering bus,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "org.freedesktop.machine1",
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "/org/freedesktop/machine1",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "org.freedesktop.machine1.Manager",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "KillMachine",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering &error,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering NULL,
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "ssi", argv[i], arg_kill_who, arg_signal);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (r < 0) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error("Could not kill machine: %s", bus_error_message(&error, -r));
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return r;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return 0;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering}
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poetteringstatic int reboot_machine(int argc, char *argv[], void *userdata) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering arg_kill_who = "leader";
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering arg_signal = SIGINT; /* sysvinit + systemd */
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return kill_machine(argc, argv, userdata);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering}
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poetteringstatic int poweroff_machine(int argc, char *argv[], void *userdata) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering arg_kill_who = "leader";
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering arg_signal = SIGRTMIN+4; /* only systemd */
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return kill_machine(argc, argv, userdata);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering}
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poetteringstatic int terminate_machine(int argc, char *argv[], void *userdata) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering sd_bus *bus = userdata;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering int i;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering assert(bus);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering polkit_agent_open_if_enabled();
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering for (i = 1; i < argc; i++) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering int r;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering r = sd_bus_call_method(
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering bus,
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "org.freedesktop.machine1",
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "/org/freedesktop/machine1",
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "org.freedesktop.machine1.Manager",
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "TerminateMachine",
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering &error,
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering NULL,
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "s", argv[i]);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (r < 0) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error("Could not terminate machine: %s", bus_error_message(&error, -r));
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return r;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return 0;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering}
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poetteringstatic int machine_get_leader(sd_bus *bus, const char *name, pid_t *ret) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *reply2 = NULL;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering const char *object;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering uint32_t leader;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering int r;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering assert(bus);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering assert(name);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering assert(ret);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering r = sd_bus_call_method(
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering bus,
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "org.freedesktop.machine1",
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "/org/freedesktop/machine1",
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "org.freedesktop.machine1.Manager",
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "GetMachine",
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering &error,
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering &reply,
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "s", name);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (r < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = sd_bus_message_read(reply, "o", &object);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return bus_log_parse_error(r);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = sd_bus_get_property(
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering bus,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "org.freedesktop.machine1",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering object,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering "org.freedesktop.machine1.Machine",
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering "Leader",
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering &error,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering &reply2,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "u");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return log_error_errno(r, "Failed to retrieve PID of leader: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = sd_bus_message_read(reply2, "u", &leader);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return bus_log_parse_error(r);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering *ret = leader;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return 0;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering}
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int copy_files(int argc, char *argv[], void *userdata) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering char *dest, *host_path, *container_path, *host_dirname, *host_basename, *container_dirname, *container_basename, *t;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_close_ int hostfd = -1;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering sd_bus *bus = userdata;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering pid_t child, leader;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering bool copy_from;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering siginfo_t si;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering assert(bus);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering copy_from = streq(argv[0], "copy-from");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering dest = argv[3] ?: argv[2];
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering host_path = strdupa(copy_from ? dest : argv[2]);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering container_path = strdupa(copy_from ? argv[2] : dest);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (!path_is_absolute(container_path)) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error("Container path not absolute.");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return -EINVAL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering t = strdupa(host_path);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering host_basename = basename(t);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering host_dirname = dirname(host_path);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering t = strdupa(container_path);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering container_basename = basename(t);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering container_dirname = dirname(container_path);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = machine_get_leader(bus, argv[1], &leader);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering hostfd = open(host_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return log_error_errno(errno, "Failed to open source directory: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering child = fork();
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (child < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return log_error_errno(errno, "Failed to fork(): %m");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (child == 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int containerfd;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering const char *q;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int mntfd;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering q = procfs_file_alloca(leader, "ns/mnt");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (mntfd < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error_errno(errno, "Failed to open mount namespace of leader: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _exit(EXIT_FAILURE);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (setns(mntfd, CLONE_NEWNS) < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error_errno(errno, "Failed to join namespace of leader: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _exit(EXIT_FAILURE);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering containerfd = open(container_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (containerfd < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error_errno(errno, "Failed top open destination directory: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _exit(EXIT_FAILURE);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (copy_from)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = copy_tree_at(containerfd, container_basename, hostfd, host_basename, true);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering else
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = copy_tree_at(hostfd, host_basename, containerfd, container_basename, true);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error_errno(errno, "Failed to copy tree: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _exit(EXIT_FAILURE);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _exit(EXIT_SUCCESS);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = wait_for_terminate(child, &si);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return log_error_errno(r, "Failed to wait for client: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (si.si_code != CLD_EXITED) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error("Client died abnormally.");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return -EIO;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (si.si_status != EXIT_SUCCESS)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return -EIO;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return 0;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering}
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int bind_mount(int argc, char *argv[], void *userdata) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering char mount_slave[] = "/tmp/propagate.XXXXXX", *mount_tmp, *mount_outside, *p;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering sd_bus *bus = userdata;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering pid_t child, leader;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering const char *dest;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering siginfo_t si;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering bool mount_slave_created = false, mount_slave_mounted = false,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_tmp_created = false, mount_tmp_mounted = false,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_outside_created = false, mount_outside_mounted = false;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering assert(bus);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* One day, when bind mounting /proc/self/fd/n works across
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering * namespace boundaries we should rework this logic to make
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering * use of it... */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering dest = argv[3] ?: argv[2];
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (!path_is_absolute(dest)) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error("Destination path not absolute.");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return -EINVAL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering p = strappenda("/run/systemd/nspawn/propagate/", argv[1], "/");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (access(p, F_OK) < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error("Container does not allow propagation of mount points.");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return -ENOTSUP;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = machine_get_leader(bus, argv[1], &leader);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* Our goal is to install a new bind mount into the container,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering possibly read-only. This is irritatingly complex
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering unfortunately, currently.
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering First, we start by creating a private playground in /tmp,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering that we can mount MS_SLAVE. (Which is necessary, since
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering MS_MOUNT cannot be applied to mounts with MS_SHARED parent
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mounts.) */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (!mkdtemp(mount_slave))
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return log_error_errno(errno, "Failed to create playground: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_slave_created = true;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (mount(mount_slave, mount_slave, NULL, MS_BIND, NULL) < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = log_error_errno(errno, "Failed to make bind mount: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto finish;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_slave_mounted = true;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (mount(NULL, mount_slave, NULL, MS_SLAVE, NULL) < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = log_error_errno(errno, "Failed to remount slave: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto finish;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* Second, we mount the source directory to a directory inside
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering of our MS_SLAVE playground. */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_tmp = strappenda(mount_slave, "/mount");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (mkdir(mount_tmp, 0700) < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = log_error_errno(errno, "Failed to create temporary mount: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto finish;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering mount_tmp_created = true;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering if (mount(argv[2], mount_tmp, NULL, MS_BIND, NULL) < 0) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = log_error_errno(errno, "Failed to overmount: %m");
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering goto finish;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering }
bf441e3d9371a7e5aa1def66cfc40f0118884644Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering mount_tmp_mounted = true;
c7b7d4493aa03e9ef5fb1e670b8969a48aa494ddLennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering /* Third, we remount the new bind mount read-only if requested. */
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (arg_read_only)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (mount(NULL, mount_tmp, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
bf441e3d9371a7e5aa1def66cfc40f0118884644Lennart Poettering r = log_error_errno(errno, "Failed to mark read-only: %m");
de33fc625725d199629ed074d6278504deb23debLennart Poettering goto finish;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering /* Fourth, we move the new bind mount into the propagation
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering * directory. This way it will appear there read-only
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering * right-away. */
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt mount_outside = strappenda("/run/systemd/nspawn/propagate/", argv[1], "/XXXXXX");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering if (!mkdtemp(mount_outside)) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = log_error_errno(errno, "Cannot create propagation directory: %m");
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt goto finish;
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt }
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering mount_outside_created = true;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering if (mount(mount_tmp, mount_outside, NULL, MS_MOVE, NULL) < 0) {
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering r = log_error_errno(errno, "Failed to move: %m");
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering goto finish;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering }
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering mount_outside_mounted = true;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering mount_tmp_mounted = false;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering (void) rmdir(mount_tmp);
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering mount_tmp_created = false;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering (void) umount(mount_slave);
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering mount_slave_mounted = false;
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering (void) rmdir(mount_slave);
d04c1fb8e215600b4950c6778c6c16ddafc14024Lennart Poettering mount_slave_created = false;
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering child = fork();
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (child < 0) {
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering r = log_error_errno(errno, "Failed to fork(): %m");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering goto finish;
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering }
40205d706e1210763ff4c98a317556375bd04bcdLennart Poettering
ee451d766a64117a41ec36dd71e61683c9d9b83cLennart Poettering if (child == 0) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering const char *mount_inside;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering int mntfd;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering const char *q;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering q = procfs_file_alloca(leader, "ns/mnt");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (mntfd < 0) {
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering log_error_errno(errno, "Failed to open mount namespace of leader: %m");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering _exit(EXIT_FAILURE);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering }
9b15b7846d4de01bb5d9700a24077787e984e8abLennart Poettering
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (setns(mntfd, CLONE_NEWNS) < 0) {
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt log_error_errno(errno, "Failed to join namespace of leader: %m");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering _exit(EXIT_FAILURE);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering }
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (arg_mkdir)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering mkdir_p(dest, 0755);
c7b7d4493aa03e9ef5fb1e670b8969a48aa494ddLennart Poettering
c7b7d4493aa03e9ef5fb1e670b8969a48aa494ddLennart Poettering /* Fifth, move the mount to the right place inside */
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering mount_inside = strappenda("/run/systemd/nspawn/incoming/", basename(mount_outside));
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering if (mount(mount_inside, dest, NULL, MS_MOVE, NULL) < 0) {
c7b7d4493aa03e9ef5fb1e670b8969a48aa494ddLennart Poettering log_error_errno(errno, "Failed to mount: %m");
c7b7d4493aa03e9ef5fb1e670b8969a48aa494ddLennart Poettering _exit(EXIT_FAILURE);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _exit(EXIT_SUCCESS);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering }
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = wait_for_terminate(child, &si);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0) {
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering log_error_errno(r, "Failed to wait for client: %m");
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering goto finish;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering }
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (si.si_code != CLD_EXITED) {
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering log_error("Client died abnormally.");
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering r = -EIO;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering goto finish;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering }
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (si.si_status != EXIT_SUCCESS) {
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering r = -EIO;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering goto finish;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering }
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering r = 0;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poetteringfinish:
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (mount_outside_mounted)
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering umount(mount_outside);
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (mount_outside_created)
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering rmdir(mount_outside);
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (mount_tmp_mounted)
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering umount(mount_tmp);
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (mount_tmp_created)
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering umount(mount_tmp);
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering if (mount_slave_mounted)
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering umount(mount_slave);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (mount_slave_created)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering umount(mount_slave);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return r;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering}
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poetteringstatic int on_machine_removed(sd_bus *bus, sd_bus_message *m, void *userdata, sd_bus_error *ret_error) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering PTYForward ** forward = (PTYForward**) userdata;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering int r;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering assert(bus);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering assert(m);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering assert(forward);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (*forward) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering /* If the forwarder is already initialized, tell it to
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering * exit on the next vhangup(), so that we still flush
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering * out what might be queued and exit then. */
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering r = pty_forward_set_ignore_vhangup(*forward, false);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (r >= 0)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return 0;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error_errno(r, "Failed to set ignore_vhangup flag: %m");
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering /* On error, or when the forwarder is not initialized yet, quit immediately */
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering sd_event_exit(sd_bus_get_event(bus), EXIT_FAILURE);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poetteringstatic int login_machine(int argc, char *argv[], void *userdata) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering _cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering _cleanup_bus_slot_unref_ sd_bus_slot *slot = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_(pty_forward_freep) PTYForward *forward = NULL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering _cleanup_event_unref_ sd_event *event = NULL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering int master = -1, r, ret = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_bus *bus = userdata;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *pty, *match;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sigset_t mask;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char last_char = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bool machine_died;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(bus);
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_transport != BUS_TRANSPORT_LOCAL &&
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering arg_transport != BUS_TRANSPORT_MACHINE) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error("Login only supported on local machines.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ENOTSUP;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering polkit_agent_open_if_enabled();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_event_default(&event);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to get event loop: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen r = sd_bus_attach_event(bus, event, 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to attach bus to event loop: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering match = strappenda("type='signal',"
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering "sender='org.freedesktop.machine1',"
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering "path='/org/freedesktop/machine1',",
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering "interface='org.freedesktop.machine1.Manager',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "member='MachineRemoved',"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "arg0='",
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering argv[1],
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "'");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_add_match(bus, &slot, match, on_machine_removed, &forward);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek return log_error_errno(r, "Failed to add machine removal match: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_new_method_call(bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering &m,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "/org/freedesktop/machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1.Manager",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "OpenMachineLogin");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return bus_log_create_error(r);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering if (r < 0)
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering return bus_log_create_error(r);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering r = sd_bus_message_append(m, "s", argv[1]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return bus_log_create_error(r);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_call(bus, m, 0, &error, &reply);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to get machine PTY: %s", bus_error_message(&error, -r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_read(reply, "hs", &master, &pty);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return bus_log_parse_error(r);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sigemptyset(&mask) == 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sigset_add_many(&mask, SIGWINCH, SIGTERM, SIGINT, -1);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_info("Connected to machine %s. Press ^] three times within 1s to exit session.", argv[1]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen r = pty_forward_new(event, master, true, &forward);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to create PTY forwarder: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_event_loop(event);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_error_errno(r, "Failed to run event loop: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pty_forward_get_last_char(forward, &last_char);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering machine_died = pty_forward_get_ignore_vhangup(forward) == 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering forward = pty_forward_free(forward);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (last_char != '\n')
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering fputc('\n', stdout);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering if (machine_died)
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering log_info("Machine %s terminated.", argv[1]);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering else
de33fc625725d199629ed074d6278504deb23debLennart Poettering log_info("Connection to machine %s terminated.", argv[1]);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_event_get_exit_code(event, &ret);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return ret;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering}
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int remove_image(int argc, char *argv[], void *userdata) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering sd_bus *bus = userdata;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int r, i;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering assert(bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering polkit_agent_open_if_enabled();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering for (i = 1; i < argc; i++) {
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering r = sd_bus_call_method(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/org/freedesktop/machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1.Manager",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "RemoveImage",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering &error,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering NULL,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "s", argv[i]);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (r < 0) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_error("Could not remove image: %s", bus_error_message(&error, -r));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return 0;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering}
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int rename_image(int argc, char *argv[], void *userdata) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering sd_bus *bus = userdata;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering int r;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering polkit_agent_open_if_enabled();
086821244b5113f00a0ef993b78dc56aae2a8f6cLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = sd_bus_call_method(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "/org/freedesktop/machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1.Manager",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "RenameImage",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering &error,
249968612f16a71df909d6e73785c18a9ff36a65Lennart Poettering NULL,
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering "ss", argv[1], argv[2]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Could not rename image: %s", bus_error_message(&error, -r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int clone_image(int argc, char *argv[], void *userdata) {
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen sd_bus *bus = userdata;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt int r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen polkit_agent_open_if_enabled();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = sd_bus_call_method(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/org/freedesktop/machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1.Manager",
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering "CloneImage",
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering &error,
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering NULL,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "ssb", argv[1], argv[2], arg_read_only);
if (r < 0) {
log_error("Could not clone image: %s", bus_error_message(&error, -r));
return r;
}
return 0;
}
static int read_only_image(int argc, char *argv[], void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
sd_bus *bus = userdata;
int b = true, r;
if (argc > 2) {
b = parse_boolean(argv[2]);
if (b < 0) {
log_error("Failed to parse boolean argument: %s", argv[2]);
return -EINVAL;
}
}
polkit_agent_open_if_enabled();
r = sd_bus_call_method(
bus,
"org.freedesktop.machine1",
"/org/freedesktop/machine1",
"org.freedesktop.machine1.Manager",
"MarkImageReadOnly",
&error,
NULL,
"sb", argv[1], b);
if (r < 0) {
log_error("Could not mark image read-only: %s", bus_error_message(&error, -r));
return r;
}
return 0;
}
static int start_machine(int argc, char *argv[], void *userdata) {
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
_cleanup_(bus_wait_for_jobs_freep) BusWaitForJobs *w = NULL;
sd_bus *bus = userdata;
int r, i;
assert(bus);
polkit_agent_open_if_enabled();
r = bus_wait_for_jobs_new(bus, &w);
if (r < 0)
return log_oom();
for (i = 1; i < argc; i++) {
_cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
_cleanup_free_ char *e = NULL, *unit = NULL;
const char *object;
if (!machine_name_is_valid(argv[i])) {
log_error("Invalid machine name %s.", argv[i]);
return -EINVAL;
}
e = unit_name_escape(argv[i]);
if (!e)
return log_oom();
unit = unit_name_build("systemd-nspawn", e, ".service");
if (!unit)
return log_oom();
r = sd_bus_message_new_method_call(
bus,
&m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"StartUnit");
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_append(m, "ss", unit, "fail");
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) {
log_error("Failed to start unit: %s", bus_error_message(&error, -r));
return r;
}
r = sd_bus_message_read(reply, "o", &object);
if (r < 0)
return bus_log_parse_error(r);
r = bus_wait_for_jobs_add(w, object);
if (r < 0)
return log_oom();
}
r = bus_wait_for_jobs(w, arg_quiet);
if (r < 0)
return r;
return 0;
}
static int enable_machine(int argc, char *argv[], void *userdata) {
_cleanup_bus_message_unref_ sd_bus_message *m = NULL, *reply = NULL;
_cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
int carries_install_info = 0;
const char *method = NULL;
sd_bus *bus = userdata;
int r, i;
assert(bus);
polkit_agent_open_if_enabled();
method = streq(argv[0], "enable") ? "EnableUnitFiles" : "DisableUnitFiles";
r = sd_bus_message_new_method_call(
bus,
&m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
method);
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_open_container(m, 'a', "s");
if (r < 0)
return bus_log_create_error(r);
for (i = 1; i < argc; i++) {
_cleanup_free_ char *e = NULL, *unit = NULL;
if (!machine_name_is_valid(argv[i])) {
log_error("Invalid machine name %s.", argv[i]);
return -EINVAL;
}
e = unit_name_escape(argv[i]);
if (!e)
return log_oom();
unit = unit_name_build("systemd-nspawn", e, ".service");
if (!unit)
return log_oom();
r = sd_bus_message_append(m, "s", unit);
if (r < 0)
return bus_log_create_error(r);
}
r = sd_bus_message_close_container(m);
if (r < 0)
return bus_log_create_error(r);
if (streq(argv[0], "enable"))
r = sd_bus_message_append(m, "bb", false, false);
else
r = sd_bus_message_append(m, "b", false);
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_call(bus, m, 0, &error, &reply);
if (r < 0) {
log_error("Failed to enable or disable unit: %s", bus_error_message(&error, -r));
return r;
}
if (streq(argv[0], "enable")) {
r = sd_bus_message_read(reply, "b", carries_install_info);
if (r < 0)
return bus_log_parse_error(r);
}
r = bus_deserialize_and_dump_unit_file_changes(reply, arg_quiet);
if (r < 0)
return r;
m = sd_bus_message_unref(m);
r = sd_bus_message_new_method_call(
bus,
&m,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
"Reload");
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_message_set_allow_interactive_authorization(m, arg_ask_password);
if (r < 0)
return bus_log_create_error(r);
r = sd_bus_call(bus, m, 0, &error, NULL);
if (r < 0) {
log_error("Failed to reload daemon: %s", bus_error_message(&error, -r));
return r;
}
return 0;
}
static int help(int argc, char *argv[], void *userdata) {
printf("%s [OPTIONS...] {COMMAND} ...\n\n"
"Send control commands to or query the virtual machine and container\n"
"registration manager.\n\n"
" -h --help Show this help\n"
" --version Show package version\n"
" --no-pager Do not pipe output into a pager\n"
" --no-legend Do not show the headers and footers\n"
" --no-ask-password Do not ask for system passwords\n"
" -H --host=[USER@]HOST Operate on remote host\n"
" -M --machine=CONTAINER Operate on local container\n"
" -p --property=NAME Show only properties by this name\n"
" -q --quiet Suppress output\n"
" -a --all Show all properties, including empty ones\n"
" -l --full Do not ellipsize output\n"
" --kill-who=WHO Who to send signal to\n"
" -s --signal=SIGNAL Which signal to send\n"
" --read-only Create read-only bind mount\n"
" --mkdir Create directory before bind mounting, if missing\n"
" -n --lines=INTEGER Number of journal entries to show\n"
" -o --output=STRING Change journal output mode (short,\n"
" short-monotonic, verbose, export, json,\n"
" json-pretty, json-sse, cat)\n\n"
"Machine Commands:\n"
" list List running VMs and containers\n"
" status NAME... Show VM/container details\n"
" show NAME... Show properties of one or more VMs/containers\n"
" start NAME... Start container as a service\n"
" login NAME Get a login prompt on a container\n"
" enable NAME... Enable automatic container start at boot\n"
" disable NAME... Disable automatic container start at boot\n"
" poweroff NAME... Power off one or more containers\n"
" reboot NAME... Reboot one or more containers\n"
" terminate NAME... Terminate one or more VMs/containers\n"
" kill NAME... Send signal to processes of a VM/container\n"
" copy-to NAME PATH [PATH] Copy files from the host to a container\n"
" copy-from NAME PATH [PATH] Copy files from a container to the host\n"
" bind NAME PATH [PATH] Bind mount a path from the host into a container\n\n"
"Image Commands:\n"
" list-images Show available images\n"
" image-status NAME... Show image details\n"
" show-image NAME... Show properties of image\n"
" clone NAME NAME Clone an image\n"
" rename NAME NAME Rename an image\n"
" read-only NAME [BOOL] Mark or unmark image read-only\n"
" remove NAME... Remove an image\n"
, program_invocation_short_name);
return 0;
}
static int parse_argv(int argc, char *argv[]) {
enum {
ARG_VERSION = 0x100,
ARG_NO_PAGER,
ARG_NO_LEGEND,
ARG_KILL_WHO,
ARG_READ_ONLY,
ARG_MKDIR,
ARG_NO_ASK_PASSWORD,
};
static const struct option options[] = {
{ "help", no_argument, NULL, 'h' },
{ "version", no_argument, NULL, ARG_VERSION },
{ "property", required_argument, NULL, 'p' },
{ "all", no_argument, NULL, 'a' },
{ "full", no_argument, NULL, 'l' },
{ "no-pager", no_argument, NULL, ARG_NO_PAGER },
{ "no-legend", no_argument, NULL, ARG_NO_LEGEND },
{ "kill-who", required_argument, NULL, ARG_KILL_WHO },
{ "signal", required_argument, NULL, 's' },
{ "host", required_argument, NULL, 'H' },
{ "machine", required_argument, NULL, 'M' },
{ "read-only", no_argument, NULL, ARG_READ_ONLY },
{ "mkdir", no_argument, NULL, ARG_MKDIR },
{ "quiet", no_argument, NULL, 'q' },
{ "lines", required_argument, NULL, 'n' },
{ "output", required_argument, NULL, 'o' },
{ "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
{}
};
int c, r;
assert(argc >= 0);
assert(argv);
while ((c = getopt_long(argc, argv, "hp:als:H:M:qn:o:", options, NULL)) >= 0)
switch (c) {
case 'h':
return help(0, NULL, NULL);
case ARG_VERSION:
puts(PACKAGE_STRING);
puts(SYSTEMD_FEATURES);
return 0;
case 'p':
r = strv_extend(&arg_property, optarg);
if (r < 0)
return log_oom();
/* If the user asked for a particular
* property, show it to him, even if it is
* empty. */
arg_all = true;
break;
case 'a':
arg_all = true;
break;
case 'l':
arg_full = true;
break;
case 'n':
if (safe_atou(optarg, &arg_lines) < 0) {
log_error("Failed to parse lines '%s'", optarg);
return -EINVAL;
}
break;
case 'o':
arg_output = output_mode_from_string(optarg);
if (arg_output < 0) {
log_error("Unknown output '%s'.", optarg);
return -EINVAL;
}
break;
case ARG_NO_PAGER:
arg_no_pager = true;
break;
case ARG_NO_LEGEND:
arg_legend = false;
break;
case ARG_KILL_WHO:
arg_kill_who = optarg;
break;
case 's':
arg_signal = signal_from_string_try_harder(optarg);
if (arg_signal < 0) {
log_error("Failed to parse signal string %s.", optarg);
return -EINVAL;
}
break;
case ARG_NO_ASK_PASSWORD:
arg_ask_password = false;
break;
case 'H':
arg_transport = BUS_TRANSPORT_REMOTE;
arg_host = optarg;
break;
case 'M':
arg_transport = BUS_TRANSPORT_MACHINE;
arg_host = optarg;
break;
case ARG_READ_ONLY:
arg_read_only = true;
break;
case ARG_MKDIR:
arg_mkdir = true;
break;
case 'q':
arg_quiet = true;
break;
case '?':
return -EINVAL;
default:
assert_not_reached("Unhandled option");
}
return 1;
}
static int machinectl_main(int argc, char *argv[], sd_bus *bus) {
static const Verb verbs[] = {
{ "help", VERB_ANY, VERB_ANY, 0, help },
{ "list", VERB_ANY, 1, VERB_DEFAULT, list_machines },
{ "list-images", VERB_ANY, 1, 0, list_images },
{ "status", 2, VERB_ANY, 0, show_machine },
{ "image-status",2, VERB_ANY, 0, show_image },
{ "show", VERB_ANY, VERB_ANY, 0, show_machine },
{ "show-image", VERB_ANY, VERB_ANY, 0, show_image },
{ "terminate", 2, VERB_ANY, 0, terminate_machine },
{ "reboot", 2, VERB_ANY, 0, reboot_machine },
{ "poweroff", 2, VERB_ANY, 0, poweroff_machine },
{ "kill", 2, VERB_ANY, 0, kill_machine },
{ "login", 2, 2, 0, login_machine },
{ "bind", 3, 4, 0, bind_mount },
{ "copy-to", 3, 4, 0, copy_files },
{ "copy-from", 3, 4, 0, copy_files },
{ "remove", 2, VERB_ANY, 0, remove_image },
{ "rename", 3, 3, 0, rename_image },
{ "clone", 3, 3, 0, clone_image },
{ "read-only", 2, 3, 0, read_only_image },
{ "start", 2, VERB_ANY, 0, start_machine },
{ "enable", 2, VERB_ANY, 0, enable_machine },
{ "disable", 2, VERB_ANY, 0, enable_machine },
{}
};
return dispatch_verb(argc, argv, verbs, bus);
}
int main(int argc, char*argv[]) {
_cleanup_bus_close_unref_ sd_bus *bus = NULL;
int r;
setlocale(LC_ALL, "");
log_parse_environment();
log_open();
r = parse_argv(argc, argv);
if (r <= 0)
goto finish;
r = bus_open_transport(arg_transport, arg_host, false, &bus);
if (r < 0) {
log_error_errno(r, "Failed to create bus connection: %m");
goto finish;
}
r = machinectl_main(argc, argv, bus);
finish:
pager_close();
polkit_agent_close();
strv_free(arg_property);
return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
}