From: mr-083 <matthieu@minio.io>
To: qemu-devel@nongnu.org, qemu-block@nongnu.org
Cc: its@irrelevant.dk, kbusch@kernel.org, stefanha@redhat.com,
mr-083 <matthieu@min.io>
Subject: [PATCH 2/2] block/monitor: add drive_insert HMP command
Date: Thu, 9 Apr 2026 09:01:11 +0200 [thread overview]
Message-ID: <20260409070114.11313-3-matthieu@min.io> (raw)
In-Reply-To: <20260409070114.11313-1-matthieu@min.io>
Add a drive_insert HMP command that reconnects a host block device file
to an existing guest device whose backing store was previously removed
with drive_del.
After drive_del, the BlockBackend remains attached to the guest device
but has no BlockDriverState (shown as "[not inserted]" in info block).
drive_insert opens the specified file, finds the device's BlockBackend
by iterating all backends and matching the attached device ID, then
calls blk_insert_bs() to reconnect the backing store.
This complements drive_del for non-removable devices (such as NVMe
namespaces) where blockdev-change-medium cannot be used. Combined with
PCIe AER Surprise Down error injection to trigger a controller reset,
this enables complete NVMe disk hot-swap simulation where the guest
sees the same device names throughout.
Example usage:
drive_del drv0 # remove backing store
drive_insert ns0 disk.qcow2 # reconnect backing
pcie_aer_inject_error rp0 SDN # trigger controller reset
Signed-off-by: Matthieu Receveur <matthieu@min.io>
---
block/monitor/block-hmp-cmds.c | 59 ++++++++++++++++++++++++++++++++++
hmp-commands.hx | 18 +++++++++++
include/block/block-hmp-cmds.h | 1 +
3 files changed, 78 insertions(+)
diff --git a/block/monitor/block-hmp-cmds.c b/block/monitor/block-hmp-cmds.c
index 1fd28d59eb..77e9662ead 100644
--- a/block/monitor/block-hmp-cmds.c
+++ b/block/monitor/block-hmp-cmds.c
@@ -38,7 +38,9 @@
#include "qemu/osdep.h"
#include "hw/core/boards.h"
#include "system/block-backend.h"
+#include "system/block-backend-global-state.h"
#include "system/blockdev.h"
+#include "block/block-global-state.h"
#include "qapi/qapi-commands-block.h"
#include "qapi/qapi-commands-block-export.h"
#include "qobject/qdict.h"
@@ -195,6 +197,63 @@ unlock:
hmp_handle_error(mon, err);
}
+void hmp_drive_insert(Monitor *mon, const QDict *qdict)
+{
+ const char *id = qdict_get_str(qdict, "id");
+ const char *filename = qdict_get_str(qdict, "filename");
+ BlockBackend *blk = NULL;
+ BlockBackend *iter;
+ BlockDriverState *bs;
+ Error *err = NULL;
+
+ GLOBAL_STATE_CODE();
+
+ /*
+ * After drive_del, the BlockBackend is removed from the monitor name
+ * registry but still attached to the device. Find it by iterating all
+ * BlockBackends and matching by the device ID shown in "info block".
+ */
+ for (iter = blk_all_next(NULL); iter; iter = blk_all_next(iter)) {
+ DeviceState *dev = blk_get_attached_dev(iter);
+ if (dev && dev->id && strcmp(dev->id, id) == 0) {
+ blk = iter;
+ break;
+ }
+ }
+
+ if (!blk) {
+ /* Fallback: try by block backend name */
+ blk = blk_by_name(id);
+ }
+
+ if (!blk) {
+ error_setg(&err, "Device '%s' not found", id);
+ goto out;
+ }
+
+ if (blk_bs(blk)) {
+ error_setg(&err, "Device '%s' already has a medium inserted", id);
+ goto out;
+ }
+
+ bs = bdrv_open(filename, NULL, NULL, BDRV_O_RDWR, &err);
+ if (!bs) {
+ goto out;
+ }
+
+ if (blk_insert_bs(blk, bs, &err) < 0) {
+ bdrv_unref(bs);
+ goto out;
+ }
+
+ bdrv_unref(bs);
+ monitor_printf(mon, "OK\n");
+ return;
+
+out:
+ hmp_handle_error(mon, err);
+}
+
void hmp_commit(Monitor *mon, const QDict *qdict)
{
const char *device = qdict_get_str(qdict, "device");
diff --git a/hmp-commands.hx b/hmp-commands.hx
index 5cc4788f12..79af8e8988 100644
--- a/hmp-commands.hx
+++ b/hmp-commands.hx
@@ -207,6 +207,24 @@ SRST
actions (drive options rerror, werror).
ERST
+ {
+ .name = "drive_insert",
+ .args_type = "id:B,filename:F",
+ .params = "device filename",
+ .help = "insert a host block device into an empty drive",
+ .cmd = hmp_drive_insert,
+ },
+
+SRST
+``drive_insert`` *device* *filename*
+ Insert a host block device file into a drive that has been emptied by
+ ``drive_del``. This reconnects the backing store without removing the
+ guest device, enabling transparent disk hot-swap for non-removable devices
+ such as NVMe namespaces. Combined with PCIe AER Surprise Down error
+ injection (``pcie_aer_inject_error`` *device* ``SDN``), this enables
+ complete NVMe disk hot-swap simulation.
+ERST
+
{
.name = "change",
.args_type = "device:B,force:-f,target:F,arg:s?,read-only-mode:s?",
diff --git a/include/block/block-hmp-cmds.h b/include/block/block-hmp-cmds.h
index 71113cd7ef..73c9607402 100644
--- a/include/block/block-hmp-cmds.h
+++ b/include/block/block-hmp-cmds.h
@@ -21,6 +21,7 @@ void hmp_drive_add(Monitor *mon, const QDict *qdict);
void hmp_commit(Monitor *mon, const QDict *qdict);
void hmp_drive_del(Monitor *mon, const QDict *qdict);
+void hmp_drive_insert(Monitor *mon, const QDict *qdict);
void hmp_drive_mirror(Monitor *mon, const QDict *qdict);
void hmp_drive_backup(Monitor *mon, const QDict *qdict);
--
2.50.1 (Apple Git-155)
next prev parent reply other threads:[~2026-04-09 8:21 UTC|newest]
Thread overview: 15+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-04-09 7:01 [PATCH 0/2] NVMe namespace hotplug and drive reconnection support mr-083
2026-04-09 7:01 ` [PATCH 1/2] hw/nvme: add namespace hotplug support mr-083
2026-04-09 7:01 ` mr-083 [this message]
2026-04-09 21:00 ` [PATCH 0/2] NVMe namespace hotplug and drive reconnection support Stefan Hajnoczi
2026-04-10 0:49 ` Matthieu Rolla
-- strict thread matches above, loose matches on Subject: below --
2026-04-09 6:01 mr-083
2026-04-09 6:01 ` [PATCH 2/2] block/monitor: add drive_insert HMP command mr-083
2026-04-14 17:57 ` Stefan Hajnoczi
2026-04-14 18:02 ` Matthieu Rolla
2026-04-14 19:05 ` Warner Losh
2026-04-14 21:01 ` Matthieu Rolla
2026-04-15 10:48 ` Daniel P. Berrangé
2026-04-15 12:32 ` Matthieu Rolla
2026-04-16 19:52 ` Stefan Hajnoczi
2026-04-16 22:00 ` Matthieu Rolla
2026-04-15 12:33 ` Stefan Hajnoczi
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260409070114.11313-3-matthieu@min.io \
--to=matthieu@minio.io \
--cc=its@irrelevant.dk \
--cc=kbusch@kernel.org \
--cc=matthieu@min.io \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=stefanha@redhat.com \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.