machinectl.c revision fefdc04b38725457a91651218feb7000f6ccc1f4
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering This file is part of systemd.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering Copyright 2013 Lennart Poettering
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering systemd is free software; you can redistribute it and/or modify it
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering under the terms of the GNU Lesser General Public License as published by
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering (at your option) any later version.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering systemd is distributed in the hope that it will be useful, but
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering Lesser General Public License for more details.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering You should have received a copy of the GNU Lesser General Public License
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic bool arg_all = false;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic bool arg_full = false;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic bool arg_no_pager = false;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic bool arg_legend = true;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
cf1d700da3fe04cd4c27980a292301694be3b05fTom Gundersenstatic bool arg_read_only = false;
91b5f997316ddc77d26f9a7a5e24c335484586bdTom Gundersenstatic bool arg_mkdir = false;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic void pager_open_if_enabled(void) {
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poettering /* Cache result before we open the pager */
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic int list_machines(int argc, char *argv[], void *userdata) {
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
&reply,
if (arg_legend)
return bus_log_parse_error(r);
return bus_log_parse_error(r);
return bus_log_parse_error(r);
if (arg_legend)
typedef struct ImageInfo {
const char *name;
const char *type;
bool read_only;
} ImageInfo;
static int compare_image_info(const void *a, const void *b) {
const ImageInfo *x = a, *y = b;
size_t max_name = strlen("NAME"), max_type = strlen("TYPE"), max_crtime = strlen("CREATED"), max_mtime = strlen("MODIFIED");
int read_only, r;
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
&reply,
return bus_log_parse_error(r);
while ((r = sd_bus_message_read(reply, "(ssbtto)", &name, &type, &read_only, &crtime, &mtime, &object)) > 0) {
size_t l;
return log_oom();
if (l > max_name)
max_name = l;
if (l > max_type)
max_type = l;
if (crtime != 0) {
if (l > max_crtime)
max_crtime = l;
if (mtime != 0) {
if (l > max_mtime)
max_mtime = l;
n_images++;
return bus_log_parse_error(r);
return bus_log_parse_error(r);
if (arg_legend)
for (j = 0; j < n_images; j++) {
images[j].read_only ? ansi_highlight_red() : "", yes_no(images[j].read_only), images[j].read_only ? ansi_highlight_off() : "",
(int) max_crtime, images[j].crtime != 0 ? format_timestamp(crtime_buf, sizeof(crtime_buf), images[j].crtime) : "-",
(int) max_mtime, images[j].mtime != 0 ? format_timestamp(mtime_buf, sizeof(mtime_buf), images[j].mtime) : "-");
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)
typedef struct ImageStatusInfo {
char *name;
char *path;
char *type;
int read_only;
assert(i);
if (i->name) {
if (i->path)
if (i->path)
if (s1)
else if (s2)
if (s1)
else if (s2)
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();