Block layer patches:

- qcow2: Allow overwriting multiple compressed clusters at once for
   better performance
 - nfs: add support for nfs_umount
 - file-posix: write_zeroes fixes
 - qemu-io, blockdev-create, pr-manager: Fix crashes and memory leaks
 - qcow2: Fix the calculation of the maximum L2 cache size
 - vpc: Fix return code for vpc_co_create()
 - blockjob: Code cleanup
 - iotests improvements (e.g. for use with valgrind)
 -----BEGIN PGP SIGNATURE-----
 
 iQIcBAABAgAGBQJde20nAAoJEH8JsnLIjy/WilcP/RGqhScaROcvr584XRJ+/r0p
 Wx/r1dfAL7uWaCrUt0Z7BtoAQb0vTJLAmShRvyfyDqSurPoTCGunQhXqHC/eX3oK
 fo6iB/fjXKCEsEjKcgamxv6it9rz3wjqeQLLakHZW4Z62yXAfyFZE/vXYdx6IS5B
 UlVI2gOjz3lfGWZCBd1rOQNnOOTtSeBkTMPndrpri5m5gvnZFBaCcAldUtrQwvau
 YQnzPhOsDlz00gR9NqDehQZcBCoNZnhhOMdcGWrvcMbabJ/yY/iqgCVxYq7m2Sol
 olcMw/Mg8Z/Mp2qr4hOUmxoHSEX9y7mZ7hCPRlw/3NdiEQpquIfpILa8CvmO8jqJ
 ZHnLWILf2ZCmU75vTM2ilhvgErtEmYbE39jzRYF/dNfBTwfx9Yp2eFbG57OWqNyJ
 sEJB3JY+RuPyqP/QX7jAelnL2jtSmyhmV1dBYIpD0cib2+VTCgdgWMoMNlXRXG+8
 9XoRVfBNHvybR7o7xw7xUTmGdkkAZDbNlzGH6ekIn3HCiDqdpL7SUkV7kBUCV9ie
 YKcZMRrwOiYr8agi4SlctyUPY/h1nFJFPKSBdPcKSf353sjZgpzYeubXUJd+kTBX
 orkkJVq9+WcqEKScvqzTraf4CN5FHP7J1rvQdxbP6RWgkY64j4gkMScGv7qu29K2
 WNQrD2Ij+KKC0zprkCx0
 =yYOk
 -----END PGP SIGNATURE-----

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

Block layer patches:

- qcow2: Allow overwriting multiple compressed clusters at once for
  better performance
- nfs: add support for nfs_umount
- file-posix: write_zeroes fixes
- qemu-io, blockdev-create, pr-manager: Fix crashes and memory leaks
- qcow2: Fix the calculation of the maximum L2 cache size
- vpc: Fix return code for vpc_co_create()
- blockjob: Code cleanup
- iotests improvements (e.g. for use with valgrind)

# gpg: Signature made Fri 13 Sep 2019 11:19:19 BST
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream: (23 commits)
  qcow2: Stop overwriting compressed clusters one by one
  block/create: Do not abort if a block driver is not available
  qemu-io: Don't leak pattern file in error path
  iotests: extend sleeping time under Valgrind
  iotests: extended timeout under Valgrind
  iotests: Valgrind fails with nonexistent directory
  iotests: Add casenotrun report to bash tests
  iotests: exclude killed processes from running under Valgrind
  iotests: allow Valgrind checking all QEMU processes
  block/nfs: add support for nfs_umount
  block/nfs: tear down aio before nfs_close
  iotests: skip 232 when run tests as root
  iotests: Test blockdev-create for vpc
  iotests: Restrict nbd Python tests to nbd
  iotests: Restrict file Python tests to file
  iotests: Add supported protocols to execute_test()
  vpc: Return 0 from vpc_co_create() on success
  file-posix: Fix has_write_zeroes after NO_FALLBACK
  pr-manager: Fix invalid g_free() crash bug
  iotests: Test reverse sub-cluster qcow2 writes
  ...

Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
Peter Maydell 2019-09-13 13:43:42 +01:00
commit 3d9442ee1d
67 changed files with 593 additions and 293 deletions

View File

@ -425,21 +425,6 @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
bdrv_set_dirty_bitmap(backup_job->copy_bitmap, 0, backup_job->len);
}
static void backup_drain(BlockJob *job)
{
BackupBlockJob *s = container_of(job, BackupBlockJob, common);
/* Need to keep a reference in case blk_drain triggers execution
* of backup_complete...
*/
if (s->target) {
BlockBackend *target = s->target;
blk_ref(target);
blk_drain(target);
blk_unref(target);
}
}
static BlockErrorAction backup_error_action(BackupBlockJob *job,
bool read, int error)
{
@ -588,13 +573,11 @@ static const BlockJobDriver backup_job_driver = {
.job_type = JOB_TYPE_BACKUP,
.free = block_job_free,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
.run = backup_run,
.commit = backup_commit,
.abort = backup_abort,
.clean = backup_clean,
},
.drain = backup_drain,
}
};
static int64_t backup_calculate_cluster_size(BlockDriverState *target,

View File

@ -216,7 +216,6 @@ static const BlockJobDriver commit_job_driver = {
.job_type = JOB_TYPE_COMMIT,
.free = block_job_free,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
.run = commit_run,
.prepare = commit_prepare,
.abort = commit_abort,

View File

@ -64,9 +64,13 @@ void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
const char *fmt = BlockdevDriver_str(options->driver);
BlockDriver *drv = bdrv_find_format(fmt);
if (!drv) {
error_setg(errp, "Block driver '%s' not found or not supported", fmt);
return;
}
/* If the driver is in the schema, we know that it exists. But it may not
* be whitelisted. */
assert(drv);
if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) {
error_setg(errp, "Driver is not whitelisted");
return;

View File

@ -1459,59 +1459,6 @@ out:
}
}
#ifdef CONFIG_XFS
static int xfs_write_zeroes(BDRVRawState *s, int64_t offset, uint64_t bytes)
{
int64_t len;
struct xfs_flock64 fl;
int err;
len = lseek(s->fd, 0, SEEK_END);
if (len < 0) {
return -errno;
}
if (offset + bytes > len) {
/* XFS_IOC_ZERO_RANGE does not increase the file length */
if (ftruncate(s->fd, offset + bytes) < 0) {
return -errno;
}
}
memset(&fl, 0, sizeof(fl));
fl.l_whence = SEEK_SET;
fl.l_start = offset;
fl.l_len = bytes;
if (xfsctl(NULL, s->fd, XFS_IOC_ZERO_RANGE, &fl) < 0) {
err = errno;
trace_file_xfs_write_zeroes(strerror(errno));
return -err;
}
return 0;
}
static int xfs_discard(BDRVRawState *s, int64_t offset, uint64_t bytes)
{
struct xfs_flock64 fl;
int err;
memset(&fl, 0, sizeof(fl));
fl.l_whence = SEEK_SET;
fl.l_start = offset;
fl.l_len = bytes;
if (xfsctl(NULL, s->fd, XFS_IOC_UNRESVSP64, &fl) < 0) {
err = errno;
trace_file_xfs_discard(strerror(errno));
return -err;
}
return 0;
}
#endif
static int translate_err(int err)
{
if (err == -ENODEV || err == -ENOSYS || err == -EOPNOTSUPP ||
@ -1555,22 +1502,20 @@ static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
} while (errno == EINTR);
ret = translate_err(-errno);
if (ret == -ENOTSUP) {
s->has_write_zeroes = false;
}
}
#endif
if (ret == -ENOTSUP) {
s->has_write_zeroes = false;
}
return ret;
}
static int handle_aiocb_write_zeroes(void *opaque)
{
RawPosixAIOData *aiocb = opaque;
#if defined(CONFIG_FALLOCATE) || defined(CONFIG_XFS)
BDRVRawState *s = aiocb->bs->opaque;
#endif
#ifdef CONFIG_FALLOCATE
BDRVRawState *s = aiocb->bs->opaque;
int64_t len;
#endif
@ -1578,12 +1523,6 @@ static int handle_aiocb_write_zeroes(void *opaque)
return handle_aiocb_write_zeroes_block(aiocb);
}
#ifdef CONFIG_XFS
if (s->is_xfs) {
return xfs_write_zeroes(s, aiocb->aio_offset, aiocb->aio_nbytes);
}
#endif
#ifdef CONFIG_FALLOCATE_ZERO_RANGE
if (s->has_write_zeroes) {
int ret = do_fallocate(s->fd, FALLOC_FL_ZERO_RANGE,
@ -1653,14 +1592,6 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
}
#endif
#ifdef CONFIG_XFS
if (s->is_xfs) {
/* xfs_discard() guarantees that the discarded area reads as all-zero
* afterwards, so we can use it here. */
return xfs_discard(s, aiocb->aio_offset, aiocb->aio_nbytes);
}
#endif
/* If we couldn't manage to unmap while guaranteed that the area reads as
* all-zero afterwards, just write zeroes without unmapping */
ret = handle_aiocb_write_zeroes(aiocb);
@ -1737,12 +1668,6 @@ static int handle_aiocb_discard(void *opaque)
ret = -errno;
#endif
} else {
#ifdef CONFIG_XFS
if (s->is_xfs) {
return xfs_discard(s, aiocb->aio_offset, aiocb->aio_nbytes);
}
#endif
#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
aiocb->aio_offset, aiocb->aio_nbytes);

View File

@ -646,14 +646,11 @@ static int mirror_exit_common(Job *job)
bdrv_ref(mirror_top_bs);
bdrv_ref(target_bs);
/* Remove target parent that still uses BLK_PERM_WRITE/RESIZE before
/*
* Remove target parent that still uses BLK_PERM_WRITE/RESIZE before
* inserting target_bs at s->to_replace, where we might not be able to get
* these permissions.
*
* Note that blk_unref() alone doesn't necessarily drop permissions because
* we might be running nested inside mirror_drain(), which takes an extra
* reference, so use an explicit blk_set_perm() first. */
blk_set_perm(s->target, 0, BLK_PERM_ALL, &error_abort);
*/
blk_unref(s->target);
s->target = NULL;
@ -1149,28 +1146,12 @@ static bool mirror_drained_poll(BlockJob *job)
return !!s->in_flight;
}
static void mirror_drain(BlockJob *job)
{
MirrorBlockJob *s = container_of(job, MirrorBlockJob, common);
/* Need to keep a reference in case blk_drain triggers execution
* of mirror_complete...
*/
if (s->target) {
BlockBackend *target = s->target;
blk_ref(target);
blk_drain(target);
blk_unref(target);
}
}
static const BlockJobDriver mirror_job_driver = {
.job_driver = {
.instance_size = sizeof(MirrorBlockJob),
.job_type = JOB_TYPE_MIRROR,
.free = block_job_free,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
.run = mirror_run,
.prepare = mirror_prepare,
.abort = mirror_abort,
@ -1178,7 +1159,6 @@ static const BlockJobDriver mirror_job_driver = {
.complete = mirror_complete,
},
.drained_poll = mirror_drained_poll,
.drain = mirror_drain,
};
static const BlockJobDriver commit_active_job_driver = {
@ -1187,7 +1167,6 @@ static const BlockJobDriver commit_active_job_driver = {
.job_type = JOB_TYPE_COMMIT,
.free = block_job_free,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
.run = mirror_run,
.prepare = mirror_prepare,
.abort = mirror_abort,
@ -1195,7 +1174,6 @@ static const BlockJobDriver commit_active_job_driver = {
.complete = mirror_complete,
},
.drained_poll = mirror_drained_poll,
.drain = mirror_drain,
};
static void coroutine_fn

View File

@ -390,12 +390,17 @@ static void nfs_attach_aio_context(BlockDriverState *bs,
static void nfs_client_close(NFSClient *client)
{
if (client->context) {
qemu_mutex_lock(&client->mutex);
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
false, NULL, NULL, NULL, NULL);
qemu_mutex_unlock(&client->mutex);
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);
#ifdef LIBNFS_FEATURE_UMOUNT
nfs_umount(client->context);
#endif
nfs_destroy_context(client->context);
client->context = NULL;
}

View File

@ -1351,13 +1351,7 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
}
entry = be64_to_cpu(l2_slice[l2_index]);
/* For the moment, overwrite compressed clusters one by one */
if (entry & QCOW_OFLAG_COMPRESSED) {
nb_clusters = 1;
} else {
nb_clusters = count_cow_clusters(bs, nb_clusters, l2_slice, l2_index);
}
nb_clusters = count_cow_clusters(bs, nb_clusters, l2_slice, l2_index);
/* This function is only called when there were no non-COW clusters, so if
* we can't find any unallocated or COW clusters either, something is

View File

@ -828,7 +828,11 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
bool l2_cache_entry_size_set;
int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_SIZE;
uint64_t max_l2_cache = virtual_disk_size / (s->cluster_size / 8);
uint64_t max_l2_entries = DIV_ROUND_UP(virtual_disk_size, s->cluster_size);
/* An L2 table is always one cluster in size so the max cache size
* should be a multiple of the cluster size. */
uint64_t max_l2_cache = ROUND_UP(max_l2_entries * sizeof(uint64_t),
s->cluster_size);
combined_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_CACHE_SIZE);
l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE);

View File

@ -212,7 +212,6 @@ static const BlockJobDriver stream_job_driver = {
.abort = stream_abort,
.clean = stream_clean,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
},
};

View File

@ -885,6 +885,7 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
goto fail;
}
ret = 0;
fail:
return ret;
}
@ -908,7 +909,7 @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
return ret;
}
return ret;
return 0;
}
static int calculate_rounded_image_size(BlockdevCreateOptionsVpc *vpc_opts,

View File

@ -90,18 +90,6 @@ void block_job_free(Job *job)
error_free(bjob->blocker);
}
void block_job_drain(Job *job)
{
BlockJob *bjob = container_of(job, BlockJob, job);
const JobDriver *drv = job->driver;
BlockJobDriver *bjdrv = container_of(drv, BlockJobDriver, job_driver);
blk_drain(bjob->blk);
if (bjdrv->drain) {
bjdrv->drain(bjob);
}
}
static char *child_job_get_parent_desc(BdrvChild *c)
{
BlockJob *job = c->opaque;
@ -422,7 +410,6 @@ void *block_job_create(const char *job_id, const BlockJobDriver *driver,
assert(is_block_job(&job->job));
assert(job->job.driver->free == &block_job_free);
assert(job->job.driver->user_resume == &block_job_user_resume);
assert(job->job.driver->drain == &block_job_drain);
job->blk = blk;

View File

@ -52,17 +52,6 @@ struct BlockJobDriver {
* besides job->blk to the new AioContext.
*/
void (*attached_aio_context)(BlockJob *job, AioContext *new_context);
/*
* If the callback is not NULL, it will be invoked when the job has to be
* synchronously cancelled or completed; it should drain BlockDriverStates
* as required to ensure progress.
*
* Block jobs must use the default implementation for job_driver.drain,
* which will in turn call this callback after doing generic block job
* stuff.
*/
void (*drain)(BlockJob *job);
};
/**
@ -107,14 +96,6 @@ void block_job_free(Job *job);
*/
void block_job_user_resume(Job *job);
/**
* block_job_drain:
* Callback to be used for JobDriver.drain in all block jobs. Drains the main
* block node associated with the block jobs and calls BlockJobDriver.drain for
* job-specific actions.
*/
void block_job_drain(Job *job);
/**
* block_job_ratelimit_get_delay:
*

View File

@ -220,13 +220,6 @@ struct JobDriver {
*/
void (*complete)(Job *job, Error **errp);
/*
* If the callback is not NULL, it will be invoked when the job has to be
* synchronously cancelled or completed; it should drain any activities
* as required to ensure progress.
*/
void (*drain)(Job *job);
/**
* If the callback is not NULL, prepare will be invoked when all the jobs
* belonging to the same transaction complete; or upon this job's completion
@ -470,12 +463,6 @@ bool job_user_paused(Job *job);
*/
void job_user_resume(Job *job, Error **errp);
/*
* Drain any activities as required to ensure progress. This can be called in a
* loop to synchronously complete a job.
*/
void job_drain(Job *job);
/**
* Get the next element from the list of block jobs after @job, or the
* first one if @job is %NULL.

12
job.c
View File

@ -523,16 +523,6 @@ void coroutine_fn job_sleep_ns(Job *job, int64_t ns)
job_pause_point(job);
}
void job_drain(Job *job)
{
/* If job is !busy this kicks it into the next pause point. */
job_enter(job);
if (job->driver->drain) {
job->driver->drain(job);
}
}
/* Assumes the block_job_mutex is held */
static bool job_timer_not_pending(Job *job)
{
@ -991,7 +981,7 @@ int job_finish_sync(Job *job, void (*finish)(Job *, Error **errp), Error **errp)
}
AIO_WAIT_WHILE(job->aio_context,
(job_drain(job), !job_is_completed(job)));
(job_enter(job), !job_is_completed(job)));
ret = (job_is_cancelled(job) && job->ret == 0) ? -ECANCELED : job->ret;
job_unref(job);

View File

@ -401,6 +401,7 @@ static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
}
fclose(f);
f = NULL;
if (len > pattern_len) {
len -= pattern_len;
@ -420,6 +421,9 @@ static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
error:
qemu_io_free(buf_origin);
if (f) {
fclose(f);
}
return NULL;
}

View File

@ -39,7 +39,6 @@ static int pr_manager_worker(void *opaque)
int fd = data->fd;
int r;
g_free(data);
trace_pr_manager_run(fd, hdr->cmdp[0], hdr->cmdp[1]);
/* The reference was taken in pr_manager_execute. */

View File

@ -110,7 +110,11 @@ echo
qemu_comm_method="monitor"
_launch_qemu -drive file="${TEST_IMG}",cache=${CACHEMODE},id=disk
h=$QEMU_HANDLE
QEMU_COMM_TIMEOUT=1
if [ "${VALGRIND_QEMU}" == "y" ]; then
QEMU_COMM_TIMEOUT=7
else
QEMU_COMM_TIMEOUT=1
fi
# Silence output since it contains the disk image path and QEMU's readline
# character echoing makes it very hard to filter the output. Plus, there

View File

@ -957,4 +957,5 @@ class TestSetSpeed(iotests.QMPTestCase):
self.cancel_and_wait(resume=True)
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2', 'qed'])
iotests.main(supported_fmts=['qcow2', 'qed'],
supported_protocols=['file'])

View File

@ -65,6 +65,7 @@ echo "== Creating a dirty image file =="
IMGOPTS="compat=1.1,lazy_refcounts=on"
_make_test_img $size
_NO_VALGRIND \
$QEMU_IO -c "write -P 0x5a 0 512" \
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
| _filter_qemu_io
@ -100,6 +101,7 @@ echo "== Opening a dirty image read/write should repair it =="
IMGOPTS="compat=1.1,lazy_refcounts=on"
_make_test_img $size
_NO_VALGRIND \
$QEMU_IO -c "write -P 0x5a 0 512" \
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
| _filter_qemu_io
@ -118,6 +120,7 @@ echo "== Creating an image file with lazy_refcounts=off =="
IMGOPTS="compat=1.1,lazy_refcounts=off"
_make_test_img $size
_NO_VALGRIND \
$QEMU_IO -c "write -P 0x5a 0 512" \
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
| _filter_qemu_io
@ -151,6 +154,7 @@ echo "== Changing lazy_refcounts setting at runtime =="
IMGOPTS="compat=1.1,lazy_refcounts=off"
_make_test_img $size
_NO_VALGRIND \
$QEMU_IO -c "reopen -o lazy-refcounts=on" \
-c "write -P 0x5a 0 512" \
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
@ -163,6 +167,7 @@ _check_test_img
IMGOPTS="compat=1.1,lazy_refcounts=on"
_make_test_img $size
_NO_VALGRIND \
$QEMU_IO -c "reopen -o lazy-refcounts=off" \
-c "write -P 0x5a 0 512" \
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \

View File

@ -11,11 +11,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
else
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
fi )
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
incompatible_features 0x1
ERROR cluster 5 refcount=0 reference=1
ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
@ -50,11 +46,7 @@ read 512/512 bytes at offset 0
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
else
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
fi )
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
incompatible_features 0x1
ERROR cluster 5 refcount=0 reference=1
Rebuilding refcount structure
@ -68,11 +60,7 @@ incompatible_features 0x0
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
else
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
fi )
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
incompatible_features 0x0
No errors were found on the image.
@ -91,11 +79,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
else
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
fi )
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
incompatible_features 0x1
ERROR cluster 5 refcount=0 reference=1
ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
@ -105,11 +89,7 @@ Data may be corrupted, or further writes to the image may corrupt it.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
else
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
fi )
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
incompatible_features 0x0
No errors were found on the image.
*** done

View File

@ -429,4 +429,5 @@ class TestReopenOverlay(ImageCommitTestCase):
self.run_commit_test(self.img1, self.img0)
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2', 'qed'])
iotests.main(supported_fmts=['qcow2', 'qed'],
supported_protocols=['file'])

View File

@ -1122,4 +1122,5 @@ class TestOrphanedSource(iotests.QMPTestCase):
self.assert_qmp(result, 'error/class', 'GenericError')
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2', 'qed'])
iotests.main(supported_fmts=['qcow2', 'qed'],
supported_protocols=['file'])

View File

@ -118,4 +118,5 @@ class TestRefcountTableGrowth(iotests.QMPTestCase):
pass
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'])
iotests.main(supported_fmts=['qcow2'],
supported_protocols=['file'])

View File

@ -175,4 +175,5 @@ class TestSCMFd(iotests.QMPTestCase):
"File descriptor named '%s' not found" % fdname)
if __name__ == '__main__':
iotests.main(supported_fmts=['raw'])
iotests.main(supported_fmts=['raw'],
supported_protocols=['file'])

View File

@ -377,6 +377,10 @@ printf %b "qemu-io $device_id \"write -P 0x33 0 4k\"\ncommit $device_id\n" |
$QEMU_IO -c "read -P 0x33 0 4k" "$TEST_IMG" | _filter_qemu_io
# Using snapshot=on with a non-existent TMPDIR
if [ "${VALGRIND_QEMU_VM}" == "y" ]; then
_casenotrun "Valgrind needs a valid TMPDIR for itself"
fi
VALGRIND_QEMU_VM= \
TMPDIR=/nonexistent run_qemu -drive driver=null-co,snapshot=on
# Using snapshot=on together with read-only=on

View File

@ -563,4 +563,5 @@ class TestDriveCompression(iotests.QMPTestCase):
target='drive1')
if __name__ == '__main__':
iotests.main(supported_fmts=['raw', 'qcow2'])
iotests.main(supported_fmts=['raw', 'qcow2'],
supported_protocols=['file'])

View File

@ -335,4 +335,5 @@ class BackupTest(iotests.QMPTestCase):
self.dismissal_failure(True)
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2', 'qed'])
iotests.main(supported_fmts=['qcow2', 'qed'],
supported_protocols=['file'])

View File

@ -256,4 +256,5 @@ class TestSnapshotDelete(ImageSnapshotTestCase):
self.assert_qmp(result, 'error/class', 'GenericError')
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'])
iotests.main(supported_fmts=['qcow2'],
supported_protocols=['file'])

View File

@ -73,6 +73,7 @@ echo
echo "=== Testing dirty version downgrade ==="
echo
IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M
_NO_VALGRIND \
$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io
$PYTHON qcow2.py "$TEST_IMG" dump-header
@ -107,6 +108,7 @@ echo
echo "=== Testing dirty lazy_refcounts=off ==="
echo
IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M
_NO_VALGRIND \
$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io
$PYTHON qcow2.py "$TEST_IMG" dump-header

View File

@ -118,11 +118,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
else
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
fi )
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
magic 0x514649fb
version 3
backing_file_offset 0x0
@ -280,11 +276,7 @@ No errors were found on the image.
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 131072/131072 bytes at offset 0
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
else
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
fi )
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
magic 0x514649fb
version 3
backing_file_offset 0x0

View File

@ -129,4 +129,5 @@ TestQemuImgInfo = None
TestQMP = None
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'])
iotests.main(supported_fmts=['qcow2'],
supported_protocols=['file'])

View File

@ -67,4 +67,5 @@ class TestLiveSnapshot(iotests.QMPTestCase):
self.checkConfig('target')
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'])
iotests.main(supported_fmts=['qcow2'],
supported_protocols=['file'])

View File

@ -717,4 +717,5 @@ if __name__ == '__main__':
iotests.qemu_default_machine)
# Need to support image creation
iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
'vmdk', 'raw', 'vhdx', 'qed'])
'vmdk', 'raw', 'vhdx', 'qed'],
supported_protocols=['file'])

View File

@ -779,4 +779,5 @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'])
iotests.main(supported_fmts=['qcow2'],
supported_protocols=['file'])

View File

@ -83,4 +83,5 @@ class TestStopWithBlockJob(iotests.QMPTestCase):
self.do_test_stop("block-commit", device="drive0")
if __name__ == '__main__':
iotests.main(supported_fmts=["qcow2"])
iotests.main(supported_fmts=["qcow2"],
supported_protocols=["file"])

View File

@ -56,4 +56,5 @@ class TestSingleDrive(iotests.QMPTestCase):
'target image does not match source after mirroring')
if __name__ == '__main__':
iotests.main(supported_fmts=['raw', 'qcow2'])
iotests.main(supported_fmts=['raw', 'qcow2'],
supported_protocols=['file'])

View File

@ -130,6 +130,7 @@ echo
# Whether lazy-refcounts was actually enabled can easily be tested: Check if
# the dirty bit is set after a crash
_NO_VALGRIND \
$QEMU_IO \
-c "reopen -o lazy-refcounts=on,overlap-check=blubb" \
-c "write -P 0x5a 0 512" \

View File

@ -35,11 +35,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-io: Unsupported value 'blubb' for qcow2 option 'overlap-check'. Allowed are any of the following: none, constant, cached, all
wrote 512/512 bytes at offset 0
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
else
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
fi )
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
incompatible_features 0x0
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0

View File

@ -358,4 +358,5 @@ class TestBlockdevDel(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.main(supported_fmts=["qcow2"])
iotests.main(supported_fmts=["qcow2"],
supported_protocols=["file"])

View File

@ -287,6 +287,5 @@ class BuiltinNBD(NBDBlockdevAddBase):
if __name__ == '__main__':
# Need to support image creation
iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
'vmdk', 'raw', 'vhdx', 'qed'])
iotests.main(supported_fmts=['raw'],
supported_protocols=['nbd'])

View File

@ -137,4 +137,5 @@ class TestFifoQuorumEvents(TestQuorumEvents):
if __name__ == '__main__':
iotests.verify_quorum()
iotests.main(supported_fmts=["raw"])
iotests.main(supported_fmts=["raw"],
supported_protocols=["file"])

View File

@ -142,4 +142,5 @@ class TestActiveMirror(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2', 'raw'])
iotests.main(supported_fmts=['qcow2', 'raw'],
supported_protocols=['file'])

View File

@ -59,4 +59,5 @@ class TestUnaligned(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.main(supported_fmts=['raw', 'qcow2'])
iotests.main(supported_fmts=['raw', 'qcow2'],
supported_protocols=['file'])

View File

@ -258,4 +258,5 @@ BaseClass = None
MirrorBaseClass = None
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'])
iotests.main(supported_fmts=['qcow2'],
supported_protocols=['file'])

View File

@ -170,4 +170,5 @@ class TestShrink1M(ShrinkBaseClass):
ShrinkBaseClass = None
if __name__ == '__main__':
iotests.main(supported_fmts=['raw', 'qcow2'])
iotests.main(supported_fmts=['raw', 'qcow2'],
supported_protocols=['file'])

View File

@ -103,4 +103,5 @@ class TestPersistentDirtyBitmap(iotests.QMPTestCase):
self.vm.shutdown()
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'])
iotests.main(supported_fmts=['qcow2'],
supported_protocols=['file'])

View File

@ -227,4 +227,5 @@ for cmb in list(itertools.product((True, False), repeat=2)):
'do_test_migration_resume_source', *list(cmb))
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'])
iotests.main(supported_fmts=['qcow2'],
supported_protocols=['file'])

View File

@ -94,8 +94,15 @@ if echo "$reply" | grep "compiled without old-style" > /dev/null; then
_notrun "migrate -b support not compiled in"
fi
QEMU_COMM_TIMEOUT=0.1 qemu_cmd_repeat=50 silent=yes \
timeout_comm=$QEMU_COMM_TIMEOUT
if [ "${VALGRIND_QEMU}" == "y" ]; then
QEMU_COMM_TIMEOUT=4
else
QEMU_COMM_TIMEOUT=0.1
fi
qemu_cmd_repeat=50 silent=yes \
_send_qemu_cmd $src "{ 'execute': 'query-migrate' }" '"status": "completed"'
QEMU_COMM_TIMEOUT=$timeout_comm
_send_qemu_cmd $src "{ 'execute': 'query-status' }" "return"
echo

View File

@ -60,7 +60,11 @@ fi
qemu_comm_method="monitor"
_launch_qemu -drive $DRIVE_ARG -incoming defer
h=$QEMU_HANDLE
QEMU_COMM_TIMEOUT=1
if [ "${VALGRIND_QEMU}" == "y" ]; then
QEMU_COMM_TIMEOUT=7
else
QEMU_COMM_TIMEOUT=1
fi
_send_qemu_cmd $h "nbd_server_start unix:$TEST_DIR/nbd" "(qemu)"
_send_qemu_cmd $h "nbd_server_add -w drive0" "(qemu)"

View File

@ -63,4 +63,5 @@ class TestInvalidateAutoclear(iotests.QMPTestCase):
self.assertEqual(f.read(1), b'\x00')
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'])
iotests.main(supported_fmts=['qcow2'],
supported_protocols=['file'])

View File

@ -115,4 +115,5 @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase):
self.assert_qmp(result, 'return/sha256', sha256);
if __name__ == '__main__':
iotests.main(supported_fmts=['qcow2'], supported_cache_modes=['none'])
iotests.main(supported_fmts=['qcow2'], supported_cache_modes=['none'],
supported_protocols=['file'])

View File

@ -153,4 +153,5 @@ class TestNbdServerRemove(iotests.QMPTestCase):
if __name__ == '__main__':
iotests.main(supported_fmts=['generic'])
iotests.main(supported_fmts=['raw'],
supported_protocols=['nbd'])

View File

@ -74,6 +74,12 @@ if [ -n "$TEST_IMG_FILE" ]; then
TEST_IMG=$TEST_IMG_FILE
fi
chmod a-w $TEST_IMG
(echo test > $TEST_IMG) 2>/dev/null && \
_notrun "Readonly attribute is ignored, probably you run this test as" \
"root, which is unsupported."
chmod a+w $TEST_IMG
echo
echo "=== -drive with read-write image: read-only/auto-read-only combinations ==="
echo

View File

@ -1000,4 +1000,5 @@ class TestBlockdevReopen(iotests.QMPTestCase):
self.reopen(opts, {'backing': 'hd2'})
if __name__ == '__main__':
iotests.main(supported_fmts=["qcow2"])
iotests.main(supported_fmts=["qcow2"],
supported_protocols=["file"])

View File

@ -57,7 +57,11 @@ TEST_IMG="$TEST_IMG.4" _make_test_img $size
{"execute":"block-commit",
"arguments":{"device":"format-4", "top-node": "format-2", "base-node":"format-0", "job-id":"job0"}}
EOF
sleep 1
if [ "${VALGRIND_QEMU}" == "y" ]; then
sleep 10
else
sleep 1
fi
echo '{"execute":"quit"}'
) | $QEMU -qmp stdio -nographic -nodefaults \
-blockdev file,node-name=file-0,filename=$TEST_IMG.0,auto-read-only=on \

View File

@ -557,4 +557,5 @@ def main():
test_backup_api()
if __name__ == '__main__':
iotests.script_main(main, supported_fmts=['qcow2'])
iotests.script_main(main, supported_fmts=['qcow2'],
supported_protocols=['file'])

67
tests/qemu-iotests/265 Executable file
View File

@ -0,0 +1,67 @@
#!/usr/bin/env bash
#
# Test reverse-ordered qcow2 writes on a sub-cluster level
#
# Copyright (C) 2019 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/>.
#
seq=$(basename $0)
echo "QA output created by $seq"
status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
}
trap "_cleanup; exit \$status" 0 1 2 3 15
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
# qcow2-specific test
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
echo '--- Writing to the image ---'
# Reduce cluster size so we get more and quicker I/O
IMGOPTS='cluster_size=4096' _make_test_img 1M
(for ((kb = 1024 - 4; kb >= 0; kb -= 4)); do \
echo "aio_write -P 42 $((kb + 1))k 2k"; \
done) \
| $QEMU_IO "$TEST_IMG" > /dev/null
echo '--- Verifying its content ---'
(for ((kb = 0; kb < 1024; kb += 4)); do \
echo "read -P 0 ${kb}k 1k"; \
echo "read -P 42 $((kb + 1))k 2k"; \
echo "read -P 0 $((kb + 3))k 1k"; \
done) \
| $QEMU_IO "$TEST_IMG" | _filter_qemu_io | grep 'verification'
# Status of qemu-io
if [ ${PIPESTATUS[1]} = 0 ]; then
echo 'Content verified.'
fi
# success, all done
echo "*** done"
rm -f $seq.full
status=0

View File

@ -0,0 +1,6 @@
QA output created by 265
--- Writing to the image ---
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576
--- Verifying its content ---
Content verified.
*** done

153
tests/qemu-iotests/266 Executable file
View File

@ -0,0 +1,153 @@
#!/usr/bin/env python
#
# Test VPC and file image creation
#
# Copyright (C) 2019 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/>.
#
import iotests
from iotests import imgfmt
def blockdev_create(vm, options):
result = vm.qmp_log('blockdev-create', job_id='job0', options=options,
filters=[iotests.filter_qmp_testfiles])
if 'return' in result:
assert result['return'] == {}
vm.run_job('job0')
# Successful image creation (defaults)
def implicit_defaults(vm, file_path):
iotests.log("=== Successful image creation (defaults) ===")
iotests.log("")
# 8 heads, 964 cyls/head, 17 secs/cyl
# (Close to 64 MB)
size = 8 * 964 * 17 * 512
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': size })
# Successful image creation (explicit defaults)
def explicit_defaults(vm, file_path):
iotests.log("=== Successful image creation (explicit defaults) ===")
iotests.log("")
# 16 heads, 964 cyls/head, 17 secs/cyl
# (Close to 128 MB)
size = 16 * 964 * 17 * 512
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': size,
'subformat': 'dynamic',
'force-size': False })
# Successful image creation (non-default options)
def non_defaults(vm, file_path):
iotests.log("=== Successful image creation (non-default options) ===")
iotests.log("")
# Not representable in CHS (fine with force-size=True)
size = 1048576
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': size,
'subformat': 'fixed',
'force-size': True })
# Size not representable in CHS with force-size=False
def non_chs_size_without_force(vm, file_path):
iotests.log("=== Size not representable in CHS ===")
iotests.log("")
# Not representable in CHS (will not work with force-size=False)
size = 1048576
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': size,
'force-size': False })
# Zero size
def zero_size(vm, file_path):
iotests.log("=== Zero size===")
iotests.log("")
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': 0 })
# Maximum CHS size
def maximum_chs_size(vm, file_path):
iotests.log("=== Maximum CHS size===")
iotests.log("")
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': 16 * 65535 * 255 * 512 })
# Actual maximum size
def maximum_size(vm, file_path):
iotests.log("=== Actual maximum size===")
iotests.log("")
blockdev_create(vm, { 'driver': imgfmt,
'file': 'protocol-node',
'size': 0xff000000 * 512,
'force-size': True })
def main():
for test_func in [implicit_defaults, explicit_defaults, non_defaults,
non_chs_size_without_force, zero_size, maximum_chs_size,
maximum_size]:
with iotests.FilePath('t.vpc') as file_path, \
iotests.VM() as vm:
vm.launch()
iotests.log('--- Creating empty file ---')
blockdev_create(vm, { 'driver': 'file',
'filename': file_path,
'size': 0 })
vm.qmp_log('blockdev-add', driver='file', filename=file_path,
node_name='protocol-node',
filters=[iotests.filter_qmp_testfiles])
iotests.log('')
print_info = test_func(vm, file_path)
iotests.log('')
vm.shutdown()
iotests.img_info_log(file_path)
iotests.script_main(main,
supported_fmts=['vpc'],
supported_protocols=['file'])

137
tests/qemu-iotests/266.out Normal file
View File

@ -0,0 +1,137 @@
--- Creating empty file ---
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
=== Successful image creation (defaults) ===
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "size": 67125248}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
image: TEST_IMG
file format: IMGFMT
virtual size: 64 MiB (67125248 bytes)
cluster_size: 2097152
--- Creating empty file ---
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
=== Successful image creation (explicit defaults) ===
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "force-size": false, "size": 134250496, "subformat": "dynamic"}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
image: TEST_IMG
file format: IMGFMT
virtual size: 128 MiB (134250496 bytes)
cluster_size: 2097152
--- Creating empty file ---
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
=== Successful image creation (non-default options) ===
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "force-size": true, "size": 1048576, "subformat": "fixed"}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
image: TEST_IMG
file format: IMGFMT
virtual size: 1 MiB (1048576 bytes)
--- Creating empty file ---
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
=== Size not representable in CHS ===
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "force-size": false, "size": 1048576}}}
{"return": {}}
Job failed: The requested image size cannot be represented in CHS geometry
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
qemu-img: Could not open 'TEST_IMG': File too small for a VHD header
--- Creating empty file ---
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
=== Zero size===
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "size": 0}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
image: TEST_IMG
file format: IMGFMT
virtual size: 0 B (0 bytes)
cluster_size: 2097152
--- Creating empty file ---
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
=== Maximum CHS size===
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "size": 136899993600}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
image: TEST_IMG
file format: IMGFMT
virtual size: 127 GiB (136899993600 bytes)
cluster_size: 2097152
--- Creating empty file ---
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "size": 0}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
{"execute": "blockdev-add", "arguments": {"driver": "file", "filename": "TEST_DIR/PID-t.vpc", "node-name": "protocol-node"}}
{"return": {}}
=== Actual maximum size===
{"execute": "blockdev-create", "arguments": {"job-id": "job0", "options": {"driver": "vpc", "file": "protocol-node", "force-size": true, "size": 2190433320960}}}
{"return": {}}
{"execute": "job-dismiss", "arguments": {"id": "job0"}}
{"return": {}}
image: TEST_IMG
file format: IMGFMT
virtual size: 1.99 TiB (2190433320960 bytes)
cluster_size: 2097152

View File

@ -60,19 +60,68 @@ if ! . ./common.config
exit 1
fi
# Set the variables to the empty string to turn Valgrind off
# for specific processes, e.g.
# $ VALGRIND_QEMU_IO= ./check -qcow2 -valgrind 015
: ${VALGRIND_QEMU_VM=$VALGRIND_QEMU}
: ${VALGRIND_QEMU_IMG=$VALGRIND_QEMU}
: ${VALGRIND_QEMU_IO=$VALGRIND_QEMU}
: ${VALGRIND_QEMU_NBD=$VALGRIND_QEMU}
: ${VALGRIND_QEMU_VXHS=$VALGRIND_QEMU}
# The Valgrind own parameters may be set with
# its environment variable VALGRIND_OPTS, e.g.
# $ VALGRIND_OPTS="--leak-check=yes" ./check -qcow2 -valgrind 015
_qemu_proc_exec()
{
local VALGRIND_LOGFILE="$1"
shift
if [[ "${VALGRIND_QEMU}" == "y" && "${NO_VALGRIND}" != "y" ]]; then
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$@"
else
exec "$@"
fi
}
_qemu_proc_valgrind_log()
{
local VALGRIND_LOGFILE="$1"
local RETVAL="$2"
if [[ "${VALGRIND_QEMU}" == "y" && "${NO_VALGRIND}" != "y" ]]; then
if [ $RETVAL == 99 ]; then
cat "${VALGRIND_LOGFILE}"
fi
rm -f "${VALGRIND_LOGFILE}"
fi
}
_qemu_wrapper()
{
local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
(
if [ -n "${QEMU_NEED_PID}" ]; then
echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid"
fi
exec "$QEMU_PROG" $QEMU_OPTIONS "$@"
VALGRIND_QEMU="${VALGRIND_QEMU_VM}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
"$QEMU_PROG" $QEMU_OPTIONS "$@"
)
RETVAL=$?
_qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
return $RETVAL
}
_qemu_img_wrapper()
{
(exec "$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS "$@")
local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
(
VALGRIND_QEMU="${VALGRIND_QEMU_IMG}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
"$QEMU_IMG_PROG" $QEMU_IMG_OPTIONS "$@"
)
RETVAL=$?
_qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
return $RETVAL
}
_qemu_io_wrapper()
@ -85,36 +134,47 @@ _qemu_io_wrapper()
QEMU_IO_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IO_ARGS"
fi
fi
local RETVAL
(
if [ "${VALGRIND_QEMU}" == "y" ]; then
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
else
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
fi
VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
"$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
)
RETVAL=$?
if [ "${VALGRIND_QEMU}" == "y" ]; then
if [ $RETVAL == 99 ]; then
cat "${VALGRIND_LOGFILE}"
fi
rm -f "${VALGRIND_LOGFILE}"
fi
(exit $RETVAL)
_qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
return $RETVAL
}
_qemu_nbd_wrapper()
{
"$QEMU_NBD_PROG" --pid-file="${QEMU_TEST_DIR}/qemu-nbd.pid" \
$QEMU_NBD_OPTIONS "$@"
local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
(
VALGRIND_QEMU="${VALGRIND_QEMU_NBD}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
"$QEMU_NBD_PROG" --pid-file="${QEMU_TEST_DIR}/qemu-nbd.pid" \
$QEMU_NBD_OPTIONS "$@"
)
RETVAL=$?
_qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
return $RETVAL
}
_qemu_vxhs_wrapper()
{
local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
(
echo $BASHPID > "${TEST_DIR}/qemu-vxhs.pid"
exec "$QEMU_VXHS_PROG" $QEMU_VXHS_OPTIONS "$@"
VALGRIND_QEMU="${VALGRIND_QEMU_VXHS}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
"$QEMU_VXHS_PROG" $QEMU_VXHS_OPTIONS "$@"
)
RETVAL=$?
_qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
return $RETVAL
}
# Valgrind bug #409141 https://bugs.kde.org/show_bug.cgi?id=409141
# Until valgrind 3.16+ is ubiquitous, we must work around a hang in
# valgrind when issuing sigkill. Disable valgrind for this invocation.
_NO_VALGRIND()
{
NO_VALGRIND="y" "$@"
}
export QEMU=_qemu_wrapper
@ -395,6 +455,15 @@ _notrun()
exit
}
# bail out, setting up .casenotrun file
# The function _casenotrun() is used as a notifier. It is the
# caller's responsibility to make skipped a particular test.
#
_casenotrun()
{
echo " [case not run] $*" >>"$OUTPUT_DIR/$seq.casenotrun"
}
# just plain bail out
#
_fail()

View File

@ -274,3 +274,5 @@
257 rw
258 rw quick
262 rw quick migration
265 rw auto quick
266 rw quick

View File

@ -909,7 +909,8 @@ def execute_unittest(output, verbosity, debug):
def execute_test(test_function=None,
supported_fmts=[], supported_oses=['linux'],
supported_cache_modes=[], unsupported_fmts=[]):
supported_cache_modes=[], unsupported_fmts=[],
supported_protocols=[], unsupported_protocols=[]):
"""Run either unittest or script-style tests."""
# We are using TEST_DIR and QEMU_DEFAULT_MACHINE as proxies to
@ -923,6 +924,7 @@ def execute_test(test_function=None,
debug = '-d' in sys.argv
verbosity = 1
verify_image_format(supported_fmts, unsupported_fmts)
verify_protocol(supported_protocols, unsupported_protocols)
verify_platform(supported_oses)
verify_cache_mode(supported_cache_modes)

View File

@ -848,7 +848,6 @@ BlockJobDriver test_job_driver = {
.instance_size = sizeof(TestBlockJob),
.free = block_job_free,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
.run = test_job_run,
.complete = test_job_complete,
.prepare = test_job_prepare,
@ -1574,7 +1573,6 @@ static const BlockJobDriver test_drop_backing_job_driver = {
.instance_size = sizeof(TestDropBackingBlockJob),
.free = block_job_free,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
.run = test_drop_backing_job_run,
.commit = test_drop_backing_job_commit,
}
@ -1711,7 +1709,6 @@ static const BlockJobDriver test_simple_job_driver = {
.instance_size = sizeof(TestSimpleBlockJob),
.free = block_job_free,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
.run = test_simple_job_run,
.clean = test_simple_job_clean,
},

View File

@ -401,7 +401,6 @@ BlockJobDriver test_job_driver = {
.instance_size = sizeof(TestBlockJob),
.free = block_job_free,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
.run = test_job_run,
.complete = test_job_complete,
.prepare = test_job_prepare,

View File

@ -72,7 +72,6 @@ static const BlockJobDriver test_block_job_driver = {
.instance_size = sizeof(TestBlockJob),
.free = block_job_free,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
.run = test_block_job_run,
.clean = test_block_job_clean,
},

View File

@ -22,7 +22,6 @@ static const BlockJobDriver test_block_job_driver = {
.instance_size = sizeof(BlockJob),
.free = block_job_free,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
},
};
@ -196,7 +195,6 @@ static const BlockJobDriver test_cancel_driver = {
.instance_size = sizeof(CancelJob),
.free = block_job_free,
.user_resume = block_job_user_resume,
.drain = block_job_drain,
.run = cancel_job_run,
.complete = cancel_job_complete,
},