machined-dbus.c revision ebd93cb684806ac0f352139e69ac8f53eb49f5e4
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering This file is part of systemd.
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering Copyright 2011 Lennart Poettering
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering systemd is free software; you can redistribute it and/or modify it
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering under the terms of the GNU Lesser General Public License as published by
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering the Free Software Foundation; either version 2.1 of the License, or
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering (at your option) any later version.
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering systemd is distributed in the hope that it will be useful, but
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering WITHOUT ANY WARRANTY; without even the implied warranty of
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering Lesser General Public License for more details.
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering You should have received a copy of the GNU Lesser General Public License
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering along with systemd; If not, see <http://www.gnu.org/licenses/>.
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poetteringstatic int method_get_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering r = sd_bus_message_read(message, "s", &name);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering machine = hashmap_get(m->machines, name);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_MACHINE, "No machine '%s' known", name);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering return sd_bus_reply_method_return(message, "o", p);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poetteringstatic int method_get_image(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering r = sd_bus_message_read(message, "s", &name);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_SUCH_IMAGE, "No image '%s' known", name);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering return sd_bus_reply_method_return(message, "o", p);
d5099efc47d4e6ac60816b5381a5f607ab03f06eMichal Schmidtstatic int method_get_machine_by_pid(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering assert_cc(sizeof(pid_t) == sizeof(uint32_t));
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering r = sd_bus_message_read(message, "u", &pid);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering _cleanup_bus_creds_unref_ sd_bus_creds *creds = NULL;
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering r = sd_bus_query_sender_creds(message, SD_BUS_CREDS_PID, &creds);
ef42202ac8ed27e7ff1fc90ef8bc2590046dff25Zbigniew Jędrzejewski-Szmek r = manager_get_machine_by_pid(m, pid, &machine);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering return sd_bus_error_setf(error, BUS_ERROR_NO_MACHINE_FOR_PID, "PID "PID_FMT" does not belong to any known machine", pid);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering return sd_bus_reply_method_return(message, "o", p);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poetteringstatic int method_list_machines(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering _cleanup_bus_message_unref_ sd_bus_message *reply = NULL;
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering r = sd_bus_message_new_method_return(message, &reply);
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering r = sd_bus_message_open_container(reply, 'a', "(ssso)");
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering HASHMAP_FOREACH(machine, m->machines, i) {
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering r = sd_bus_message_append(reply, "(ssso)",
30bdd695250eeecbf0b36c1e3c90d67ca03953edLennart Poettering strempty(machine_class_to_string(machine->class)),
static int method_create_or_register_machine(Manager *manager, sd_bus_message *message, bool read_network, Machine **_m, sd_bus_error *error) {
MachineClass c;
Machine *m;
if (read_network) {
size_t i;
for (i = 0; i < n_netif; i++) {
if (netif[i] <= 0)
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Invalid network interface index %i", netif[i]);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Root directory must be empty or an absolute path");
if (leader == 0) {
m->class = c;
if (!m->service) {
r = -ENOMEM;
goto fail;
if (!m->root_directory) {
r = -ENOMEM;
goto fail;
if (n_netif > 0) {
if (!m->netif) {
r = -ENOMEM;
goto fail;
*_m = m;
fail:
static int method_create_machine_internal(sd_bus *bus, sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
goto fail;
goto fail;
fail:
static int method_create_machine_with_network(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
static int method_create_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
static int method_register_machine_internal(sd_bus *bus, sd_bus_message *message, bool read_network, void *userdata, sd_bus_error *error) {
r = sd_bus_error_set_errnof(error, r, "Failed to determine unit of process "PID_FMT" : %s", m->leader, strerror(-r));
goto fail;
m->registered = true;
goto fail;
p = machine_bus_path(m);
r = -ENOMEM;
goto fail;
fail:
static int method_register_machine_with_network(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
static int method_register_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
static int method_terminate_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
assert(m);
if (!machine)
static int method_kill_machine(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
assert(m);
if (!machine)
static int method_get_machine_addresses(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
assert(m);
if (!machine)
static int method_get_machine_os_release(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
assert(m);
if (!machine)
static int method_list_images(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
Iterator i;
assert(m);
if (!images)
return -ENOMEM;
return -ENOMEM;
static int method_open_machine_pty(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
assert(m);
if (!machine)
static int method_open_machine_login(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
assert(m);
if (!machine)
static int method_remove_image(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
r = image_remove(i);
static int method_rename_image(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
static int method_clone_image(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
int read_only, r;
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", old_name);
return sd_bus_error_setf(error, SD_BUS_ERROR_INVALID_ARGS, "Image name '%s' is invalid.", new_name);
static int method_mark_image_read_only(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *name;
int read_only, r;
SD_BUS_METHOD("CreateMachineWithNetwork", "sayssusaia(sv)", "o", method_create_machine_with_network, 0),
SD_BUS_METHOD("RegisterMachineWithNetwork", "sayssusai", "o", method_register_machine_with_network, 0),
SD_BUS_METHOD("TerminateMachine", "s", NULL, method_terminate_machine, SD_BUS_VTABLE_CAPABILITY(CAP_KILL)),
SD_BUS_METHOD("GetMachineAddresses", "s", "a(iay)", method_get_machine_addresses, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("GetMachineOSRelease", "s", "a{ss}", method_get_machine_os_release, SD_BUS_VTABLE_UNPRIVILEGED),
SD_BUS_METHOD("OpenMachineLogin", "s", "hs", method_open_machine_login, SD_BUS_VTABLE_UNPRIVILEGED),
assert(m);
if (!machine)
sd_bus_error_setf(&e, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
int match_properties_changed(sd_bus *bus, sd_bus_message *message, void *userdata, sd_bus_error *error) {
const char *path;
assert(m);
if (!path)
if (machine)
assert(m);
if (machine)
Iterator i;
int manager_start_scope(
const char *scope,
const char *slice,
const char *description,
char **job) {
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
if (more_properties) {
r = sd_bus_message_close_container(m);
if (job) {
char *copy;
if (!copy)
return -ENOMEM;
r = sd_bus_call_method(
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
&reply,
if (job)
if (job) {
char *copy;
if (!copy)
return -ENOMEM;
return sd_bus_call_method(
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
NULL,
const char *state;
if (!path)
return -ENOMEM;
r = sd_bus_get_property(
"org.freedesktop.systemd1",
path,
"org.freedesktop.systemd1.Unit",
&error,
&reply,
return -EINVAL;
r = sd_bus_get_property(
"org.freedesktop.systemd1",
path,
"org.freedesktop.systemd1.Job",
&error,
&reply,
assert(m);
if (!mm)
assert(m);
if (!machine) {
if (!machine)
return -ENOMEM;
if (_machine)