All of lore.kernel.org
 help / color / mirror / Atom feed
From: Kevin Wolf <kwolf@redhat.com>
To: qemu-block@nongnu.org
Cc: kwolf@redhat.com, mreitz@redhat.com, jcody@redhat.com,
	famz@redhat.com, qemu-devel@nongnu.org
Subject: [Qemu-devel] [PATCH 46/54] hmp: Request permissions in qemu-io
Date: Tue, 21 Feb 2017 15:58:42 +0100	[thread overview]
Message-ID: <1487689130-30373-47-git-send-email-kwolf@redhat.com> (raw)
In-Reply-To: <1487689130-30373-1-git-send-email-kwolf@redhat.com>

The HMP command 'qemu-io' is a bit tricky because it wants to work on
the original BlockBackend, but additional permissions could be required.
The details are explained in a comment in the code, but in summary, just
request whatever permissions the current qemu-io command needs.

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
---
 block/block-backend.c          |  6 ++++++
 hmp.c                          | 26 +++++++++++++++++++++++++-
 include/qemu-io.h              |  1 +
 include/sysemu/block-backend.h |  1 +
 qemu-io-cmds.c                 | 28 ++++++++++++++++++++++++++++
 5 files changed, 61 insertions(+), 1 deletion(-)

diff --git a/block/block-backend.c b/block/block-backend.c
index 38a3858..daa7908 100644
--- a/block/block-backend.c
+++ b/block/block-backend.c
@@ -584,6 +584,12 @@ int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
     return 0;
 }
 
+void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm)
+{
+    *perm = blk->perm;
+    *shared_perm = blk->shared_perm;
+}
+
 static int blk_do_attach_dev(BlockBackend *blk, void *dev)
 {
     if (blk->dev) {
diff --git a/hmp.c b/hmp.c
index 801fddb..fde5016 100644
--- a/hmp.c
+++ b/hmp.c
@@ -2045,7 +2045,6 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
     if (!blk) {
         BlockDriverState *bs = bdrv_lookup_bs(NULL, device, &err);
         if (bs) {
-            /* FIXME Use real permissions */
             blk = local_blk = blk_new(0, BLK_PERM_ALL);
             ret = blk_insert_bs(blk, bs, &err);
             if (ret < 0) {
@@ -2059,6 +2058,31 @@ void hmp_qemu_io(Monitor *mon, const QDict *qdict)
     aio_context = blk_get_aio_context(blk);
     aio_context_acquire(aio_context);
 
+    /*
+     * Notably absent: Proper permission management. This is sad, but it seems
+     * almost impossible to achieve without changing the semantics and thereby
+     * limiting the use cases of the qemu-io HMP command.
+     *
+     * In an ideal world we would unconditionally create a new BlockBackend for
+     * qemuio_command(), but we have commands like 'reopen' and want them to
+     * take effect on the exact BlockBackend whose name the user passed instead
+     * of just on a temporary copy of it.
+     *
+     * Another problem is that deleting the temporary BlockBackend involves
+     * draining all requests on it first, but some qemu-iotests cases want to
+     * issue multiple aio_read/write requests and expect them to complete in
+     * the background while the monitor has already returned.
+     *
+     * This is also what prevents us from saving the original permissions and
+     * restoring them later: We can't revoke permissions until all requests
+     * have completed, and we don't know when that is nor can we really let
+     * anything else run before we have revoken them to avoid race conditions.
+     *
+     * What happens now is that command() in qemu-io-cmds.c can extend the
+     * permissions if necessary for the qemu-io command. And they simply stay
+     * extended, possibly resulting in a read-only guest device keeping write
+     * permissions. Ugly, but it appears to be the lesser evil.
+     */
     qemuio_command(blk, command);
 
     aio_context_release(aio_context);
diff --git a/include/qemu-io.h b/include/qemu-io.h
index 4d402b9..196fde0 100644
--- a/include/qemu-io.h
+++ b/include/qemu-io.h
@@ -36,6 +36,7 @@ typedef struct cmdinfo {
     const char  *args;
     const char  *oneline;
     helpfunc_t  help;
+    uint64_t    perm;
 } cmdinfo_t;
 
 extern bool qemuio_misalign;
diff --git a/include/sysemu/block-backend.h b/include/sysemu/block-backend.h
index b23f683..096c17f 100644
--- a/include/sysemu/block-backend.h
+++ b/include/sysemu/block-backend.h
@@ -107,6 +107,7 @@ bool bdrv_has_blk(BlockDriverState *bs);
 bool bdrv_is_root_node(BlockDriverState *bs);
 int blk_set_perm(BlockBackend *blk, uint64_t perm, uint64_t shared_perm,
                  Error **errp);
+void blk_get_perm(BlockBackend *blk, uint64_t *perm, uint64_t *shared_perm);
 
 void blk_set_allow_write_beyond_eof(BlockBackend *blk, bool allow);
 void blk_iostatus_enable(BlockBackend *blk);
diff --git a/qemu-io-cmds.c b/qemu-io-cmds.c
index e415b03..035cb96 100644
--- a/qemu-io-cmds.c
+++ b/qemu-io-cmds.c
@@ -83,6 +83,29 @@ static int command(BlockBackend *blk, const cmdinfo_t *ct, int argc,
         }
         return 0;
     }
+
+    /* Request additional permissions if necessary for this command. The caller
+     * is responsible for restoring the original permissions afterwards if this
+     * is what it wants. */
+    if (ct->perm && blk_is_available(blk)) {
+        uint64_t orig_perm, orig_shared_perm;
+        blk_get_perm(blk, &orig_perm, &orig_shared_perm);
+
+        if (ct->perm & ~orig_perm) {
+            uint64_t new_perm;
+            Error *local_err = NULL;
+            int ret;
+
+            new_perm = orig_perm | ct->perm;
+
+            ret = blk_set_perm(blk, new_perm, orig_shared_perm, &local_err);
+            if (ret < 0) {
+                error_report_err(local_err);
+                return 0;
+            }
+        }
+    }
+
     optind = 0;
     return ct->cfunc(blk, argc, argv);
 }
@@ -916,6 +939,7 @@ static const cmdinfo_t write_cmd = {
     .name       = "write",
     .altname    = "w",
     .cfunc      = write_f,
+    .perm       = BLK_PERM_WRITE,
     .argmin     = 2,
     .argmax     = -1,
     .args       = "[-bcCfquz] [-P pattern] off len",
@@ -1091,6 +1115,7 @@ static int writev_f(BlockBackend *blk, int argc, char **argv);
 static const cmdinfo_t writev_cmd = {
     .name       = "writev",
     .cfunc      = writev_f,
+    .perm       = BLK_PERM_WRITE,
     .argmin     = 2,
     .argmax     = -1,
     .args       = "[-Cfq] [-P pattern] off len [len..]",
@@ -1390,6 +1415,7 @@ static int aio_write_f(BlockBackend *blk, int argc, char **argv);
 static const cmdinfo_t aio_write_cmd = {
     .name       = "aio_write",
     .cfunc      = aio_write_f,
+    .perm       = BLK_PERM_WRITE,
     .argmin     = 2,
     .argmax     = -1,
     .args       = "[-Cfiquz] [-P pattern] off len [len..]",
@@ -1554,6 +1580,7 @@ static const cmdinfo_t truncate_cmd = {
     .name       = "truncate",
     .altname    = "t",
     .cfunc      = truncate_f,
+    .perm       = BLK_PERM_WRITE | BLK_PERM_RESIZE,
     .argmin     = 1,
     .argmax     = 1,
     .args       = "off",
@@ -1651,6 +1678,7 @@ static const cmdinfo_t discard_cmd = {
     .name       = "discard",
     .altname    = "d",
     .cfunc      = discard_f,
+    .perm       = BLK_PERM_WRITE,
     .argmin     = 2,
     .argmax     = -1,
     .args       = "[-Cq] off len",
-- 
1.8.3.1

  parent reply	other threads:[~2017-02-21 15:00 UTC|newest]

Thread overview: 131+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2017-02-21 14:57 [Qemu-devel] [PATCH 00/54] New op blocker system, part 1 Kevin Wolf
2017-02-21 14:57 ` [Qemu-devel] [PATCH 01/54] blockdev: Use BlockBackend to resize in qmp_block_resize() Kevin Wolf
2017-02-22 12:27   ` Max Reitz
2017-02-21 14:57 ` [Qemu-devel] [PATCH 02/54] qcow2: Use BB for resizing in qcow2_amend_options() Kevin Wolf
2017-02-22 12:28   ` Max Reitz
2017-02-22 15:53   ` Eric Blake
2017-02-21 14:57 ` [Qemu-devel] [PATCH 03/54] mirror: Resize active commit base in mirror_run() Kevin Wolf
2017-02-22 12:34   ` Max Reitz
2017-02-23 11:31   ` Fam Zheng
2017-02-21 14:58 ` [Qemu-devel] [PATCH 04/54] block: Pass BdrvChild to bdrv_truncate() Kevin Wolf
2017-02-22 12:37   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 05/54] block: Attach bs->file only during .bdrv_open() Kevin Wolf
2017-02-22 12:41   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 06/54] block: Factor out bdrv_open_child_bs() Kevin Wolf
2017-02-22 12:46   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 07/54] block: Use BlockBackend for image probing Kevin Wolf
2017-02-22 12:56   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 08/54] block: Factor out bdrv_open_driver() Kevin Wolf
2017-02-22 12:59   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 09/54] block: Add bdrv_new_open_driver() Kevin Wolf
2017-02-22 13:15   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 10/54] vvfat: Use opened node as backing file Kevin Wolf
2017-02-22 13:26   ` Max Reitz
2017-02-23 11:49   ` Fam Zheng
2017-02-23 12:25     ` Kevin Wolf
2017-02-23 12:45       ` Fam Zheng
2017-02-21 14:58 ` [Qemu-devel] [PATCH 11/54] tests: Use opened block node for block job tests Kevin Wolf
2017-02-22 13:41   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 12/54] block: Add op blocker permission constants Kevin Wolf
2017-02-22 13:43   ` Max Reitz
2017-02-23 11:53   ` Fam Zheng
2017-02-21 14:58 ` [Qemu-devel] [PATCH 13/54] block: Add Error argument to bdrv_attach_child() Kevin Wolf
2017-02-22 13:46   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 14/54] block: Let callers request permissions when attaching a child node Kevin Wolf
2017-02-22 13:47   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 15/54] block: Involve block drivers in permission granting Kevin Wolf
2017-02-22 14:04   ` Max Reitz
2017-02-27 12:28     ` Kevin Wolf
2017-02-27 12:32       ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 16/54] block: Default .bdrv_child_perm() for filter drivers Kevin Wolf
2017-02-22 14:05   ` Max Reitz
2017-02-22 14:28   ` Max Reitz
2017-02-23 12:36   ` Fam Zheng
2017-02-21 14:58 ` [Qemu-devel] [PATCH 17/54] block: Request child permissions in " Kevin Wolf
2017-02-22 14:07   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 18/54] block: Default .bdrv_child_perm() for format drivers Kevin Wolf
2017-02-22 14:08   ` Max Reitz
2017-02-25 11:57   ` Max Reitz
2017-02-27 12:33     ` Kevin Wolf
2017-02-27 12:34       ` Max Reitz
2017-02-27 14:05         ` Kevin Wolf
2017-02-27 14:15           ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 19/54] block: Request child permissions in " Kevin Wolf
2017-02-22 14:09   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 20/54] vvfat: Implement .bdrv_child_perm() Kevin Wolf
2017-02-22 14:12   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 21/54] block: Require .bdrv_child_perm() with child nodes Kevin Wolf
2017-02-22 14:14   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 22/54] block: Request real permissions in bdrv_attach_child() Kevin Wolf
2017-02-22 14:24   ` Max Reitz
2017-02-22 14:31   ` Max Reitz
2017-02-27 14:10     ` Kevin Wolf
2017-02-21 14:58 ` [Qemu-devel] [PATCH 23/54] block: Add permissions to BlockBackend Kevin Wolf
2017-02-22 14:32   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 24/54] block: Add permissions to blk_new() Kevin Wolf
2017-02-22 14:36   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 25/54] block: Add error parameter to blk_insert_bs() Kevin Wolf
2017-02-22 14:42   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 26/54] block: Add BDRV_O_RESIZE for blk_new_open() Kevin Wolf
2017-02-22 14:51   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 27/54] block: Request real permissions in blk_new_open() Kevin Wolf
2017-02-22 14:52   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 28/54] block: Allow error return in BlockDevOps.change_media_cb() Kevin Wolf
2017-02-24 13:29   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 29/54] hw/block: Request permissions Kevin Wolf
2017-02-24 13:46   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 30/54] hw/block: Introduce share-rw qdev property Kevin Wolf
2017-02-24 13:49   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 31/54] blockjob: Add permissions to block_job_create() Kevin Wolf
2017-02-24 13:50   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 32/54] block: Add BdrvChildRole.get_parent_desc() Kevin Wolf
2017-02-24 13:56   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 33/54] block: Include details on permission errors in message Kevin Wolf
2017-02-24  8:41   ` Fam Zheng
2017-02-24 13:58   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 34/54] block: Add BdrvChildRole.stay_at_node Kevin Wolf
2017-02-24 14:00   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 35/54] blockjob: Add permissions to block_job_add_bdrv() Kevin Wolf
2017-02-24 14:10   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 36/54] commit: Use real permissions in commit block job Kevin Wolf
2017-02-24 17:29   ` Max Reitz
2017-02-27 18:43     ` Kevin Wolf
2017-02-21 14:58 ` [Qemu-devel] [PATCH 37/54] commit: Use real permissions for HMP 'commit' Kevin Wolf
2017-02-25 11:58   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 38/54] backup: Use real permissions in backup block job Kevin Wolf
2017-02-25 12:06   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 39/54] block: Fix pending requests check in bdrv_append() Kevin Wolf
2017-02-25 12:15   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 40/54] block: BdrvChildRole.attach/detach() callbacks Kevin Wolf
2017-02-25 12:29   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 41/54] block: Allow backing file links in change_parent_backing_link() Kevin Wolf
2017-02-25 12:33   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 42/54] mirror: Use real permissions in mirror/active commit block job Kevin Wolf
2017-02-25 13:49   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 43/54] stream: Use real permissions in streaming " Kevin Wolf
2017-02-25 13:58   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 44/54] mirror: Add filter-node-name to blockdev-mirror Kevin Wolf
2017-02-25 14:19   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 45/54] commit: Add filter-node-name to block-commit Kevin Wolf
2017-02-25 14:37   ` Max Reitz
2017-02-21 14:58 ` Kevin Wolf [this message]
2017-02-25 14:46   ` [Qemu-devel] [PATCH 46/54] hmp: Request permissions in qemu-io Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 47/54] migration/block: Use real permissions Kevin Wolf
2017-02-25 14:54   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 48/54] nbd/server: Use real permissions for NBD exports Kevin Wolf
2017-02-25 15:05   ` Max Reitz
2017-02-27 20:09   ` Eric Blake
2017-02-21 14:58 ` [Qemu-devel] [PATCH 49/54] tests: Remove FIXME comments Kevin Wolf
2017-02-25 15:06   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 50/54] block: Pass BdrvChild to bdrv_aligned_preadv/pwritev Kevin Wolf
2017-02-25 15:12   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 51/54] block: Assertions for write permissions Kevin Wolf
2017-02-25 15:13   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 52/54] block: Assertions for resize permission Kevin Wolf
2017-02-25 15:14   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 53/54] block: Add Error parameter to bdrv_set_backing_hd() Kevin Wolf
2017-02-25 15:36   ` Max Reitz
2017-02-21 14:58 ` [Qemu-devel] [PATCH 54/54] block: Add Error parameter to bdrv_append() Kevin Wolf
2017-02-25 15:49   ` Max Reitz
2017-02-21 16:38 ` [Qemu-devel] [PATCH 00/54] New op blocker system, part 1 no-reply
2017-02-24 14:25 ` Kevin Wolf

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1487689130-30373-47-git-send-email-kwolf@redhat.com \
    --to=kwolf@redhat.com \
    --cc=famz@redhat.com \
    --cc=jcody@redhat.com \
    --cc=mreitz@redhat.com \
    --cc=qemu-block@nongnu.org \
    --cc=qemu-devel@nongnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.