machinectl.c revision 56159e0d918e9a9be07988133bb2847779325de0
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
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 "bus-util.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#include "bus-error.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "build.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "strv.h"
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering#include "unit-name.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "cgroup-show.h"
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering#include "cgroup-util.h"
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering#include "ptyfwd.h"
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering#include "event-util.h"
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering#include "path-util.h"
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering#include "mkdir.h"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering#include "copy.h"
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering#include "verbs.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic char **arg_property = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_all = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_full = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_no_pager = false;
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersenstatic bool arg_legend = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic const char *arg_kill_who = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int arg_signal = SIGTERM;
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poetteringstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic char *arg_host = NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic bool arg_read_only = false;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic bool arg_mkdir = false;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void pager_open_if_enabled(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Cache result before we open the pager */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_no_pager)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pager_open(false);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int list_machines(int argc, char *argv[], void *userdata) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen const char *name, *class, *service, *object;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering sd_bus *bus = userdata;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering unsigned k = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(bus);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pager_open_if_enabled();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_bus_call_method(
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen bus,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "org.freedesktop.machine1",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "/org/freedesktop/machine1",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "org.freedesktop.machine1.Manager",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "ListMachines",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen &error,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen &reply,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Could not get machines: %s", bus_error_message(&error, -r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen if (arg_legend)
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen printf("%-32s %-9s %-16s\n", "MACHINE", "CONTAINER", "SERVICE");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssso)");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0)
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering return bus_log_parse_error(r);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen while ((r = sd_bus_message_read(reply, "(ssso)", &name, &class, &service, &object)) > 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("%-32s %-9s %-16s\n", name, class, service);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering k++;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0)
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering return bus_log_parse_error(r);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_bus_message_exit_container(reply);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0)
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering return bus_log_parse_error(r);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen if (arg_legend)
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen printf("\n%u machines listed.\n", k);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringtypedef struct ImageInfo {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering const char *name;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering const char *type;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering bool read_only;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering} ImageInfo;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringstatic int compare_image_info(const void *a, const void *b) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering const ImageInfo *x = a, *y = b;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return strcmp(x->name, y->name);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart 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");
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;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering sd_bus *bus = userdata;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering int read_only;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering int r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(bus);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering pager_open_if_enabled();
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_bus_call_method(
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering bus,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "org.freedesktop.machine1",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "/org/freedesktop/machine1",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "org.freedesktop.machine1.Manager",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "ListImages",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering &error,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering &reply,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart 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, "(ssbo)");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return bus_log_parse_error(r);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering while ((r = sd_bus_message_read(reply, "(ssbo)", &name, &type, &read_only, &object)) > 0) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (name[0] == '.' && !arg_all)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering continue;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (!GREEDY_REALLOC(images, n_allocated, n_images + 1))
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return log_oom();
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering images[n_images].name = name;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering images[n_images].type = type;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering images[n_images].read_only = read_only;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (strlen(name) > max_name)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering max_name = strlen(name);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (strlen(type) > max_type)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering max_type = strlen(type);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering n_images++;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return bus_log_parse_error(r);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_bus_message_exit_container(reply);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return bus_log_parse_error(r);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering qsort_safe(images, n_images, sizeof(ImageInfo), compare_image_info);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (arg_legend)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("%-*s %-*s %-3s\n", (int) max_name, "NAME", (int) max_type, "TYPE", "RO");
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering for (j = 0; j < n_images; j++) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("%-*s %-*s %-3s\n",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering (int) max_name, images[j].name,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering (int) max_type, images[j].type,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering yes_no(images[j].read_only));
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return bus_log_parse_error(r);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (arg_legend)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("\n%zu images listed.\n", n_images);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poetteringstatic int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering _cleanup_free_ char *path = NULL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering const char *cgroup;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering int r, output_flags;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering unsigned c;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering assert(bus);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering assert(unit);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering if (arg_transport == BUS_TRANSPORT_REMOTE)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering path = unit_dbus_path_from_name(unit);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (!path)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return log_oom();
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering r = sd_bus_get_property(
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering bus,
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering "org.freedesktop.systemd1",
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering path,
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering endswith(unit, ".scope") ? "org.freedesktop.systemd1.Scope" : "org.freedesktop.systemd1.Service",
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering "ControlGroup",
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering &error,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen &reply,
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering "s");
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Failed to query ControlGroup: %s", bus_error_message(&error, -r));
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering r = sd_bus_message_read(reply, "s", &cgroup);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering if (r < 0)
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering return bus_log_parse_error(r);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering if (isempty(cgroup))
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering return 0;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, false) != 0 && leader <= 0)
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering return 0;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering output_flags =
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering arg_all * OUTPUT_SHOW_ALL |
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering arg_full * OUTPUT_FULL_WIDTH;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering c = columns();
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (c > 18)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering c -= 18;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering else
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering c = 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, output_flags);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return 0;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poetteringstatic int print_addresses(sd_bus *bus, const char *name, int ifi, const char *prefix, const char *prefix2) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering int r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(bus);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(name);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(prefix);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(prefix2);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_call_method(bus,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "org.freedesktop.machine1",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "/org/freedesktop/machine1",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "org.freedesktop.machine1.Manager",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "GetMachineAddresses",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering NULL,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering &reply,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "s", name);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(iay)");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return bus_log_parse_error(r);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering int family;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering const void *a;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering size_t sz;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering char buffer[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)];
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering r = sd_bus_message_read(reply, "i", &family);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return bus_log_parse_error(r);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_message_read_array(reply, 'y', &a, &sz);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return bus_log_parse_error(r);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fputs(prefix, stdout);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fputs(inet_ntop(family, a, buffer, sizeof(buffer)), stdout);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (family == AF_INET6 && ifi > 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering printf("%%%i", ifi);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fputc('\n', stdout);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_message_exit_container(reply);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return bus_log_parse_error(r);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (prefix != prefix2)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering prefix = prefix2;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return bus_log_parse_error(r);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_message_exit_container(reply);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return bus_log_parse_error(r);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 0;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poetteringstatic int print_os_release(sd_bus *bus, const char *name, const char *prefix) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering const char *k, *v, *pretty = NULL;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering int r;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(bus);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(name);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(prefix);
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 "GetMachineOSRelease",
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', "{ss}");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (r < 0)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return bus_log_parse_error(r);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering while ((r = sd_bus_message_read(reply, "{ss}", &k, &v)) > 0) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (streq(k, "PRETTY_NAME"))
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering pretty = v;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering }
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (r < 0)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return bus_log_parse_error(r);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = sd_bus_message_exit_container(reply);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (r < 0)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return bus_log_parse_error(r);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (pretty)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering printf("%s%s\n", prefix, pretty);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return 0;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering}
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringtypedef struct MachineStatusInfo {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers char *name;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sd_id128_t id;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers char *class;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers char *service;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering char *unit;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers char *root_directory;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pid_t leader;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering usec_t timestamp;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering int *netif;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering unsigned n_netif;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering} MachineStatusInfo;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering char since2[FORMAT_TIMESTAMP_MAX], *s2;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering int ifi = -1;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(i);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering fputs(strna(i->name), stdout);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!sd_id128_equal(i->id, SD_ID128_NULL))
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering putchar('\n');
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering s2 = format_timestamp(since2, sizeof(since2), i->timestamp);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (s1)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Since: %s; %s\n", s2, s1);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering else if (s2)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Since: %s\n", s2);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (i->leader > 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_free_ char *t = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Leader: %u", (unsigned) i->leader);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering get_process_comm(i->leader, &t);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (t)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf(" (%s)", t);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering putchar('\n');
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (i->service) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Service: %s", i->service);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (i->class)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("; class %s", i->class);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering putchar('\n');
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering } else if (i->class)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Class: %s\n", i->class);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (i->root_directory)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\t Root: %s\n", i->root_directory);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (i->n_netif > 0) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering unsigned c;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fputs("\t Iface:", stdout);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering for (c = 0; c < i->n_netif; c++) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering char name[IF_NAMESIZE+1] = "";
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (if_indextoname(i->netif[c], name)) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fputc(' ', stdout);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fputs(name, stdout);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (ifi < 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering ifi = i->netif[c];
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering else
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering ifi = 0;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering } else
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering printf(" %i", i->netif[c]);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fputc('\n', stdout);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering print_addresses(bus, i->name, ifi,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "\t Address: ",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "\t ");
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering print_os_release(bus, i->name, "\t OS: ");
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (i->unit) {
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering printf("\t Unit: %s\n", i->unit);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering show_unit_cgroup(bus, i->unit, i->leader);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poetteringstatic int map_netif(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering MachineStatusInfo *i = userdata;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering size_t l;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering const void *v;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering int r;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert_cc(sizeof(int32_t) == sizeof(int));
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering r = sd_bus_message_read_array(m, SD_BUS_TYPE_INT32, &v, &l);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (r < 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return r;
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek if (r == 0)
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek return -EBADMSG;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering i->n_netif = l / sizeof(int32_t);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering i->netif = memdup(v, l);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (!i->netif)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return -ENOMEM;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return 0;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering}
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sieversstatic int show_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
a6c616024db23fef34152c1432892824a07799ccLennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers static const struct bus_properties_map map[] = {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Name", "s", NULL, offsetof(MachineStatusInfo, name) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Class", "s", NULL, offsetof(MachineStatusInfo, class) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Service", "s", NULL, offsetof(MachineStatusInfo, service) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Unit", "s", NULL, offsetof(MachineStatusInfo, unit) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "RootDirectory", "s", NULL, offsetof(MachineStatusInfo, root_directory) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Leader", "u", NULL, offsetof(MachineStatusInfo, leader) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Timestamp", "t", NULL, offsetof(MachineStatusInfo, timestamp) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "Id", "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering { "NetworkInterfaces", "ai", map_netif, 0 },
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers {}
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers };
a6c616024db23fef34152c1432892824a07799ccLennart Poettering
a6c616024db23fef34152c1432892824a07799ccLennart Poettering MachineStatusInfo info = {};
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen int r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(verb);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(path);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(new_line);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = bus_map_all_properties(bus,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "org.freedesktop.machine1",
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers path,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers map,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers &info);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Could not get properties: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (*new_line)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("\n");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering *new_line = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers print_machine_status_info(bus, &info);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers free(info.name);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers free(info.class);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers free(info.service);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering free(info.unit);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers free(info.root_directory);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering free(info.netif);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return r;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sieversstatic int show_properties(sd_bus *bus, const char *path, bool *new_line) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(bus);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(path);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(new_line);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (*new_line)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers printf("\n");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers *new_line = true;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
27e72d6b22890ba4a8cbc05c49667cd1cccf1461Simon Peeters r = bus_print_all_properties(bus, "org.freedesktop.machine1", path, arg_property, arg_all);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0)
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Could not get properties: %m");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int show(int argc, char *argv[], void *userdata) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers bool properties, new_line = false;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering sd_bus *bus = userdata;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering int r = 0, i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering properties = !strstr(argv[0], "status");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pager_open_if_enabled();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (properties && argc <= 1) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers /* If no argument is specified, inspect the manager
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * itself */
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = show_properties(bus, "/org/freedesktop/machine1", &new_line);
8c841f21f5042b11acc91cc1b039cb162cbbe8f4Djalal Harouni if (r < 0)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering for (i = 1; i < argc; i++) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering const char *path = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_bus_call_method(
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen bus,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "org.freedesktop.machine1",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "/org/freedesktop/machine1",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "org.freedesktop.machine1.Manager",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "GetMachine",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen &error,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen &reply,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "s", argv[i]);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_bus_message_read(reply, "o", &path);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering if (r < 0)
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering return bus_log_parse_error(r);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (properties)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = show_properties(bus, path, &new_line);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers else
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = show_info(argv[0], bus, path, &new_line);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int kill_machine(int argc, char *argv[], void *userdata) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering sd_bus *bus = userdata;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering int i;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!arg_kill_who)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_kill_who = "all";
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering for (i = 1; i < argc; i++) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_bus_call_method(
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering bus,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "org.freedesktop.machine1",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "/org/freedesktop/machine1",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "org.freedesktop.machine1.Manager",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "KillMachine",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering &error,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering NULL,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "ssi", argv[i], arg_kill_who, arg_signal);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Could not kill machine: %s", bus_error_message(&error, -r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int reboot_machine(int argc, char *argv[], void *userdata) {
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering arg_kill_who = "leader";
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering arg_signal = SIGINT; /* sysvinit + systemd */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return kill_machine(argc, argv, userdata);
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int poweroff_machine(int argc, char *argv[], void *userdata) {
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering arg_kill_who = "leader";
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering arg_signal = SIGRTMIN+4; /* only systemd */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return kill_machine(argc, argv, userdata);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int terminate_machine(int argc, char *argv[], void *userdata) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering sd_bus *bus = userdata;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering int i;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(bus);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering for (i = 1; i < argc; i++) {
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering int r;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering r = sd_bus_call_method(
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering bus,
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering "org.freedesktop.machine1",
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering "/org/freedesktop/machine1",
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering "org.freedesktop.machine1.Manager",
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering "TerminateMachine",
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering &error,
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering NULL,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "s", argv[i]);
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering if (r < 0) {
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering log_error("Could not terminate machine: %s", bus_error_message(&error, -r));
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering return r;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering }
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering }
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering return 0;
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering}
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int machine_get_leader(sd_bus *bus, const char *name, pid_t *ret) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *reply2 = NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering const char *object;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering uint32_t leader;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering assert(bus);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering assert(name);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering assert(ret);
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 "GetMachine",
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering &error,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering &reply,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering "s", name);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (r < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart 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,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering "org.freedesktop.machine1",
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering object,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering "org.freedesktop.machine1.Machine",
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering "Leader",
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering &error,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering &reply2,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart 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)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart 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) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering char *dest, *host_path, *container_path, *host_dirname, *host_basename, *container_dirname, *container_basename, *t;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering _cleanup_close_ int hostfd = -1;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering sd_bus *bus = userdata;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering pid_t child, leader;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering bool copy_from;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering siginfo_t si;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering int r;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(bus);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering copy_from = streq(argv[0], "copy-from");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering dest = argv[3] ?: argv[2];
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering host_path = strdupa(copy_from ? dest : argv[2]);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering container_path = strdupa(copy_from ? argv[2] : dest);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (!path_is_absolute(container_path)) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error("Container path not absolute.");
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return -EINVAL;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering t = strdup(host_path);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering host_basename = basename(t);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering host_dirname = dirname(host_path);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering t = strdup(container_path);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering container_basename = basename(t);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering container_dirname = dirname(container_path);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = machine_get_leader(bus, argv[1], &leader);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (r < 0)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return r;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering hostfd = open(host_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (r < 0)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return log_error_errno(errno, "Failed to open source directory: %m");
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering child = fork();
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (child < 0)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return log_error_errno(errno, "Failed to fork(): %m");
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (child == 0) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering int containerfd;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering const char *q;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering int mntfd;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering q = procfs_file_alloca(leader, "ns/mnt");
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering mntfd = open(q, O_RDONLY|O_NOCTTY|O_CLOEXEC);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (mntfd < 0) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error_errno(errno, "Failed to open mount namespace of leader: %m");
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering _exit(EXIT_FAILURE);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (setns(mntfd, CLONE_NEWNS) < 0) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error_errno(errno, "Failed to join namespace of leader: %m");
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering _exit(EXIT_FAILURE);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering containerfd = open(container_dirname, O_CLOEXEC|O_RDONLY|O_NOCTTY|O_DIRECTORY);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (containerfd < 0) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error_errno(errno, "Failed top open destination directory: %m");
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering _exit(EXIT_FAILURE);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (copy_from)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering r = copy_tree_at(containerfd, container_basename, hostfd, host_basename, true);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering else
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering r = copy_tree_at(hostfd, host_basename, containerfd, container_basename, true);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (r < 0) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error_errno(errno, "Failed to copy tree: %m");
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering _exit(EXIT_FAILURE);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering _exit(EXIT_SUCCESS);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering r = wait_for_terminate(child, &si);
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (r < 0)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return log_error_errno(r, "Failed to wait for client: %m");
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (si.si_code != CLD_EXITED) {
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering log_error("Client died abnormally.");
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return -EIO;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering }
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering if (si.si_status != EXIT_SUCCESS)
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return -EIO;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering return 0;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering}
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int bind_mount(int argc, char *argv[], void *userdata) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering char mount_slave[] = "/tmp/propagate.XXXXXX", *mount_tmp, *mount_outside, *p;
56159e0d918e9a9be07988133bb2847779325de0Lennart 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
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(bus);
56159e0d918e9a9be07988133bb2847779325de0Lennart 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
56159e0d918e9a9be07988133bb2847779325de0Lennart 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
56159e0d918e9a9be07988133bb2847779325de0Lennart 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
56159e0d918e9a9be07988133bb2847779325de0Lennart 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 }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_tmp_created = true;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (mount(argv[2], mount_tmp, NULL, MS_BIND, NULL) < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = log_error_errno(errno, "Failed to overmount: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto finish;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_tmp_mounted = true;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* Third, we remount the new bind mount read-only if requested. */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (arg_read_only)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (mount(NULL, mount_tmp, NULL, MS_BIND|MS_REMOUNT|MS_RDONLY, NULL) < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = log_error_errno(errno, "Failed to mark read-only: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto finish;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* Fourth, we move the new bind mount into the propagation
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering * directory. This way it will appear there read-only
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering * right-away. */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering mount_outside = strappenda("/run/systemd/nspawn/propagate/", argv[1], "/XXXXXX");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (!mkdtemp(mount_outside)) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = log_error_errno(errno, "Cannot create propagation directory: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto finish;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_outside_created = true;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (mount(mount_tmp, mount_outside, NULL, MS_MOVE, NULL) < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = log_error_errno(errno, "Failed to move: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto finish;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_outside_mounted = true;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_tmp_mounted = false;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering (void) rmdir(mount_tmp);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_tmp_created = false;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering (void) umount(mount_slave);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_slave_mounted = false;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering (void) rmdir(mount_slave);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_slave_created = false;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering child = fork();
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (child < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = log_error_errno(errno, "Failed to fork(): %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto finish;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (child == 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering const char *mount_inside;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering int mntfd;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering const char *q;
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
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (arg_mkdir)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mkdir_p(dest, 0755);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering /* Fifth, move the mount to the right place inside */
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering mount_inside = strappenda("/run/systemd/nspawn/incoming/", basename(mount_outside));
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (mount(mount_inside, dest, NULL, MS_MOVE, NULL) < 0) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error_errno(errno, "Failed to mount: %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 log_error_errno(r, "Failed to wait for client: %m");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto finish;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (si.si_code != CLD_EXITED) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering log_error("Client died abnormally.");
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = -EIO;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto finish;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (si.si_status != EXIT_SUCCESS) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = -EIO;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering goto finish;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering }
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering r = 0;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringfinish:
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (mount_outside_mounted)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering umount(mount_outside);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (mount_outside_created)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering rmdir(mount_outside);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (mount_tmp_mounted)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering umount(mount_tmp);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (mount_tmp_created)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering umount(mount_tmp);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (mount_slave_mounted)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering umount(mount_slave);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering if (mount_slave_created)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering umount(mount_slave);
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return r;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering}
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic int openpt_in_namespace(pid_t pid, int flags) {
3d94f76c99da13e5603831d0b278f8c8c21bcb02Lennart Poettering _cleanup_close_pair_ int pair[2] = { -1, -1 };
a4475f577bd0daf762d6c3b4e58bc484e0cb74afLennart Poettering _cleanup_close_ int pidnsfd = -1, mntnsfd = -1, rootfd = -1;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering union {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering struct cmsghdr cmsghdr;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering uint8_t buf[CMSG_SPACE(sizeof(int))];
34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1Zbigniew Jędrzejewski-Szmek } control = {};
34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1Zbigniew Jędrzejewski-Szmek struct msghdr mh = {
34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1Zbigniew Jędrzejewski-Szmek .msg_control = &control,
34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1Zbigniew Jędrzejewski-Szmek .msg_controllen = sizeof(control),
34a6778fb9d1065f3fbb8e2243b9f0f25d1d18f1Zbigniew Jędrzejewski-Szmek };
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering struct cmsghdr *cmsg;
f69157a66ffe413b4cf8bd79057487fc8921e78bThomas Hindoe Paaboel Andersen int master = -1, r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering pid_t child;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering siginfo_t si;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert(pid > 0);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = namespace_open(pid, &pidnsfd, &mntnsfd, NULL, &rootfd);
bc9fd78c7bfc39881e19457e476393635f8b0442Lennart Poettering if (r < 0)
bc9fd78c7bfc39881e19457e476393635f8b0442Lennart Poettering return r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
bc9fd78c7bfc39881e19457e476393635f8b0442Lennart Poettering if (socketpair(AF_UNIX, SOCK_DGRAM, 0, pair) < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return -errno;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering child = fork();
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (child < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return -errno;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (child == 0) {
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering pair[0] = safe_close(pair[0]);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = namespace_enter(pidnsfd, mntnsfd, -1, rootfd);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _exit(EXIT_FAILURE);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering master = posix_openpt(flags);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (master < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _exit(EXIT_FAILURE);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering cmsg = CMSG_FIRSTHDR(&mh);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering cmsg->cmsg_level = SOL_SOCKET;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering cmsg->cmsg_type = SCM_RIGHTS;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering cmsg->cmsg_len = CMSG_LEN(sizeof(int));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering mh.msg_controllen = cmsg->cmsg_len;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
bc9fd78c7bfc39881e19457e476393635f8b0442Lennart Poettering if (sendmsg(pair[1], &mh, MSG_NOSIGNAL) < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _exit(EXIT_FAILURE);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _exit(EXIT_SUCCESS);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
03e334a1c7dc8c20c38902aa039440763acc9b17Lennart Poettering pair[1] = safe_close(pair[1]);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
fbadf04511389c4a0687ba5e9baf0ecebdbb07f1Lennart Poettering r = wait_for_terminate(child, &si);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS)
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return -EIO;
fbadf04511389c4a0687ba5e9baf0ecebdbb07f1Lennart Poettering
bc9fd78c7bfc39881e19457e476393635f8b0442Lennart Poettering if (recvmsg(pair[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return -errno;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg))
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering int *fds;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering unsigned n_fds;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering fds = (int*) CMSG_DATA(cmsg);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (n_fds != 1) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering close_many(fds, n_fds);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return -EIO;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering master = fds[0];
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
6261f11fc3d0a8b63c5afa5313d96607a008b54eLennart Poettering if (master < 0)
6261f11fc3d0a8b63c5afa5313d96607a008b54eLennart Poettering return -EIO;
6261f11fc3d0a8b63c5afa5313d96607a008b54eLennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return master;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering}
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int login_machine(int argc, char *argv[], void *userdata) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
249968612f16a71df909d6e73785c18a9ff36a65Lennart Poettering _cleanup_bus_close_unref_ sd_bus *container_bus = NULL;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering _cleanup_(pty_forward_freep) PTYForward *forward = NULL;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering _cleanup_event_unref_ sd_event *event = NULL;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _cleanup_close_ int master = -1;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering _cleanup_free_ char *getty = NULL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering sd_bus *bus = userdata;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering const char *pty, *p;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering pid_t leader;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering sigset_t mask;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering int r, ret = 0;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert(bus);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (arg_transport != BUS_TRANSPORT_LOCAL) {
923d8fd381bced1c2d90ca53d18629d61a0f454aLennart Poettering log_error("Login only supported on local machines.");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return -ENOTSUP;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_event_default(&event);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to get event loop: %m");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_bus_attach_event(bus, event, 0);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to attach bus to event loop: %m");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = machine_get_leader(bus, argv[1], &leader);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering if (r < 0)
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering return r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering master = openpt_in_namespace(leader, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (master < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(master, "Failed to acquire pseudo tty: %m");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering pty = ptsname(master);
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (!pty)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "Failed to get pty name: %m");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering p = startswith(pty, "/dev/pts/");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!p) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Invalid pty name %s.", pty);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return -EIO;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = sd_bus_open_system_container(&container_bus, argv[1]);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to get container bus: %m");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering getty = strjoin("container-getty@", p, ".service", NULL);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (!getty)
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return log_oom();
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt if (unlockpt(master) < 0)
4a62c710b62a5a3c7a8a278b810b9d5b5a0c8f4fMichal Schmidt return log_error_errno(errno, "Failed to unlock tty: %m");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering r = sd_bus_call_method(container_bus,
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "org.freedesktop.systemd1",
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "/org/freedesktop/systemd1",
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "org.freedesktop.systemd1.Manager",
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "StartUnit",
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering &error, &reply,
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering "ss", getty, "replace");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering if (r < 0) {
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering log_error("Failed to start getty service: %s", bus_error_message(&error, r));
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering return r;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering }
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
a6c616024db23fef34152c1432892824a07799ccLennart Poettering container_bus = sd_bus_unref(container_bus);
a6c616024db23fef34152c1432892824a07799ccLennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert_se(sigemptyset(&mask) == 0);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering sigset_add_many(&mask, SIGWINCH, SIGTERM, SIGINT, -1);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_info("Connected to container %s. Press ^] three times within 1s to exit session.", argv[1]);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sd_event_add_signal(event, NULL, SIGINT, NULL, NULL);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sd_event_add_signal(event, NULL, SIGTERM, NULL, NULL);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = pty_forward_new(event, master, &forward);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to create PTY forwarder: %m");
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering r = sd_event_loop(event);
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0)
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt return log_error_errno(r, "Failed to run event loop: %m");
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering forward = pty_forward_free(forward);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering fputc('\n', stdout);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_info("Connection to container %s terminated.", argv[1]);
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering sd_event_get_exit_code(event, &ret);
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poettering return ret;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering}
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int help(int argc, char *argv[], void *userdata) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("%s [OPTIONS...] {COMMAND} ...\n\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "Send control commands to or query the virtual machine and container\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering "registration manager.\n\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " -h --help Show this help\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " --version Show package version\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " --no-pager Do not pipe output into a pager\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " --no-legend Do not show the headers and footers\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " -H --host=[USER@]HOST Operate on remote host\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " -M --machine=CONTAINER Operate on local container\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " -p --property=NAME Show only properties by this name\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " -a --all Show all properties, including empty ones\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " -l --full Do not ellipsize output\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " --kill-who=WHO Who to send signal to\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " -s --signal=SIGNAL Which signal to send\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " --read-only Create read-only bind mount\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " --mkdir Create directory before bind mounting, if missing\n\n"
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "Machine Commands:\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " list List running VMs and containers\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " status NAME... Show VM/container status\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " show NAME... Show properties of one or more VMs/containers\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " login NAME Get a login prompt on a container\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " poweroff NAME... Power off one or more containers\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " reboot NAME... Reboot one or more containers\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " kill NAME... Send signal to processes of a VM/container\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " terminate NAME... Terminate one or more VMs/containers\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " bind NAME PATH [PATH] Bind mount a path from the host into a container\n"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering " copy-to NAME PATH [PATH] Copy files from the host to a container\n"
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering " copy-from NAME PATH [PATH] Copy files from a container to the host\n\n"
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "Image commands:\n"
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering " list-images Show available images\n",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering program_invocation_short_name);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering enum {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_VERSION = 0x100,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_NO_PAGER,
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen ARG_NO_LEGEND,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering ARG_KILL_WHO,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering ARG_READ_ONLY,
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering ARG_MKDIR,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering };
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering static const struct option options[] = {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "help", no_argument, NULL, 'h' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "version", no_argument, NULL, ARG_VERSION },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "property", required_argument, NULL, 'p' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "all", no_argument, NULL, 'a' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "full", no_argument, NULL, 'l' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "no-pager", no_argument, NULL, ARG_NO_PAGER },
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen { "no-legend", no_argument, NULL, ARG_NO_LEGEND },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "kill-who", required_argument, NULL, ARG_KILL_WHO },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "signal", required_argument, NULL, 's' },
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering { "host", required_argument, NULL, 'H' },
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering { "machine", required_argument, NULL, 'M' },
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering { "read-only", no_argument, NULL, ARG_READ_ONLY },
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering { "mkdir", no_argument, NULL, ARG_MKDIR },
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering {}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering };
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering int c, r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(argc >= 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(argv);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
601185b43da638b1c74153deae01dbd518680889Zbigniew Jędrzejewski-Szmek while ((c = getopt_long(argc, argv, "hp:als:H:M:", options, NULL)) >= 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering switch (c) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case 'h':
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return help(0, NULL, NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case ARG_VERSION:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering puts(PACKAGE_STRING);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering puts(SYSTEMD_FEATURES);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering case 'p':
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering r = strv_extend(&arg_property, optarg);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering if (r < 0)
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering return log_oom();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* If the user asked for a particular
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * property, show it to him, even if it is
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering * empty. */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_all = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case 'a':
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_all = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case 'l':
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_full = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case ARG_NO_PAGER:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_no_pager = true;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen case ARG_NO_LEGEND:
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen arg_legend = false;
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen break;
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case ARG_KILL_WHO:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_kill_who = optarg;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case 's':
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering arg_signal = signal_from_string_try_harder(optarg);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_signal < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse signal string %s.", optarg);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case 'H':
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering arg_transport = BUS_TRANSPORT_REMOTE;
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering arg_host = optarg;
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering break;
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering case 'M':
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering arg_transport = BUS_TRANSPORT_CONTAINER;
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering arg_host = optarg;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering case ARG_READ_ONLY:
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering arg_read_only = true;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering break;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering case ARG_MKDIR:
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering arg_mkdir = true;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering break;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering case '?':
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering default:
eb9da376d76b48585b3b63b4f91903b54f7abd36Lennart Poettering assert_not_reached("Unhandled option");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic int machinectl_main(int argc, char *argv[], sd_bus *bus) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering static const Verb verbs[] = {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "help", VERB_ANY, VERB_ANY, 0, help },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "list", VERB_ANY, 1, VERB_DEFAULT, list_machines },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "list-images", VERB_ANY, 1, 0, list_images },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "status", 2, VERB_ANY, 0, show },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "show", VERB_ANY, VERB_ANY, 0, show },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "terminate", 2, VERB_ANY, 0, terminate_machine },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "reboot", 2, VERB_ANY, 0, reboot_machine },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "poweroff", 2, VERB_ANY, 0, poweroff_machine },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "kill", 2, VERB_ANY, 0, kill_machine },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "login", 2, 2, 0, login_machine },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "bind", 3, 4, 0, bind_mount },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "copy-to", 3, 4, 0, copy_files },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering { "copy-from", 3, 4, 0, copy_files },
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering {}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering };
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return dispatch_verb(argc, argv, verbs, bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint main(int argc, char*argv[]) {
249968612f16a71df909d6e73785c18a9ff36a65Lennart Poettering _cleanup_bus_close_unref_ sd_bus *bus = NULL;
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering setlocale(LC_ALL, "");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_parse_environment();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_open();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = parse_argv(argc, argv);
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering if (r <= 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering r = bus_open_transport(arg_transport, arg_host, false, &bus);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0) {
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt log_error_errno(r, "Failed to create bus connection: %m");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen goto finish;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = machinectl_main(argc, argv, bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringfinish:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pager_close();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering strv_free(arg_property);
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering
84f6181c2ac99a0514ca5e0c8fc8c8e284caf789Lennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}