Patchwork [v2,05/15] qdev: Allow device specification by qtree path for device_del

login
register
mail settings
Submitter Jan Kiszka
Date May 22, 2010, 8:18 a.m.
Message ID <818363ead9495baadb853a9385eb065703e72507.1274516288.git.jan.kiszka@web.de>
Download mbox | patch
Permalink /patch/53256/
State New
Headers show

Comments

Jan Kiszka - May 22, 2010, 8:18 a.m.
From: Jan Kiszka <jan.kiszka@siemens.com>

Allow to specify the device to be removed via device_del not only by ID
but also by its full or abbreviated qtree path. For this purpose,
qdev_find is introduced which combines searching for device IDs with
walking the qtree when required.

Signed-off-by: Jan Kiszka <jan.kiszka@siemens.com>
---
 hw/qdev.c       |   46 ++++++++++++++++++++++++++++++++++++++++++----
 qemu-monitor.hx |   10 +++++-----
 2 files changed, 47 insertions(+), 9 deletions(-)

Patch

diff --git a/hw/qdev.c b/hw/qdev.c
index 6d55e50..fa611a1 100644
--- a/hw/qdev.c
+++ b/hw/qdev.c
@@ -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);
diff --git a/qemu-monitor.hx b/qemu-monitor.hx
index c8f1789..754d71e 100644
--- a/qemu-monitor.hx
+++ b/qemu-monitor.hx
@@ -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