mirror of https://github.com/xemu-project/xemu.git
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:
commit
3d9442ee1d
|
@ -425,21 +425,6 @@ void backup_do_checkpoint(BlockJob *job, Error **errp)
|
||||||
bdrv_set_dirty_bitmap(backup_job->copy_bitmap, 0, backup_job->len);
|
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,
|
static BlockErrorAction backup_error_action(BackupBlockJob *job,
|
||||||
bool read, int error)
|
bool read, int error)
|
||||||
{
|
{
|
||||||
|
@ -588,13 +573,11 @@ static const BlockJobDriver backup_job_driver = {
|
||||||
.job_type = JOB_TYPE_BACKUP,
|
.job_type = JOB_TYPE_BACKUP,
|
||||||
.free = block_job_free,
|
.free = block_job_free,
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
|
||||||
.run = backup_run,
|
.run = backup_run,
|
||||||
.commit = backup_commit,
|
.commit = backup_commit,
|
||||||
.abort = backup_abort,
|
.abort = backup_abort,
|
||||||
.clean = backup_clean,
|
.clean = backup_clean,
|
||||||
},
|
}
|
||||||
.drain = backup_drain,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static int64_t backup_calculate_cluster_size(BlockDriverState *target,
|
static int64_t backup_calculate_cluster_size(BlockDriverState *target,
|
||||||
|
|
|
@ -216,7 +216,6 @@ static const BlockJobDriver commit_job_driver = {
|
||||||
.job_type = JOB_TYPE_COMMIT,
|
.job_type = JOB_TYPE_COMMIT,
|
||||||
.free = block_job_free,
|
.free = block_job_free,
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
|
||||||
.run = commit_run,
|
.run = commit_run,
|
||||||
.prepare = commit_prepare,
|
.prepare = commit_prepare,
|
||||||
.abort = commit_abort,
|
.abort = commit_abort,
|
||||||
|
|
|
@ -64,9 +64,13 @@ void qmp_blockdev_create(const char *job_id, BlockdevCreateOptions *options,
|
||||||
const char *fmt = BlockdevDriver_str(options->driver);
|
const char *fmt = BlockdevDriver_str(options->driver);
|
||||||
BlockDriver *drv = bdrv_find_format(fmt);
|
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
|
/* If the driver is in the schema, we know that it exists. But it may not
|
||||||
* be whitelisted. */
|
* be whitelisted. */
|
||||||
assert(drv);
|
|
||||||
if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) {
|
if (bdrv_uses_whitelist() && !bdrv_is_whitelisted(drv, false)) {
|
||||||
error_setg(errp, "Driver is not whitelisted");
|
error_setg(errp, "Driver is not whitelisted");
|
||||||
return;
|
return;
|
||||||
|
|
|
@ -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)
|
static int translate_err(int err)
|
||||||
{
|
{
|
||||||
if (err == -ENODEV || err == -ENOSYS || err == -EOPNOTSUPP ||
|
if (err == -ENODEV || err == -ENOSYS || err == -EOPNOTSUPP ||
|
||||||
|
@ -1555,22 +1502,20 @@ static ssize_t handle_aiocb_write_zeroes_block(RawPosixAIOData *aiocb)
|
||||||
} while (errno == EINTR);
|
} while (errno == EINTR);
|
||||||
|
|
||||||
ret = translate_err(-errno);
|
ret = translate_err(-errno);
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (ret == -ENOTSUP) {
|
if (ret == -ENOTSUP) {
|
||||||
s->has_write_zeroes = false;
|
s->has_write_zeroes = false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int handle_aiocb_write_zeroes(void *opaque)
|
static int handle_aiocb_write_zeroes(void *opaque)
|
||||||
{
|
{
|
||||||
RawPosixAIOData *aiocb = opaque;
|
RawPosixAIOData *aiocb = opaque;
|
||||||
#if defined(CONFIG_FALLOCATE) || defined(CONFIG_XFS)
|
|
||||||
BDRVRawState *s = aiocb->bs->opaque;
|
|
||||||
#endif
|
|
||||||
#ifdef CONFIG_FALLOCATE
|
#ifdef CONFIG_FALLOCATE
|
||||||
|
BDRVRawState *s = aiocb->bs->opaque;
|
||||||
int64_t len;
|
int64_t len;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
@ -1578,12 +1523,6 @@ static int handle_aiocb_write_zeroes(void *opaque)
|
||||||
return handle_aiocb_write_zeroes_block(aiocb);
|
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
|
#ifdef CONFIG_FALLOCATE_ZERO_RANGE
|
||||||
if (s->has_write_zeroes) {
|
if (s->has_write_zeroes) {
|
||||||
int ret = do_fallocate(s->fd, FALLOC_FL_ZERO_RANGE,
|
int ret = do_fallocate(s->fd, FALLOC_FL_ZERO_RANGE,
|
||||||
|
@ -1653,14 +1592,6 @@ static int handle_aiocb_write_zeroes_unmap(void *opaque)
|
||||||
}
|
}
|
||||||
#endif
|
#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
|
/* If we couldn't manage to unmap while guaranteed that the area reads as
|
||||||
* all-zero afterwards, just write zeroes without unmapping */
|
* all-zero afterwards, just write zeroes without unmapping */
|
||||||
ret = handle_aiocb_write_zeroes(aiocb);
|
ret = handle_aiocb_write_zeroes(aiocb);
|
||||||
|
@ -1737,12 +1668,6 @@ static int handle_aiocb_discard(void *opaque)
|
||||||
ret = -errno;
|
ret = -errno;
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
#ifdef CONFIG_XFS
|
|
||||||
if (s->is_xfs) {
|
|
||||||
return xfs_discard(s, aiocb->aio_offset, aiocb->aio_nbytes);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
|
#ifdef CONFIG_FALLOCATE_PUNCH_HOLE
|
||||||
ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
|
ret = do_fallocate(s->fd, FALLOC_FL_PUNCH_HOLE | FALLOC_FL_KEEP_SIZE,
|
||||||
aiocb->aio_offset, aiocb->aio_nbytes);
|
aiocb->aio_offset, aiocb->aio_nbytes);
|
||||||
|
|
|
@ -646,14 +646,11 @@ static int mirror_exit_common(Job *job)
|
||||||
bdrv_ref(mirror_top_bs);
|
bdrv_ref(mirror_top_bs);
|
||||||
bdrv_ref(target_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
|
* inserting target_bs at s->to_replace, where we might not be able to get
|
||||||
* these permissions.
|
* 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);
|
blk_unref(s->target);
|
||||||
s->target = NULL;
|
s->target = NULL;
|
||||||
|
|
||||||
|
@ -1149,28 +1146,12 @@ static bool mirror_drained_poll(BlockJob *job)
|
||||||
return !!s->in_flight;
|
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 = {
|
static const BlockJobDriver mirror_job_driver = {
|
||||||
.job_driver = {
|
.job_driver = {
|
||||||
.instance_size = sizeof(MirrorBlockJob),
|
.instance_size = sizeof(MirrorBlockJob),
|
||||||
.job_type = JOB_TYPE_MIRROR,
|
.job_type = JOB_TYPE_MIRROR,
|
||||||
.free = block_job_free,
|
.free = block_job_free,
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
|
||||||
.run = mirror_run,
|
.run = mirror_run,
|
||||||
.prepare = mirror_prepare,
|
.prepare = mirror_prepare,
|
||||||
.abort = mirror_abort,
|
.abort = mirror_abort,
|
||||||
|
@ -1178,7 +1159,6 @@ static const BlockJobDriver mirror_job_driver = {
|
||||||
.complete = mirror_complete,
|
.complete = mirror_complete,
|
||||||
},
|
},
|
||||||
.drained_poll = mirror_drained_poll,
|
.drained_poll = mirror_drained_poll,
|
||||||
.drain = mirror_drain,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static const BlockJobDriver commit_active_job_driver = {
|
static const BlockJobDriver commit_active_job_driver = {
|
||||||
|
@ -1187,7 +1167,6 @@ static const BlockJobDriver commit_active_job_driver = {
|
||||||
.job_type = JOB_TYPE_COMMIT,
|
.job_type = JOB_TYPE_COMMIT,
|
||||||
.free = block_job_free,
|
.free = block_job_free,
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
|
||||||
.run = mirror_run,
|
.run = mirror_run,
|
||||||
.prepare = mirror_prepare,
|
.prepare = mirror_prepare,
|
||||||
.abort = mirror_abort,
|
.abort = mirror_abort,
|
||||||
|
@ -1195,7 +1174,6 @@ static const BlockJobDriver commit_active_job_driver = {
|
||||||
.complete = mirror_complete,
|
.complete = mirror_complete,
|
||||||
},
|
},
|
||||||
.drained_poll = mirror_drained_poll,
|
.drained_poll = mirror_drained_poll,
|
||||||
.drain = mirror_drain,
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void coroutine_fn
|
static void coroutine_fn
|
||||||
|
|
|
@ -390,12 +390,17 @@ static void nfs_attach_aio_context(BlockDriverState *bs,
|
||||||
static void nfs_client_close(NFSClient *client)
|
static void nfs_client_close(NFSClient *client)
|
||||||
{
|
{
|
||||||
if (client->context) {
|
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) {
|
if (client->fh) {
|
||||||
nfs_close(client->context, client->fh);
|
nfs_close(client->context, client->fh);
|
||||||
client->fh = NULL;
|
client->fh = NULL;
|
||||||
}
|
}
|
||||||
aio_set_fd_handler(client->aio_context, nfs_get_fd(client->context),
|
#ifdef LIBNFS_FEATURE_UMOUNT
|
||||||
false, NULL, NULL, NULL, NULL);
|
nfs_umount(client->context);
|
||||||
|
#endif
|
||||||
nfs_destroy_context(client->context);
|
nfs_destroy_context(client->context);
|
||||||
client->context = NULL;
|
client->context = NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -1351,13 +1351,7 @@ static int handle_alloc(BlockDriverState *bs, uint64_t guest_offset,
|
||||||
}
|
}
|
||||||
|
|
||||||
entry = be64_to_cpu(l2_slice[l2_index]);
|
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
|
/* 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
|
* we can't find any unallocated or COW clusters either, something is
|
||||||
|
|
|
@ -828,7 +828,11 @@ static void read_cache_sizes(BlockDriverState *bs, QemuOpts *opts,
|
||||||
bool l2_cache_entry_size_set;
|
bool l2_cache_entry_size_set;
|
||||||
int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
|
int min_refcount_cache = MIN_REFCOUNT_CACHE_SIZE * s->cluster_size;
|
||||||
uint64_t virtual_disk_size = bs->total_sectors * BDRV_SECTOR_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);
|
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);
|
l2_cache_size_set = qemu_opt_get(opts, QCOW2_OPT_L2_CACHE_SIZE);
|
||||||
|
|
|
@ -212,7 +212,6 @@ static const BlockJobDriver stream_job_driver = {
|
||||||
.abort = stream_abort,
|
.abort = stream_abort,
|
||||||
.clean = stream_clean,
|
.clean = stream_clean,
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -885,6 +885,7 @@ static int create_dynamic_disk(BlockBackend *blk, uint8_t *buf,
|
||||||
goto fail;
|
goto fail;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ret = 0;
|
||||||
fail:
|
fail:
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
@ -908,7 +909,7 @@ static int create_fixed_disk(BlockBackend *blk, uint8_t *buf,
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
return ret;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int calculate_rounded_image_size(BlockdevCreateOptionsVpc *vpc_opts,
|
static int calculate_rounded_image_size(BlockdevCreateOptionsVpc *vpc_opts,
|
||||||
|
|
13
blockjob.c
13
blockjob.c
|
@ -90,18 +90,6 @@ void block_job_free(Job *job)
|
||||||
error_free(bjob->blocker);
|
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)
|
static char *child_job_get_parent_desc(BdrvChild *c)
|
||||||
{
|
{
|
||||||
BlockJob *job = c->opaque;
|
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(is_block_job(&job->job));
|
||||||
assert(job->job.driver->free == &block_job_free);
|
assert(job->job.driver->free == &block_job_free);
|
||||||
assert(job->job.driver->user_resume == &block_job_user_resume);
|
assert(job->job.driver->user_resume == &block_job_user_resume);
|
||||||
assert(job->job.driver->drain == &block_job_drain);
|
|
||||||
|
|
||||||
job->blk = blk;
|
job->blk = blk;
|
||||||
|
|
||||||
|
|
|
@ -52,17 +52,6 @@ struct BlockJobDriver {
|
||||||
* besides job->blk to the new AioContext.
|
* besides job->blk to the new AioContext.
|
||||||
*/
|
*/
|
||||||
void (*attached_aio_context)(BlockJob *job, AioContext *new_context);
|
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);
|
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:
|
* block_job_ratelimit_get_delay:
|
||||||
*
|
*
|
||||||
|
|
|
@ -220,13 +220,6 @@ struct JobDriver {
|
||||||
*/
|
*/
|
||||||
void (*complete)(Job *job, Error **errp);
|
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
|
* 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
|
* 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);
|
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
|
* Get the next element from the list of block jobs after @job, or the
|
||||||
* first one if @job is %NULL.
|
* first one if @job is %NULL.
|
||||||
|
|
12
job.c
12
job.c
|
@ -523,16 +523,6 @@ void coroutine_fn job_sleep_ns(Job *job, int64_t ns)
|
||||||
job_pause_point(job);
|
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 */
|
/* Assumes the block_job_mutex is held */
|
||||||
static bool job_timer_not_pending(Job *job)
|
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,
|
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;
|
ret = (job_is_cancelled(job) && job->ret == 0) ? -ECANCELED : job->ret;
|
||||||
job_unref(job);
|
job_unref(job);
|
||||||
|
|
|
@ -401,6 +401,7 @@ static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
|
f = NULL;
|
||||||
|
|
||||||
if (len > pattern_len) {
|
if (len > pattern_len) {
|
||||||
len -= pattern_len;
|
len -= pattern_len;
|
||||||
|
@ -420,6 +421,9 @@ static void *qemu_io_alloc_from_file(BlockBackend *blk, size_t len,
|
||||||
|
|
||||||
error:
|
error:
|
||||||
qemu_io_free(buf_origin);
|
qemu_io_free(buf_origin);
|
||||||
|
if (f) {
|
||||||
|
fclose(f);
|
||||||
|
}
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,7 +39,6 @@ static int pr_manager_worker(void *opaque)
|
||||||
int fd = data->fd;
|
int fd = data->fd;
|
||||||
int r;
|
int r;
|
||||||
|
|
||||||
g_free(data);
|
|
||||||
trace_pr_manager_run(fd, hdr->cmdp[0], hdr->cmdp[1]);
|
trace_pr_manager_run(fd, hdr->cmdp[0], hdr->cmdp[1]);
|
||||||
|
|
||||||
/* The reference was taken in pr_manager_execute. */
|
/* The reference was taken in pr_manager_execute. */
|
||||||
|
|
|
@ -110,7 +110,11 @@ echo
|
||||||
qemu_comm_method="monitor"
|
qemu_comm_method="monitor"
|
||||||
_launch_qemu -drive file="${TEST_IMG}",cache=${CACHEMODE},id=disk
|
_launch_qemu -drive file="${TEST_IMG}",cache=${CACHEMODE},id=disk
|
||||||
h=$QEMU_HANDLE
|
h=$QEMU_HANDLE
|
||||||
|
if [ "${VALGRIND_QEMU}" == "y" ]; then
|
||||||
|
QEMU_COMM_TIMEOUT=7
|
||||||
|
else
|
||||||
QEMU_COMM_TIMEOUT=1
|
QEMU_COMM_TIMEOUT=1
|
||||||
|
fi
|
||||||
|
|
||||||
# Silence output since it contains the disk image path and QEMU's readline
|
# 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
|
# character echoing makes it very hard to filter the output. Plus, there
|
||||||
|
|
|
@ -957,4 +957,5 @@ class TestSetSpeed(iotests.QMPTestCase):
|
||||||
self.cancel_and_wait(resume=True)
|
self.cancel_and_wait(resume=True)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2', 'qed'])
|
iotests.main(supported_fmts=['qcow2', 'qed'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -65,6 +65,7 @@ echo "== Creating a dirty image file =="
|
||||||
IMGOPTS="compat=1.1,lazy_refcounts=on"
|
IMGOPTS="compat=1.1,lazy_refcounts=on"
|
||||||
_make_test_img $size
|
_make_test_img $size
|
||||||
|
|
||||||
|
_NO_VALGRIND \
|
||||||
$QEMU_IO -c "write -P 0x5a 0 512" \
|
$QEMU_IO -c "write -P 0x5a 0 512" \
|
||||||
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
|
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
|
||||||
| _filter_qemu_io
|
| _filter_qemu_io
|
||||||
|
@ -100,6 +101,7 @@ echo "== Opening a dirty image read/write should repair it =="
|
||||||
IMGOPTS="compat=1.1,lazy_refcounts=on"
|
IMGOPTS="compat=1.1,lazy_refcounts=on"
|
||||||
_make_test_img $size
|
_make_test_img $size
|
||||||
|
|
||||||
|
_NO_VALGRIND \
|
||||||
$QEMU_IO -c "write -P 0x5a 0 512" \
|
$QEMU_IO -c "write -P 0x5a 0 512" \
|
||||||
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
|
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
|
||||||
| _filter_qemu_io
|
| _filter_qemu_io
|
||||||
|
@ -118,6 +120,7 @@ echo "== Creating an image file with lazy_refcounts=off =="
|
||||||
IMGOPTS="compat=1.1,lazy_refcounts=off"
|
IMGOPTS="compat=1.1,lazy_refcounts=off"
|
||||||
_make_test_img $size
|
_make_test_img $size
|
||||||
|
|
||||||
|
_NO_VALGRIND \
|
||||||
$QEMU_IO -c "write -P 0x5a 0 512" \
|
$QEMU_IO -c "write -P 0x5a 0 512" \
|
||||||
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
|
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
|
||||||
| _filter_qemu_io
|
| _filter_qemu_io
|
||||||
|
@ -151,6 +154,7 @@ echo "== Changing lazy_refcounts setting at runtime =="
|
||||||
IMGOPTS="compat=1.1,lazy_refcounts=off"
|
IMGOPTS="compat=1.1,lazy_refcounts=off"
|
||||||
_make_test_img $size
|
_make_test_img $size
|
||||||
|
|
||||||
|
_NO_VALGRIND \
|
||||||
$QEMU_IO -c "reopen -o lazy-refcounts=on" \
|
$QEMU_IO -c "reopen -o lazy-refcounts=on" \
|
||||||
-c "write -P 0x5a 0 512" \
|
-c "write -P 0x5a 0 512" \
|
||||||
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
|
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
|
||||||
|
@ -163,6 +167,7 @@ _check_test_img
|
||||||
IMGOPTS="compat=1.1,lazy_refcounts=on"
|
IMGOPTS="compat=1.1,lazy_refcounts=on"
|
||||||
_make_test_img $size
|
_make_test_img $size
|
||||||
|
|
||||||
|
_NO_VALGRIND \
|
||||||
$QEMU_IO -c "reopen -o lazy-refcounts=off" \
|
$QEMU_IO -c "reopen -o lazy-refcounts=off" \
|
||||||
-c "write -P 0x5a 0 512" \
|
-c "write -P 0x5a 0 512" \
|
||||||
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
|
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 \
|
||||||
|
|
|
@ -11,11 +11,7 @@ No errors were found on the image.
|
||||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
|
||||||
wrote 512/512 bytes at offset 0
|
wrote 512/512 bytes at offset 0
|
||||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||||
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
|
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
|
||||||
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
else
|
|
||||||
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
fi )
|
|
||||||
incompatible_features 0x1
|
incompatible_features 0x1
|
||||||
ERROR cluster 5 refcount=0 reference=1
|
ERROR cluster 5 refcount=0 reference=1
|
||||||
ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
|
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
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
|
||||||
wrote 512/512 bytes at offset 0
|
wrote 512/512 bytes at offset 0
|
||||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||||
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
|
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
|
||||||
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
else
|
|
||||||
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
fi )
|
|
||||||
incompatible_features 0x1
|
incompatible_features 0x1
|
||||||
ERROR cluster 5 refcount=0 reference=1
|
ERROR cluster 5 refcount=0 reference=1
|
||||||
Rebuilding refcount structure
|
Rebuilding refcount structure
|
||||||
|
@ -68,11 +60,7 @@ incompatible_features 0x0
|
||||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
|
||||||
wrote 512/512 bytes at offset 0
|
wrote 512/512 bytes at offset 0
|
||||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||||
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
|
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
|
||||||
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
else
|
|
||||||
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
fi )
|
|
||||||
incompatible_features 0x0
|
incompatible_features 0x0
|
||||||
No errors were found on the image.
|
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
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
|
||||||
wrote 512/512 bytes at offset 0
|
wrote 512/512 bytes at offset 0
|
||||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||||
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
|
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
|
||||||
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
else
|
|
||||||
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
fi )
|
|
||||||
incompatible_features 0x1
|
incompatible_features 0x1
|
||||||
ERROR cluster 5 refcount=0 reference=1
|
ERROR cluster 5 refcount=0 reference=1
|
||||||
ERROR OFLAG_COPIED data cluster: l2_entry=8000000000050000 refcount=0
|
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
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
|
||||||
wrote 512/512 bytes at offset 0
|
wrote 512/512 bytes at offset 0
|
||||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||||
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
|
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
|
||||||
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
else
|
|
||||||
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
fi )
|
|
||||||
incompatible_features 0x0
|
incompatible_features 0x0
|
||||||
No errors were found on the image.
|
No errors were found on the image.
|
||||||
*** done
|
*** done
|
||||||
|
|
|
@ -429,4 +429,5 @@ class TestReopenOverlay(ImageCommitTestCase):
|
||||||
self.run_commit_test(self.img1, self.img0)
|
self.run_commit_test(self.img1, self.img0)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2', 'qed'])
|
iotests.main(supported_fmts=['qcow2', 'qed'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -1122,4 +1122,5 @@ class TestOrphanedSource(iotests.QMPTestCase):
|
||||||
self.assert_qmp(result, 'error/class', 'GenericError')
|
self.assert_qmp(result, 'error/class', 'GenericError')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2', 'qed'])
|
iotests.main(supported_fmts=['qcow2', 'qed'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -118,4 +118,5 @@ class TestRefcountTableGrowth(iotests.QMPTestCase):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2'])
|
iotests.main(supported_fmts=['qcow2'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -175,4 +175,5 @@ class TestSCMFd(iotests.QMPTestCase):
|
||||||
"File descriptor named '%s' not found" % fdname)
|
"File descriptor named '%s' not found" % fdname)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['raw'])
|
iotests.main(supported_fmts=['raw'],
|
||||||
|
supported_protocols=['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
|
$QEMU_IO -c "read -P 0x33 0 4k" "$TEST_IMG" | _filter_qemu_io
|
||||||
|
|
||||||
# Using snapshot=on with a non-existent TMPDIR
|
# 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
|
TMPDIR=/nonexistent run_qemu -drive driver=null-co,snapshot=on
|
||||||
|
|
||||||
# Using snapshot=on together with read-only=on
|
# Using snapshot=on together with read-only=on
|
||||||
|
|
|
@ -563,4 +563,5 @@ class TestDriveCompression(iotests.QMPTestCase):
|
||||||
target='drive1')
|
target='drive1')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['raw', 'qcow2'])
|
iotests.main(supported_fmts=['raw', 'qcow2'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -335,4 +335,5 @@ class BackupTest(iotests.QMPTestCase):
|
||||||
self.dismissal_failure(True)
|
self.dismissal_failure(True)
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2', 'qed'])
|
iotests.main(supported_fmts=['qcow2', 'qed'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -256,4 +256,5 @@ class TestSnapshotDelete(ImageSnapshotTestCase):
|
||||||
self.assert_qmp(result, 'error/class', 'GenericError')
|
self.assert_qmp(result, 'error/class', 'GenericError')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2'])
|
iotests.main(supported_fmts=['qcow2'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -73,6 +73,7 @@ echo
|
||||||
echo "=== Testing dirty version downgrade ==="
|
echo "=== Testing dirty version downgrade ==="
|
||||||
echo
|
echo
|
||||||
IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M
|
IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M
|
||||||
|
_NO_VALGRIND \
|
||||||
$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \
|
$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \
|
||||||
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io
|
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io
|
||||||
$PYTHON qcow2.py "$TEST_IMG" dump-header
|
$PYTHON qcow2.py "$TEST_IMG" dump-header
|
||||||
|
@ -107,6 +108,7 @@ echo
|
||||||
echo "=== Testing dirty lazy_refcounts=off ==="
|
echo "=== Testing dirty lazy_refcounts=off ==="
|
||||||
echo
|
echo
|
||||||
IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M
|
IMGOPTS="compat=1.1,lazy_refcounts=on" _make_test_img 64M
|
||||||
|
_NO_VALGRIND \
|
||||||
$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \
|
$QEMU_IO -c "write -P 0x2a 0 128k" -c flush \
|
||||||
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io
|
-c "sigraise $(kill -l KILL)" "$TEST_IMG" 2>&1 | _filter_qemu_io
|
||||||
$PYTHON qcow2.py "$TEST_IMG" dump-header
|
$PYTHON qcow2.py "$TEST_IMG" dump-header
|
||||||
|
|
|
@ -118,11 +118,7 @@ No errors were found on the image.
|
||||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||||
wrote 131072/131072 bytes at offset 0
|
wrote 131072/131072 bytes at offset 0
|
||||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||||
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
|
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
|
||||||
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
else
|
|
||||||
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
fi )
|
|
||||||
magic 0x514649fb
|
magic 0x514649fb
|
||||||
version 3
|
version 3
|
||||||
backing_file_offset 0x0
|
backing_file_offset 0x0
|
||||||
|
@ -280,11 +276,7 @@ No errors were found on the image.
|
||||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||||
wrote 131072/131072 bytes at offset 0
|
wrote 131072/131072 bytes at offset 0
|
||||||
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||||
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
|
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
|
||||||
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
else
|
|
||||||
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
fi )
|
|
||||||
magic 0x514649fb
|
magic 0x514649fb
|
||||||
version 3
|
version 3
|
||||||
backing_file_offset 0x0
|
backing_file_offset 0x0
|
||||||
|
|
|
@ -129,4 +129,5 @@ TestQemuImgInfo = None
|
||||||
TestQMP = None
|
TestQMP = None
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2'])
|
iotests.main(supported_fmts=['qcow2'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -67,4 +67,5 @@ class TestLiveSnapshot(iotests.QMPTestCase):
|
||||||
self.checkConfig('target')
|
self.checkConfig('target')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2'])
|
iotests.main(supported_fmts=['qcow2'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -717,4 +717,5 @@ if __name__ == '__main__':
|
||||||
iotests.qemu_default_machine)
|
iotests.qemu_default_machine)
|
||||||
# Need to support image creation
|
# Need to support image creation
|
||||||
iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
|
iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
|
||||||
'vmdk', 'raw', 'vhdx', 'qed'])
|
'vmdk', 'raw', 'vhdx', 'qed'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -779,4 +779,5 @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2'])
|
iotests.main(supported_fmts=['qcow2'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -83,4 +83,5 @@ class TestStopWithBlockJob(iotests.QMPTestCase):
|
||||||
self.do_test_stop("block-commit", device="drive0")
|
self.do_test_stop("block-commit", device="drive0")
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=["qcow2"])
|
iotests.main(supported_fmts=["qcow2"],
|
||||||
|
supported_protocols=["file"])
|
||||||
|
|
|
@ -56,4 +56,5 @@ class TestSingleDrive(iotests.QMPTestCase):
|
||||||
'target image does not match source after mirroring')
|
'target image does not match source after mirroring')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['raw', 'qcow2'])
|
iotests.main(supported_fmts=['raw', 'qcow2'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -130,6 +130,7 @@ echo
|
||||||
|
|
||||||
# Whether lazy-refcounts was actually enabled can easily be tested: Check if
|
# Whether lazy-refcounts was actually enabled can easily be tested: Check if
|
||||||
# the dirty bit is set after a crash
|
# the dirty bit is set after a crash
|
||||||
|
_NO_VALGRIND \
|
||||||
$QEMU_IO \
|
$QEMU_IO \
|
||||||
-c "reopen -o lazy-refcounts=on,overlap-check=blubb" \
|
-c "reopen -o lazy-refcounts=on,overlap-check=blubb" \
|
||||||
-c "write -P 0x5a 0 512" \
|
-c "write -P 0x5a 0 512" \
|
||||||
|
|
|
@ -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
|
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
|
wrote 512/512 bytes at offset 0
|
||||||
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
512 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
|
||||||
./common.rc: Killed ( if [ "${VALGRIND_QEMU}" == "y" ]; then
|
./common.rc: Killed ( VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@" )
|
||||||
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
else
|
|
||||||
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@";
|
|
||||||
fi )
|
|
||||||
incompatible_features 0x0
|
incompatible_features 0x0
|
||||||
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
|
||||||
wrote 65536/65536 bytes at offset 0
|
wrote 65536/65536 bytes at offset 0
|
||||||
|
|
|
@ -358,4 +358,5 @@ class TestBlockdevDel(iotests.QMPTestCase):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=["qcow2"])
|
iotests.main(supported_fmts=["qcow2"],
|
||||||
|
supported_protocols=["file"])
|
||||||
|
|
|
@ -287,6 +287,5 @@ class BuiltinNBD(NBDBlockdevAddBase):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
# Need to support image creation
|
iotests.main(supported_fmts=['raw'],
|
||||||
iotests.main(supported_fmts=['vpc', 'parallels', 'qcow', 'vdi', 'qcow2',
|
supported_protocols=['nbd'])
|
||||||
'vmdk', 'raw', 'vhdx', 'qed'])
|
|
||||||
|
|
|
@ -137,4 +137,5 @@ class TestFifoQuorumEvents(TestQuorumEvents):
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.verify_quorum()
|
iotests.verify_quorum()
|
||||||
iotests.main(supported_fmts=["raw"])
|
iotests.main(supported_fmts=["raw"],
|
||||||
|
supported_protocols=["file"])
|
||||||
|
|
|
@ -142,4 +142,5 @@ class TestActiveMirror(iotests.QMPTestCase):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2', 'raw'])
|
iotests.main(supported_fmts=['qcow2', 'raw'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -59,4 +59,5 @@ class TestUnaligned(iotests.QMPTestCase):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['raw', 'qcow2'])
|
iotests.main(supported_fmts=['raw', 'qcow2'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -258,4 +258,5 @@ BaseClass = None
|
||||||
MirrorBaseClass = None
|
MirrorBaseClass = None
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2'])
|
iotests.main(supported_fmts=['qcow2'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -170,4 +170,5 @@ class TestShrink1M(ShrinkBaseClass):
|
||||||
ShrinkBaseClass = None
|
ShrinkBaseClass = None
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['raw', 'qcow2'])
|
iotests.main(supported_fmts=['raw', 'qcow2'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -103,4 +103,5 @@ class TestPersistentDirtyBitmap(iotests.QMPTestCase):
|
||||||
self.vm.shutdown()
|
self.vm.shutdown()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2'])
|
iotests.main(supported_fmts=['qcow2'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -227,4 +227,5 @@ for cmb in list(itertools.product((True, False), repeat=2)):
|
||||||
'do_test_migration_resume_source', *list(cmb))
|
'do_test_migration_resume_source', *list(cmb))
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2'])
|
iotests.main(supported_fmts=['qcow2'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -94,8 +94,15 @@ if echo "$reply" | grep "compiled without old-style" > /dev/null; then
|
||||||
_notrun "migrate -b support not compiled in"
|
_notrun "migrate -b support not compiled in"
|
||||||
fi
|
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"'
|
_send_qemu_cmd $src "{ 'execute': 'query-migrate' }" '"status": "completed"'
|
||||||
|
QEMU_COMM_TIMEOUT=$timeout_comm
|
||||||
_send_qemu_cmd $src "{ 'execute': 'query-status' }" "return"
|
_send_qemu_cmd $src "{ 'execute': 'query-status' }" "return"
|
||||||
|
|
||||||
echo
|
echo
|
||||||
|
|
|
@ -60,7 +60,11 @@ fi
|
||||||
qemu_comm_method="monitor"
|
qemu_comm_method="monitor"
|
||||||
_launch_qemu -drive $DRIVE_ARG -incoming defer
|
_launch_qemu -drive $DRIVE_ARG -incoming defer
|
||||||
h=$QEMU_HANDLE
|
h=$QEMU_HANDLE
|
||||||
|
if [ "${VALGRIND_QEMU}" == "y" ]; then
|
||||||
|
QEMU_COMM_TIMEOUT=7
|
||||||
|
else
|
||||||
QEMU_COMM_TIMEOUT=1
|
QEMU_COMM_TIMEOUT=1
|
||||||
|
fi
|
||||||
|
|
||||||
_send_qemu_cmd $h "nbd_server_start unix:$TEST_DIR/nbd" "(qemu)"
|
_send_qemu_cmd $h "nbd_server_start unix:$TEST_DIR/nbd" "(qemu)"
|
||||||
_send_qemu_cmd $h "nbd_server_add -w drive0" "(qemu)"
|
_send_qemu_cmd $h "nbd_server_add -w drive0" "(qemu)"
|
||||||
|
|
|
@ -63,4 +63,5 @@ class TestInvalidateAutoclear(iotests.QMPTestCase):
|
||||||
self.assertEqual(f.read(1), b'\x00')
|
self.assertEqual(f.read(1), b'\x00')
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2'])
|
iotests.main(supported_fmts=['qcow2'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -115,4 +115,5 @@ class TestDirtyBitmapPostcopyMigration(iotests.QMPTestCase):
|
||||||
self.assert_qmp(result, 'return/sha256', sha256);
|
self.assert_qmp(result, 'return/sha256', sha256);
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['qcow2'], supported_cache_modes=['none'])
|
iotests.main(supported_fmts=['qcow2'], supported_cache_modes=['none'],
|
||||||
|
supported_protocols=['file'])
|
||||||
|
|
|
@ -153,4 +153,5 @@ class TestNbdServerRemove(iotests.QMPTestCase):
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=['generic'])
|
iotests.main(supported_fmts=['raw'],
|
||||||
|
supported_protocols=['nbd'])
|
||||||
|
|
|
@ -74,6 +74,12 @@ if [ -n "$TEST_IMG_FILE" ]; then
|
||||||
TEST_IMG=$TEST_IMG_FILE
|
TEST_IMG=$TEST_IMG_FILE
|
||||||
fi
|
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
|
||||||
echo "=== -drive with read-write image: read-only/auto-read-only combinations ==="
|
echo "=== -drive with read-write image: read-only/auto-read-only combinations ==="
|
||||||
echo
|
echo
|
||||||
|
|
|
@ -1000,4 +1000,5 @@ class TestBlockdevReopen(iotests.QMPTestCase):
|
||||||
self.reopen(opts, {'backing': 'hd2'})
|
self.reopen(opts, {'backing': 'hd2'})
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.main(supported_fmts=["qcow2"])
|
iotests.main(supported_fmts=["qcow2"],
|
||||||
|
supported_protocols=["file"])
|
||||||
|
|
|
@ -57,7 +57,11 @@ TEST_IMG="$TEST_IMG.4" _make_test_img $size
|
||||||
{"execute":"block-commit",
|
{"execute":"block-commit",
|
||||||
"arguments":{"device":"format-4", "top-node": "format-2", "base-node":"format-0", "job-id":"job0"}}
|
"arguments":{"device":"format-4", "top-node": "format-2", "base-node":"format-0", "job-id":"job0"}}
|
||||||
EOF
|
EOF
|
||||||
|
if [ "${VALGRIND_QEMU}" == "y" ]; then
|
||||||
|
sleep 10
|
||||||
|
else
|
||||||
sleep 1
|
sleep 1
|
||||||
|
fi
|
||||||
echo '{"execute":"quit"}'
|
echo '{"execute":"quit"}'
|
||||||
) | $QEMU -qmp stdio -nographic -nodefaults \
|
) | $QEMU -qmp stdio -nographic -nodefaults \
|
||||||
-blockdev file,node-name=file-0,filename=$TEST_IMG.0,auto-read-only=on \
|
-blockdev file,node-name=file-0,filename=$TEST_IMG.0,auto-read-only=on \
|
||||||
|
|
|
@ -557,4 +557,5 @@ def main():
|
||||||
test_backup_api()
|
test_backup_api()
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
iotests.script_main(main, supported_fmts=['qcow2'])
|
iotests.script_main(main, supported_fmts=['qcow2'],
|
||||||
|
supported_protocols=['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
|
|
@ -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
|
|
@ -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'])
|
|
@ -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
|
||||||
|
|
|
@ -60,19 +60,68 @@ if ! . ./common.config
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
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()
|
_qemu_wrapper()
|
||||||
{
|
{
|
||||||
|
local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
|
||||||
(
|
(
|
||||||
if [ -n "${QEMU_NEED_PID}" ]; then
|
if [ -n "${QEMU_NEED_PID}" ]; then
|
||||||
echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid"
|
echo $BASHPID > "${QEMU_TEST_DIR}/qemu-${_QEMU_HANDLE}.pid"
|
||||||
fi
|
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()
|
_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()
|
_qemu_io_wrapper()
|
||||||
|
@ -85,36 +134,47 @@ _qemu_io_wrapper()
|
||||||
QEMU_IO_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IO_ARGS"
|
QEMU_IO_ARGS="--object secret,id=keysec0,data=$IMGKEYSECRET $QEMU_IO_ARGS"
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
local RETVAL
|
|
||||||
(
|
(
|
||||||
if [ "${VALGRIND_QEMU}" == "y" ]; then
|
VALGRIND_QEMU="${VALGRIND_QEMU_IO}" _qemu_proc_exec "${VALGRIND_LOGFILE}" \
|
||||||
exec valgrind --log-file="${VALGRIND_LOGFILE}" --error-exitcode=99 "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
|
"$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
|
||||||
else
|
|
||||||
exec "$QEMU_IO_PROG" $QEMU_IO_ARGS "$@"
|
|
||||||
fi
|
|
||||||
)
|
)
|
||||||
RETVAL=$?
|
RETVAL=$?
|
||||||
if [ "${VALGRIND_QEMU}" == "y" ]; then
|
_qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
|
||||||
if [ $RETVAL == 99 ]; then
|
return $RETVAL
|
||||||
cat "${VALGRIND_LOGFILE}"
|
|
||||||
fi
|
|
||||||
rm -f "${VALGRIND_LOGFILE}"
|
|
||||||
fi
|
|
||||||
(exit $RETVAL)
|
|
||||||
}
|
}
|
||||||
|
|
||||||
_qemu_nbd_wrapper()
|
_qemu_nbd_wrapper()
|
||||||
{
|
{
|
||||||
|
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_PROG" --pid-file="${QEMU_TEST_DIR}/qemu-nbd.pid" \
|
||||||
$QEMU_NBD_OPTIONS "$@"
|
$QEMU_NBD_OPTIONS "$@"
|
||||||
|
)
|
||||||
|
RETVAL=$?
|
||||||
|
_qemu_proc_valgrind_log "${VALGRIND_LOGFILE}" $RETVAL
|
||||||
|
return $RETVAL
|
||||||
}
|
}
|
||||||
|
|
||||||
_qemu_vxhs_wrapper()
|
_qemu_vxhs_wrapper()
|
||||||
{
|
{
|
||||||
|
local VALGRIND_LOGFILE="${TEST_DIR}"/$$.valgrind
|
||||||
(
|
(
|
||||||
echo $BASHPID > "${TEST_DIR}/qemu-vxhs.pid"
|
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
|
export QEMU=_qemu_wrapper
|
||||||
|
@ -395,6 +455,15 @@ _notrun()
|
||||||
exit
|
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
|
# just plain bail out
|
||||||
#
|
#
|
||||||
_fail()
|
_fail()
|
||||||
|
|
|
@ -274,3 +274,5 @@
|
||||||
257 rw
|
257 rw
|
||||||
258 rw quick
|
258 rw quick
|
||||||
262 rw quick migration
|
262 rw quick migration
|
||||||
|
265 rw auto quick
|
||||||
|
266 rw quick
|
||||||
|
|
|
@ -909,7 +909,8 @@ def execute_unittest(output, verbosity, debug):
|
||||||
|
|
||||||
def execute_test(test_function=None,
|
def execute_test(test_function=None,
|
||||||
supported_fmts=[], supported_oses=['linux'],
|
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."""
|
"""Run either unittest or script-style tests."""
|
||||||
|
|
||||||
# We are using TEST_DIR and QEMU_DEFAULT_MACHINE as proxies to
|
# 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
|
debug = '-d' in sys.argv
|
||||||
verbosity = 1
|
verbosity = 1
|
||||||
verify_image_format(supported_fmts, unsupported_fmts)
|
verify_image_format(supported_fmts, unsupported_fmts)
|
||||||
|
verify_protocol(supported_protocols, unsupported_protocols)
|
||||||
verify_platform(supported_oses)
|
verify_platform(supported_oses)
|
||||||
verify_cache_mode(supported_cache_modes)
|
verify_cache_mode(supported_cache_modes)
|
||||||
|
|
||||||
|
|
|
@ -848,7 +848,6 @@ BlockJobDriver test_job_driver = {
|
||||||
.instance_size = sizeof(TestBlockJob),
|
.instance_size = sizeof(TestBlockJob),
|
||||||
.free = block_job_free,
|
.free = block_job_free,
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
|
||||||
.run = test_job_run,
|
.run = test_job_run,
|
||||||
.complete = test_job_complete,
|
.complete = test_job_complete,
|
||||||
.prepare = test_job_prepare,
|
.prepare = test_job_prepare,
|
||||||
|
@ -1574,7 +1573,6 @@ static const BlockJobDriver test_drop_backing_job_driver = {
|
||||||
.instance_size = sizeof(TestDropBackingBlockJob),
|
.instance_size = sizeof(TestDropBackingBlockJob),
|
||||||
.free = block_job_free,
|
.free = block_job_free,
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
|
||||||
.run = test_drop_backing_job_run,
|
.run = test_drop_backing_job_run,
|
||||||
.commit = test_drop_backing_job_commit,
|
.commit = test_drop_backing_job_commit,
|
||||||
}
|
}
|
||||||
|
@ -1711,7 +1709,6 @@ static const BlockJobDriver test_simple_job_driver = {
|
||||||
.instance_size = sizeof(TestSimpleBlockJob),
|
.instance_size = sizeof(TestSimpleBlockJob),
|
||||||
.free = block_job_free,
|
.free = block_job_free,
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
|
||||||
.run = test_simple_job_run,
|
.run = test_simple_job_run,
|
||||||
.clean = test_simple_job_clean,
|
.clean = test_simple_job_clean,
|
||||||
},
|
},
|
||||||
|
|
|
@ -401,7 +401,6 @@ BlockJobDriver test_job_driver = {
|
||||||
.instance_size = sizeof(TestBlockJob),
|
.instance_size = sizeof(TestBlockJob),
|
||||||
.free = block_job_free,
|
.free = block_job_free,
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
|
||||||
.run = test_job_run,
|
.run = test_job_run,
|
||||||
.complete = test_job_complete,
|
.complete = test_job_complete,
|
||||||
.prepare = test_job_prepare,
|
.prepare = test_job_prepare,
|
||||||
|
|
|
@ -72,7 +72,6 @@ static const BlockJobDriver test_block_job_driver = {
|
||||||
.instance_size = sizeof(TestBlockJob),
|
.instance_size = sizeof(TestBlockJob),
|
||||||
.free = block_job_free,
|
.free = block_job_free,
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
|
||||||
.run = test_block_job_run,
|
.run = test_block_job_run,
|
||||||
.clean = test_block_job_clean,
|
.clean = test_block_job_clean,
|
||||||
},
|
},
|
||||||
|
|
|
@ -22,7 +22,6 @@ static const BlockJobDriver test_block_job_driver = {
|
||||||
.instance_size = sizeof(BlockJob),
|
.instance_size = sizeof(BlockJob),
|
||||||
.free = block_job_free,
|
.free = block_job_free,
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -196,7 +195,6 @@ static const BlockJobDriver test_cancel_driver = {
|
||||||
.instance_size = sizeof(CancelJob),
|
.instance_size = sizeof(CancelJob),
|
||||||
.free = block_job_free,
|
.free = block_job_free,
|
||||||
.user_resume = block_job_user_resume,
|
.user_resume = block_job_user_resume,
|
||||||
.drain = block_job_drain,
|
|
||||||
.run = cancel_job_run,
|
.run = cancel_job_run,
|
||||||
.complete = cancel_job_complete,
|
.complete = cancel_job_complete,
|
||||||
},
|
},
|
||||||
|
|
Loading…
Reference in New Issue