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