1
The following changes since commit 4c55b1d0bad8a703f0499fe62e3761a0cd288da3:
1
The following changes since commit b0fbe46ad82982b289a44ee2495b59b0bad8a842:
2
2
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-error-2017-04-24' into staging (2017-04-24 14:49:48 +0100)
3
Update version for v2.11.0-rc0 release (2017-11-07 16:05:28 +0000)
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
git://github.com/stefanha/qemu.git tags/block-pull-request
8
8
9
for you to fetch changes up to ecfa185400ade2abc9915efa924cbad1e15a21a4:
9
for you to fetch changes up to ef6dada8b44e1e7c4bec5c1115903af9af415b50:
10
10
11
qemu-iotests: _cleanup_qemu must be called on exit (2017-04-24 15:09:33 -0400)
11
util/async: use atomic_mb_set in qemu_bh_cancel (2017-11-08 19:09:15 +0000)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
Pull v2, with 32-bit errors fixed. I don't have OS X to test compile on,
14
Pull request
15
but I think it is safe to assume the cause of the compile error was the same.
15
16
v2:
17
* v1 emails 2/3 and 3/3 weren't sent due to an email failure
18
* Included Sergio's updated wording in the commit description
19
16
----------------------------------------------------------------
20
----------------------------------------------------------------
17
21
18
Ashish Mittal (2):
22
Sergio Lopez (1):
19
block/vxhs.c: Add support for a new block device type called "vxhs"
23
util/async: use atomic_mb_set in qemu_bh_cancel
20
block/vxhs.c: Add qemu-iotests for new block device type "vxhs"
21
24
22
Jeff Cody (10):
25
Stefan Hajnoczi (1):
23
qemu-iotests: exclude vxhs from image creation via protocol
26
tests-aio-multithread: fix /aio/multi/schedule race condition
24
block: add bdrv_set_read_only() helper function
25
block: do not set BDS read_only if copy_on_read enabled
26
block: honor BDRV_O_ALLOW_RDWR when clearing bs->read_only
27
block: code movement
28
block: introduce bdrv_can_set_read_only()
29
block: use bdrv_can_set_read_only() during reopen
30
block/rbd - update variable names to more apt names
31
block/rbd: Add support for reopen()
32
qemu-iotests: _cleanup_qemu must be called on exit
33
27
34
block.c | 56 +++-
28
tests/test-aio-multithread.c | 5 ++---
35
block/Makefile.objs | 2 +
29
util/async.c | 2 +-
36
block/bochs.c | 5 +-
30
2 files changed, 3 insertions(+), 4 deletions(-)
37
block/cloop.c | 5 +-
38
block/dmg.c | 6 +-
39
block/rbd.c | 65 +++--
40
block/trace-events | 17 ++
41
block/vvfat.c | 19 +-
42
block/vxhs.c | 575 +++++++++++++++++++++++++++++++++++++++
43
configure | 39 +++
44
include/block/block.h | 2 +
45
qapi/block-core.json | 23 +-
46
tests/qemu-iotests/017 | 1 +
47
tests/qemu-iotests/020 | 1 +
48
tests/qemu-iotests/028 | 1 +
49
tests/qemu-iotests/029 | 1 +
50
tests/qemu-iotests/073 | 1 +
51
tests/qemu-iotests/094 | 11 +-
52
tests/qemu-iotests/102 | 5 +-
53
tests/qemu-iotests/109 | 1 +
54
tests/qemu-iotests/114 | 1 +
55
tests/qemu-iotests/117 | 1 +
56
tests/qemu-iotests/130 | 2 +
57
tests/qemu-iotests/134 | 1 +
58
tests/qemu-iotests/140 | 1 +
59
tests/qemu-iotests/141 | 1 +
60
tests/qemu-iotests/143 | 1 +
61
tests/qemu-iotests/156 | 2 +
62
tests/qemu-iotests/158 | 1 +
63
tests/qemu-iotests/common | 6 +
64
tests/qemu-iotests/common.config | 13 +
65
tests/qemu-iotests/common.filter | 1 +
66
tests/qemu-iotests/common.rc | 19 ++
67
33 files changed, 844 insertions(+), 42 deletions(-)
68
create mode 100644 block/vxhs.c
69
31
70
--
32
--
71
2.9.3
33
2.13.6
72
34
73
35
diff view generated by jsdifflib
Deleted patch
1
From: Ashish Mittal <ashmit602@gmail.com>
2
1
3
Source code for the qnio library that this code loads can be downloaded from:
4
https://github.com/VeritasHyperScale/libqnio.git
5
6
Sample command line using JSON syntax:
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
13
Sample command line using URI syntax:
14
qemu-img convert -f raw -O raw -n
15
/var/lib/nova/instances/_base/0c5eacd5ebea5ed914b6a3e7b18f1ce734c386ad
16
vxhs://192.168.0.1:9999/c6718f6b-0401-441d-a8c3-1f0064d75ee0
17
18
Sample command line using TLS credentials (run in secure mode):
19
./qemu-io --object
20
tls-creds-x509,id=tls0,dir=/etc/pki/qemu/vxhs,endpoint=client -c 'read
21
-v 66000 2.5k' 'json:{"server.host": "127.0.0.1", "server.port": "9999",
22
"vdisk-id": "/test.raw", "driver": "vxhs", "tls-creds":"tls0"}'
23
24
[Jeff: Modified trace-events with the correct string formatting]
25
26
Signed-off-by: Ashish Mittal <Ashish.Mittal@veritas.com>
27
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
28
Reviewed-by: Jeff Cody <jcody@redhat.com>
29
Signed-off-by: Jeff Cody <jcody@redhat.com>
30
Message-id: 1491277689-24949-2-git-send-email-Ashish.Mittal@veritas.com
31
---
32
block/Makefile.objs | 2 +
33
block/trace-events | 17 ++
34
block/vxhs.c | 575 +++++++++++++++++++++++++++++++++++++++++++++++++++
35
configure | 39 ++++
36
qapi/block-core.json | 23 ++-
37
5 files changed, 654 insertions(+), 2 deletions(-)
38
create mode 100644 block/vxhs.c
39
40
diff --git a/block/Makefile.objs b/block/Makefile.objs
41
index XXXXXXX..XXXXXXX 100644
42
--- a/block/Makefile.objs
43
+++ b/block/Makefile.objs
44
@@ -XXX,XX +XXX,XX @@ block-obj-$(CONFIG_LIBNFS) += nfs.o
45
block-obj-$(CONFIG_CURL) += curl.o
46
block-obj-$(CONFIG_RBD) += rbd.o
47
block-obj-$(CONFIG_GLUSTERFS) += gluster.o
48
+block-obj-$(CONFIG_VXHS) += vxhs.o
49
block-obj-$(CONFIG_LIBSSH2) += ssh.o
50
block-obj-y += accounting.o dirty-bitmap.o
51
block-obj-y += write-threshold.o
52
@@ -XXX,XX +XXX,XX @@ rbd.o-cflags := $(RBD_CFLAGS)
53
rbd.o-libs := $(RBD_LIBS)
54
gluster.o-cflags := $(GLUSTERFS_CFLAGS)
55
gluster.o-libs := $(GLUSTERFS_LIBS)
56
+vxhs.o-libs := $(VXHS_LIBS)
57
ssh.o-cflags := $(LIBSSH2_CFLAGS)
58
ssh.o-libs := $(LIBSSH2_LIBS)
59
block-obj-$(if $(CONFIG_BZIP2),m,n) += dmg-bz2.o
60
diff --git a/block/trace-events b/block/trace-events
61
index XXXXXXX..XXXXXXX 100644
62
--- a/block/trace-events
63
+++ b/block/trace-events
64
@@ -XXX,XX +XXX,XX @@ qed_aio_write_data(void *s, void *acb, int ret, uint64_t offset, size_t len) "s
65
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
66
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
67
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"
68
+
69
+# block/vxhs.c
70
+vxhs_iio_callback(int error) "ctx is NULL: error %d"
71
+vxhs_iio_callback_chnfail(int err, int error) "QNIO channel failed, no i/o %d, %d"
72
+vxhs_iio_callback_unknwn(int opcode, int err) "unexpected opcode %d, errno %d"
73
+vxhs_aio_rw_invalid(int req) "Invalid I/O request iodir %d"
74
+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 = %"PRIu64" offset = %"PRIu64" ACB = %p. Error = %d, errno = %d"
75
+vxhs_get_vdisk_stat_err(char *guid, int ret, int err) "vDisk (%s) stat ioctl failed, ret = %d, errno = %d"
76
+vxhs_get_vdisk_stat(char *vdisk_guid, uint64_t vdisk_size) "vDisk %s stat ioctl returned size %"PRIu64
77
+vxhs_complete_aio(void *acb, uint64_t ret) "aio failed acb %p ret %"PRIu64
78
+vxhs_parse_uri_filename(const char *filename) "URI passed via bdrv_parse_filename %s"
79
+vxhs_open_vdiskid(const char *vdisk_id) "Opening vdisk-id %s"
80
+vxhs_open_hostinfo(char *of_vsa_addr, int port) "Adding host %s:%d to BDRVVXHSState"
81
+vxhs_open_iio_open(const char *host) "Failed to connect to storage agent on host %s"
82
+vxhs_parse_uri_hostinfo(char *host, int port) "Host: IP %s, Port %d"
83
+vxhs_close(char *vdisk_guid) "Closing vdisk %s"
84
+vxhs_get_creds(const char *cacert, const char *client_key, const char *client_cert) "cacert %s, client_key %s, client_cert %s"
85
diff --git a/block/vxhs.c b/block/vxhs.c
86
new file mode 100644
87
index XXXXXXX..XXXXXXX
88
--- /dev/null
89
+++ b/block/vxhs.c
90
@@ -XXX,XX +XXX,XX @@
91
+/*
92
+ * QEMU Block driver for Veritas HyperScale (VxHS)
93
+ *
94
+ * Copyright (c) 2017 Veritas Technologies LLC.
95
+ *
96
+ * This work is licensed under the terms of the GNU GPL, version 2 or later.
97
+ * See the COPYING file in the top-level directory.
98
+ *
99
+ */
100
+
101
+#include "qemu/osdep.h"
102
+#include <qnio/qnio_api.h>
103
+#include <sys/param.h>
104
+#include "block/block_int.h"
105
+#include "qapi/qmp/qerror.h"
106
+#include "qapi/qmp/qdict.h"
107
+#include "qapi/qmp/qstring.h"
108
+#include "trace.h"
109
+#include "qemu/uri.h"
110
+#include "qapi/error.h"
111
+#include "qemu/uuid.h"
112
+#include "crypto/tlscredsx509.h"
113
+
114
+#define VXHS_OPT_FILENAME "filename"
115
+#define VXHS_OPT_VDISK_ID "vdisk-id"
116
+#define VXHS_OPT_SERVER "server"
117
+#define VXHS_OPT_HOST "host"
118
+#define VXHS_OPT_PORT "port"
119
+
120
+/* Only accessed under QEMU global mutex */
121
+static uint32_t vxhs_ref;
122
+
123
+typedef enum {
124
+ VDISK_AIO_READ,
125
+ VDISK_AIO_WRITE,
126
+} VDISKAIOCmd;
127
+
128
+/*
129
+ * HyperScale AIO callbacks structure
130
+ */
131
+typedef struct VXHSAIOCB {
132
+ BlockAIOCB common;
133
+ int err;
134
+} VXHSAIOCB;
135
+
136
+typedef struct VXHSvDiskHostsInfo {
137
+ void *dev_handle; /* Device handle */
138
+ char *host; /* Host name or IP */
139
+ int port; /* Host's port number */
140
+} VXHSvDiskHostsInfo;
141
+
142
+/*
143
+ * Structure per vDisk maintained for state
144
+ */
145
+typedef struct BDRVVXHSState {
146
+ VXHSvDiskHostsInfo vdisk_hostinfo; /* Per host info */
147
+ char *vdisk_guid;
148
+ char *tlscredsid; /* tlscredsid */
149
+} BDRVVXHSState;
150
+
151
+static void vxhs_complete_aio_bh(void *opaque)
152
+{
153
+ VXHSAIOCB *acb = opaque;
154
+ BlockCompletionFunc *cb = acb->common.cb;
155
+ void *cb_opaque = acb->common.opaque;
156
+ int ret = 0;
157
+
158
+ if (acb->err != 0) {
159
+ trace_vxhs_complete_aio(acb, acb->err);
160
+ ret = (-EIO);
161
+ }
162
+
163
+ qemu_aio_unref(acb);
164
+ cb(cb_opaque, ret);
165
+}
166
+
167
+/*
168
+ * Called from a libqnio thread
169
+ */
170
+static void vxhs_iio_callback(void *ctx, uint32_t opcode, uint32_t error)
171
+{
172
+ VXHSAIOCB *acb = NULL;
173
+
174
+ switch (opcode) {
175
+ case IRP_READ_REQUEST:
176
+ case IRP_WRITE_REQUEST:
177
+
178
+ /*
179
+ * ctx is VXHSAIOCB*
180
+ * ctx is NULL if error is QNIOERROR_CHANNEL_HUP
181
+ */
182
+ if (ctx) {
183
+ acb = ctx;
184
+ } else {
185
+ trace_vxhs_iio_callback(error);
186
+ goto out;
187
+ }
188
+
189
+ if (error) {
190
+ if (!acb->err) {
191
+ acb->err = error;
192
+ }
193
+ trace_vxhs_iio_callback(error);
194
+ }
195
+
196
+ aio_bh_schedule_oneshot(bdrv_get_aio_context(acb->common.bs),
197
+ vxhs_complete_aio_bh, acb);
198
+ break;
199
+
200
+ default:
201
+ if (error == QNIOERROR_HUP) {
202
+ /*
203
+ * Channel failed, spontaneous notification,
204
+ * not in response to I/O
205
+ */
206
+ trace_vxhs_iio_callback_chnfail(error, errno);
207
+ } else {
208
+ trace_vxhs_iio_callback_unknwn(opcode, error);
209
+ }
210
+ break;
211
+ }
212
+out:
213
+ return;
214
+}
215
+
216
+static QemuOptsList runtime_opts = {
217
+ .name = "vxhs",
218
+ .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
219
+ .desc = {
220
+ {
221
+ .name = VXHS_OPT_FILENAME,
222
+ .type = QEMU_OPT_STRING,
223
+ .help = "URI to the Veritas HyperScale image",
224
+ },
225
+ {
226
+ .name = VXHS_OPT_VDISK_ID,
227
+ .type = QEMU_OPT_STRING,
228
+ .help = "UUID of the VxHS vdisk",
229
+ },
230
+ {
231
+ .name = "tls-creds",
232
+ .type = QEMU_OPT_STRING,
233
+ .help = "ID of the TLS/SSL credentials to use",
234
+ },
235
+ { /* end of list */ }
236
+ },
237
+};
238
+
239
+static QemuOptsList runtime_tcp_opts = {
240
+ .name = "vxhs_tcp",
241
+ .head = QTAILQ_HEAD_INITIALIZER(runtime_tcp_opts.head),
242
+ .desc = {
243
+ {
244
+ .name = VXHS_OPT_HOST,
245
+ .type = QEMU_OPT_STRING,
246
+ .help = "host address (ipv4 addresses)",
247
+ },
248
+ {
249
+ .name = VXHS_OPT_PORT,
250
+ .type = QEMU_OPT_NUMBER,
251
+ .help = "port number on which VxHSD is listening (default 9999)",
252
+ .def_value_str = "9999"
253
+ },
254
+ { /* end of list */ }
255
+ },
256
+};
257
+
258
+/*
259
+ * Parse incoming URI and populate *options with the host
260
+ * and device information
261
+ */
262
+static int vxhs_parse_uri(const char *filename, QDict *options)
263
+{
264
+ URI *uri = NULL;
265
+ char *port;
266
+ int ret = 0;
267
+
268
+ trace_vxhs_parse_uri_filename(filename);
269
+ uri = uri_parse(filename);
270
+ if (!uri || !uri->server || !uri->path) {
271
+ uri_free(uri);
272
+ return -EINVAL;
273
+ }
274
+
275
+ qdict_put(options, VXHS_OPT_SERVER".host", qstring_from_str(uri->server));
276
+
277
+ if (uri->port) {
278
+ port = g_strdup_printf("%d", uri->port);
279
+ qdict_put(options, VXHS_OPT_SERVER".port", qstring_from_str(port));
280
+ g_free(port);
281
+ }
282
+
283
+ qdict_put(options, "vdisk-id", qstring_from_str(uri->path));
284
+
285
+ trace_vxhs_parse_uri_hostinfo(uri->server, uri->port);
286
+ uri_free(uri);
287
+
288
+ return ret;
289
+}
290
+
291
+static void vxhs_parse_filename(const char *filename, QDict *options,
292
+ Error **errp)
293
+{
294
+ if (qdict_haskey(options, "vdisk-id") || qdict_haskey(options, "server")) {
295
+ error_setg(errp, "vdisk-id/server and a file name may not be specified "
296
+ "at the same time");
297
+ return;
298
+ }
299
+
300
+ if (strstr(filename, "://")) {
301
+ int ret = vxhs_parse_uri(filename, options);
302
+ if (ret < 0) {
303
+ error_setg(errp, "Invalid URI. URI should be of the form "
304
+ " vxhs://<host_ip>:<port>/<vdisk-id>");
305
+ }
306
+ }
307
+}
308
+
309
+static int vxhs_init_and_ref(void)
310
+{
311
+ if (vxhs_ref++ == 0) {
312
+ if (iio_init(QNIO_VERSION, vxhs_iio_callback)) {
313
+ return -ENODEV;
314
+ }
315
+ }
316
+ return 0;
317
+}
318
+
319
+static void vxhs_unref(void)
320
+{
321
+ if (--vxhs_ref == 0) {
322
+ iio_fini();
323
+ }
324
+}
325
+
326
+static void vxhs_get_tls_creds(const char *id, char **cacert,
327
+ char **key, char **cert, Error **errp)
328
+{
329
+ Object *obj;
330
+ QCryptoTLSCreds *creds;
331
+ QCryptoTLSCredsX509 *creds_x509;
332
+
333
+ obj = object_resolve_path_component(
334
+ object_get_objects_root(), id);
335
+
336
+ if (!obj) {
337
+ error_setg(errp, "No TLS credentials with id '%s'",
338
+ id);
339
+ return;
340
+ }
341
+
342
+ creds_x509 = (QCryptoTLSCredsX509 *)
343
+ object_dynamic_cast(obj, TYPE_QCRYPTO_TLS_CREDS_X509);
344
+
345
+ if (!creds_x509) {
346
+ error_setg(errp, "Object with id '%s' is not TLS credentials",
347
+ id);
348
+ return;
349
+ }
350
+
351
+ creds = &creds_x509->parent_obj;
352
+
353
+ if (creds->endpoint != QCRYPTO_TLS_CREDS_ENDPOINT_CLIENT) {
354
+ error_setg(errp,
355
+ "Expecting TLS credentials with a client endpoint");
356
+ return;
357
+ }
358
+
359
+ /*
360
+ * Get the cacert, client_cert and client_key file names.
361
+ */
362
+ if (!creds->dir) {
363
+ error_setg(errp, "TLS object missing 'dir' property value");
364
+ return;
365
+ }
366
+
367
+ *cacert = g_strdup_printf("%s/%s", creds->dir,
368
+ QCRYPTO_TLS_CREDS_X509_CA_CERT);
369
+ *cert = g_strdup_printf("%s/%s", creds->dir,
370
+ QCRYPTO_TLS_CREDS_X509_CLIENT_CERT);
371
+ *key = g_strdup_printf("%s/%s", creds->dir,
372
+ QCRYPTO_TLS_CREDS_X509_CLIENT_KEY);
373
+}
374
+
375
+static int vxhs_open(BlockDriverState *bs, QDict *options,
376
+ int bdrv_flags, Error **errp)
377
+{
378
+ BDRVVXHSState *s = bs->opaque;
379
+ void *dev_handlep;
380
+ QDict *backing_options = NULL;
381
+ QemuOpts *opts = NULL;
382
+ QemuOpts *tcp_opts = NULL;
383
+ char *of_vsa_addr = NULL;
384
+ Error *local_err = NULL;
385
+ const char *vdisk_id_opt;
386
+ const char *server_host_opt;
387
+ int ret = 0;
388
+ char *cacert = NULL;
389
+ char *client_key = NULL;
390
+ char *client_cert = NULL;
391
+
392
+ ret = vxhs_init_and_ref();
393
+ if (ret < 0) {
394
+ ret = -EINVAL;
395
+ goto out;
396
+ }
397
+
398
+ /* Create opts info from runtime_opts and runtime_tcp_opts list */
399
+ opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
400
+ tcp_opts = qemu_opts_create(&runtime_tcp_opts, NULL, 0, &error_abort);
401
+
402
+ qemu_opts_absorb_qdict(opts, options, &local_err);
403
+ if (local_err) {
404
+ ret = -EINVAL;
405
+ goto out;
406
+ }
407
+
408
+ /* vdisk-id is the disk UUID */
409
+ vdisk_id_opt = qemu_opt_get(opts, VXHS_OPT_VDISK_ID);
410
+ if (!vdisk_id_opt) {
411
+ error_setg(&local_err, QERR_MISSING_PARAMETER, VXHS_OPT_VDISK_ID);
412
+ ret = -EINVAL;
413
+ goto out;
414
+ }
415
+
416
+ /* vdisk-id may contain a leading '/' */
417
+ if (strlen(vdisk_id_opt) > UUID_FMT_LEN + 1) {
418
+ error_setg(&local_err, "vdisk-id cannot be more than %d characters",
419
+ UUID_FMT_LEN);
420
+ ret = -EINVAL;
421
+ goto out;
422
+ }
423
+
424
+ s->vdisk_guid = g_strdup(vdisk_id_opt);
425
+ trace_vxhs_open_vdiskid(vdisk_id_opt);
426
+
427
+ /* get the 'server.' arguments */
428
+ qdict_extract_subqdict(options, &backing_options, VXHS_OPT_SERVER".");
429
+
430
+ qemu_opts_absorb_qdict(tcp_opts, backing_options, &local_err);
431
+ if (local_err != NULL) {
432
+ ret = -EINVAL;
433
+ goto out;
434
+ }
435
+
436
+ server_host_opt = qemu_opt_get(tcp_opts, VXHS_OPT_HOST);
437
+ if (!server_host_opt) {
438
+ error_setg(&local_err, QERR_MISSING_PARAMETER,
439
+ VXHS_OPT_SERVER"."VXHS_OPT_HOST);
440
+ ret = -EINVAL;
441
+ goto out;
442
+ }
443
+
444
+ if (strlen(server_host_opt) > MAXHOSTNAMELEN) {
445
+ error_setg(&local_err, "server.host cannot be more than %d characters",
446
+ MAXHOSTNAMELEN);
447
+ ret = -EINVAL;
448
+ goto out;
449
+ }
450
+
451
+ /* check if we got tls-creds via the --object argument */
452
+ s->tlscredsid = g_strdup(qemu_opt_get(opts, "tls-creds"));
453
+ if (s->tlscredsid) {
454
+ vxhs_get_tls_creds(s->tlscredsid, &cacert, &client_key,
455
+ &client_cert, &local_err);
456
+ if (local_err != NULL) {
457
+ ret = -EINVAL;
458
+ goto out;
459
+ }
460
+ trace_vxhs_get_creds(cacert, client_key, client_cert);
461
+ }
462
+
463
+ s->vdisk_hostinfo.host = g_strdup(server_host_opt);
464
+ s->vdisk_hostinfo.port = g_ascii_strtoll(qemu_opt_get(tcp_opts,
465
+ VXHS_OPT_PORT),
466
+ NULL, 0);
467
+
468
+ trace_vxhs_open_hostinfo(s->vdisk_hostinfo.host,
469
+ s->vdisk_hostinfo.port);
470
+
471
+ of_vsa_addr = g_strdup_printf("of://%s:%d",
472
+ s->vdisk_hostinfo.host,
473
+ s->vdisk_hostinfo.port);
474
+
475
+ /*
476
+ * Open qnio channel to storage agent if not opened before
477
+ */
478
+ dev_handlep = iio_open(of_vsa_addr, s->vdisk_guid, 0,
479
+ cacert, client_key, client_cert);
480
+ if (dev_handlep == NULL) {
481
+ trace_vxhs_open_iio_open(of_vsa_addr);
482
+ ret = -ENODEV;
483
+ goto out;
484
+ }
485
+ s->vdisk_hostinfo.dev_handle = dev_handlep;
486
+
487
+out:
488
+ g_free(of_vsa_addr);
489
+ QDECREF(backing_options);
490
+ qemu_opts_del(tcp_opts);
491
+ qemu_opts_del(opts);
492
+ g_free(cacert);
493
+ g_free(client_key);
494
+ g_free(client_cert);
495
+
496
+ if (ret < 0) {
497
+ vxhs_unref();
498
+ error_propagate(errp, local_err);
499
+ g_free(s->vdisk_hostinfo.host);
500
+ g_free(s->vdisk_guid);
501
+ g_free(s->tlscredsid);
502
+ s->vdisk_guid = NULL;
503
+ }
504
+
505
+ return ret;
506
+}
507
+
508
+static const AIOCBInfo vxhs_aiocb_info = {
509
+ .aiocb_size = sizeof(VXHSAIOCB)
510
+};
511
+
512
+/*
513
+ * This allocates QEMU-VXHS callback for each IO
514
+ * and is passed to QNIO. When QNIO completes the work,
515
+ * it will be passed back through the callback.
516
+ */
517
+static BlockAIOCB *vxhs_aio_rw(BlockDriverState *bs, int64_t sector_num,
518
+ QEMUIOVector *qiov, int nb_sectors,
519
+ BlockCompletionFunc *cb, void *opaque,
520
+ VDISKAIOCmd iodir)
521
+{
522
+ VXHSAIOCB *acb = NULL;
523
+ BDRVVXHSState *s = bs->opaque;
524
+ size_t size;
525
+ uint64_t offset;
526
+ int iio_flags = 0;
527
+ int ret = 0;
528
+ void *dev_handle = s->vdisk_hostinfo.dev_handle;
529
+
530
+ offset = sector_num * BDRV_SECTOR_SIZE;
531
+ size = nb_sectors * BDRV_SECTOR_SIZE;
532
+ acb = qemu_aio_get(&vxhs_aiocb_info, bs, cb, opaque);
533
+
534
+ /*
535
+ * Initialize VXHSAIOCB.
536
+ */
537
+ acb->err = 0;
538
+
539
+ iio_flags = IIO_FLAG_ASYNC;
540
+
541
+ switch (iodir) {
542
+ case VDISK_AIO_WRITE:
543
+ ret = iio_writev(dev_handle, acb, qiov->iov, qiov->niov,
544
+ offset, (uint64_t)size, iio_flags);
545
+ break;
546
+ case VDISK_AIO_READ:
547
+ ret = iio_readv(dev_handle, acb, qiov->iov, qiov->niov,
548
+ offset, (uint64_t)size, iio_flags);
549
+ break;
550
+ default:
551
+ trace_vxhs_aio_rw_invalid(iodir);
552
+ goto errout;
553
+ }
554
+
555
+ if (ret != 0) {
556
+ trace_vxhs_aio_rw_ioerr(s->vdisk_guid, iodir, size, offset,
557
+ acb, ret, errno);
558
+ goto errout;
559
+ }
560
+ return &acb->common;
561
+
562
+errout:
563
+ qemu_aio_unref(acb);
564
+ return NULL;
565
+}
566
+
567
+static BlockAIOCB *vxhs_aio_readv(BlockDriverState *bs,
568
+ int64_t sector_num, QEMUIOVector *qiov,
569
+ int nb_sectors,
570
+ BlockCompletionFunc *cb, void *opaque)
571
+{
572
+ return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors, cb,
573
+ opaque, VDISK_AIO_READ);
574
+}
575
+
576
+static BlockAIOCB *vxhs_aio_writev(BlockDriverState *bs,
577
+ int64_t sector_num, QEMUIOVector *qiov,
578
+ int nb_sectors,
579
+ BlockCompletionFunc *cb, void *opaque)
580
+{
581
+ return vxhs_aio_rw(bs, sector_num, qiov, nb_sectors,
582
+ cb, opaque, VDISK_AIO_WRITE);
583
+}
584
+
585
+static void vxhs_close(BlockDriverState *bs)
586
+{
587
+ BDRVVXHSState *s = bs->opaque;
588
+
589
+ trace_vxhs_close(s->vdisk_guid);
590
+
591
+ g_free(s->vdisk_guid);
592
+ s->vdisk_guid = NULL;
593
+
594
+ /*
595
+ * Close vDisk device
596
+ */
597
+ if (s->vdisk_hostinfo.dev_handle) {
598
+ iio_close(s->vdisk_hostinfo.dev_handle);
599
+ s->vdisk_hostinfo.dev_handle = NULL;
600
+ }
601
+
602
+ vxhs_unref();
603
+
604
+ /*
605
+ * Free the dynamically allocated host string etc
606
+ */
607
+ g_free(s->vdisk_hostinfo.host);
608
+ g_free(s->tlscredsid);
609
+ s->tlscredsid = NULL;
610
+ s->vdisk_hostinfo.host = NULL;
611
+ s->vdisk_hostinfo.port = 0;
612
+}
613
+
614
+static int64_t vxhs_get_vdisk_stat(BDRVVXHSState *s)
615
+{
616
+ int64_t vdisk_size = -1;
617
+ int ret = 0;
618
+ void *dev_handle = s->vdisk_hostinfo.dev_handle;
619
+
620
+ ret = iio_ioctl(dev_handle, IOR_VDISK_STAT, &vdisk_size, 0);
621
+ if (ret < 0) {
622
+ trace_vxhs_get_vdisk_stat_err(s->vdisk_guid, ret, errno);
623
+ return -EIO;
624
+ }
625
+
626
+ trace_vxhs_get_vdisk_stat(s->vdisk_guid, vdisk_size);
627
+ return vdisk_size;
628
+}
629
+
630
+/*
631
+ * Returns the size of vDisk in bytes. This is required
632
+ * by QEMU block upper block layer so that it is visible
633
+ * to guest.
634
+ */
635
+static int64_t vxhs_getlength(BlockDriverState *bs)
636
+{
637
+ BDRVVXHSState *s = bs->opaque;
638
+ int64_t vdisk_size;
639
+
640
+ vdisk_size = vxhs_get_vdisk_stat(s);
641
+ if (vdisk_size < 0) {
642
+ return -EIO;
643
+ }
644
+
645
+ return vdisk_size;
646
+}
647
+
648
+static BlockDriver bdrv_vxhs = {
649
+ .format_name = "vxhs",
650
+ .protocol_name = "vxhs",
651
+ .instance_size = sizeof(BDRVVXHSState),
652
+ .bdrv_file_open = vxhs_open,
653
+ .bdrv_parse_filename = vxhs_parse_filename,
654
+ .bdrv_close = vxhs_close,
655
+ .bdrv_getlength = vxhs_getlength,
656
+ .bdrv_aio_readv = vxhs_aio_readv,
657
+ .bdrv_aio_writev = vxhs_aio_writev,
658
+};
659
+
660
+static void bdrv_vxhs_init(void)
661
+{
662
+ bdrv_register(&bdrv_vxhs);
663
+}
664
+
665
+block_init(bdrv_vxhs_init);
666
diff --git a/configure b/configure
667
index XXXXXXX..XXXXXXX 100755
668
--- a/configure
669
+++ b/configure
670
@@ -XXX,XX +XXX,XX @@ numa=""
671
tcmalloc="no"
672
jemalloc="no"
673
replication="yes"
674
+vxhs=""
675
676
supported_cpu="no"
677
supported_os="no"
678
@@ -XXX,XX +XXX,XX @@ for opt do
679
;;
680
--enable-replication) replication="yes"
681
;;
682
+ --disable-vxhs) vxhs="no"
683
+ ;;
684
+ --enable-vxhs) vxhs="yes"
685
+ ;;
686
*)
687
echo "ERROR: unknown option $opt"
688
echo "Try '$0 --help' for more information"
689
@@ -XXX,XX +XXX,XX @@ disabled with --disable-FEATURE, default is enabled if available:
690
xfsctl xfsctl support
691
qom-cast-debug cast debugging support
692
tools build qemu-io, qemu-nbd and qemu-image tools
693
+ vxhs Veritas HyperScale vDisk backend support
694
695
NOTE: The object files are built at the place where configure is launched
696
EOF
697
@@ -XXX,XX +XXX,XX @@ if compile_prog "" "" ; then
698
fi
699
700
##########################################
701
+# Veritas HyperScale block driver VxHS
702
+# Check if libvxhs is installed
703
+
704
+if test "$vxhs" != "no" ; then
705
+ cat > $TMPC <<EOF
706
+#include <stdint.h>
707
+#include <qnio/qnio_api.h>
708
+
709
+void *vxhs_callback;
710
+
711
+int main(void) {
712
+ iio_init(QNIO_VERSION, vxhs_callback);
713
+ return 0;
714
+}
715
+EOF
716
+ vxhs_libs="-lvxhs -lssl"
717
+ if compile_prog "" "$vxhs_libs" ; then
718
+ vxhs=yes
719
+ else
720
+ if test "$vxhs" = "yes" ; then
721
+ feature_not_found "vxhs block device" "Install libvxhs See github"
722
+ fi
723
+ vxhs=no
724
+ fi
725
+fi
726
+
727
+##########################################
728
# End of CC checks
729
# After here, no more $cc or $ld runs
730
731
@@ -XXX,XX +XXX,XX @@ echo "tcmalloc support $tcmalloc"
732
echo "jemalloc support $jemalloc"
733
echo "avx2 optimization $avx2_opt"
734
echo "replication support $replication"
735
+echo "VxHS block device $vxhs"
736
737
if test "$sdl_too_old" = "yes"; then
738
echo "-> Your SDL version is too old - please upgrade to have SDL support"
739
@@ -XXX,XX +XXX,XX @@ if test "$pthread_setname_np" = "yes" ; then
740
echo "CONFIG_PTHREAD_SETNAME_NP=y" >> $config_host_mak
741
fi
742
743
+if test "$vxhs" = "yes" ; then
744
+ echo "CONFIG_VXHS=y" >> $config_host_mak
745
+ echo "VXHS_LIBS=$vxhs_libs" >> $config_host_mak
746
+fi
747
+
748
if test "$tcg_interpreter" = "yes"; then
749
QEMU_INCLUDES="-I\$(SRC_PATH)/tcg/tci $QEMU_INCLUDES"
750
elif test "$ARCH" = "sparc64" ; then
751
diff --git a/qapi/block-core.json b/qapi/block-core.json
752
index XXXXXXX..XXXXXXX 100644
753
--- a/qapi/block-core.json
754
+++ b/qapi/block-core.json
755
@@ -XXX,XX +XXX,XX @@
756
#
757
# Drivers that are supported in block device operations.
758
#
759
+# @vxhs: Since 2.10
760
+#
761
# Since: 2.9
762
##
763
{ 'enum': 'BlockdevDriver',
764
@@ -XXX,XX +XXX,XX @@
765
'host_device', 'http', 'https', 'iscsi', 'luks', 'nbd', 'nfs',
766
'null-aio', 'null-co', 'parallels', 'qcow', 'qcow2', 'qed',
767
'quorum', 'raw', 'rbd', 'replication', 'sheepdog', 'ssh',
768
- 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat' ] }
769
+ 'vdi', 'vhdx', 'vmdk', 'vpc', 'vvfat', 'vxhs' ] }
770
771
##
772
# @BlockdevOptionsFile:
773
@@ -XXX,XX +XXX,XX @@
774
'data': { '*offset': 'int', '*size': 'int' } }
775
776
##
777
+# @BlockdevOptionsVxHS:
778
+#
779
+# Driver specific block device options for VxHS
780
+#
781
+# @vdisk-id: UUID of VxHS volume
782
+# @server: vxhs server IP, port
783
+# @tls-creds: TLS credentials ID
784
+#
785
+# Since: 2.10
786
+##
787
+{ 'struct': 'BlockdevOptionsVxHS',
788
+ 'data': { 'vdisk-id': 'str',
789
+ 'server': 'InetSocketAddressBase',
790
+ '*tls-creds': 'str' } }
791
+
792
+##
793
# @BlockdevOptions:
794
#
795
# Options for creating a block device. Many options are available for all
796
@@ -XXX,XX +XXX,XX @@
797
'vhdx': 'BlockdevOptionsGenericFormat',
798
'vmdk': 'BlockdevOptionsGenericCOWFormat',
799
'vpc': 'BlockdevOptionsGenericFormat',
800
- 'vvfat': 'BlockdevOptionsVVFAT'
801
+ 'vvfat': 'BlockdevOptionsVVFAT',
802
+ 'vxhs': 'BlockdevOptionsVxHS'
803
} }
804
805
##
806
--
807
2.9.3
808
809
diff view generated by jsdifflib
Deleted patch
1
From: Ashish Mittal <ashmit602@gmail.com>
2
1
3
These changes use a vxhs test server that is a part of the following
4
repository:
5
https://github.com/VeritasHyperScale/libqnio.git
6
7
Signed-off-by: Ashish Mittal <Ashish.Mittal@veritas.com>
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Reviewed-by: Jeff Cody <jcody@redhat.com>
10
Signed-off-by: Jeff Cody <jcody@redhat.com>
11
Message-id: 1491277689-24949-3-git-send-email-Ashish.Mittal@veritas.com
12
---
13
tests/qemu-iotests/common | 6 ++++++
14
tests/qemu-iotests/common.config | 13 +++++++++++++
15
tests/qemu-iotests/common.filter | 1 +
16
tests/qemu-iotests/common.rc | 19 +++++++++++++++++++
17
4 files changed, 39 insertions(+)
18
19
diff --git a/tests/qemu-iotests/common b/tests/qemu-iotests/common
20
index XXXXXXX..XXXXXXX 100644
21
--- a/tests/qemu-iotests/common
22
+++ b/tests/qemu-iotests/common
23
@@ -XXX,XX +XXX,XX @@ check options
24
-ssh test ssh
25
-nfs test nfs
26
-luks test luks
27
+ -vxhs test vxhs
28
-xdiff graphical mode diff
29
-nocache use O_DIRECT on backing file
30
-misalign misalign memory allocations
31
@@ -XXX,XX +XXX,XX @@ testlist options
32
xpand=false
33
;;
34
35
+ -vxhs)
36
+ IMGPROTO=vxhs
37
+ xpand=false
38
+ ;;
39
+
40
-ssh)
41
IMGPROTO=ssh
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
{
57
(
58
@@ -XXX,XX +XXX,XX @@ _qemu_nbd_wrapper()
59
)
60
}
61
62
+_qemu_vxhs_wrapper()
63
+{
64
+ (
65
+ echo $BASHPID > "${TEST_DIR}/qemu-vxhs.pid"
66
+ exec "$QEMU_VXHS_PROG" $QEMU_VXHS_OPTIONS "$@"
67
+ )
68
+}
69
+
70
export QEMU=_qemu_wrapper
71
export QEMU_IMG=_qemu_img_wrapper
72
export QEMU_IO=_qemu_io_wrapper
73
export QEMU_NBD=_qemu_nbd_wrapper
74
+export QEMU_VXHS=_qemu_vxhs_wrapper
75
76
QEMU_IMG_EXTRA_ARGS=
77
if [ "$IMGOPTSSYNTAX" = "true" ]; then
78
diff --git a/tests/qemu-iotests/common.filter b/tests/qemu-iotests/common.filter
79
index XXXXXXX..XXXXXXX 100644
80
--- a/tests/qemu-iotests/common.filter
81
+++ b/tests/qemu-iotests/common.filter
82
@@ -XXX,XX +XXX,XX @@ _filter_img_info()
83
-e "s#$TEST_DIR#TEST_DIR#g" \
84
-e "s#$IMGFMT#IMGFMT#g" \
85
-e 's#nbd://127.0.0.1:10810$#TEST_DIR/t.IMGFMT#g' \
86
+ -e 's#json.*vdisk-id.*vxhs"}}#TEST_DIR/t.IMGFMT#' \
87
-e "/encrypted: yes/d" \
88
-e "/cluster_size: [0-9]\\+/d" \
89
-e "/table_size: [0-9]\\+/d" \
90
diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc
91
index XXXXXXX..XXXXXXX 100644
92
--- a/tests/qemu-iotests/common.rc
93
+++ b/tests/qemu-iotests/common.rc
94
@@ -XXX,XX +XXX,XX @@ else
95
elif [ "$IMGPROTO" = "nfs" ]; then
96
TEST_DIR="nfs://127.0.0.1/$TEST_DIR"
97
TEST_IMG=$TEST_DIR/t.$IMGFMT
98
+ elif [ "$IMGPROTO" = "vxhs" ]; then
99
+ TEST_IMG_FILE=$TEST_DIR/t.$IMGFMT
100
+ TEST_IMG="vxhs://127.0.0.1:9999/t.$IMGFMT"
101
else
102
TEST_IMG=$IMGPROTO:$TEST_DIR/t.$IMGFMT
103
fi
104
@@ -XXX,XX +XXX,XX @@ _make_test_img()
105
eval "$QEMU_NBD -v -t -b 127.0.0.1 -p 10810 -f $IMGFMT $TEST_IMG_FILE >/dev/null &"
106
sleep 1 # FIXME: qemu-nbd needs to be listening before we continue
107
fi
108
+
109
+ # Start QNIO server on image directory for vxhs protocol
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
--
135
2.9.3
136
137
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
We have a helper wrapper for checking for the BDS read_only flag,
1
test_multi_co_schedule_entry() set to_schedule[id] in the final loop
2
add a helper wrapper to set the read_only flag as well.
2
iteration before terminating the coroutine. There is a race condition
3
where the main thread attempts to enter the terminating or terminated
4
coroutine when signalling coroutines to stop:
3
5
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
atomic_mb_set(&now_stopping, true);
5
Signed-off-by: Jeff Cody <jcody@redhat.com>
7
for (i = 0; i < NUM_CONTEXTS; i++) {
6
Reviewed-by: John Snow <jsnow@redhat.com>
8
ctx_run(i, finish_cb, NULL); <--- enters dead coroutine!
7
Message-id: 9b18972d05f5fa2ac16c014f0af98d680553048d.1491597120.git.jcody@redhat.com
9
to_schedule[i] = NULL;
10
}
11
12
Make sure only to set to_schedule[id] if this coroutine really needs to
13
be scheduled!
14
15
Reported-by: "R.Nageswara Sastry" <nasastry@in.ibm.com>
16
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
17
Reviewed-by: Paolo Bonzini <pbonzini@redhat.com>
18
Message-id: 20171106190233.1175-1-stefanha@redhat.com
19
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
8
---
20
---
9
block.c | 5 +++++
21
tests/test-aio-multithread.c | 5 ++---
10
block/bochs.c | 2 +-
22
1 file changed, 2 insertions(+), 3 deletions(-)
11
block/cloop.c | 2 +-
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
23
18
diff --git a/block.c b/block.c
24
diff --git a/tests/test-aio-multithread.c b/tests/test-aio-multithread.c
19
index XXXXXXX..XXXXXXX 100644
25
index XXXXXXX..XXXXXXX 100644
20
--- a/block.c
26
--- a/tests/test-aio-multithread.c
21
+++ b/block.c
27
+++ b/tests/test-aio-multithread.c
22
@@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size,
28
@@ -XXX,XX +XXX,XX @@ static void finish_cb(void *opaque)
29
static coroutine_fn void test_multi_co_schedule_entry(void *opaque)
30
{
31
g_assert(to_schedule[id] == NULL);
32
- atomic_mb_set(&to_schedule[id], qemu_coroutine_self());
33
34
while (!atomic_mb_read(&now_stopping)) {
35
int n;
36
37
n = g_test_rand_int_range(0, NUM_CONTEXTS);
38
schedule_next(n);
39
+
40
+ atomic_mb_set(&to_schedule[id], qemu_coroutine_self());
41
qemu_coroutine_yield();
42
-
43
g_assert(to_schedule[id] == NULL);
44
- atomic_mb_set(&to_schedule[id], qemu_coroutine_self());
23
}
45
}
24
}
46
}
25
47
26
+void bdrv_set_read_only(BlockDriverState *bs, bool read_only)
27
+{
28
+ bs->read_only = read_only;
29
+}
30
+
31
void bdrv_get_full_backing_filename_from_filename(const char *backed,
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
}
41
42
- bs->read_only = true; /* no write support yet */
43
+ bdrv_set_read_only(bs, true); /* no write support yet */
44
45
ret = bdrv_pread(bs->file, 0, &bochs, sizeof(bochs));
46
if (ret < 0) {
47
diff --git a/block/cloop.c b/block/cloop.c
48
index XXXXXXX..XXXXXXX 100644
49
--- a/block/cloop.c
50
+++ b/block/cloop.c
51
@@ -XXX,XX +XXX,XX @@ static int cloop_open(BlockDriverState *bs, QDict *options, int flags,
52
return -EINVAL;
53
}
54
55
- bs->read_only = true;
56
+ bdrv_set_read_only(bs, true);
57
58
/* read header */
59
ret = bdrv_pread(bs->file, 128, &s->block_size, 4);
60
diff --git a/block/dmg.c b/block/dmg.c
61
index XXXXXXX..XXXXXXX 100644
62
--- a/block/dmg.c
63
+++ b/block/dmg.c
64
@@ -XXX,XX +XXX,XX @@ static int dmg_open(BlockDriverState *bs, QDict *options, int flags,
65
}
66
67
block_module_load_one("dmg-bz2");
68
- bs->read_only = true;
69
+ bdrv_set_read_only(bs, true);
70
71
s->n_chunks = 0;
72
s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
73
diff --git a/block/rbd.c b/block/rbd.c
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
--
48
--
121
2.9.3
49
2.13.6
122
50
123
51
diff view generated by jsdifflib
Deleted patch
1
A few block drivers will set the BDS read_only flag from their
2
.bdrv_open() function. This means the bs->read_only flag could
3
be set after we enable copy_on_read, as the BDRV_O_COPY_ON_READ
4
flag check occurs prior to the call to bdrv->bdrv_open().
5
1
6
This adds an error return to bdrv_set_read_only(), and an error will be
7
return if we try to set the BDS to read_only while copy_on_read is
8
enabled.
9
10
This patch also changes the behavior of vvfat. Before, vvfat could
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
36
--- a/block.c
37
+++ b/block.c
38
@@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size,
39
}
40
}
41
42
-void bdrv_set_read_only(BlockDriverState *bs, bool read_only)
43
+int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
44
{
45
+ /* Do not set read_only if copy_on_read is enabled */
46
+ if (bs->copy_on_read && read_only) {
47
+ error_setg(errp, "Can't set node '%s' to r/o with copy-on-read enabled",
48
+ bdrv_get_device_or_node_name(bs));
49
+ return -EINVAL;
50
+ }
51
+
52
bs->read_only = read_only;
53
+ return 0;
54
}
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
+ }
101
+
102
block_module_load_one("dmg-bz2");
103
- bdrv_set_read_only(bs, true);
104
105
s->n_chunks = 0;
106
s->offsets = s->lengths = s->sectors = s->sectorcounts = NULL;
107
diff --git a/block/rbd.c b/block/rbd.c
108
index XXXXXXX..XXXXXXX 100644
109
--- a/block/rbd.c
110
+++ b/block/rbd.c
111
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
112
goto failed_shutdown;
113
}
114
115
+ /* rbd_open is always r/w */
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
--
189
2.9.3
190
191
diff view generated by jsdifflib
Deleted patch
1
The BDRV_O_ALLOW_RDWR flag allows / prohibits the changing of
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
1
6
Signed-off-by: Jeff Cody <jcody@redhat.com>
7
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Message-id: be2e5fb2d285cbece2b6d06bed54a6f56520d251.1491597120.git.jcody@redhat.com
10
---
11
block.c | 7 +++++++
12
1 file changed, 7 insertions(+)
13
14
diff --git a/block.c b/block.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block.c
17
+++ b/block.c
18
@@ -XXX,XX +XXX,XX @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
19
return -EINVAL;
20
}
21
22
+ /* Do not clear read_only if it is prohibited */
23
+ if (!read_only && !(bs->open_flags & BDRV_O_ALLOW_RDWR)) {
24
+ error_setg(errp, "Node '%s' is read only",
25
+ bdrv_get_device_or_node_name(bs));
26
+ return -EPERM;
27
+ }
28
+
29
bs->read_only = read_only;
30
return 0;
31
}
32
--
33
2.9.3
34
35
diff view generated by jsdifflib
Deleted patch
1
Move bdrv_is_read_only() up with its friends.
2
1
3
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
4
Reviewed-by: John Snow <jsnow@redhat.com>
5
Signed-off-by: Jeff Cody <jcody@redhat.com>
6
Message-id: 73b2399459760c32506f9407efb9dddb3a2789de.1491597120.git.jcody@redhat.com
7
---
8
block.c | 10 +++++-----
9
1 file changed, 5 insertions(+), 5 deletions(-)
10
11
diff --git a/block.c b/block.c
12
index XXXXXXX..XXXXXXX 100644
13
--- a/block.c
14
+++ b/block.c
15
@@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size,
16
}
17
}
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
--
40
2.9.3
41
42
diff view generated by jsdifflib
Deleted patch
1
Introduce check function for setting read_only flags. Will return < 0 on
2
error, with appropriate Error value set. Does not alter any flags.
3
1
4
Signed-off-by: Jeff Cody <jcody@redhat.com>
5
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
Reviewed-by: John Snow <jsnow@redhat.com>
7
Message-id: e2bba34ac3bc76a0c42adc390413f358ae0566e8.1491597120.git.jcody@redhat.com
8
---
9
block.c | 14 +++++++++++++-
10
include/block/block.h | 1 +
11
2 files changed, 14 insertions(+), 1 deletion(-)
12
13
diff --git a/block.c b/block.c
14
index XXXXXXX..XXXXXXX 100644
15
--- a/block.c
16
+++ b/block.c
17
@@ -XXX,XX +XXX,XX @@ bool bdrv_is_read_only(BlockDriverState *bs)
18
return bs->read_only;
19
}
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
{
24
/* Do not set read_only if copy_on_read is enabled */
25
if (bs->copy_on_read && read_only) {
26
@@ -XXX,XX +XXX,XX @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
27
return -EPERM;
28
}
29
30
+ return 0;
31
+}
32
+
33
+int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
34
+{
35
+ int ret = 0;
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
--
58
2.9.3
59
60
diff view generated by jsdifflib
Deleted patch
1
Signed-off-by: Jeff Cody <jcody@redhat.com>
2
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
3
Reviewed-by: John Snow <jsnow@redhat.com>
4
Message-id: 00aed7ffdd7be4b9ed9ce1007d50028a72b34ebe.1491597120.git.jcody@redhat.com
5
---
6
block.c | 14 ++++++++------
7
1 file changed, 8 insertions(+), 6 deletions(-)
8
1
9
diff --git a/block.c b/block.c
10
index XXXXXXX..XXXXXXX 100644
11
--- a/block.c
12
+++ b/block.c
13
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
14
BlockDriver *drv;
15
QemuOpts *opts;
16
const char *value;
17
+ bool read_only;
18
19
assert(reopen_state != NULL);
20
assert(reopen_state->bs->drv != NULL);
21
@@ -XXX,XX +XXX,XX @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
22
qdict_put(reopen_state->options, "driver", qstring_from_str(value));
23
}
24
25
- /* if we are to stay read-only, do not allow permission change
26
- * to r/w */
27
- if (!(reopen_state->bs->open_flags & BDRV_O_ALLOW_RDWR) &&
28
- reopen_state->flags & BDRV_O_RDWR) {
29
- error_setg(errp, "Node '%s' is read only",
30
- bdrv_get_device_or_node_name(reopen_state->bs));
31
+ /* If we are to stay read-only, do not allow permission change
32
+ * to r/w. Attempting to set to r/w may fail if either BDRV_O_ALLOW_RDWR is
33
+ * not set, or if the BDS still has copy_on_read enabled */
34
+ read_only = !(reopen_state->flags & BDRV_O_RDWR);
35
+ ret = bdrv_can_set_read_only(reopen_state->bs, read_only, &local_err);
36
+ if (local_err) {
37
+ error_propagate(errp, local_err);
38
goto error;
39
}
40
41
--
42
2.9.3
43
44
diff view generated by jsdifflib
Deleted patch
1
Update 'clientname' to be 'user', which tracks better with both
2
the QAPI and rados variable naming.
3
1
4
Update 'name' to be 'image_name', as it indicates the rbd image.
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
8
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
9
Signed-off-by: Jeff Cody <jcody@redhat.com>
10
Reviewed-by: John Snow <jsnow@redhat.com>
11
Message-id: b7ec1fb2e1cf36f9b6911631447a5b0422590b7d.1491597120.git.jcody@redhat.com
12
---
13
block/rbd.c | 33 +++++++++++++++++----------------
14
1 file changed, 17 insertions(+), 16 deletions(-)
15
16
diff --git a/block/rbd.c b/block/rbd.c
17
index XXXXXXX..XXXXXXX 100644
18
--- a/block/rbd.c
19
+++ b/block/rbd.c
20
@@ -XXX,XX +XXX,XX @@ typedef struct BDRVRBDState {
21
rados_t cluster;
22
rados_ioctx_t io_ctx;
23
rbd_image_t image;
24
- char *name;
25
+ char *image_name;
26
char *snap;
27
} BDRVRBDState;
28
29
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
30
int64_t bytes = 0;
31
int64_t objsize;
32
int obj_order = 0;
33
- const char *pool, *name, *conf, *clientname, *keypairs;
34
+ const char *pool, *image_name, *conf, *user, *keypairs;
35
const char *secretid;
36
rados_t cluster;
37
rados_ioctx_t io_ctx;
38
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
39
*/
40
pool = qdict_get_try_str(options, "pool");
41
conf = qdict_get_try_str(options, "conf");
42
- clientname = qdict_get_try_str(options, "user");
43
- name = qdict_get_try_str(options, "image");
44
+ user = qdict_get_try_str(options, "user");
45
+ image_name = qdict_get_try_str(options, "image");
46
keypairs = qdict_get_try_str(options, "=keyvalue-pairs");
47
48
- ret = rados_create(&cluster, clientname);
49
+ ret = rados_create(&cluster, user);
50
if (ret < 0) {
51
error_setg_errno(errp, -ret, "error initializing");
52
goto exit;
53
@@ -XXX,XX +XXX,XX @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
54
goto shutdown;
55
}
56
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
--
133
2.9.3
134
135
diff view generated by jsdifflib
1
This adds support for reopen in rbd, for changing between r/w and r/o.
1
From: Sergio Lopez <slp@redhat.com>
2
2
3
Note, that this is only a flag change, but we will block a change from
3
Commit b7a745d added a qemu_bh_cancel call to the completion function
4
r/o to r/w if we are using an RBD internal snapshot.
4
as an optimization to prevent it from unnecessarily rescheduling itself.
5
5
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
6
This completion function is scheduled from worker_thread, after setting
7
Signed-off-by: Jeff Cody <jcody@redhat.com>
7
the state of a ThreadPoolElement to THREAD_DONE.
8
Reviewed-by: John Snow <jsnow@redhat.com>
8
9
Message-id: d4e87539167ec6527d44c97b164eabcccf96e4f3.1491597120.git.jcody@redhat.com
9
This was considered to be safe, as the completion function restarts the
10
loop just after the call to qemu_bh_cancel. But, as this loop lacks a HW
11
memory barrier, the read of req->state may actually happen _before_ the
12
call, seeing it still as THREAD_QUEUED, and ending the completion
13
function without having processed a pending TPE linked at pool->head:
14
15
worker thread | I/O thread
16
------------------------------------------------------------------------
17
| speculatively read req->state
18
req->state = THREAD_DONE; |
19
qemu_bh_schedule(p->completion_bh) |
20
bh->scheduled = 1; |
21
| qemu_bh_cancel(p->completion_bh)
22
| bh->scheduled = 0;
23
| if (req->state == THREAD_DONE)
24
| // sees THREAD_QUEUED
25
26
The source of the misunderstanding was that qemu_bh_cancel is now being
27
used by the _consumer_ rather than the producer, and therefore now needs
28
to have acquire semantics just like e.g. aio_bh_poll.
29
30
In some situations, if there are no other independent requests in the
31
same aio context that could eventually trigger the scheduling of the
32
completion function, the omitted TPE and all operations pending on it
33
will get stuck forever.
34
35
[Added Sergio's updated wording about the HW memory barrier.
36
--Stefan]
37
38
Signed-off-by: Sergio Lopez <slp@redhat.com>
39
Message-id: 20171108063447.2842-1-slp@redhat.com
40
Signed-off-by: Stefan Hajnoczi <stefanha@redhat.com>
10
---
41
---
11
block/rbd.c | 21 +++++++++++++++++++++
42
util/async.c | 2 +-
12
1 file changed, 21 insertions(+)
43
1 file changed, 1 insertion(+), 1 deletion(-)
13
44
14
diff --git a/block/rbd.c b/block/rbd.c
45
diff --git a/util/async.c b/util/async.c
15
index XXXXXXX..XXXXXXX 100644
46
index XXXXXXX..XXXXXXX 100644
16
--- a/block/rbd.c
47
--- a/util/async.c
17
+++ b/block/rbd.c
48
+++ b/util/async.c
18
@@ -XXX,XX +XXX,XX @@ failed_opts:
49
@@ -XXX,XX +XXX,XX @@ void qemu_bh_schedule(QEMUBH *bh)
19
return r;
50
*/
51
void qemu_bh_cancel(QEMUBH *bh)
52
{
53
- bh->scheduled = 0;
54
+ atomic_mb_set(&bh->scheduled, 0);
20
}
55
}
21
56
22
+
57
/* This func is async.The bottom half will do the delete action at the finial
23
+/* Since RBD is currently always opened R/W via the API,
24
+ * we just need to check if we are using a snapshot or not, in
25
+ * order to determine if we will allow it to be R/W */
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
--
58
--
54
2.9.3
59
2.13.6
55
60
56
61
diff view generated by jsdifflib
Deleted patch
1
For the tests that use the common.qemu functions for running a QEMU
2
process, _cleanup_qemu must be called in the exit function.
3
1
4
If it is not, if the qemu process aborts, then not all of the droppings
5
are cleaned up (e.g. pidfile, fifos).
6
7
This updates those tests that did not have a cleanup in qemu-iotests.
8
9
(I swapped spaces for tabs in test 102 as well)
10
11
Reported-by: Eric Blake <eblake@redhat.com>
12
Reviewed-by: Eric Blake <eblake@redhat.com>
13
Signed-off-by: Jeff Cody <jcody@redhat.com>
14
Message-id: d59c2f6ad6c1da8b9b3c7f357c94a7122ccfc55a.1492544096.git.jcody@redhat.com
15
---
16
tests/qemu-iotests/028 | 1 +
17
tests/qemu-iotests/094 | 11 ++++++++---
18
tests/qemu-iotests/102 | 5 +++--
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
{
36
+ _cleanup_qemu
37
rm -f "${TEST_IMG}.copy"
38
_cleanup_test_img
39
}
40
diff --git a/tests/qemu-iotests/094 b/tests/qemu-iotests/094
41
index XXXXXXX..XXXXXXX 100755
42
--- a/tests/qemu-iotests/094
43
+++ b/tests/qemu-iotests/094
44
@@ -XXX,XX +XXX,XX @@ echo "QA output created by $seq"
45
here="$PWD"
46
status=1    # failure is the default!
47
48
-trap "exit \$status" 0 1 2 3 15
49
+_cleanup()
50
+{
51
+ _cleanup_qemu
52
+ _cleanup_test_img
53
+ rm -f "$TEST_DIR/source.$IMGFMT"
54
+}
55
+
56
+trap "_cleanup; exit \$status" 0 1 2 3 15
57
58
# get standard environment, filters and checks
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
{
82
-    _cleanup_test_img
83
+ _cleanup_qemu
84
+ _cleanup_test_img
85
}
86
trap "_cleanup; exit \$status" 0 1 2 3 15
87
88
diff --git a/tests/qemu-iotests/109 b/tests/qemu-iotests/109
89
index XXXXXXX..XXXXXXX 100755
90
--- a/tests/qemu-iotests/109
91
+++ b/tests/qemu-iotests/109
92
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
93
94
_cleanup()
95
{
96
+ _cleanup_qemu
97
rm -f $TEST_IMG.src
98
    _cleanup_test_img
99
}
100
diff --git a/tests/qemu-iotests/117 b/tests/qemu-iotests/117
101
index XXXXXXX..XXXXXXX 100755
102
--- a/tests/qemu-iotests/117
103
+++ b/tests/qemu-iotests/117
104
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
105
106
_cleanup()
107
{
108
+ _cleanup_qemu
109
    _cleanup_test_img
110
}
111
trap "_cleanup; exit \$status" 0 1 2 3 15
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
--
173
2.9.3
174
175
diff view generated by jsdifflib