machinectl.c revision bf441e3d9371a7e5aa1def66cfc40f0118884644
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster This file is part of systemd.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Copyright 2013 Lennart Poettering
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster systemd is free software; you can redistribute it and/or modify it
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster under the terms of the GNU Lesser General Public License as published by
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster the Free Software Foundation; either version 2.1 of the License, or
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster (at your option) any later version.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster systemd is distributed in the hope that it will be useful, but
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster WITHOUT ANY WARRANTY; without even the implied warranty of
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster Lesser General Public License for more details.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster You should have received a copy of the GNU Lesser General Public License
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster along with systemd; If not, see <http://www.gnu.org/licenses/>.
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic bool arg_all = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic bool arg_full = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic bool arg_no_pager = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic bool arg_legend = true;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic BusTransport arg_transport = BUS_TRANSPORT_LOCAL;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic bool arg_read_only = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic bool arg_mkdir = false;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic void pager_open_if_enabled(void) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster /* Cache result before we open the pager */
8af80418ba1ec431c8027fa9668e5678658d3611Allan Fosterstatic int list_machines(int argc, char *argv[], void *userdata) {
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster _cleanup_bus_error_free_ sd_bus_error error = SD_BUS_ERROR_NULL;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster unsigned k = 0;
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "org.freedesktop.machine1",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "org.freedesktop.machine1.Manager",
8af80418ba1ec431c8027fa9668e5678658d3611Allan Foster "ListMachines",
&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;
int read_only;
r = sd_bus_call_method(
bus,
"/org/freedesktop/machine1",
&error,
&reply,
return bus_log_parse_error(r);
return log_oom();
n_images++;
return bus_log_parse_error(r);
return bus_log_parse_error(r);
if (arg_legend)
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",
&error,
&reply,
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();