machined-dbus.c revision cba38758b4d49c6fe7c2f0eea255e11ee9df23eb
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik This file is part of systemd.
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik Copyright 2011 Lennart Poettering
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik systemd is free software; you can redistribute it and/or modify it
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik under the terms of the GNU Lesser General Public License as published by
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik the Free Software Foundation; either version 2.1 of the License, or
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik (at your option) any later version.
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik systemd is distributed in the hope that it will be useful, but
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik WITHOUT ANY WARRANTY; without even the implied warranty of
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik Lesser General Public License for more details.
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik You should have received a copy of the GNU Lesser General Public License
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik along with systemd; If not, see <http://www.gnu.org/licenses/>.
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <interface name=\"org.freedesktop.machine1.Manager\">\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <method name=\"GetMachine\">\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"machine\" type=\"o\" direction=\"out\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " </method>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <method name=\"GetMachineByPID\">\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"pid\" type=\"u\" direction=\"in\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"machine\" type=\"o\" direction=\"out\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " </method>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <method name=\"ListMachines\">\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"machines\" type=\"a(ssso)\" direction=\"out\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " </method>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <method name=\"CreateMachine\">\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"id\" type=\"ay\" direction=\"in\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"service\" type=\"s\" direction=\"in\"/>\n" \
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik " <arg name=\"class\" type=\"s\" direction=\"in\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"leader\" type=\"u\" direction=\"in\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"root_directory\" type=\"s\" direction=\"in\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"scope_properties\" type=\"a(sv)\" direction=\"in\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"path\" type=\"o\" direction=\"out\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " </method>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <method name=\"KillMachine\">\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"name\" type=\"s\" direction=\"in\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"who\" type=\"s\" direction=\"in\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"signal\" type=\"s\" direction=\"in\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " </method>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <method name=\"TerminateMachine\">\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"id\" type=\"s\" direction=\"in\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " </method>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <signal name=\"MachineNew\">\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"machine\" type=\"s\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"path\" type=\"o\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " </signal>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <signal name=\"MachineRemoved\">\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"machine\" type=\"s\"/>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " <arg name=\"path\" type=\"o\"/>\n" \
71e31fc573ba527f0d2be7929c2cb98037c860ecKnut Anders Hatlen " </signal>\n" \
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik " </interface>\n"
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik "org.freedesktop.machine1.Manager\0"
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikstatic bool valid_machine_name(const char *p) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik return false;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik return false;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik return false;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvikstatic int bus_manager_create_machine(Manager *manager, DBusMessage *message) {
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik const char *name, *service, *class, *root_directory;
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (!dbus_message_iter_init(message, &iter) ||
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE)
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik dbus_message_iter_get_fixed_array(&sub, &v, &n);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik else if (n == 16)
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik dbus_message_iter_get_basic(&iter, &service);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik dbus_message_iter_get_basic(&iter, &root_directory);
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik if (!(isempty(root_directory) || path_is_absolute(root_directory)))
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT)
8d22687fbdc540bd0b4d05fd90d87fb6037f4b9fJorgen Austvik leader = bus_get_unix_process_id(manager->bus, dbus_message_get_sender(message), NULL);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik m->create_message = dbus_message_ref(message);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvikstatic DBusHandlerResult manager_message_handler(
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik _cleanup_dbus_message_unref_ DBusMessage *reply = NULL;
71e31fc573ba527f0d2be7929c2cb98037c860ecKnut Anders Hatlen if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Manager", "GetMachine")) {
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik return bus_send_error_reply(connection, message, &error, -EINVAL);
71e31fc573ba527f0d2be7929c2cb98037c860ecKnut Anders Hatlen machine = hashmap_get(m->machines, name);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik return bus_send_error_reply(connection, message, &error, -ENOENT);
381a9b85cf2c73401fc1bff06c2e0d86389a5e88Jorgen Austvik reply = dbus_message_new_method_return(message);
goto oom;
free(p);
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Manager", "GetMachineByPID")) {
if (!dbus_message_get_args(
&error,
if (!reply)
goto oom;
goto oom;
free(p);
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Manager", "ListMachines")) {
Iterator i;
if (!reply)
goto oom;
goto oom;
const char *class;
goto oom;
goto oom;
free(p);
goto oom;
goto oom;
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Manager", "CreateMachine")) {
} else if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Manager", "KillMachine")) {
const char *swho;
const char *name;
if (!dbus_message_get_args(
&error,
if (who < 0)
if (!machine)
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.machine1.Manager", "TerminateMachine")) {
const char *name;
if (!dbus_message_get_args(
&error,
if (!machine)
if (!reply)
goto oom;
} else if (dbus_message_is_method_call(message, "org.freedesktop.DBus.Introspectable", "Introspect")) {
FILE *f;
Iterator i;
if (!reply)
goto oom;
goto oom;
free(p);
if (ferror(f)) {
fclose(f);
goto oom;
fclose(f);
if (!introspection)
goto oom;
goto oom;
if (reply) {
goto oom;
return DBUS_HANDLER_RESULT_HANDLED;
oom:
return DBUS_HANDLER_RESULT_NEED_MEMORY;
void *userdata) {
assert(m);
log_debug("Got message: %s %s %s", strna(dbus_message_get_sender(message)), strna(dbus_message_get_interface(message)), strna(dbus_message_get_member(message)));
goto finish;
if (mm) {
dbus_set_error(&error, BUS_ERROR_JOB_FAILED, "Start job for unit %s failed with '%s'", unit, result);
} else if (dbus_message_is_signal(message, "org.freedesktop.DBus.Properties", "PropertiesChanged")) {
const char *path;
if (!path)
goto finish;
if (unit) {
if (mm)
goto finish;
if (mm)
dbus_bool_t b;
DBUS_TYPE_BOOLEAN, &b,
goto finish;
Iterator i;
int type, r;
switch (type) {
case DBUS_TYPE_STRUCT: {
return log_oom();
return log_oom();
case DBUS_TYPE_ARRAY: {
if (!dbus_message_iter_open_container(dest, DBUS_TYPE_ARRAY, dbus_message_iter_get_signature(&src_sub), &dest_sub))
return log_oom();
return log_oom();
case DBUS_TYPE_VARIANT: {
if (!dbus_message_iter_open_container(dest, DBUS_TYPE_VARIANT, dbus_message_iter_get_signature(&src_sub), &dest_sub))
return log_oom();
return log_oom();
case DBUS_TYPE_STRING:
case DBUS_TYPE_OBJECT_PATH:
case DBUS_TYPE_BYTE:
case DBUS_TYPE_BOOLEAN:
case DBUS_TYPE_UINT16:
case DBUS_TYPE_INT16:
case DBUS_TYPE_UINT32:
case DBUS_TYPE_INT32:
case DBUS_TYPE_UINT64:
case DBUS_TYPE_INT64:
case DBUS_TYPE_DOUBLE:
case DBUS_TYPE_SIGNATURE: {
return -EINVAL;
int manager_start_scope(
const char *scope,
const char *slice,
const char *description,
char **job) {
uint32_t u;
if (!slice)
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
return log_oom();
return log_oom();
return log_oom();
return log_oom();
return log_oom();
u = pid;
return log_oom();
if (more_properties) {
return log_oom();
if (!reply)
return -EIO;
if (job) {
char *copy;
return -EIO;
if (!copy)
return -ENOMEM;
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
&reply,
if (job)
if (job) {
char *copy;
return -EIO;
if (!copy)
return -ENOMEM;
int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error) {
"org.freedesktop.systemd1",
"/org/freedesktop/systemd1",
"org.freedesktop.systemd1.Manager",
&reply,
DBUS_TYPE_STRING, &w,
const char *state;
if (!path)
return -ENOMEM;
"org.freedesktop.systemd1",
path,
&reply,
&error,
return -EINVAL;
return -EINVAL;