qemu/blkdebug-Allow-taking-unsharing-permissi.patch
Bruce Rogers 405ca57e69 Accepting request 784401 from home:bfrogers:branches:Virtualization
- Include upstream patches targeted for the next stable release
  (bug fixes only)
  audio-oss-fix-buffer-pos-calculation.patch
  blkdebug-Allow-taking-unsharing-permissi.patch
  block-Add-bdrv_qapi_perm_to_blk_perm.patch
  block-backup-top-fix-failure-path.patch
  block-block-copy-fix-progress-calculatio.patch
  block-fix-crash-on-zero-length-unaligned.patch
  block-fix-memleaks-in-bdrv_refresh_filen.patch
  block-Fix-VM-size-field-width-in-snapsho.patch
  block-nbd-extract-the-common-cleanup-cod.patch
  block-nbd-fix-memory-leak-in-nbd_open.patch
  block-qcow2-threads-fix-qcow2_decompress.patch
  hw-arm-cubieboard-use-ARM-Cortex-A8-as-t.patch
  hw-intc-arm_gicv3_kvm-Stop-wrongly-progr.patch
  iotests-add-test-for-backup-top-failure-.patch
  iotests-Fix-nonportable-use-of-od-endian.patch
  job-refactor-progress-to-separate-object.patch
  target-arm-Correct-definition-of-PMCRDP.patch
  target-arm-fix-TCG-leak-for-fcvt-half-do.patch
  tpm-ppi-page-align-PPI-RAM.patch
  vhost-user-blk-delete-virtioqueues-in-un.patch
  virtio-add-ability-to-delete-vq-through-.patch
  virtio-crypto-do-delete-ctrl_vq-in-virti.patch
  virtio-pmem-do-delete-rq_vq-in-virtio_pm.patch
- Add Obsoletes directive for qemu-audio-sdl and qemu-ui-sdl since
  for a qemu package upgrade from SLE12-SP5, support for SDL is
  dropped

OBS-URL: https://build.opensuse.org/request/show/784401
OBS-URL: https://build.opensuse.org/package/show/Virtualization/qemu?expand=0&rev=534
2020-03-12 19:48:43 +00:00

202 lines
6.8 KiB
Diff

From: Max Reitz <mreitz@redhat.com>
Date: Fri, 8 Nov 2019 13:34:53 +0100
Subject: blkdebug: Allow taking/unsharing permissions
Git-commit: 69c6449ff10fe4e3219e960549307096d5366bd0
Sometimes it is useful to be able to add a node to the block graph that
takes or unshare a certain set of permissions for debugging purposes.
This patch adds this capability to blkdebug.
(Note that you cannot make blkdebug release or share permissions that it
needs to take or cannot share, because this might result in assertion
failures in the block layer. But if the blkdebug node has no parents,
it will not take any permissions and share everything by default, so you
can then freely choose what permissions to take and share.)
Signed-off-by: Max Reitz <mreitz@redhat.com>
Message-id: 20191108123455.39445-4-mreitz@redhat.com
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
Signed-off-by: Max Reitz <mreitz@redhat.com>
Signed-off-by: Bruce Rogers <brogers@suse.com>
---
block/blkdebug.c | 93 +++++++++++++++++++++++++++++++++++++++++++-
qapi/block-core.json | 14 ++++++-
2 files changed, 105 insertions(+), 2 deletions(-)
diff --git a/block/blkdebug.c b/block/blkdebug.c
index 5ae96c52b0733fc37bd5f485e124..af44aa973fd1855a48317ff7fd3f 100644
--- a/block/blkdebug.c
+++ b/block/blkdebug.c
@@ -28,10 +28,14 @@
#include "qemu/cutils.h"
#include "qemu/config-file.h"
#include "block/block_int.h"
+#include "block/qdict.h"
#include "qemu/module.h"
#include "qemu/option.h"
+#include "qapi/qapi-visit-block-core.h"
#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qlist.h"
#include "qapi/qmp/qstring.h"
+#include "qapi/qobject-input-visitor.h"
#include "sysemu/qtest.h"
typedef struct BDRVBlkdebugState {
@@ -44,6 +48,9 @@ typedef struct BDRVBlkdebugState {
uint64_t opt_discard;
uint64_t max_discard;
+ uint64_t take_child_perms;
+ uint64_t unshare_child_perms;
+
/* For blkdebug_refresh_filename() */
char *config_file;
@@ -344,6 +351,69 @@ static void blkdebug_parse_filename(const char *filename, QDict *options,
qdict_put_str(options, "x-image", filename);
}
+static int blkdebug_parse_perm_list(uint64_t *dest, QDict *options,
+ const char *prefix, Error **errp)
+{
+ int ret = 0;
+ QDict *subqdict = NULL;
+ QObject *crumpled_subqdict = NULL;
+ Visitor *v = NULL;
+ BlockPermissionList *perm_list = NULL, *element;
+ Error *local_err = NULL;
+
+ *dest = 0;
+
+ qdict_extract_subqdict(options, &subqdict, prefix);
+ if (!qdict_size(subqdict)) {
+ goto out;
+ }
+
+ crumpled_subqdict = qdict_crumple(subqdict, errp);
+ if (!crumpled_subqdict) {
+ ret = -EINVAL;
+ goto out;
+ }
+
+ v = qobject_input_visitor_new(crumpled_subqdict);
+ visit_type_BlockPermissionList(v, NULL, &perm_list, &local_err);
+ if (local_err) {
+ error_propagate(errp, local_err);
+ ret = -EINVAL;
+ goto out;
+ }
+
+ for (element = perm_list; element; element = element->next) {
+ *dest |= bdrv_qapi_perm_to_blk_perm(element->value);
+ }
+
+out:
+ qapi_free_BlockPermissionList(perm_list);
+ visit_free(v);
+ qobject_unref(subqdict);
+ qobject_unref(crumpled_subqdict);
+ return ret;
+}
+
+static int blkdebug_parse_perms(BDRVBlkdebugState *s, QDict *options,
+ Error **errp)
+{
+ int ret;
+
+ ret = blkdebug_parse_perm_list(&s->take_child_perms, options,
+ "take-child-perms.", errp);
+ if (ret < 0) {
+ return ret;
+ }
+
+ ret = blkdebug_parse_perm_list(&s->unshare_child_perms, options,
+ "unshare-child-perms.", errp);
+ if (ret < 0) {
+ return ret;
+ }
+
+ return 0;
+}
+
static QemuOptsList runtime_opts = {
.name = "blkdebug",
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
@@ -419,6 +489,12 @@ static int blkdebug_open(BlockDriverState *bs, QDict *options, int flags,
/* Set initial state */
s->state = 1;
+ /* Parse permissions modifiers before opening the image file */
+ ret = blkdebug_parse_perms(s, options, errp);
+ if (ret < 0) {
+ goto out;
+ }
+
/* Open the image file */
bs->file = bdrv_open_child(qemu_opt_get(opts, "x-image"), options, "image",
bs, &child_file, false, &local_err);
@@ -916,6 +992,21 @@ static int blkdebug_reopen_prepare(BDRVReopenState *reopen_state,
return 0;
}
+static void blkdebug_child_perm(BlockDriverState *bs, BdrvChild *c,
+ const BdrvChildRole *role,
+ BlockReopenQueue *reopen_queue,
+ uint64_t perm, uint64_t shared,
+ uint64_t *nperm, uint64_t *nshared)
+{
+ BDRVBlkdebugState *s = bs->opaque;
+
+ bdrv_filter_default_perms(bs, c, role, reopen_queue, perm, shared,
+ nperm, nshared);
+
+ *nperm |= s->take_child_perms;
+ *nshared &= ~s->unshare_child_perms;
+}
+
static const char *const blkdebug_strong_runtime_opts[] = {
"config",
"inject-error.",
@@ -940,7 +1031,7 @@ static BlockDriver bdrv_blkdebug = {
.bdrv_file_open = blkdebug_open,
.bdrv_close = blkdebug_close,
.bdrv_reopen_prepare = blkdebug_reopen_prepare,
- .bdrv_child_perm = bdrv_filter_default_perms,
+ .bdrv_child_perm = blkdebug_child_perm,
.bdrv_getlength = blkdebug_getlength,
.bdrv_refresh_filename = blkdebug_refresh_filename,
diff --git a/qapi/block-core.json b/qapi/block-core.json
index 0cf68fea1450e6cb739863d2367c..bcf77d496289480b86b1c9d80374 100644
--- a/qapi/block-core.json
+++ b/qapi/block-core.json
@@ -3450,6 +3450,16 @@
#
# @set-state: array of state-change descriptions
#
+# @take-child-perms: Permissions to take on @image in addition to what
+# is necessary anyway (which depends on how the
+# blkdebug node is used). Defaults to none.
+# (since 5.0)
+#
+# @unshare-child-perms: Permissions not to share on @image in addition
+# to what cannot be shared anyway (which depends
+# on how the blkdebug node is used). Defaults
+# to none. (since 5.0)
+#
# Since: 2.9
##
{ 'struct': 'BlockdevOptionsBlkdebug',
@@ -3459,7 +3469,9 @@
'*opt-write-zero': 'int32', '*max-write-zero': 'int32',
'*opt-discard': 'int32', '*max-discard': 'int32',
'*inject-error': ['BlkdebugInjectErrorOptions'],
- '*set-state': ['BlkdebugSetStateOptions'] } }
+ '*set-state': ['BlkdebugSetStateOptions'],
+ '*take-child-perms': ['BlockPermission'],
+ '*unshare-child-perms': ['BlockPermission'] } }
##
# @BlockdevOptionsBlklogwrites: