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);
}
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 */
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 */
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",
bdrv_get_device_or_node_name(bs));
return -EPERM;
@ -269,7 +272,7 @@ int bdrv_set_read_only(BlockDriverState *bs, bool read_only, Error **errp)
{
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) {
return ret;
}
@ -1933,6 +1936,8 @@ static void bdrv_replace_child(BdrvChild *child, BlockDriverState *new_bs)
BlockDriverState *old_bs = child->bs;
uint64_t perm, shared_perm;
bdrv_replace_child_noperm(child, new_bs);
if (old_bs) {
/* Update permissions for old node. This is guaranteed to succeed
* 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_replace_child_noperm(child, new_bs);
if (new_bs) {
bdrv_get_cumulative_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);
QDECREF(old_options);
/* bdrv_open() masks this flag out */
/* bdrv_open_inherit() sets and clears some additional flags internally */
flags &= ~BDRV_O_PROTOCOL;
if (flags & BDRV_O_RDWR) {
flags |= BDRV_O_ALLOW_RDWR;
}
QLIST_FOREACH(child, &bs->children, next) {
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
* not set, or if the BDS still has copy_on_read enabled */
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) {
error_propagate(errp, local_err);
goto error;

View File

@ -1339,6 +1339,9 @@ static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb)
#if defined(CONFIG_FALLOCATE) || defined(CONFIG_XFS)
BDRVRawState *s = aiocb->bs->opaque;
#endif
#ifdef CONFIG_FALLOCATE
int64_t len;
#endif
if (aiocb->aio_type & QEMU_AIO_BLKDEV) {
return handle_aiocb_write_zeroes_block(aiocb);
@ -1381,7 +1384,10 @@ static ssize_t handle_aiocb_write_zeroes(RawPosixAIOData *aiocb)
#endif
#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);
if (ret == 0 || ret != -ENOTSUP) {
return ret;

View File

@ -433,19 +433,23 @@ static void nfs_client_close(NFSClient *client)
if (client->context) {
if (client->fh) {
nfs_close(client->context, client->fh);
client->fh = NULL;
}
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
false, NULL, NULL, NULL, NULL);
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)
{
NFSClient *client = bs->opaque;
nfs_client_close(client);
qemu_mutex_destroy(&client->mutex);
}
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;
char *file = NULL, *strp = NULL;
qemu_mutex_init(&client->mutex);
opts = qemu_opts_create(&runtime_opts, NULL, 0, &error_abort);
qemu_opts_absorb_qdict(opts, options, &local_err);
if (local_err) {
@ -660,7 +665,7 @@ static int nfs_file_open(BlockDriverState *bs, QDict *options, int flags,
if (ret < 0) {
return ret;
}
qemu_mutex_init(&client->mutex);
bs->total_sectors = ret;
ret = 0;
return ret;

View File

@ -29,11 +29,6 @@ static QemuOptsList runtime_opts = {
.name = "null",
.head = QTAILQ_HEAD_INITIALIZER(runtime_opts.head),
.desc = {
{
.name = "filename",
.type = QEMU_OPT_STRING,
.help = "",
},
{
.name = BLOCK_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,
Error **errp)
{
@ -242,6 +261,7 @@ static BlockDriver bdrv_null_co = {
.instance_size = sizeof(BDRVNullState),
.bdrv_file_open = null_file_open,
.bdrv_parse_filename = null_co_parse_filename,
.bdrv_close = null_close,
.bdrv_getlength = null_getlength,
@ -261,6 +281,7 @@ static BlockDriver bdrv_null_aio = {
.instance_size = sizeof(BDRVNullState),
.bdrv_file_open = null_file_open,
.bdrv_parse_filename = null_aio_parse_filename,
.bdrv_close = null_close,
.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)
{
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);
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);
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;
space += s->prealloc_size;
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;
}
if (!(flags & BDRV_O_RESIZE) || !bdrv_has_zero_init(bs->file->bs) ||
bdrv_truncate(bs->file, bdrv_getlength(bs->file->bs),
PREALLOC_MODE_OFF, NULL) != 0) {
if (!bdrv_has_zero_init(bs->file->bs)) {
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++) {
result = bdrv_co_flush(s->children[i]->bs);
if (result) {
quorum_report_bad(QUORUM_OP_TYPE_FLUSH, 0,
bdrv_getlength(s->children[i]->bs),
quorum_report_bad(QUORUM_OP_TYPE_FLUSH, 0, 0,
s->children[i]->bs->node_name, result);
result_value.l = result;
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;
uint64_t new_file_size;
void *data = NULL;
int64_t file_length;
VHDXLogDescEntries *desc_entries = NULL;
VHDXLogEntryHeader hdr_tmp = { 0 };
@ -510,10 +511,15 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
if (ret < 0) {
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
* size, then that means the file has been truncated / corrupted, and
* 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;
goto exit;
}
@ -543,19 +549,30 @@ static int vhdx_log_flush(BlockDriverState *bs, BDRVVHDXState *s,
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;
if (new_file_size % (1024*1024)) {
/* round up to nearest 1MB boundary */
new_file_size = ((new_file_size >> 20) + 1) << 20;
bdrv_truncate(bs->file, new_file_size, PREALLOC_MODE_OFF, NULL);
new_file_size = QEMU_ALIGN_UP(new_file_size, MiB);
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);
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
* now. This also sets the log guid to 0, to indicate an empty log */
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 bytes_written = 0;
uint64_t file_offset;
int64_t file_length;
VHDXHeader *header;
VHDXLogEntryHeader new_hdr;
VHDXLogDescriptor *new_desc = NULL;
@ -904,6 +922,12 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
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
* including the header and descriptor metadata */
@ -913,11 +937,11 @@ static int vhdx_log_write(BlockDriverState *bs, BDRVVHDXState *s,
.sequence_number = s->log.sequence,
.descriptor_count = sectors,
.reserved = 0,
.flushed_file_offset = bdrv_getlength(bs->file->bs),
.last_file_offset = bdrv_getlength(bs->file->bs),
.flushed_file_offset = file_length,
.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);
@ -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
* 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);
if (ret < 0) {
goto exit;
@ -1030,7 +1058,11 @@ int vhdx_log_write_and_flush(BlockDriverState *bs, BDRVVHDXState *s,
logs.log = s->log;
/* 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);
if (ret < 0) {
goto exit;

View File

@ -1166,10 +1166,20 @@ exit:
static int vhdx_allocate_block(BlockDriverState *bs, BDRVVHDXState *s,
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 */
*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,
PREALLOC_MODE_OFF, NULL);

View File

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

View File

@ -127,7 +127,6 @@ struct BlockDriver {
Error **errp);
void (*bdrv_close)(BlockDriverState *bs);
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);
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"
"\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"
" -o, -- Changes block driver options (cf. 'open' command)\n"
"\n");
@ -1942,7 +1943,7 @@ static const cmdinfo_t reopen_cmd = {
.argmin = 0,
.argmax = -1,
.cfunc = reopen_f,
.args = "[-r] [-c cache] [-o options]",
.args = "[(-r|-w)] [-c cache] [-o options]",
.oneline = "reopens an image with new options",
.help = reopen_help,
};
@ -1955,11 +1956,12 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
int c;
int flags = bs->open_flags;
bool writethrough = !blk_enable_write_cache(blk);
bool has_rw_option = false;
BlockReopenQueue *brq;
Error *local_err = NULL;
while ((c = getopt(argc, argv, "c:o:r")) != -1) {
while ((c = getopt(argc, argv, "c:o:rw")) != -1) {
switch (c) {
case 'c':
if (bdrv_parse_cache_mode(optarg, &flags, &writethrough) < 0) {
@ -1974,7 +1976,20 @@ static int reopen_f(BlockBackend *blk, int argc, char **argv)
}
break;
case 'r':
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;
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;
default:
qemu_opts_reset(&reopen_opts);

View File

@ -67,7 +67,8 @@ function run_qemu()
_send_qemu_cmd $QEMU_HANDLE '' "BLOCK_JOB_COMPLETED"
fi
_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

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_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"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": {}}
{"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!
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_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 512, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"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": {}}
{"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!
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_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 262144, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"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": {}}
{"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!
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_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"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": {}}
{"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!
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_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"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": {}}
{"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!
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_COMPLETED", "data": {"device": "src", "len": LEN, "offset": 0, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"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": {}}
{"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!
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_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"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": {}}
{"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!
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_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"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": {}}
{"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!
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_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"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": {}}
{"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!
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_COMPLETED", "data": {"device": "src", "len": LEN, "offset": OFFSET, "speed": 0, "type": "mirror", "error": "Operation not permitted"}}
{"return": []}
{"return": {}}
{"timestamp": {"seconds": TIMESTAMP, "microseconds": TIMESTAMP}, "event": "SHUTDOWN", "data": {"guest": false}}
read 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
{"return": {}}
{"return": {}}
{"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": {}}
{"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!
Images are identical.
@ -216,12 +266,18 @@ Specify the 'raw' format explicitly to remove the restrictions.
{"return": {}}
{"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": {}}
{"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!
Images are identical.
{"return": {}}
{"return": {}}
{"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": {}}
{"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!
Images are identical.
*** done

View File

@ -75,7 +75,7 @@ sector = "%d"
drive_args.append("stats-account-failed=%s" %
(self.account_failed and "on" or "off"))
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),
','.join(drive_args))
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
185 rw auto
186 rw auto
187 rw auto
188 rw auto quick
189 rw auto
190 rw auto quick