Skip to content

Commit

Permalink
Merge remote-tracking branch 'mreitz/tags/pull-block-for-kevin-2016-0…
Browse files Browse the repository at this point in the history
…6-16' into queue-block

Block patches

# gpg: Signature made Thu Jun 16 15:21:35 2016 CEST
# gpg:                using RSA key 0x3BB14202E838ACAD
# gpg: Good signature from "Max Reitz <mreitz@redhat.com>"
# Primary key fingerprint: 91BE B60A 30DB 3E88 57D1  1829 F407 DB00 61D5 CF40
#      Subkey fingerprint: 58B3 81CE 2DC8 9CF9 9730  EE64 3BB1 4202 E838 ACAD

* mreitz/tags/pull-block-for-kevin-2016-06-16:
  hbitmap: add 'pos < size' asserts
  iotests: Add test for oVirt-like storage migration
  iotests: Add test for post-mirror backing chains
  block/null: Implement bdrv_refresh_filename()
  block/mirror: Fix target backing BDS
  block: Allow replacement of a BDS by its overlay
  rbd:change error_setg() to error_setg_errno()
  iotests: 095: Clean up QEMU before showing image info
  block: Create the commit block job before reopening any image
  block: Prevent sleeping jobs from resuming if they have been paused
  block: use the block job list in qmp_query_block_jobs()
  block: use the block job list in bdrv_drain_all()

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
  • Loading branch information
kevmw committed Jun 16, 2016
2 parents 4186904 + 0e32119 commit 60251f4
Show file tree
Hide file tree
Showing 16 changed files with 646 additions and 64 deletions.
24 changes: 15 additions & 9 deletions block.c
Expand Up @@ -2226,9 +2226,23 @@ void bdrv_close_all(void)
static void change_parent_backing_link(BlockDriverState *from,
BlockDriverState *to)
{
BdrvChild *c, *next;
BdrvChild *c, *next, *to_c;

QLIST_FOREACH_SAFE(c, &from->parents, next_parent, next) {
if (c->role == &child_backing) {
/* @from is generally not allowed to be a backing file, except for
* when @to is the overlay. In that case, @from may not be replaced
* by @to as @to's backing node. */
QLIST_FOREACH(to_c, &to->children, next) {
if (to_c == c) {
break;
}
}
if (to_c) {
continue;
}
}

assert(c->role != &child_backing);
bdrv_ref(to);
bdrv_replace_child(c, to);
Expand Down Expand Up @@ -2277,14 +2291,6 @@ void bdrv_replace_in_backing_chain(BlockDriverState *old, BlockDriverState *new)

change_parent_backing_link(old, new);

/* Change backing files if a previously independent node is added to the
* chain. For active commit, we replace top by its own (indirect) backing
* file and don't do anything here so we don't build a loop. */
if (new->backing == NULL && !bdrv_chain_contains(backing_bs(old), new)) {
bdrv_set_backing_hd(new, backing_bs(old));
bdrv_set_backing_hd(old, NULL);
}

bdrv_unref(old);
}

Expand Down
11 changes: 6 additions & 5 deletions block/commit.c
Expand Up @@ -236,6 +236,11 @@ void commit_start(BlockDriverState *bs, BlockDriverState *base,
return;
}

s = block_job_create(&commit_job_driver, bs, speed, cb, opaque, errp);
if (!s) {
return;
}

orig_base_flags = bdrv_get_flags(base);
orig_overlay_flags = bdrv_get_flags(overlay_bs);

Expand All @@ -252,16 +257,12 @@ void commit_start(BlockDriverState *bs, BlockDriverState *base,
bdrv_reopen_multiple(reopen_queue, &local_err);
if (local_err != NULL) {
error_propagate(errp, local_err);
block_job_unref(&s->common);
return;
}
}


s = block_job_create(&commit_job_driver, bs, speed, cb, opaque, errp);
if (!s) {
return;
}

s->base = blk_new();
blk_insert_bs(s->base, base);

Expand Down
24 changes: 18 additions & 6 deletions block/io.c
Expand Up @@ -289,15 +289,21 @@ void bdrv_drain_all(void)
bool busy = true;
BlockDriverState *bs;
BdrvNextIterator it;
BlockJob *job = NULL;
GSList *aio_ctxs = NULL, *ctx;

while ((job = block_job_next(job))) {
AioContext *aio_context = blk_get_aio_context(job->blk);

aio_context_acquire(aio_context);
block_job_pause(job);
aio_context_release(aio_context);
}

for (bs = bdrv_first(&it); bs; bs = bdrv_next(&it)) {
AioContext *aio_context = bdrv_get_aio_context(bs);

aio_context_acquire(aio_context);
if (bs->job) {
block_job_pause(bs->job);
}
bdrv_parent_drained_begin(bs);
bdrv_io_unplugged_begin(bs);
bdrv_drain_recurse(bs);
Expand Down Expand Up @@ -340,12 +346,18 @@ void bdrv_drain_all(void)
aio_context_acquire(aio_context);
bdrv_io_unplugged_end(bs);
bdrv_parent_drained_end(bs);
if (bs->job) {
block_job_resume(bs->job);
}
aio_context_release(aio_context);
}
g_slist_free(aio_ctxs);

job = NULL;
while ((job = block_job_next(job))) {
AioContext *aio_context = blk_get_aio_context(job->blk);

aio_context_acquire(aio_context);
block_job_resume(job);
aio_context_release(aio_context);
}
}

/**
Expand Down
39 changes: 28 additions & 11 deletions block/mirror.c
Expand Up @@ -44,6 +44,7 @@ typedef struct MirrorBlockJob {
/* Used to block operations on the drive-mirror-replace target */
Error *replace_blocker;
bool is_none_mode;
BlockMirrorBackingMode backing_mode;
BlockdevOnError on_source_error, on_target_error;
bool synced;
bool should_complete;
Expand Down Expand Up @@ -742,20 +743,26 @@ static void mirror_set_speed(BlockJob *job, int64_t speed, Error **errp)
static void mirror_complete(BlockJob *job, Error **errp)
{
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
Error *local_err = NULL;
int ret;
BlockDriverState *src, *target;

src = blk_bs(job->blk);
target = blk_bs(s->target);

ret = bdrv_open_backing_file(blk_bs(s->target), NULL, "backing",
&local_err);
if (ret < 0) {
error_propagate(errp, local_err);
return;
}
if (!s->synced) {
error_setg(errp, QERR_BLOCK_JOB_NOT_READY, job->id);
return;
}

if (s->backing_mode == MIRROR_OPEN_BACKING_CHAIN) {
int ret;

assert(!target->backing);
ret = bdrv_open_backing_file(target, NULL, "backing", errp);
if (ret < 0) {
return;
}
}

/* check the target bs is not blocked and block all operations on it */
if (s->replaces) {
AioContext *replace_aio_context;
Expand All @@ -777,6 +784,13 @@ static void mirror_complete(BlockJob *job, Error **errp)
aio_context_release(replace_aio_context);
}

if (s->backing_mode == MIRROR_SOURCE_BACKING_CHAIN) {
BlockDriverState *backing = s->is_none_mode ? src : s->base;
if (backing_bs(target) != backing) {
bdrv_set_backing_hd(target, backing);
}
}

s->should_complete = true;
block_job_enter(&s->common);
}
Expand All @@ -799,6 +813,7 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
const char *replaces,
int64_t speed, uint32_t granularity,
int64_t buf_size,
BlockMirrorBackingMode backing_mode,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
bool unmap,
Expand Down Expand Up @@ -836,6 +851,7 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
s->on_source_error = on_source_error;
s->on_target_error = on_target_error;
s->is_none_mode = is_none_mode;
s->backing_mode = backing_mode;
s->base = base;
s->granularity = granularity;
s->buf_size = ROUND_UP(buf_size, granularity);
Expand All @@ -859,7 +875,8 @@ static void mirror_start_job(BlockDriverState *bs, BlockDriverState *target,
void mirror_start(BlockDriverState *bs, BlockDriverState *target,
const char *replaces,
int64_t speed, uint32_t granularity, int64_t buf_size,
MirrorSyncMode mode, BlockdevOnError on_source_error,
MirrorSyncMode mode, BlockMirrorBackingMode backing_mode,
BlockdevOnError on_source_error,
BlockdevOnError on_target_error,
bool unmap,
BlockCompletionFunc *cb,
Expand All @@ -875,7 +892,7 @@ void mirror_start(BlockDriverState *bs, BlockDriverState *target,
is_none_mode = mode == MIRROR_SYNC_MODE_NONE;
base = mode == MIRROR_SYNC_MODE_TOP ? backing_bs(bs) : NULL;
mirror_start_job(bs, target, replaces,
speed, granularity, buf_size,
speed, granularity, buf_size, backing_mode,
on_source_error, on_target_error, unmap, cb, opaque, errp,
&mirror_job_driver, is_none_mode, base);
}
Expand Down Expand Up @@ -922,7 +939,7 @@ void commit_active_start(BlockDriverState *bs, BlockDriverState *base,
}
}

mirror_start_job(bs, base, NULL, speed, 0, 0,
mirror_start_job(bs, base, NULL, speed, 0, 0, MIRROR_LEAVE_BACKING_CHAIN,
on_error, on_error, false, cb, opaque, &local_err,
&commit_active_job_driver, false, base);
if (local_err) {
Expand Down
20 changes: 20 additions & 0 deletions block/null.c
Expand Up @@ -12,6 +12,8 @@

#include "qemu/osdep.h"
#include "qapi/error.h"
#include "qapi/qmp/qdict.h"
#include "qapi/qmp/qstring.h"
#include "block/block_int.h"

#define NULL_OPT_LATENCY "latency-ns"
Expand Down Expand Up @@ -223,6 +225,20 @@ static int64_t coroutine_fn null_co_get_block_status(BlockDriverState *bs,
}
}

static void null_refresh_filename(BlockDriverState *bs, QDict *opts)
{
QINCREF(opts);
qdict_del(opts, "filename");

if (!qdict_size(opts)) {
snprintf(bs->exact_filename, sizeof(bs->exact_filename), "%s://",
bs->drv->format_name);
}

qdict_put(opts, "driver", qstring_from_str(bs->drv->format_name));
bs->full_open_options = opts;
}

static BlockDriver bdrv_null_co = {
.format_name = "null-co",
.protocol_name = "null-co",
Expand All @@ -238,6 +254,8 @@ static BlockDriver bdrv_null_co = {
.bdrv_reopen_prepare = null_reopen_prepare,

.bdrv_co_get_block_status = null_co_get_block_status,

.bdrv_refresh_filename = null_refresh_filename,
};

static BlockDriver bdrv_null_aio = {
Expand All @@ -255,6 +273,8 @@ static BlockDriver bdrv_null_aio = {
.bdrv_reopen_prepare = null_reopen_prepare,

.bdrv_co_get_block_status = null_co_get_block_status,

.bdrv_refresh_filename = null_refresh_filename,
};

static void bdrv_null_init(void)
Expand Down
38 changes: 23 additions & 15 deletions block/rbd.c
Expand Up @@ -290,7 +290,8 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf,
if (only_read_conf_file) {
ret = rados_conf_read_file(cluster, value);
if (ret < 0) {
error_setg(errp, "error reading conf file %s", value);
error_setg_errno(errp, -ret, "error reading conf file %s",
value);
break;
}
}
Expand All @@ -299,7 +300,7 @@ static int qemu_rbd_set_conf(rados_t cluster, const char *conf,
} else if (!only_read_conf_file) {
ret = rados_conf_set(cluster, name, value);
if (ret < 0) {
error_setg(errp, "invalid conf option %s", name);
error_setg_errno(errp, -ret, "invalid conf option %s", name);
ret = -EINVAL;
break;
}
Expand Down Expand Up @@ -354,9 +355,10 @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
}

clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
if (rados_create(&cluster, clientname) < 0) {
error_setg(errp, "error initializing");
return -EIO;
ret = rados_create(&cluster, clientname);
if (ret < 0) {
error_setg_errno(errp, -ret, "error initializing");
return ret;
}

if (strstr(conf, "conf=") == NULL) {
Expand All @@ -381,21 +383,27 @@ static int qemu_rbd_create(const char *filename, QemuOpts *opts, Error **errp)
return -EIO;
}

if (rados_connect(cluster) < 0) {
error_setg(errp, "error connecting");
ret = rados_connect(cluster);
if (ret < 0) {
error_setg_errno(errp, -ret, "error connecting");
rados_shutdown(cluster);
return -EIO;
return ret;
}

if (rados_ioctx_create(cluster, pool, &io_ctx) < 0) {
error_setg(errp, "error opening pool %s", pool);
ret = rados_ioctx_create(cluster, pool, &io_ctx);
if (ret < 0) {
error_setg_errno(errp, -ret, "error opening pool %s", pool);
rados_shutdown(cluster);
return -EIO;
return ret;
}

ret = rbd_create(io_ctx, name, bytes, &obj_order);
rados_ioctx_destroy(io_ctx);
rados_shutdown(cluster);
if (ret < 0) {
error_setg_errno(errp, -ret, "error rbd create");
return ret;
}

return ret;
}
Expand Down Expand Up @@ -500,7 +508,7 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,
clientname = qemu_rbd_parse_clientname(conf, clientname_buf);
r = rados_create(&s->cluster, clientname);
if (r < 0) {
error_setg(errp, "error initializing");
error_setg_errno(errp, -r, "error initializing");
goto failed_opts;
}

Expand Down Expand Up @@ -546,19 +554,19 @@ static int qemu_rbd_open(BlockDriverState *bs, QDict *options, int flags,

r = rados_connect(s->cluster);
if (r < 0) {
error_setg(errp, "error connecting");
error_setg_errno(errp, -r, "error connecting");
goto failed_shutdown;
}

r = rados_ioctx_create(s->cluster, pool, &s->io_ctx);
if (r < 0) {
error_setg(errp, "error opening pool %s", pool);
error_setg_errno(errp, -r, "error opening pool %s", pool);
goto failed_shutdown;
}

r = rbd_open(s->io_ctx, s->name, &s->image, s->snap);
if (r < 0) {
error_setg(errp, "error reading header from %s", s->name);
error_setg_errno(errp, -r, "error reading header from %s", s->name);
goto failed_open;
}

Expand Down

0 comments on commit 60251f4

Please sign in to comment.