@@ -54,6 +54,15 @@
#include "qemu/config-file.h"
#include "monitor/qdev.h"
#include "qapi/qmp/qdict.h"
+#include "sysemu/sysemu.h"
+#include "sysemu/blockdev.h"
+#include "block/block.h"
+#include "qapi/qmp/qstring.h"
+#include "hw/qdev-properties.h"
+#include "hw/scsi/scsi.h"
+#include "block/qdict.h"
+#include "qapi/qmp/qlist.h"
+#include "qemu/log.h"
static ProxyLinkState *proxy_link;
PCIDevice *remote_pci_dev;
@@ -223,6 +232,107 @@ fail:
PUT_REMOTE_WAIT(wait);
}
+static int init_drive(QDict *rqdict, Error **errp)
+{
+ QemuOpts *opts;
+ Error *local_error = NULL;
+
+ if (rqdict != NULL && qdict_size(rqdict) > 0) {
+ opts = qemu_opts_from_qdict(&qemu_drive_opts,
+ rqdict, &local_error);
+ if (!opts) {
+ error_propagate(errp, local_error);
+ return -EINVAL;
+ }
+ } else {
+ return -EINVAL;
+ }
+ if (drive_new(opts, IF_IDE, &local_error) == NULL) {
+ error_propagate(errp, local_error);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int setup_drive(ProcMsg *msg, Error **errp)
+{
+ QObject *obj;
+ QDict *qdict;
+ QString *qstr;
+ Error *local_error = NULL;
+ int rc = -EINVAL;
+
+ if (!msg->data2) {
+ return rc;
+ }
+
+ qstr = qstring_from_str((char *)msg->data2);
+ obj = qobject_from_json(qstring_get_str(qstr), errp);
+ if (!obj) {
+ return rc;
+ }
+
+ qdict = qobject_to(QDict, obj);
+ if (!qdict) {
+ return rc;
+ }
+
+ qdict_del(qdict, "rid");
+ if (init_drive(qdict, &local_error)) {
+ error_propagate(errp, local_error);
+ return rc;
+ }
+
+ return 0;
+}
+
+static int setup_device(ProcMsg *msg, Error **errp)
+{
+ QObject *obj;
+ QDict *qdict;
+ QString *qstr;
+ QemuOpts *opts;
+ DeviceState *dev = NULL;
+ int rc = -EINVAL;
+
+ if (!msg->data2) {
+ return rc;
+ }
+
+ qstr = qstring_from_str((char *)msg->data2);
+
+ obj = qobject_from_json(qstring_get_str(qstr), errp);
+ if (!obj) {
+ error_setg(errp, "Could not convert to json object.");
+ return rc;
+ }
+
+ qdict = qobject_to(QDict, obj);
+ if (!qdict) {
+ return rc;
+ }
+
+ g_assert(qdict_size(qdict) > 1);
+
+ qdict_del(qdict, "command");
+ qdict_del(qdict, "rid");
+
+ opts = qemu_opts_from_qdict(&qemu_device_opts, qdict, errp);
+
+ dev = qdev_device_add(opts, errp);
+ if (!dev) {
+ error_setg(errp, "Could not add device %s.", qstring_get_str(qstr));
+ return rc;
+ }
+ if (object_dynamic_cast(OBJECT(dev), TYPE_PCI_DEVICE)) {
+ remote_pci_dev = PCI_DEVICE(dev);
+ }
+ qemu_opts_del(opts);
+
+ return 0;
+}
+
static void process_msg(GIOCondition cond)
{
ProcMsg *msg = NULL;
@@ -268,11 +378,27 @@ static void process_msg(GIOCondition cond)
*/
remote_sysmem_reconfig(msg, &err);
if (err) {
+ error_report_err(err);
goto finalize_loop;
}
break;
case SET_IRQFD:
process_set_irqfd_msg(remote_pci_dev, msg);
+ qdev_machine_creation_done();
+ qemu_mutex_lock_iothread();
+ qemu_run_machine_init_done_notifiers();
+ qemu_mutex_unlock_iothread();
+
+ break;
+ case DRIVE_OPTS:
+ if (setup_drive(msg, &err)) {
+ error_report_err(err);
+ }
+ break;
+ case DEV_OPTS:
+ if (setup_device(msg, &err)) {
+ error_report_err(err);
+ }
break;
case DEVICE_ADD:
process_device_add_msg(msg);