mirror of
				https://github.com/qemu/qemu.git
				synced 2025-10-31 04:06:46 +00:00 
			
		
		
		
	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); | ||||
| } | ||||
| 
 | ||||
| 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, | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
| @ -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; | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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; | ||||
|     } | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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); | ||||
|  | ||||
| @ -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, | ||||
|     }, | ||||
| }; | ||||
| 
 | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
							
								
								
									
										13
									
								
								blockjob.c
									
									
									
									
									
								
							
							
						
						
									
										13
									
								
								blockjob.c
									
									
									
									
									
								
							| @ -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; | ||||
| 
 | ||||
|  | ||||
| @ -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: | ||||
|  * | ||||
|  | ||||
| @ -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
									
									
									
									
									
								
							
							
						
						
									
										12
									
								
								job.c
									
									
									
									
									
								
							| @ -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); | ||||
|  | ||||
| @ -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; | ||||
| } | ||||
| 
 | ||||
|  | ||||
| @ -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.  */ | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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']) | ||||
|  | ||||
| @ -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 \ | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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']) | ||||
|  | ||||
| @ -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']) | ||||
|  | ||||
| @ -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']) | ||||
|  | ||||
| @ -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']) | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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']) | ||||
|  | ||||
| @ -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']) | ||||
|  | ||||
| @ -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']) | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -129,4 +129,5 @@ TestQemuImgInfo = None | ||||
| TestQMP = None | ||||
| 
 | ||||
| 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') | ||||
| 
 | ||||
| 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) | ||||
|     # 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']) | ||||
|  | ||||
| @ -779,4 +779,5 @@ class TestIncrementalBackupBlkdebug(TestIncrementalBackupBase): | ||||
| 
 | ||||
| 
 | ||||
| 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") | ||||
| 
 | ||||
| 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') | ||||
| 
 | ||||
| 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 | ||||
| # 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" \ | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -358,4 +358,5 @@ class TestBlockdevDel(iotests.QMPTestCase): | ||||
| 
 | ||||
| 
 | ||||
| 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__': | ||||
|     # 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']) | ||||
|  | ||||
| @ -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"]) | ||||
|  | ||||
| @ -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']) | ||||
|  | ||||
| @ -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']) | ||||
|  | ||||
| @ -258,4 +258,5 @@ BaseClass = None | ||||
| MirrorBaseClass = None | ||||
| 
 | ||||
| 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 | ||||
| 
 | ||||
| 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() | ||||
| 
 | ||||
| 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)) | ||||
| 
 | ||||
| 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" | ||||
| 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 | ||||
|  | ||||
| @ -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)" | ||||
|  | ||||
| @ -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']) | ||||
|  | ||||
| @ -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']) | ||||
|  | ||||
| @ -153,4 +153,5 @@ class TestNbdServerRemove(iotests.QMPTestCase): | ||||
| 
 | ||||
| 
 | ||||
| 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 | ||||
| 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 | ||||
|  | ||||
| @ -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"]) | ||||
|  | ||||
| @ -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 \ | ||||
|  | ||||
| @ -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
									
								
							
							
						
						
									
										67
									
								
								tests/qemu-iotests/265
									
									
									
									
									
										Executable 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 | ||||
							
								
								
									
										6
									
								
								tests/qemu-iotests/265.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										6
									
								
								tests/qemu-iotests/265.out
									
									
									
									
									
										Normal 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
									
								
							
							
						
						
									
										153
									
								
								tests/qemu-iotests/266
									
									
									
									
									
										Executable 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
									
								
							
							
						
						
									
										137
									
								
								tests/qemu-iotests/266.out
									
									
									
									
									
										Normal 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 | ||||
| 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() | ||||
|  | ||||
| @ -274,3 +274,5 @@ | ||||
| 257 rw | ||||
| 258 rw quick | ||||
| 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, | ||||
|                  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) | ||||
| 
 | ||||
|  | ||||
| @ -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, | ||||
|     }, | ||||
|  | ||||
| @ -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, | ||||
|  | ||||
| @ -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, | ||||
|     }, | ||||
|  | ||||
| @ -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, | ||||
|     }, | ||||
|  | ||||
		Loading…
	
		Reference in New Issue
	
	Block a user
	 Peter Maydell
						Peter Maydell