[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[PATCH v5 06/35] qdev: allow setting drive property for realized device
From: |
Vladimir Sementsov-Ogievskiy |
Subject: |
[PATCH v5 06/35] qdev: allow setting drive property for realized device |
Date: |
Thu, 10 Jun 2021 14:25:49 +0300 |
We need an ability to insert filters above top block node, attached to
block device. It can't be achieved with blockdev-reopen command. So, we
want do it with help of qom-set.
Intended usage:
Assume there is a node A that is attached to some guest device.
1. blockdev-add to create a filter node B that has A as its child.
2. qom-set to change the node attached to the guest device’s
BlockBackend from A to B.
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Reviewed-by: Max Reitz <mreitz@redhat.com>
---
hw/core/qdev-properties-system.c | 43 +++++++++++++++++++++++---------
1 file changed, 31 insertions(+), 12 deletions(-)
diff --git a/hw/core/qdev-properties-system.c b/hw/core/qdev-properties-system.c
index 2760c21f11..e71f5d64d1 100644
--- a/hw/core/qdev-properties-system.c
+++ b/hw/core/qdev-properties-system.c
@@ -36,11 +36,11 @@
static bool check_prop_still_unset(Object *obj, const char *name,
const void *old_val, const char *new_val,
- Error **errp)
+ bool allow_override, Error **errp)
{
const GlobalProperty *prop = qdev_find_global_prop(obj, name);
- if (!old_val) {
+ if (!old_val || (!prop && allow_override)) {
return true;
}
@@ -93,16 +93,34 @@ static void set_drive_helper(Object *obj, Visitor *v, const
char *name,
BlockBackend *blk;
bool blk_created = false;
int ret;
+ BlockDriverState *bs;
+ AioContext *ctx;
if (!visit_type_str(v, name, &str, errp)) {
return;
}
- /*
- * TODO Should this really be an error? If no, the old value
- * needs to be released before we store the new one.
- */
- if (!check_prop_still_unset(obj, name, *ptr, str, errp)) {
+ if (!check_prop_still_unset(obj, name, *ptr, str, true, errp)) {
+ return;
+ }
+
+ if (*ptr) {
+ /* BlockBackend alread exists. So, we want to change attached node */
+ blk = *ptr;
+ ctx = blk_get_aio_context(blk);
+ bs = bdrv_lookup_bs(NULL, str, errp);
+ if (!bs) {
+ return;
+ }
+
+ if (ctx != bdrv_get_aio_context(bs)) {
+ error_setg(errp, "Different aio context is not supported for new "
+ "node");
+ }
+
+ aio_context_acquire(ctx);
+ blk_replace_bs(blk, bs, errp);
+ aio_context_release(ctx);
return;
}
@@ -114,7 +132,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const
char *name,
blk = blk_by_name(str);
if (!blk) {
- BlockDriverState *bs = bdrv_lookup_bs(NULL, str, NULL);
+ bs = bdrv_lookup_bs(NULL, str, NULL);
if (bs) {
/*
* If the device supports iothreads, it will make sure to move the
@@ -123,8 +141,7 @@ static void set_drive_helper(Object *obj, Visitor *v, const
char *name,
* aware of iothreads require their BlockBackends to be in the main
* AioContext.
*/
- AioContext *ctx = iothread ? bdrv_get_aio_context(bs) :
- qemu_get_aio_context();
+ ctx = iothread ? bdrv_get_aio_context(bs) : qemu_get_aio_context();
blk = blk_new(ctx, 0, BLK_PERM_ALL);
blk_created = true;
@@ -196,6 +213,7 @@ static void release_drive(Object *obj, const char *name,
void *opaque)
const PropertyInfo qdev_prop_drive = {
.name = "str",
.description = "Node name or ID of a block device to use as a backend",
+ .realized_set_allowed = true,
.get = get_drive,
.set = set_drive,
.release = release_drive,
@@ -204,6 +222,7 @@ const PropertyInfo qdev_prop_drive = {
const PropertyInfo qdev_prop_drive_iothread = {
.name = "str",
.description = "Node name or ID of a block device to use as a backend",
+ .realized_set_allowed = true,
.get = get_drive,
.set = set_drive_iothread,
.release = release_drive,
@@ -238,7 +257,7 @@ static void set_chr(Object *obj, Visitor *v, const char
*name, void *opaque,
* TODO Should this really be an error? If no, the old value
* needs to be released before we store the new one.
*/
- if (!check_prop_still_unset(obj, name, be->chr, str, errp)) {
+ if (!check_prop_still_unset(obj, name, be->chr, str, false, errp)) {
return;
}
@@ -408,7 +427,7 @@ static void set_netdev(Object *obj, Visitor *v, const char
*name,
* TODO Should this really be an error? If no, the old value
* needs to be released before we store the new one.
*/
- if (!check_prop_still_unset(obj, name, ncs[i], str, errp)) {
+ if (!check_prop_still_unset(obj, name, ncs[i], str, false, errp)) {
goto out;
}
--
2.29.2
- [PATCH v5 00/35] block: publish backup-top filter, Vladimir Sementsov-Ogievskiy, 2021/06/10
- [PATCH v5 01/35] block: rename bdrv_replace_child to bdrv_replace_child_tran, Vladimir Sementsov-Ogievskiy, 2021/06/10
- [PATCH v5 02/35] block: comment graph-modifying function not updating permissions, Vladimir Sementsov-Ogievskiy, 2021/06/10
- [PATCH v5 06/35] qdev: allow setting drive property for realized device,
Vladimir Sementsov-Ogievskiy <=
- [PATCH v5 03/35] block: introduce bdrv_replace_child_bs(), Vladimir Sementsov-Ogievskiy, 2021/06/10
- [PATCH v5 10/35] block/backup: set copy_range and compress after filter insertion, Vladimir Sementsov-Ogievskiy, 2021/06/10
- [PATCH v5 04/35] block: introduce blk_replace_bs, Vladimir Sementsov-Ogievskiy, 2021/06/10
- [PATCH v5 05/35] qdev-properties: PropertyInfo: add realized_set_allowed field, Vladimir Sementsov-Ogievskiy, 2021/06/10
- [PATCH v5 07/35] block: rename backup-top to copy-before-write, Vladimir Sementsov-Ogievskiy, 2021/06/10
- [PATCH v5 11/35] block/backup: move cluster size calculation to block-copy, Vladimir Sementsov-Ogievskiy, 2021/06/10
- [PATCH v5 08/35] block-copy: always set BDRV_REQ_SERIALISING flag, Vladimir Sementsov-Ogievskiy, 2021/06/10
- [PATCH v5 12/35] block/copy-before-write: relax permission requirements when no parents, Vladimir Sementsov-Ogievskiy, 2021/06/10
- [PATCH v5 14/35] block/copy-before-write: use file child instead of backing, Vladimir Sementsov-Ogievskiy, 2021/06/10
- [PATCH v5 09/35] block/block-copy: introduce block_copy_set_copy_opts(), Vladimir Sementsov-Ogievskiy, 2021/06/10