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