1
The following changes since commit bfec359afba088aaacc7d316f43302f28c6e642a:
1
The following changes since commit 19eb2d4e736dc895f31fbd6b520e514f10cc08e0:
2
2
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-qdev-2017-04-21' into staging (2017-04-21 11:42:03 +0100)
3
Merge remote-tracking branch 'remotes/thibault/tags/samuel-thibault' into staging (2019-05-07 10:43:32 +0100)
4
4
5
are available in the git repository at:
5
are available in the Git repository at:
6
6
7
git://github.com/codyprime/qemu-kvm-jtc.git tags/block-pull-request
7
https://git.xanclic.moe/XanClic/qemu.git tags/pull-block-2019-05-07
8
8
9
for you to fetch changes up to 1507631e438930bc07f776f303af127a9cdb4d41:
9
for you to fetch changes up to 1278dce7927301bf3d004a40061dbd2c1e0846a8:
10
10
11
qemu-iotests: _cleanup_qemu must be called on exit (2017-04-21 08:32:44 -0400)
11
iotests: Fix iotests 110 and 126 (2019-05-07 17:14:21 +0200)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
Block patches:
15
Block patches for 2.10
15
- Fixes to qcow2's implementation of qemu-img check
16
- Our SSH driver now supports bdrv_refresh_filename()
17
- Miscellaneous fixes
16
18
17
----------------------------------------------------------------
19
----------------------------------------------------------------
20
Alberto Garcia (2):
21
block: Assert that drv->bdrv_child_perm is set in bdrv_child_perm()
22
commit: Use bdrv_append() in commit_start()
18
23
19
Ashish Mittal (2):
24
Andrey Shinkevich (1):
20
block/vxhs.c: Add support for a new block device type called "vxhs"
25
qcow2: discard bitmap when removed
21
block/vxhs.c: Add qemu-iotests for new block device type "vxhs"
22
26
23
Jeff Cody (10):
27
Max Reitz (3):
24
qemu-iotests: exclude vxhs from image creation via protocol
28
block/ssh: Implement .bdrv_refresh_filename()
25
block: add bdrv_set_read_only() helper function
29
block/ssh: Implement .bdrv_dirname()
26
block: do not set BDS read_only if copy_on_read enabled
30
iotests: Fix iotests 110 and 126
27
block: honor BDRV_O_ALLOW_RDWR when clearing bs->read_only
28
block: code movement
29
block: introduce bdrv_can_set_read_only()
30
block: use bdrv_can_set_read_only() during reopen
31
block/rbd - update variable names to more apt names
32
block/rbd: Add support for reopen()
33
qemu-iotests: _cleanup_qemu must be called on exit
34
31
35
block.c | 56 +++-
32
Vladimir Sementsov-Ogievskiy (5):
36
block/Makefile.objs | 2 +
33
qcow2-refcount: fix check_oflag_copied
37
block/bochs.c | 5 +-
34
qcow2-refcount: avoid eating RAM
38
block/cloop.c | 5 +-
35
qcow2-refcount: check_refcounts_l2: reduce ignored overlaps
39
block/dmg.c | 6 +-
36
qcow2-refcount: check_refcounts_l2: don't count fixed cluster as
40
block/rbd.c | 65 +++--
37
allocated
41
block/trace-events | 17 ++
38
qcow2-refcount: don't mask corruptions under internal errors
42
block/vvfat.c | 19 +-
39
43
block/vxhs.c | 575 +++++++++++++++++++++++++++++++++++++++
40
block.c | 9 ++--
44
configure | 39 +++
41
block/commit.c | 11 +----
45
include/block/block.h | 2 +
42
block/qcow2-bitmap.c | 2 +-
46
qapi/block-core.json | 23 +-
43
block/qcow2-refcount.c | 80 ++++++++++++++++++++++-------------
47
tests/qemu-iotests/017 | 1 +
44
block/ssh.c | 73 +++++++++++++++++++++++++++++---
48
tests/qemu-iotests/020 | 1 +
45
tests/qemu-iotests/110 | 10 +++--
49
tests/qemu-iotests/028 | 1 +
46
tests/qemu-iotests/126 | 10 +++--
50
tests/qemu-iotests/029 | 1 +
47
tests/qemu-iotests/138 | 12 +++---
51
tests/qemu-iotests/073 | 1 +
48
tests/qemu-iotests/138.out | 5 ++-
52
tests/qemu-iotests/094 | 11 +-
49
tests/qemu-iotests/207 | 10 ++---
53
tests/qemu-iotests/102 | 5 +-
50
tests/qemu-iotests/207.out | 10 ++---
54
tests/qemu-iotests/109 | 1 +
51
tests/qemu-iotests/common.rc | 2 +-
55
tests/qemu-iotests/114 | 1 +
52
tests/qemu-iotests/iotests.py | 2 +-
56
tests/qemu-iotests/117 | 1 +
53
13 files changed, 159 insertions(+), 77 deletions(-)
57
tests/qemu-iotests/130 | 2 +
58
tests/qemu-iotests/134 | 1 +
59
tests/qemu-iotests/140 | 1 +
60
tests/qemu-iotests/141 | 1 +
61
tests/qemu-iotests/143 | 1 +
62
tests/qemu-iotests/156 | 2 +
63
tests/qemu-iotests/158 | 1 +
64
tests/qemu-iotests/common | 6 +
65
tests/qemu-iotests/common.config | 13 +
66
tests/qemu-iotests/common.filter | 1 +
67
tests/qemu-iotests/common.rc | 19 ++
68
33 files changed, 844 insertions(+), 42 deletions(-)
69
create mode 100644 block/vxhs.c
70
54
71
--
55
--
72
2.9.3
56
2.20.1
73
57
74
58
diff view generated by jsdifflib
1
Update 'clientname' to be 'user', which tracks better with both
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
the QAPI and rados variable naming.
3
2
4
Update 'name' to be 'image_name', as it indicates the rbd image.
3
Increase corruptions_fixed only after successful fix.
5
Naming it 'image' would have been ideal, but we are using that for
6
the rados_image_t value returned by rbd_open().
7
4
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
Signed-off-by: Jeff Cody <jcody@redhat.com>
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
10
Reviewed-by: John Snow <jsnow@redhat.com>
7
Message-id: 20190227131433.197063-2-vsementsov@virtuozzo.com
11
Message-id: b7ec1fb2e1cf36f9b6911631447a5b0422590b7d.1491597120.git.jcody@redhat.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
9
---
13
block/rbd.c | 33 +++++++++++++++++----------------
10
block/qcow2-refcount.c | 8 ++++----
14
1 file changed, 17 insertions(+), 16 deletions(-)
11
1 file changed, 4 insertions(+), 4 deletions(-)
15
12
16
diff --git a/block/rbd.c b/block/rbd.c
13
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
17
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
18
--- a/block/rbd.c
15
--- a/block/qcow2-refcount.c
19
+++ b/block/rbd.c
16
+++ b/block/qcow2-refcount.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVRBDState {
17
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
21
rados_t cluster;
18
for (i = 0; i < s->l1_size; i++) {
22
rados_ioctx_t io_ctx;
19
uint64_t l1_entry = s->l1_table[i];
23
rbd_image_t image;
20
uint64_t l2_offset = l1_entry & L1E_OFFSET_MASK;
24
- char *name;
21
- bool l2_dirty = false;
25
+ char *image_name;
22
+ int l2_dirty = 0;
26
char *snap;
23
27
} BDRVRBDState;
24
if (!l2_offset) {
28
25
continue;
29
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
26
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
30
int64_t bytes = 0;
27
l2_table[j] = cpu_to_be64(refcount == 1
31
int64_t objsize;
28
? l2_entry | QCOW_OFLAG_COPIED
32
int obj_order = 0;
29
: l2_entry & ~QCOW_OFLAG_COPIED);
33
- const char *pool, *name, *conf, *clientname, *keypairs;
30
- l2_dirty = true;
34
+ const char *pool, *image_name, *conf, *user, *keypairs;
31
- res->corruptions_fixed++;
35
const char *secretid;
32
+ l2_dirty++;
36
rados_t cluster;
33
} else {
37
rados_ioctx_t io_ctx;
34
res->corruptions++;
38
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
35
}
39
*/
36
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
40
pool = qdict_get_try_str(options, "pool");
37
}
41
conf = qdict_get_try_str(options, "conf");
38
}
42
- clientname = qdict_get_try_str(options, "user");
39
43
- name = qdict_get_try_str(options, "image");
40
- if (l2_dirty) {
44
+ user = qdict_get_try_str(options, "user");
41
+ if (l2_dirty > 0) {
45
+ image_name = qdict_get_try_str(options, "image");
42
ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L2,
46
keypairs = qdict_get_try_str(options, "=keyvalue-pairs");
43
l2_offset, s->cluster_size,
47
44
false);
48
- ret = rados_create(&cluster, clientname);
45
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
49
+ ret = rados_create(&cluster, user);
46
res->check_errors++;
50
if (ret < 0) {
47
goto fail;
51
error_setg_errno(errp, -ret, "error initializing");
48
}
52
goto exit;
49
+ res->corruptions_fixed += l2_dirty;
53
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
50
}
54
goto shutdown;
55
}
51
}
56
52
57
- ret = rbd_create(io_ctx, name, bytes, &obj_order);
58
+ ret = rbd_create(io_ctx, image_name, bytes, &obj_order);
59
if (ret < 0) {
60
error_setg_errno(errp, -ret, "error rbd create");
61
}
62
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
63
Error **errp)
64
{
65
BDRVRBDState *s = bs->opaque;
66
- const char *pool, *snap, *conf, *clientname, *name, *keypairs;
67
+ const char *pool, *snap, *conf, *user, *image_name, *keypairs;
68
const char *secretid;
69
QemuOpts *opts;
70
Error *local_err = NULL;
71
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
72
pool = qemu_opt_get(opts, "pool");
73
conf = qemu_opt_get(opts, "conf");
74
snap = qemu_opt_get(opts, "snapshot");
75
- clientname = qemu_opt_get(opts, "user");
76
- name = qemu_opt_get(opts, "image");
77
+ user = qemu_opt_get(opts, "user");
78
+ image_name = qemu_opt_get(opts, "image");
79
keypairs = qemu_opt_get(opts, "=keyvalue-pairs");
80
81
- if (!pool || !name) {
82
+ if (!pool || !image_name) {
83
error_setg(errp, "Parameters 'pool' and 'image' are required");
84
r = -EINVAL;
85
goto failed_opts;
86
}
87
88
- r = rados_create(&s->cluster, clientname);
89
+ r = rados_create(&s->cluster, user);
90
if (r < 0) {
91
error_setg_errno(errp, -r, "error initializing");
92
goto failed_opts;
93
}
94
95
s->snap = g_strdup(snap);
96
- s->name = g_strdup(name);
97
+ s->image_name = g_strdup(image_name);
98
99
/* try default location when conf=NULL, but ignore failure */
100
r = rados_conf_read_file(s->cluster, conf);
101
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
102
}
103
104
/* rbd_open is always r/w */
105
- r = rbd_open(s->io_ctx, s->name, &s->image, s->snap);
106
+ r = rbd_open(s->io_ctx, s->image_name, &s->image, s->snap);
107
if (r < 0) {
108
- error_setg_errno(errp, -r, "error reading header from %s", s->name);
109
+ error_setg_errno(errp, -r, "error reading header from %s",
110
+ s->image_name);
111
goto failed_open;
112
}
113
114
@@ -XXX,XX +XXX,XX @@ failed_open:
115
failed_shutdown:
116
rados_shutdown(s->cluster);
117
g_free(s->snap);
118
- g_free(s->name);
119
+ g_free(s->image_name);
120
failed_opts:
121
qemu_opts_del(opts);
122
g_free(mon_host);
123
@@ -XXX,XX +XXX,XX @@ static void qemu_rbd_close(BlockDriverState *bs)
124
rbd_close(s->image);
125
rados_ioctx_destroy(s->io_ctx);
126
g_free(s->snap);
127
- g_free(s->name);
128
+ g_free(s->image_name);
129
rados_shutdown(s->cluster);
130
}
131
132
--
53
--
133
2.9.3
54
2.20.1
134
55
135
56
diff view generated by jsdifflib
1
From: Ashish Mittal <ashmit602@gmail.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Source code for the qnio library that this code loads can be downloaded from:
3
qcow2_inc_refcounts_imrt() (through realloc_refcount_array()) can eat
4
https://github.com/VeritasHyperScale/libqnio.git
4
an unpredictable amount of memory on corrupted table entries, which are
5
referencing regions far beyond the end of file.
5
6
6
Sample command line using JSON syntax:
7
Prevent this, by skipping such regions from further processing.
7
./x86_64-softmmu/qemu-system-x86_64 -name instance-00000008 -S -vnc 0.0.0.0:0
8
-k en-us -vga cirrus -device virtio-balloon-pci,id=balloon0,bus=pci.0,addr=0x5
9
-msg timestamp=on
10
'json:{"driver":"vxhs","vdisk-id":"c3e9095a-a5ee-4dce-afeb-2a59fb387410",
11
"server":{"host":"172.172.17.4","port":"9999"}}'
12
8
13
Sample command line using URI syntax:
9
Interesting that iotest 138 checks exactly the behavior which we fix
14
qemu-img convert -f raw -O raw -n
10
here. So, change the test appropriately.
15
/var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
16
vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
17
11
18
Sample command line using TLS credentials (run in secure mode):
12
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
19
./qemu-io --object
13
Reviewed-by: Max Reitz <mreitz@redhat.com>
20
tls-creds-x509,id=tls0,dir=/etc/pki/qemu/vxhs,endpoint=client -c 'read
14
Message-id: 20190227131433.197063-3-vsementsov@virtuozzo.com
21
-v 66000 2.5k' 'json:{"server.host": "127.0.0.1", "server.port": "9999",
15
Signed-off-by: Max Reitz <mreitz@redhat.com>
22
"vdisk-id": "/test.raw", "driver": "vxhs", "tls-creds":"tls0"}'
16
---
17
block/qcow2-refcount.c | 19 +++++++++++++++++++
18
tests/qemu-iotests/138 | 12 +++++-------
19
tests/qemu-iotests/138.out | 5 ++++-
20
3 files changed, 28 insertions(+), 8 deletions(-)
23
21
24
Signed-off-by: Ashish Mittal <Ashish.Mittal@veritas.com>
22
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
25
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
26
Reviewed-by: Jeff Cody <jcody@redhat.com>
27
Signed-off-by: Jeff Cody <jcody@redhat.com>
28
Message-id: 1491277689-24949-2-git-send-email-Ashish.Mittal@veritas.com
29
---
30
block/Makefile.objs | 2 +
31
block/trace-events | 17 ++
32
block/vxhs.c | 575 +++++++++++++++++++++++++++++++++++++++++++++++++++
33
configure | 39 ++++
34
qapi/block-core.json | 23 ++-
35
5 files changed, 654 insertions(+), 2 deletions(-)
36
create mode 100644 block/vxhs.c
37
38
diff --git a/block/Makefile.objs b/block/Makefile.objs
39
index XXXXXXX..XXXXXXX 100644
23
index XXXXXXX..XXXXXXX 100644
40
--- a/block/Makefile.objs
24
--- a/block/qcow2-refcount.c
41
+++ b/block/Makefile.objs
25
+++ b/block/qcow2-refcount.c
42
@@ -XXX,XX +XXX,XX @@ block-obj-$(CONFIG_LIBNFS) += nfs.o
26
@@ -XXX,XX +XXX,XX @@ int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
43
block-obj-$(CONFIG_CURL) += curl.o
27
{
44
block-obj-$(CONFIG_RBD) += rbd.o
28
BDRVQcow2State *s = bs->opaque;
45
block-obj-$(CONFIG_GLUSTERFS) += gluster.o
29
uint64_t start, last, cluster_offset, k, refcount;
46
+block-obj-$(CONFIG_VXHS) += vxhs.o
30
+ int64_t file_len;
47
block-obj-$(CONFIG_LIBSSH2) += ssh.o
31
int ret;
48
block-obj-y += accounting.o dirty-bitmap.o
32
49
block-obj-y += write-threshold.o
33
if (size <= 0) {
50
@@ -XXX,XX +XXX,XX @@ rbd.o-cflags := $(RBD_CFLAGS)
34
return 0;
51
rbd.o-libs := $(RBD_LIBS)
35
}
52
gluster.o-cflags := $(GLUSTERFS_CFLAGS)
36
53
gluster.o-libs := $(GLUSTERFS_LIBS)
37
+ file_len = bdrv_getlength(bs->file->bs);
54
+vxhs.o-libs := $(VXHS_LIBS)
38
+ if (file_len < 0) {
55
ssh.o-cflags := $(LIBSSH2_CFLAGS)
39
+ return file_len;
56
ssh.o-libs := $(LIBSSH2_LIBS)
57
block-obj-$(if $(CONFIG_BZIP2),m,n) += dmg-bz2.o
58
diff --git a/block/trace-events b/block/trace-events
59
index XXXXXXX..XXXXXXX 100644
60
--- a/block/trace-events
61
+++ b/block/trace-events
62
@@ -XXX,XX +XXX,XX @@ qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s
63
qed_aio_write_prefill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
64
qed_aio_write_postfill(void *s, void *acb, uint64_t start, size_t len, uint64_t offset) "s %p acb %p start %"PRIu64" len %zu offset %"PRIu64
65
qed_aio_write_main(void *s, void *acb, int ret, uint64_t offset, size_t len) "s %p acb %p ret %d offset %"PRIu64" len %zu"
66
+
67
+# block/vxhs.c
68
+vxhs_iio_callback(int error) "ctx is NULL: error %d"
69
+vxhs_iio_callback_chnfail(int err, int error) "QNIO channel failed, no i/o %d, %d"
70
+vxhs_iio_callback_unknwn(int opcode, int err) "unexpected opcode %d, errno %d"
71
+vxhs_aio_rw_invalid(int req) "Invalid I/O request iodir %d"
72
+vxhs_aio_rw_ioerr(char *guid, int iodir, uint64_t size, uint64_t off, void *acb, int ret, int err) "IO ERROR (vDisk %s) FOR : Read/Write = %d size = %lu offset = %lu ACB = %p. Error = %d, errno = %d"
73
+vxhs_get_vdisk_stat_err(char *guid, int ret, int err) "vDisk (%s) stat ioctl failed, ret = %d, errno = %d"
74
+vxhs_get_vdisk_stat(char *vdisk_guid, uint64_t vdisk_size) "vDisk %s stat ioctl returned size %lu"
75
+vxhs_complete_aio(void *acb, uint64_t ret) "aio failed acb %p ret %ld"
76
+vxhs_parse_uri_filename(const char *filename) "URI passed via bdrv_parse_filename %s"
77
+vxhs_open_vdiskid(const char *vdisk_id) "Opening vdisk-id %s"
78
+vxhs_open_hostinfo(char *of_vsa_addr, int port) "Adding host %s:%d to BDRVVXHSState"
79
+vxhs_open_iio_open(const char *host) "Failed to connect to storage agent on host %s"
80
+vxhs_parse_uri_hostinfo(char *host, int port) "Host: IP %s, Port %d"
81
+vxhs_close(char *vdisk_guid) "Closing vdisk %s"
82
+vxhs_get_creds(const char *cacert, const char *client_key, const char *client_cert) "cacert %s, client_key %s, client_cert %s"
83
diff --git a/block/vxhs.c b/block/vxhs.c
84
new file mode 100644
85
index XXXXXXX..XXXXXXX
86
--- /dev/null
87
+++ b/block/vxhs.c
88
@@ -XXX,XX +XXX,XX @@
89
+/*
90
+ * QEMU Block driver for Veritas HyperScale (VxHS)
91
+ *
92
+ * Copyright (c) 2017 Veritas Technologies LLC.
93
+ *
94
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
95
+ * See the COPYING file in the top-level directory.
96
+ *
97
+ */
98
+
99
+#include "qemu/osdep.h"
100
+#include <qnio/qnio_api.h>
101
+#include <sys/param.h>
102
+#include "block/block_int.h"
103
+#include "qapi/qmp/qerror.h"
104
+#include "qapi/qmp/qdict.h"
105
+#include "qapi/qmp/qstring.h"
106
+#include "trace.h"
107
+#include "qemu/uri.h"
108
+#include "qapi/error.h"
109
+#include "qemu/uuid.h"
110
+#include "crypto/tlscredsx509.h"
111
+
112
+#define VXHS_OPT_FILENAME "filename"
113
+#define VXHS_OPT_VDISK_ID "vdisk-id"
114
+#define VXHS_OPT_SERVER "server"
115
+#define VXHS_OPT_HOST "host"
116
+#define VXHS_OPT_PORT "port"
117
+
118
+/* Only accessed under QEMU global mutex */
119
+static uint32_t vxhs_ref;
120
+
121
+typedef enum {
122
+ VDISK_AIO_READ,
123
+ VDISK_AIO_WRITE,
124
+} VDISKAIOCmd;
125
+
126
+/*
127
+ * HyperScale AIO callbacks structure
128
+ */
129
+typedef struct VXHSAIOCB {
130
+ BlockAIOCB common;
131
+ int err;
132
+} VXHSAIOCB;
133
+
134
+typedef struct VXHSvDiskHostsInfo {
135
+ void *dev_handle; /* Device handle */
136
+ char *host; /* Host name or IP */
137
+ int port; /* Host's port number */
138
+} VXHSvDiskHostsInfo;
139
+
140
+/*
141
+ * Structure per vDisk maintained for state
142
+ */
143
+typedef struct BDRVVXHSState {
144
+ VXHSvDiskHostsInfo vdisk_hostinfo; /* Per host info */
145
+ char *vdisk_guid;
146
+ char *tlscredsid; /* tlscredsid */
147
+} BDRVVXHSState;
148
+
149
+static void vxhs_complete_aio_bh(void *opaque)
150
+{
151
+ VXHSAIOCB *acb = opaque;
152
+ BlockCompletionFunc *cb = acb->common.cb;
153
+ void *cb_opaque = acb->common.opaque;
154
+ int ret = 0;
155
+
156
+ if (acb->err != 0) {
157
+ trace_vxhs_complete_aio(acb, acb->err);
158
+ ret = (-EIO);
159
+ }
160
+
161
+ qemu_aio_unref(acb);
162
+ cb(cb_opaque, ret);
163
+}
164
+
165
+/*
166
+ * Called from a libqnio thread
167
+ */
168
+static void vxhs_iio_callback(void *ctx, uint32_t opcode, uint32_t error)
169
+{
170
+ VXHSAIOCB *acb = NULL;
171
+
172
+ switch (opcode) {
173
+ case IRP_READ_REQUEST:
174
+ case IRP_WRITE_REQUEST:
175
+
176
+ /*
177
+ * ctx is VXHSAIOCB*
178
+ * ctx is NULL if error is QNIOERROR_CHANNEL_HUP
179
+ */
180
+ if (ctx) {
181
+ acb = ctx;
182
+ } else {
183
+ trace_vxhs_iio_callback(error);
184
+ goto out;
185
+ }
186
+
187
+ if (error) {
188
+ if (!acb->err) {
189
+ acb->err = error;
190
+ }
191
+ trace_vxhs_iio_callback(error);
192
+ }
193
+
194
+ aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
195
+ vxhs_complete_aio_bh, acb);
196
+ break;
197
+
198
+ default:
199
+ if (error == QNIOERROR_HUP) {
200
+ /*
201
+ * Channel failed, spontaneous notification,
202
+ * not in response to I/O
203
+ */
204
+ trace_vxhs_iio_callback_chnfail(error, errno);
205
+ } else {
206
+ trace_vxhs_iio_callback_unknwn(opcode, error);
207
+ }
208
+ break;
209
+ }
210
+out:
211
+ return;
212
+}
213
+
214
+static QemuOptsList runtime_opts = {
215
+ .name = "vxhs",
216
+ .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
217
+ .desc = {
218
+ {
219
+ .name = VXHS_OPT_FILENAME,
220
+ .type = QEMU_OPT_STRING,
221
+ .help = "URI to the Veritas HyperScale image",
222
+ },
223
+ {
224
+ .name = VXHS_OPT_VDISK_ID,
225
+ .type = QEMU_OPT_STRING,
226
+ .help = "UUID of the VxHS vdisk",
227
+ },
228
+ {
229
+ .name = "tls-creds",
230
+ .type = QEMU_OPT_STRING,
231
+ .help = "ID of the TLS/SSL credentials to use",
232
+ },
233
+ { /* end of list */ }
234
+ },
235
+};
236
+
237
+static QemuOptsList runtime_tcp_opts = {
238
+ .name = "vxhs_tcp",
239
+ .head = QTAILQ_HEAD_INITIALIZER(runtime_tcp_opts.head),
240
+ .desc = {
241
+ {
242
+ .name = VXHS_OPT_HOST,
243
+ .type = QEMU_OPT_STRING,
244
+ .help = "host address (ipv4 addresses)",
245
+ },
246
+ {
247
+ .name = VXHS_OPT_PORT,
248
+ .type = QEMU_OPT_NUMBER,
249
+ .help = "port number on which VxHSD is listening (default 9999)",
250
+ .def_value_str = "9999"
251
+ },
252
+ { /* end of list */ }
253
+ },
254
+};
255
+
256
+/*
257
+ * Parse incoming URI and populate *options with the host
258
+ * and device information
259
+ */
260
+static int vxhs_parse_uri(const char *filename, QDict *options)
261
+{
262
+ URI *uri = NULL;
263
+ char *port;
264
+ int ret = 0;
265
+
266
+ trace_vxhs_parse_uri_filename(filename);
267
+ uri = uri_parse(filename);
268
+ if (!uri || !uri->server || !uri->path) {
269
+ uri_free(uri);
270
+ return -EINVAL;
271
+ }
272
+
273
+ qdict_put(options, VXHS_OPT_SERVER".host", qstring_from_str(uri->server));
274
+
275
+ if (uri->port) {
276
+ port = g_strdup_printf("%d", uri->port);
277
+ qdict_put(options, VXHS_OPT_SERVER".port", qstring_from_str(port));
278
+ g_free(port);
279
+ }
280
+
281
+ qdict_put(options, "vdisk-id", qstring_from_str(uri->path));
282
+
283
+ trace_vxhs_parse_uri_hostinfo(uri->server, uri->port);
284
+ uri_free(uri);
285
+
286
+ return ret;
287
+}
288
+
289
+static void vxhs_parse_filename(const char *filename, QDict *options,
290
+ Error **errp)
291
+{
292
+ if (qdict_haskey(options, "vdisk-id") || qdict_haskey(options, "server")) {
293
+ error_setg(errp, "vdisk-id/server and a file name may not be specified "
294
+ "at the same time");
295
+ return;
296
+ }
297
+
298
+ if (strstr(filename, "://")) {
299
+ int ret = vxhs_parse_uri(filename, options);
300
+ if (ret < 0) {
301
+ error_setg(errp, "Invalid URI. URI should be of the form "
302
+ " vxhs://<host_ip>:<port>/<vdisk-id>");
303
+ }
304
+ }
305
+}
306
+
307
+static int vxhs_init_and_ref(void)
308
+{
309
+ if (vxhs_ref++ == 0) {
310
+ if (iio_init(QNIO_VERSION, vxhs_iio_callback)) {
311
+ return -ENODEV;
312
+ }
313
+ }
314
+ return 0;
315
+}
316
+
317
+static void vxhs_unref(void)
318
+{
319
+ if (--vxhs_ref == 0) {
320
+ iio_fini();
321
+ }
322
+}
323
+
324
+static void vxhs_get_tls_creds(const char *id, char **cacert,
325
+ char **key, char **cert, Error **errp)
326
+{
327
+ Object *obj;
328
+ QCryptoTLSCreds *creds;
329
+ QCryptoTLSCredsX509 *creds_x509;
330
+
331
+ obj = object_resolve_path_component(
332
+ object_get_objects_root(), id);
333
+
334
+ if (!obj) {
335
+ error_setg(errp, "No TLS credentials with id '%s'",
336
+ id);
337
+ return;
338
+ }
339
+
340
+ creds_x509 = (QCryptoTLSCredsX509 *)
341
+ object_dynamic_cast(obj, TYPE_QCRYPTO_TLS_CREDS_X509);
342
+
343
+ if (!creds_x509) {
344
+ error_setg(errp, "Object with id '%s' is not TLS credentials",
345
+ id);
346
+ return;
347
+ }
348
+
349
+ creds = &creds_x509->parent_obj;
350
+
351
+ if (creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
352
+ error_setg(errp,
353
+ "Expecting TLS credentials with a client endpoint");
354
+ return;
355
+ }
40
+ }
356
+
41
+
357
+ /*
42
+ /*
358
+ * Get the cacert, client_cert and client_key file names.
43
+ * Last cluster of qcow2 image may be semi-allocated, so it may be OK to
44
+ * reference some space after file end but it should be less than one
45
+ * cluster.
359
+ */
46
+ */
360
+ if (!creds->dir) {
47
+ if (offset + size - file_len >= s->cluster_size) {
361
+ error_setg(errp, "TLS object missing 'dir' property value");
48
+ fprintf(stderr, "ERROR: counting reference for region exceeding the "
362
+ return;
49
+ "end of the file by one cluster or more: offset 0x%" PRIx64
50
+ " size 0x%" PRIx64 "\n", offset, size);
51
+ res->corruptions++;
52
+ return 0;
363
+ }
53
+ }
364
+
54
+
365
+ *cacert = g_strdup_printf("%s/%s", creds->dir,
55
start = start_of_cluster(s, offset);
366
+ QCRYPTO_TLS_CREDS_X509_CA_CERT);
56
last = start_of_cluster(s, offset + size - 1);
367
+ *cert = g_strdup_printf("%s/%s", creds->dir,
57
for(cluster_offset = start; cluster_offset <= last;
368
+ QCRYPTO_TLS_CREDS_X509_CLIENT_CERT);
58
diff --git a/tests/qemu-iotests/138 b/tests/qemu-iotests/138
369
+ *key = g_strdup_printf("%s/%s", creds->dir,
59
index XXXXXXX..XXXXXXX 100755
370
+ QCRYPTO_TLS_CREDS_X509_CLIENT_KEY);
60
--- a/tests/qemu-iotests/138
371
+}
61
+++ b/tests/qemu-iotests/138
62
@@ -XXX,XX +XXX,XX @@ $QEMU_IO -c 'write 0 512' "$TEST_IMG" | _filter_qemu_io
63
# Put the data cluster at a multiple of 2 TB, resulting in the image apparently
64
# having a multiple of 2^32 clusters
65
# (To be more specific: It is at 32 PB)
66
-poke_file "$TEST_IMG" 2048 "\x80\x80\x00\x00\x00\x00\x00\x00"
67
+poke_file "$TEST_IMG" $((2048 + 8)) "\x00\x80\x00\x00\x00\x00\x00\x00"
68
69
# An offset of 32 PB results in qemu-img check having to allocate an in-memory
70
-# refcount table of 128 TB (16 bit refcounts, 512 byte clusters).
71
-# This should be generally too much for any system and thus fail.
72
-# What this test is checking is that the qcow2 driver actually tries to allocate
73
-# such a large amount of memory (and is consequently aborting) instead of having
74
-# truncated the cluster count somewhere (which would result in much less memory
75
-# being allocated and then a segfault occurring).
76
+# refcount table of 128 TB (16 bit refcounts, 512 byte clusters), if qemu-img
77
+# don't check that referenced data cluster is far beyond the end of file.
78
+# But starting from 4.0, qemu-img does this check, and instead of "Cannot
79
+# allocate memory", we have an error showing that l2 entry is invalid.
80
_check_test_img
81
82
# success, all done
83
diff --git a/tests/qemu-iotests/138.out b/tests/qemu-iotests/138.out
84
index XXXXXXX..XXXXXXX 100644
85
--- a/tests/qemu-iotests/138.out
86
+++ b/tests/qemu-iotests/138.out
87
@@ -XXX,XX +XXX,XX @@ QA output created by 138
88
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=512
89
wrote 512/512 bytes at offset 0
90
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
91
-qemu-img: Check failed: Cannot allocate memory
92
+ERROR: counting reference for region exceeding the end of the file by one cluster or more: offset 0x80000000000000 size 0x200
372
+
93
+
373
+static int vxhs_open(BlockDriverState *bs, QDict *options,
94
+1 errors were found on the image.
374
+ int bdrv_flags, Error **errp)
95
+Data may be corrupted, or further writes to the image may corrupt it.
375
+{
96
*** done
376
+ BDRVVXHSState *s = bs->opaque;
377
+ void *dev_handlep;
378
+ QDict *backing_options = NULL;
379
+ QemuOpts *opts = NULL;
380
+ QemuOpts *tcp_opts = NULL;
381
+ char *of_vsa_addr = NULL;
382
+ Error *local_err = NULL;
383
+ const char *vdisk_id_opt;
384
+ const char *server_host_opt;
385
+ int ret = 0;
386
+ char *cacert = NULL;
387
+ char *client_key = NULL;
388
+ char *client_cert = NULL;
389
+
390
+ ret = vxhs_init_and_ref();
391
+ if (ret < 0) {
392
+ ret = -EINVAL;
393
+ goto out;
394
+ }
395
+
396
+ /* Create opts info from runtime_opts and runtime_tcp_opts list */
397
+ opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
398
+ tcp_opts = qemu_opts_create(&runtime_tcp_opts, NULL, 0, &error_abort);
399
+
400
+ qemu_opts_absorb_qdict(opts, options, &local_err);
401
+ if (local_err) {
402
+ ret = -EINVAL;
403
+ goto out;
404
+ }
405
+
406
+ /* vdisk-id is the disk UUID */
407
+ vdisk_id_opt = qemu_opt_get(opts, VXHS_OPT_VDISK_ID);
408
+ if (!vdisk_id_opt) {
409
+ error_setg(&local_err, QERR_MISSING_PARAMETER, VXHS_OPT_VDISK_ID);
410
+ ret = -EINVAL;
411
+ goto out;
412
+ }
413
+
414
+ /* vdisk-id may contain a leading '/' */
415
+ if (strlen(vdisk_id_opt) > UUID_FMT_LEN + 1) {
416
+ error_setg(&local_err, "vdisk-id cannot be more than %d characters",
417
+ UUID_FMT_LEN);
418
+ ret = -EINVAL;
419
+ goto out;
420
+ }
421
+
422
+ s->vdisk_guid = g_strdup(vdisk_id_opt);
423
+ trace_vxhs_open_vdiskid(vdisk_id_opt);
424
+
425
+ /* get the 'server.' arguments */
426
+ qdict_extract_subqdict(options, &backing_options, VXHS_OPT_SERVER".");
427
+
428
+ qemu_opts_absorb_qdict(tcp_opts, backing_options, &local_err);
429
+ if (local_err != NULL) {
430
+ ret = -EINVAL;
431
+ goto out;
432
+ }
433
+
434
+ server_host_opt = qemu_opt_get(tcp_opts, VXHS_OPT_HOST);
435
+ if (!server_host_opt) {
436
+ error_setg(&local_err, QERR_MISSING_PARAMETER,
437
+ VXHS_OPT_SERVER"."VXHS_OPT_HOST);
438
+ ret = -EINVAL;
439
+ goto out;
440
+ }
441
+
442
+ if (strlen(server_host_opt) > MAXHOSTNAMELEN) {
443
+ error_setg(&local_err, "server.host cannot be more than %d characters",
444
+ MAXHOSTNAMELEN);
445
+ ret = -EINVAL;
446
+ goto out;
447
+ }
448
+
449
+ /* check if we got tls-creds via the --object argument */
450
+ s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds"));
451
+ if (s->tlscredsid) {
452
+ vxhs_get_tls_creds(s->tlscredsid, &cacert, &client_key,
453
+ &client_cert, &local_err);
454
+ if (local_err != NULL) {
455
+ ret = -EINVAL;
456
+ goto out;
457
+ }
458
+ trace_vxhs_get_creds(cacert, client_key, client_cert);
459
+ }
460
+
461
+ s->vdisk_hostinfo.host = g_strdup(server_host_opt);
462
+ s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,
463
+ VXHS_OPT_PORT),
464
+ NULL, 0);
465
+
466
+ trace_vxhs_open_hostinfo(s->vdisk_hostinfo.host,
467
+ s->vdisk_hostinfo.port);
468
+
469
+ of_vsa_addr = g_strdup_printf("of://%s:%d",
470
+ s->vdisk_hostinfo.host,
471
+ s->vdisk_hostinfo.port);
472
+
473
+ /*
474
+ * Open qnio channel to storage agent if not opened before
475
+ */
476
+ dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0,
477
+ cacert, client_key, client_cert);
478
+ if (dev_handlep == NULL) {
479
+ trace_vxhs_open_iio_open(of_vsa_addr);
480
+ ret = -ENODEV;
481
+ goto out;
482
+ }
483
+ s->vdisk_hostinfo.dev_handle = dev_handlep;
484
+
485
+out:
486
+ g_free(of_vsa_addr);
487
+ QDECREF(backing_options);
488
+ qemu_opts_del(tcp_opts);
489
+ qemu_opts_del(opts);
490
+ g_free(cacert);
491
+ g_free(client_key);
492
+ g_free(client_cert);
493
+
494
+ if (ret < 0) {
495
+ vxhs_unref();
496
+ error_propagate(errp, local_err);
497
+ g_free(s->vdisk_hostinfo.host);
498
+ g_free(s->vdisk_guid);
499
+ g_free(s->tlscredsid);
500
+ s->vdisk_guid = NULL;
501
+ }
502
+
503
+ return ret;
504
+}
505
+
506
+static const AIOCBInfo vxhs_aiocb_info = {
507
+ .aiocb_size = sizeof(VXHSAIOCB)
508
+};
509
+
510
+/*
511
+ * This allocates QEMU-VXHS callback for each IO
512
+ * and is passed to QNIO. When QNIO completes the work,
513
+ * it will be passed back through the callback.
514
+ */
515
+static BlockAIOCB *vxhs_aio_rw(BlockDriverState *bs, int64_t sector_num,
516
+ QEMUIOVector *qiov, int nb_sectors,
517
+ BlockCompletionFunc *cb, void *opaque,
518
+ VDISKAIOCmd iodir)
519
+{
520
+ VXHSAIOCB *acb = NULL;
521
+ BDRVVXHSState *s = bs->opaque;
522
+ size_t size;
523
+ uint64_t offset;
524
+ int iio_flags = 0;
525
+ int ret = 0;
526
+ void *dev_handle = s->vdisk_hostinfo.dev_handle;
527
+
528
+ offset = sector_num * BDRV_SECTOR_SIZE;
529
+ size = nb_sectors * BDRV_SECTOR_SIZE;
530
+ acb = qemu_aio_get(&vxhs_aiocb_info, bs, cb, opaque);
531
+
532
+ /*
533
+ * Initialize VXHSAIOCB.
534
+ */
535
+ acb->err = 0;
536
+
537
+ iio_flags = IIO_FLAG_ASYNC;
538
+
539
+ switch (iodir) {
540
+ case VDISK_AIO_WRITE:
541
+ ret = iio_writev(dev_handle, acb, qiov->iov, qiov->niov,
542
+ offset, (uint64_t)size, iio_flags);
543
+ break;
544
+ case VDISK_AIO_READ:
545
+ ret = iio_readv(dev_handle, acb, qiov->iov, qiov->niov,
546
+ offset, (uint64_t)size, iio_flags);
547
+ break;
548
+ default:
549
+ trace_vxhs_aio_rw_invalid(iodir);
550
+ goto errout;
551
+ }
552
+
553
+ if (ret != 0) {
554
+ trace_vxhs_aio_rw_ioerr(s->vdisk_guid, iodir, size, offset,
555
+ acb, ret, errno);
556
+ goto errout;
557
+ }
558
+ return &acb->common;
559
+
560
+errout:
561
+ qemu_aio_unref(acb);
562
+ return NULL;
563
+}
564
+
565
+static BlockAIOCB *vxhs_aio_readv(BlockDriverState *bs,
566
+ int64_t sector_num, QEMUIOVector *qiov,
567
+ int nb_sectors,
568
+ BlockCompletionFunc *cb, void *opaque)
569
+{
570
+ return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors, cb,
571
+ opaque, VDISK_AIO_READ);
572
+}
573
+
574
+static BlockAIOCB *vxhs_aio_writev(BlockDriverState *bs,
575
+ int64_t sector_num, QEMUIOVector *qiov,
576
+ int nb_sectors,
577
+ BlockCompletionFunc *cb, void *opaque)
578
+{
579
+ return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors,
580
+ cb, opaque, VDISK_AIO_WRITE);
581
+}
582
+
583
+static void vxhs_close(BlockDriverState *bs)
584
+{
585
+ BDRVVXHSState *s = bs->opaque;
586
+
587
+ trace_vxhs_close(s->vdisk_guid);
588
+
589
+ g_free(s->vdisk_guid);
590
+ s->vdisk_guid = NULL;
591
+
592
+ /*
593
+ * Close vDisk device
594
+ */
595
+ if (s->vdisk_hostinfo.dev_handle) {
596
+ iio_close(s->vdisk_hostinfo.dev_handle);
597
+ s->vdisk_hostinfo.dev_handle = NULL;
598
+ }
599
+
600
+ vxhs_unref();
601
+
602
+ /*
603
+ * Free the dynamically allocated host string etc
604
+ */
605
+ g_free(s->vdisk_hostinfo.host);
606
+ g_free(s->tlscredsid);
607
+ s->tlscredsid = NULL;
608
+ s->vdisk_hostinfo.host = NULL;
609
+ s->vdisk_hostinfo.port = 0;
610
+}
611
+
612
+static int64_t vxhs_get_vdisk_stat(BDRVVXHSState *s)
613
+{
614
+ int64_t vdisk_size = -1;
615
+ int ret = 0;
616
+ void *dev_handle = s->vdisk_hostinfo.dev_handle;
617
+
618
+ ret = iio_ioctl(dev_handle, IOR_VDISK_STAT, &vdisk_size, 0);
619
+ if (ret < 0) {
620
+ trace_vxhs_get_vdisk_stat_err(s->vdisk_guid, ret, errno);
621
+ return -EIO;
622
+ }
623
+
624
+ trace_vxhs_get_vdisk_stat(s->vdisk_guid, vdisk_size);
625
+ return vdisk_size;
626
+}
627
+
628
+/*
629
+ * Returns the size of vDisk in bytes. This is required
630
+ * by QEMU block upper block layer so that it is visible
631
+ * to guest.
632
+ */
633
+static int64_t vxhs_getlength(BlockDriverState *bs)
634
+{
635
+ BDRVVXHSState *s = bs->opaque;
636
+ int64_t vdisk_size;
637
+
638
+ vdisk_size = vxhs_get_vdisk_stat(s);
639
+ if (vdisk_size < 0) {
640
+ return -EIO;
641
+ }
642
+
643
+ return vdisk_size;
644
+}
645
+
646
+static BlockDriver bdrv_vxhs = {
647
+ .format_name = "vxhs",
648
+ .protocol_name = "vxhs",
649
+ .instance_size = sizeof(BDRVVXHSState),
650
+ .bdrv_file_open = vxhs_open,
651
+ .bdrv_parse_filename = vxhs_parse_filename,
652
+ .bdrv_close = vxhs_close,
653
+ .bdrv_getlength = vxhs_getlength,
654
+ .bdrv_aio_readv = vxhs_aio_readv,
655
+ .bdrv_aio_writev = vxhs_aio_writev,
656
+};
657
+
658
+static void bdrv_vxhs_init(void)
659
+{
660
+ bdrv_register(&bdrv_vxhs);
661
+}
662
+
663
+block_init(bdrv_vxhs_init);
664
diff --git a/configure b/configure
665
index XXXXXXX..XXXXXXX 100755
666
--- a/configure
667
+++ b/configure
668
@@ -XXX,XX +XXX,XX @@ numa=""
669
tcmalloc="no"
670
jemalloc="no"
671
replication="yes"
672
+vxhs=""
673
674
supported_cpu="no"
675
supported_os="no"
676
@@ -XXX,XX +XXX,XX @@ for opt do
677
;;
678
--enable-replication) replication="yes"
679
;;
680
+ --disable-vxhs) vxhs="no"
681
+ ;;
682
+ --enable-vxhs) vxhs="yes"
683
+ ;;
684
*)
685
echo "ERROR: unknown option $opt"
686
echo "Try '$0 --help' for more information"
687
@@ -XXX,XX +XXX,XX @@ disabled with --disable-FEATURE, default is enabled if available:
688
xfsctl xfsctl support
689
qom-cast-debug cast debugging support
690
tools build qemu-io, qemu-nbd and qemu-image tools
691
+ vxhs Veritas HyperScale vDisk backend support
692
693
NOTE: The object files are built at the place where configure is launched
694
EOF
695
@@ -XXX,XX +XXX,XX @@ if compile_prog "" "" ; then
696
fi
697
698
##########################################
699
+# Veritas HyperScale block driver VxHS
700
+# Check if libvxhs is installed
701
+
702
+if test "$vxhs" != "no" ; then
703
+ cat > $TMPC <<EOF
704
+#include <stdint.h>
705
+#include <qnio/qnio_api.h>
706
+
707
+void *vxhs_callback;
708
+
709
+int main(void) {
710
+ iio_init(QNIO_VERSION, vxhs_callback);
711
+ return 0;
712
+}
713
+EOF
714
+ vxhs_libs="-lvxhs -lssl"
715
+ if compile_prog "" "$vxhs_libs" ; then
716
+ vxhs=yes
717
+ else
718
+ if test "$vxhs" = "yes" ; then
719
+ feature_not_found "vxhs block device" "Install libvxhs See github"
720
+ fi
721
+ vxhs=no
722
+ fi
723
+fi
724
+
725
+##########################################
726
# End of CC checks
727
# After here, no more $cc or $ld runs
728
729
@@ -XXX,XX +XXX,XX @@ echo "tcmalloc support $tcmalloc"
730
echo "jemalloc support $jemalloc"
731
echo "avx2 optimization $avx2_opt"
732
echo "replication support $replication"
733
+echo "VxHS block device $vxhs"
734
735
if test "$sdl_too_old" = "yes"; then
736
echo "-> Your SDL version is too old - please upgrade to have SDL support"
737
@@ -XXX,XX +XXX,XX @@ if test "$pthread_setname_np" = "yes" ; then
738
echo "CONFIG_PTHREAD_SETNAME_NP=y" >> $config_host_mak
739
fi
740
741
+if test "$vxhs" = "yes" ; then
742
+ echo "CONFIG_VXHS=y" >> $config_host_mak
743
+ echo "VXHS_LIBS=$vxhs_libs" >> $config_host_mak
744
+fi
745
+
746
if test "$tcg_interpreter" = "yes"; then
747
QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
748
elif test "$ARCH" = "sparc64" ; then
749
diff --git a/qapi/block-core.json b/qapi/block-core.json
750
index XXXXXXX..XXXXXXX 100644
751
--- a/qapi/block-core.json
752
+++ b/qapi/block-core.json
753
@@ -XXX,XX +XXX,XX @@
754
#
755
# Drivers that are supported in block device operations.
756
#
757
+# @vxhs: Since 2.10
758
+#
759
# Since: 2.9
760
##
761
{ 'enum': 'BlockdevDriver',
762
@@ -XXX,XX +XXX,XX @@
763
'host_device', 'http', 'https', 'iscsi', 'luks', 'nbd', 'nfs',
764
'null-aio', 'null-co', 'parallels', 'qcow', 'qcow2', 'qed',
765
'quorum', 'raw', 'rbd', 'replication', 'sheepdog', 'ssh',
766
- 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
767
+ 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxhs' ] }
768
769
##
770
# @BlockdevOptionsFile:
771
@@ -XXX,XX +XXX,XX @@
772
'data': { '*offset': 'int', '*size': 'int' } }
773
774
##
775
+# @BlockdevOptionsVxHS:
776
+#
777
+# Driver specific block device options for VxHS
778
+#
779
+# @vdisk-id: UUID of VxHS volume
780
+# @server: vxhs server IP, port
781
+# @tls-creds: TLS credentials ID
782
+#
783
+# Since: 2.10
784
+##
785
+{ 'struct': 'BlockdevOptionsVxHS',
786
+ 'data': { 'vdisk-id': 'str',
787
+ 'server': 'InetSocketAddressBase',
788
+ '*tls-creds': 'str' } }
789
+
790
+##
791
# @BlockdevOptions:
792
#
793
# Options for creating a block device. Many options are available for all
794
@@ -XXX,XX +XXX,XX @@
795
'vhdx': 'BlockdevOptionsGenericFormat',
796
'vmdk': 'BlockdevOptionsGenericCOWFormat',
797
'vpc': 'BlockdevOptionsGenericFormat',
798
- 'vvfat': 'BlockdevOptionsVVFAT'
799
+ 'vvfat': 'BlockdevOptionsVVFAT',
800
+ 'vxhs': 'BlockdevOptionsVxHS'
801
} }
802
803
##
804
--
97
--
805
2.9.3
98
2.20.1
806
99
807
100
diff view generated by jsdifflib
1
For the tests that use the common.qemu functions for running a QEMU
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
process, _cleanup_qemu must be called in the exit function.
3
2
4
If it is not, if the qemu process aborts, then not all of the droppings
3
Reduce number of structures ignored in overlap check: when checking
5
are cleaned up (e.g. pidfile, fifos).
4
active table ignore active tables, when checking inactive table ignore
5
inactive ones.
6
6
7
This updates those tests that did not have a cleanup in qemu-iotests.
7
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
8
Reviewed-by: Max Reitz <mreitz@redhat.com>
9
Message-id: 20190227131433.197063-4-vsementsov@virtuozzo.com
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
11
---
12
block/qcow2-refcount.c | 16 +++++++++-------
13
1 file changed, 9 insertions(+), 7 deletions(-)
8
14
9
(I swapped spaces for tabs in test 102 as well)
15
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
10
16
index XXXXXXX..XXXXXXX 100644
11
Reported-by: Eric Blake <eblake@redhat.com>
17
--- a/block/qcow2-refcount.c
12
Reviewed-by: Eric Blake <eblake@redhat.com>
18
+++ b/block/qcow2-refcount.c
13
Signed-off-by: Jeff Cody <jcody@redhat.com>
19
@@ -XXX,XX +XXX,XX @@ enum {
14
Message-id: d59c2f6ad6c1da8b9b3c7f357c94a7122ccfc55a.1492544096.git.jcody@redhat.com
20
static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
15
---
21
void **refcount_table,
16
tests/qemu-iotests/028 | 1 +
22
int64_t *refcount_table_size, int64_t l2_offset,
17
tests/qemu-iotests/094 | 11 ++++++++---
23
- int flags, BdrvCheckMode fix)
18
tests/qemu-iotests/102 | 5 +++--
24
+ int flags, BdrvCheckMode fix, bool active)
19
tests/qemu-iotests/109 | 1 +
20
tests/qemu-iotests/117 | 1 +
21
tests/qemu-iotests/130 | 1 +
22
tests/qemu-iotests/140 | 1 +
23
tests/qemu-iotests/141 | 1 +
24
tests/qemu-iotests/143 | 1 +
25
tests/qemu-iotests/156 | 1 +
26
10 files changed, 19 insertions(+), 5 deletions(-)
27
28
diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028
29
index XXXXXXX..XXXXXXX 100755
30
--- a/tests/qemu-iotests/028
31
+++ b/tests/qemu-iotests/028
32
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
33
34
_cleanup()
35
{
25
{
36
+ _cleanup_qemu
26
BDRVQcow2State *s = bs->opaque;
37
rm -f "${TEST_IMG}.copy"
27
uint64_t *l2_table, l2_entry;
38
_cleanup_test_img
28
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
39
}
29
if (fix & BDRV_FIX_ERRORS) {
40
diff --git a/tests/qemu-iotests/094 b/tests/qemu-iotests/094
30
uint64_t l2e_offset =
41
index XXXXXXX..XXXXXXX 100755
31
l2_offset + (uint64_t)i * sizeof(uint64_t);
42
--- a/tests/qemu-iotests/094
32
+ int ign = active ? QCOW2_OL_ACTIVE_L2 :
43
+++ b/tests/qemu-iotests/094
33
+ QCOW2_OL_INACTIVE_L2;
44
@@ -XXX,XX +XXX,XX @@ echo "QA output created by $seq"
34
45
here="$PWD"
35
l2_entry = QCOW_OFLAG_ZERO;
46
status=1    # failure is the default!
36
l2_table[i] = cpu_to_be64(l2_entry);
47
37
- ret = qcow2_pre_write_overlap_check(bs,
48
-trap "exit \$status" 0 1 2 3 15
38
- QCOW2_OL_ACTIVE_L2 | QCOW2_OL_INACTIVE_L2,
49
+_cleanup()
39
+ ret = qcow2_pre_write_overlap_check(bs, ign,
50
+{
40
l2e_offset, sizeof(uint64_t), false);
51
+ _cleanup_qemu
41
if (ret < 0) {
52
+ _cleanup_test_img
42
fprintf(stderr, "ERROR: Overlap check failed\n");
53
+ rm -f "$TEST_DIR/source.$IMGFMT"
43
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l1(BlockDriverState *bs,
54
+}
44
void **refcount_table,
55
+
45
int64_t *refcount_table_size,
56
+trap "_cleanup; exit \$status" 0 1 2 3 15
46
int64_t l1_table_offset, int l1_size,
57
47
- int flags, BdrvCheckMode fix)
58
# get standard environment, filters and checks
48
+ int flags, BdrvCheckMode fix, bool active)
59
. ./common.rc
60
@@ -XXX,XX +XXX,XX @@ _send_qemu_cmd $QEMU_HANDLE \
61
62
wait=1 _cleanup_qemu
63
64
-_cleanup_test_img
65
-rm -f "$TEST_DIR/source.$IMGFMT"
66
67
# success, all done
68
echo '*** done'
69
diff --git a/tests/qemu-iotests/102 b/tests/qemu-iotests/102
70
index XXXXXXX..XXXXXXX 100755
71
--- a/tests/qemu-iotests/102
72
+++ b/tests/qemu-iotests/102
73
@@ -XXX,XX +XXX,XX @@ seq=$(basename $0)
74
echo "QA output created by $seq"
75
76
here=$PWD
77
-status=1    # failure is the default!
78
+status=1 # failure is the default!
79
80
_cleanup()
81
{
49
{
82
-    _cleanup_test_img
50
BDRVQcow2State *s = bs->opaque;
83
+ _cleanup_qemu
51
uint64_t *l1_table = NULL, l2_offset, l1_size2;
84
+ _cleanup_test_img
52
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l1(BlockDriverState *bs,
85
}
53
/* Process and check L2 entries */
86
trap "_cleanup; exit \$status" 0 1 2 3 15
54
ret = check_refcounts_l2(bs, res, refcount_table,
87
55
refcount_table_size, l2_offset, flags,
88
diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
56
- fix);
89
index XXXXXXX..XXXXXXX 100755
57
+ fix, active);
90
--- a/tests/qemu-iotests/109
58
if (ret < 0) {
91
+++ b/tests/qemu-iotests/109
59
goto fail;
92
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
60
}
93
61
@@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
94
_cleanup()
62
/* current L1 table */
95
{
63
ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
96
+ _cleanup_qemu
64
s->l1_table_offset, s->l1_size, CHECK_FRAG_INFO,
97
rm -f $TEST_IMG.src
65
- fix);
98
    _cleanup_test_img
66
+ fix, true);
99
}
67
if (ret < 0) {
100
diff --git a/tests/qemu-iotests/117 b/tests/qemu-iotests/117
68
return ret;
101
index XXXXXXX..XXXXXXX 100755
69
}
102
--- a/tests/qemu-iotests/117
70
@@ -XXX,XX +XXX,XX @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
103
+++ b/tests/qemu-iotests/117
71
continue;
104
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
72
}
105
73
ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
106
_cleanup()
74
- sn->l1_table_offset, sn->l1_size, 0, fix);
107
{
75
+ sn->l1_table_offset, sn->l1_size, 0, fix,
108
+ _cleanup_qemu
76
+ false);
109
    _cleanup_test_img
77
if (ret < 0) {
110
}
78
return ret;
111
trap "_cleanup; exit \$status" 0 1 2 3 15
79
}
112
diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130
113
index XXXXXXX..XXXXXXX 100755
114
--- a/tests/qemu-iotests/130
115
+++ b/tests/qemu-iotests/130
116
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
117
118
_cleanup()
119
{
120
+ _cleanup_qemu
121
_cleanup_test_img
122
}
123
trap "_cleanup; exit \$status" 0 1 2 3 15
124
diff --git a/tests/qemu-iotests/140 b/tests/qemu-iotests/140
125
index XXXXXXX..XXXXXXX 100755
126
--- a/tests/qemu-iotests/140
127
+++ b/tests/qemu-iotests/140
128
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
129
130
_cleanup()
131
{
132
+ _cleanup_qemu
133
_cleanup_test_img
134
rm -f "$TEST_DIR/nbd"
135
}
136
diff --git a/tests/qemu-iotests/141 b/tests/qemu-iotests/141
137
index XXXXXXX..XXXXXXX 100755
138
--- a/tests/qemu-iotests/141
139
+++ b/tests/qemu-iotests/141
140
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
141
142
_cleanup()
143
{
144
+ _cleanup_qemu
145
_cleanup_test_img
146
rm -f "$TEST_DIR/{b,m,o}.$IMGFMT"
147
}
148
diff --git a/tests/qemu-iotests/143 b/tests/qemu-iotests/143
149
index XXXXXXX..XXXXXXX 100755
150
--- a/tests/qemu-iotests/143
151
+++ b/tests/qemu-iotests/143
152
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
153
154
_cleanup()
155
{
156
+ _cleanup_qemu
157
rm -f "$TEST_DIR/nbd"
158
}
159
trap "_cleanup; exit \$status" 0 1 2 3 15
160
diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
161
index XXXXXXX..XXXXXXX 100755
162
--- a/tests/qemu-iotests/156
163
+++ b/tests/qemu-iotests/156
164
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
165
166
_cleanup()
167
{
168
+ _cleanup_qemu
169
rm -f "$TEST_IMG{,.target}{,.backing,.overlay}"
170
}
171
trap "_cleanup; exit \$status" 0 1 2 3 15
172
--
80
--
173
2.9.3
81
2.20.1
174
82
175
83
diff view generated by jsdifflib
1
This adds support for reopen in rbd, for changing between r/w and r/o.
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
2
3
Note, that this is only a flag change, but we will block a change from
3
Do not count a cluster which is fixed to be ZERO as allocated.
4
r/o to r/w if we are using an RBD internal snapshot.
5
4
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
7
Signed-off-by: Jeff Cody <jcody@redhat.com>
6
Reviewed-by: Max Reitz <mreitz@redhat.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
7
Message-id: 20190227131433.197063-5-vsementsov@virtuozzo.com
9
Message-id: d4e87539167ec6527d44c97b164eabcccf96e4f3.1491597120.git.jcody@redhat.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
9
---
11
block/rbd.c | 21 +++++++++++++++++++++
10
block/qcow2-refcount.c | 18 +++++++++---------
12
1 file changed, 21 insertions(+)
11
1 file changed, 9 insertions(+), 9 deletions(-)
13
12
14
diff --git a/block/rbd.c b/block/rbd.c
13
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/block/rbd.c
15
--- a/block/qcow2-refcount.c
17
+++ b/block/rbd.c
16
+++ b/block/qcow2-refcount.c
18
@@ -XXX,XX +XXX,XX @@ failed_opts:
17
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
19
return r;
18
{
20
}
19
uint64_t offset = l2_entry & L2E_OFFSET_MASK;
21
20
21
- if (flags & CHECK_FRAG_INFO) {
22
- res->bfi.allocated_clusters++;
23
- if (next_contiguous_offset &&
24
- offset != next_contiguous_offset) {
25
- res->bfi.fragmented_clusters++;
26
- }
27
- next_contiguous_offset = offset + s->cluster_size;
28
- }
29
-
30
/* Correct offsets are cluster aligned */
31
if (offset_into_cluster(s, offset)) {
32
if (qcow2_get_cluster_type(bs, l2_entry) ==
33
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
34
}
35
}
36
37
+ if (flags & CHECK_FRAG_INFO) {
38
+ res->bfi.allocated_clusters++;
39
+ if (next_contiguous_offset &&
40
+ offset != next_contiguous_offset) {
41
+ res->bfi.fragmented_clusters++;
42
+ }
43
+ next_contiguous_offset = offset + s->cluster_size;
44
+ }
22
+
45
+
23
+/* Since RBD is currently always opened R/W via the API,
46
/* Mark cluster as used */
24
+ * we just need to check if we are using a snapshot or not, in
47
if (!has_data_file(bs)) {
25
+ * order to determine if we will allow it to be R/W */
48
ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table,
26
+static int qemu_rbd_reopen_prepare(BDRVReopenState *state,
27
+ BlockReopenQueue *queue, Error **errp)
28
+{
29
+ BDRVRBDState *s = state->bs->opaque;
30
+ int ret = 0;
31
+
32
+ if (s->snap && state->flags & BDRV_O_RDWR) {
33
+ error_setg(errp,
34
+ "Cannot change node '%s' to r/w when using RBD snapshot",
35
+ bdrv_get_device_or_node_name(state->bs));
36
+ ret = -EINVAL;
37
+ }
38
+
39
+ return ret;
40
+}
41
+
42
static void qemu_rbd_close(BlockDriverState *bs)
43
{
44
BDRVRBDState *s = bs->opaque;
45
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_rbd = {
46
.bdrv_parse_filename = qemu_rbd_parse_filename,
47
.bdrv_file_open = qemu_rbd_open,
48
.bdrv_close = qemu_rbd_close,
49
+ .bdrv_reopen_prepare = qemu_rbd_reopen_prepare,
50
.bdrv_create = qemu_rbd_create,
51
.bdrv_has_zero_init = bdrv_has_zero_init_1,
52
.bdrv_get_info = qemu_rbd_getinfo,
53
--
49
--
54
2.9.3
50
2.20.1
55
51
56
52
diff view generated by jsdifflib
1
Signed-off-by: Jeff Cody <jcody@redhat.com>
1
From: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
2
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
2
3
Reviewed-by: John Snow <jsnow@redhat.com>
3
No reasons for not reporting found corruptions as corruptions in case
4
Message-id: 00aed7ffdd7be4b9ed9ce1007d50028a72b34ebe.1491597120.git.jcody@redhat.com
4
of some internal errors, especially in case of just failed to fix l2
5
entry (and in this case, missed corruptions may influence comparing
6
logic, when we calculate difference between corruptions fields of two
7
results)
8
9
Signed-off-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
10
Message-id: 20190227131433.197063-6-vsementsov@virtuozzo.com
11
Reviewed-by: Max Reitz <mreitz@redhat.com>
12
Signed-off-by: Max Reitz <mreitz@redhat.com>
5
---
13
---
6
block.c | 14 ++++++++------
14
block/qcow2-refcount.c | 19 +++++++++----------
7
1 file changed, 8 insertions(+), 6 deletions(-)
15
1 file changed, 9 insertions(+), 10 deletions(-)
8
16
9
diff --git a/block.c b/block.c
17
diff --git a/block/qcow2-refcount.c b/block/qcow2-refcount.c
10
index XXXXXXX..XXXXXXX 100644
18
index XXXXXXX..XXXXXXX 100644
11
--- a/block.c
19
--- a/block/qcow2-refcount.c
12
+++ b/block.c
20
+++ b/block/qcow2-refcount.c
13
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
21
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
14
BlockDriver *drv;
22
15
QemuOpts *opts;
23
/* Correct offsets are cluster aligned */
16
const char *value;
24
if (offset_into_cluster(s, offset)) {
17
+ bool read_only;
25
+ res->corruptions++;
18
26
+
19
assert(reopen_state != NULL);
27
if (qcow2_get_cluster_type(bs, l2_entry) ==
20
assert(reopen_state->bs->drv != NULL);
28
QCOW2_CLUSTER_ZERO_ALLOC)
21
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
29
{
22
qdict_put(reopen_state->options, "driver", qstring_from_str(value));
30
@@ -XXX,XX +XXX,XX @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
31
/* Do not abort, continue checking the rest of this
32
* L2 table's entries */
33
} else {
34
+ res->corruptions--;
35
res->corruptions_fixed++;
36
/* Skip marking the cluster as used
37
* (it is unused now) */
38
continue;
39
}
40
- } else {
41
- res->corruptions++;
42
}
43
} else {
44
fprintf(stderr, "ERROR offset=%" PRIx64 ": Data cluster is "
45
"not properly aligned; L2 entry corrupted.\n", offset);
46
- res->corruptions++;
47
}
48
}
49
50
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
51
continue;
52
}
53
if ((refcount == 1) != ((l1_entry & QCOW_OFLAG_COPIED) != 0)) {
54
+ res->corruptions++;
55
fprintf(stderr, "%s OFLAG_COPIED L2 cluster: l1_index=%d "
56
"l1_entry=%" PRIx64 " refcount=%" PRIu64 "\n",
57
repair ? "Repairing" : "ERROR", i, l1_entry, refcount);
58
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
59
res->check_errors++;
60
goto fail;
61
}
62
+ res->corruptions--;
63
res->corruptions_fixed++;
64
- } else {
65
- res->corruptions++;
66
}
67
}
68
69
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
70
}
71
}
72
if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {
73
+ res->corruptions++;
74
fprintf(stderr, "%s OFLAG_COPIED data cluster: "
75
"l2_entry=%" PRIx64 " refcount=%" PRIu64 "\n",
76
repair ? "Repairing" : "ERROR", l2_entry, refcount);
77
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
78
? l2_entry | QCOW_OFLAG_COPIED
79
: l2_entry & ~QCOW_OFLAG_COPIED);
80
l2_dirty++;
81
- } else {
82
- res->corruptions++;
83
}
84
}
85
}
86
@@ -XXX,XX +XXX,XX @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
87
res->check_errors++;
88
goto fail;
89
}
90
+ res->corruptions -= l2_dirty;
91
res->corruptions_fixed += l2_dirty;
92
}
23
}
93
}
24
94
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
25
- /* if we are to stay read-only, do not allow permission change
95
}
26
- * to r/w */
96
27
- if (!(reopen_state->bs->open_flags & BDRV_O_ALLOW_RDWR) &&
97
if (cluster >= *nb_clusters) {
28
- reopen_state->flags & BDRV_O_RDWR) {
98
+ res->corruptions++;
29
- error_setg(errp, "Node '%s' is read only",
99
fprintf(stderr, "%s refcount block %" PRId64 " is outside image\n",
30
- bdrv_get_device_or_node_name(reopen_state->bs));
100
fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR", i);
31
+ /* If we are to stay read-only, do not allow permission change
101
32
+ * to r/w. Attempting to set to r/w may fail if either BDRV_O_ALLOW_RDWR is
102
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
33
+ * not set, or if the BDS still has copy_on_read enabled */
103
goto resize_fail;
34
+ read_only = !(reopen_state->flags & BDRV_O_RDWR);
104
}
35
+ ret = bdrv_can_set_read_only(reopen_state->bs, read_only, &local_err);
105
36
+ if (local_err) {
106
+ res->corruptions--;
37
+ error_propagate(errp, local_err);
107
res->corruptions_fixed++;
38
goto error;
108
ret = qcow2_inc_refcounts_imrt(bs, res,
39
}
109
refcount_table, nb_clusters,
40
110
@@ -XXX,XX +XXX,XX @@ static int check_refblocks(BlockDriverState *bs, BdrvCheckResult *res,
111
continue;
112
113
resize_fail:
114
- res->corruptions++;
115
*rebuild = true;
116
fprintf(stderr, "ERROR could not resize image: %s\n",
117
strerror(-ret));
118
- } else {
119
- res->corruptions++;
120
}
121
continue;
122
}
41
--
123
--
42
2.9.3
124
2.20.1
43
125
44
126
diff view generated by jsdifflib
1
Move bdrv_is_read_only() up with its friends.
1
From: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
2
2
3
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
3
Bitmap data may take a lot of disk space, so it's better to discard it
4
Reviewed-by: John Snow <jsnow@redhat.com>
4
always.
5
Signed-off-by: Jeff Cody <jcody@redhat.com>
5
6
Message-id: 73b2399459760c32506f9407efb9dddb3a2789de.1491597120.git.jcody@redhat.com
6
Signed-off-by: Andrey Shinkevich <andrey.shinkevich@virtuozzo.com>
7
Message-id: 1551346019-293202-1-git-send-email-andrey.shinkevich@virtuozzo.com
8
Reviewed-by: Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>
9
[mreitz: Use the commit message proposed by Vladimir]
10
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
---
11
---
8
block.c | 10 +++++-----
12
block/qcow2-bitmap.c | 2 +-
9
1 file changed, 5 insertions(+), 5 deletions(-)
13
1 file changed, 1 insertion(+), 1 deletion(-)
10
14
11
diff --git a/block.c b/block.c
15
diff --git a/block/qcow2-bitmap.c b/block/qcow2-bitmap.c
12
index XXXXXXX..XXXXXXX 100644
16
index XXXXXXX..XXXXXXX 100644
13
--- a/block.c
17
--- a/block/qcow2-bitmap.c
14
+++ b/block.c
18
+++ b/block/qcow2-bitmap.c
15
@@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size,
19
@@ -XXX,XX +XXX,XX @@ static void clear_bitmap_table(BlockDriverState *bs, uint64_t *bitmap_table,
20
continue;
21
}
22
23
- qcow2_free_clusters(bs, addr, s->cluster_size, QCOW2_DISCARD_OTHER);
24
+ qcow2_free_clusters(bs, addr, s->cluster_size, QCOW2_DISCARD_ALWAYS);
25
bitmap_table[i] = 0;
16
}
26
}
17
}
27
}
18
19
+bool bdrv_is_read_only(BlockDriverState *bs)
20
+{
21
+ return bs->read_only;
22
+}
23
+
24
int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
25
{
26
/* Do not set read_only if copy_on_read is enabled */
27
@@ -XXX,XX +XXX,XX @@ void bdrv_get_geometry(BlockDriverState *bs, uint64_t *nb_sectors_ptr)
28
*nb_sectors_ptr = nb_sectors < 0 ? 0 : nb_sectors;
29
}
30
31
-bool bdrv_is_read_only(BlockDriverState *bs)
32
-{
33
- return bs->read_only;
34
-}
35
-
36
bool bdrv_is_sg(BlockDriverState *bs)
37
{
38
return bs->sg;
39
--
28
--
40
2.9.3
29
2.20.1
41
30
42
31
diff view generated by jsdifflib
1
From: Ashish Mittal <ashmit602@gmail.com>
1
This requires some changes to keep iotests 104 and 207 working.
2
2
3
These changes use a vxhs test server that is a part of the following
3
qemu-img info in 104 will now return a filename including the user name
4
repository:
4
and the port, which need to be filtered by adjusting REMOTE_TEST_DIR in
5
https://github.com/VeritasHyperScale/libqnio.git
5
common.rc. This additional information has to be marked optional,
6
6
however (which is simple as REMOTE_TEST_DIR is a regex), because
7
Signed-off-by: Ashish Mittal <Ashish.Mittal@veritas.com>
7
otherwise 197 and 215 would fail: They use it (indirectly) to filter
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
qemu-img create output which contains a backing filename they have
9
Reviewed-by: Jeff Cody <jcody@redhat.com>
9
passed to it -- which probably does not contain a user name or port
10
Signed-off-by: Jeff Cody <jcody@redhat.com>
10
number.
11
Message-id: 1491277689-24949-3-git-send-email-Ashish.Mittal@veritas.com
11
12
The problem in 207 is a nice one to have: qemu-img info used to return
13
json:{} filenames, but with this patch it returns nice plain ones. We
14
now need to adjust the filtering to hide the user name (and port number
15
while we are at it). The simplest way to do this is to include both in
16
iotests.remote_filename() so that bdrv_refresh_filename() will not
17
change it, and then iotests.img_info_log() will filter it correctly
18
automatically.
19
20
Signed-off-by: Max Reitz <mreitz@redhat.com>
21
Tested-by: Richard W.M. Jones <rjones@redhat.com>
22
Message-id: 20190225190828.17726-2-mreitz@redhat.com
23
Signed-off-by: Max Reitz <mreitz@redhat.com>
12
---
24
---
13
tests/qemu-iotests/common | 6 ++++++
25
block/ssh.c | 52 +++++++++++++++++++++++++++++++----
14
tests/qemu-iotests/common.config | 13 +++++++++++++
26
tests/qemu-iotests/207 | 10 +++----
15
tests/qemu-iotests/common.filter | 1 +
27
tests/qemu-iotests/207.out | 10 +++----
16
tests/qemu-iotests/common.rc | 19 +++++++++++++++++++
28
tests/qemu-iotests/common.rc | 2 +-
17
4 files changed, 39 insertions(+)
29
tests/qemu-iotests/iotests.py | 2 +-
18
30
5 files changed, 59 insertions(+), 17 deletions(-)
19
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
31
20
index XXXXXXX..XXXXXXX 100644
32
diff --git a/block/ssh.c b/block/ssh.c
21
--- a/tests/qemu-iotests/common
33
index XXXXXXX..XXXXXXX 100644
22
+++ b/tests/qemu-iotests/common
34
--- a/block/ssh.c
23
@@ -XXX,XX +XXX,XX @@ check options
35
+++ b/block/ssh.c
24
-ssh test ssh
36
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVSSHState {
25
-nfs test nfs
37
26
-luks test luks
38
/* Used to warn if 'flush' is not supported. */
27
+ -vxhs test vxhs
39
bool unsafe_flush_warning;
28
-xdiff graphical mode diff
40
+
29
-nocache use O_DIRECT on backing file
41
+ /*
30
-misalign misalign memory allocations
42
+ * Store the user name for ssh_refresh_filename() because the
31
@@ -XXX,XX +XXX,XX @@ testlist options
43
+ * default depends on the system you are on -- therefore, when we
32
xpand=false
44
+ * generate a filename, it should always contain the user name we
33
;;
45
+ * are actually using.
34
46
+ */
35
+ -vxhs)
47
+ char *user;
36
+ IMGPROTO=vxhs
48
} BDRVSSHState;
37
+ xpand=false
49
38
+ ;;
50
static void ssh_state_init(BDRVSSHState *s)
39
+
51
@@ -XXX,XX +XXX,XX @@ static void ssh_state_init(BDRVSSHState *s)
40
-ssh)
52
41
IMGPROTO=ssh
53
static void ssh_state_free(BDRVSSHState *s)
42
xpand=false
43
diff --git a/tests/qemu-iotests/common.config b/tests/qemu-iotests/common.config
44
index XXXXXXX..XXXXXXX 100644
45
--- a/tests/qemu-iotests/common.config
46
+++ b/tests/qemu-iotests/common.config
47
@@ -XXX,XX +XXX,XX @@ if [ -z "$QEMU_NBD_PROG" ]; then
48
export QEMU_NBD_PROG="`set_prog_path qemu-nbd`"
49
fi
50
51
+if [ -z "$QEMU_VXHS_PROG" ]; then
52
+ export QEMU_VXHS_PROG="`set_prog_path qnio_server`"
53
+fi
54
+
55
_qemu_wrapper()
56
{
54
{
57
(
55
+ g_free(s->user);
58
@@ -XXX,XX +XXX,XX @@ _qemu_nbd_wrapper()
56
+
59
)
57
if (s->sftp_handle) {
58
libssh2_sftp_close(s->sftp_handle);
59
}
60
@@ -XXX,XX +XXX,XX @@ static int connect_to_ssh(BDRVSSHState *s, BlockdevOptionsSsh *opts,
61
int ssh_flags, int creat_mode, Error **errp)
62
{
63
int r, ret;
64
- const char *user;
65
long port = 0;
66
67
if (opts->has_user) {
68
- user = opts->user;
69
+ s->user = g_strdup(opts->user);
70
} else {
71
- user = g_get_user_name();
72
- if (!user) {
73
+ s->user = g_strdup(g_get_user_name());
74
+ if (!s->user) {
75
error_setg_errno(errp, errno, "Can't get user name");
76
ret = -errno;
77
goto err;
78
@@ -XXX,XX +XXX,XX @@ static int connect_to_ssh(BDRVSSHState *s, BlockdevOptionsSsh *opts,
79
}
80
81
/* Authenticate. */
82
- ret = authenticate(s, user, errp);
83
+ ret = authenticate(s, s->user, errp);
84
if (ret < 0) {
85
goto err;
86
}
87
@@ -XXX,XX +XXX,XX @@ static int coroutine_fn ssh_co_truncate(BlockDriverState *bs, int64_t offset,
88
return ssh_grow_file(s, offset, errp);
60
}
89
}
61
90
62
+_qemu_vxhs_wrapper()
91
+static void ssh_refresh_filename(BlockDriverState *bs)
63
+{
92
+{
64
+ (
93
+ BDRVSSHState *s = bs->opaque;
65
+ echo $BASHPID > "${TEST_DIR}/qemu-vxhs.pid"
94
+ const char *path, *host_key_check;
66
+ exec "$QEMU_VXHS_PROG" $QEMU_VXHS_OPTIONS "$@"
95
+ int ret;
67
+ )
96
+
97
+ /*
98
+ * None of these options can be represented in a plain "host:port"
99
+ * format, so if any was given, we have to abort.
100
+ */
101
+ if (s->inet->has_ipv4 || s->inet->has_ipv6 || s->inet->has_to ||
102
+ s->inet->has_numeric)
103
+ {
104
+ return;
105
+ }
106
+
107
+ path = qdict_get_try_str(bs->full_open_options, "path");
108
+ assert(path); /* mandatory option */
109
+
110
+ host_key_check = qdict_get_try_str(bs->full_open_options, "host_key_check");
111
+
112
+ ret = snprintf(bs->exact_filename, sizeof(bs->exact_filename),
113
+ "ssh://%s@%s:%s%s%s%s",
114
+ s->user, s->inet->host, s->inet->port, path,
115
+ host_key_check ? "?host_key_check=" : "",
116
+ host_key_check ?: "");
117
+ if (ret >= sizeof(bs->exact_filename)) {
118
+ /* An overflow makes the filename unusable, so do not report any */
119
+ bs->exact_filename[0] = '\0';
120
+ }
68
+}
121
+}
69
+
122
+
70
export QEMU=_qemu_wrapper
123
static const char *const ssh_strong_runtime_opts[] = {
71
export QEMU_IMG=_qemu_img_wrapper
124
"host",
72
export QEMU_IO=_qemu_io_wrapper
125
"port",
73
export QEMU_NBD=_qemu_nbd_wrapper
126
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_ssh = {
74
+export QEMU_VXHS=_qemu_vxhs_wrapper
127
.bdrv_getlength = ssh_getlength,
75
128
.bdrv_co_truncate = ssh_co_truncate,
76
QEMU_IMG_EXTRA_ARGS=
129
.bdrv_co_flush_to_disk = ssh_co_flush,
77
if [ "$IMGOPTSSYNTAX" = "true" ]; then
130
+ .bdrv_refresh_filename = ssh_refresh_filename,
78
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
131
.create_opts = &ssh_create_opts,
79
index XXXXXXX..XXXXXXX 100644
132
.strong_runtime_opts = ssh_strong_runtime_opts,
80
--- a/tests/qemu-iotests/common.filter
133
};
81
+++ b/tests/qemu-iotests/common.filter
134
diff --git a/tests/qemu-iotests/207 b/tests/qemu-iotests/207
82
@@ -XXX,XX +XXX,XX @@ _filter_img_info()
135
index XXXXXXX..XXXXXXX 100755
83
-e "s#$TEST_DIR#TEST_DIR#g" \
136
--- a/tests/qemu-iotests/207
84
-e "s#$IMGFMT#IMGFMT#g" \
137
+++ b/tests/qemu-iotests/207
85
-e 's#nbd://127.0.0.1:10810$#TEST_DIR/t.IMGFMT#g' \
138
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.img') as disk_path, \
86
+ -e 's#json.*vdisk-id.*vxhs"}}#TEST_DIR/t.IMGFMT#' \
139
'size': 4194304 })
87
-e "/encrypted: yes/d" \
140
vm.shutdown()
88
-e "/cluster_size: [0-9]\\+/d" \
141
89
-e "/table_size: [0-9]\\+/d" \
142
- iotests.img_info_log(remote_path, filter_path=disk_path)
143
+ iotests.img_info_log(remote_path)
144
iotests.log("")
145
iotests.img_info_log(disk_path)
146
147
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.img') as disk_path, \
148
'size': 8388608 })
149
vm.shutdown()
150
151
- iotests.img_info_log(remote_path, filter_path=disk_path)
152
+ iotests.img_info_log(remote_path)
153
154
vm.launch()
155
blockdev_create(vm, { 'driver': 'ssh',
156
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.img') as disk_path, \
157
'size': 4194304 })
158
vm.shutdown()
159
160
- iotests.img_info_log(remote_path, filter_path=disk_path)
161
+ iotests.img_info_log(remote_path)
162
163
md5_key = subprocess.check_output(
164
'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
165
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.img') as disk_path, \
166
'size': 8388608 })
167
vm.shutdown()
168
169
- iotests.img_info_log(remote_path, filter_path=disk_path)
170
+ iotests.img_info_log(remote_path)
171
172
sha1_key = subprocess.check_output(
173
'ssh-keyscan -t rsa 127.0.0.1 2>/dev/null | grep -v "\\^#" | ' +
174
@@ -XXX,XX +XXX,XX @@ with iotests.FilePath('t.img') as disk_path, \
175
'size': 4194304 })
176
vm.shutdown()
177
178
- iotests.img_info_log(remote_path, filter_path=disk_path)
179
+ iotests.img_info_log(remote_path)
180
181
#
182
# Invalid path and user
183
diff --git a/tests/qemu-iotests/207.out b/tests/qemu-iotests/207.out
184
index XXXXXXX..XXXXXXX 100644
185
--- a/tests/qemu-iotests/207.out
186
+++ b/tests/qemu-iotests/207.out
187
@@ -XXX,XX +XXX,XX @@
188
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
189
{"return": {}}
190
191
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
192
+image: TEST_IMG
193
file format: IMGFMT
194
virtual size: 4 MiB (4194304 bytes)
195
196
@@ -XXX,XX +XXX,XX @@ virtual size: 4 MiB (4194304 bytes)
197
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
198
{"return": {}}
199
200
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
201
+image: TEST_IMG
202
file format: IMGFMT
203
virtual size: 8 MiB (8388608 bytes)
204
205
@@ -XXX,XX +XXX,XX @@ virtual size: 8 MiB (8388608 bytes)
206
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
207
{"return": {}}
208
209
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
210
+image: TEST_IMG
211
file format: IMGFMT
212
virtual size: 4 MiB (4194304 bytes)
213
214
@@ -XXX,XX +XXX,XX @@ Job failed: remote host key does not match host_key_check 'wrong'
215
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
216
{"return": {}}
217
218
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
219
+image: TEST_IMG
220
file format: IMGFMT
221
virtual size: 8 MiB (8388608 bytes)
222
223
@@ -XXX,XX +XXX,XX @@ Job failed: remote host key does not match host_key_check 'wrong'
224
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
225
{"return": {}}
226
227
-image: json:{"driver": "IMGFMT", "file": {"server.host": "127.0.0.1", "server.port": "22", "driver": "ssh", "path": "TEST_IMG"}}
228
+image: TEST_IMG
229
file format: IMGFMT
230
virtual size: 4 MiB (4194304 bytes)
231
90
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
232
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
91
index XXXXXXX..XXXXXXX 100644
233
index XXXXXXX..XXXXXXX 100644
92
--- a/tests/qemu-iotests/common.rc
234
--- a/tests/qemu-iotests/common.rc
93
+++ b/tests/qemu-iotests/common.rc
235
+++ b/tests/qemu-iotests/common.rc
94
@@ -XXX,XX +XXX,XX @@ else
236
@@ -XXX,XX +XXX,XX @@ else
237
TEST_IMG="nbd:127.0.0.1:10810"
238
elif [ "$IMGPROTO" = "ssh" ]; then
239
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
240
- REMOTE_TEST_DIR="ssh://127.0.0.1$TEST_DIR"
241
+ REMOTE_TEST_DIR="ssh://\\($USER@\\)\\?127.0.0.1\\(:[0-9]\\+\\)\\?$TEST_DIR"
242
TEST_IMG="ssh://127.0.0.1$TEST_IMG_FILE"
95
elif [ "$IMGPROTO" = "nfs" ]; then
243
elif [ "$IMGPROTO" = "nfs" ]; then
96
TEST_DIR="nfs://127.0.0.1/$TEST_DIR"
244
TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
97
TEST_IMG=$TEST_DIR/t.$IMGFMT
245
diff --git a/tests/qemu-iotests/iotests.py b/tests/qemu-iotests/iotests.py
98
+ elif [ "$IMGPROTO" = "vxhs" ]; then
246
index XXXXXXX..XXXXXXX 100644
99
+ TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
247
--- a/tests/qemu-iotests/iotests.py
100
+ TEST_IMG="vxhs://127.0.0.1:9999/t.$IMGFMT"
248
+++ b/tests/qemu-iotests/iotests.py
101
else
249
@@ -XXX,XX +XXX,XX @@ def remote_filename(path):
102
TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
250
if imgproto == 'file':
103
fi
251
return path
104
@@ -XXX,XX +XXX,XX @@ _make_test_img()
252
elif imgproto == 'ssh':
105
eval "$QEMU_NBD -v -t -b 127.0.0.1 -p 10810 -f $IMGFMT $TEST_IMG_FILE >/dev/null &"
253
- return "ssh://127.0.0.1%s" % (path)
106
sleep 1 # FIXME: qemu-nbd needs to be listening before we continue
254
+ return "ssh://%s@127.0.0.1:22%s" % (os.environ.get('USER'), path)
107
fi
255
else:
108
+
256
raise Exception("Protocol %s not supported" % (imgproto))
109
+ # Start QNIO server on image directory for vxhs protocol
257
110
+ if [ $IMGPROTO = "vxhs" ]; then
111
+ eval "$QEMU_VXHS -d $TEST_DIR > /dev/null &"
112
+ sleep 1 # Wait for server to come up.
113
+ fi
114
}
115
116
_rm_test_img()
117
@@ -XXX,XX +XXX,XX @@ _cleanup_test_img()
118
fi
119
rm -f "$TEST_IMG_FILE"
120
;;
121
+ vxhs)
122
+ if [ -f "${TEST_DIR}/qemu-vxhs.pid" ]; then
123
+ local QEMU_VXHS_PID
124
+ read QEMU_VXHS_PID < "${TEST_DIR}/qemu-vxhs.pid"
125
+ kill ${QEMU_VXHS_PID} >/dev/null 2>&1
126
+ rm -f "${TEST_DIR}/qemu-vxhs.pid"
127
+ fi
128
+ rm -f "$TEST_IMG_FILE"
129
+ ;;
130
+
131
file)
132
_rm_test_img "$TEST_DIR/t.$IMGFMT"
133
_rm_test_img "$TEST_DIR/t.$IMGFMT.orig"
134
--
258
--
135
2.9.3
259
2.20.1
136
260
137
261
diff view generated by jsdifflib
Deleted patch
1
The protocol VXHS does not support image creation. Some tests expect
2
to be able to create images through the protocol. Exclude VXHS from
3
these tests.
4
1
5
Signed-off-by: Jeff Cody <jcody@redhat.com>
6
---
7
tests/qemu-iotests/017 | 1 +
8
tests/qemu-iotests/020 | 1 +
9
tests/qemu-iotests/029 | 1 +
10
tests/qemu-iotests/073 | 1 +
11
tests/qemu-iotests/114 | 1 +
12
tests/qemu-iotests/130 | 1 +
13
tests/qemu-iotests/134 | 1 +
14
tests/qemu-iotests/156 | 1 +
15
tests/qemu-iotests/158 | 1 +
16
9 files changed, 9 insertions(+)
17
18
diff --git a/tests/qemu-iotests/017 b/tests/qemu-iotests/017
19
index XXXXXXX..XXXXXXX 100755
20
--- a/tests/qemu-iotests/017
21
+++ b/tests/qemu-iotests/017
22
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
23
# Any format supporting backing files
24
_supported_fmt qcow qcow2 vmdk qed
25
_supported_proto generic
26
+_unsupported_proto vxhs
27
_supported_os Linux
28
_unsupported_imgopts "subformat=monolithicFlat" "subformat=twoGbMaxExtentFlat"
29
30
diff --git a/tests/qemu-iotests/020 b/tests/qemu-iotests/020
31
index XXXXXXX..XXXXXXX 100755
32
--- a/tests/qemu-iotests/020
33
+++ b/tests/qemu-iotests/020
34
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
35
# Any format supporting backing files
36
_supported_fmt qcow qcow2 vmdk qed
37
_supported_proto generic
38
+_unsupported_proto vxhs
39
_supported_os Linux
40
_unsupported_imgopts "subformat=monolithicFlat" \
41
"subformat=twoGbMaxExtentFlat" \
42
diff --git a/tests/qemu-iotests/029 b/tests/qemu-iotests/029
43
index XXXXXXX..XXXXXXX 100755
44
--- a/tests/qemu-iotests/029
45
+++ b/tests/qemu-iotests/029
46
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
47
# Any format supporting intenal snapshots
48
_supported_fmt qcow2
49
_supported_proto generic
50
+_unsupported_proto vxhs
51
_supported_os Linux
52
# Internal snapshots are (currently) impossible with refcount_bits=1
53
_unsupported_imgopts 'refcount_bits=1[^0-9]'
54
diff --git a/tests/qemu-iotests/073 b/tests/qemu-iotests/073
55
index XXXXXXX..XXXXXXX 100755
56
--- a/tests/qemu-iotests/073
57
+++ b/tests/qemu-iotests/073
58
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
59
60
_supported_fmt qcow2
61
_supported_proto generic
62
+_unsupported_proto vxhs
63
_supported_os Linux
64
65
CLUSTER_SIZE=64k
66
diff --git a/tests/qemu-iotests/114 b/tests/qemu-iotests/114
67
index XXXXXXX..XXXXXXX 100755
68
--- a/tests/qemu-iotests/114
69
+++ b/tests/qemu-iotests/114
70
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
71
72
_supported_fmt qcow2
73
_supported_proto generic
74
+_unsupported_proto vxhs
75
_supported_os Linux
76
77
78
diff --git a/tests/qemu-iotests/130 b/tests/qemu-iotests/130
79
index XXXXXXX..XXXXXXX 100755
80
--- a/tests/qemu-iotests/130
81
+++ b/tests/qemu-iotests/130
82
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
83
84
_supported_fmt qcow2
85
_supported_proto generic
86
+_unsupported_proto vxhs
87
_supported_os Linux
88
89
qemu_comm_method="monitor"
90
diff --git a/tests/qemu-iotests/134 b/tests/qemu-iotests/134
91
index XXXXXXX..XXXXXXX 100755
92
--- a/tests/qemu-iotests/134
93
+++ b/tests/qemu-iotests/134
94
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
95
96
_supported_fmt qcow2
97
_supported_proto generic
98
+_unsupported_proto vxhs
99
_supported_os Linux
100
101
102
diff --git a/tests/qemu-iotests/156 b/tests/qemu-iotests/156
103
index XXXXXXX..XXXXXXX 100755
104
--- a/tests/qemu-iotests/156
105
+++ b/tests/qemu-iotests/156
106
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
107
108
_supported_fmt qcow2 qed
109
_supported_proto generic
110
+_unsupported_proto vxhs
111
_supported_os Linux
112
113
# Create source disk
114
diff --git a/tests/qemu-iotests/158 b/tests/qemu-iotests/158
115
index XXXXXXX..XXXXXXX 100755
116
--- a/tests/qemu-iotests/158
117
+++ b/tests/qemu-iotests/158
118
@@ -XXX,XX +XXX,XX @@ trap "_cleanup; exit \$status" 0 1 2 3 15
119
120
_supported_fmt qcow2
121
_supported_proto generic
122
+_unsupported_proto vxhs
123
_supported_os Linux
124
125
126
--
127
2.9.3
128
129
diff view generated by jsdifflib
1
A few block drivers will set the BDS read_only flag from their
1
ssh_bdrv_dirname() is basically the generic bdrv_dirname(), except it
2
.bdrv_open() function. This means the bs->read_only flag could
2
takes care not to silently chop off any query string (i.e.,
3
be set after we enable copy_on_read, as the BDRV_O_COPY_ON_READ
3
host_key_check).
4
flag check occurs prior to the call to bdrv->bdrv_open().
5
4
6
This adds an error return to bdrv_set_read_only(), and an error will be
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
7
return if we try to set the BDS to read_only while copy_on_read is
6
Tested-by: Richard W.M. Jones <rjones@redhat.com>
8
enabled.
7
Message-id: 20190225190828.17726-3-mreitz@redhat.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
9
---
10
block/ssh.c | 21 +++++++++++++++++++++
11
1 file changed, 21 insertions(+)
9
12
10
This patch also changes the behavior of vvfat. Before, vvfat could
13
diff --git a/block/ssh.c b/block/ssh.c
11
override the drive 'readonly' flag with its own, internal 'rw' flag.
12
13
For instance, this -drive parameter would result in a writable image:
14
15
"-drive format=vvfat,dir=/tmp/vvfat,rw,if=virtio,readonly=on"
16
17
This is not correct. Now, attempting to use the above -drive parameter
18
will result in an error (i.e., 'rw' is incompatible with 'readonly=on').
19
20
Signed-off-by: Jeff Cody <jcody@redhat.com>
21
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
22
Reviewed-by: John Snow <jsnow@redhat.com>
23
Message-id: 0c5b4c1cc2c651471b131f21376dfd5ea24d2196.1491597120.git.jcody@redhat.com
24
---
25
block.c | 10 +++++++++-
26
block/bochs.c | 5 ++++-
27
block/cloop.c | 5 ++++-
28
block/dmg.c | 6 +++++-
29
block/rbd.c | 11 ++++++++++-
30
block/vvfat.c | 19 +++++++++++++++----
31
include/block/block.h | 2 +-
32
7 files changed, 48 insertions(+), 10 deletions(-)
33
34
diff --git a/block.c b/block.c
35
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
36
--- a/block.c
15
--- a/block/ssh.c
37
+++ b/block.c
16
+++ b/block/ssh.c
38
@@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size,
17
@@ -XXX,XX +XXX,XX @@ static void ssh_refresh_filename(BlockDriverState *bs)
39
}
18
}
40
}
19
}
41
20
42
-void bdrv_set_read_only(BlockDriverState *bs, bool read_only)
21
+static char *ssh_bdrv_dirname(BlockDriverState *bs, Error **errp)
43
+int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
22
+{
44
{
23
+ if (qdict_haskey(bs->full_open_options, "host_key_check")) {
45
+ /* Do not set read_only if copy_on_read is enabled */
24
+ /*
46
+ if (bs->copy_on_read && read_only) {
25
+ * We cannot generate a simple prefix if we would have to
47
+ error_setg(errp, "Can't set node '%s' to r/o with copy-on-read enabled",
26
+ * append a query string.
48
+ bdrv_get_device_or_node_name(bs));
27
+ */
49
+ return -EINVAL;
28
+ error_setg(errp,
29
+ "Cannot generate a base directory with host_key_check set");
30
+ return NULL;
50
+ }
31
+ }
51
+
32
+
52
bs->read_only = read_only;
33
+ if (bs->exact_filename[0] == '\0') {
53
+ return 0;
34
+ error_setg(errp, "Cannot generate a base directory for this ssh node");
54
}
35
+ return NULL;
55
56
void bdrv_get_full_backing_filename_from_filename(const char *backed,
57
diff --git a/block/bochs.c b/block/bochs.c
58
index XXXXXXX..XXXXXXX 100644
59
--- a/block/bochs.c
60
+++ b/block/bochs.c
61
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
62
return -EINVAL;
63
}
64
65
- bdrv_set_read_only(bs, true); /* no write support yet */
66
+ ret = bdrv_set_read_only(bs, true, errp); /* no write support yet */
67
+ if (ret < 0) {
68
+ return ret;
69
+ }
70
71
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
72
if (ret < 0) {
73
diff --git a/block/cloop.c b/block/cloop.c
74
index XXXXXXX..XXXXXXX 100644
75
--- a/block/cloop.c
76
+++ b/block/cloop.c
77
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
78
return -EINVAL;
79
}
80
81
- bdrv_set_read_only(bs, true);
82
+ ret = bdrv_set_read_only(bs, true, errp);
83
+ if (ret < 0) {
84
+ return ret;
85
+ }
86
87
/* read header */
88
ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
89
diff --git a/block/dmg.c b/block/dmg.c
90
index XXXXXXX..XXXXXXX 100644
91
--- a/block/dmg.c
92
+++ b/block/dmg.c
93
@@ -XXX,XX +XXX,XX @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
94
return -EINVAL;
95
}
96
97
+ ret = bdrv_set_read_only(bs, true, errp);
98
+ if (ret < 0) {
99
+ return ret;
100
+ }
36
+ }
101
+
37
+
102
block_module_load_one("dmg-bz2");
38
+ return path_combine(bs->exact_filename, "");
103
- bdrv_set_read_only(bs, true);
39
+}
104
40
+
105
s->n_chunks = 0;
41
static const char *const ssh_strong_runtime_opts[] = {
106
s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
42
"host",
107
diff --git a/block/rbd.c b/block/rbd.c
43
"port",
108
index XXXXXXX..XXXXXXX 100644
44
@@ -XXX,XX +XXX,XX @@ static BlockDriver bdrv_ssh = {
109
--- a/block/rbd.c
45
.bdrv_co_truncate = ssh_co_truncate,
110
+++ b/block/rbd.c
46
.bdrv_co_flush_to_disk = ssh_co_flush,
111
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
47
.bdrv_refresh_filename = ssh_refresh_filename,
112
goto failed_shutdown;
48
+ .bdrv_dirname = ssh_bdrv_dirname,
113
}
49
.create_opts = &ssh_create_opts,
114
50
.strong_runtime_opts = ssh_strong_runtime_opts,
115
+ /* rbd_open is always r/w */
51
};
116
r = rbd_open(s->io_ctx, s->name, &s->image, s->snap);
117
if (r < 0) {
118
error_setg_errno(errp, -r, "error reading header from %s", s->name);
119
goto failed_open;
120
}
121
122
- bdrv_set_read_only(bs, (s->snap != NULL));
123
+ /* If we are using an rbd snapshot, we must be r/o, otherwise
124
+ * leave as-is */
125
+ if (s->snap != NULL) {
126
+ r = bdrv_set_read_only(bs, true, &local_err);
127
+ if (r < 0) {
128
+ error_propagate(errp, local_err);
129
+ goto failed_open;
130
+ }
131
+ }
132
133
qemu_opts_del(opts);
134
return 0;
135
diff --git a/block/vvfat.c b/block/vvfat.c
136
index XXXXXXX..XXXXXXX 100644
137
--- a/block/vvfat.c
138
+++ b/block/vvfat.c
139
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
140
141
s->current_cluster=0xffffffff;
142
143
- /* read only is the default for safety */
144
- bdrv_set_read_only(bs, true);
145
s->qcow = NULL;
146
s->qcow_filename = NULL;
147
s->fat2 = NULL;
148
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
149
s->sector_count = cyls * heads * secs - (s->first_sectors_number - 1);
150
151
if (qemu_opt_get_bool(opts, "rw", false)) {
152
- ret = enable_write_target(bs, errp);
153
+ if (!bdrv_is_read_only(bs)) {
154
+ ret = enable_write_target(bs, errp);
155
+ if (ret < 0) {
156
+ goto fail;
157
+ }
158
+ } else {
159
+ ret = -EPERM;
160
+ error_setg(errp,
161
+ "Unable to set VVFAT to 'rw' when drive is read-only");
162
+ goto fail;
163
+ }
164
+ } else {
165
+ /* read only is the default for safety */
166
+ ret = bdrv_set_read_only(bs, true, &local_err);
167
if (ret < 0) {
168
+ error_propagate(errp, local_err);
169
goto fail;
170
}
171
- bdrv_set_read_only(bs, false);
172
}
173
174
bs->total_sectors = cyls * heads * secs;
175
diff --git a/include/block/block.h b/include/block/block.h
176
index XXXXXXX..XXXXXXX 100644
177
--- a/include/block/block.h
178
+++ b/include/block/block.h
179
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
180
int64_t sector_num, int nb_sectors, int *pnum);
181
182
bool bdrv_is_read_only(BlockDriverState *bs);
183
-void bdrv_set_read_only(BlockDriverState *bs, bool read_only);
184
+int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
185
bool bdrv_is_sg(BlockDriverState *bs);
186
bool bdrv_is_inserted(BlockDriverState *bs);
187
int bdrv_media_changed(BlockDriverState *bs);
188
--
52
--
189
2.9.3
53
2.20.1
190
54
191
55
diff view generated by jsdifflib
1
Introduce check function for setting read_only flags. Will return < 0 on
1
From: Alberto Garcia <berto@igalia.com>
2
error, with appropriate Error value set. Does not alter any flags.
3
2
4
Signed-off-by: Jeff Cody <jcody@redhat.com>
3
There is no need to check for this because all block drivers that have
5
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
4
children implement bdrv_child_perm and all callers already ensure that
6
Reviewed-by: John Snow <jsnow@redhat.com>
5
bs->drv is set.
7
Message-id: e2bba34ac3bc76a0c42adc390413f358ae0566e8.1491597120.git.jcody@redhat.com
6
7
Furthermore, if this check would fail then the callers would end up
8
with uninitialized values for nperm and nshared.
9
10
This patch replaces the check with an assertion.
11
12
Signed-off-by: Alberto Garcia <berto@igalia.com>
13
Message-id: 20190404112953.4058-1-berto@igalia.com
14
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
15
---
9
block.c | 14 +++++++++++++-
16
block.c | 9 ++++-----
10
include/block/block.h | 1 +
17
1 file changed, 4 insertions(+), 5 deletions(-)
11
2 files changed, 14 insertions(+), 1 deletion(-)
12
18
13
diff --git a/block.c b/block.c
19
diff --git a/block.c b/block.c
14
index XXXXXXX..XXXXXXX 100644
20
index XXXXXXX..XXXXXXX 100644
15
--- a/block.c
21
--- a/block.c
16
+++ b/block.c
22
+++ b/block.c
17
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_read_only(BlockDriverState *bs)
23
@@ -XXX,XX +XXX,XX @@ static void bdrv_child_perm(BlockDriverState *bs, BlockDriverState *child_bs,
18
return bs->read_only;
24
uint64_t parent_perm, uint64_t parent_shared,
19
}
25
uint64_t *nperm, uint64_t *nshared)
20
21
-int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
22
+int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
23
{
26
{
24
/* Do not set read_only if copy_on_read is enabled */
27
- if (bs->drv && bs->drv->bdrv_child_perm) {
25
if (bs->copy_on_read && read_only) {
28
- bs->drv->bdrv_child_perm(bs, c, role, reopen_queue,
26
@@ -XXX,XX +XXX,XX @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
29
- parent_perm, parent_shared,
27
return -EPERM;
30
- nperm, nshared);
28
}
31
- }
29
32
+ assert(bs->drv && bs->drv->bdrv_child_perm);
30
+ return 0;
33
+ bs->drv->bdrv_child_perm(bs, c, role, reopen_queue,
31
+}
34
+ parent_perm, parent_shared,
32
+
35
+ nperm, nshared);
33
+int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
36
/* TODO Take force_share from reopen_queue */
34
+{
37
if (child_bs && child_bs->force_share) {
35
+ int ret = 0;
38
*nshared = BLK_PERM_ALL;
36
+
37
+ ret = bdrv_can_set_read_only(bs, read_only, errp);
38
+ if (ret < 0) {
39
+ return ret;
40
+ }
41
+
42
bs->read_only = read_only;
43
return 0;
44
}
45
diff --git a/include/block/block.h b/include/block/block.h
46
index XXXXXXX..XXXXXXX 100644
47
--- a/include/block/block.h
48
+++ b/include/block/block.h
49
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
50
int64_t sector_num, int nb_sectors, int *pnum);
51
52
bool bdrv_is_read_only(BlockDriverState *bs);
53
+int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
54
int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
55
bool bdrv_is_sg(BlockDriverState *bs);
56
bool bdrv_is_inserted(BlockDriverState *bs);
57
--
39
--
58
2.9.3
40
2.20.1
59
41
60
42
diff view generated by jsdifflib
1
The BDRV_O_ALLOW_RDWR flag allows / prohibits the changing of
1
From: Alberto Garcia <berto@igalia.com>
2
the BDS 'read_only' state, but there are a few places where it
3
is ignored. In the bdrv_set_read_only() helper, make sure to
4
honor the flag.
5
2
6
Signed-off-by: Jeff Cody <jcody@redhat.com>
3
This function combines bdrv_set_backing_hd() and bdrv_replace_node()
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
4
so we can use it to simplify the code a bit in commit_start().
8
Reviewed-by: John Snow <jsnow@redhat.com>
5
9
Message-id: be2e5fb2d285cbece2b6d06bed54a6f56520d251.1491597120.git.jcody@redhat.com
6
Signed-off-by: Alberto Garcia <berto@igalia.com>
7
Message-id: 20190403143748.9790-1-berto@igalia.com
8
Signed-off-by: Max Reitz <mreitz@redhat.com>
10
---
9
---
11
block.c | 7 +++++++
10
block/commit.c | 11 +----------
12
1 file changed, 7 insertions(+)
11
1 file changed, 1 insertion(+), 10 deletions(-)
13
12
14
diff --git a/block.c b/block.c
13
diff --git a/block/commit.c b/block/commit.c
15
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100644
16
--- a/block.c
15
--- a/block/commit.c
17
+++ b/block.c
16
+++ b/block/commit.c
18
@@ -XXX,XX +XXX,XX @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
17
@@ -XXX,XX +XXX,XX @@ void commit_start(const char *job_id, BlockDriverState *bs,
19
return -EINVAL;
18
commit_top_bs->total_sectors = top->total_sectors;
19
bdrv_set_aio_context(commit_top_bs, bdrv_get_aio_context(top));
20
21
- bdrv_set_backing_hd(commit_top_bs, top, &local_err);
22
+ bdrv_append(commit_top_bs, top, &local_err);
23
if (local_err) {
24
- bdrv_unref(commit_top_bs);
25
- commit_top_bs = NULL;
26
- error_propagate(errp, local_err);
27
- goto fail;
28
- }
29
- bdrv_replace_node(top, commit_top_bs, &local_err);
30
- if (local_err) {
31
- bdrv_unref(commit_top_bs);
32
commit_top_bs = NULL;
33
error_propagate(errp, local_err);
34
goto fail;
20
}
35
}
21
36
22
+ /* Do not clear read_only if it is prohibited */
37
s->commit_top_bs = commit_top_bs;
23
+ if (!read_only && !(bs->open_flags & BDRV_O_ALLOW_RDWR)) {
38
- bdrv_unref(commit_top_bs);
24
+ error_setg(errp, "Node '%s' is read only",
39
25
+ bdrv_get_device_or_node_name(bs));
40
/* Block all nodes between top and base, because they will
26
+ return -EPERM;
41
* disappear from the chain after this operation. */
27
+ }
28
+
29
bs->read_only = read_only;
30
return 0;
31
}
32
--
42
--
33
2.9.3
43
2.20.1
34
44
35
45
diff view generated by jsdifflib
1
We have a helper wrapper for checking for the BDS read_only flag,
1
A recent patch results in qemu-img reporting the backing file format of
2
add a helper wrapper to set the read_only flag as well.
2
vmdk images as vmdk. This broke iotests 110 and 126.
3
3
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
4
Fixes: 7502be838e2fb62cc00f9e55f632e0b88ead5e6e
5
Signed-off-by: Jeff Cody <jcody@redhat.com>
5
Signed-off-by: Max Reitz <mreitz@redhat.com>
6
Reviewed-by: John Snow <jsnow@redhat.com>
6
Message-id: 20190415154129.31021-1-mreitz@redhat.com
7
Message-id: 9b18972d05f5fa2ac16c014f0af98d680553048d.1491597120.git.jcody@redhat.com
7
Signed-off-by: Max Reitz <mreitz@redhat.com>
8
---
8
---
9
block.c | 5 +++++
9
tests/qemu-iotests/110 | 10 +++++++---
10
block/bochs.c | 2 +-
10
tests/qemu-iotests/126 | 10 +++++++---
11
block/cloop.c | 2 +-
11
2 files changed, 14 insertions(+), 6 deletions(-)
12
block/dmg.c | 2 +-
13
block/rbd.c | 2 +-
14
block/vvfat.c | 4 ++--
15
include/block/block.h | 1 +
16
7 files changed, 12 insertions(+), 6 deletions(-)
17
12
18
diff --git a/block.c b/block.c
13
diff --git a/tests/qemu-iotests/110 b/tests/qemu-iotests/110
19
index XXXXXXX..XXXXXXX 100644
14
index XXXXXXX..XXXXXXX 100755
20
--- a/block.c
15
--- a/tests/qemu-iotests/110
21
+++ b/block.c
16
+++ b/tests/qemu-iotests/110
22
@@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size,
17
@@ -XXX,XX +XXX,XX @@ TEST_IMG="$TEST_IMG.base" _make_test_img 64M
18
_make_test_img -b "$TEST_IMG_REL.base" 64M
19
# qemu should be able to reconstruct the filename, so relative backing names
20
# should work
21
+# (We have to filter the backing file format because vmdk always
22
+# reports it (as vmdk), whereas other image formats would do so only
23
+# with the backing_fmt creation option, which neither vmdk nor qcow
24
+# support)
25
TEST_IMG="json:{'driver':'$IMGFMT','file':{'driver':'file','filename':'$TEST_IMG'}}" \
26
- _img_info | _filter_img_info
27
+ _img_info | _filter_img_info | grep -v 'backing file format'
28
29
echo
30
echo '=== Non-reconstructable filename ==='
31
@@ -XXX,XX +XXX,XX @@ TEST_IMG="json:{
32
}
33
]
23
}
34
}
24
}
35
-}" _img_info | _filter_img_info
25
36
+}" _img_info | _filter_img_info | grep -v 'backing file format'
26
+void bdrv_set_read_only(BlockDriverState *bs, bool read_only)
37
27
+{
38
echo
28
+ bs->read_only = read_only;
39
echo '=== Backing name is always relative to the backed image ==='
29
+}
40
@@ -XXX,XX +XXX,XX @@ TEST_IMG="json:{
30
+
41
}
31
void bdrv_get_full_backing_filename_from_filename(const char *backed,
42
]
32
const char *backing,
33
char *dest, size_t sz,
34
diff --git a/block/bochs.c b/block/bochs.c
35
index XXXXXXX..XXXXXXX 100644
36
--- a/block/bochs.c
37
+++ b/block/bochs.c
38
@@ -XXX,XX +XXX,XX @@ static int bochs_open(BlockDriverState *bs, QDict *options, int flags,
39
return -EINVAL;
40
}
43
}
41
44
-}" _img_info | _filter_img_info
42
- bs->read_only = true; /* no write support yet */
45
+}" _img_info | _filter_img_info | grep -v 'backing file format'
43
+ bdrv_set_read_only(bs, true); /* no write support yet */
46
44
47
45
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
48
# success, all done
46
if (ret < 0) {
49
diff --git a/tests/qemu-iotests/126 b/tests/qemu-iotests/126
47
diff --git a/block/cloop.c b/block/cloop.c
50
index XXXXXXX..XXXXXXX 100755
48
index XXXXXXX..XXXXXXX 100644
51
--- a/tests/qemu-iotests/126
49
--- a/block/cloop.c
52
+++ b/tests/qemu-iotests/126
50
+++ b/block/cloop.c
53
@@ -XXX,XX +XXX,XX @@ TOP_IMG="$TEST_DIR/image:top.$IMGFMT"
51
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
54
TEST_IMG=$BASE_IMG _make_test_img 64M
52
return -EINVAL;
55
TEST_IMG=$TOP_IMG _make_test_img -b ./image:base.$IMGFMT
53
}
56
54
57
-# The default cluster size depends on the image format
55
- bs->read_only = true;
58
-TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size'
56
+ bdrv_set_read_only(bs, true);
59
+# (1) The default cluster size depends on the image format
57
60
+# (2) vmdk only supports vmdk backing files, so it always reports the
58
/* read header */
61
+# format of its backing file as such (but neither it nor qcow
59
ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
62
+# support the backing_fmt creation option, so we cannot use that to
60
diff --git a/block/dmg.c b/block/dmg.c
63
+# harmonize the output across all image formats this test supports)
61
index XXXXXXX..XXXXXXX 100644
64
+TEST_IMG=$TOP_IMG _img_info | grep -ve 'cluster_size' -e 'backing file format'
62
--- a/block/dmg.c
65
63
+++ b/block/dmg.c
66
_rm_test_img "$BASE_IMG"
64
@@ -XXX,XX +XXX,XX @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
67
_rm_test_img "$TOP_IMG"
65
}
68
@@ -XXX,XX +XXX,XX @@ TOP_IMG="file:image:top.$IMGFMT"
66
69
TEST_IMG=$BASE_IMG _make_test_img 64M
67
block_module_load_one("dmg-bz2");
70
TEST_IMG=$TOP_IMG _make_test_img -b "$BASE_IMG"
68
- bs->read_only = true;
71
69
+ bdrv_set_read_only(bs, true);
72
-TEST_IMG=$TOP_IMG _img_info | grep -v 'cluster_size'
70
73
+TEST_IMG=$TOP_IMG _img_info | grep -ve 'cluster_size' -e 'backing file format'
71
s->n_chunks = 0;
74
72
s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
75
_rm_test_img "$BASE_IMG"
73
diff --git a/block/rbd.c b/block/rbd.c
76
_rm_test_img "image:top.$IMGFMT"
74
index XXXXXXX..XXXXXXX 100644
75
--- a/block/rbd.c
76
+++ b/block/rbd.c
77
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
78
goto failed_open;
79
}
80
81
- bs->read_only = (s->snap != NULL);
82
+ bdrv_set_read_only(bs, (s->snap != NULL));
83
84
qemu_opts_del(opts);
85
return 0;
86
diff --git a/block/vvfat.c b/block/vvfat.c
87
index XXXXXXX..XXXXXXX 100644
88
--- a/block/vvfat.c
89
+++ b/block/vvfat.c
90
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
91
s->current_cluster=0xffffffff;
92
93
/* read only is the default for safety */
94
- bs->read_only = true;
95
+ bdrv_set_read_only(bs, true);
96
s->qcow = NULL;
97
s->qcow_filename = NULL;
98
s->fat2 = NULL;
99
@@ -XXX,XX +XXX,XX @@ static int vvfat_open(BlockDriverState *bs, QDict *options, int flags,
100
if (ret < 0) {
101
goto fail;
102
}
103
- bs->read_only = false;
104
+ bdrv_set_read_only(bs, false);
105
}
106
107
bs->total_sectors = cyls * heads * secs;
108
diff --git a/include/block/block.h b/include/block/block.h
109
index XXXXXXX..XXXXXXX 100644
110
--- a/include/block/block.h
111
+++ b/include/block/block.h
112
@@ -XXX,XX +XXX,XX @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
113
int64_t sector_num, int nb_sectors, int *pnum);
114
115
bool bdrv_is_read_only(BlockDriverState *bs);
116
+void bdrv_set_read_only(BlockDriverState *bs, bool read_only);
117
bool bdrv_is_sg(BlockDriverState *bs);
118
bool bdrv_is_inserted(BlockDriverState *bs);
119
int bdrv_media_changed(BlockDriverState *bs);
120
--
77
--
121
2.9.3
78
2.20.1
122
79
123
80
diff view generated by jsdifflib