+ dbus_message_iter_get_basic(&iter, &name);
+
+ if (!valid_machine_name(name) ||
+ !dbus_message_iter_next(&iter) ||
+ dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_ARRAY ||
+ dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_BYTE)
+ return -EINVAL;
+
+ dbus_message_iter_recurse(&iter, &sub);
+ dbus_message_iter_get_fixed_array(&sub, &v, &n);
+
+ if (n == 0)
+ id = SD_ID128_NULL;
+ else if (n == 16)
+ memcpy(&id, v, n);
+ else
+ return -EINVAL;
+
+ if (!dbus_message_iter_next(&iter) ||
+ dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&iter, &service);
+
+ if (!dbus_message_iter_next(&iter) ||
+ dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&iter, &class);
+
+ if (isempty(class))
+ c = _MACHINE_CLASS_INVALID;
+ else {
+ c = machine_class_from_string(class);
+ if (c < 0)
+ return -EINVAL;
+ }
+
+ if (!dbus_message_iter_next(&iter) ||
+ dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_UINT32)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&iter, &leader);
+ if (!dbus_message_iter_next(&iter) ||
+ dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&iter, &slice);
+ if (!(isempty(slice) || (unit_name_is_valid(slice, false) && endswith(slice, ".slice"))) ||
+ !dbus_message_iter_next(&iter) ||
+ dbus_message_iter_get_arg_type(&iter) != DBUS_TYPE_STRING)
+ return -EINVAL;
+
+ dbus_message_iter_get_basic(&iter, &root_directory);
+
+ if (!(isempty(root_directory) || path_is_absolute(root_directory)))
+ return -EINVAL;
+
+ if (hashmap_get(manager->machines, name))
+ return -EEXIST;
+
+ if (leader <= 0) {
+ leader = bus_get_unix_process_id(manager->bus, dbus_message_get_sender(message), NULL);
+ if (leader == 0)
+ return -EINVAL;
+ }
+
+ r = manager_add_machine(manager, name, &m);
+ if (r < 0)
+ goto fail;
+
+ m->leader = leader;
+ m->class = c;
+ m->id = id;
+
+ if (!isempty(service)) {
+ m->service = strdup(service);
+ if (!m->service) {
+ r = -ENOMEM;
+ goto fail;
+ }
+ }
+
+ if (!isempty(slice)) {
+ m->slice = strdup(slice);
+ if (!m->slice) {
+ r = -ENOMEM;
+ goto fail;
+ }
+ }
+
+ if (!isempty(root_directory)) {
+ m->root_directory = strdup(root_directory);
+ if (!m->root_directory) {
+ r = -ENOMEM;
+ goto fail;
+ }
+ }
+
+ r = machine_start(m);
+ if (r < 0)
+ goto fail;
+
+ reply = dbus_message_new_method_return(message);
+ if (!reply) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ p = machine_bus_path(m);
+ if (!p) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ b = dbus_message_append_args(
+ reply,
+ DBUS_TYPE_OBJECT_PATH, &p,
+ DBUS_TYPE_INVALID);
+ if (!b) {
+ r = -ENOMEM;
+ goto fail;
+ }
+
+ *_reply = reply;
+ reply = NULL;
+ return 0;
+
+fail:
+ if (m)
+ machine_add_to_gc_queue(m);