[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[PATCH 3/8] qdev: Support forced device_del in QMP and HMP



Add an optional force argument to the QMP device_del command and expose it
in HMP as "device_del -f".

When force is requested, qdev_unplug() bypasses the pending deletion guard
and asks the selected hotplug controller to complete removal through its
force_unplug callback. Controllers that do not implement the callback
reject the operation.

Forced removal bypasses guest cooperation.

Signed-off-by: Dongli Zhang <dongli.zhang@xxxxxxxxxx>
---
 hmp-commands.hx       | 11 ++++++-----
 qapi/qdev.json        | 11 +++++++++--
 system/qdev-monitor.c | 11 +++++++----
 3 files changed, 22 insertions(+), 11 deletions(-)

diff --git a/hmp-commands.hx b/hmp-commands.hx
index 43ff220b5f..022502b20f 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -708,17 +708,18 @@ ERST
 
     {
         .name       = "device_del",
-        .args_type  = "id:s",
-        .params     = "device",
-        .help       = "remove device",
+        .args_type  = "force:-f,id:s",
+        .params     = "[-f] device",
+        .help       = "remove device, use -f to force removal",
         .cmd        = hmp_device_del,
         .command_completion = device_del_completion,
     },
 
 SRST
-``device_del`` *id*
+``device_del`` [*-f*] *id*
   Remove device *id*. *id* may be a short ID
-  or a QOM object path.
+  or a QOM object path.  Use -f to force removal without waiting for
+  guest cooperation.
 ERST
 
     {
diff --git a/qapi/qdev.json b/qapi/qdev.json
index 974cf9c583..cb5b5ad1db 100644
--- a/qapi/qdev.json
+++ b/qapi/qdev.json
@@ -90,6 +90,11 @@
 #
 # @id: the device's ID or QOM path
 #
+# @force: if true, remove the device without waiting for guest
+#     cooperation.  The guest may still be using the device.  This can
+#     cause guest-visible errors, I/O failures, or guest crashes.
+#     (since 11.2)
+#
 # Errors:
 #     - If @id is not a valid device, DeviceNotFound
 #
@@ -101,7 +106,9 @@
 #    will automatically complete removal for all devices.  If a
 #    guest-side error in the hot removal process is detected, the
 #    device will not be removed and a `DEVICE_UNPLUG_GUEST_ERROR`
-#    event is sent.  Some errors cannot be detected.
+#    event is sent.  Some errors cannot be detected.  If @force is
+#    true, guest cooperation is bypassed, but backend cleanup is still
+#    performed through the device's normal unrealize path.
 #
 # Since: 0.14
 #
@@ -117,7 +124,7 @@
 #          "arguments": { "id": "/machine/peripheral-anon/device[0]" } }
 #     <- { "return": {} }
 ##
-{ 'command': 'device_del', 'data': {'id': 'str'} }
+{ 'command': 'device_del', 'data': {'id': 'str', '*force': 'bool'} }
 
 ##
 # @DEVICE_DELETED:
diff --git a/system/qdev-monitor.c b/system/qdev-monitor.c
index fa3cae246b..ca10a25c46 100644
--- a/system/qdev-monitor.c
+++ b/system/qdev-monitor.c
@@ -956,11 +956,13 @@ void qdev_unplug(DeviceState *dev, bool force, Error 
**errp)
     error_propagate(errp, local_err);
 }
 
-void qmp_device_del(const char *id, Error **errp)
+void qmp_device_del(const char *id, bool has_force, bool force, Error **errp)
 {
     DeviceState *dev = find_device_state(id, false, errp);
+    bool do_force = has_force && force;
+
     if (dev != NULL) {
-        if (dev->pending_deleted_event &&
+        if (!do_force && dev->pending_deleted_event &&
             (dev->pending_deleted_expires_ms == 0 ||
              dev->pending_deleted_expires_ms > 
qemu_clock_get_ms(QEMU_CLOCK_VIRTUAL))) {
             error_setg(errp, "Device %s is already in the "
@@ -968,7 +970,7 @@ void qmp_device_del(const char *id, Error **errp)
             return;
         }
 
-        qdev_unplug(dev, false, errp);
+        qdev_unplug(dev, do_force, errp);
     }
 }
 
@@ -1046,9 +1048,10 @@ out:
 void hmp_device_del(Monitor *mon, const QDict *qdict)
 {
     const char *id = qdict_get_str(qdict, "id");
+    bool force = qdict_get_try_bool(qdict, "force", false);
     Error *err = NULL;
 
-    qmp_device_del(id, &err);
+    qmp_device_del(id, true, force, &err);
     hmp_handle_error(mon, err);
 }
 
-- 
2.43.5




 


Rackspace

Lists.xenproject.org is hosted with RackSpace, monitoring our
servers 24x7x365 and backed by RackSpace's Fanatical Support®.