Block layer patches for 2.10.0-rc2

-----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJZicL/AAoJEH8JsnLIjy/WnRYP/AhJ+3RuyemPn1rTRVbz6AtS
 3nWmNJTCrbbmxP9dfM50C30q1OjT9114AibC0qz4cm6LGRA7O82kWT0KcWHOM443
 ljnuxXfJ3S0FGC0sJXG4jdzkOEIWBnIsfYqkVih4KPzsARUTlBZjtANjyyvRMFmT
 hgqUKrKl+WwE0Ys248xSuE8bCE5TmSkvKV14ezq/FpjZMmJVpsQXFhkUfH8ZjX48
 USCDG8MAOFFJsPojl9ONOFn9dc3hX2GLwOJe7fSLe19ppnA7FiTPLy0ySpLMpQA6
 Ipu+PmHtfVBmHX6g6a0XXput7gGNJ1aURNRQuWiLtOlo4uoybwMRf7teKe8ob5+n
 S2PmhKOFXVMK+pbARZJ8IPAWcHo6dcMqEJXN5xvJLcKiN2WM5A4rx1/liSDIbQ9p
 +TrFhzZlLmMy/6xMJdv63uwKbWcdS18R4q9tzU5Y+/BTG/+LsKgpkwscnqeEvEEv
 i5+0QjdJZQajCuF4PTE2dEzw2WesPHdUFcYMtYAm9QKGG07kwJOoncJ+ghuriyrw
 JzvcoSbkug8a7M+18zoDTszWyXqHl3ObODVUCiLQFe0Tzu+SxYy0cDrH/QMNi7cI
 EcfbLDfCNOaNU27ctsGiey6idB2qHwWpZ0N+XnTb2TRIBRX6WAefVdxF0aTJPQdh
 +vwWHW7+gd1QwEgCQpvP
 =swst
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging

Block layer patches for 2.10.0-rc2

# gpg: Signature made Tue 08 Aug 2017 14:56:15 BST
# gpg:                using RSA key 0x7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>"
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream:
  block/nfs: fix mutex assertion in nfs_file_close()
  qemu-iotests: Test reopen between read-only and read-write
  qemu-io: Allow reopen read-write
  block: Set BDRV_O_ALLOW_RDWR during rw reopen
  block: Allow reopen rw without BDRV_O_ALLOW_RDWR
  block: Fix order in bdrv_replace_child()
  parallels: drop check that bdrv_truncate() is working
  parallels: respect error code of bdrv_getlength() in allocate_clusters()
  block: respect error code from bdrv_getlength in handle_aiocb_write_zeroes
  vmdk: Fix error handling/reporting of vmdk_check
  block/null: Remove 'filename' option
  block: drop bdrv_set_key from BlockDriver
  block/vhdx: check error return of bdrv_truncate()
  block/vhdx: check error return of bdrv_flush()
  block/vhdx: check for offset overflow to bdrv_truncate()
  block/vhdx: check error return of bdrv_getlength()
  quorum: Set sectors-count to 0 when reporting a flush error
  qemu-iotests/109: Fix lock race condition

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2017-08-08 15:23:21 +01:00
commit 53b080fa83
18 changed files with 299 additions and 48 deletions

20
block.c
View File

@ -246,7 +246,8 @@ bool bdrv_is_writable(BlockDriverState *bs)
return !bdrv_is_read_only(bs) && !(bs->open_flags & BDRV_O_INACTIVE); return !bdrv_is_read_only(bs) && !(bs->open_flags & BDRV_O_INACTIVE);
} }
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, Error **errp) int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
bool ignore_allow_rdw, Error **errp)
{ {
/* Do not set read_only if copy_on_read is enabled */ /* Do not set read_only if copy_on_read is enabled */
if (bs->copy_on_read && read_only) { if (bs->copy_on_read && read_only) {
@ -256,7 +257,9 @@ int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
} }
/* Do not clear read_only if it is prohibited */ /* Do not clear read_only if it is prohibited */
if (!read_only && !(bs->open_flags & BDRV_O_ALLOW_RDWR)) { if (!read_only && !(bs->open_flags & BDRV_O_ALLOW_RDWR) &&
!ignore_allow_rdw)
{
error_setg(errp, "Node '%s' is read only", error_setg(errp, "Node '%s' is read only",
bdrv_get_device_or_node_name(bs)); bdrv_get_device_or_node_name(bs));
return -EPERM; return -EPERM;
@ -269,7 +272,7 @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
{ {
int ret = 0; int ret = 0;
ret = bdrv_can_set_read_only(bs, read_only, errp); ret = bdrv_can_set_read_only(bs, read_only, false, errp);
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
@ -1933,6 +1936,8 @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
BlockDriverState *old_bs = child->bs; BlockDriverState *old_bs = child->bs;
uint64_t perm, shared_perm; uint64_t perm, shared_perm;
bdrv_replace_child_noperm(child, new_bs);
if (old_bs) { if (old_bs) {
/* Update permissions for old node. This is guaranteed to succeed /* Update permissions for old node. This is guaranteed to succeed
* because we're just taking a parent away, so we're loosening * because we're just taking a parent away, so we're loosening
@ -1942,8 +1947,6 @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
bdrv_set_perm(old_bs, perm, shared_perm); bdrv_set_perm(old_bs, perm, shared_perm);
} }
bdrv_replace_child_noperm(child, new_bs);
if (new_bs) { if (new_bs) {
bdrv_get_cumulative_perm(new_bs, &perm, &shared_perm); bdrv_get_cumulative_perm(new_bs, &perm, &shared_perm);
bdrv_set_perm(new_bs, perm, shared_perm); bdrv_set_perm(new_bs, perm, shared_perm);
@ -2726,8 +2729,11 @@ static BlockReopenQueue *bdrv_reopen_queue_child(BlockReopenQueue *bs_queue,
bdrv_join_options(bs, options, old_options); bdrv_join_options(bs, options, old_options);
QDECREF(old_options); QDECREF(old_options);
/* bdrv_open() masks this flag out */ /* bdrv_open_inherit() sets and clears some additional flags internally */
flags &= ~BDRV_O_PROTOCOL; flags &= ~BDRV_O_PROTOCOL;
if (flags & BDRV_O_RDWR) {
flags |= BDRV_O_ALLOW_RDWR;
}
QLIST_FOREACH(child, &bs->children, next) { QLIST_FOREACH(child, &bs->children, next) {
QDict *new_child_options; QDict *new_child_options;
@ -2907,7 +2913,7 @@ int bdrv_reopen_prepare(BDRVReopenState *reopen_state, BlockReopenQueue *queue,
* to r/w. Attempting to set to r/w may fail if either BDRV_O_ALLOW_RDWR is * to r/w. Attempting to set to r/w may fail if either BDRV_O_ALLOW_RDWR is
* not set, or if the BDS still has copy_on_read enabled */ * not set, or if the BDS still has copy_on_read enabled */
read_only = !(reopen_state->flags & BDRV_O_RDWR); read_only = !(reopen_state->flags & BDRV_O_RDWR);
ret = bdrv_can_set_read_only(reopen_state->bs, read_only, &local_err); ret = bdrv_can_set_read_only(reopen_state->bs, read_only, true, &local_err);
if (local_err) { if (local_err) {
error_propagate(errp, local_err); error_propagate(errp, local_err);
goto error; goto error;

View File

@ -1339,6 +1339,9 @@ static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb)
#if defined(CONFIG_FALLOCATE) || defined(CONFIG_XFS) #if defined(CONFIG_FALLOCATE) || defined(CONFIG_XFS)
BDRVRawState *s = aiocb->bs->opaque; BDRVRawState *s = aiocb->bs->opaque;
#endif #endif
#ifdef CONFIG_FALLOCATE
int64_t len;
#endif
if (aiocb->aio_type & QEMU_AIO_BLKDEV) { if (aiocb->aio_type & QEMU_AIO_BLKDEV) {
return handle_aiocb_write_zeroes_block(aiocb); return handle_aiocb_write_zeroes_block(aiocb);
@ -1381,7 +1384,10 @@ static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb)
#endif #endif
#ifdef CONFIG_FALLOCATE #ifdef CONFIG_FALLOCATE
if (s->has_fallocate && aiocb->aio_offset >= bdrv_getlength(aiocb->bs)) { /* Last resort: we are trying to extend the file with zeroed data. This
* can be done via fallocate(fd, 0) */
len = bdrv_getlength(aiocb->bs);
if (s->has_fallocate && len >= 0 && aiocb->aio_offset >= len) {
int ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes); int ret = do_fallocate(s->fd, 0, aiocb->aio_offset, aiocb->aio_nbytes);
if (ret == 0 || ret != -ENOTSUP) { if (ret == 0 || ret != -ENOTSUP) {
return ret; return ret;

View File

@ -433,19 +433,23 @@ static void nfs_client_close(NFSClient *client)
if (client->context) { if (client->context) {
if (client->fh) { if (client->fh) {
nfs_close(client->context, client->fh); nfs_close(client->context, client->fh);
client->fh = NULL;
} }
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context), aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
false, NULL, NULL, NULL, NULL); false, NULL, NULL, NULL, NULL);
nfs_destroy_context(client->context); nfs_destroy_context(client->context);
client->context = NULL;
} }
memset(client, 0, sizeof(NFSClient)); g_free(client->path);
qemu_mutex_destroy(&client->mutex);
qapi_free_NFSServer(client->server);
client->server = NULL;
} }
static void nfs_file_close(BlockDriverState *bs) static void nfs_file_close(BlockDriverState *bs)
{ {
NFSClient *client = bs->opaque; NFSClient *client = bs->opaque;
nfs_client_close(client); nfs_client_close(client);
qemu_mutex_destroy(&client->mutex);
} }
static NFSServer *nfs_config(QDict *options, Error **errp) static NFSServer *nfs_config(QDict *options, Error **errp)
@ -498,6 +502,7 @@ static int64_t nfs_client_open(NFSClient *client, QDict *options,
struct stat st; struct stat st;
char *file = NULL, *strp = NULL; char *file = NULL, *strp = NULL;
qemu_mutex_init(&client->mutex);
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort); opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err); qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) { if (local_err) {
@ -660,7 +665,7 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags,
if (ret < 0) { if (ret < 0) {
return ret; return ret;
} }
qemu_mutex_init(&client->mutex);
bs->total_sectors = ret; bs->total_sectors = ret;
ret = 0; ret = 0;
return ret; return ret;

View File

@ -29,11 +29,6 @@ static QemuOptsList runtime_opts = {
.name = "null", .name = "null",
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head), .head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
.desc = { .desc = {
{
.name = "filename",
.type = QEMU_OPT_STRING,
.help = "",
},
{ {
.name = BLOCK_OPT_SIZE, .name = BLOCK_OPT_SIZE,
.type = QEMU_OPT_SIZE, .type = QEMU_OPT_SIZE,
@ -54,6 +49,30 @@ static QemuOptsList runtime_opts = {
}, },
}; };
static void null_co_parse_filename(const char *filename, QDict *options,
Error **errp)
{
/* This functions only exists so that a null-co:// filename is accepted
* with the null-co driver. */
if (strcmp(filename, "null-co://")) {
error_setg(errp, "The only allowed filename for this driver is "
"'null-co://'");
return;
}
}
static void null_aio_parse_filename(const char *filename, QDict *options,
Error **errp)
{
/* This functions only exists so that a null-aio:// filename is accepted
* with the null-aio driver. */
if (strcmp(filename, "null-aio://")) {
error_setg(errp, "The only allowed filename for this driver is "
"'null-aio://'");
return;
}
}
static int null_file_open(BlockDriverState *bs, QDict *options, int flags, static int null_file_open(BlockDriverState *bs, QDict *options, int flags,
Error **errp) Error **errp)
{ {
@ -242,6 +261,7 @@ static BlockDriver bdrv_null_co = {
.instance_size = sizeof(BDRVNullState), .instance_size = sizeof(BDRVNullState),
.bdrv_file_open = null_file_open, .bdrv_file_open = null_file_open,
.bdrv_parse_filename = null_co_parse_filename,
.bdrv_close = null_close, .bdrv_close = null_close,
.bdrv_getlength = null_getlength, .bdrv_getlength = null_getlength,
@ -261,6 +281,7 @@ static BlockDriver bdrv_null_aio = {
.instance_size = sizeof(BDRVNullState), .instance_size = sizeof(BDRVNullState),
.bdrv_file_open = null_file_open, .bdrv_file_open = null_file_open,
.bdrv_parse_filename = null_aio_parse_filename,
.bdrv_close = null_close, .bdrv_close = null_close,
.bdrv_getlength = null_getlength, .bdrv_getlength = null_getlength,

View File

@ -192,7 +192,7 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
int nb_sectors, int *pnum) int nb_sectors, int *pnum)
{ {
BDRVParallelsState *s = bs->opaque; BDRVParallelsState *s = bs->opaque;
int64_t pos, space, idx, to_allocate, i; int64_t pos, space, idx, to_allocate, i, len;
pos = block_status(s, sector_num, nb_sectors, pnum); pos = block_status(s, sector_num, nb_sectors, pnum);
if (pos > 0) { if (pos > 0) {
@ -214,7 +214,11 @@ static int64_t allocate_clusters(BlockDriverState *bs, int64_t sector_num,
assert(idx < s->bat_size && idx + to_allocate <= s->bat_size); assert(idx < s->bat_size && idx + to_allocate <= s->bat_size);
space = to_allocate * s->tracks; space = to_allocate * s->tracks;
if (s->data_end + space > bdrv_getlength(bs->file->bs) >> BDRV_SECTOR_BITS) { len = bdrv_getlength(bs->file->bs);
if (len < 0) {
return len;
}
if (s->data_end + space > (len >> BDRV_SECTOR_BITS)) {
int ret; int ret;
space += s->prealloc_size; space += s->prealloc_size;
if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) { if (s->prealloc_mode == PRL_PREALLOC_MODE_FALLOCATE) {
@ -699,9 +703,7 @@ static int parallels_open(BlockDriverState *bs, QDict *options, int flags,
goto fail_options; goto fail_options;
} }
if (!(flags & BDRV_O_RESIZE) || !bdrv_has_zero_init(bs->file->bs) || if (!bdrv_has_zero_init(bs->file->bs)) {
bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs),
PREALLOC_MODE_OFF, NULL) != 0) {
s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE; s->prealloc_mode = PRL_PREALLOC_MODE_FALLOCATE;
} }

View File

@ -785,8 +785,7 @@ static coroutine_fn int quorum_co_flush(BlockDriverState *bs)
for (i = 0; i < s->num_children; i++) { for (i = 0; i < s->num_children; i++) {
result = bdrv_co_flush(s->children[i]->bs); result = bdrv_co_flush(s->children[i]->bs);
if (result) { if (result) {
quorum_report_bad(QUORUM_OP_TYPE_FLUSH, 0, quorum_report_bad(QUORUM_OP_TYPE_FLUSH, 0, 0,
bdrv_getlength(s->children[i]->bs),
s->children[i]->bs->node_name, result); s->children[i]->bs->node_name, result);
result_value.l = result; result_value.l = result;
quorum_count_vote(&error_votes, &result_value, i); quorum_count_vote(&error_votes, &result_value, i);

View File

@ -491,6 +491,7 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
uint32_t cnt, sectors_read; uint32_t cnt, sectors_read;
uint64_t new_file_size; uint64_t new_file_size;
void *data = NULL; void *data = NULL;
int64_t file_length;
VHDXLogDescEntries *desc_entries = NULL; VHDXLogDescEntries *desc_entries = NULL;
VHDXLogEntryHeader hdr_tmp = { 0 }; VHDXLogEntryHeader hdr_tmp = { 0 };
@ -510,10 +511,15 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
if (ret < 0) { if (ret < 0) {
goto exit; goto exit;
} }
file_length = bdrv_getlength(bs->file->bs);
if (file_length < 0) {
ret = file_length;
goto exit;
}
/* if the log shows a FlushedFileOffset larger than our current file /* if the log shows a FlushedFileOffset larger than our current file
* size, then that means the file has been truncated / corrupted, and * size, then that means the file has been truncated / corrupted, and
* we must refused to open it / use it */ * we must refused to open it / use it */
if (hdr_tmp.flushed_file_offset > bdrv_getlength(bs->file->bs)) { if (hdr_tmp.flushed_file_offset > file_length) {
ret = -EINVAL; ret = -EINVAL;
goto exit; goto exit;
} }
@ -543,19 +549,30 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
goto exit; goto exit;
} }
} }
if (bdrv_getlength(bs->file->bs) < desc_entries->hdr.last_file_offset) { if (file_length < desc_entries->hdr.last_file_offset) {
new_file_size = desc_entries->hdr.last_file_offset; new_file_size = desc_entries->hdr.last_file_offset;
if (new_file_size % (1024*1024)) { if (new_file_size % (1024*1024)) {
/* round up to nearest 1MB boundary */ /* round up to nearest 1MB boundary */
new_file_size = ((new_file_size >> 20) + 1) << 20; new_file_size = QEMU_ALIGN_UP(new_file_size, MiB);
bdrv_truncate(bs->file, new_file_size, PREALLOC_MODE_OFF, NULL); if (new_file_size > INT64_MAX) {
ret = -EINVAL;
goto exit;
}
ret = bdrv_truncate(bs->file, new_file_size, PREALLOC_MODE_OFF,
NULL);
if (ret < 0) {
goto exit;
}
} }
} }
qemu_vfree(desc_entries); qemu_vfree(desc_entries);
desc_entries = NULL; desc_entries = NULL;
} }
bdrv_flush(bs); ret = bdrv_flush(bs);
if (ret < 0) {
goto exit;
}
/* once the log is fully flushed, indicate that we have an empty log /* once the log is fully flushed, indicate that we have an empty log
* now. This also sets the log guid to 0, to indicate an empty log */ * now. This also sets the log guid to 0, to indicate an empty log */
vhdx_log_reset(bs, s); vhdx_log_reset(bs, s);
@ -851,6 +868,7 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
uint32_t partial_sectors = 0; uint32_t partial_sectors = 0;
uint32_t bytes_written = 0; uint32_t bytes_written = 0;
uint64_t file_offset; uint64_t file_offset;
int64_t file_length;
VHDXHeader *header; VHDXHeader *header;
VHDXLogEntryHeader new_hdr; VHDXLogEntryHeader new_hdr;
VHDXLogDescriptor *new_desc = NULL; VHDXLogDescriptor *new_desc = NULL;
@ -904,6 +922,12 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
sectors += partial_sectors; sectors += partial_sectors;
file_length = bdrv_getlength(bs->file->bs);
if (file_length < 0) {
ret = file_length;
goto exit;
}
/* sectors is now how many sectors the data itself takes, not /* sectors is now how many sectors the data itself takes, not
* including the header and descriptor metadata */ * including the header and descriptor metadata */
@ -913,11 +937,11 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
.sequence_number = s->log.sequence, .sequence_number = s->log.sequence,
.descriptor_count = sectors, .descriptor_count = sectors,
.reserved = 0, .reserved = 0,
.flushed_file_offset = bdrv_getlength(bs->file->bs), .flushed_file_offset = file_length,
.last_file_offset = bdrv_getlength(bs->file->bs), .last_file_offset = file_length,
.log_guid = header->log_guid,
}; };
new_hdr.log_guid = header->log_guid;
desc_sectors = vhdx_compute_desc_sectors(new_hdr.descriptor_count); desc_sectors = vhdx_compute_desc_sectors(new_hdr.descriptor_count);
@ -1022,7 +1046,11 @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
/* Make sure data written (new and/or changed blocks) is stable /* Make sure data written (new and/or changed blocks) is stable
* on disk, before creating log entry */ * on disk, before creating log entry */
bdrv_flush(bs); ret = bdrv_flush(bs);
if (ret < 0) {
goto exit;
}
ret = vhdx_log_write(bs, s, data, length, offset); ret = vhdx_log_write(bs, s, data, length, offset);
if (ret < 0) { if (ret < 0) {
goto exit; goto exit;
@ -1030,7 +1058,11 @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
logs.log = s->log; logs.log = s->log;
/* Make sure log is stable on disk */ /* Make sure log is stable on disk */
bdrv_flush(bs); ret = bdrv_flush(bs);
if (ret < 0) {
goto exit;
}
ret = vhdx_log_flush(bs, s, &logs); ret = vhdx_log_flush(bs, s, &logs);
if (ret < 0) { if (ret < 0) {
goto exit; goto exit;

View File

@ -1166,10 +1166,20 @@ exit:
static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s, static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
uint64_t *new_offset) uint64_t *new_offset)
{ {
*new_offset = bdrv_getlength(bs->file->bs); int64_t current_len;
current_len = bdrv_getlength(bs->file->bs);
if (current_len < 0) {
return current_len;
}
*new_offset = current_len;
/* per the spec, the address for a block is in units of 1MB */ /* per the spec, the address for a block is in units of 1MB */
*new_offset = ROUND_UP(*new_offset, 1024 * 1024); *new_offset = ROUND_UP(*new_offset, 1024 * 1024);
if (*new_offset > INT64_MAX) {
return -EINVAL;
}
return bdrv_truncate(bs->file, *new_offset + s->block_size, return bdrv_truncate(bs->file, *new_offset + s->block_size,
PREALLOC_MODE_OFF, NULL); PREALLOC_MODE_OFF, NULL);

View File

@ -2236,6 +2236,7 @@ static int vmdk_check(BlockDriverState *bs, BdrvCheckResult *result,
fprintf(stderr, fprintf(stderr,
"ERROR: could not find extent for sector %" PRId64 "\n", "ERROR: could not find extent for sector %" PRId64 "\n",
sector_num); sector_num);
ret = -EINVAL;
break; break;
} }
ret = get_cluster_offset(bs, extent, NULL, ret = get_cluster_offset(bs, extent, NULL,
@ -2247,19 +2248,28 @@ static int vmdk_check(BlockDriverState *bs, BdrvCheckResult *result,
PRId64 "\n", sector_num); PRId64 "\n", sector_num);
break; break;
} }
if (ret == VMDK_OK && if (ret == VMDK_OK) {
cluster_offset >= bdrv_getlength(extent->file->bs)) int64_t extent_len = bdrv_getlength(extent->file->bs);
{ if (extent_len < 0) {
fprintf(stderr, fprintf(stderr,
"ERROR: cluster offset for sector %" "ERROR: could not get extent file length for sector %"
PRId64 " points after EOF\n", sector_num); PRId64 "\n", sector_num);
break; ret = extent_len;
break;
}
if (cluster_offset >= extent_len) {
fprintf(stderr,
"ERROR: cluster offset for sector %"
PRId64 " points after EOF\n", sector_num);
ret = -EINVAL;
break;
}
} }
sector_num += extent->cluster_sectors; sector_num += extent->cluster_sectors;
} }
result->corruptions++; result->corruptions++;
return 0; return ret;
} }
static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs) static ImageInfoSpecific *vmdk_get_specific_info(BlockDriverState *bs)

View File

@ -436,7 +436,8 @@ int bdrv_is_allocated_above(BlockDriverState *top, BlockDriverState *base,
bool bdrv_is_read_only(BlockDriverState *bs); bool bdrv_is_read_only(BlockDriverState *bs);
bool bdrv_is_writable(BlockDriverState *bs); bool bdrv_is_writable(BlockDriverState *bs);
int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only, Error **errp); int bdrv_can_set_read_only(BlockDriverState *bs, bool read_only,
bool ignore_allow_rdw, Error **errp);
int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp); int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp);
bool bdrv_is_sg(BlockDriverState *bs); bool bdrv_is_sg(BlockDriverState *bs);
bool bdrv_is_inserted(BlockDriverState *bs); bool bdrv_is_inserted(BlockDriverState *bs);

View File

@ -127,7 +127,6 @@ struct BlockDriver {
Error **errp); Error **errp);
void (*bdrv_close)(BlockDriverState *bs); void (*bdrv_close)(BlockDriverState *bs);
int (*bdrv_create)(const char *filename, QemuOpts *opts, Error **errp); int (*bdrv_create)(const char *filename, QemuOpts *opts, Error **errp);
int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
int (*bdrv_make_empty)(BlockDriverState *bs); int (*bdrv_make_empty)(BlockDriverState *bs);
void (*bdrv_refresh_filename)(BlockDriverState *bs, QDict *options); void (*bdrv_refresh_filename)(BlockDriverState *bs, QDict *options);

View File

@ -1920,6 +1920,7 @@ static void reopen_help(void)
" 'reopen -o lazy-refcounts=on' - activates lazy refcount writeback on a qcow2 image\n" " 'reopen -o lazy-refcounts=on' - activates lazy refcount writeback on a qcow2 image\n"
"\n" "\n"
" -r, -- Reopen the image read-only\n" " -r, -- Reopen the image read-only\n"
" -w, -- Reopen the image read-write\n"
" -c, -- Change the cache mode to the given value\n" " -c, -- Change the cache mode to the given value\n"
" -o, -- Changes block driver options (cf. 'open' command)\n" " -o, -- Changes block driver options (cf. 'open' command)\n"
"\n"); "\n");
@ -1942,7 +1943,7 @@ static const cmdinfo_t reopen_cmd = {
.argmin = 0, .argmin = 0,
.argmax = -1, .argmax = -1,
.cfunc = reopen_f, .cfunc = reopen_f,
.args = "[-r] [-c cache] [-o options]", .args = "[(-r|-w)] [-c cache] [-o options]",
.oneline = "reopens an image with new options", .oneline = "reopens an image with new options",
.help = reopen_help, .help = reopen_help,
}; };
@ -1955,11 +1956,12 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
int c; int c;
int flags = bs->open_flags; int flags = bs->open_flags;
bool writethrough = !blk_enable_write_cache(blk); bool writethrough = !blk_enable_write_cache(blk);
bool has_rw_option = false;
BlockReopenQueue *brq; BlockReopenQueue *brq;
Error *local_err = NULL; Error *local_err = NULL;
while ((c = getopt(argc, argv, "c:o:r")) != -1) { while ((c = getopt(argc, argv, "c:o:rw")) != -1) {
switch (c) { switch (c) {
case 'c': case 'c':
if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) { if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) {
@ -1974,7 +1976,20 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
} }
break; break;
case 'r': case 'r':
if (has_rw_option) {
error_report("Only one -r/-w option may be given");
return 0;
}
flags &= ~BDRV_O_RDWR; flags &= ~BDRV_O_RDWR;
has_rw_option = true;
break;
case 'w':
if (has_rw_option) {
error_report("Only one -r/-w option may be given");
return 0;
}
flags |= BDRV_O_RDWR;
has_rw_option = true;
break; break;
default: default:
qemu_opts_reset(&reopen_opts); qemu_opts_reset(&reopen_opts);

View File

@ -67,7 +67,8 @@ function run_qemu()
_send_qemu_cmd $QEMU_HANDLE '' "BLOCK_JOB_COMPLETED" _send_qemu_cmd $QEMU_HANDLE '' "BLOCK_JOB_COMPLETED"
fi fi
_send_qemu_cmd $QEMU_HANDLE '{"execute":"query-block-jobs"}' "return" _send_qemu_cmd $QEMU_HANDLE '{"execute":"query-block-jobs"}' "return"
_cleanup_qemu _send_qemu_cmd $QEMU_HANDLE '{"execute":"quit"}' "return"
wait=1 _cleanup_qemu
} }
for fmt in qcow qcow2 qed vdi vmdk vpc; do for fmt in qcow qcow2 qed vdi vmdk vpc; do

View File

@ -12,12 +12,17 @@ Specify the 'raw' format explicitly to remove the restrictions.
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []} {"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0 read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}} {"return": {}}
{"return": {}} {"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
Warning: Image size mismatch! Warning: Image size mismatch!
Images are identical. Images are identical.
@ -33,12 +38,17 @@ Specify the 'raw' format explicitly to remove the restrictions.
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 512, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 512, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []} {"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0 read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}} {"return": {}}
{"return": {}} {"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 197120, "offset": 197120, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 197120, "offset": 197120, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 197120, "offset": 197120, "speed": 0, "type": "mirror"}}
Warning: Image size mismatch! Warning: Image size mismatch!
Images are identical. Images are identical.
@ -54,12 +64,17 @@ Specify the 'raw' format explicitly to remove the restrictions.
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 262144, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 262144, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []} {"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0 read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}} {"return": {}}
{"return": {}} {"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
Warning: Image size mismatch! Warning: Image size mismatch!
Images are identical. Images are identical.
@ -75,12 +90,17 @@ Specify the 'raw' format explicitly to remove the restrictions.
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []} {"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0 read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}} {"return": {}}
{"return": {}} {"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 1024, "offset": 1024, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 1024, "offset": 1024, "speed": 0, "type": "mirror"}}
Warning: Image size mismatch! Warning: Image size mismatch!
Images are identical. Images are identical.
@ -96,12 +116,17 @@ Specify the 'raw' format explicitly to remove the restrictions.
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []} {"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0 read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}} {"return": {}}
{"return": {}} {"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 65536, "offset": 65536, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 65536, "offset": 65536, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 65536, "offset": 65536, "speed": 0, "type": "mirror"}}
Warning: Image size mismatch! Warning: Image size mismatch!
Images are identical. Images are identical.
@ -117,12 +142,17 @@ Specify the 'raw' format explicitly to remove the restrictions.
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []} {"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0 read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}} {"return": {}}
{"return": {}} {"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
Warning: Image size mismatch! Warning: Image size mismatch!
Images are identical. Images are identical.
@ -137,12 +167,17 @@ Specify the 'raw' format explicitly to remove the restrictions.
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []} {"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0 read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}} {"return": {}}
{"return": {}} {"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2560, "offset": 2560, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2560, "offset": 2560, "speed": 0, "type": "mirror"}}
Warning: Image size mismatch! Warning: Image size mismatch!
Images are identical. Images are identical.
@ -157,12 +192,17 @@ Specify the 'raw' format explicitly to remove the restrictions.
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []} {"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0 read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}} {"return": {}}
{"return": {}} {"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 31457280, "offset": 31457280, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 31457280, "offset": 31457280, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 31457280, "offset": 31457280, "speed": 0, "type": "mirror"}}
Warning: Image size mismatch! Warning: Image size mismatch!
Images are identical. Images are identical.
@ -177,12 +217,17 @@ Specify the 'raw' format explicitly to remove the restrictions.
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []} {"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0 read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}} {"return": {}}
{"return": {}} {"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 327680, "offset": 327680, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 327680, "offset": 327680, "speed": 0, "type": "mirror"}}
Warning: Image size mismatch! Warning: Image size mismatch!
Images are identical. Images are identical.
@ -197,12 +242,17 @@ Specify the 'raw' format explicitly to remove the restrictions.
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_ERROR", "data": {"device": "src", "operation": "write", "action": "report"}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []} {"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0 read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}} {"return": {}}
{"return": {}} {"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2048, "offset": 2048, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 2048, "offset": 2048, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 2048, "offset": 2048, "speed": 0, "type": "mirror"}}
Warning: Image size mismatch! Warning: Image size mismatch!
Images are identical. Images are identical.
@ -216,12 +266,18 @@ Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}} {"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
Warning: Image size mismatch! Warning: Image size mismatch!
Images are identical. Images are identical.
{"return": {}} {"return": {}}
{"return": {}} {"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}} {"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_READY", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
{"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]} {"return": [{"io-status": "ok", "device": "src", "busy": false, "len": 512, "offset": 512, "paused": false, "speed": 0, "ready": true, "type": "mirror"}]}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "BLOCK_JOB_COMPLETED", "data": {"device": "src", "len": 512, "offset": 512, "speed": 0, "type": "mirror"}}
Warning: Image size mismatch! Warning: Image size mismatch!
Images are identical. Images are identical.
*** done *** done

View File

@ -75,7 +75,7 @@ sector = "%d"
drive_args.append("stats-account-failed=%s" % drive_args.append("stats-account-failed=%s" %
(self.account_failed and "on" or "off")) (self.account_failed and "on" or "off"))
self.create_blkdebug_file() self.create_blkdebug_file()
self.vm = iotests.VM().add_drive('blkdebug:%s:%s ' % self.vm = iotests.VM().add_drive('blkdebug:%s:%s' %
(blkdebug_file, self.test_img), (blkdebug_file, self.test_img),
','.join(drive_args)) ','.join(drive_args))
self.vm.launch() self.vm.launch()

69
tests/qemu-iotests/187 Executable file
View File

@ -0,0 +1,69 @@
#!/bin/bash
#
# Test switching between read-only and read-write
#
# Copyright (C) 2017 Red Hat, Inc.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
#
# creator
owner=kwolf@redhat.com
seq=`basename $0`
echo "QA output created by $seq"
here=`pwd`
status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
rm -f "$TEST_IMG.2"
rm -f "$TEST_IMG.3"
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
size=64M
_make_test_img $size
echo
echo "Start from read-only"
echo
$QEMU_IO -r -c 'write 0 64k' $TEST_IMG | _filter_qemu_io
$QEMU_IO -r -c 'reopen -w' -c 'write 0 64k' $TEST_IMG | _filter_qemu_io
$QEMU_IO -r -c 'reopen -w' -c 'reopen -r' -c 'write 0 64k' $TEST_IMG | _filter_qemu_io
echo
echo "Start from read-write"
echo
$QEMU_IO -c 'write 0 64k' $TEST_IMG | _filter_qemu_io
$QEMU_IO -c 'reopen -r' -c 'write 0 64k' $TEST_IMG | _filter_qemu_io
$QEMU_IO -c 'reopen -r' -c 'reopen -w' -c 'write 0 64k' $TEST_IMG | _filter_qemu_io
# success, all done
echo "*** done"
rm -f $seq.full
status=0

View File

@ -0,0 +1,18 @@
QA output created by 187
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
Start from read-only
Block node is read-only
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Block node is read-only
Start from read-write
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
write failed: Operation not permitted
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
*** done

View File

@ -182,6 +182,7 @@
183 rw auto migration 183 rw auto migration
185 rw auto 185 rw auto
186 rw auto 186 rw auto
187 rw auto
188 rw auto quick 188 rw auto quick
189 rw auto 189 rw auto
190 rw auto quick 190 rw auto quick