File 0283-xen-add-block-resize-support-for-xe.patch of Package qemu.19799
From: Bruce Rogers <brogers@suse.com>
Date: Mon, 30 Apr 2018 13:27:17 -0600
Subject: xen: add block resize support for xen disks
Provide monitor naming of xen disks, and plumb guest driver
notification through xenstore of resizing instigated via the
monitor.
[BR: FATE#325467]
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
block/block-backend.c | 11 ++++++++++-
blockdev.c | 8 ++++++++
hw/block/m25p80.c | 2 +-
hw/block/xen_disk.c | 21 ++++++++++++++++++++-
include/hw/xen/xen.h | 1 +
include/sysemu/block-backend.h | 4 +++-
qemu-img.c | 4 ++++
qemu-io.c | 4 ++++
qemu-nbd.c | 4 ++++
tests/Makefile | 2 +-
xen-common-stub.c | 5 +++++
xen-common.c | 7 +++++++
12 files changed, 68 insertions(+), 5 deletions(-)
diff --git a/block/block-backend.c b/block/block-backend.c
index de71d75c3dbcd8fc7c2200aeba2e..b868509c041e4d039278c278c0a8 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -36,6 +36,7 @@ struct BlockBackend {
QTAILQ_ENTRY(BlockBackend) monitor_link; /* for monitor_block_backends */
void *dev; /* attached device model, if any */
+ bool xen_dev; /* true if dev is a Xen disk */
/* TODO change to DeviceState when all users are qdevified */
const BlockDevOps *dev_ops;
void *dev_opaque;
@@ -460,11 +461,12 @@ int blk_attach_dev(BlockBackend *blk, void *dev)
* @blk must not have a device model attached already.
* TODO qdevified devices don't use this, remove when devices are qdevified
*/
-void blk_attach_dev_nofail(BlockBackend *blk, void *dev)
+void blk_attach_dev_nofail(BlockBackend *blk, void *dev, bool xen_dev)
{
if (blk_attach_dev(blk, dev) < 0) {
abort();
}
+ blk->xen_dev = xen_dev;
}
/*
@@ -1483,6 +1485,13 @@ int blk_truncate(BlockBackend *blk, int64_t offset)
return bdrv_truncate(blk_bs(blk), offset);
}
+void blk_legacy_resize_cb(BlockBackend *blk)
+{
+ if (blk->xen_dev) {
+ xen_blk_resize_cb(blk->dev);
+ }
+}
+
int blk_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors)
{
int ret = blk_check_request(blk, sector_num, nb_sectors);
diff --git a/blockdev.c b/blockdev.c
index 260a6f5e02326aa966a712ac5a2b..b9a02fcebeb722fe8c193328e2cc 100644
--- a/blockdev.c
+++ b/blockdev.c
@@ -2907,6 +2907,7 @@ void qmp_block_resize(bool has_device, const char *device,
{
Error *local_err = NULL;
BlockDriverState *bs;
+ BlockBackend *cb_blk = NULL;
AioContext *aio_context;
int ret;
@@ -2918,6 +2919,10 @@ void qmp_block_resize(bool has_device, const char *device,
return;
}
+ if (has_device) {
+ cb_blk = blk_by_name(device);
+ }
+
aio_context = bdrv_get_aio_context(bs);
aio_context_acquire(aio_context);
@@ -2942,6 +2947,9 @@ void qmp_block_resize(bool has_device, const char *device,
ret = bdrv_truncate(bs, size);
switch (ret) {
case 0:
+ if (cb_blk) {
+ blk_legacy_resize_cb(cb_blk);
+ }
break;
case -ENOMEDIUM:
error_setg(errp, QERR_DEVICE_HAS_NO_MEDIUM, device);
diff --git a/hw/block/m25p80.c b/hw/block/m25p80.c
index 906b71257ecfd154f9694d7270bb..d9a9ae699ac51e6396181949c38f 100644
--- a/hw/block/m25p80.c
+++ b/hw/block/m25p80.c
@@ -902,7 +902,7 @@ static int m25p80_init(SSISlave *ss)
if (dinfo) {
DB_PRINT_L(0, "Binding to IF_MTD drive\n");
s->blk = blk_by_legacy_dinfo(dinfo);
- blk_attach_dev_nofail(s->blk, s);
+ blk_attach_dev_nofail(s->blk, s, false);
s->storage = blk_blockalign(s->blk, s->size);
diff --git a/hw/block/xen_disk.c b/hw/block/xen_disk.c
index 2ec76f8d83976f0a27821947a0ce..0920de9f4fd662e112522cff8012 100644
--- a/hw/block/xen_disk.c
+++ b/hw/block/xen_disk.c
@@ -901,6 +901,7 @@ static int blk_connect(struct XenDevice *xendev)
int pers, index, qflags;
bool readonly = true;
bool writethrough = true;
+ Error *errp = NULL;
/* read-only ? */
if (blkdev->directiosafe) {
@@ -956,7 +957,14 @@ static int blk_connect(struct XenDevice *xendev)
* so we can blk_unref() unconditionally */
blk_ref(blkdev->blk);
}
- blk_attach_dev_nofail(blkdev->blk, blkdev);
+ blk_attach_dev_nofail(blkdev->blk, blkdev, true);
+ if (!monitor_add_blk(blkdev->blk, g_strdup(blkdev->dev), &errp)) {
+ xen_be_printf(&blkdev->xendev, 0, "error: %s\n",
+ error_get_pretty(errp));
+ error_free(errp);
+ return -1;
+ }
+
blkdev->file_size = blk_getlength(blkdev->blk);
if (blkdev->file_size < 0) {
BlockDriverState *bs = blk_bs(blkdev->blk);
@@ -1059,6 +1067,7 @@ static void blk_disconnect(struct XenDevice *xendev)
if (blkdev->blk) {
blk_detach_dev(blkdev->blk, blkdev);
+ monitor_remove_blk(blkdev->blk);
blk_unref(blkdev->blk);
blkdev->blk = NULL;
}
@@ -1123,6 +1132,16 @@ static void blk_event(struct XenDevice *xendev)
qemu_bh_schedule(blkdev->bh);
}
+extern void xen_blk_resize_update(void *dev);
+void xen_blk_resize_update(void *dev)
+{
+ struct XenBlkDev *blkdev = dev;
+ blkdev->file_size = blk_getlength(blkdev->blk);
+ xenstore_write_be_int64(&blkdev->xendev, "sectors",
+ blkdev->file_size / blkdev->file_blk);
+ xen_be_set_state(&blkdev->xendev, blkdev->xendev.be_state);
+}
+
struct XenDevOps xen_blkdev_ops = {
.size = sizeof(struct XenBlkDev),
.flags = DEVOPS_FLAG_NEED_GNTDEV,
diff --git a/include/hw/xen/xen.h b/include/hw/xen/xen.h
index 6eb815aacebbb8f10c9e67cc6b2f..dde06e0617846c8e3ca4f363cb34 100644
--- a/include/hw/xen/xen.h
+++ b/include/hw/xen/xen.h
@@ -46,4 +46,5 @@ void xen_modified_memory(ram_addr_t start, ram_addr_t length);
void xen_register_framebuffer(struct MemoryRegion *mr);
+
#endif /* QEMU_HW_XEN_H */
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index 745f0ef3d91c8eacd45996805c9c..9f7929f0141b3b66a93f90b1b4c9 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -86,7 +86,7 @@ void blk_iostatus_disable(BlockBackend *blk);
void blk_iostatus_reset(BlockBackend *blk);
void blk_iostatus_set_err(BlockBackend *blk, int error);
int blk_attach_dev(BlockBackend *blk, void *dev);
-void blk_attach_dev_nofail(BlockBackend *blk, void *dev);
+void blk_attach_dev_nofail(BlockBackend *blk, void *dev, bool xen_dev);
void blk_detach_dev(BlockBackend *blk, void *dev);
void *blk_get_attached_dev(BlockBackend *blk);
void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
@@ -189,6 +189,8 @@ int coroutine_fn blk_co_write_zeroes(BlockBackend *blk, int64_t offset,
int blk_write_compressed(BlockBackend *blk, int64_t sector_num,
const uint8_t *buf, int nb_sectors);
int blk_truncate(BlockBackend *blk, int64_t offset);
+void blk_legacy_resize_cb(BlockBackend *blk);
+void xen_blk_resize_cb(void *dev);
int blk_discard(BlockBackend *blk, int64_t sector_num, int nb_sectors);
int blk_save_vmstate(BlockBackend *blk, const uint8_t *buf,
int64_t pos, int size);
diff --git a/qemu-img.c b/qemu-img.c
index a04921686dd259c92fb65652a058..95bcb74bf0610473746fe965df69 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -63,6 +63,10 @@ typedef enum OutputFormat {
/* Default to cache=writeback as data integrity is not important for qemu-img */
#define BDRV_DEFAULT_CACHE "writeback"
+void xen_blk_resize_cb(void *dev)
+{
+}
+
static void format_print(void *opaque, const char *name)
{
printf(" %s", name);
diff --git a/qemu-io.c b/qemu-io.c
index 0598251e7c7b3b597b5a9fe9aabf..137ac33909c250e46610472cf9a0 100644
--- a/qemu-io.c
+++ b/qemu-io.c
@@ -38,6 +38,10 @@ static bool imageOpts;
static ReadLineState *readline_state;
+void xen_blk_resize_cb(void *dev)
+{
+}
+
static int close_f(BlockBackend *blk, int argc, char **argv)
{
blk_unref(qemuio_blk);
diff --git a/qemu-nbd.c b/qemu-nbd.c
index 7293e9578149136e92293e17e7e7..0d76bd092256c630d42b2b6cd419 100644
--- a/qemu-nbd.c
+++ b/qemu-nbd.c
@@ -59,6 +59,10 @@ static QIOChannelSocket *server_ioc;
static int server_watch = -1;
static QCryptoTLSCreds *tlscreds;
+void xen_blk_resize_cb(void *dev)
+{
+}
+
static void usage(const char *name)
{
(printf) (
diff --git a/tests/Makefile b/tests/Makefile
index 73d5b40c0352b53956534e107d35..cdb78e382b4446d35b9d9ce4b191 100644
--- a/tests/Makefile
+++ b/tests/Makefile
@@ -407,7 +407,7 @@ test-qapi-obj-y = tests/test-qapi-visit.o tests/test-qapi-types.o \
$(test-qom-obj-y)
test-crypto-obj-y = $(crypto-obj-y) $(test-qom-obj-y)
test-io-obj-y = $(io-obj-y) $(test-crypto-obj-y)
-test-block-obj-y = $(block-obj-y) $(test-io-obj-y)
+test-block-obj-y = $(block-obj-y) $(test-io-obj-y) xen-common-stub.o
tests/check-qint$(EXESUF): tests/check-qint.o $(test-util-obj-y)
tests/check-qstring$(EXESUF): tests/check-qstring.o $(test-util-obj-y)
diff --git a/xen-common-stub.c b/xen-common-stub.c
index 699c3f1c642e33b396fe14f20b7c..fc1c7943836e285abd77270bfcc7 100644
--- a/xen-common-stub.c
+++ b/xen-common-stub.c
@@ -8,7 +8,12 @@
#include "qemu/osdep.h"
#include "qemu-common.h"
#include "hw/xen/xen.h"
+#include "sysemu/block-backend.h"
void xenstore_store_pv_console_info(int i, CharDriverState *chr)
{
}
+
+void xen_blk_resize_cb(void *dev)
+{
+}
diff --git a/xen-common.c b/xen-common.c
index e641ad1aeff8b0d325b6a98c4f2e..219b7aac1c9680be0974805212c3 100644
--- a/xen-common.c
+++ b/xen-common.c
@@ -14,6 +14,7 @@
#include "sysemu/char.h"
#include "sysemu/accel.h"
#include "migration/migration.h"
+#include "sysemu/block-backend.h"
//#define DEBUG_XEN
@@ -25,6 +26,12 @@
do { } while (0)
#endif
+extern void xen_blk_resize_update(void *dev);
+void xen_blk_resize_cb(void *dev)
+{
+ xen_blk_resize_update(dev);
+}
+
static int store_dev_info(int domid, CharDriverState *cs, const char *string)
{
struct xs_handle *xs = NULL;