summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLennart Poettering <lennart@poettering.net>2013-07-11 19:53:46 +0200
committerLennart Poettering <lennart@poettering.net>2013-07-11 19:53:46 +0200
commit554604b3073467af75dc94fac9e2343148603289 (patch)
treec02fe3cb7b64ce3188129c2cba63c8adfec1ee8a
parentc14901bdebb311531fb85b02c7c6eebf6e8e4388 (diff)
machined: forward scope properties array from client to systemd
This makes nspawn's --scope= switch work again.
-rw-r--r--src/machine/machine.c8
-rw-r--r--src/machine/machine.h2
-rw-r--r--src/machine/machined-dbus.c128
-rw-r--r--src/machine/machined.c2
-rw-r--r--src/machine/machined.h2
5 files changed, 132 insertions, 10 deletions
diff --git a/src/machine/machine.c b/src/machine/machine.c
index 591a656f1e..602aa18be6 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 7501fa372e..c5d52a968b 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 4664c73a9c..1e8bc609a3 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 c7c4ecc375..3ce51da90d 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 32a15fe1ab..780f51678c 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);