diff options
-rw-r--r-- | block.c | 5 | ||||
-rw-r--r-- | block/gluster.c | 143 | ||||
-rw-r--r-- | block/quorum.c | 9 | ||||
-rw-r--r-- | block/vmdk.c | 2 | ||||
-rw-r--r-- | docs/qmp/qmp-events.txt | 75 | ||||
-rw-r--r-- | qapi-schema.json | 5 | ||||
-rwxr-xr-x | tests/qemu-iotests-quick.sh | 1 | ||||
-rwxr-xr-x | tests/qemu-iotests/081 | 3 | ||||
-rw-r--r-- | tests/qemu-iotests/081.out | 2 | ||||
-rw-r--r-- | tests/qemu-iotests/common.rc | 2 | ||||
-rw-r--r-- | tests/qemu-iotests/group | 34 |
11 files changed, 203 insertions, 78 deletions
@@ -547,8 +547,9 @@ int get_tmp_filename(char *filename, int size) int fd; const char *tmpdir; tmpdir = getenv("TMPDIR"); - if (!tmpdir) - tmpdir = "/tmp"; + if (!tmpdir) { + tmpdir = "/var/tmp"; + } if (snprintf(filename, size, "%s/vl.XXXXXX", tmpdir) >= size) { return -EOVERFLOW; } diff --git a/block/gluster.c b/block/gluster.c index 14d390b4c7..54ee9b7d93 100644 --- a/block/gluster.c +++ b/block/gluster.c @@ -45,11 +45,13 @@ typedef struct GlusterConf { static void qemu_gluster_gconf_free(GlusterConf *gconf) { - g_free(gconf->server); - g_free(gconf->volname); - g_free(gconf->image); - g_free(gconf->transport); - g_free(gconf); + if (gconf) { + g_free(gconf->server); + g_free(gconf->volname); + g_free(gconf->image); + g_free(gconf->transport); + g_free(gconf); + } } static int parse_volume_options(GlusterConf *gconf, char *path) @@ -272,11 +274,28 @@ static QemuOptsList runtime_opts = { }, }; +static void qemu_gluster_parse_flags(int bdrv_flags, int *open_flags) +{ + assert(open_flags != NULL); + + *open_flags |= O_BINARY; + + if (bdrv_flags & BDRV_O_RDWR) { + *open_flags |= O_RDWR; + } else { + *open_flags |= O_RDONLY; + } + + if ((bdrv_flags & BDRV_O_NOCACHE)) { + *open_flags |= O_DIRECT; + } +} + static int qemu_gluster_open(BlockDriverState *bs, QDict *options, int bdrv_flags, Error **errp) { BDRVGlusterState *s = bs->opaque; - int open_flags = O_BINARY; + int open_flags = 0; int ret = 0; GlusterConf *gconf = g_malloc0(sizeof(GlusterConf)); QemuOpts *opts; @@ -299,15 +318,7 @@ static int qemu_gluster_open(BlockDriverState *bs, QDict *options, goto out; } - if (bdrv_flags & BDRV_O_RDWR) { - open_flags |= O_RDWR; - } else { - open_flags |= O_RDONLY; - } - - if ((bdrv_flags & BDRV_O_NOCACHE)) { - open_flags |= O_DIRECT; - } + qemu_gluster_parse_flags(bdrv_flags, &open_flags); s->fd = glfs_open(s->glfs, gconf->image, open_flags); if (!s->fd) { @@ -329,6 +340,96 @@ out: return ret; } +typedef struct BDRVGlusterReopenState { + struct glfs *glfs; + struct glfs_fd *fd; +} BDRVGlusterReopenState; + + +static int qemu_gluster_reopen_prepare(BDRVReopenState *state, + BlockReopenQueue *queue, Error **errp) +{ + int ret = 0; + BDRVGlusterReopenState *reop_s; + GlusterConf *gconf = NULL; + int open_flags = 0; + + assert(state != NULL); + assert(state->bs != NULL); + + state->opaque = g_malloc0(sizeof(BDRVGlusterReopenState)); + reop_s = state->opaque; + + qemu_gluster_parse_flags(state->flags, &open_flags); + + gconf = g_malloc0(sizeof(GlusterConf)); + + reop_s->glfs = qemu_gluster_init(gconf, state->bs->filename); + if (reop_s->glfs == NULL) { + ret = -errno; + goto exit; + } + + reop_s->fd = glfs_open(reop_s->glfs, gconf->image, open_flags); + if (reop_s->fd == NULL) { + /* reops->glfs will be cleaned up in _abort */ + ret = -errno; + goto exit; + } + +exit: + /* state->opaque will be freed in either the _abort or _commit */ + qemu_gluster_gconf_free(gconf); + return ret; +} + +static void qemu_gluster_reopen_commit(BDRVReopenState *state) +{ + BDRVGlusterReopenState *reop_s = state->opaque; + BDRVGlusterState *s = state->bs->opaque; + + + /* close the old */ + if (s->fd) { + glfs_close(s->fd); + } + if (s->glfs) { + glfs_fini(s->glfs); + } + + /* use the newly opened image / connection */ + s->fd = reop_s->fd; + s->glfs = reop_s->glfs; + + g_free(state->opaque); + state->opaque = NULL; + + return; +} + + +static void qemu_gluster_reopen_abort(BDRVReopenState *state) +{ + BDRVGlusterReopenState *reop_s = state->opaque; + + if (reop_s == NULL) { + return; + } + + if (reop_s->fd) { + glfs_close(reop_s->fd); + } + + if (reop_s->glfs) { + glfs_fini(reop_s->glfs); + } + + g_free(state->opaque); + state->opaque = NULL; + + return; +} + #ifdef CONFIG_GLUSTERFS_ZEROFILL static coroutine_fn int qemu_gluster_co_write_zeroes(BlockDriverState *bs, int64_t sector_num, int nb_sectors, BdrvRequestFlags flags) @@ -619,6 +720,9 @@ static BlockDriver bdrv_gluster = { .instance_size = sizeof(BDRVGlusterState), .bdrv_needs_filename = true, .bdrv_file_open = qemu_gluster_open, + .bdrv_reopen_prepare = qemu_gluster_reopen_prepare, + .bdrv_reopen_commit = qemu_gluster_reopen_commit, + .bdrv_reopen_abort = qemu_gluster_reopen_abort, .bdrv_close = qemu_gluster_close, .bdrv_create = qemu_gluster_create, .bdrv_getlength = qemu_gluster_getlength, @@ -643,6 +747,9 @@ static BlockDriver bdrv_gluster_tcp = { .instance_size = sizeof(BDRVGlusterState), .bdrv_needs_filename = true, .bdrv_file_open = qemu_gluster_open, + .bdrv_reopen_prepare = qemu_gluster_reopen_prepare, + .bdrv_reopen_commit = qemu_gluster_reopen_commit, + .bdrv_reopen_abort = qemu_gluster_reopen_abort, .bdrv_close = qemu_gluster_close, .bdrv_create = qemu_gluster_create, .bdrv_getlength = qemu_gluster_getlength, @@ -667,6 +774,9 @@ static BlockDriver bdrv_gluster_unix = { .instance_size = sizeof(BDRVGlusterState), .bdrv_needs_filename = true, .bdrv_file_open = qemu_gluster_open, + .bdrv_reopen_prepare = qemu_gluster_reopen_prepare, + .bdrv_reopen_commit = qemu_gluster_reopen_commit, + .bdrv_reopen_abort = qemu_gluster_reopen_abort, .bdrv_close = qemu_gluster_close, .bdrv_create = qemu_gluster_create, .bdrv_getlength = qemu_gluster_getlength, @@ -691,6 +801,9 @@ static BlockDriver bdrv_gluster_rdma = { .instance_size = sizeof(BDRVGlusterState), .bdrv_needs_filename = true, .bdrv_file_open = qemu_gluster_open, + .bdrv_reopen_prepare = qemu_gluster_reopen_prepare, + .bdrv_reopen_commit = qemu_gluster_reopen_commit, + .bdrv_reopen_abort = qemu_gluster_reopen_abort, .bdrv_close = qemu_gluster_close, .bdrv_create = qemu_gluster_create, .bdrv_getlength = qemu_gluster_getlength, diff --git a/block/quorum.c b/block/quorum.c index 6c28239718..bd997b7322 100644 --- a/block/quorum.c +++ b/block/quorum.c @@ -200,11 +200,14 @@ static void quorum_report_bad(QuorumAIOCB *acb, char *node_name, int ret) { QObject *data; assert(node_name); - data = qobject_from_jsonf("{ 'ret': %d" - ", 'node-name': %s" + data = qobject_from_jsonf("{ 'node-name': %s" ", 'sector-num': %" PRId64 ", 'sectors-count': %d }", - ret, node_name, acb->sector_num, acb->nb_sectors); + node_name, acb->sector_num, acb->nb_sectors); + if (ret < 0) { + QDict *dict = qobject_to_qdict(data); + qdict_put(dict, "error", qstring_from_str(strerror(-ret))); + } monitor_protocol_event(QEVENT_QUORUM_REPORT_BAD, data); qobject_decref(data); } diff --git a/block/vmdk.c b/block/vmdk.c index 83839f9b7a..b69988d169 100644 --- a/block/vmdk.c +++ b/block/vmdk.c @@ -1184,7 +1184,7 @@ static int64_t coroutine_fn vmdk_co_get_block_status(BlockDriverState *bs, break; case VMDK_OK: ret = BDRV_BLOCK_DATA; - if (extent->file == bs->file) { + if (extent->file == bs->file && !extent->compressed) { ret |= BDRV_BLOCK_OFFSET_VALID | offset; } diff --git a/docs/qmp/qmp-events.txt b/docs/qmp/qmp-events.txt index 00f95154dd..145402e078 100644 --- a/docs/qmp/qmp-events.txt +++ b/docs/qmp/qmp-events.txt @@ -225,6 +225,45 @@ Data: "timestamp": { "seconds": 1368697518, "microseconds": 326866 } } } +QUORUM_FAILURE +-------------- + +Emitted by the Quorum block driver if it fails to establish a quorum. + +Data: + +- "reference": device name if defined else node name. +- "sector-num": Number of the first sector of the failed read operation. +- "sector-count": Failed read operation sector count. + +Example: + +{ "event": "QUORUM_FAILURE", + "data": { "reference": "usr1", "sector-num": 345435, "sector-count": 5 }, + "timestamp": { "seconds": 1344522075, "microseconds": 745528 } } + +QUORUM_REPORT_BAD +----------------- + +Emitted to report a corruption of a Quorum file. + +Data: + +- "error": Error message (json-string, optional) + Only present on failure. This field contains a human-readable + error message. There are no semantics other than that the + block layer reported an error and clients should not try to + interpret the error string. +- "node-name": The graph node name of the block driver state. +- "sector-num": Number of the first sector of the failed read operation. +- "sector-count": Failed read operation sector count. + +Example: + +{ "event": "QUORUM_REPORT_BAD", + "data": { "node-name": "1.raw", "sector-num": 345435, "sector-count": 5 }, + "timestamp": { "seconds": 1344522075, "microseconds": 745528 } } + RESET ----- @@ -500,39 +539,3 @@ Example: Note: If action is "reset", "shutdown", or "pause" the WATCHDOG event is followed respectively by the RESET, SHUTDOWN, or STOP events. - -QUORUM_FAILURE --------------- - -Emitted by the Quorum block driver if it fails to establish a quorum. - -Data: - -- "reference": device name if defined else node name. -- "sector-num": Number of the first sector of the failed read operation. -- "sector-count": Failed read operation sector count. - -Example: - -{ "event": "QUORUM_FAILURE", - "data": { "reference": "usr1", "sector-num": 345435, "sector-count": 5 }, - "timestamp": { "seconds": 1344522075, "microseconds": 745528 } } - -QUORUM_REPORT_BAD ------------------ - -Emitted to report a corruption of a Quorum file. - -Data: - -- "ret": The IO return code. -- "node-name": The graph node name of the block driver state. -- "sector-num": Number of the first sector of the failed read operation. -- "sector-count": Failed read operation sector count. - -Example: - -{ "event": "QUORUM_REPORT_BAD", - "data": { "ret": 0, "node-name": "1.raw", "sector-num": 345435, - "sector-count": 5 }, - "timestamp": { "seconds": 1344522075, "microseconds": 745528 } } diff --git a/qapi-schema.json b/qapi-schema.json index ac8ad24966..c3592f6c11 100644 --- a/qapi-schema.json +++ b/qapi-schema.json @@ -4436,10 +4436,11 @@ # Driver specific block device options for Quorum # # @blkverify: #optional true if the driver must print content mismatch +# set to false by default # -# @children: the children block device to use +# @children: the children block devices to use # -# @vote_threshold: the vote limit under which a read will fail +# @vote-threshold: the vote limit under which a read will fail # # Since: 2.0 ## diff --git a/tests/qemu-iotests-quick.sh b/tests/qemu-iotests-quick.sh index cf90de0b8b..c449e8ab4a 100755 --- a/tests/qemu-iotests-quick.sh +++ b/tests/qemu-iotests-quick.sh @@ -8,6 +8,7 @@ export QEMU_PROG="this_should_be_unused" export QEMU_IMG_PROG="$(pwd)/qemu-img" export QEMU_IO_PROG="$(pwd)/qemu-io" +export QEMU_NBD_PROG="$(pwd)/qemu-nbd" cd $SRC_PATH/tests/qemu-iotests diff --git a/tests/qemu-iotests/081 b/tests/qemu-iotests/081 index f053f11942..b512d00cc8 100755 --- a/tests/qemu-iotests/081 +++ b/tests/qemu-iotests/081 @@ -56,6 +56,9 @@ function run_qemu() do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp | _filter_qemu_io } +test_quorum=$($QEMU_IMG --help|grep quorum) +[ "$test_quorum" = "" ] && _supported_fmt quorum + quorum="file.driver=quorum,file.children.0.file.filename=$TEST_DIR/1.raw" quorum="$quorum,file.children.1.file.filename=$TEST_DIR/2.raw" quorum="$quorum,file.children.2.file.filename=$TEST_DIR/3.raw,file.vote-threshold=2" diff --git a/tests/qemu-iotests/081.out b/tests/qemu-iotests/081.out index 4fe2f95f63..84aeb0c730 100644 --- a/tests/qemu-iotests/081.out +++ b/tests/qemu-iotests/081.out @@ -30,7 +30,7 @@ Testing: -drive file=TEST_DIR/2.IMGFMT,format=IMGFMT,if=none,id=drive2 QMP_VERSION {"return": {}} {"return": {}} -{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "QUORUM_REPORT_BAD", "data": {"node-name": "", "ret": 0, "sectors-count": 20480, "sector-num": 0}} +{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "QUORUM_REPORT_BAD", "data": {"node-name": "", "sectors-count": 20480, "sector-num": 0}} read 10485760/10485760 bytes at offset 0 10 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) {"return": ""} diff --git a/tests/qemu-iotests/common.rc b/tests/qemu-iotests/common.rc index 71e9a7462d..881079bdb9 100644 --- a/tests/qemu-iotests/common.rc +++ b/tests/qemu-iotests/common.rc @@ -203,7 +203,7 @@ _cleanup_test_img() ;; rbd) - rbd rm "$TEST_DIR/t.$IMGFMT" > /dev/null + rbd --no-progress rm "$TEST_DIR/t.$IMGFMT" > /dev/null ;; sheepdog) diff --git a/tests/qemu-iotests/group b/tests/qemu-iotests/group index db127d924d..8dd8553035 100644 --- a/tests/qemu-iotests/group +++ b/tests/qemu-iotests/group @@ -58,30 +58,30 @@ 049 rw auto 050 rw auto backing quick 051 rw auto -052 rw auto backing -053 rw auto -054 rw auto +052 rw auto backing quick +053 rw auto quick +054 rw auto quick 055 rw auto 056 rw auto backing 057 rw auto -058 rw auto -059 rw auto -060 rw auto -061 rw auto -062 rw auto -063 rw auto -064 rw auto +058 rw auto quick +059 rw auto quick +060 rw auto quick +061 rw auto quick +062 rw auto quick +063 rw auto quick +064 rw auto quick 065 rw auto -066 rw auto +066 rw auto quick 067 rw auto 068 rw auto -069 rw auto -070 rw auto +069 rw auto quick +070 rw auto quick 071 rw auto -072 rw auto -073 rw auto -074 rw auto -077 rw auto +072 rw auto quick +073 rw auto quick +074 rw auto quick +077 rw auto quick 079 rw auto 081 rw auto 082 rw auto quick |