machine-dbus.c revision c7abe32be167ded048a5bb8a912faf2e745b20cb
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering This file is part of systemd.
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering Copyright 2011 Lennart Poettering
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering systemd is free software; you can redistribute it and/or modify it
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering under the terms of the GNU Lesser General Public License as published by
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering the Free Software Foundation; either version 2.1 of the License, or
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering (at your option) any later version.
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering systemd is distributed in the hope that it will be useful, but
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering Lesser General Public License for more details.
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering You should have received a copy of the GNU Lesser General Public License
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering r = sd_bus_message_append_array(reply, 'y', &m->id, 16);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering state = machine_state_to_string(machine_get_state(m));
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering r = sd_bus_message_append_basic(reply, 's', state);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering assert_cc(sizeof(int) == sizeof(int32_t));
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering r = sd_bus_message_append_array(reply, 'i', m->netif, m->n_netif * sizeof(int));
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringstatic BUS_DEFINE_PROPERTY_GET_ENUM(property_get_class, machine_class, MachineClass);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringint bus_machine_method_terminate(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return sd_bus_reply_method_return(message, NULL);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringint bus_machine_method_kill(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering r = sd_bus_message_read(message, "si", &swho, &signo);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid kill parameter '%s'", swho);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid signal %i", signo);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return sd_bus_reply_method_return(message, NULL);
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poetteringint bus_machine_method_get_addresses(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering _cleanup_close_pair_ int pair[2] = { -1, -1 };
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering _cleanup_free_ char *us = NULL, *them = NULL;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering const char *p;
07630cea1f3a845c09309f197ac7c4f11edd3b62Lennart Poettering return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Requesting IP address data is only supported on container machines.");
f3e2e81d5385b9ffd84ed110d00eb347ec0e14f1Lennart Poettering r = readlink_malloc("/proc/self/ns/net", &us);
return sd_bus_error_setf(error, BUS_ERROR_NO_PRIVATE_NETWORKING, "Machine %s does not use private networking", m->name);
return -errno;
if (child < 0)
if (child == 0) {
struct local_address *a;
for (a = addresses, i = 0; i < n; a++, i++) {
int family;
ssize_t n;
return -errno;
switch (family) {
case AF_INET:
return -EIO;
case AF_INET6:
return -EIO;
int bus_machine_method_get_os_release(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Requesting OS release data is only supported on container machines.");
return -errno;
if (child < 0)
if (child == 0) {
if (fd < 0) {
if (fd < 0)
return -errno;
STRV_FOREACH_PAIR(k, v, l) {
int bus_machine_method_open_pty(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
assert(m);
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Opening pseudo TTYs is only supported on container machines.");
if (master < 0)
return master;
int bus_machine_method_open_login(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Opening logins is only supported on container machines.");
error);
if (master < 0)
return master;
return -errno;
#ifdef ENABLE_KDBUS
asprintf(&container_bus->address, "x-machine-kernel:pid=" PID_FMT ";x-machine-unix:pid=" PID_FMT, m->leader, m->leader);
return log_oom();
if (!getty)
return log_oom();
r = sd_bus_call_method(
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
int bus_machine_method_bind_mount(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Bind mounting is only supported on container machines.");
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Source path must be absolute and not contain ../.");
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Destination path must be absolute and not contain ../.");
return sd_bus_error_setf(error, SD_BUS_ERROR_NOT_SUPPORTED, "Container does not allow propagation of mount points.");
mount_slave_created = true;
goto finish;
mount_slave_mounted = true;
goto finish;
r = sd_bus_error_set_errnof(error, errno, "Failed to create temporary mount point %s: %m", mount_tmp);
goto finish;
mount_tmp_created = true;
goto finish;
mount_tmp_mounted = true;
if (read_only)
goto finish;
r = sd_bus_error_set_errnof(error, errno, "Cannot create propagation directory %s: %m", mount_outside);
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;
goto finish;
if (child < 0) {
goto finish;
if (child == 0) {
const char *mount_inside;
int mntfd;
if (mntfd < 0) {
goto child_fail;
goto child_fail;
if (make_directory)
goto child_fail;
goto finish;
goto finish;
goto finish;
if (mount_tmp_mounted)
if (mount_tmp_created)
if (mount_slave_mounted)
if (mount_slave_created)
BUS_PROPERTY_DUAL_TIMESTAMP("Timestamp", offsetof(Machine, timestamp), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("Scope", "s", NULL, offsetof(Machine, unit), SD_BUS_VTABLE_PROPERTY_CONST|SD_BUS_VTABLE_HIDDEN),
SD_BUS_PROPERTY("Class", "s", property_get_class, offsetof(Machine, class), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_PROPERTY("RootDirectory", "s", NULL, offsetof(Machine, root_directory), SD_BUS_VTABLE_PROPERTY_CONST),
SD_BUS_METHOD("Terminate", NULL, NULL, bus_machine_method_terminate, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
SD_BUS_METHOD("GetAddresses", NULL, "a(iay)", bus_machine_method_get_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetOSRelease", NULL, "a{ss}", bus_machine_method_get_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
int machine_object_find(sd_bus *bus, const char *path, const char *interface, void *userdata, void **found, sd_bus_error *error) {
assert(m);
if (!message)
e = bus_label_unescape(p);
return -ENOMEM;
if (!machine)
assert(m);
return NULL;
int machine_node_enumerator(sd_bus *bus, const char *path, void *userdata, char ***nodes, sd_bus_error *error) {
Iterator i;
return -ENOMEM;
r = strv_consume(&l, p);
*nodes = l;
l = NULL;
assert(m);
p = machine_bus_path(m);
return -ENOMEM;
return sd_bus_emit_signal(
"/org/freedesktop/machine1",
assert(m);
if (!m->create_message)
c = m->create_message;
if (error)
machine_save(m);
p = machine_bus_path(m);
return -ENOMEM;