aboutsummaryrefslogtreecommitdiff
path: root/block
diff options
context:
space:
mode:
authorPeter Maydell <peter.maydell@linaro.org>2014-03-04 16:33:25 +0000
committerPeter Maydell <peter.maydell@linaro.org>2014-03-04 16:33:25 +0000
commit4a29420ea1c5a34191281855f5f51e70deab8940 (patch)
treeb84d29d3f4f396fc3af91ee93a4c891056d8c9a4 /block
parent4fd42afe6117ab16dc5e2e7216cced8010afc1d1 (diff)
parent3eba13ec25341ce473591ff338eab3196890a4eb (diff)
Merge remote-tracking branch 'remotes/stefanha/tags/block-pull-request' into staging
Block pull request # gpg: Signature made Fri 28 Feb 2014 18:27:24 GMT using RSA key ID 81AB73C8 # gpg: Good signature from "Stefan Hajnoczi <stefanha@redhat.com>" # gpg: aka "Stefan Hajnoczi <stefanha@gmail.com>" # gpg: WARNING: This key is not certified with a trusted signature! # gpg: There is no indication that the signature belongs to the owner. # Primary key fingerprint: 8695 A8BF D3F9 7CDA AC35 775A 9CA4 ABB3 81AB 73C8 * remotes/stefanha/tags/block-pull-request: block/vmdk: do not report file offset for compressed extents discard rbd error output when not relevant in qemu-iotests block: use /var/tmp instead of /tmp for -snapshot qemu-io-test: Disable Quorum test when not compiled in. qmp: Make Quorum error events more palatable. qmp: Fix BlockdevOptionQuorum. block: gluster - add reopen support. block: gluster - code movements, state storage changes qemu-iotests: add more tests to the "quick" group Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
Diffstat (limited to 'block')
-rw-r--r--block/gluster.c143
-rw-r--r--block/quorum.c9
-rw-r--r--block/vmdk.c2
3 files changed, 135 insertions, 19 deletions
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;
}