machinectl.c revision de33fc625725d199629ed074d6278504deb23deb
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync This file is part of systemd.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Copyright 2013 Lennart Poettering
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync systemd is free software; you can redistribute it and/or modify it
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync under the terms of the GNU Lesser General Public License as published by
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync the Free Software Foundation; either version 2.1 of the License, or
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync (at your option) any later version.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync systemd is distributed in the hope that it will be useful, but
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync WITHOUT ANY WARRANTY; without even the implied warranty of
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync Lesser General Public License for more details.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync You should have received a copy of the GNU Lesser General Public License
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync along with systemd; If not, see <http://www.gnu.org/licenses/>.
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic bool arg_all = false;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic bool arg_full = false;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic bool arg_no_pager = false;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic bool arg_legend = true;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic bool arg_read_only = false;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic bool arg_mkdir = false;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic void pager_open_if_enabled(void) {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync /* Cache result before we open the pager */
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic int list_machines(int argc, char *argv[], void *userdata) {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync unsigned k = 0;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync "org.freedesktop.machine1",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync "org.freedesktop.machine1.Manager",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync "ListMachines",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (r < 0) {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync log_error("Could not get machines: %s", bus_error_message(&error, -r));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync printf("%-32s %-9s %-16s\n", "MACHINE", "CONTAINER", "SERVICE");
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssso)");
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync while ((r = sd_bus_message_read(reply, "(ssso)", &name, &class, &service, &object)) > 0) {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync printf("%-32s %-9s %-16s\n", name, class, service);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsynctypedef struct ImageInfo {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync const char *name;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync const char *type;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic int compare_image_info(const void *a, const void *b) {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync const ImageInfo *x = a, *y = b;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsyncstatic int list_images(int argc, char *argv[], void *userdata) {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync size_t max_name = strlen("NAME"), max_type = strlen("TYPE");
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync "org.freedesktop.machine1",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync "org.freedesktop.machine1.Manager",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync "ListImages",
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (r < 0) {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync log_error("Could not get images: %s", bus_error_message(&error, -r));
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync r = sd_bus_message_enter_container(reply, SD_BUS_TYPE_ARRAY, "(ssbo)");
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync while ((r = sd_bus_message_read(reply, "(ssbo)", &name, &type, &read_only, &object)) > 0) {
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync if (!GREEDY_REALLOC(images, n_allocated, n_images + 1))
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync qsort_safe(images, n_images, sizeof(ImageInfo), compare_image_info);
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync printf("%-*s %-*s %-3s\n", (int) max_name, "NAME", (int) max_type, "TYPE", "RO");
3194da424708abdd288b28d96892b3a5f3f7df0bvboxsync for (j = 0; j < n_images; j++) {
return bus_log_parse_error(r);
if (arg_legend)
const char *cgroup;
int r, output_flags;
if (!path)
return log_oom();
r = sd_bus_get_property(
bus,
"org.freedesktop.systemd1",
path,
&error,
&reply,
return bus_log_parse_error(r);
c = columns();
show_cgroup_and_extra(SYSTEMD_CGROUP_CONTROLLER, cgroup, "\t\t ", c, false, &leader, leader > 0, output_flags);
static int print_addresses(sd_bus *bus, const char *name, int ifi, const char *prefix, const char *prefix2) {
"/org/freedesktop/machine1",
NULL,
&reply,
return bus_log_parse_error(r);
int family;
return bus_log_parse_error(r);
return bus_log_parse_error(r);
return bus_log_parse_error(r);
return bus_log_parse_error(r);
return bus_log_parse_error(r);
"/org/freedesktop/machine1",
NULL,
&reply,
return bus_log_parse_error(r);
pretty = v;
return bus_log_parse_error(r);
return bus_log_parse_error(r);
if (pretty)
typedef struct MachineStatusInfo {
char *name;
char *class;
char *service;
char *unit;
char *root_directory;
int *netif;
unsigned n_netif;
assert(i);
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,
const char *object;
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
&reply,
return bus_log_parse_error(r);
r = sd_bus_get_property(
bus,
&error,
&reply2,
return bus_log_parse_error(r);
char *dest, *host_path, *container_path, *host_dirname, *host_basename, *container_dirname, *container_basename, *t;
bool copy_from;
return -EINVAL;
if (child < 0)
if (child == 0) {
int containerfd;
int mntfd;
if (mntfd < 0) {
if (containerfd < 0) {
if (copy_from)
return -EIO;
return -EIO;
const char *dest;
return -EINVAL;
return -ENOTSUP;
mount_slave_created = true;
goto finish;
mount_slave_mounted = true;
goto finish;
goto finish;
mount_tmp_created = true;
goto finish;
mount_tmp_mounted = true;
if (arg_read_only)
goto finish;
goto finish;
mount_outside_created = true;
goto finish;
mount_outside_mounted = true;
mount_tmp_mounted = false;
mount_tmp_created = false;
mount_slave_mounted = false;
mount_slave_created = false;
if (child < 0) {
goto finish;
if (child == 0) {
const char *mount_inside;
int mntfd;
if (mntfd < 0) {
if (arg_mkdir)
goto finish;
r = -EIO;
goto finish;
r = -EIO;
goto finish;
if (mount_tmp_mounted)
if (mount_tmp_created)
if (mount_slave_mounted)
if (mount_slave_created)
const char *pty;
char last_char = 0;
return -ENOTSUP;
"/org/freedesktop/machine1",
return bus_log_create_error(r);
r = sd_bus_message_set_allow_interactive_authorization(m, true);
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_parse_error(r);
return ret;
" show NAME... Show properties of one or more VMs/containers\n"
" terminate NAME... Terminate one or more VMs/containers\n"
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;
case ARG_READ_ONLY:
arg_read_only = true;
case ARG_MKDIR:
arg_mkdir = true;
return -EINVAL;
log_open();
goto finish;
goto finish;
pager_close();