machinectl.c revision b43d75c378d919900e5c1e82a82e3e17dd3de9f9
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/>.
cf1d700da3fe04cd4c27980a292301694be3b05fTom Gundersenstatic bool arg_all = false;
36c32f6120a0c3fe19be5aeaa1926e179e8c29baTom Gundersenstatic bool arg_full = false;
91b5f997316ddc77d26f9a7a5e24c335484586bdTom Gundersenstatic bool arg_no_pager = false;
6666907869fb3bc7fe6a6025540db5b887c7a78bTom Gundersenstatic bool arg_legend = true;
ce6c77ebf12f80c807ad7589a1fb565fabc6a543Tom Gundersenstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic bool arg_read_only = false;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic bool arg_mkdir = false;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic bool arg_quiet = false;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic bool arg_ask_password = true;
fc2f9534d07db2b185c02b1961428b53daf1986eLennart Poetteringstatic OutputMode arg_output = OUTPUT_SHORT;
static bool arg_force = false;
static void pager_open_if_enabled(void) {
if (arg_no_pager)
pager_open(false);
static void polkit_agent_open_if_enabled(void) {
if (!arg_ask_password)
typedef struct MachineInfo {
const char *name;
const char *class;
const char *service;
} MachineInfo;
static int compare_machine_info(const void *a, const void *b) {
const MachineInfo *x = a, *y = b;
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
&reply,
NULL);
return bus_log_parse_error(r);
size_t l;
return log_oom();
if (l > max_name)
max_name = l;
if (l > max_class)
max_class = l;
if (l > max_service)
max_service = l;
n_machines ++;
return bus_log_parse_error(r);
return bus_log_parse_error(r);
if (arg_legend)
for (j = 0; j < n_machines; j++)
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_size = strlen("USAGE"), 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, "(ssbttto)", &name, &type, &read_only, &crtime, &mtime, &size, &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;
if (l > max_size)
max_size = 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_normal() : "",
if (arg_legend)
const char *cgroup;
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, get_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;
if (info) {
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) {
i->unit,
NULL);
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;
if (info) {
assert(i);
if (i->name) {
if (i->type)
if (i->path)
else if (s2)
else if (s2)
s4 = i->usage_exclusive != i->usage ? format_bytes(bs_exclusive, sizeof(bs_exclusive), i->usage_exclusive) : NULL;
else if (s3)
s4 = i->limit_exclusive != i->limit ? format_bytes(bs_exclusive, sizeof(bs_exclusive), i->limit_exclusive) : NULL;
else if (s3)
path,
map,
&info);
if (*new_line)
*new_line = true;
typedef struct PoolStatusInfo {
char *path;
if (info) {
if (i->path)
"/org/freedesktop/machine1",
map,
&info);
if (*new_line)
*new_line = true;
if (properties)
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,
bool copy_from;
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
assert(m);
if (*forward) {
static int process_forward(sd_event *event, PTYForward **forward, int master, PTYForwardFlags flags, const char *name) {
char last_char = 0;
bool machine_died;
int ret = 0, r;
if (machine_died)
return ret;
return -EINVAL;
return -EOPNOTSUPP;
"path='/org/freedesktop/machine1',",
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
&reply,
return bus_log_parse_error(r);
return -EOPNOTSUPP;
return log_oom();
if (arg_uid)
else if (machine) {
const char *at;
if (at) {
"path='/org/freedesktop/machine1',",
bus,
"/org/freedesktop/machine1",
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_parse_error(r);
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
return -EINVAL;
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
return -EINVAL;
return log_oom();
return log_oom();
const char *object;
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
&error,
&reply,
return bus_log_parse_error(r);
return log_oom();
int carries_install_info = 0;
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
method);
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_create_error(r);
r = sd_bus_message_close_container(m);
return bus_log_create_error(r);
return bus_log_create_error(r);
return bus_log_parse_error(r);
r = sd_bus_call_method(
bus,
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
&error,
NULL,
NULL);
unsigned priority;
assert(m);
assert(m);
static int transfer_signal_handler(sd_event_source *s, const struct signalfd_siginfo *si, void *userdata) {
assert(s);
if (!arg_quiet)
log_info("Continuing download in the background. Use \"machinectl cancel-transfer %" PRIu32 "\" to abort transfer.", PTR_TO_UINT32(userdata));
assert(m);
r = sd_bus_add_match(
bus,
"path='/org/freedesktop/import1'",
r = sd_bus_add_match(
bus,
return bus_log_parse_error(r);
if (!arg_quiet)
else if (path)
if (!local) {
return -EINVAL;
return log_oom();
return -EINVAL;
if (path) {
if (fd < 0)
bus,
"/org/freedesktop/import1",
return bus_log_create_error(r);
return bus_log_create_error(r);
else if (path)
if (!local) {
return -EINVAL;
return log_oom();
return -EINVAL;
if (path) {
if (fd < 0)
bus,
"/org/freedesktop/import1",
return bus_log_create_error(r);
return bus_log_create_error(r);
static void determine_compression_from_filename(const char *p) {
if (arg_format)
return -EINVAL;
if (path) {
if (fd < 0)
bus,
"/org/freedesktop/import1",
return bus_log_create_error(r);
return bus_log_create_error(r);
return -EINVAL;
if (path) {
if (fd < 0)
bus,
"/org/freedesktop/import1",
return bus_log_create_error(r);
return bus_log_create_error(r);
return -EINVAL;
local = l;
if (local) {
return log_oom();
return -EINVAL;
bus,
"/org/freedesktop/import1",
return bus_log_create_error(r);
return bus_log_create_error(r);
return -EINVAL;
local = l;
if (local) {
return log_oom();
return -EINVAL;
bus,
"/org/freedesktop/import1",
return bus_log_create_error(r);
return bus_log_create_error(r);
typedef struct TransferInfo {
const char *type;
const char *remote;
const char *local;
double progress;
} TransferInfo;
static int compare_transfer_info(const void *a, const void *b) {
const TransferInfo *x = a, *y = b;
double progress;
r = sd_bus_call_method(
bus,
"/org/freedesktop/import1",
&error,
&reply,
NULL);
return bus_log_parse_error(r);
while ((r = sd_bus_message_read(reply, "(usssdo)", &id, &type, &remote, &local, &progress, &object)) > 0) {
size_t l;
return log_oom();
if (l > max_type)
max_type = l;
if (l > max_remote)
max_remote = l;
if (l > max_local)
max_local = l;
n_transfers ++;
return bus_log_parse_error(r);
return bus_log_parse_error(r);
if (arg_legend)
for (j = 0; j < n_transfers; j++)
if (arg_legend)
r = sd_bus_call_method(
bus,
"/org/freedesktop/import1",
&error,
NULL,
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
NULL,
" show [NAME...] Show properties of one or more VMs/containers\n"
" terminate NAME... Terminate one or more VMs/containers\n"
case ARG_VERSION:
return version();
return log_oom();
arg_all = true;
arg_all = true;
arg_full = true;
return -EINVAL;
if (arg_output < 0) {
return -EINVAL;
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_NO_ASK_PASSWORD:
arg_ask_password = false;
case ARG_READ_ONLY:
arg_read_only = true;
case ARG_MKDIR:
arg_mkdir = true;
arg_quiet = true;
case ARG_VERIFY:
if (arg_verify < 0) {
return -EINVAL;
case ARG_FORCE:
arg_force = true;
case ARG_FORMAT:
return -EINVAL;
case ARG_UID:
case ARG_SETENV:
return -EINVAL;
return log_oom();
return -EINVAL;
log_open();
goto finish;
goto finish;
pager_close();