[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-devel] [PATCH v3 02/23] block: New BlockBackend
From: |
Markus Armbruster |
Subject: |
[Qemu-devel] [PATCH v3 02/23] block: New BlockBackend |
Date: |
Tue, 16 Sep 2014 20:12:07 +0200 |
A block device consists of a frontend device model and a backend.
A block backend has a tree of block drivers doing the actual work.
The tree is managed by the block layer.
We currently use a single abstraction BlockDriverState both for tree
nodes and the backend as a whole. Drawbacks:
* Its API includes both stuff that makes sense only at the block
backend level (root of the tree) and stuff that's only for use
within the block layer. This makes the API bigger and more complex
than necessary. Moreover, it's not obvious which interfaces are
meant for device models, and which really aren't.
* Since device models keep a reference to their backend, the backend
object can't just be destroyed. But for media change, we need to
replace the tree. Our solution is to make the BlockDriverState
generic, with actual driver state in a separate object, pointed to
by member opaque. That lets us replace the tree by deinitializing
and reinitializing its root. This special need of the root makes
the data structure awkward everywhere in the tree.
The general plan is to separate the APIs into "block backend", for use
by device models, monitor and whatever other code dealing with block
backends, and "block driver", for use by the block layer and whatever
other code (if any) dealing with trees and tree nodes.
Code dealing with block backends, device models in particular, should
become completely oblivious of BlockDriverState. This should let us
clean up both APIs, and the tree data structures.
This commit is a first step. It creates a minimal "block backend"
API: type BlockBackend and functions to create, destroy and find them.
BlockBackend objects are created and destroyed exactly when root
BlockDriverState objects are created and destroyed. "Root" in the
sense of "in bdrv_states". They're not yet used for anything; that'll
come shortly.
BlockBackend is reference-counted. Its reference count never exceeds
one so far, but that's going to change.
Signed-off-by: Markus Armbruster <address@hidden>
---
block/Makefile.objs | 2 +-
block/block-backend.c | 120 +++++++++++++++++++++++++++++++++++++++++
blockdev.c | 11 +++-
hw/block/xen_disk.c | 11 ++++
include/qemu/typedefs.h | 1 +
include/sysemu/block-backend.h | 26 +++++++++
qemu-img.c | 70 +++++++++++++++++++++---
qemu-io.c | 8 +++
qemu-nbd.c | 5 +-
9 files changed, 243 insertions(+), 11 deletions(-)
create mode 100644 block/block-backend.c
create mode 100644 include/sysemu/block-backend.h
diff --git a/block/Makefile.objs b/block/Makefile.objs
index c9c8bbb..e410e7a 100644
--- a/block/Makefile.objs
+++ b/block/Makefile.objs
@@ -5,7 +5,7 @@ block-obj-y += qed-check.o
block-obj-$(CONFIG_VHDX) += vhdx.o vhdx-endian.o vhdx-log.o
block-obj-$(CONFIG_QUORUM) += quorum.o
block-obj-y += parallels.o blkdebug.o blkverify.o
-block-obj-y += snapshot.o qapi.o
+block-obj-y += block-backend.o snapshot.o qapi.o
block-obj-$(CONFIG_WIN32) += raw-win32.o win32-aio.o
block-obj-$(CONFIG_POSIX) += raw-posix.o
block-obj-$(CONFIG_LINUX_AIO) += linux-aio.o
diff --git a/block/block-backend.c b/block/block-backend.c
new file mode 100644
index 0000000..e89caa9
--- /dev/null
+++ b/block/block-backend.c
@@ -0,0 +1,120 @@
+/*
+ * QEMU Block backends
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * Authors:
+ * Markus Armbruster <address@hidden>,
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later. See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "sysemu/block-backend.h"
+#include "block/block_int.h"
+
+struct BlockBackend {
+ char *name;
+ int refcnt;
+ QTAILQ_ENTRY(BlockBackend) link; /* for blk_backends */
+};
+
+/* All the BlockBackends */
+static QTAILQ_HEAD(, BlockBackend) blk_backends =
+ QTAILQ_HEAD_INITIALIZER(blk_backends);
+
+/*
+ * Create a new BlockBackend with @name, with a reference count of one.
+ * @name must not be null or empty.
+ * Fail if a BlockBackend with this name already exists.
+ * Store an error through @errp on failure, unless it's null.
+ * Return the new BlockBackend on success, null on failure.
+ */
+BlockBackend *blk_new(const char *name, Error **errp)
+{
+ BlockBackend *blk;
+
+ assert(name && name[0]);
+ if (blk_by_name(name)) {
+ error_setg(errp, "Device with id '%s' already exists", name);
+ return NULL;
+ }
+
+ blk = g_new0(BlockBackend, 1);
+ blk->name = g_strdup(name);
+ blk->refcnt = 1;
+ QTAILQ_INSERT_TAIL(&blk_backends, blk, link);
+ return blk;
+}
+
+static void blk_delete(BlockBackend *blk)
+{
+ assert(!blk->refcnt);
+ QTAILQ_REMOVE(&blk_backends, blk, link);
+ g_free(blk->name);
+ g_free(blk);
+}
+
+/*
+ * Increment @blk's reference count.
+ * @blk must not be null.
+ */
+void blk_ref(BlockBackend *blk)
+{
+ blk->refcnt++;
+}
+
+/*
+ * Decrement @blk's reference count.
+ * If this drops it to zero, destroy @blk.
+ * For convenience, do nothing if @blk is null.
+ */
+void blk_unref(BlockBackend *blk)
+{
+ if (blk) {
+ assert(blk->refcnt > 0);
+ if (!--blk->refcnt) {
+ blk_delete(blk);
+ }
+ }
+}
+
+/*
+ * Return the BlockBackend after @blk.
+ * If @blk is null, return the first one.
+ * Else, return @blk's next sibling, which may be null.
+ *
+ * To iterate over all BlockBackends, do
+ * for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
+ * ...
+ * }
+ */
+BlockBackend *blk_next(BlockBackend *blk)
+{
+ return blk ? QTAILQ_NEXT(blk, link) : QTAILQ_FIRST(&blk_backends);
+}
+
+/*
+ * Return @blk's name, a non-null, non-empty string.
+ */
+const char *blk_name(BlockBackend *blk)
+{
+ return blk->name;
+}
+
+/*
+ * Return the BlockBackend with name @name if it exists, else null.
+ * @name must not be null.
+ */
+BlockBackend *blk_by_name(const char *name)
+{
+ BlockBackend *blk;
+
+ assert(name);
+ QTAILQ_FOREACH(blk, &blk_backends, link) {
+ if (!strcmp(name, blk->name)) {
+ return blk;
+ }
+ }
+ return NULL;
+}
diff --git a/blockdev.c b/blockdev.c
index c9463e3..583235a 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -30,6 +30,7 @@
* THE SOFTWARE.
*/
+#include "sysemu/block-backend.h"
#include "sysemu/blockdev.h"
#include "hw/block/block.h"
#include "block/blockjob.h"
@@ -307,6 +308,7 @@ static DriveInfo *blockdev_init(const char *file, QDict
*bs_opts,
int ro = 0;
int bdrv_flags = 0;
int on_read_error, on_write_error;
+ BlockBackend *blk;
BlockDriverState *bs;
DriveInfo *dinfo;
ThrottleConfig cfg;
@@ -463,9 +465,13 @@ static DriveInfo *blockdev_init(const char *file, QDict
*bs_opts,
}
/* init */
+ blk = blk_new(qemu_opts_id(opts), errp);
+ if (!blk) {
+ goto early_err;
+ }
bs = bdrv_new_root(qemu_opts_id(opts), errp);
if (!bs) {
- goto early_err;
+ goto bdrv_new_err;
}
bs->open_flags = snapshot ? BDRV_O_SNAPSHOT : 0;
bs->read_only = ro;
@@ -531,6 +537,8 @@ static DriveInfo *blockdev_init(const char *file, QDict
*bs_opts,
err:
bdrv_unref(bs);
+bdrv_new_err:
+ blk_unref(blk);
early_err:
qemu_opts_del(opts);
err_no_opts:
@@ -1791,6 +1799,7 @@ int do_drive_del(Monitor *mon, const QDict *qdict,
QObject **ret_data)
} else {
drive_del(dinfo);
}
+ blk_unref(blk_by_name(id));
aio_context_release(aio_context);
return 0;
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 7f0f66b..265cf13 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -39,6 +39,7 @@
#include "hw/xen/xen_backend.h"
#include "xen_blkif.h"
#include "sysemu/blockdev.h"
+#include "sysemu/block-backend.h"
/* ------------------------------------------------------------- */
@@ -854,12 +855,18 @@ static int blk_connect(struct XenDevice *xendev)
blkdev->dinfo = drive_get(IF_XEN, 0, index);
if (!blkdev->dinfo) {
Error *local_err = NULL;
+ BlockBackend *blk;
BlockDriver *drv;
/* setup via xenbus -> create new block driver instance */
xen_be_printf(&blkdev->xendev, 2, "create new bdrv (xenbus setup)\n");
+ blk = blk_new(blkdev->dev, NULL);
+ if (!blk) {
+ return -1;
+ }
blkdev->bs = bdrv_new_root(blkdev->dev, NULL);
if (!blkdev->bs) {
+ blk_unref(blk);
return -1;
}
@@ -870,6 +877,7 @@ static int blk_connect(struct XenDevice *xendev)
error_get_pretty(local_err));
error_free(local_err);
bdrv_unref(blkdev->bs);
+ blk_unref(blk);
blkdev->bs = NULL;
return -1;
}
@@ -985,6 +993,9 @@ static void blk_disconnect(struct XenDevice *xendev)
if (blkdev->bs) {
bdrv_detach_dev(blkdev->bs, blkdev);
bdrv_unref(blkdev->bs);
+ if (!blkdev->dinfo) {
+ blk_unref(blk_by_name(blkdev->dev));
+ }
blkdev->bs = NULL;
}
xen_be_unbind_evtchn(&blkdev->xendev);
diff --git a/include/qemu/typedefs.h b/include/qemu/typedefs.h
index 5f20b0e..198da2e 100644
--- a/include/qemu/typedefs.h
+++ b/include/qemu/typedefs.h
@@ -35,6 +35,7 @@ typedef struct MachineClass MachineClass;
typedef struct NICInfo NICInfo;
typedef struct HCIInfo HCIInfo;
typedef struct AudioState AudioState;
+typedef struct BlockBackend BlockBackend;
typedef struct BlockDriverState BlockDriverState;
typedef struct DriveInfo DriveInfo;
typedef struct DisplayState DisplayState;
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
new file mode 100644
index 0000000..3f8371c
--- /dev/null
+++ b/include/sysemu/block-backend.h
@@ -0,0 +1,26 @@
+/*
+ * QEMU Block backends
+ *
+ * Copyright (C) 2014 Red Hat, Inc.
+ *
+ * Authors:
+ * Markus Armbruster <address@hidden>,
+ *
+ * This work is licensed under the terms of the GNU GPL, version 2 or
+ * later. See the COPYING file in the top-level directory.
+ */
+
+#ifndef BLOCK_BACKEND_H
+#define BLOCK_BACKEND_H
+
+#include "qemu/typedefs.h"
+#include "qapi/error.h"
+
+BlockBackend *blk_new(const char *name, Error **errp);
+void blk_ref(BlockBackend *blk);
+void blk_unref(BlockBackend *blk);
+const char *blk_name(BlockBackend *blk);
+BlockBackend *blk_by_name(const char *name);
+BlockBackend *blk_next(BlockBackend *blk);
+
+#endif
diff --git a/qemu-img.c b/qemu-img.c
index 58d59d0..acb272e 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -29,6 +29,7 @@
#include "qemu/error-report.h"
#include "qemu/osdep.h"
#include "sysemu/sysemu.h"
+#include "sysemu/block-backend.h"
#include "block/block_int.h"
#include "block/qapi.h"
#include <getopt.h>
@@ -575,10 +576,11 @@ static int img_check(int argc, char **argv)
int c, ret;
OutputFormat output_format = OFORMAT_HUMAN;
const char *filename, *fmt, *output, *cache;
+ BlockBackend *blk;
BlockDriverState *bs;
int fix = 0;
int flags = BDRV_O_FLAGS | BDRV_O_CHECK;
- ImageCheck *check;
+ ImageCheck *check = NULL;
bool quiet = false;
fmt = NULL;
@@ -649,9 +651,11 @@ static int img_check(int argc, char **argv)
return 1;
}
+ blk = blk_new("image", &error_abort);
bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
if (!bs) {
- return 1;
+ ret = 1;
+ goto fail;
}
check = g_new0(ImageCheck, 1);
@@ -710,6 +714,7 @@ static int img_check(int argc, char **argv)
fail:
qapi_free_ImageCheck(check);
bdrv_unref(bs);
+ blk_unref(blk);
return ret;
}
@@ -718,6 +723,7 @@ static int img_commit(int argc, char **argv)
{
int c, ret, flags;
const char *filename, *fmt, *cache;
+ BlockBackend *blk;
BlockDriverState *bs;
bool quiet = false;
@@ -756,9 +762,11 @@ static int img_commit(int argc, char **argv)
return 1;
}
+ blk = blk_new("image", &error_abort);
bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
if (!bs) {
- return 1;
+ ret = -1;
+ goto out;
}
ret = bdrv_commit(bs);
switch(ret) {
@@ -779,7 +787,9 @@ static int img_commit(int argc, char **argv)
break;
}
+out:
bdrv_unref(bs);
+ blk_unref(blk);
if (ret) {
return 1;
}
@@ -942,6 +952,7 @@ static int check_empty_sectors(BlockDriverState *bs,
int64_t sect_num,
static int img_compare(int argc, char **argv)
{
const char *fmt1 = NULL, *fmt2 = NULL, *cache, *filename1, *filename2;
+ BlockBackend *blk1, *blk2;
BlockDriverState *bs1, *bs2;
int64_t total_sectors1, total_sectors2;
uint8_t *buf1 = NULL, *buf2 = NULL;
@@ -1011,18 +1022,20 @@ static int img_compare(int argc, char **argv)
goto out3;
}
+ blk1 = blk_new("image 1", &error_abort);
bs1 = bdrv_new_open("image 1", filename1, fmt1, flags, true, quiet);
if (!bs1) {
error_report("Can't open file %s", filename1);
ret = 2;
- goto out3;
+ goto out2;
}
+ blk2 = blk_new("image 2", &error_abort);
bs2 = bdrv_new_open("image 2", filename2, fmt2, flags, true, quiet);
if (!bs2) {
error_report("Can't open file %s", filename2);
ret = 2;
- goto out2;
+ goto out1;
}
buf1 = qemu_blockalign(bs1, IO_BUF_SIZE);
@@ -1183,11 +1196,14 @@ static int img_compare(int argc, char **argv)
ret = 0;
out:
- bdrv_unref(bs2);
qemu_vfree(buf1);
qemu_vfree(buf2);
+out1:
+ bdrv_unref(bs2);
+ blk_unref(blk2);
out2:
bdrv_unref(bs1);
+ blk_unref(blk1);
out3:
qemu_progress_end();
return ret;
@@ -1200,6 +1216,7 @@ static int img_convert(int argc, char **argv)
int progress = 0, flags, src_flags;
const char *fmt, *out_fmt, *cache, *src_cache, *out_baseimg, *out_filename;
BlockDriver *drv, *proto_drv;
+ BlockBackend **blk = NULL, *out_blk = NULL;
BlockDriverState **bs = NULL, *out_bs = NULL;
int64_t total_sectors, nb_sectors, sector_num, bs_offset;
int64_t *bs_sectors = NULL;
@@ -1354,6 +1371,7 @@ static int img_convert(int argc, char **argv)
qemu_progress_print(0, 100);
+ blk = g_new0(BlockBackend *, bs_n);
bs = g_new0(BlockDriverState *, bs_n);
bs_sectors = g_new(int64_t, bs_n);
@@ -1361,6 +1379,7 @@ static int img_convert(int argc, char **argv)
for (bs_i = 0; bs_i < bs_n; bs_i++) {
char *id = bs_n > 1 ? g_strdup_printf("source %d", bs_i)
: g_strdup("source");
+ blk[bs_i] = blk_new(id, &error_abort);
bs[bs_i] = bdrv_new_open(id, argv[optind + bs_i], fmt, src_flags,
true, quiet);
g_free(id);
@@ -1486,6 +1505,7 @@ static int img_convert(int argc, char **argv)
goto out;
}
+ out_blk = blk_new("target", &error_abort);
out_bs = bdrv_new_open("target", out_filename, out_fmt, flags, true,
quiet);
if (!out_bs) {
ret = -1;
@@ -1742,6 +1762,7 @@ out:
if (out_bs) {
bdrv_unref(out_bs);
}
+ blk_unref(out_blk);
if (bs) {
for (bs_i = 0; bs_i < bs_n; bs_i++) {
if (bs[bs_i]) {
@@ -1750,6 +1771,12 @@ out:
}
g_free(bs);
}
+ if (blk) {
+ for (bs_i = 0; bs_i < bs_n; bs_i++) {
+ blk_unref(blk[bs_i]);
+ }
+ g_free(blk);
+ }
g_free(bs_sectors);
fail_getopt:
g_free(options);
@@ -1858,6 +1885,7 @@ static ImageInfoList *collect_image_info_list(const char
*filename,
filenames = g_hash_table_new_full(g_str_hash, str_equal_func, NULL, NULL);
while (filename) {
+ BlockBackend *blk;
BlockDriverState *bs;
ImageInfo *info;
ImageInfoList *elem;
@@ -1869,9 +1897,11 @@ static ImageInfoList *collect_image_info_list(const char
*filename,
}
g_hash_table_insert(filenames, (gpointer)filename, NULL);
+ blk = blk_new("image", &error_abort);
bs = bdrv_new_open("image", filename, fmt,
BDRV_O_FLAGS | BDRV_O_NO_BACKING, false, false);
if (!bs) {
+ blk_unref(blk);
goto err;
}
@@ -1880,6 +1910,7 @@ static ImageInfoList *collect_image_info_list(const char
*filename,
error_report("%s", error_get_pretty(err));
error_free(err);
bdrv_unref(bs);
+ blk_unref(blk);
goto err;
}
@@ -1889,6 +1920,7 @@ static ImageInfoList *collect_image_info_list(const char
*filename,
last = &elem->next;
bdrv_unref(bs);
+ blk_unref(blk);
filename = fmt = NULL;
if (chain) {
@@ -2082,6 +2114,7 @@ static int img_map(int argc, char **argv)
{
int c;
OutputFormat output_format = OFORMAT_HUMAN;
+ BlockBackend *blk;
BlockDriverState *bs;
const char *filename, *fmt, *output;
int64_t length;
@@ -2130,9 +2163,11 @@ static int img_map(int argc, char **argv)
return 1;
}
+ blk = blk_new("image", &error_abort);
bs = bdrv_new_open("image", filename, fmt, BDRV_O_FLAGS, true, false);
if (!bs) {
- return 1;
+ ret = -1;
+ goto out;
}
if (output_format == OFORMAT_HUMAN) {
@@ -2175,6 +2210,7 @@ static int img_map(int argc, char **argv)
out:
bdrv_unref(bs);
+ blk_unref(blk);
return ret < 0;
}
@@ -2185,6 +2221,7 @@ out:
static int img_snapshot(int argc, char **argv)
{
+ BlockBackend *blk;
BlockDriverState *bs;
QEMUSnapshotInfo sn;
char *filename, *snapshot_name = NULL;
@@ -2250,9 +2287,11 @@ static int img_snapshot(int argc, char **argv)
filename = argv[optind++];
/* Open the image */
+ blk = blk_new("image", &error_abort);
bs = bdrv_new_open("image", filename, NULL, bdrv_oflags, true, quiet);
if (!bs) {
- return 1;
+ ret = -1;
+ goto out;
}
/* Perform the requested action */
@@ -2296,7 +2335,9 @@ static int img_snapshot(int argc, char **argv)
}
/* Cleanup */
+out:
bdrv_unref(bs);
+ blk_unref(blk);
if (ret) {
return 1;
}
@@ -2305,6 +2346,7 @@ static int img_snapshot(int argc, char **argv)
static int img_rebase(int argc, char **argv)
{
+ BlockBackend *blk = NULL, *blk_old_backing = NULL, *blk_new_backing = NULL;
BlockDriverState *bs = NULL, *bs_old_backing = NULL, *bs_new_backing =
NULL;
BlockDriver *old_backing_drv, *new_backing_drv;
char *filename;
@@ -2393,6 +2435,7 @@ static int img_rebase(int argc, char **argv)
* Ignore the old backing file for unsafe rebase in case we want to correct
* the reference to a renamed or moved backing file.
*/
+ blk = blk_new("image", &error_abort);
bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
if (!bs) {
ret = -1;
@@ -2425,6 +2468,7 @@ static int img_rebase(int argc, char **argv)
if (!unsafe) {
char backing_name[1024];
+ blk_old_backing = blk_new("old_backing", &error_abort);
bs_old_backing = bdrv_new_root("old_backing", &error_abort);
bdrv_get_backing_filename(bs, backing_name, sizeof(backing_name));
ret = bdrv_open(&bs_old_backing, backing_name, NULL, NULL, src_flags,
@@ -2436,6 +2480,7 @@ static int img_rebase(int argc, char **argv)
goto out;
}
if (out_baseimg[0]) {
+ blk_new_backing = blk_new("new_backing", &error_abort);
bs_new_backing = bdrv_new_root("new_backing", &error_abort);
ret = bdrv_open(&bs_new_backing, out_baseimg, NULL, NULL,
src_flags,
new_backing_drv, &local_err);
@@ -2614,12 +2659,15 @@ out:
if (bs_old_backing != NULL) {
bdrv_unref(bs_old_backing);
}
+ blk_unref(blk_old_backing);
if (bs_new_backing != NULL) {
bdrv_unref(bs_new_backing);
}
+ blk_unref(blk_new_backing);
}
bdrv_unref(bs);
+ blk_unref(blk);
if (ret) {
return 1;
}
@@ -2632,6 +2680,7 @@ static int img_resize(int argc, char **argv)
const char *filename, *fmt, *size;
int64_t n, total_size;
bool quiet = false;
+ BlockBackend *blk = NULL;
BlockDriverState *bs = NULL;
QemuOpts *param;
static QemuOptsList resize_options = {
@@ -2708,6 +2757,7 @@ static int img_resize(int argc, char **argv)
n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
qemu_opts_del(param);
+ blk = blk_new("image", &error_abort);
bs = bdrv_new_open("image", filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR,
true, quiet);
if (!bs) {
@@ -2745,6 +2795,7 @@ out:
if (bs) {
bdrv_unref(bs);
}
+ blk_unref(blk);
if (ret) {
return 1;
}
@@ -2760,6 +2811,7 @@ static int img_amend(int argc, char **argv)
const char *fmt = NULL, *filename, *cache;
int flags;
bool quiet = false;
+ BlockBackend *blk = NULL;
BlockDriverState *bs = NULL;
cache = BDRV_DEFAULT_CACHE;
@@ -2823,6 +2875,7 @@ static int img_amend(int argc, char **argv)
goto out;
}
+ blk = blk_new("image", &error_abort);
bs = bdrv_new_open("image", filename, fmt, flags, true, quiet);
if (!bs) {
error_report("Could not open image '%s'", filename);
@@ -2856,6 +2909,7 @@ out:
if (bs) {
bdrv_unref(bs);
}
+ blk_unref(blk);
qemu_opts_del(opts);
qemu_opts_free(create_opts);
g_free(options);
diff --git a/qemu-io.c b/qemu-io.c
index 24ca59c..57090de 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -19,6 +19,7 @@
#include "qemu/option.h"
#include "qemu/config-file.h"
#include "qemu/readline.h"
+#include "sysemu/block-backend.h"
#include "block/block_int.h"
#include "trace/control.h"
@@ -26,6 +27,7 @@
static char *progname;
+static BlockBackend *qemuio_blk;
static BlockDriverState *qemuio_bs;
/* qemu-io commands passed using -c */
@@ -37,7 +39,9 @@ static ReadLineState *readline_state;
static int close_f(BlockDriverState *bs, int argc, char **argv)
{
bdrv_unref(bs);
+ blk_unref(qemuio_blk);
qemuio_bs = NULL;
+ qemuio_blk = NULL;
return 0;
}
@@ -58,6 +62,7 @@ static int openfile(char *name, int flags, int growable,
QDict *opts)
return 1;
}
+ qemuio_blk = blk_new("hda", &error_abort);
qemuio_bs = bdrv_new_root("hda", &error_abort);
if (growable) {
@@ -70,7 +75,9 @@ static int openfile(char *name, int flags, int growable,
QDict *opts)
error_get_pretty(local_err));
error_free(local_err);
bdrv_unref(qemuio_bs);
+ blk_unref(qemuio_blk);
qemuio_bs = NULL;
+ qemuio_blk = NULL;
return 1;
}
@@ -479,6 +486,7 @@ int main(int argc, char **argv)
if (qemuio_bs) {
bdrv_unref(qemuio_bs);
}
+ blk_unref(qemuio_blk);
g_free(readline_state);
return 0;
}
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 24b8454..ff95da6 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -17,7 +17,7 @@
*/
#include "qemu-common.h"
-#include "block/block.h"
+#include "sysemu/block-backend.h"
#include "block/block_int.h"
#include "block/nbd.h"
#include "qemu/main-loop.h"
@@ -384,6 +384,7 @@ static void nbd_accept(void *opaque)
int main(int argc, char **argv)
{
+ BlockBackend *blk;
BlockDriverState *bs;
BlockDriver *drv;
off_t dev_offset = 0;
@@ -687,6 +688,7 @@ int main(int argc, char **argv)
drv = NULL;
}
+ blk = blk_new("hda", &error_abort);
bs = bdrv_new_root("hda", &error_abort);
srcpath = argv[optind];
@@ -770,6 +772,7 @@ int main(int argc, char **argv)
} while (state != TERMINATED);
bdrv_unref(bs);
+ blk_unref(blk);
if (sockpath) {
unlink(sockpath);
}
--
1.9.3
- Re: [Qemu-devel] [PATCH v3 03/23] block: Connect BlockBackend to BlockDriverState, (continued)
[Qemu-devel] [PATCH v3 05/23] block: Code motion to get rid of stubs/blockdev.c, Markus Armbruster, 2014/09/16
[Qemu-devel] [PATCH v3 09/23] block: Merge BlockBackend and BlockDriverState name spaces, Markus Armbruster, 2014/09/16
[Qemu-devel] [PATCH v3 02/23] block: New BlockBackend,
Markus Armbruster <=
[Qemu-devel] [PATCH v3 07/23] block: Eliminate bdrv_iterate(), use bdrv_next(), Markus Armbruster, 2014/09/16
[Qemu-devel] [PATCH v3 10/23] block: Eliminate DriveInfo member bdrv, use blk_by_legacy_dinfo(), Markus Armbruster, 2014/09/16