machinectl.c revision f647962d64e844689f3e2acfce6102fc47e76df2
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering This file is part of systemd.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Copyright 2013 Lennart Poettering
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is free software; you can redistribute it and/or modify it
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering under the terms of the GNU Lesser General Public License as published by
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering (at your option) any later version.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering systemd is distributed in the hope that it will be useful, but
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering Lesser General Public License for more details.
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering You should have received a copy of the GNU Lesser General Public License
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersenstatic bool arg_all = false;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poetteringstatic bool arg_full = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool arg_no_pager = false;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic bool arg_legend = true;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poetteringstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic void pager_open_if_enabled(void) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering /* Cache result before we open the pager */
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poetteringstatic int list_machines(sd_bus *bus, char **args, unsigned n) {
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering const char *name, *class, *service, *object;
4e945a6f7971fd7d1f6b2c62ee3afdaff3c95ce4Lennart Poettering unsigned k = 0;
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "org.freedesktop.machine1",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "org.freedesktop.machine1.Manager",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering "ListMachines",
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering log_error("Could not get machines: %s", bus_error_message(&error, -r));
cab5b05903096e1c9cf5575ccc73f89d15c8db69Lennart Poettering printf("%-32s %-9s %-16s\n", "MACHINE", "CONTAINER", "SERVICE");
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssso)");
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen while ((r = sd_bus_message_read(reply, "(ssso)", &name, &class, &service, &object)) > 0) {
3e684349c2cead2e6fd2f816c34eb17daba23a49Lennart Poettering printf("%-32s %-9s %-16s\n", name, class, service);
74b2466e14a1961bf3ac0e8a60cfaceec705bd59Lennart Poettering r = sd_bus_message_exit_container(reply);
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersenstatic int show_unit_cgroup(sd_bus *bus, const char *unit, pid_t leader) {
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
91b14d6ff362b938a72db17b095ee9903d07381bTom Gundersen _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
84129d46cd6e95e142973da93aede4c7433c9600Lennart Poettering endswith(unit, ".scope") ? "org.freedesktop.systemd1.Scope" : "org.freedesktop.systemd1.Service",
84129d46cd6e95e142973da93aede4c7433c9600Lennart Poettering "ControlGroup",
b826ab586c9e0a9c0d438a75c28cf3a8ab485929Tom Gundersen log_error("Failed to query ControlGroup: %s", bus_error_message(&error, -r));
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering r = sd_bus_message_read(reply, "s", &cgroup);
87f5a19343acf8ba697acc5a62bdb1a2b8c9eda3Lennart Poettering if (cg_is_empty_recursive(SYSTEMD_CGROUP_CONTROLLER, cgroup, false) != 0 && leader <= 0)
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poettering show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, output_flags);
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poetteringstatic int print_addresses(sd_bus *bus, const char *name, int ifi, const char *prefix, const char *prefix2) {
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poettering "org.freedesktop.machine1",
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poettering "org.freedesktop.machine1.Manager",
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poettering "GetMachineAddresses",
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "(iay)");
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poettering while ((r = sd_bus_message_enter_container(reply, 'r', "iay")) > 0) {
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poettering const void *a;
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poettering char buffer[MAX(INET6_ADDRSTRLEN, INET_ADDRSTRLEN)];
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poettering r = sd_bus_message_read(reply, "i", &family);
636e813dc98ea40c58c6c85bc5e7e3c9f0904ea2Lennart Poettering r = sd_bus_message_read_array(reply, 'y', &a, &sz);
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering fputs(inet_ntop(family, a, buffer, sizeof(buffer)), stdout);
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering r = sd_bus_message_exit_container(reply);
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering r = sd_bus_message_exit_container(reply);
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poetteringstatic int print_os_release(sd_bus *bus, const char *name, const char *prefix) {
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering "org.freedesktop.machine1",
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering "org.freedesktop.machine1.Manager",
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering "GetMachineOSRelease",
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering r = sd_bus_message_enter_container(reply, 'a', "{ss}");
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering while ((r = sd_bus_message_read(reply, "{ss}", &k, &v)) > 0) {
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering r = sd_bus_message_exit_container(reply);
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poetteringstatic void print_machine_status_info(sd_bus *bus, MachineStatusInfo *i) {
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering char since1[FORMAT_TIMESTAMP_RELATIVE_MAX], *s1;
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering if (!sd_id128_equal(i->id, SD_ID128_NULL))
f2f1dbe50fea13abadc9c1e845a29031b90b40f3Lennart Poettering printf("(" SD_ID128_FORMAT_STR ")\n", SD_ID128_FORMAT_VAL(i->id));
if (s1)
else if (s2)
if (i->leader > 0) {
if (i->service) {
if (i->class)
} else if (i->class)
if (i->root_directory)
if (i->n_netif > 0) {
for (c = 0; c < i->n_netif; c++) {
if (ifi < 0)
ifi = 0;
if (i->unit) {
static int map_netif(sd_bus *bus, const char *member, sd_bus_message *m, sd_bus_error *error, void *userdata) {
size_t l;
return -EBADMSG;
if (!i->netif)
return -ENOMEM;
path,
map,
&info);
if (*new_line)
*new_line = true;
if (*new_line)
*new_line = true;
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
&reply,
return bus_log_parse_error(r);
if (properties)
if (!arg_kill_who)
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
} control = {};
return -errno;
if (child < 0)
return -errno;
if (child == 0) {
if (master < 0)
return -EIO;
return -errno;
int *fds;
unsigned n_fds;
return -EIO;
if (master < 0)
return -EIO;
return master;
int r, ret = 0;
return -ENOTSUP;
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
&reply,
return bus_log_parse_error(r);
r = sd_bus_get_property(
bus,
path,
&error,
&reply2,
return bus_log_parse_error(r);
if (master < 0)
if (!pty) {
return -errno;
return -EIO;
if (!getty)
return log_oom();
return -errno;
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
return ret;
static void help(void) {
" show NAME... Show properties of one or more VMs/containers\n"
" terminate NAME... Terminate one or more VMs/containers\n",
help();
case ARG_VERSION:
return log_oom();
arg_all = true;
arg_all = true;
arg_full = true;
case ARG_NO_PAGER:
arg_no_pager = true;
case ARG_NO_LEGEND:
arg_legend = false;
case ARG_KILL_WHO:
if (arg_signal < 0) {
return -EINVAL;
return -EINVAL;
const char* verb;
MORE,
LESS,
} argc_cmp;
const int argc;
} verbs[] = {
int left;
if (left <= 0)
help();
return -EINVAL;
case EQUAL:
return -EINVAL;
case MORE:
return -EINVAL;
case LESS:
return -EINVAL;
log_open();
goto finish;
goto finish;
pager_close();