machinectl.c revision eb9da376d76b48585b3b63b4f91903b54f7abd36
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 <unistd.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <errno.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <string.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <getopt.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <pwd.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <locale.h>
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include <socket.h>
04d39279245834494baccfdb9349db8bf80abd13Lennart Poettering#include <fcntl.h>
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering#include "sd-bus.h"
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering#include "log.h"
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poettering#include "util.h"
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poettering#include "macro.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "pager.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#include "bus-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "bus-error.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "build.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "strv.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "unit-name.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#include "cgroup-show.h"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen#include "cgroup-util.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering#include "ptyfwd.h"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringstatic char **arg_property = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic bool arg_all = false;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poetteringstatic bool arg_full = false;
04d39279245834494baccfdb9349db8bf80abd13Lennart Poetteringstatic bool arg_no_pager = false;
023fb90b83871a15ef7f57e8cd126e3426f99b9eLennart Poetteringstatic const char *arg_kill_who = NULL;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int arg_signal = SIGTERM;
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic bool arg_ask_password = true;
f2cbe59e113f08549949a76ac5b9b3972df4cc30Lennart Poetteringstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poetteringstatic char *arg_host = NULL;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringstatic void pager_open_if_enabled(void) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering /* Cache result before we open the pager */
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (arg_no_pager)
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen return;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pager_open(false);
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart Poetteringstatic int list_machines(sd_bus *bus, char **args, unsigned n) {
785890acf6d629ff881a1f065f431df1b7fc8c7aLennart 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 unsigned k = 0;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pager_open_if_enabled();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_call_method(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "/org/freedesktop/machine1",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "org.freedesktop.machine1.Manager",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "ListMachines",
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen &error,
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen &reply,
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Could not get machines: %s", bus_error_message(&error, -r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (on_tty())
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering printf("%-32s %-9s %-16s\n", "MACHINE", "CONTAINER", "SERVICE");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssso)");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0)
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen goto fail;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen while ((r = sd_bus_message_read(reply, "(ssso)", &name, &class, &service, &object)) > 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen printf("%-32s %-9s %-16s\n", name, class, service);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen k++;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering goto fail;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_exit_container(reply);
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen if (r < 0)
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen goto fail;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (on_tty())
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen printf("\n%u machines listed.\n", k);
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return 0;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringfail:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Failed to parse reply: %s", strerror(-r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poetteringstatic int show_scope_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen _cleanup_free_ char *path = NULL;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering const char *cgroup;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering int r, output_flags;
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen unsigned c;
e56056e93d33619a3acf13e483900b4f8938228fThomas Hindoe Paaboel Andersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(bus);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering assert(unit);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart 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)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering return log_oom();
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering r = sd_bus_get_property(
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering bus,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "org.freedesktop.systemd1",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering path,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "org.freedesktop.systemd1.Scope",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "ControlGroup",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering &error,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering &reply,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "s");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (r < 0) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_error("Failed to query ControlGroup: %s", bus_error_message(&error, -r));
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering }
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = sd_bus_message_read(reply, "s", &cgroup);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_error("Failed to parse reply: %s", strerror(-r));
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return r;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering }
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (isempty(cgroup))
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return 0;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, false) != 0 && leader <= 0)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering output_flags =
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering arg_all * OUTPUT_SHOW_ALL |
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering arg_full * OUTPUT_FULL_WIDTH;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering c = columns();
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (c > 18)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering c -= 18;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering else
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering c = 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, output_flags);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return 0;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering}
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringtypedef struct MachineStatusInfo {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering char *name;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering sd_id128_t id;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering char *class;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering char *service;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering char *scope;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering char *root_directory;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering pid_t leader;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering usec_t timestamp;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering} MachineStatusInfo;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poetteringstatic void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering char since2[FORMAT_TIMESTAMP_MAX], *s2;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(i);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering fputs(strna(i->name), stdout);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (!sd_id128_equal(i->id, SD_ID128_NULL))
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id));
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering else
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering putchar('\n');
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering s1 = format_timestamp_relative(since1, sizeof(since1), i->timestamp);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering s2 = format_timestamp(since2, sizeof(since2), i->timestamp);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (s1)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("\t Since: %s; %s\n", s2, s1);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering else if (s2)
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering printf("\t Since: %s\n", s2);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (i->leader > 0) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering _cleanup_free_ char *t = NULL;
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering printf("\t Leader: %u", (unsigned) i->leader);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering get_process_comm(i->leader, &t);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering if (t)
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering printf(" (%s)", t);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering putchar('\n');
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering }
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (i->service) {
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering printf("\t Service: %s", i->service);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (i->class)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("; class %s", i->class);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering putchar('\n');
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering } else if (i->class)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("\t Class: %s\n", i->class);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (i->root_directory)
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("\t Root: %s\n", i->root_directory);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (i->scope) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering printf("\t Unit: %s\n", i->scope);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering show_scope_cgroup(bus, i->scope, i->leader);
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering }
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering}
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poetteringstatic int show_info(const char *verb, sd_bus *bus, const char *path, bool *new_line) {
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering MachineStatusInfo info = {};
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering static const struct bus_properties_map map[] = {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering { "Name", "s", NULL, offsetof(MachineStatusInfo, name) },
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering { "Class", "s", NULL, offsetof(MachineStatusInfo, class) },
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering { "Service", "s", NULL, offsetof(MachineStatusInfo, service) },
10f9c75519671e7c7ab8993b54fe22da7c2d0c38Lennart Poettering { "Scope", "s", NULL, offsetof(MachineStatusInfo, scope) },
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering { "RootDirectory", "s", NULL, offsetof(MachineStatusInfo, root_directory) },
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering { "Leader", "u", NULL, offsetof(MachineStatusInfo, leader) },
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering { "Timestamp", "t", NULL, offsetof(MachineStatusInfo, timestamp) },
8937e7b68940d0fa0d0aab90eb7425fa7dccebc9Lennart Poettering { "Id", "ay", bus_map_id128, offsetof(MachineStatusInfo, id) },
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering {}
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering };
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering int r;
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(path);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering assert(new_line);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering r = bus_map_all_properties(bus,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering "org.freedesktop.machine1",
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering path,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering map,
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering &info);
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering if (r < 0) {
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering log_error("Could not get properties: %s", strerror(-r));
cd61c3bfd718fb398cc53ced906266a9297782c9Lennart Poettering return r;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (*new_line)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering printf("\n");
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering *new_line = true;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering print_machine_status_info(bus, &info);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering free(info.name);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering free(info.class);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering free(info.service);
d21ed1ead18d16d35c30299a69d3366847f8a039Lennart Poettering free(info.scope);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering free(info.root_directory);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poetteringstatic int show_properties(sd_bus *bus, const char *path, bool *new_line) {
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering int r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (*new_line)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering printf("\n");
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering *new_line = true;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen r = bus_print_all_properties(bus, path, arg_property, arg_all);
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering if (r < 0)
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering log_error("Could not get properties: %s", strerror(-r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering}
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poetteringstatic int show(sd_bus *bus, char **args, unsigned n) {
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering int r = 0;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering unsigned i;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering bool properties, new_line = false;
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering assert(bus);
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering assert(args);
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering properties = !strstr(args[0], "status");
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering pager_open_if_enabled();
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (properties && n <= 1) {
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering /* If no argument is specified, inspect the manager
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering * itself */
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering r = show_properties(bus, "/org/freedesktop/machine1", &new_line);
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering if (r < 0) {
9d12709626bccc0cae677a7035f62efe6aabb4abLennart Poettering log_error("Failed to query properties: %s", strerror(-r));
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering return r;
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering }
aa1936ea1a89c2bb968ba33e3274898a4eeae771Lennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering for (i = 1; i < n; i++) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering const char *path = NULL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_call_method(
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering bus,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "org.freedesktop.machine1",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "/org/freedesktop/machine1",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "org.freedesktop.machine1.Manager",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "GetMachine",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering &error,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering &reply,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "s", args[i]);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_error("Could not get path to machine: %s", bus_error_message(&error, -r));
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_message_read(reply, "o", &path);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0) {
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering log_error("Failed to parse reply: %s", strerror(-r));
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering break;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering if (properties)
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering r = show_properties(bus, path, &new_line);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering else
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = show_info(args[0], bus, path, &new_line);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
0dd25fb9f005d8ab7ac4bc10a609d00569f8c56aLennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering}
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poetteringstatic int kill_machine(sd_bus *bus, char **args, unsigned n) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering unsigned i;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering assert(args);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (!arg_kill_who)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering arg_kill_who = "all";
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering for (i = 1; i < n; i++) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering int r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = sd_bus_call_method(
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering bus,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "org.freedesktop.machine1",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "/org/freedesktop/machine1",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "org.freedesktop.machine1.Manager",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "KillMachine",
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering &error,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering NULL,
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering "ssi", args[i], arg_kill_who, arg_signal);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering log_error("Could not kill machine: %s", bus_error_message(&error, -r));
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return r;
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering }
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering return 0;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering}
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poetteringstatic int terminate_machine(sd_bus *bus, char **args, unsigned n) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering unsigned i;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering assert(args);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering for (i = 1; i < n; i++) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering int r;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering r = sd_bus_call_method(
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering bus,
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "org.freedesktop.machine1",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "/org/freedesktop/machine1",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "org.freedesktop.machine1.Manager",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "TerminateMachine",
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering &error,
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering NULL,
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering "s", args[i]);
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (r < 0) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering log_error("Could not terminate machine: %s", bus_error_message(&error, -r));
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return r;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering }
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering }
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering return 0;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering}
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poetteringstatic int openpt_in_namespace(pid_t pid, int flags) {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering _cleanup_close_ int nsfd = -1, rootfd = -1;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering _cleanup_free_ char *ns = NULL, *root = NULL;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering _cleanup_close_pipe_ int sock[2] = { -1, -1 };
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering struct msghdr mh;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering union {
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering struct cmsghdr cmsghdr;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering uint8_t buf[CMSG_SPACE(sizeof(int))];
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering } control;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering struct cmsghdr *cmsg;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering int master = -1, r;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering pid_t child;
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering siginfo_t si;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = asprintf(&ns, "/proc/%lu/ns/mnt", (unsigned long) pid);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return -ENOMEM;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering nsfd = open(ns, O_RDONLY|O_NOCTTY|O_CLOEXEC);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers if (nsfd < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -errno;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering r = asprintf(&root, "/proc/%lu/root", (unsigned long) pid);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -ENOMEM;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen rootfd = open(root, O_RDONLY|O_NOCTTY|O_CLOEXEC|O_DIRECTORY);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (rootfd < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -errno;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (socketpair(AF_UNIX, SOCK_DGRAM, 0, sock) < 0)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return -errno;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering zero(control);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering zero(mh);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mh.msg_control = &control;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mh.msg_controllen = sizeof(control);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering child = fork();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (child < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -errno;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (child == 0) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering close_nointr_nofail(sock[0]);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering sock[0] = -1;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = setns(nsfd, CLONE_NEWNS);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _exit(EXIT_FAILURE);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (fchdir(rootfd) < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _exit(EXIT_FAILURE);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (chroot(".") < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _exit(EXIT_FAILURE);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering master = posix_openpt(flags);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (master < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _exit(EXIT_FAILURE);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering cmsg = CMSG_FIRSTHDR(&mh);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering cmsg->cmsg_level = SOL_SOCKET;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering cmsg->cmsg_type = SCM_RIGHTS;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering cmsg->cmsg_len = CMSG_LEN(sizeof(int));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering memcpy(CMSG_DATA(cmsg), &master, sizeof(int));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering mh.msg_controllen = cmsg->cmsg_len;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sendmsg(sock[1], &mh, MSG_NOSIGNAL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering close_nointr_nofail(master);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _exit(EXIT_FAILURE);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _exit(EXIT_SUCCESS);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering close_nointr_nofail(sock[1]);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering sock[1] = -1;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (recvmsg(sock[0], &mh, MSG_NOSIGNAL|MSG_CMSG_CLOEXEC) < 0)
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return -errno;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering for (cmsg = CMSG_FIRSTHDR(&mh); cmsg; cmsg = CMSG_NXTHDR(&mh, cmsg))
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (cmsg->cmsg_level == SOL_SOCKET && cmsg->cmsg_type == SCM_RIGHTS) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering int *fds;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering unsigned n_fds;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering fds = (int*) CMSG_DATA(cmsg);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering n_fds = (cmsg->cmsg_len - CMSG_LEN(0)) / sizeof(int);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (n_fds != 1) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering close_many(fds, n_fds);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return -EIO;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering master = fds[0];
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering r = wait_for_terminate(child, &si);
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering if (r < 0 || si.si_code != CLD_EXITED || si.si_status != EXIT_SUCCESS || master < 0) {
878cd7e95ca303f9851d227a22d2022bd49944b0Lennart Poettering
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering if (master >= 0)
717603e391b52983ca1fd218e7333a1b9dfc5c05Lennart Poettering close_nointr_nofail(master);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering return r < 0 ? r : -EIO;
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return master;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poetteringstatic int login_machine(sd_bus *bus, char **args, unsigned n) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL, *reply2 = NULL, *reply3 = NULL;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering _cleanup_bus_unref_ sd_bus *container_bus = NULL;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering _cleanup_close_ int master = -1;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering _cleanup_free_ char *getty = NULL;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering const char *path, *pty, *p;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering uint32_t leader;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering sigset_t mask;
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek int r;
e7e9b6bb0b0bc5b1eb256a44f8afec6b634f26efZbigniew Jędrzejewski-Szmek
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert(bus);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering assert(args);
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering if (arg_transport != BUS_TRANSPORT_LOCAL) {
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering log_error("Login only support on local machines.");
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return -ENOTSUP;
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering }
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering r = sd_bus_call_method(
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering bus,
a6c616024db23fef34152c1432892824a07799ccLennart Poettering "org.freedesktop.machine1",
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "/org/freedesktop/machine1",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "org.freedesktop.machine1.Manager",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "GetMachine",
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering &error,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering &reply,
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering "s", args[1]);
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 }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = sd_bus_message_read(reply, "o", &path);
a6c616024db23fef34152c1432892824a07799ccLennart Poettering if (r < 0) {
a6c616024db23fef34152c1432892824a07799ccLennart Poettering log_error("Failed to parse reply: %s", strerror(-r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = sd_bus_get_property(
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.machine1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering path,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "org.freedesktop.machine1.Machine",
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "Leader",
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers &error,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers &reply2,
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers "u");
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt if (r < 0) {
f647962d64e844689f3e2acfce6102fc47e76df2Michal Schmidt log_error("Failed to retrieve PID of leader: %s", strerror(-r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = sd_bus_message_read(reply2, "u", &leader);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_error("Failed to parse reply: %s", strerror(-r));
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return r;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers master = openpt_in_namespace(leader, O_RDWR|O_NOCTTY|O_CLOEXEC|O_NDELAY);
89f7c8465cd1ab37347dd0c15920bce31e8225dfLennart Poettering if (master < 0) {
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers log_error("Failed to acquire pseudo tty: %s", strerror(-master));
f48e75cb9a8112d35855c44a156934f2ee0edb2eLennart Poettering return master;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers pty = ptsname(master);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!pty) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_error("Failed to get pty name: %m");
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return -errno;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering p = startswith(pty, "/dev/pts/");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (!p) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_error("Invalid pty name %s.", pty);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers return -EIO;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers r = sd_bus_open_system_container(args[1], &container_bus);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen if (r < 0) {
27e72d6b22890ba4a8cbc05c49667cd1cccf1461Simon Peeters log_error("Failed to get container bus: %s", strerror(-r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return r;
da927ba997d68401563b927f92e6e40e021a8e5cMichal Schmidt }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
a7893c6b28772edbc7e1fea3c209caa54d465648Lennart Poettering getty = strjoin("container-getty@", p, ".service", NULL);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (!getty)
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return log_oom();
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (unlockpt(master) < 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Failed to unlock tty: %m");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return -errno;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = sd_bus_call_method(container_bus,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.systemd1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "/org/freedesktop/systemd1",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "org.freedesktop.systemd1.Manager",
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering "StartUnit",
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering &error, &reply3,
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering "ss", getty, "replace");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_error("Failed to start getty service: %s", bus_error_message(&error, r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return r;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert_se(sigemptyset(&mask) == 0);
8c841f21f5042b11acc91cc1b039cb162cbbe8f4Djalal Harouni sigset_add_many(&mask, SIGWINCH, SIGTERM, SIGINT, -1);
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers assert_se(sigprocmask(SIG_BLOCK, &mask, NULL) == 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_info("Connected to container %s. Press ^] three times within 1s to exit session.", args[1]);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = process_pty(master, &mask, 0, 0);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering if (r < 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Failed to process pseudo tty: %s", strerror(-r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen return r;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen fputc('\n', stdout);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_info("Connection to container %s terminated.", args[1]);
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return 0;
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen}
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersenstatic int help(void) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen printf("%s [OPTIONS...] {COMMAND} ...\n\n"
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen "Send control commands to or query the virtual machine and container registration manager.\n\n"
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering " -h --help Show this help\n"
5b30bef856e89a571df57b7b953e9a1409d9acedLennart Poettering " --version Show package version\n"
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering " --no-pager Do not pipe output into a pager\n"
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers " --no-ask-password Don't prompt for password\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering " -H --host=[USER@]HOST Operate on remote host\n"
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers " -M --machine=CONTAINER Operate on local container\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering " -p --property=NAME Show only properties by this name\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering " -a --all Show all properties, including empty ones\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering " -l --full Do not ellipsize output\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering " --kill-who=WHO Who to send signal to\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering " -s --signal=SIGNAL Which signal to send\n\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering "Commands:\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering " list List running VMs and containers\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering " status [NAME...] Show VM/container status\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering " show [NAME...] Show properties of one or more VMs/containers\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering " terminate [NAME...] Terminate one or more VMs/containers\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering " kill [NAME...] Send signal to processes of a VM/container\n"
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering " login [NAME] Get a login prompt on a container\n",
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering program_invocation_short_name);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return 0;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering}
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poetteringstatic int parse_argv(int argc, char *argv[]) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering enum {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering ARG_VERSION = 0x100,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering ARG_NO_PAGER,
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering ARG_KILL_WHO,
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering ARG_NO_ASK_PASSWORD,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering };
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering static const struct option options[] = {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "help", no_argument, NULL, 'h' },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "version", no_argument, NULL, ARG_VERSION },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "property", required_argument, NULL, 'p' },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "all", no_argument, NULL, 'a' },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "full", no_argument, NULL, 'l' },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "no-pager", no_argument, NULL, ARG_NO_PAGER },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "kill-who", required_argument, NULL, ARG_KILL_WHO },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "signal", required_argument, NULL, 's' },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "host", required_argument, NULL, 'H' },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "machine", required_argument, NULL, 'M' },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "no-ask-password", no_argument, NULL, ARG_NO_ASK_PASSWORD },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering {}
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering };
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int c, r;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(argc >= 0);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(argv);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering while ((c = getopt_long(argc, argv, "hp:als:H:M:", options, NULL)) >= 0) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering switch (c) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering case 'h':
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return help();
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering case ARG_VERSION:
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering puts(PACKAGE_STRING);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering puts(SYSTEMD_FEATURES);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return 0;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering case 'p':
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering r = strv_extend(&arg_property, optarg);
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering if (r < 0)
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering return log_oom();
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering /* If the user asked for a particular
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering * property, show it to him, even if it is
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering * empty. */
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering arg_all = true;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering break;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering case 'a':
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering arg_all = true;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering case 'l':
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering arg_full = true;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering case ARG_NO_PAGER:
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering arg_no_pager = true;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering break;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering case ARG_NO_ASK_PASSWORD:
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering arg_ask_password = false;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering break;
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering
b6b1849830f5e4a6065c3b0c993668e500c954d3Lennart Poettering case ARG_KILL_WHO:
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering arg_kill_who = optarg;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering case 's':
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering arg_signal = signal_from_string_try_harder(optarg);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (arg_signal < 0) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_error("Failed to parse signal string %s.", optarg);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -EINVAL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering case 'H':
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering arg_transport = BUS_TRANSPORT_REMOTE;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering arg_host = optarg;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering case 'M':
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering arg_transport = BUS_TRANSPORT_CONTAINER;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering arg_host = optarg;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering case '?':
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -EINVAL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering default:
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert_not_reached("Unhandled option");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return 1;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering}
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poetteringstatic int machinectl_main(sd_bus *bus, int argc, char *argv[]) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering static const struct {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering const char* verb;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering const enum {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering MORE,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering LESS,
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering EQUAL
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering } argc_cmp;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering const int argc;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int (* const dispatch)(sd_bus *bus, char **args, unsigned n);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering } verbs[] = {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "list", LESS, 1, list_machines },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "status", MORE, 2, show },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "show", MORE, 1, show },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "terminate", MORE, 2, terminate_machine },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "kill", MORE, 2, kill_machine },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering { "login", MORE, 2, login_machine },
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering };
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering int left;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering unsigned i;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(argc >= 0);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering assert(argv);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering left = argc - optind;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (left <= 0)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering /* Special rule: no arguments means "list-sessions" */
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering i = 0;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering else {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (streq(argv[optind], "help")) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering help();
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return 0;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering for (i = 0; i < ELEMENTSOF(verbs); i++)
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (streq(argv[optind], verbs[i].verb))
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (i >= ELEMENTSOF(verbs)) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_error("Unknown operation %s", argv[optind]);
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -EINVAL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering switch (verbs[i].argc_cmp) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering case EQUAL:
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (left != verbs[i].argc) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_error("Invalid number of arguments.");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -EINVAL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering case MORE:
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (left < verbs[i].argc) {
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering log_error("Too few arguments.");
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering return -EINVAL;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering }
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering break;
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering case LESS:
fefdc04b38725457a91651218feb7000f6ccc1f4Lennart Poettering if (left > verbs[i].argc) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering log_error("Too many arguments.");
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering return -EINVAL;
9f6eb1cd58f2ddf2eb6ba0e4de056e13d938af75Kay Sievers }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering break;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen default:
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering assert_not_reached("Unknown comparison operator.");
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering }
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering return verbs[i].dispatch(bus, argv + optind, left);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringint main(int argc, char*argv[]) {
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering _cleanup_bus_unref_ sd_bus *bus = NULL;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering int r;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering setlocale(LC_ALL, "");
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_parse_environment();
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering log_open();
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = parse_argv(argc, argv);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (r <= 0)
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering goto finish;
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering r = bus_open_transport(arg_transport, arg_host, false, &bus);
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering if (r < 0) {
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen log_error("Failed to create bus connection: %s", strerror(-r));
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen goto finish;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering }
a1da85830bfaa77b9eb9c54693e5573559c97e50Tom Gundersen
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering r = machinectl_main(bus, argc, argv);
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poetteringfinish:
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering pager_close();
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering strv_free(arg_property);
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering
1dba654b27918c22e413ac5b3c19301f1ff86ad2Lennart Poettering return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS;
1ee306e1248866617c96ed9f4263f375588ad838Lennart Poettering}
56159e0d918e9a9be07988133bb2847779325de0Lennart Poettering