summary refs log tree commit diff stats
path: root/qdev-monitor.c
diff options
context:
space:
mode:
authorDaniel P. Berrange <berrange@redhat.com>2015-09-11 13:33:56 +0100
committerMarkus Armbruster <armbru@redhat.com>2015-09-22 11:31:56 +0200
commit6287d827d494b5850049584c3f7fb1a589dbb1de (patch)
tree30f2e39cf5ca440c911434aa9c2c587e1f625f6c /qdev-monitor.c
parent9e72681d16792d0ffc42bab634b1753ff299bdfd (diff)
downloadfocaccia-qemu-6287d827d494b5850049584c3f7fb1a589dbb1de.tar.gz
focaccia-qemu-6287d827d494b5850049584c3f7fb1a589dbb1de.zip
monitor: allow device_del to accept QOM paths
Currently device_del requires that the client provide the
device short ID. device_add allows devices to be created
without giving an ID, at which point there is no way to
delete them with device_del. The QOM object path, however,
provides an alternative way to identify the devices.

Allowing device_del to accept an object path ensures all
devices are deletable regardless of whether they have an
ID.

 (qemu) device_add usb-mouse
 (qemu) qom-list /machine/peripheral-anon
 device[0] (child<usb-mouse>)
 type (string)
 (qemu) device_del /machine/peripheral-anon/device[0]

Devices are required to be marked as hotpluggable
otherwise an error is raised

 (qemu) device_del /machine/unattached/device[4]
 Device 'PIIX3' does not support hotplugging

Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
Message-Id: <1441974836-17476-1-git-send-email-berrange@redhat.com>
Reviewed-by: Eric Blake <eblake@redhat.com>
[Commit message touched up, accidental white-space change dropped]
Signed-off-by: Markus Armbruster <armbru@redhat.com>
Diffstat (limited to 'qdev-monitor.c')
-rw-r--r--qdev-monitor.c20
1 files changed, 15 insertions, 5 deletions
diff --git a/qdev-monitor.c b/qdev-monitor.c
index 0bf7f83a1d..eb7aef2c81 100644
--- a/qdev-monitor.c
+++ b/qdev-monitor.c
@@ -771,12 +771,17 @@ void qmp_device_add(QDict *qdict, QObject **ret_data, Error **errp)
 void qmp_device_del(const char *id, Error **errp)
 {
     Object *obj;
-    char *root_path = object_get_canonical_path(qdev_get_peripheral());
-    char *path = g_strdup_printf("%s/%s", root_path, id);
 
-    g_free(root_path);
-    obj = object_resolve_path_type(path, TYPE_DEVICE, NULL);
-    g_free(path);
+    if (id[0] == '/') {
+        obj = object_resolve_path(id, NULL);
+    } else {
+        char *root_path = object_get_canonical_path(qdev_get_peripheral());
+        char *path = g_strdup_printf("%s/%s", root_path, id);
+
+        g_free(root_path);
+        obj = object_resolve_path_type(path, TYPE_DEVICE, NULL);
+        g_free(path);
+    }
 
     if (!obj) {
         error_set(errp, ERROR_CLASS_DEVICE_NOT_FOUND,
@@ -784,6 +789,11 @@ void qmp_device_del(const char *id, Error **errp)
         return;
     }
 
+    if (!object_dynamic_cast(obj, TYPE_DEVICE)) {
+        error_setg(errp, "%s is not a hotpluggable device", id);
+        return;
+    }
+
     qdev_unplug(DEVICE(obj), errp);
 }