[Top][All Lists]
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v5 10/15] blockdev: make image streaming safe across
From: |
Stefan Hajnoczi |
Subject: |
[Qemu-devel] [PATCH v5 10/15] blockdev: make image streaming safe across hotplug |
Date: |
Fri, 13 Jan 2012 13:14:12 +0000 |
Unplugging a storage interface like virtio-blk causes the host block
device to be deleted too. Long-running operations like block migration
must take a DriveInfo reference to prevent the BlockDriverState from
being freed. For image streaming we can do the same thing.
Note that it is not possible to acquire/release the drive reference in
block.c where the block job functions live because
drive_get_ref()/drive_put_ref() are blockdev.c functions. Calling them
from block.c would be a layering violation - tools like qemu-img don't
even link against blockdev.c.
Signed-off-by: Stefan Hajnoczi <address@hidden>
---
blockdev.c | 38 ++++++++++++++++++++++++++++++++++++++
1 files changed, 38 insertions(+), 0 deletions(-)
diff --git a/blockdev.c b/blockdev.c
index 4549c9e..45a6ba6 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -202,6 +202,37 @@ void drive_get_ref(DriveInfo *dinfo)
dinfo->refcount++;
}
+typedef struct {
+ QEMUBH *bh;
+ DriveInfo *dinfo;
+} DrivePutRefBH;
+
+static void drive_put_ref_bh(void *opaque)
+{
+ DrivePutRefBH *s = opaque;
+
+ drive_put_ref(s->dinfo);
+ qemu_bh_delete(s->bh);
+ g_free(s);
+}
+
+/*
+ * Release a drive reference in a BH
+ *
+ * It is not possible to use drive_put_ref() from a callback function when the
+ * callers still need the drive. In such cases we schedule a BH to release the
+ * reference.
+ */
+static void drive_put_ref_bh_schedule(DriveInfo *dinfo)
+{
+ DrivePutRefBH *s;
+
+ s = g_new(DrivePutRefBH, 1);
+ s->bh = qemu_bh_new(drive_put_ref_bh, s);
+ s->dinfo = dinfo;
+ qemu_bh_schedule(s->bh);
+}
+
static int parse_block_error_action(const char *buf, int is_read)
{
if (!strcmp(buf, "ignore")) {
@@ -917,6 +948,8 @@ static void block_stream_cb(void *opaque, int ret)
monitor_protocol_event(QEVENT_BLOCK_JOB_COMPLETED, obj);
}
qobject_decref(obj);
+
+ drive_put_ref_bh_schedule(drive_get_by_blockdev(bs));
}
void qmp_block_stream(const char *device, bool has_base,
@@ -949,6 +982,11 @@ void qmp_block_stream(const char *device, bool has_base,
}
}
+ /* Grab a reference so hotplug does not delete the BlockDriverState from
+ * underneath us.
+ */
+ drive_get_ref(drive_get_by_blockdev(bs));
+
trace_qmp_block_stream(bs, bs->job);
}
--
1.7.7.3
- [Qemu-devel] [PATCH v5 02/15] block: check bdrv_in_use() before blockdev operations, (continued)
- [Qemu-devel] [PATCH v5 07/15] qmp: add block_job_set_speed command, Stefan Hajnoczi, 2012/01/13
- [Qemu-devel] [PATCH v5 14/15] docs: describe live block operations, Stefan Hajnoczi, 2012/01/13
- [Qemu-devel] [PATCH v5 11/15] block: add bdrv_find_backing_image, Stefan Hajnoczi, 2012/01/13
- [Qemu-devel] [PATCH v5 10/15] blockdev: make image streaming safe across hotplug,
Stefan Hajnoczi <=
- [Qemu-devel] [PATCH v5 12/15] add QERR_BASE_NOT_FOUND, Stefan Hajnoczi, 2012/01/13
- [Qemu-devel] [PATCH v5 08/15] qmp: add block_job_cancel command, Stefan Hajnoczi, 2012/01/13
- [Qemu-devel] [PATCH v5 06/15] qmp: add block_stream command, Stefan Hajnoczi, 2012/01/13
- [Qemu-devel] [PATCH v5 13/15] block: add support for partial streaming, Stefan Hajnoczi, 2012/01/13
[Qemu-devel] [PATCH v5 15/15] test: add image streaming test cases, Stefan Hajnoczi, 2012/01/13