|
@@ -856,18 +856,9 @@ void hmp_info_qdm(Monitor *mon, const QDict *qdict)
|
|
|
|
|
|
void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
|
|
void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
|
|
{
|
|
{
|
|
- QemuOpts *opts;
|
|
|
|
DeviceState *dev;
|
|
DeviceState *dev;
|
|
|
|
|
|
- opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, errp);
|
|
|
|
- if (!opts) {
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- if (!monitor_cur_is_qmp() && qdev_device_help(opts)) {
|
|
|
|
- qemu_opts_del(opts);
|
|
|
|
- return;
|
|
|
|
- }
|
|
|
|
- dev = qdev_device_add(opts, errp);
|
|
|
|
|
|
+ dev = qdev_device_add_from_qdict(qdict, true, errp);
|
|
if (!dev) {
|
|
if (!dev) {
|
|
/*
|
|
/*
|
|
* Drain all pending RCU callbacks. This is done because
|
|
* Drain all pending RCU callbacks. This is done because
|
|
@@ -879,9 +870,6 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
|
|
* to the user
|
|
* to the user
|
|
*/
|
|
*/
|
|
drain_call_rcu();
|
|
drain_call_rcu();
|
|
-
|
|
|
|
- qemu_opts_del(opts);
|
|
|
|
- return;
|
|
|
|
}
|
|
}
|
|
object_unref(OBJECT(dev));
|
|
object_unref(OBJECT(dev));
|
|
}
|
|
}
|
|
@@ -1018,8 +1006,34 @@ void qmp_device_sync_config(const char *id, Error **errp)
|
|
void hmp_device_add(Monitor *mon, const QDict *qdict)
|
|
void hmp_device_add(Monitor *mon, const QDict *qdict)
|
|
{
|
|
{
|
|
Error *err = NULL;
|
|
Error *err = NULL;
|
|
|
|
+ QemuOpts *opts;
|
|
|
|
+ DeviceState *dev;
|
|
|
|
|
|
- qmp_device_add((QDict *)qdict, NULL, &err);
|
|
|
|
|
|
+ opts = qemu_opts_from_qdict(qemu_find_opts("device"), qdict, &err);
|
|
|
|
+ if (!opts) {
|
|
|
|
+ goto out;
|
|
|
|
+ }
|
|
|
|
+ if (qdev_device_help(opts)) {
|
|
|
|
+ qemu_opts_del(opts);
|
|
|
|
+ return;
|
|
|
|
+ }
|
|
|
|
+ dev = qdev_device_add(opts, &err);
|
|
|
|
+ if (!dev) {
|
|
|
|
+ /*
|
|
|
|
+ * Drain all pending RCU callbacks. This is done because
|
|
|
|
+ * some bus related operations can delay a device removal
|
|
|
|
+ * (in this case this can happen if device is added and then
|
|
|
|
+ * removed due to a configuration error)
|
|
|
|
+ * to a RCU callback, but user might expect that this interface
|
|
|
|
+ * will finish its job completely once qmp command returns result
|
|
|
|
+ * to the user
|
|
|
|
+ */
|
|
|
|
+ drain_call_rcu();
|
|
|
|
+
|
|
|
|
+ qemu_opts_del(opts);
|
|
|
|
+ }
|
|
|
|
+ object_unref(dev);
|
|
|
|
+out:
|
|
hmp_handle_error(mon, err);
|
|
hmp_handle_error(mon, err);
|
|
}
|
|
}
|
|
|
|
|