@@ -666,6 +666,44 @@ search_dev_bus:
}
}
+static DeviceState *qdev_find(const char *path)
+{
+ const char *dev_name;
+ DeviceState *dev;
+ char *bus_path;
+ BusState *bus;
+
+ dev_name = strrchr(path, '/');
+ if (!dev_name) {
+ bus = main_system_bus;
+ dev = qdev_find_recursive(bus, path);
+ if (dev) {
+ return dev;
+ }
+ dev_name = path;
+ } else {
+ dev_name++;
+ bus_path = qemu_strdup(path);
+ bus_path[dev_name - path] = 0;
+
+ bus = qbus_find(bus_path);
+ qemu_free(bus_path);
+
+ if (!bus) {
+ /* qbus_find already reported the error */
+ return NULL;
+ }
+ }
+ dev = qbus_find_dev(bus, dev_name);
+ if (!dev) {
+ qerror_report(QERR_DEVICE_NOT_FOUND, dev_name);
+ if (!monitor_cur_is_qmp()) {
+ qbus_list_dev(bus);
+ }
+ }
+ return dev;
+}
+
void qbus_create_inplace(BusState *bus, BusInfo *info,
DeviceState *parent, const char *name)
{
@@ -824,12 +862,12 @@ int do_device_add(Monitor *mon, const QDict *qdict, QObject **ret_data)
int do_device_del(Monitor *mon, const QDict *qdict, QObject **ret_data)
{
- const char *id = qdict_get_str(qdict, "id");
+ const char *path = qdict_get_str(qdict, "path");
DeviceState *dev;
- dev = qdev_find_recursive(main_system_bus, id);
- if (NULL == dev) {
- qerror_report(QERR_DEVICE_NOT_FOUND, id);
+ dev = qdev_find(path);
+ if (!dev) {
+ qerror_report(QERR_DEVICE_NOT_FOUND, path);
return -1;
}
return qdev_unplug(dev);
@@ -703,7 +703,7 @@ EQMP
{
.name = "device_del",
- .args_type = "id:s",
+ .args_type = "path:s",
.params = "device",
.help = "remove device",
.user_print = monitor_user_noop,
@@ -711,10 +711,10 @@ EQMP
},
STEXI
-@item device_del @var{id}
+@item device_del @var{path}
@findex device_del
-Remove device @var{id}.
+Remove device @var{path}.
ETEXI
SQMP
device_del
@@ -724,11 +724,11 @@ Remove a device.
Arguments:
-- "id": the device's ID (json-string)
+- "path": the device's qtree path or unique ID (json-string)
Example:
--> { "execute": "device_del", "arguments": { "id": "net1" } }
+-> { "execute": "device_del", "arguments": { "path": "net1" } }
<- { "return": {} }
EQMP