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