From 554604b3073467af75dc94fac9e2343148603289 Mon Sep 17 00:00:00 2001 From: Lennart Poettering Date: Thu, 11 Jul 2013 19:53:46 +0200 Subject: [PATCH] machined: forward scope properties array from client to systemd This makes nspawn's --scope= switch work again. --- src/machine/machine.c | 8 +-- src/machine/machine.h | 2 +- src/machine/machined-dbus.c | 128 +++++++++++++++++++++++++++++++++++- src/machine/machined.c | 2 +- src/machine/machined.h | 2 +- 5 files changed, 132 insertions(+), 10 deletions(-) diff --git a/src/machine/machine.c b/src/machine/machine.c index 591a656f1..602aa18be 100644 --- a/src/machine/machine.c +++ b/src/machine/machine.c @@ -217,7 +217,7 @@ int machine_load(Machine *m) { return r; } -static int machine_start_scope(Machine *m) { +static int machine_start_scope(Machine *m, DBusMessageIter *iter) { _cleanup_free_ char *description = NULL; DBusError error; char *job; @@ -241,7 +241,7 @@ static int machine_start_scope(Machine *m) { description = strappend(m->class == MACHINE_VM ? "Virtual Machine " : "Container ", m->name); - r = manager_start_scope(m->manager, scope, m->leader, SPECIAL_MACHINE_SLICE, description, &error, &job); + r = manager_start_scope(m->manager, scope, m->leader, SPECIAL_MACHINE_SLICE, description, iter, &error, &job); if (r < 0) { log_error("Failed to start machine scope: %s", bus_error(&error, r)); dbus_error_free(&error); @@ -262,7 +262,7 @@ static int machine_start_scope(Machine *m) { return r; } -int machine_start(Machine *m) { +int machine_start(Machine *m, DBusMessageIter *iter) { int r; assert(m); @@ -271,7 +271,7 @@ int machine_start(Machine *m) { return 0; /* Create cgroup */ - r = machine_start_scope(m); + r = machine_start_scope(m, iter); if (r < 0) return r; diff --git a/src/machine/machine.h b/src/machine/machine.h index 7501fa372..c5d52a968 100644 --- a/src/machine/machine.h +++ b/src/machine/machine.h @@ -82,7 +82,7 @@ Machine* machine_new(Manager *manager, const char *name); void machine_free(Machine *m); int machine_check_gc(Machine *m, bool drop_not_started); void machine_add_to_gc_queue(Machine *m); -int machine_start(Machine *m); +int machine_start(Machine *m, DBusMessageIter *iter); int machine_stop(Machine *m); int machine_save(Machine *m); int machine_load(Machine *m); diff --git a/src/machine/machined-dbus.c b/src/machine/machined-dbus.c index 4664c73a9..1e8bc609a 100644 --- a/src/machine/machined-dbus.c +++ b/src/machine/machined-dbus.c @@ -185,6 +185,13 @@ static int bus_manager_create_machine(Manager *manager, DBusMessage *message) { if (!(isempty(root_directory) || path_is_absolute(root_directory))) return -EINVAL; + if (!dbus_message_iter_next(&iter) || + dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY || + dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_STRUCT) + return -EINVAL; + + dbus_message_iter_recurse(&iter, &sub); + if (hashmap_get(manager->machines, name)) return -EEXIST; @@ -218,7 +225,7 @@ static int bus_manager_create_machine(Manager *manager, DBusMessage *message) { } } - r = machine_start(m); + r = machine_start(m, &sub); if (r < 0) goto fail; @@ -614,12 +621,118 @@ finish: return DBUS_HANDLER_RESULT_NOT_YET_HANDLED; } +static int copy_many_fields(DBusMessageIter *dest, DBusMessageIter *src); + +static int copy_one_field(DBusMessageIter *dest, DBusMessageIter *src) { + int type, r; + + type = dbus_message_iter_get_arg_type(src); + + switch (type) { + + case DBUS_TYPE_STRUCT: { + DBusMessageIter dest_sub, src_sub; + + dbus_message_iter_recurse(src, &src_sub); + + if (!dbus_message_iter_open_container(dest, DBUS_TYPE_STRUCT, NULL, &dest_sub)) + return log_oom(); + + r = copy_many_fields(&dest_sub, &src_sub); + if (r < 0) + return r; + + if (!dbus_message_iter_close_container(dest, &dest_sub)) + return log_oom(); + + return 0; + } + + case DBUS_TYPE_ARRAY: { + DBusMessageIter dest_sub, src_sub; + + dbus_message_iter_recurse(src, &src_sub); + + if (!dbus_message_iter_open_container(dest, DBUS_TYPE_ARRAY, dbus_message_iter_get_signature(&src_sub), &dest_sub)) + return log_oom(); + + r = copy_many_fields(&dest_sub, &src_sub); + if (r < 0) + return r; + + if (!dbus_message_iter_close_container(dest, &dest_sub)) + return log_oom(); + + return 0; + } + + case DBUS_TYPE_VARIANT: { + DBusMessageIter dest_sub, src_sub; + + dbus_message_iter_recurse(src, &src_sub); + + if (!dbus_message_iter_open_container(dest, DBUS_TYPE_VARIANT, dbus_message_iter_get_signature(&src_sub), &dest_sub)) + return log_oom(); + + r = copy_one_field(&dest_sub, &src_sub); + if (r < 0) + return r; + + if (!dbus_message_iter_close_container(dest, &dest_sub)) + return log_oom(); + + return 0; + } + + 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: { + const void *p; + + dbus_message_iter_get_basic(src, &p); + dbus_message_iter_append_basic(dest, type, &p); + return 0; + } + + default: + return -EINVAL; + } +} + +static int copy_many_fields(DBusMessageIter *dest, DBusMessageIter *src) { + int r; + + assert(dest); + assert(src); + + while (dbus_message_iter_get_arg_type(src) != DBUS_TYPE_INVALID) { + + r = copy_one_field(dest, src); + if (r < 0) + return r; + + dbus_message_iter_next(src); + } + + return 0; +} + int manager_start_scope( Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, + DBusMessageIter *more_properties, DBusError *error, char **job) { @@ -630,6 +743,7 @@ int manager_start_scope( uint64_t timeout = 500 * USEC_PER_MSEC; const char *fail = "fail"; uint32_t u; + int r; assert(manager); assert(scope); @@ -698,8 +812,16 @@ int manager_start_scope( !dbus_message_iter_append_basic(&sub4, DBUS_TYPE_UINT32, &u) || !dbus_message_iter_close_container(&sub3, &sub4) || !dbus_message_iter_close_container(&sub2, &sub3) || - !dbus_message_iter_close_container(&sub, &sub2) || - !dbus_message_iter_close_container(&iter, &sub)) + !dbus_message_iter_close_container(&sub, &sub2)) + return log_oom(); + + if (more_properties) { + r = copy_many_fields(&sub, more_properties); + if (r < 0) + return r; + } + + if (!dbus_message_iter_close_container(&iter, &sub)) return log_oom(); reply = dbus_connection_send_with_reply_and_block(manager->bus, m, -1, error); diff --git a/src/machine/machined.c b/src/machine/machined.c index c7c4ecc37..3ce51da90 100644 --- a/src/machine/machined.c +++ b/src/machine/machined.c @@ -330,7 +330,7 @@ int manager_startup(Manager *m) { /* And start everything */ HASHMAP_FOREACH(machine, m->machines, i) - machine_start(machine); + machine_start(machine, NULL); return 0; } diff --git a/src/machine/machined.h b/src/machine/machined.h index 32a15fe1a..780f51678 100644 --- a/src/machine/machined.h +++ b/src/machine/machined.h @@ -67,7 +67,7 @@ extern const DBusObjectPathVTable bus_manager_vtable; DBusHandlerResult bus_message_filter(DBusConnection *c, DBusMessage *message, void *userdata); -int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, DBusError *error, char **job); +int manager_start_scope(Manager *manager, const char *scope, pid_t pid, const char *slice, const char *description, DBusMessageIter *more_properties, DBusError *error, char **job); int manager_stop_unit(Manager *manager, const char *unit, DBusError *error, char **job); int manager_kill_unit(Manager *manager, const char *unit, KillWho who, int signo, DBusError *error); int manager_unit_is_active(Manager *manager, const char *unit); -- 2.30.2