master
c 79 lines 2.62 KB
Raw
1 /* SPDX-License-Identifier: GPL-2.0-or-later */
2 #include "qemu/osdep.h"
3
4 #include "system/block-backend.h"
5 #include "block/block_int.h"
6 #include "qapi/qapi-commands-block.h"
7 #include "qapi/error.h"
8 #include "qemu-io.h"
9
10 void qmp_x_qemu_io(const char *device, const char *qdev,
11 const char *command, Error **errp)
12 {
13 BlockBackend *blk = NULL;
14 BlockBackend *local_blk = NULL;
15 BlockDriverState *bs = NULL;
16 int ret;
17
18 if (!device && !qdev) {
19 error_setg(errp, "Must specify either device or qdev");
20 return;
21 }
22 if (qdev && device) {
23 error_setg(errp, "Cannot specify both qdev and device");
24 return;
25 }
26
27 if (qdev) {
28 blk = blk_by_qdev_id(qdev, errp);
29 if (!blk) {
30 return;
31 }
32 } else {
33 blk = blk_by_name(device);
34 if (!blk) {
35 bs = bdrv_lookup_bs(NULL, device, errp);
36 if (!bs) {
37 return;
38 }
39 }
40 }
41
42 if (bs) {
43 blk = local_blk = blk_new(bdrv_get_aio_context(bs), 0, BLK_PERM_ALL);
44 ret = blk_insert_bs(blk, bs, errp);
45 if (ret < 0) {
46 goto fail;
47 }
48 }
49
50 /*
51 * Notably absent: Proper permission management. This is sad, but it seems
52 * almost impossible to achieve without changing the semantics and thereby
53 * limiting the use cases of the qemu-io command.
54 *
55 * In an ideal world we would unconditionally create a new BlockBackend for
56 * qemuio_command(), but we have commands like 'reopen' and want them to
57 * take effect on the exact BlockBackend whose name the user passed instead
58 * of just on a temporary copy of it.
59 *
60 * Another problem is that deleting the temporary BlockBackend involves
61 * draining all requests on it first, but some qemu-iotests cases want to
62 * issue multiple aio_read/write requests and expect them to complete in
63 * the background while the monitor has already returned.
64 *
65 * This is also what prevents us from saving the original permissions and
66 * restoring them later: We can't revoke permissions until all requests
67 * have completed, and we don't know when that is nor can we really let
68 * anything else run before we have revoken them to avoid race conditions.
69 *
70 * What happens now is that command() in qemu-io-cmds.c can extend the
71 * permissions if necessary for the qemu-io command. And they simply stay
72 * extended, possibly resulting in a read-only guest device keeping write
73 * permissions. Ugly, but it appears to be the lesser evil.
74 */
75 qemuio_command(blk, command, errp);
76
77 fail:
78 blk_unref(local_blk);
79 }