1
The following changes since commit d84f714eafedd8bb9d4aaec8b76417bef8e3535e:
1
The following changes since commit bfec359afba088aaacc7d316f43302f28c6e642a:
2
2
3
Update version for v2.9.0-rc0 release (2017-03-14 19:18:23 +0000)
3
Merge remote-tracking branch 'remotes/armbru/tags/pull-qdev-2017-04-21' into staging (2017-04-21 11:42:03 +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/stefanha/qemu.git tags/block-pull-request
7
git://github.com/codyprime/qemu-kvm-jtc.git tags/block-pull-request
8
8
9
for you to fetch changes up to 9dc44aa5829eb3131a01378a738dee28a382bbc1:
9
for you to fetch changes up to 1507631e438930bc07f776f303af127a9cdb4d41:
10
10
11
os: don't corrupt pre-existing memory-backend data with prealloc (2017-03-15 11:55:41 +0800)
11
qemu-iotests: _cleanup_qemu must be called on exit (2017-04-21 08:32:44 -0400)
12
12
13
----------------------------------------------------------------
13
----------------------------------------------------------------
14
14
15
Block patches for 2.10
16
15
----------------------------------------------------------------
17
----------------------------------------------------------------
16
18
17
Daniel P. Berrange (1):
19
Ashish Mittal (2):
18
os: don't corrupt pre-existing memory-backend data with prealloc
20
block/vxhs.c: Add support for a new block device type called "vxhs"
21
block/vxhs.c: Add qemu-iotests for new block device type "vxhs"
19
22
20
util/oslib-posix.c | 14 +++++++++++++-
23
Jeff Cody (10):
21
1 file changed, 13 insertions(+), 1 deletion(-)
24
qemu-iotests: exclude vxhs from image creation via protocol
25
block: add bdrv_set_read_only() helper function
26
block: do not set BDS read_only if copy_on_read enabled
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
35
block.c | 56 +++-
36
block/Makefile.objs | 2 +
37
block/bochs.c | 5 +-
38
block/cloop.c | 5 +-
39
block/dmg.c | 6 +-
40
block/rbd.c | 65 +++--
41
block/trace-events | 17 ++
42
block/vvfat.c | 19 +-
43
block/vxhs.c | 575 +++++++++++++++++++++++++++++++++++++++
44
configure | 39 +++
45
include/block/block.h | 2 +
46
qapi/block-core.json | 23 +-
47
tests/qemu-iotests/017 | 1 +
48
tests/qemu-iotests/020 | 1 +
49
tests/qemu-iotests/028 | 1 +
50
tests/qemu-iotests/029 | 1 +
51
tests/qemu-iotests/073 | 1 +
52
tests/qemu-iotests/094 | 11 +-
53
tests/qemu-iotests/102 | 5 +-
54
tests/qemu-iotests/109 | 1 +
55
tests/qemu-iotests/114 | 1 +
56
tests/qemu-iotests/117 | 1 +
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
22
70
23
--
71
--
24
2.9.3
72
2.9.3
25
73
26
74
diff view generated by jsdifflib
New patch
1
From: Ashish Mittal <ashmit602@gmail.com>
1
2
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
Signed-off-by: Ashish Mittal <Ashish.Mittal@veritas.com>
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
40
--- a/block/Makefile.objs
41
+++ b/block/Makefile.objs
42
@@ -XXX,XX +XXX,XX @@ block-obj-$(CONFIG_LIBNFS) += nfs.o
43
block-obj-$(CONFIG_CURL) += curl.o
44
block-obj-$(CONFIG_RBD) += rbd.o
45
block-obj-$(CONFIG_GLUSTERFS) += gluster.o
46
+block-obj-$(CONFIG_VXHS) += vxhs.o
47
block-obj-$(CONFIG_LIBSSH2) += ssh.o
48
block-obj-y += accounting.o dirty-bitmap.o
49
block-obj-y += write-threshold.o
50
@@ -XXX,XX +XXX,XX @@ rbd.o-cflags := $(RBD_CFLAGS)
51
rbd.o-libs := $(RBD_LIBS)
52
gluster.o-cflags := $(GLUSTERFS_CFLAGS)
53
gluster.o-libs := $(GLUSTERFS_LIBS)
54
+vxhs.o-libs := $(VXHS_LIBS)
55
ssh.o-cflags := $(LIBSSH2_CFLAGS)
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
+ }
356
+
357
+ /*
358
+ * Get the cacert, client_cert and client_key file names.
359
+ */
360
+ if (!creds->dir) {
361
+ error_setg(errp, "TLS object missing 'dir' property value");
362
+ return;
363
+ }
364
+
365
+ *cacert = g_strdup_printf("%s/%s", creds->dir,
366
+ QCRYPTO_TLS_CREDS_X509_CA_CERT);
367
+ *cert = g_strdup_printf("%s/%s", creds->dir,
368
+ QCRYPTO_TLS_CREDS_X509_CLIENT_CERT);
369
+ *key = g_strdup_printf("%s/%s", creds->dir,
370
+ QCRYPTO_TLS_CREDS_X509_CLIENT_KEY);
371
+}
372
+
373
+static int vxhs_open(BlockDriverState *bs, QDict *options,
374
+ int bdrv_flags, Error **errp)
375
+{
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
--
805
2.9.3
806
807
diff view generated by jsdifflib
New patch
1
From: Ashish Mittal <ashmit602@gmail.com>
1
2
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
New 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.
1
4
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
New patch
1
We have a helper wrapper for checking for the BDS read_only flag,
2
add a helper wrapper to set the read_only flag as well.
1
3
4
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
5
Signed-off-by: Jeff Cody <jcody@redhat.com>
6
Reviewed-by: John Snow <jsnow@redhat.com>
7
Message-id: 9b18972d05f5fa2ac16c014f0af98d680553048d.1491597120.git.jcody@redhat.com
8
---
9
block.c | 5 +++++
10
block/bochs.c | 2 +-
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
18
diff --git a/block.c b/block.c
19
index XXXXXXX..XXXXXXX 100644
20
--- a/block.c
21
+++ b/block.c
22
@@ -XXX,XX +XXX,XX @@ void path_combine(char *dest, int dest_size,
23
}
24
}
25
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
--
121
2.9.3
122
123
diff view generated by jsdifflib
New 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().
1
5
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
New 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.
1
5
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
New patch
1
Move bdrv_is_read_only() up with its friends.
1
2
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
New 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.
1
3
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
New 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(-)
1
8
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
New patch
1
Update 'clientname' to be 'user', which tracks better with both
2
the QAPI and rados variable naming.
1
3
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
New patch
1
This adds support for reopen in rbd, for changing between r/w and r/o.
1
2
3
Note, that this is only a flag change, but we will block a change from
4
r/o to r/w if we are using an RBD internal snapshot.
5
6
Reviewed-by: Stefan Hajnoczi <stefanha@redhat.com>
7
Signed-off-by: Jeff Cody <jcody@redhat.com>
8
Reviewed-by: John Snow <jsnow@redhat.com>
9
Message-id: d4e87539167ec6527d44c97b164eabcccf96e4f3.1491597120.git.jcody@redhat.com
10
---
11
block/rbd.c | 21 +++++++++++++++++++++
12
1 file changed, 21 insertions(+)
13
14
diff --git a/block/rbd.c b/block/rbd.c
15
index XXXXXXX..XXXXXXX 100644
16
--- a/block/rbd.c
17
+++ b/block/rbd.c
18
@@ -XXX,XX +XXX,XX @@ failed_opts:
19
return r;
20
}
21
22
+
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
--
54
2.9.3
55
56
diff view generated by jsdifflib
1
From: "Daniel P. Berrange" <berrange@redhat.com>
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.
2
3
3
When using a memory-backend object with prealloc turned on, QEMU
4
If it is not, if the qemu process aborts, then not all of the droppings
4
will memset() the first byte in every memory page to zero. While
5
are cleaned up (e.g. pidfile, fifos).
5
this might have been acceptable for memory backends associated
6
with RAM, this corrupts application data for NVDIMMs.
7
6
8
Instead of setting every page to zero, read the current byte
7
This updates those tests that did not have a cleanup in qemu-iotests.
9
value and then just write that same value back, so we are not
10
corrupting the original data. Directly write the value instead
11
of memset()ing it, since there's no benefit to memset for a
12
single byte write.
13
8
14
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
9
(I swapped spaces for tabs in test 102 as well)
15
Reviewed-by: Andrea Arcangeli <aarcange@redhat.com>
10
16
Message-id: 20170303113255.28262-1-berrange@redhat.com
11
Reported-by: Eric Blake <eblake@redhat.com>
17
Signed-off-by: Stefan Hajnoczi <stefanha@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
18
---
15
---
19
util/oslib-posix.c | 14 +++++++++++++-
16
tests/qemu-iotests/028 | 1 +
20
1 file changed, 13 insertions(+), 1 deletion(-)
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(-)
21
27
22
diff --git a/util/oslib-posix.c b/util/oslib-posix.c
28
diff --git a/tests/qemu-iotests/028 b/tests/qemu-iotests/028
23
index XXXXXXX..XXXXXXX 100644
29
index XXXXXXX..XXXXXXX 100755
24
--- a/util/oslib-posix.c
30
--- a/tests/qemu-iotests/028
25
+++ b/util/oslib-posix.c
31
+++ b/tests/qemu-iotests/028
26
@@ -XXX,XX +XXX,XX @@ static void *do_touch_pages(void *arg)
32
@@ -XXX,XX +XXX,XX @@ status=1    # failure is the default!
27
memset_thread_failed = true;
33
28
} else {
34
_cleanup()
29
for (i = 0; i < numpages; i++) {
35
{
30
- memset(addr, 0, 1);
36
+ _cleanup_qemu
31
+ /*
37
rm -f "${TEST_IMG}.copy"
32
+ * Read & write back the same value, so we don't
38
_cleanup_test_img
33
+ * corrupt existing user/app data that might be
39
}
34
+ * stored.
40
diff --git a/tests/qemu-iotests/094 b/tests/qemu-iotests/094
35
+ *
41
index XXXXXXX..XXXXXXX 100755
36
+ * 'volatile' to stop compiler optimizing this away
42
--- a/tests/qemu-iotests/094
37
+ * to a no-op
43
+++ b/tests/qemu-iotests/094
38
+ *
44
@@ -XXX,XX +XXX,XX @@ echo "QA output created by $seq"
39
+ * TODO: get a better solution from kernel so we
45
here="$PWD"
40
+ * don't need to write at all so we don't cause
46
status=1    # failure is the default!
41
+ * wear on the storage backing the region...
47
42
+ */
48
-trap "exit \$status" 0 1 2 3 15
43
+ *(volatile char *)addr = *addr;
49
+_cleanup()
44
addr += hpagesize;
50
+{
45
}
51
+ _cleanup_qemu
46
}
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
47
--
172
--
48
2.9.3
173
2.9.3
49
174
50
175
diff view generated by jsdifflib