Block layer patches
-----BEGIN PGP SIGNATURE----- Version: GnuPG v2.0.22 (GNU/Linux) iQIcBAABAgAGBQJZbg1XAAoJEH8JsnLIjy/Wdj8QAJm5SE8cOwonEDRd9AV5n0Eg xoHLFEEKjqBJ8oDHHn7huVbNdHN693vM2ro2Exxx8ZCTSdIkvSeVmEOrzb76sWOe QRbCTWUKbMD6wjCNF5tqPsvmk+ZkHMqYhyVcRAaIpd+IcEECA16ot/fhRa6Ec/bk 8GHzDSxkVq5wFgoEJ09hGEE7GY2uGdV1HEJK7xq+Vittx8LV3QMnlH4KvZ9VzYfe BnNsmK5vMNlsHTfWfQXsB+sxb+aGGr5v45e4XfctTxGx08ajMC50WnYZUezySERJ TXimHOiJNHMpapfU7focLuapwMm6AxpQAh5QzxTBgaqW7eeX3P16DWx4m/WfRL7v AuyM4U3TdH0vYZPGlQ5pAlScmeZh+GRBRiDkJf/04q7hH2Hgt85+8gyef7FF/Qta KT49tBr64eA89ZUDVFBCkukyYWKWTDSNrGJjB6gMqh7cI6gI55uLdXB/nF4vCgJu YfYTdaF/1GJm22HtAg3O5fctRDh14rkBgi5jPhifaT7pP0zZm0JBxGlpXUWkg3RA NIhZ2fJ2/FasS7/5IsUjJbYuI52CTLmNXQIRt/ZHekzQkgk1VPrnJls0ibCdG8NF 4z90uIG7bUuEIjZWKogB+gyH9MMtG3qlfZ0RjmXq2FfWCNhBmfezcGOx+Jnf+XDb IMPzzwu77XVcduj4XxKL =2c6k -----END PGP SIGNATURE----- Merge remote-tracking branch 'remotes/kevin/tags/for-upstream' into staging Block layer patches # gpg: Signature made Tue 18 Jul 2017 14:29:59 BST # gpg: using RSA key 0x7F09B272C88F2FD6 # gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" # Primary key fingerprint: DC3D EB15 9A9A F95D 3D74 56FE 7F09 B272 C88F 2FD6 * remotes/kevin/tags/for-upstream: (21 commits) qemu-img: Check for backing image if specified during create blockdev: move BDRV_O_NO_BACKING option forward block/vvfat: Fix compiler warning with gcc 7 vvfat: initialize memory after allocating it vvfat: correctly parse non-ASCII short and long file names vvfat: add a constant for bootsector name vvfat: add constants for special values of name[0] qemu-iotests: Test unplug of -device without drive qemu-iotests: Test 'info block' scsi-disk: bdrv_attach_dev() for empty CD-ROM ide: bdrv_attach_dev() for empty CD-ROM block: List anonymous device BBs in query-block block/qapi: Use blk_all_next() for query-block block: Make blk_all_next() public block/qapi: Add qdev device name to query-block block: Make blk_get_attached_dev_id() public block/vpc.c: Handle write failures in get_image_offset() block/vmdk: Report failures in vmdk_read_cid() block: remove timer canceling in throttle_config() block: add clock_type field to ThrottleGroup ... Signed-off-by: Peter Maydell <peter.maydell@linaro.org>
This commit is contained in:
		
						commit
						f1a46e8885
					
				
							
								
								
									
										32
									
								
								block.c
									
									
									
									
									
								
							
							
						
						
									
										32
									
								
								block.c
									
									
									
									
									
								
							@ -4396,14 +4396,12 @@ void bdrv_img_create(const char *filename, const char *fmt,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    backing_fmt = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT);
 | 
					    backing_fmt = qemu_opt_get(opts, BLOCK_OPT_BACKING_FMT);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    // The size for the image must always be specified, with one exception:
 | 
					    /* The size for the image must always be specified, unless we have a backing
 | 
				
			||||||
    // If we are using a backing file, we can obtain the size from there
 | 
					     * file and we have not been forbidden from opening it. */
 | 
				
			||||||
    size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0);
 | 
					    size = qemu_opt_get_size(opts, BLOCK_OPT_SIZE, 0);
 | 
				
			||||||
    if (size == -1) {
 | 
					    if (backing_file && !(flags & BDRV_O_NO_BACKING)) {
 | 
				
			||||||
        if (backing_file) {
 | 
					 | 
				
			||||||
        BlockDriverState *bs;
 | 
					        BlockDriverState *bs;
 | 
				
			||||||
        char *full_backing = g_new0(char, PATH_MAX);
 | 
					        char *full_backing = g_new0(char, PATH_MAX);
 | 
				
			||||||
            int64_t size;
 | 
					 | 
				
			||||||
        int back_flags;
 | 
					        int back_flags;
 | 
				
			||||||
        QDict *backing_options = NULL;
 | 
					        QDict *backing_options = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -4427,9 +4425,20 @@ void bdrv_img_create(const char *filename, const char *fmt,
 | 
				
			|||||||
        bs = bdrv_open(full_backing, NULL, backing_options, back_flags,
 | 
					        bs = bdrv_open(full_backing, NULL, backing_options, back_flags,
 | 
				
			||||||
                       &local_err);
 | 
					                       &local_err);
 | 
				
			||||||
        g_free(full_backing);
 | 
					        g_free(full_backing);
 | 
				
			||||||
            if (!bs) {
 | 
					        if (!bs && size != -1) {
 | 
				
			||||||
 | 
					            /* Couldn't open BS, but we have a size, so it's nonfatal */
 | 
				
			||||||
 | 
					            warn_reportf_err(local_err,
 | 
				
			||||||
 | 
					                            "Could not verify backing image. "
 | 
				
			||||||
 | 
					                            "This may become an error in future versions.\n");
 | 
				
			||||||
 | 
					            local_err = NULL;
 | 
				
			||||||
 | 
					        } else if (!bs) {
 | 
				
			||||||
 | 
					            /* Couldn't open bs, do not have size */
 | 
				
			||||||
 | 
					            error_append_hint(&local_err,
 | 
				
			||||||
 | 
					                              "Could not open backing image to determine size.\n");
 | 
				
			||||||
            goto out;
 | 
					            goto out;
 | 
				
			||||||
            }
 | 
					        } else {
 | 
				
			||||||
 | 
					            if (size == -1) {
 | 
				
			||||||
 | 
					                /* Opened BS, have no size */
 | 
				
			||||||
                size = bdrv_getlength(bs);
 | 
					                size = bdrv_getlength(bs);
 | 
				
			||||||
                if (size < 0) {
 | 
					                if (size < 0) {
 | 
				
			||||||
                    error_setg_errno(errp, -size, "Could not get size of '%s'",
 | 
					                    error_setg_errno(errp, -size, "Could not get size of '%s'",
 | 
				
			||||||
@ -4437,15 +4446,16 @@ void bdrv_img_create(const char *filename, const char *fmt,
 | 
				
			|||||||
                    bdrv_unref(bs);
 | 
					                    bdrv_unref(bs);
 | 
				
			||||||
                    goto out;
 | 
					                    goto out;
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
 | 
					 | 
				
			||||||
                qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, &error_abort);
 | 
					                qemu_opt_set_number(opts, BLOCK_OPT_SIZE, size, &error_abort);
 | 
				
			||||||
 | 
					            }
 | 
				
			||||||
            bdrv_unref(bs);
 | 
					            bdrv_unref(bs);
 | 
				
			||||||
        } else {
 | 
					        }
 | 
				
			||||||
 | 
					    } /* (backing_file && !(flags & BDRV_O_NO_BACKING)) */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if (size == -1) {
 | 
				
			||||||
        error_setg(errp, "Image creation needs a size parameter");
 | 
					        error_setg(errp, "Image creation needs a size parameter");
 | 
				
			||||||
        goto out;
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!quiet) {
 | 
					    if (!quiet) {
 | 
				
			||||||
        printf("Formatting '%s', fmt=%s ", filename, fmt);
 | 
					        printf("Formatting '%s', fmt=%s ", filename, fmt);
 | 
				
			||||||
 | 
				
			|||||||
@ -83,7 +83,6 @@ static const AIOCBInfo block_backend_aiocb_info = {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static void drive_info_del(DriveInfo *dinfo);
 | 
					static void drive_info_del(DriveInfo *dinfo);
 | 
				
			||||||
static BlockBackend *bdrv_first_blk(BlockDriverState *bs);
 | 
					static BlockBackend *bdrv_first_blk(BlockDriverState *bs);
 | 
				
			||||||
static char *blk_get_attached_dev_id(BlockBackend *blk);
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* All BlockBackends */
 | 
					/* All BlockBackends */
 | 
				
			||||||
static QTAILQ_HEAD(, BlockBackend) block_backends =
 | 
					static QTAILQ_HEAD(, BlockBackend) block_backends =
 | 
				
			||||||
@ -343,7 +342,7 @@ void blk_unref(BlockBackend *blk)
 | 
				
			|||||||
 * Behaves similarly to blk_next() but iterates over all BlockBackends, even the
 | 
					 * Behaves similarly to blk_next() but iterates over all BlockBackends, even the
 | 
				
			||||||
 * ones which are hidden (i.e. are not referenced by the monitor).
 | 
					 * ones which are hidden (i.e. are not referenced by the monitor).
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static BlockBackend *blk_all_next(BlockBackend *blk)
 | 
					BlockBackend *blk_all_next(BlockBackend *blk)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return blk ? QTAILQ_NEXT(blk, link)
 | 
					    return blk ? QTAILQ_NEXT(blk, link)
 | 
				
			||||||
               : QTAILQ_FIRST(&block_backends);
 | 
					               : QTAILQ_FIRST(&block_backends);
 | 
				
			||||||
@ -726,7 +725,7 @@ void *blk_get_attached_dev(BlockBackend *blk)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
/* Return the qdev ID, or if no ID is assigned the QOM path, of the block
 | 
					/* Return the qdev ID, or if no ID is assigned the QOM path, of the block
 | 
				
			||||||
 * device attached to the BlockBackend. */
 | 
					 * device attached to the BlockBackend. */
 | 
				
			||||||
static char *blk_get_attached_dev_id(BlockBackend *blk)
 | 
					char *blk_get_attached_dev_id(BlockBackend *blk)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    DeviceState *dev;
 | 
					    DeviceState *dev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -90,7 +90,9 @@ static void commit_complete(BlockJob *job, void *opaque)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    /* Make sure overlay_bs and top stay around until bdrv_set_backing_hd() */
 | 
					    /* Make sure overlay_bs and top stay around until bdrv_set_backing_hd() */
 | 
				
			||||||
    bdrv_ref(top);
 | 
					    bdrv_ref(top);
 | 
				
			||||||
 | 
					    if (overlay_bs) {
 | 
				
			||||||
        bdrv_ref(overlay_bs);
 | 
					        bdrv_ref(overlay_bs);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Remove base node parent that still uses BLK_PERM_WRITE/RESIZE before
 | 
					    /* Remove base node parent that still uses BLK_PERM_WRITE/RESIZE before
 | 
				
			||||||
     * the normal backing chain can be restored. */
 | 
					     * the normal backing chain can be restored. */
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										20
									
								
								block/qapi.c
									
									
									
									
									
								
							
							
						
						
									
										20
									
								
								block/qapi.c
									
									
									
									
									
								
							@ -322,11 +322,21 @@ static void bdrv_query_info(BlockBackend *blk, BlockInfo **p_info,
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    BlockInfo *info = g_malloc0(sizeof(*info));
 | 
					    BlockInfo *info = g_malloc0(sizeof(*info));
 | 
				
			||||||
    BlockDriverState *bs = blk_bs(blk);
 | 
					    BlockDriverState *bs = blk_bs(blk);
 | 
				
			||||||
 | 
					    char *qdev;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    info->device = g_strdup(blk_name(blk));
 | 
					    info->device = g_strdup(blk_name(blk));
 | 
				
			||||||
    info->type = g_strdup("unknown");
 | 
					    info->type = g_strdup("unknown");
 | 
				
			||||||
    info->locked = blk_dev_is_medium_locked(blk);
 | 
					    info->locked = blk_dev_is_medium_locked(blk);
 | 
				
			||||||
    info->removable = blk_dev_has_removable_media(blk);
 | 
					    info->removable = blk_dev_has_removable_media(blk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    qdev = blk_get_attached_dev_id(blk);
 | 
				
			||||||
 | 
					    if (qdev && *qdev) {
 | 
				
			||||||
 | 
					        info->has_qdev = true;
 | 
				
			||||||
 | 
					        info->qdev = qdev;
 | 
				
			||||||
 | 
					    } else {
 | 
				
			||||||
 | 
					        g_free(qdev);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (blk_dev_has_tray(blk)) {
 | 
					    if (blk_dev_has_tray(blk)) {
 | 
				
			||||||
        info->has_tray_open = true;
 | 
					        info->has_tray_open = true;
 | 
				
			||||||
        info->tray_open = blk_dev_is_tray_open(blk);
 | 
					        info->tray_open = blk_dev_is_tray_open(blk);
 | 
				
			||||||
@ -462,8 +472,14 @@ BlockInfoList *qmp_query_block(Error **errp)
 | 
				
			|||||||
    BlockBackend *blk;
 | 
					    BlockBackend *blk;
 | 
				
			||||||
    Error *local_err = NULL;
 | 
					    Error *local_err = NULL;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (blk = blk_next(NULL); blk; blk = blk_next(blk)) {
 | 
					    for (blk = blk_all_next(NULL); blk; blk = blk_all_next(blk)) {
 | 
				
			||||||
        BlockInfoList *info = g_malloc0(sizeof(*info));
 | 
					        BlockInfoList *info;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (!*blk_name(blk) && !blk_get_attached_dev(blk)) {
 | 
				
			||||||
 | 
					            continue;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        info = g_malloc0(sizeof(*info));
 | 
				
			||||||
        bdrv_query_info(blk, &info->value, &local_err);
 | 
					        bdrv_query_info(blk, &info->value, &local_err);
 | 
				
			||||||
        if (local_err) {
 | 
					        if (local_err) {
 | 
				
			||||||
            error_propagate(errp, local_err);
 | 
					            error_propagate(errp, local_err);
 | 
				
			||||||
 | 
				
			|||||||
@ -61,6 +61,7 @@ typedef struct ThrottleGroup {
 | 
				
			|||||||
    QLIST_HEAD(, BlockBackendPublic) head;
 | 
					    QLIST_HEAD(, BlockBackendPublic) head;
 | 
				
			||||||
    BlockBackend *tokens[2];
 | 
					    BlockBackend *tokens[2];
 | 
				
			||||||
    bool any_timer_armed[2];
 | 
					    bool any_timer_armed[2];
 | 
				
			||||||
 | 
					    QEMUClockType clock_type;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* These two are protected by the global throttle_groups_lock */
 | 
					    /* These two are protected by the global throttle_groups_lock */
 | 
				
			||||||
    unsigned refcount;
 | 
					    unsigned refcount;
 | 
				
			||||||
@ -98,6 +99,12 @@ ThrottleState *throttle_group_incref(const char *name)
 | 
				
			|||||||
    if (!tg) {
 | 
					    if (!tg) {
 | 
				
			||||||
        tg = g_new0(ThrottleGroup, 1);
 | 
					        tg = g_new0(ThrottleGroup, 1);
 | 
				
			||||||
        tg->name = g_strdup(name);
 | 
					        tg->name = g_strdup(name);
 | 
				
			||||||
 | 
					        tg->clock_type = QEMU_CLOCK_REALTIME;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        if (qtest_enabled()) {
 | 
				
			||||||
 | 
					            /* For testing block IO throttling only */
 | 
				
			||||||
 | 
					            tg->clock_type = QEMU_CLOCK_VIRTUAL;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        qemu_mutex_init(&tg->lock);
 | 
					        qemu_mutex_init(&tg->lock);
 | 
				
			||||||
        throttle_init(&tg->ts);
 | 
					        throttle_init(&tg->ts);
 | 
				
			||||||
        QLIST_INIT(&tg->head);
 | 
					        QLIST_INIT(&tg->head);
 | 
				
			||||||
@ -310,7 +317,7 @@ static void schedule_next_request(BlockBackend *blk, bool is_write)
 | 
				
			|||||||
            token = blk;
 | 
					            token = blk;
 | 
				
			||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            ThrottleTimers *tt = &blk_get_public(token)->throttle_timers;
 | 
					            ThrottleTimers *tt = &blk_get_public(token)->throttle_timers;
 | 
				
			||||||
            int64_t now = qemu_clock_get_ns(tt->clock_type);
 | 
					            int64_t now = qemu_clock_get_ns(tg->clock_type);
 | 
				
			||||||
            timer_mod(tt->timers[is_write], now);
 | 
					            timer_mod(tt->timers[is_write], now);
 | 
				
			||||||
            tg->any_timer_armed[is_write] = true;
 | 
					            tg->any_timer_armed[is_write] = true;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
@ -419,18 +426,10 @@ void throttle_group_restart_blk(BlockBackend *blk)
 | 
				
			|||||||
void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg)
 | 
					void throttle_group_config(BlockBackend *blk, ThrottleConfig *cfg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    BlockBackendPublic *blkp = blk_get_public(blk);
 | 
					    BlockBackendPublic *blkp = blk_get_public(blk);
 | 
				
			||||||
    ThrottleTimers *tt = &blkp->throttle_timers;
 | 
					 | 
				
			||||||
    ThrottleState *ts = blkp->throttle_state;
 | 
					    ThrottleState *ts = blkp->throttle_state;
 | 
				
			||||||
    ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
 | 
					    ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
 | 
				
			||||||
    qemu_mutex_lock(&tg->lock);
 | 
					    qemu_mutex_lock(&tg->lock);
 | 
				
			||||||
    /* throttle_config() cancels the timers */
 | 
					    throttle_config(ts, tg->clock_type, cfg);
 | 
				
			||||||
    if (timer_pending(tt->timers[0])) {
 | 
					 | 
				
			||||||
        tg->any_timer_armed[0] = false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    if (timer_pending(tt->timers[1])) {
 | 
					 | 
				
			||||||
        tg->any_timer_armed[1] = false;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    throttle_config(ts, tt, cfg);
 | 
					 | 
				
			||||||
    qemu_mutex_unlock(&tg->lock);
 | 
					    qemu_mutex_unlock(&tg->lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    throttle_group_restart_blk(blk);
 | 
					    throttle_group_restart_blk(blk);
 | 
				
			||||||
@ -497,13 +496,6 @@ void throttle_group_register_blk(BlockBackend *blk, const char *groupname)
 | 
				
			|||||||
    BlockBackendPublic *blkp = blk_get_public(blk);
 | 
					    BlockBackendPublic *blkp = blk_get_public(blk);
 | 
				
			||||||
    ThrottleState *ts = throttle_group_incref(groupname);
 | 
					    ThrottleState *ts = throttle_group_incref(groupname);
 | 
				
			||||||
    ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
 | 
					    ThrottleGroup *tg = container_of(ts, ThrottleGroup, ts);
 | 
				
			||||||
    int clock_type = QEMU_CLOCK_REALTIME;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    if (qtest_enabled()) {
 | 
					 | 
				
			||||||
        /* For testing block IO throttling only */
 | 
					 | 
				
			||||||
        clock_type = QEMU_CLOCK_VIRTUAL;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    blkp->throttle_state = ts;
 | 
					    blkp->throttle_state = ts;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qemu_mutex_lock(&tg->lock);
 | 
					    qemu_mutex_lock(&tg->lock);
 | 
				
			||||||
@ -518,7 +510,7 @@ void throttle_group_register_blk(BlockBackend *blk, const char *groupname)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    throttle_timers_init(&blkp->throttle_timers,
 | 
					    throttle_timers_init(&blkp->throttle_timers,
 | 
				
			||||||
                         blk_get_aio_context(blk),
 | 
					                         blk_get_aio_context(blk),
 | 
				
			||||||
                         clock_type,
 | 
					                         tg->clock_type,
 | 
				
			||||||
                         read_timer_cb,
 | 
					                         read_timer_cb,
 | 
				
			||||||
                         write_timer_cb,
 | 
					                         write_timer_cb,
 | 
				
			||||||
                         blk);
 | 
					                         blk);
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										44
									
								
								block/vmdk.c
									
									
									
									
									
								
							
							
						
						
									
										44
									
								
								block/vmdk.c
									
									
									
									
									
								
							@ -242,10 +242,11 @@ static void vmdk_free_last_extent(BlockDriverState *bs)
 | 
				
			|||||||
    s->extents = g_renew(VmdkExtent, s->extents, s->num_extents);
 | 
					    s->extents = g_renew(VmdkExtent, s->extents, s->num_extents);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
 | 
					/* Return -ve errno, or 0 on success and write CID into *pcid. */
 | 
				
			||||||
 | 
					static int vmdk_read_cid(BlockDriverState *bs, int parent, uint32_t *pcid)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    char *desc;
 | 
					    char *desc;
 | 
				
			||||||
    uint32_t cid = 0xffffffff;
 | 
					    uint32_t cid;
 | 
				
			||||||
    const char *p_name, *cid_str;
 | 
					    const char *p_name, *cid_str;
 | 
				
			||||||
    size_t cid_str_size;
 | 
					    size_t cid_str_size;
 | 
				
			||||||
    BDRVVmdkState *s = bs->opaque;
 | 
					    BDRVVmdkState *s = bs->opaque;
 | 
				
			||||||
@ -254,8 +255,7 @@ static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
 | 
				
			|||||||
    desc = g_malloc0(DESC_SIZE);
 | 
					    desc = g_malloc0(DESC_SIZE);
 | 
				
			||||||
    ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
 | 
					    ret = bdrv_pread(bs->file, s->desc_offset, desc, DESC_SIZE);
 | 
				
			||||||
    if (ret < 0) {
 | 
					    if (ret < 0) {
 | 
				
			||||||
        g_free(desc);
 | 
					        goto out;
 | 
				
			||||||
        return 0;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (parent) {
 | 
					    if (parent) {
 | 
				
			||||||
@ -268,13 +268,21 @@ static uint32_t vmdk_read_cid(BlockDriverState *bs, int parent)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    desc[DESC_SIZE - 1] = '\0';
 | 
					    desc[DESC_SIZE - 1] = '\0';
 | 
				
			||||||
    p_name = strstr(desc, cid_str);
 | 
					    p_name = strstr(desc, cid_str);
 | 
				
			||||||
    if (p_name != NULL) {
 | 
					    if (p_name == NULL) {
 | 
				
			||||||
        p_name += cid_str_size;
 | 
					        ret = -EINVAL;
 | 
				
			||||||
        sscanf(p_name, "%" SCNx32, &cid);
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					    p_name += cid_str_size;
 | 
				
			||||||
 | 
					    if (sscanf(p_name, "%" SCNx32, &cid) != 1) {
 | 
				
			||||||
 | 
					        ret = -EINVAL;
 | 
				
			||||||
 | 
					        goto out;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    *pcid = cid;
 | 
				
			||||||
 | 
					    ret = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					out:
 | 
				
			||||||
    g_free(desc);
 | 
					    g_free(desc);
 | 
				
			||||||
    return cid;
 | 
					    return ret;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
 | 
					static int vmdk_write_cid(BlockDriverState *bs, uint32_t cid)
 | 
				
			||||||
@ -322,7 +330,10 @@ static int vmdk_is_cid_valid(BlockDriverState *bs)
 | 
				
			|||||||
    if (!s->cid_checked && bs->backing) {
 | 
					    if (!s->cid_checked && bs->backing) {
 | 
				
			||||||
        BlockDriverState *p_bs = bs->backing->bs;
 | 
					        BlockDriverState *p_bs = bs->backing->bs;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        cur_pcid = vmdk_read_cid(p_bs, 0);
 | 
					        if (vmdk_read_cid(p_bs, 0, &cur_pcid) != 0) {
 | 
				
			||||||
 | 
					            /* read failure: report as not valid */
 | 
				
			||||||
 | 
					            return 0;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if (s->parent_cid != cur_pcid) {
 | 
					        if (s->parent_cid != cur_pcid) {
 | 
				
			||||||
            /* CID not valid */
 | 
					            /* CID not valid */
 | 
				
			||||||
            return 0;
 | 
					            return 0;
 | 
				
			||||||
@ -975,8 +986,14 @@ static int vmdk_open(BlockDriverState *bs, QDict *options, int flags,
 | 
				
			|||||||
    if (ret) {
 | 
					    if (ret) {
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    s->cid = vmdk_read_cid(bs, 0);
 | 
					    ret = vmdk_read_cid(bs, 0, &s->cid);
 | 
				
			||||||
    s->parent_cid = vmdk_read_cid(bs, 1);
 | 
					    if (ret) {
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    ret = vmdk_read_cid(bs, 1, &s->parent_cid);
 | 
				
			||||||
 | 
					    if (ret) {
 | 
				
			||||||
 | 
					        goto fail;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
    qemu_co_mutex_init(&s->lock);
 | 
					    qemu_co_mutex_init(&s->lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* Disable migration when VMDK images are used */
 | 
					    /* Disable migration when VMDK images are used */
 | 
				
			||||||
@ -2008,8 +2025,11 @@ static int vmdk_create(const char *filename, QemuOpts *opts, Error **errp)
 | 
				
			|||||||
            ret = -EINVAL;
 | 
					            ret = -EINVAL;
 | 
				
			||||||
            goto exit;
 | 
					            goto exit;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        parent_cid = vmdk_read_cid(blk_bs(blk), 0);
 | 
					        ret = vmdk_read_cid(blk_bs(blk), 0, &parent_cid);
 | 
				
			||||||
        blk_unref(blk);
 | 
					        blk_unref(blk);
 | 
				
			||||||
 | 
					        if (ret) {
 | 
				
			||||||
 | 
					            goto exit;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        snprintf(parent_desc_line, BUF_SIZE,
 | 
					        snprintf(parent_desc_line, BUF_SIZE,
 | 
				
			||||||
                "parentFileNameHint=\"%s\"", backing_file);
 | 
					                "parentFileNameHint=\"%s\"", backing_file);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										30
									
								
								block/vpc.c
									
									
									
									
									
								
							
							
						
						
									
										30
									
								
								block/vpc.c
									
									
									
									
									
								
							@ -460,17 +460,23 @@ static int vpc_reopen_prepare(BDRVReopenState *state,
 | 
				
			|||||||
/*
 | 
					/*
 | 
				
			||||||
 * Returns the absolute byte offset of the given sector in the image file.
 | 
					 * Returns the absolute byte offset of the given sector in the image file.
 | 
				
			||||||
 * If the sector is not allocated, -1 is returned instead.
 | 
					 * If the sector is not allocated, -1 is returned instead.
 | 
				
			||||||
 | 
					 * If an error occurred trying to write an updated block bitmap back to
 | 
				
			||||||
 | 
					 * the file, -2 is returned, and the error value is written to *err.
 | 
				
			||||||
 | 
					 * This can only happen for a write operation.
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * The parameter write must be 1 if the offset will be used for a write
 | 
					 * The parameter write must be 1 if the offset will be used for a write
 | 
				
			||||||
 * operation (the block bitmaps is updated then), 0 otherwise.
 | 
					 * operation (the block bitmaps is updated then), 0 otherwise.
 | 
				
			||||||
 | 
					 * If write is true then err must not be NULL.
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
static inline int64_t get_image_offset(BlockDriverState *bs, uint64_t offset,
 | 
					static inline int64_t get_image_offset(BlockDriverState *bs, uint64_t offset,
 | 
				
			||||||
                                       bool write)
 | 
					                                       bool write, int *err)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    BDRVVPCState *s = bs->opaque;
 | 
					    BDRVVPCState *s = bs->opaque;
 | 
				
			||||||
    uint64_t bitmap_offset, block_offset;
 | 
					    uint64_t bitmap_offset, block_offset;
 | 
				
			||||||
    uint32_t pagetable_index, offset_in_block;
 | 
					    uint32_t pagetable_index, offset_in_block;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    assert(!(write && err == NULL));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    pagetable_index = offset / s->block_size;
 | 
					    pagetable_index = offset / s->block_size;
 | 
				
			||||||
    offset_in_block = offset % s->block_size;
 | 
					    offset_in_block = offset % s->block_size;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -487,10 +493,15 @@ static inline int64_t get_image_offset(BlockDriverState *bs, uint64_t offset,
 | 
				
			|||||||
       correctness. */
 | 
					       correctness. */
 | 
				
			||||||
    if (write && (s->last_bitmap_offset != bitmap_offset)) {
 | 
					    if (write && (s->last_bitmap_offset != bitmap_offset)) {
 | 
				
			||||||
        uint8_t bitmap[s->bitmap_size];
 | 
					        uint8_t bitmap[s->bitmap_size];
 | 
				
			||||||
 | 
					        int r;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        s->last_bitmap_offset = bitmap_offset;
 | 
					        s->last_bitmap_offset = bitmap_offset;
 | 
				
			||||||
        memset(bitmap, 0xff, s->bitmap_size);
 | 
					        memset(bitmap, 0xff, s->bitmap_size);
 | 
				
			||||||
        bdrv_pwrite_sync(bs->file, bitmap_offset, bitmap, s->bitmap_size);
 | 
					        r = bdrv_pwrite_sync(bs->file, bitmap_offset, bitmap, s->bitmap_size);
 | 
				
			||||||
 | 
					        if (r < 0) {
 | 
				
			||||||
 | 
					            *err = r;
 | 
				
			||||||
 | 
					            return -2;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return block_offset;
 | 
					    return block_offset;
 | 
				
			||||||
@ -561,7 +572,7 @@ static int64_t alloc_block(BlockDriverState* bs, int64_t offset)
 | 
				
			|||||||
    if (ret < 0)
 | 
					    if (ret < 0)
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return get_image_offset(bs, offset, false);
 | 
					    return get_image_offset(bs, offset, false, NULL);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fail:
 | 
					fail:
 | 
				
			||||||
    s->free_data_block_offset -= (s->block_size + s->bitmap_size);
 | 
					    s->free_data_block_offset -= (s->block_size + s->bitmap_size);
 | 
				
			||||||
@ -601,7 +612,7 @@ vpc_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
 | 
				
			|||||||
    qemu_iovec_init(&local_qiov, qiov->niov);
 | 
					    qemu_iovec_init(&local_qiov, qiov->niov);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (bytes > 0) {
 | 
					    while (bytes > 0) {
 | 
				
			||||||
        image_offset = get_image_offset(bs, offset, false);
 | 
					        image_offset = get_image_offset(bs, offset, false, NULL);
 | 
				
			||||||
        n_bytes = MIN(bytes, s->block_size - (offset % s->block_size));
 | 
					        n_bytes = MIN(bytes, s->block_size - (offset % s->block_size));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (image_offset == -1) {
 | 
					        if (image_offset == -1) {
 | 
				
			||||||
@ -650,7 +661,11 @@ vpc_co_pwritev(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
 | 
				
			|||||||
    qemu_iovec_init(&local_qiov, qiov->niov);
 | 
					    qemu_iovec_init(&local_qiov, qiov->niov);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    while (bytes > 0) {
 | 
					    while (bytes > 0) {
 | 
				
			||||||
        image_offset = get_image_offset(bs, offset, true);
 | 
					        image_offset = get_image_offset(bs, offset, true, &ret);
 | 
				
			||||||
 | 
					        if (image_offset == -2) {
 | 
				
			||||||
 | 
					            /* Failed to write block bitmap: can't proceed with write */
 | 
				
			||||||
 | 
					            goto fail;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        n_bytes = MIN(bytes, s->block_size - (offset % s->block_size));
 | 
					        n_bytes = MIN(bytes, s->block_size - (offset % s->block_size));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (image_offset == -1) {
 | 
					        if (image_offset == -1) {
 | 
				
			||||||
@ -702,7 +717,7 @@ static int64_t coroutine_fn vpc_co_get_block_status(BlockDriverState *bs,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    qemu_co_mutex_lock(&s->lock);
 | 
					    qemu_co_mutex_lock(&s->lock);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    offset = get_image_offset(bs, sector_num << BDRV_SECTOR_BITS, false);
 | 
					    offset = get_image_offset(bs, sector_num << BDRV_SECTOR_BITS, false, NULL);
 | 
				
			||||||
    start = offset;
 | 
					    start = offset;
 | 
				
			||||||
    allocated = (offset != -1);
 | 
					    allocated = (offset != -1);
 | 
				
			||||||
    *pnum = 0;
 | 
					    *pnum = 0;
 | 
				
			||||||
@ -727,7 +742,8 @@ static int64_t coroutine_fn vpc_co_get_block_status(BlockDriverState *bs,
 | 
				
			|||||||
        if (nb_sectors == 0) {
 | 
					        if (nb_sectors == 0) {
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        offset = get_image_offset(bs, sector_num << BDRV_SECTOR_BITS, false);
 | 
					        offset = get_image_offset(bs, sector_num << BDRV_SECTOR_BITS, false,
 | 
				
			||||||
 | 
					                                  NULL);
 | 
				
			||||||
    } while (offset == -1);
 | 
					    } while (offset == -1);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    qemu_co_mutex_unlock(&s->lock);
 | 
					    qemu_co_mutex_unlock(&s->lock);
 | 
				
			||||||
 | 
				
			|||||||
@ -71,6 +71,17 @@ void nonono(const char* file, int line, const char* msg) {
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
#endif
 | 
					#endif
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					/* bootsector OEM name. see related compatibility problems at:
 | 
				
			||||||
 | 
					 * https://jdebp.eu/FGA/volume-boot-block-oem-name-field.html
 | 
				
			||||||
 | 
					 * http://seasip.info/Misc/oemid.html
 | 
				
			||||||
 | 
					 */
 | 
				
			||||||
 | 
					#define BOOTSECTOR_OEM_NAME "MSWIN4.1"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#define DIR_DELETED 0xe5
 | 
				
			||||||
 | 
					#define DIR_KANJI DIR_DELETED
 | 
				
			||||||
 | 
					#define DIR_KANJI_FAKE 0x05
 | 
				
			||||||
 | 
					#define DIR_FREE 0x00
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* dynamic array functions */
 | 
					/* dynamic array functions */
 | 
				
			||||||
typedef struct array_t {
 | 
					typedef struct array_t {
 | 
				
			||||||
    char* pointer;
 | 
					    char* pointer;
 | 
				
			||||||
@ -104,6 +115,7 @@ static inline int array_ensure_allocated(array_t* array, int index)
 | 
				
			|||||||
        array->pointer = g_realloc(array->pointer, new_size);
 | 
					        array->pointer = g_realloc(array->pointer, new_size);
 | 
				
			||||||
        if (!array->pointer)
 | 
					        if (!array->pointer)
 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
 | 
					        memset(array->pointer + array->size, 0, new_size - array->size);
 | 
				
			||||||
        array->size = new_size;
 | 
					        array->size = new_size;
 | 
				
			||||||
        array->next = index + 1;
 | 
					        array->next = index + 1;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -466,7 +478,7 @@ static direntry_t *create_long_filename(BDRVVVFATState *s, const char *filename)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static char is_free(const direntry_t* direntry)
 | 
					static char is_free(const direntry_t* direntry)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return direntry->name[0]==0xe5 || direntry->name[0]==0x00;
 | 
					    return direntry->name[0] == DIR_DELETED || direntry->name[0] == DIR_FREE;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static char is_volume_label(const direntry_t* direntry)
 | 
					static char is_volume_label(const direntry_t* direntry)
 | 
				
			||||||
@ -487,7 +499,7 @@ static char is_short_name(const direntry_t* direntry)
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
static char is_directory(const direntry_t* direntry)
 | 
					static char is_directory(const direntry_t* direntry)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    return direntry->attributes & 0x10 && direntry->name[0] != 0xe5;
 | 
					    return direntry->attributes & 0x10 && direntry->name[0] != DIR_DELETED;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
static inline char is_dot(const direntry_t* direntry)
 | 
					static inline char is_dot(const direntry_t* direntry)
 | 
				
			||||||
@ -537,7 +549,7 @@ static direntry_t *create_short_filename(BDRVVVFATState *s,
 | 
				
			|||||||
    const gchar *p, *last_dot = NULL;
 | 
					    const gchar *p, *last_dot = NULL;
 | 
				
			||||||
    gunichar c;
 | 
					    gunichar c;
 | 
				
			||||||
    bool lossy_conversion = false;
 | 
					    bool lossy_conversion = false;
 | 
				
			||||||
    char tail[11];
 | 
					    char tail[8];
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!entry) {
 | 
					    if (!entry) {
 | 
				
			||||||
        return NULL;
 | 
					        return NULL;
 | 
				
			||||||
@ -589,8 +601,8 @@ static direntry_t *create_short_filename(BDRVVVFATState *s,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (entry->name[0] == 0xe5) {
 | 
					    if (entry->name[0] == DIR_KANJI) {
 | 
				
			||||||
        entry->name[0] = 0x05;
 | 
					        entry->name[0] = DIR_KANJI_FAKE;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* numeric-tail generation */
 | 
					    /* numeric-tail generation */
 | 
				
			||||||
@ -602,7 +614,8 @@ static direntry_t *create_short_filename(BDRVVVFATState *s,
 | 
				
			|||||||
    for (i = lossy_conversion ? 1 : 0; i < 999999; i++) {
 | 
					    for (i = lossy_conversion ? 1 : 0; i < 999999; i++) {
 | 
				
			||||||
        direntry_t *entry1;
 | 
					        direntry_t *entry1;
 | 
				
			||||||
        if (i > 0) {
 | 
					        if (i > 0) {
 | 
				
			||||||
            int len = sprintf(tail, "~%d", i);
 | 
					            int len = snprintf(tail, sizeof(tail), "~%u", (unsigned)i);
 | 
				
			||||||
 | 
					            assert(len <= 7);
 | 
				
			||||||
            memcpy(entry->name + MIN(j, 8 - len), tail, len);
 | 
					            memcpy(entry->name + MIN(j, 8 - len), tail, len);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        for (entry1 = array_get(&(s->directory), directory_start);
 | 
					        for (entry1 = array_get(&(s->directory), directory_start);
 | 
				
			||||||
@ -1023,7 +1036,7 @@ static int init_directories(BDRVVVFATState* s,
 | 
				
			|||||||
    bootsector->jump[0]=0xeb;
 | 
					    bootsector->jump[0]=0xeb;
 | 
				
			||||||
    bootsector->jump[1]=0x3e;
 | 
					    bootsector->jump[1]=0x3e;
 | 
				
			||||||
    bootsector->jump[2]=0x90;
 | 
					    bootsector->jump[2]=0x90;
 | 
				
			||||||
    memcpy(bootsector->name, "MSWIN4.1", 8);
 | 
					    memcpy(bootsector->name, BOOTSECTOR_OEM_NAME, 8);
 | 
				
			||||||
    bootsector->sector_size=cpu_to_le16(0x200);
 | 
					    bootsector->sector_size=cpu_to_le16(0x200);
 | 
				
			||||||
    bootsector->sectors_per_cluster=s->sectors_per_cluster;
 | 
					    bootsector->sectors_per_cluster=s->sectors_per_cluster;
 | 
				
			||||||
    bootsector->reserved_sectors=cpu_to_le16(1);
 | 
					    bootsector->reserved_sectors=cpu_to_le16(1);
 | 
				
			||||||
@ -1658,6 +1671,7 @@ typedef struct {
 | 
				
			|||||||
     * filename length is 0x3f * 13 bytes.
 | 
					     * filename length is 0x3f * 13 bytes.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    unsigned char name[0x3f * 13 + 1];
 | 
					    unsigned char name[0x3f * 13 + 1];
 | 
				
			||||||
 | 
					    gunichar2 name2[0x3f * 13 + 1];
 | 
				
			||||||
    int checksum, len;
 | 
					    int checksum, len;
 | 
				
			||||||
    int sequence_number;
 | 
					    int sequence_number;
 | 
				
			||||||
} long_file_name;
 | 
					} long_file_name;
 | 
				
			||||||
@ -1679,16 +1693,21 @@ static int parse_long_name(long_file_name* lfn,
 | 
				
			|||||||
        return 1;
 | 
					        return 1;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pointer[0] & 0x40) {
 | 
					    if (pointer[0] & 0x40) {
 | 
				
			||||||
 | 
					        /* first entry; do some initialization */
 | 
				
			||||||
        lfn->sequence_number = pointer[0] & 0x3f;
 | 
					        lfn->sequence_number = pointer[0] & 0x3f;
 | 
				
			||||||
        lfn->checksum = pointer[13];
 | 
					        lfn->checksum = pointer[13];
 | 
				
			||||||
        lfn->name[0] = 0;
 | 
					        lfn->name[0] = 0;
 | 
				
			||||||
        lfn->name[lfn->sequence_number * 13] = 0;
 | 
					        lfn->name[lfn->sequence_number * 13] = 0;
 | 
				
			||||||
    } else if ((pointer[0] & 0x3f) != --lfn->sequence_number)
 | 
					    } else if ((pointer[0] & 0x3f) != --lfn->sequence_number) {
 | 
				
			||||||
 | 
					        /* not the expected sequence number */
 | 
				
			||||||
        return -1;
 | 
					        return -1;
 | 
				
			||||||
    else if (pointer[13] != lfn->checksum)
 | 
					    } else if (pointer[13] != lfn->checksum) {
 | 
				
			||||||
 | 
					        /* not the expected checksum */
 | 
				
			||||||
        return -2;
 | 
					        return -2;
 | 
				
			||||||
    else if (pointer[12] || pointer[26] || pointer[27])
 | 
					    } else if (pointer[12] || pointer[26] || pointer[27]) {
 | 
				
			||||||
 | 
					        /* invalid zero fields */
 | 
				
			||||||
        return -3;
 | 
					        return -3;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    offset = 13 * (lfn->sequence_number - 1);
 | 
					    offset = 13 * (lfn->sequence_number - 1);
 | 
				
			||||||
    for (i = 0, j = 1; i < 13; i++, j+=2) {
 | 
					    for (i = 0, j = 1; i < 13; i++, j+=2) {
 | 
				
			||||||
@ -1697,16 +1716,29 @@ static int parse_long_name(long_file_name* lfn,
 | 
				
			|||||||
        else if (j == 26)
 | 
					        else if (j == 26)
 | 
				
			||||||
            j = 28;
 | 
					            j = 28;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (pointer[j+1] == 0)
 | 
					        if (pointer[j] == 0 && pointer[j + 1] == 0) {
 | 
				
			||||||
            lfn->name[offset + i] = pointer[j];
 | 
					            /* end of long file name */
 | 
				
			||||||
        else if (pointer[j+1] != 0xff || (pointer[0] & 0x40) == 0)
 | 
					            break;
 | 
				
			||||||
            return -4;
 | 
					        }
 | 
				
			||||||
        else
 | 
					        gunichar2 c = (pointer[j + 1] << 8) + pointer[j];
 | 
				
			||||||
            lfn->name[offset + i] = 0;
 | 
					        lfn->name2[offset + i] = c;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (pointer[0] & 0x40)
 | 
					    if (pointer[0] & 0x40) {
 | 
				
			||||||
        lfn->len = offset + strlen((char*)lfn->name + offset);
 | 
					        /* first entry; set len */
 | 
				
			||||||
 | 
					        lfn->len = offset + i;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    if ((pointer[0] & 0x3f) == 0x01) {
 | 
				
			||||||
 | 
					        /* last entry; finalize entry */
 | 
				
			||||||
 | 
					        glong olen;
 | 
				
			||||||
 | 
					        gchar *utf8 = g_utf16_to_utf8(lfn->name2, lfn->len, NULL, &olen, NULL);
 | 
				
			||||||
 | 
					        if (!utf8) {
 | 
				
			||||||
 | 
					            return -4;
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        lfn->len = olen;
 | 
				
			||||||
 | 
					        memcpy(lfn->name, utf8, olen + 1);
 | 
				
			||||||
 | 
					        g_free(utf8);
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    return 0;
 | 
					    return 0;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
@ -1722,13 +1754,15 @@ static int parse_short_name(BDRVVVFATState* s,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
 | 
					    for (j = 7; j >= 0 && direntry->name[j] == ' '; j--);
 | 
				
			||||||
    for (i = 0; i <= j; i++) {
 | 
					    for (i = 0; i <= j; i++) {
 | 
				
			||||||
        if (direntry->name[i] <= ' ' || direntry->name[i] > 0x7f)
 | 
					        uint8_t c = direntry->name[i];
 | 
				
			||||||
 | 
					        if (c != to_valid_short_char(c)) {
 | 
				
			||||||
            return -1;
 | 
					            return -1;
 | 
				
			||||||
        else if (s->downcase_short_names)
 | 
					        } else if (s->downcase_short_names) {
 | 
				
			||||||
            lfn->name[i] = qemu_tolower(direntry->name[i]);
 | 
					            lfn->name[i] = qemu_tolower(direntry->name[i]);
 | 
				
			||||||
        else
 | 
					        } else {
 | 
				
			||||||
            lfn->name[i] = direntry->name[i];
 | 
					            lfn->name[i] = direntry->name[i];
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for (j = 2; j >= 0 && direntry->name[8 + j] == ' '; j--) {
 | 
					    for (j = 2; j >= 0 && direntry->name[8 + j] == ' '; j--) {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -1737,7 +1771,7 @@ static int parse_short_name(BDRVVVFATState* s,
 | 
				
			|||||||
        lfn->name[i + j + 1] = '\0';
 | 
					        lfn->name[i + j + 1] = '\0';
 | 
				
			||||||
        for (;j >= 0; j--) {
 | 
					        for (;j >= 0; j--) {
 | 
				
			||||||
            uint8_t c = direntry->name[8 + j];
 | 
					            uint8_t c = direntry->name[8 + j];
 | 
				
			||||||
            if (c <= ' ' || c > 0x7f) {
 | 
					            if (c != to_valid_short_char(c)) {
 | 
				
			||||||
                return -2;
 | 
					                return -2;
 | 
				
			||||||
            } else if (s->downcase_short_names) {
 | 
					            } else if (s->downcase_short_names) {
 | 
				
			||||||
                lfn->name[i + j] = qemu_tolower(c);
 | 
					                lfn->name[i + j] = qemu_tolower(c);
 | 
				
			||||||
@ -1748,8 +1782,8 @@ static int parse_short_name(BDRVVVFATState* s,
 | 
				
			|||||||
    } else
 | 
					    } else
 | 
				
			||||||
        lfn->name[i + j + 1] = '\0';
 | 
					        lfn->name[i + j + 1] = '\0';
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (lfn->name[0] == 0x05) {
 | 
					    if (lfn->name[0] == DIR_KANJI_FAKE) {
 | 
				
			||||||
        lfn->name[0] = 0xe5;
 | 
					        lfn->name[0] = DIR_KANJI;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
    lfn->len = strlen((char*)lfn->name);
 | 
					    lfn->len = strlen((char*)lfn->name);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -2955,7 +2989,6 @@ DLOG(checkpoint());
 | 
				
			|||||||
    /*
 | 
					    /*
 | 
				
			||||||
     * Some sanity checks:
 | 
					     * Some sanity checks:
 | 
				
			||||||
     * - do not allow writing to the boot sector
 | 
					     * - do not allow writing to the boot sector
 | 
				
			||||||
     * - do not allow to write non-ASCII filenames
 | 
					 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (sector_num < s->offset_to_fat)
 | 
					    if (sector_num < s->offset_to_fat)
 | 
				
			||||||
@ -2989,13 +3022,8 @@ DLOG(checkpoint());
 | 
				
			|||||||
                direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
 | 
					                direntries = (direntry_t*)(buf + 0x200 * (begin - sector_num));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                for (k = 0; k < (end - begin) * 0x10; k++) {
 | 
					                for (k = 0; k < (end - begin) * 0x10; k++) {
 | 
				
			||||||
                    /* do not allow non-ASCII filenames */
 | 
					 | 
				
			||||||
                    if (parse_long_name(&lfn, direntries + k) < 0) {
 | 
					 | 
				
			||||||
                        fprintf(stderr, "Warning: non-ASCII filename\n");
 | 
					 | 
				
			||||||
                        return -1;
 | 
					 | 
				
			||||||
                    }
 | 
					 | 
				
			||||||
                    /* no access to the direntry of a read-only file */
 | 
					                    /* no access to the direntry of a read-only file */
 | 
				
			||||||
                    else if (is_short_name(direntries+k) &&
 | 
					                    if (is_short_name(direntries + k) &&
 | 
				
			||||||
                            (direntries[k].attributes & 1)) {
 | 
					                            (direntries[k].attributes & 1)) {
 | 
				
			||||||
                        if (memcmp(direntries + k,
 | 
					                        if (memcmp(direntries + k,
 | 
				
			||||||
                                    array_get(&(s->directory), dir_index + k),
 | 
					                                    array_get(&(s->directory), dir_index + k),
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								blockdev.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								blockdev.c
									
									
									
									
									
								
							@ -1710,7 +1710,8 @@ static void external_snapshot_prepare(BlkActionState *common,
 | 
				
			|||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        flags = state->old_bs->open_flags;
 | 
					        flags = state->old_bs->open_flags;
 | 
				
			||||||
        flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_NO_BACKING | BDRV_O_COPY_ON_READ);
 | 
					        flags &= ~(BDRV_O_SNAPSHOT | BDRV_O_COPY_ON_READ);
 | 
				
			||||||
 | 
					        flags |= BDRV_O_NO_BACKING;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        /* create new image w/backing file */
 | 
					        /* create new image w/backing file */
 | 
				
			||||||
        mode = s->has_mode ? s->mode : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
 | 
					        mode = s->has_mode ? s->mode : NEW_IMAGE_MODE_ABSOLUTE_PATHS;
 | 
				
			||||||
@ -1735,8 +1736,6 @@ static void external_snapshot_prepare(BlkActionState *common,
 | 
				
			|||||||
            qdict_put_str(options, "node-name", snapshot_node_name);
 | 
					            qdict_put_str(options, "node-name", snapshot_node_name);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        qdict_put_str(options, "driver", format);
 | 
					        qdict_put_str(options, "driver", format);
 | 
				
			||||||
 | 
					 | 
				
			||||||
        flags |= BDRV_O_NO_BACKING;
 | 
					 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    state->new_bs = bdrv_open(new_image_file, snapshot_ref, options, flags,
 | 
					    state->new_bs = bdrv_open(new_image_file, snapshot_ref, options, flags,
 | 
				
			||||||
@ -3548,6 +3547,9 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
 | 
				
			|||||||
        backing_mode = MIRROR_OPEN_BACKING_CHAIN;
 | 
					        backing_mode = MIRROR_OPEN_BACKING_CHAIN;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    /* Don't open backing image in create() */
 | 
				
			||||||
 | 
					    flags |= BDRV_O_NO_BACKING;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if ((arg->sync == MIRROR_SYNC_MODE_FULL || !source)
 | 
					    if ((arg->sync == MIRROR_SYNC_MODE_FULL || !source)
 | 
				
			||||||
        && arg->mode != NEW_IMAGE_MODE_EXISTING)
 | 
					        && arg->mode != NEW_IMAGE_MODE_EXISTING)
 | 
				
			||||||
    {
 | 
					    {
 | 
				
			||||||
@ -3587,8 +3589,7 @@ void qmp_drive_mirror(DriveMirror *arg, Error **errp)
 | 
				
			|||||||
    /* Mirroring takes care of copy-on-write using the source's backing
 | 
					    /* Mirroring takes care of copy-on-write using the source's backing
 | 
				
			||||||
     * file.
 | 
					     * file.
 | 
				
			||||||
     */
 | 
					     */
 | 
				
			||||||
    target_bs = bdrv_open(arg->target, NULL, options,
 | 
					    target_bs = bdrv_open(arg->target, NULL, options, flags, errp);
 | 
				
			||||||
                          flags | BDRV_O_NO_BACKING, errp);
 | 
					 | 
				
			||||||
    if (!target_bs) {
 | 
					    if (!target_bs) {
 | 
				
			||||||
        goto out;
 | 
					        goto out;
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
@ -86,7 +86,7 @@ void fsdev_throttle_init(FsThrottle *fst)
 | 
				
			|||||||
                             fsdev_throttle_read_timer_cb,
 | 
					                             fsdev_throttle_read_timer_cb,
 | 
				
			||||||
                             fsdev_throttle_write_timer_cb,
 | 
					                             fsdev_throttle_write_timer_cb,
 | 
				
			||||||
                             fst);
 | 
					                             fst);
 | 
				
			||||||
        throttle_config(&fst->ts, &fst->tt, &fst->cfg);
 | 
					        throttle_config(&fst->ts, QEMU_CLOCK_REALTIME, &fst->cfg);
 | 
				
			||||||
        qemu_co_queue_init(&fst->throttled_reqs[0]);
 | 
					        qemu_co_queue_init(&fst->throttled_reqs[0]);
 | 
				
			||||||
        qemu_co_queue_init(&fst->throttled_reqs[1]);
 | 
					        qemu_co_queue_init(&fst->throttled_reqs[1]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										11
									
								
								hmp.c
									
									
									
									
									
								
							
							
						
						
									
										11
									
								
								hmp.c
									
									
									
									
									
								
							@ -401,16 +401,16 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
    assert(!info || !info->has_inserted || info->inserted == inserted);
 | 
					    assert(!info || !info->has_inserted || info->inserted == inserted);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (info) {
 | 
					    if (info && *info->device) {
 | 
				
			||||||
        monitor_printf(mon, "%s", info->device);
 | 
					        monitor_printf(mon, "%s", info->device);
 | 
				
			||||||
        if (inserted && inserted->has_node_name) {
 | 
					        if (inserted && inserted->has_node_name) {
 | 
				
			||||||
            monitor_printf(mon, " (%s)", inserted->node_name);
 | 
					            monitor_printf(mon, " (%s)", inserted->node_name);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    } else {
 | 
					    } else {
 | 
				
			||||||
        assert(inserted);
 | 
					        assert(info || inserted);
 | 
				
			||||||
        monitor_printf(mon, "%s",
 | 
					        monitor_printf(mon, "%s",
 | 
				
			||||||
                       inserted->has_node_name
 | 
					                       inserted && inserted->has_node_name ? inserted->node_name
 | 
				
			||||||
                       ? inserted->node_name
 | 
					                       : info && info->has_qdev ? info->qdev
 | 
				
			||||||
                       : "<anonymous>");
 | 
					                       : "<anonymous>");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -425,6 +425,9 @@ static void print_block_info(Monitor *mon, BlockInfo *info,
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (info) {
 | 
					    if (info) {
 | 
				
			||||||
 | 
					        if (info->has_qdev) {
 | 
				
			||||||
 | 
					            monitor_printf(mon, "    Attached to:      %s\n", info->qdev);
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
        if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
 | 
					        if (info->has_io_status && info->io_status != BLOCK_DEVICE_IO_STATUS_OK) {
 | 
				
			||||||
            monitor_printf(mon, "    I/O status:       %s\n",
 | 
					            monitor_printf(mon, "    I/O status:       %s\n",
 | 
				
			||||||
                           BlockDeviceIoStatus_lookup[info->io_status]);
 | 
					                           BlockDeviceIoStatus_lookup[info->io_status]);
 | 
				
			||||||
 | 
				
			|||||||
@ -164,6 +164,7 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
 | 
				
			|||||||
    IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
 | 
					    IDEBus *bus = DO_UPCAST(IDEBus, qbus, dev->qdev.parent_bus);
 | 
				
			||||||
    IDEState *s = bus->ifs + dev->unit;
 | 
					    IDEState *s = bus->ifs + dev->unit;
 | 
				
			||||||
    Error *err = NULL;
 | 
					    Error *err = NULL;
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!dev->conf.blk) {
 | 
					    if (!dev->conf.blk) {
 | 
				
			||||||
        if (kind != IDE_CD) {
 | 
					        if (kind != IDE_CD) {
 | 
				
			||||||
@ -172,6 +173,8 @@ static int ide_dev_initfn(IDEDevice *dev, IDEDriveKind kind)
 | 
				
			|||||||
        } else {
 | 
					        } else {
 | 
				
			||||||
            /* Anonymous BlockBackend for an empty drive */
 | 
					            /* Anonymous BlockBackend for an empty drive */
 | 
				
			||||||
            dev->conf.blk = blk_new(0, BLK_PERM_ALL);
 | 
					            dev->conf.blk = blk_new(0, BLK_PERM_ALL);
 | 
				
			||||||
 | 
					            ret = blk_attach_dev(dev->conf.blk, &dev->qdev);
 | 
				
			||||||
 | 
					            assert(ret == 0);
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -2384,9 +2384,14 @@ static void scsi_hd_realize(SCSIDevice *dev, Error **errp)
 | 
				
			|||||||
static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
 | 
					static void scsi_cd_realize(SCSIDevice *dev, Error **errp)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
 | 
					    SCSIDiskState *s = DO_UPCAST(SCSIDiskState, qdev, dev);
 | 
				
			||||||
 | 
					    int ret;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    if (!dev->conf.blk) {
 | 
					    if (!dev->conf.blk) {
 | 
				
			||||||
 | 
					        /* Anonymous BlockBackend for an empty drive. As we put it into
 | 
				
			||||||
 | 
					         * dev->conf, qdev takes care of detaching on unplug. */
 | 
				
			||||||
        dev->conf.blk = blk_new(0, BLK_PERM_ALL);
 | 
					        dev->conf.blk = blk_new(0, BLK_PERM_ALL);
 | 
				
			||||||
 | 
					        ret = blk_attach_dev(dev->conf.blk, &dev->qdev);
 | 
				
			||||||
 | 
					        assert(ret == 0);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    s->qdev.blocksize = 2048;
 | 
					    s->qdev.blocksize = 2048;
 | 
				
			||||||
 | 
				
			|||||||
@ -139,7 +139,7 @@ bool throttle_enabled(ThrottleConfig *cfg);
 | 
				
			|||||||
bool throttle_is_valid(ThrottleConfig *cfg, Error **errp);
 | 
					bool throttle_is_valid(ThrottleConfig *cfg, Error **errp);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void throttle_config(ThrottleState *ts,
 | 
					void throttle_config(ThrottleState *ts,
 | 
				
			||||||
                     ThrottleTimers *tt,
 | 
					                     QEMUClockType clock_type,
 | 
				
			||||||
                     ThrottleConfig *cfg);
 | 
					                     ThrottleConfig *cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
void throttle_get_config(ThrottleState *ts, ThrottleConfig *cfg);
 | 
					void throttle_get_config(ThrottleState *ts, ThrottleConfig *cfg);
 | 
				
			||||||
 | 
				
			|||||||
@ -100,6 +100,7 @@ void blk_remove_all_bs(void);
 | 
				
			|||||||
const char *blk_name(const BlockBackend *blk);
 | 
					const char *blk_name(const BlockBackend *blk);
 | 
				
			||||||
BlockBackend *blk_by_name(const char *name);
 | 
					BlockBackend *blk_by_name(const char *name);
 | 
				
			||||||
BlockBackend *blk_next(BlockBackend *blk);
 | 
					BlockBackend *blk_next(BlockBackend *blk);
 | 
				
			||||||
 | 
					BlockBackend *blk_all_next(BlockBackend *blk);
 | 
				
			||||||
bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp);
 | 
					bool monitor_add_blk(BlockBackend *blk, const char *name, Error **errp);
 | 
				
			||||||
void monitor_remove_blk(BlockBackend *blk);
 | 
					void monitor_remove_blk(BlockBackend *blk);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -126,6 +127,7 @@ int blk_attach_dev(BlockBackend *blk, DeviceState *dev);
 | 
				
			|||||||
void blk_attach_dev_legacy(BlockBackend *blk, void *dev);
 | 
					void blk_attach_dev_legacy(BlockBackend *blk, void *dev);
 | 
				
			||||||
void blk_detach_dev(BlockBackend *blk, void *dev);
 | 
					void blk_detach_dev(BlockBackend *blk, void *dev);
 | 
				
			||||||
void *blk_get_attached_dev(BlockBackend *blk);
 | 
					void *blk_get_attached_dev(BlockBackend *blk);
 | 
				
			||||||
 | 
					char *blk_get_attached_dev_id(BlockBackend *blk);
 | 
				
			||||||
BlockBackend *blk_by_dev(void *dev);
 | 
					BlockBackend *blk_by_dev(void *dev);
 | 
				
			||||||
BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
 | 
					BlockBackend *blk_by_qdev_id(const char *id, Error **errp);
 | 
				
			||||||
void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
 | 
					void blk_set_dev_ops(BlockBackend *blk, const BlockDevOps *ops, void *opaque);
 | 
				
			||||||
 | 
				
			|||||||
@ -457,6 +457,9 @@
 | 
				
			|||||||
#
 | 
					#
 | 
				
			||||||
# @device: The device name associated with the virtual device.
 | 
					# @device: The device name associated with the virtual device.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					# @qdev: The qdev ID, or if no ID is assigned, the QOM path of the block
 | 
				
			||||||
 | 
					#        device. (since 2.10)
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
# @type: This field is returned only for compatibility reasons, it should
 | 
					# @type: This field is returned only for compatibility reasons, it should
 | 
				
			||||||
#        not be used (always returns 'unknown')
 | 
					#        not be used (always returns 'unknown')
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
@ -482,7 +485,7 @@
 | 
				
			|||||||
# Since:  0.14.0
 | 
					# Since:  0.14.0
 | 
				
			||||||
##
 | 
					##
 | 
				
			||||||
{ 'struct': 'BlockInfo',
 | 
					{ 'struct': 'BlockInfo',
 | 
				
			||||||
  'data': {'device': 'str', 'type': 'str', 'removable': 'bool',
 | 
					  'data': {'device': 'str', '*qdev': 'str', 'type': 'str', 'removable': 'bool',
 | 
				
			||||||
           'locked': 'bool', '*inserted': 'BlockDeviceInfo',
 | 
					           'locked': 'bool', '*inserted': 'BlockDeviceInfo',
 | 
				
			||||||
           '*tray_open': 'bool', '*io-status': 'BlockDeviceIoStatus',
 | 
					           '*tray_open': 'bool', '*io-status': 'BlockDeviceIoStatus',
 | 
				
			||||||
           '*dirty-bitmaps': ['BlockDirtyInfo'] } }
 | 
					           '*dirty-bitmaps': ['BlockDirtyInfo'] } }
 | 
				
			||||||
@ -577,6 +580,7 @@
 | 
				
			|||||||
#                   }
 | 
					#                   }
 | 
				
			||||||
#                }
 | 
					#                }
 | 
				
			||||||
#             },
 | 
					#             },
 | 
				
			||||||
 | 
					#             "qdev": "ide_disk",
 | 
				
			||||||
#             "type":"unknown"
 | 
					#             "type":"unknown"
 | 
				
			||||||
#          },
 | 
					#          },
 | 
				
			||||||
#          {
 | 
					#          {
 | 
				
			||||||
@ -584,12 +588,15 @@
 | 
				
			|||||||
#             "device":"ide1-cd0",
 | 
					#             "device":"ide1-cd0",
 | 
				
			||||||
#             "locked":false,
 | 
					#             "locked":false,
 | 
				
			||||||
#             "removable":true,
 | 
					#             "removable":true,
 | 
				
			||||||
 | 
					#             "qdev": "/machine/unattached/device[23]",
 | 
				
			||||||
 | 
					#             "tray_open": false,
 | 
				
			||||||
#             "type":"unknown"
 | 
					#             "type":"unknown"
 | 
				
			||||||
#          },
 | 
					#          },
 | 
				
			||||||
#          {
 | 
					#          {
 | 
				
			||||||
#             "device":"floppy0",
 | 
					#             "device":"floppy0",
 | 
				
			||||||
#             "locked":false,
 | 
					#             "locked":false,
 | 
				
			||||||
#             "removable":true,
 | 
					#             "removable":true,
 | 
				
			||||||
 | 
					#             "qdev": "/machine/unattached/device[20]",
 | 
				
			||||||
#             "type":"unknown"
 | 
					#             "type":"unknown"
 | 
				
			||||||
#          },
 | 
					#          },
 | 
				
			||||||
#          {
 | 
					#          {
 | 
				
			||||||
 | 
				
			|||||||
@ -22,9 +22,9 @@ STEXI
 | 
				
			|||||||
ETEXI
 | 
					ETEXI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF("create", img_create,
 | 
					DEF("create", img_create,
 | 
				
			||||||
    "create [-q] [--object objectdef] [-f fmt] [-b backing_file] [-F backing_fmt] [-o options] filename [size]")
 | 
					    "create [-q] [--object objectdef] [-f fmt] [-b backing_file] [-F backing_fmt] [-u] [-o options] filename [size]")
 | 
				
			||||||
STEXI
 | 
					STEXI
 | 
				
			||||||
@item create [--object @var{objectdef}] [-q] [-f @var{fmt}] [-b @var{backing_file}] [-F @var{backing_fmt}] [-o @var{options}] @var{filename} [@var{size}]
 | 
					@item create [--object @var{objectdef}] [-q] [-f @var{fmt}] [-b @var{backing_file}] [-F @var{backing_fmt}] [-u] [-o @var{options}] @var{filename} [@var{size}]
 | 
				
			||||||
ETEXI
 | 
					ETEXI
 | 
				
			||||||
 | 
					
 | 
				
			||||||
DEF("commit", img_commit,
 | 
					DEF("commit", img_commit,
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										16
									
								
								qemu-img.c
									
									
									
									
									
								
							
							
						
						
									
										16
									
								
								qemu-img.c
									
									
									
									
									
								
							@ -150,9 +150,11 @@ static void QEMU_NORETURN help(void)
 | 
				
			|||||||
           "  'snapshot_id_or_name' is deprecated, use 'snapshot_param'\n"
 | 
					           "  'snapshot_id_or_name' is deprecated, use 'snapshot_param'\n"
 | 
				
			||||||
           "    instead\n"
 | 
					           "    instead\n"
 | 
				
			||||||
           "  '-c' indicates that target image must be compressed (qcow format only)\n"
 | 
					           "  '-c' indicates that target image must be compressed (qcow format only)\n"
 | 
				
			||||||
           "  '-u' enables unsafe rebasing. It is assumed that old and new backing file\n"
 | 
					           "  '-u' allows unsafe backing chains. For rebasing, it is assumed that old and\n"
 | 
				
			||||||
           "       match exactly. The image doesn't need a working backing file before\n"
 | 
					           "       new backing file match exactly. The image doesn't need a working\n"
 | 
				
			||||||
           "       rebasing in this case (useful for renaming the backing file)\n"
 | 
					           "       backing file before rebasing in this case (useful for renaming the\n"
 | 
				
			||||||
 | 
					           "       backing file). For image creation, allow creating without attempting\n"
 | 
				
			||||||
 | 
					           "       to open the backing file.\n"
 | 
				
			||||||
           "  '-h' with or without a command shows this help and lists the supported formats\n"
 | 
					           "  '-h' with or without a command shows this help and lists the supported formats\n"
 | 
				
			||||||
           "  '-p' show progress of command (only certain commands)\n"
 | 
					           "  '-p' show progress of command (only certain commands)\n"
 | 
				
			||||||
           "  '-q' use Quiet mode - do not print any output (except errors)\n"
 | 
					           "  '-q' use Quiet mode - do not print any output (except errors)\n"
 | 
				
			||||||
@ -429,6 +431,7 @@ static int img_create(int argc, char **argv)
 | 
				
			|||||||
    char *options = NULL;
 | 
					    char *options = NULL;
 | 
				
			||||||
    Error *local_err = NULL;
 | 
					    Error *local_err = NULL;
 | 
				
			||||||
    bool quiet = false;
 | 
					    bool quiet = false;
 | 
				
			||||||
 | 
					    int flags = 0;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    for(;;) {
 | 
					    for(;;) {
 | 
				
			||||||
        static const struct option long_options[] = {
 | 
					        static const struct option long_options[] = {
 | 
				
			||||||
@ -436,7 +439,7 @@ static int img_create(int argc, char **argv)
 | 
				
			|||||||
            {"object", required_argument, 0, OPTION_OBJECT},
 | 
					            {"object", required_argument, 0, OPTION_OBJECT},
 | 
				
			||||||
            {0, 0, 0, 0}
 | 
					            {0, 0, 0, 0}
 | 
				
			||||||
        };
 | 
					        };
 | 
				
			||||||
        c = getopt_long(argc, argv, ":F:b:f:ho:q",
 | 
					        c = getopt_long(argc, argv, ":F:b:f:ho:qu",
 | 
				
			||||||
                        long_options, NULL);
 | 
					                        long_options, NULL);
 | 
				
			||||||
        if (c == -1) {
 | 
					        if (c == -1) {
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
@ -476,6 +479,9 @@ static int img_create(int argc, char **argv)
 | 
				
			|||||||
        case 'q':
 | 
					        case 'q':
 | 
				
			||||||
            quiet = true;
 | 
					            quiet = true;
 | 
				
			||||||
            break;
 | 
					            break;
 | 
				
			||||||
 | 
					        case 'u':
 | 
				
			||||||
 | 
					            flags |= BDRV_O_NO_BACKING;
 | 
				
			||||||
 | 
					            break;
 | 
				
			||||||
        case OPTION_OBJECT: {
 | 
					        case OPTION_OBJECT: {
 | 
				
			||||||
            QemuOpts *opts;
 | 
					            QemuOpts *opts;
 | 
				
			||||||
            opts = qemu_opts_parse_noisily(&qemu_object_opts,
 | 
					            opts = qemu_opts_parse_noisily(&qemu_object_opts,
 | 
				
			||||||
@ -528,7 +534,7 @@ static int img_create(int argc, char **argv)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    bdrv_img_create(filename, fmt, base_filename, base_fmt,
 | 
					    bdrv_img_create(filename, fmt, base_filename, base_fmt,
 | 
				
			||||||
                    options, img_size, 0, quiet, &local_err);
 | 
					                    options, img_size, flags, quiet, &local_err);
 | 
				
			||||||
    if (local_err) {
 | 
					    if (local_err) {
 | 
				
			||||||
        error_reportf_err(local_err, "%s: ", filename);
 | 
					        error_reportf_err(local_err, "%s: ", filename);
 | 
				
			||||||
        goto fail;
 | 
					        goto fail;
 | 
				
			||||||
 | 
				
			|||||||
@ -233,7 +233,7 @@ If @code{-r} is specified, exit codes representing the image state refer to the
 | 
				
			|||||||
state after (the attempt at) repairing it. That is, a successful @code{-r all}
 | 
					state after (the attempt at) repairing it. That is, a successful @code{-r all}
 | 
				
			||||||
will yield the exit code 0, independently of the image state before.
 | 
					will yield the exit code 0, independently of the image state before.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@item create [-f @var{fmt}] [-b @var{backing_file}] [-F @var{backing_fmt}] [-o @var{options}] @var{filename} [@var{size}]
 | 
					@item create [-f @var{fmt}] [-b @var{backing_file}] [-F @var{backing_fmt}] [-u] [-o @var{options}] @var{filename} [@var{size}]
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Create the new disk image @var{filename} of size @var{size} and format
 | 
					Create the new disk image @var{filename} of size @var{size} and format
 | 
				
			||||||
@var{fmt}. Depending on the file format, you can add one or more @var{options}
 | 
					@var{fmt}. Depending on the file format, you can add one or more @var{options}
 | 
				
			||||||
@ -244,6 +244,13 @@ only the differences from @var{backing_file}. No size needs to be specified in
 | 
				
			|||||||
this case. @var{backing_file} will never be modified unless you use the
 | 
					this case. @var{backing_file} will never be modified unless you use the
 | 
				
			||||||
@code{commit} monitor command (or qemu-img commit).
 | 
					@code{commit} monitor command (or qemu-img commit).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Note that a given backing file will be opened to check that it is valid. Use
 | 
				
			||||||
 | 
					the @code{-u} option to enable unsafe backing file mode, which means that the
 | 
				
			||||||
 | 
					image will be created even if the associated backing file cannot be opened. A
 | 
				
			||||||
 | 
					matching backing file must be created or additional options be used to make the
 | 
				
			||||||
 | 
					backing file specification valid when you want to use an image created this
 | 
				
			||||||
 | 
					way.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
The size can also be specified using the @var{size} option with @code{-o},
 | 
					The size can also be specified using the @var{size} option with @code{-o},
 | 
				
			||||||
it doesn't need to be specified separately in this case.
 | 
					it doesn't need to be specified separately in this case.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -137,6 +137,19 @@ run_qemu <<EOF
 | 
				
			|||||||
{ "execute": "quit" }
 | 
					{ "execute": "quit" }
 | 
				
			||||||
EOF
 | 
					EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					echo === Empty drive with -device and device_del ===
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					run_qemu -device virtio-scsi-pci -device scsi-cd,id=cd0 <<EOF
 | 
				
			||||||
 | 
					{ "execute": "qmp_capabilities" }
 | 
				
			||||||
 | 
					{ "execute": "query-block" }
 | 
				
			||||||
 | 
					{ "execute": "device_del", "arguments": { "id": "cd0" } }
 | 
				
			||||||
 | 
					{ "execute": "system_reset" }
 | 
				
			||||||
 | 
					{ "execute": "query-block" }
 | 
				
			||||||
 | 
					{ "execute": "quit" }
 | 
				
			||||||
 | 
					EOF
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# success, all done
 | 
					# success, all done
 | 
				
			||||||
echo "*** done"
 | 
					echo "*** done"
 | 
				
			||||||
rm -f $seq.full
 | 
					rm -f $seq.full
 | 
				
			||||||
 | 
				
			|||||||
@ -57,6 +57,7 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti
 | 
				
			|||||||
                "file": "TEST_DIR/t.qcow2",
 | 
					                "file": "TEST_DIR/t.qcow2",
 | 
				
			||||||
                "encryption_key_missing": false
 | 
					                "encryption_key_missing": false
 | 
				
			||||||
            },
 | 
					            },
 | 
				
			||||||
 | 
					            "qdev": "/machine/peripheral/virtio0/virtio-backend",
 | 
				
			||||||
            "type": "unknown"
 | 
					            "type": "unknown"
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
    ]
 | 
					    ]
 | 
				
			||||||
@ -415,4 +416,43 @@ Testing:
 | 
				
			|||||||
    "return": {
 | 
					    "return": {
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Empty drive with -device and device_del ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -device virtio-scsi-pci -device scsi-cd,id=cd0
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    QMP_VERSION
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "return": {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "return": [
 | 
				
			||||||
 | 
					        {
 | 
				
			||||||
 | 
					            "device": "",
 | 
				
			||||||
 | 
					            "locked": false,
 | 
				
			||||||
 | 
					            "removable": true,
 | 
				
			||||||
 | 
					            "qdev": "cd0",
 | 
				
			||||||
 | 
					            "tray_open": false,
 | 
				
			||||||
 | 
					            "type": "unknown"
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "return": {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "return": {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "return": [
 | 
				
			||||||
 | 
					    ]
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    "return": {
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
*** done
 | 
					*** done
 | 
				
			||||||
 | 
				
			|||||||
@ -85,8 +85,8 @@ run_qemu_img create -f $IMGFMT -o cluster_size=4k -o help "$TEST_IMG" $size
 | 
				
			|||||||
run_qemu_img create -f $IMGFMT -o cluster_size=4k -o \? "$TEST_IMG" $size
 | 
					run_qemu_img create -f $IMGFMT -o cluster_size=4k -o \? "$TEST_IMG" $size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Looks like a help option, but is part of the backing file name
 | 
					# Looks like a help option, but is part of the backing file name
 | 
				
			||||||
run_qemu_img create -f $IMGFMT -o backing_file="$TEST_IMG",,help "$TEST_IMG" $size
 | 
					run_qemu_img create -f $IMGFMT -u -o backing_file="$TEST_IMG",,help "$TEST_IMG" $size
 | 
				
			||||||
run_qemu_img create -f $IMGFMT -o backing_file="$TEST_IMG",,\? "$TEST_IMG" $size
 | 
					run_qemu_img create -f $IMGFMT -u -o backing_file="$TEST_IMG",,\? "$TEST_IMG" $size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Try to trick qemu-img into creating escaped commas
 | 
					# Try to trick qemu-img into creating escaped commas
 | 
				
			||||||
run_qemu_img create -f $IMGFMT -o backing_file="$TEST_IMG", -o help "$TEST_IMG" $size
 | 
					run_qemu_img create -f $IMGFMT -o backing_file="$TEST_IMG", -o help "$TEST_IMG" $size
 | 
				
			||||||
 | 
				
			|||||||
@ -210,10 +210,10 @@ lazy_refcounts   Postpone refcount updates
 | 
				
			|||||||
refcount_bits    Width of a reference count entry in bits
 | 
					refcount_bits    Width of a reference count entry in bits
 | 
				
			||||||
nocow            Turn off copy-on-write (valid only on btrfs)
 | 
					nocow            Turn off copy-on-write (valid only on btrfs)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M
 | 
					Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,help TEST_DIR/t.qcow2 128M
 | 
				
			||||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help cluster_size=65536 lazy_refcounts=off refcount_bits=16
 | 
					Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,help cluster_size=65536 lazy_refcounts=off refcount_bits=16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2,,? TEST_DIR/t.qcow2 128M
 | 
					Testing: create -f qcow2 -u -o backing_file=TEST_DIR/t.qcow2,,? TEST_DIR/t.qcow2 128M
 | 
				
			||||||
Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,? cluster_size=65536 lazy_refcounts=off refcount_bits=16
 | 
					Formatting 'TEST_DIR/t.qcow2', fmt=qcow2 size=134217728 backing_file=TEST_DIR/t.qcow2,,? cluster_size=65536 lazy_refcounts=off refcount_bits=16
 | 
				
			||||||
 | 
					
 | 
				
			||||||
Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2, -o help TEST_DIR/t.qcow2 128M
 | 
					Testing: create -f qcow2 -o backing_file=TEST_DIR/t.qcow2, -o help TEST_DIR/t.qcow2 128M
 | 
				
			||||||
 | 
				
			|||||||
@ -104,7 +104,7 @@ function add_snapshot_image()
 | 
				
			|||||||
{
 | 
					{
 | 
				
			||||||
    base_image="${TEST_DIR}/$((${1}-1))-${snapshot_virt0}"
 | 
					    base_image="${TEST_DIR}/$((${1}-1))-${snapshot_virt0}"
 | 
				
			||||||
    snapshot_file="${TEST_DIR}/${1}-${snapshot_virt0}"
 | 
					    snapshot_file="${TEST_DIR}/${1}-${snapshot_virt0}"
 | 
				
			||||||
    _make_test_img -b "${base_image}" "$size"
 | 
					    _make_test_img -u -b "${base_image}" "$size"
 | 
				
			||||||
    mv "${TEST_IMG}" "${snapshot_file}"
 | 
					    mv "${TEST_IMG}" "${snapshot_file}"
 | 
				
			||||||
    do_blockdev_add "$1" "'backing': '', " "${snapshot_file}"
 | 
					    do_blockdev_add "$1" "'backing': '', " "${snapshot_file}"
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
				
			|||||||
@ -1,3 +1,4 @@
 | 
				
			|||||||
QA output created by 111
 | 
					QA output created by 111
 | 
				
			||||||
qemu-img: TEST_DIR/t.IMGFMT: Could not open 'TEST_DIR/t.IMGFMT.inexistent': No such file or directory
 | 
					qemu-img: TEST_DIR/t.IMGFMT: Could not open 'TEST_DIR/t.IMGFMT.inexistent': No such file or directory
 | 
				
			||||||
 | 
					Could not open backing image to determine size.
 | 
				
			||||||
*** done
 | 
					*** done
 | 
				
			||||||
 | 
				
			|||||||
@ -65,7 +65,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
 | 
				
			|||||||
    # Add a BlockDriverState that will be used as overlay for the base_img BDS
 | 
					    # Add a BlockDriverState that will be used as overlay for the base_img BDS
 | 
				
			||||||
    def addBlockDriverStateOverlay(self, node):
 | 
					    def addBlockDriverStateOverlay(self, node):
 | 
				
			||||||
        self.checkBlockDriverState(node, False)
 | 
					        self.checkBlockDriverState(node, False)
 | 
				
			||||||
        iotests.qemu_img('create', '-f', iotests.imgfmt,
 | 
					        iotests.qemu_img('create', '-u', '-f', iotests.imgfmt,
 | 
				
			||||||
                         '-b', base_img, new_img, '1M')
 | 
					                         '-b', base_img, new_img, '1M')
 | 
				
			||||||
        opts = {'driver': iotests.imgfmt,
 | 
					        opts = {'driver': iotests.imgfmt,
 | 
				
			||||||
                'node-name': node,
 | 
					                'node-name': node,
 | 
				
			||||||
 | 
				
			|||||||
@ -66,7 +66,7 @@ _send_qemu_cmd $QEMU_HANDLE \
 | 
				
			|||||||
    'return'
 | 
					    'return'
 | 
				
			||||||
 | 
					
 | 
				
			||||||
# Create snapshot
 | 
					# Create snapshot
 | 
				
			||||||
TEST_IMG="$TEST_IMG.overlay" _make_test_img -b "$TEST_IMG" 1M
 | 
					TEST_IMG="$TEST_IMG.overlay" _make_test_img -u -b "$TEST_IMG" 1M
 | 
				
			||||||
_send_qemu_cmd $QEMU_HANDLE \
 | 
					_send_qemu_cmd $QEMU_HANDLE \
 | 
				
			||||||
    "{ 'execute': 'blockdev-snapshot-sync',
 | 
					    "{ 'execute': 'blockdev-snapshot-sync',
 | 
				
			||||||
       'arguments': { 'device': 'source',
 | 
					       'arguments': { 'device': 'source',
 | 
				
			||||||
 | 
				
			|||||||
@ -66,7 +66,7 @@ echo "== verify pattern =="
 | 
				
			|||||||
$QEMU_IO --object $SECRET -c "read -P 0xa 0 $size" --image-opts $IMGSPECBASE | _filter_qemu_io | _filter_testdir
 | 
					$QEMU_IO --object $SECRET -c "read -P 0xa 0 $size" --image-opts $IMGSPECBASE | _filter_qemu_io | _filter_testdir
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo "== create overlay =="
 | 
					echo "== create overlay =="
 | 
				
			||||||
_make_test_img --object $SECRET -o "encryption=on,encrypt.key-secret=sec0" -b "$TEST_IMG_BASE" $size
 | 
					_make_test_img -u --object $SECRET -o "encryption=on,encrypt.key-secret=sec0" -b "$TEST_IMG_BASE" $size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo
 | 
					echo
 | 
				
			||||||
echo "== writing part of a cluster =="
 | 
					echo "== writing part of a cluster =="
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										147
									
								
								tests/qemu-iotests/186
									
									
									
									
									
										Executable file
									
								
							
							
						
						
									
										147
									
								
								tests/qemu-iotests/186
									
									
									
									
									
										Executable file
									
								
							@ -0,0 +1,147 @@
 | 
				
			|||||||
 | 
					#!/bin/bash
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Test 'info block' with all kinds of configurations
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# Copyright (C) 2017 Red Hat, Inc.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This program is free software; you can redistribute it and/or modify
 | 
				
			||||||
 | 
					# it under the terms of the GNU General Public License as published by
 | 
				
			||||||
 | 
					# the Free Software Foundation; either version 2 of the License, or
 | 
				
			||||||
 | 
					# (at your option) any later version.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# This program is distributed in the hope that it will be useful,
 | 
				
			||||||
 | 
					# but WITHOUT ANY WARRANTY; without even the implied warranty of
 | 
				
			||||||
 | 
					# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 | 
				
			||||||
 | 
					# GNU General Public License for more details.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					# You should have received a copy of the GNU General Public License
 | 
				
			||||||
 | 
					# along with this program.  If not, see <http://www.gnu.org/licenses/>.
 | 
				
			||||||
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# creator
 | 
				
			||||||
 | 
					owner=kwolf@redhat.com
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					seq=`basename $0`
 | 
				
			||||||
 | 
					echo "QA output created by $seq"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					here=`pwd`
 | 
				
			||||||
 | 
					status=1	# failure is the default!
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_cleanup()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
						_cleanup_test_img
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					trap "_cleanup; exit \$status" 0 1 2 3 15
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# get standard environment, filters and checks
 | 
				
			||||||
 | 
					. ./common.rc
 | 
				
			||||||
 | 
					. ./common.filter
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					_supported_fmt qcow2
 | 
				
			||||||
 | 
					_supported_proto file
 | 
				
			||||||
 | 
					_supported_os Linux
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					if [ "$QEMU_DEFAULT_MACHINE" != "pc" ]; then
 | 
				
			||||||
 | 
					    _notrun "Requires a PC machine"
 | 
				
			||||||
 | 
					fi
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function do_run_qemu()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    echo Testing: "$@"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    (
 | 
				
			||||||
 | 
					        if ! test -t 0; then
 | 
				
			||||||
 | 
					            while read cmd; do
 | 
				
			||||||
 | 
					                echo $cmd
 | 
				
			||||||
 | 
					            done
 | 
				
			||||||
 | 
					        fi
 | 
				
			||||||
 | 
					        echo quit
 | 
				
			||||||
 | 
					    ) | $QEMU -S -nodefaults -display none -device virtio-scsi-pci -monitor stdio "$@"
 | 
				
			||||||
 | 
					    echo
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					function check_info_block()
 | 
				
			||||||
 | 
					{
 | 
				
			||||||
 | 
					    echo "info block" |
 | 
				
			||||||
 | 
					    QEMU_OPTIONS="" do_run_qemu "$@" | _filter_win32 | _filter_hmp |
 | 
				
			||||||
 | 
					        _filter_qemu | _filter_generated_node_ids
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					size=64M
 | 
				
			||||||
 | 
					_make_test_img $size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					removable="floppy ide-cd scsi-cd"
 | 
				
			||||||
 | 
					fixed="ide-hd scsi-hd virtio-blk-pci"
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					echo "=== Empty drives ==="
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for dev in $removable; do
 | 
				
			||||||
 | 
					    check_info_block -device $dev
 | 
				
			||||||
 | 
					    check_info_block -device $dev,id=qdev_id
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					echo "=== -blockdev/-device=<node-name> ==="
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for dev in $fixed $removable; do
 | 
				
			||||||
 | 
					    check_info_block -blockdev driver=null-co,node-name=null -device $dev,drive=null
 | 
				
			||||||
 | 
					    check_info_block -blockdev driver=null-co,node-name=null -device $dev,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					echo "=== -drive if=none/-device=<node-name> ==="
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# This creates two BlockBackends that will show up in 'info block'!
 | 
				
			||||||
 | 
					# A monitor-owned one from -drive, and anonymous one from -device
 | 
				
			||||||
 | 
					for dev in $fixed $removable; do
 | 
				
			||||||
 | 
					    check_info_block -drive if=none,driver=null-co,node-name=null -device $dev,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					echo "=== -drive if=none/-device=<bb-name> (with medium) ==="
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for dev in $fixed $removable; do
 | 
				
			||||||
 | 
					    check_info_block -drive if=none,driver=null-co,node-name=null -device $dev,drive=none0
 | 
				
			||||||
 | 
					    check_info_block -drive if=none,driver=null-co,node-name=null -device $dev,drive=none0,id=qdev_id
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					echo "=== -drive if=none/-device=<bb-name> (without medium) ==="
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check_info_block -drive if=none
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					for dev in $removable; do
 | 
				
			||||||
 | 
					    check_info_block -drive if=none -device $dev,drive=none0
 | 
				
			||||||
 | 
					    check_info_block -drive if=none -device $dev,drive=none0,id=qdev_id
 | 
				
			||||||
 | 
					done
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					echo "=== -drive if=... ==="
 | 
				
			||||||
 | 
					echo
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check_info_block -drive if=floppy
 | 
				
			||||||
 | 
					check_info_block -drive if=floppy,driver=null-co
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check_info_block -drive if=ide,driver=null-co
 | 
				
			||||||
 | 
					check_info_block -drive if=ide,media=cdrom
 | 
				
			||||||
 | 
					check_info_block -drive if=ide,driver=null-co,media=cdrom
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check_info_block -drive if=scsi,driver=null-co
 | 
				
			||||||
 | 
					check_info_block -drive if=scsi,media=cdrom
 | 
				
			||||||
 | 
					check_info_block -drive if=scsi,driver=null-co,media=cdrom
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check_info_block -drive if=virtio,driver=null-co
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					check_info_block -drive if=pflash,driver=null-co,size=1M
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# success, all done
 | 
				
			||||||
 | 
					echo "*** done"
 | 
				
			||||||
 | 
					rm -f $seq.full
 | 
				
			||||||
 | 
					status=0
 | 
				
			||||||
							
								
								
									
										489
									
								
								tests/qemu-iotests/186.out
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										489
									
								
								tests/qemu-iotests/186.out
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,489 @@
 | 
				
			|||||||
 | 
					QA output created by 186
 | 
				
			||||||
 | 
					Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== Empty drives ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -device floppy
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					/machine/peripheral-anon/device[1]: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -device floppy,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					qdev_id: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -device ide-cd
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					/machine/peripheral-anon/device[1]: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -device ide-cd,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					qdev_id: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -device scsi-cd
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					/machine/peripheral-anon/device[1]: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -device scsi-cd,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					qdev_id: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== -blockdev/-device=<node-name> ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -blockdev driver=null-co,node-name=null -device ide-hd,drive=null
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -blockdev driver=null-co,node-name=null -device ide-hd,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -blockdev driver=null-co,node-name=null -device scsi-hd,drive=null
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -blockdev driver=null-co,node-name=null -device scsi-hd,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -blockdev driver=null-co,node-name=null -device virtio-blk-pci,drive=null
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]/virtio-backend
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -blockdev driver=null-co,node-name=null -device virtio-blk-pci,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral/qdev_id/virtio-backend
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -blockdev driver=null-co,node-name=null -device floppy,drive=null
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -blockdev driver=null-co,node-name=null -device floppy,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -blockdev driver=null-co,node-name=null -device ide-cd,drive=null
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -blockdev driver=null-co,node-name=null -device ide-cd,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -blockdev driver=null-co,node-name=null -device scsi-cd,drive=null
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -blockdev driver=null-co,node-name=null -device scsi-cd,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== -drive if=none/-device=<node-name> ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device ide-hd,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device scsi-hd,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device virtio-blk-pci,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral/qdev_id/virtio-backend
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device floppy,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device ide-cd,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device scsi-cd,drive=null,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					null: null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== -drive if=none/-device=<bb-name> (with medium) ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device ide-hd,drive=none0
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device ide-hd,drive=none0,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device scsi-hd,drive=none0
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device scsi-hd,drive=none0,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device virtio-blk-pci,drive=none0
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]/virtio-backend
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device virtio-blk-pci,drive=none0,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral/qdev_id/virtio-backend
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device floppy,drive=none0
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device floppy,drive=none0,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device ide-cd,drive=none0
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device ide-cd,drive=none0,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device scsi-cd,drive=none0
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none,driver=null-co,node-name=null -device scsi-cd,drive=none0,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0 (null): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== -drive if=none/-device=<bb-name> (without medium) ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0: [not inserted]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none -device floppy,drive=none0
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none -device floppy,drive=none0,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none -device ide-cd,drive=none0
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none -device ide-cd,drive=none0,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none -device scsi-cd,drive=none0
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=none -device scsi-cd,drive=none0,id=qdev_id
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					none0: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      qdev_id
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					=== -drive if=... ===
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=floppy
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					floppy0: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      /machine/unattached/device[17]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=floppy,driver=null-co
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					floppy0 (NODE_NAME): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/unattached/device[17]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=ide,driver=null-co
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					ide0-hd0 (NODE_NAME): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/unattached/device[18]
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=ide,media=cdrom
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					ide0-cd0: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      /machine/unattached/device[18]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=ide,driver=null-co,media=cdrom
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					ide0-cd0 (NODE_NAME): null-co:// (null-co, read-only)
 | 
				
			||||||
 | 
					    Attached to:      /machine/unattached/device[18]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					warning: qemu-system-x86_64: -drive if=scsi,driver=null-co: bus=0,unit=0 is deprecated with this machine type
 | 
				
			||||||
 | 
					Testing: -drive if=scsi,driver=null-co
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					scsi0-hd0 (NODE_NAME): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/unattached/device[27]/scsi.0/legacy[0]
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					warning: qemu-system-x86_64: -drive if=scsi,media=cdrom: bus=0,unit=0 is deprecated with this machine type
 | 
				
			||||||
 | 
					Testing: -drive if=scsi,media=cdrom
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					scsi0-cd0: [not inserted]
 | 
				
			||||||
 | 
					    Attached to:      /machine/unattached/device[27]/scsi.0/legacy[0]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					warning: qemu-system-x86_64: -drive if=scsi,driver=null-co,media=cdrom: bus=0,unit=0 is deprecated with this machine type
 | 
				
			||||||
 | 
					Testing: -drive if=scsi,driver=null-co,media=cdrom
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					scsi0-cd0 (NODE_NAME): null-co:// (null-co, read-only)
 | 
				
			||||||
 | 
					    Attached to:      /machine/unattached/device[27]/scsi.0/legacy[0]
 | 
				
			||||||
 | 
					    Removable device: not locked, tray closed
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=virtio,driver=null-co
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					virtio0 (NODE_NAME): null-co:// (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/peripheral-anon/device[1]/virtio-backend
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					Testing: -drive if=pflash,driver=null-co,size=1M
 | 
				
			||||||
 | 
					QEMU X.Y.Z monitor - type 'help' for more information
 | 
				
			||||||
 | 
					(qemu) info block
 | 
				
			||||||
 | 
					pflash0 (NODE_NAME): json:{"driver": "null-co", "size": "1M"} (null-co)
 | 
				
			||||||
 | 
					    Attached to:      /machine/unattached/device[2]
 | 
				
			||||||
 | 
					    Cache mode:       writeback
 | 
				
			||||||
 | 
					(qemu) quit
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					*** done
 | 
				
			||||||
@ -66,7 +66,7 @@ echo "== verify pattern =="
 | 
				
			|||||||
$QEMU_IO --object $SECRET0 -c "read -P 0xa 0 $size" --image-opts $IMGSPECBASE | _filter_qemu_io | _filter_testdir
 | 
					$QEMU_IO --object $SECRET0 -c "read -P 0xa 0 $size" --image-opts $IMGSPECBASE | _filter_qemu_io | _filter_testdir
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo "== create overlay =="
 | 
					echo "== create overlay =="
 | 
				
			||||||
_make_test_img --object $SECRET1 -o "encrypt.format=luks,encrypt.key-secret=sec1,encrypt.iter-time=10" -b "$TEST_IMG_BASE" $size
 | 
					_make_test_img --object $SECRET1 -o "encrypt.format=luks,encrypt.key-secret=sec1,encrypt.iter-time=10" -u -b "$TEST_IMG_BASE" $size
 | 
				
			||||||
 | 
					
 | 
				
			||||||
echo
 | 
					echo
 | 
				
			||||||
echo "== writing part of a cluster =="
 | 
					echo "== writing part of a cluster =="
 | 
				
			||||||
 | 
				
			|||||||
@ -181,5 +181,6 @@
 | 
				
			|||||||
182 rw auto quick
 | 
					182 rw auto quick
 | 
				
			||||||
183 rw auto migration
 | 
					183 rw auto migration
 | 
				
			||||||
185 rw auto
 | 
					185 rw auto
 | 
				
			||||||
 | 
					186 rw auto
 | 
				
			||||||
188 rw auto quick
 | 
					188 rw auto quick
 | 
				
			||||||
189 rw auto quick
 | 
					189 rw auto quick
 | 
				
			||||||
 | 
				
			|||||||
@ -228,7 +228,7 @@ static void test_config_functions(void)
 | 
				
			|||||||
                         read_timer_cb, write_timer_cb, &ts);
 | 
					                         read_timer_cb, write_timer_cb, &ts);
 | 
				
			||||||
    /* structure reset by throttle_init previous_leak should be null */
 | 
					    /* structure reset by throttle_init previous_leak should be null */
 | 
				
			||||||
    g_assert(!ts.previous_leak);
 | 
					    g_assert(!ts.previous_leak);
 | 
				
			||||||
    throttle_config(&ts, &tt, &orig_cfg);
 | 
					    throttle_config(&ts, QEMU_CLOCK_VIRTUAL, &orig_cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* has previous leak been initialized by throttle_config ? */
 | 
					    /* has previous leak been initialized by throttle_config ? */
 | 
				
			||||||
    g_assert(ts.previous_leak);
 | 
					    g_assert(ts.previous_leak);
 | 
				
			||||||
@ -486,7 +486,7 @@ static bool do_test_accounting(bool is_ops, /* are we testing bps or ops */
 | 
				
			|||||||
    throttle_init(&ts);
 | 
					    throttle_init(&ts);
 | 
				
			||||||
    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
 | 
					    throttle_timers_init(&tt, ctx, QEMU_CLOCK_VIRTUAL,
 | 
				
			||||||
                         read_timer_cb, write_timer_cb, &ts);
 | 
					                         read_timer_cb, write_timer_cb, &ts);
 | 
				
			||||||
    throttle_config(&ts, &tt, &cfg);
 | 
					    throttle_config(&ts, QEMU_CLOCK_VIRTUAL, &cfg);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    /* account a read */
 | 
					    /* account a read */
 | 
				
			||||||
    throttle_account(&ts, false, size);
 | 
					    throttle_account(&ts, false, size);
 | 
				
			||||||
 | 
				
			|||||||
@ -388,22 +388,14 @@ static void throttle_unfix_bucket(LeakyBucket *bkt)
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* take care of canceling a timer */
 | 
					 | 
				
			||||||
static void throttle_cancel_timer(QEMUTimer *timer)
 | 
					 | 
				
			||||||
{
 | 
					 | 
				
			||||||
    assert(timer != NULL);
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    timer_del(timer);
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
/* Used to configure the throttle
 | 
					/* Used to configure the throttle
 | 
				
			||||||
 *
 | 
					 *
 | 
				
			||||||
 * @ts: the throttle state we are working on
 | 
					 * @ts: the throttle state we are working on
 | 
				
			||||||
 * @tt: the throttle timers we use in this aio context
 | 
					 * @clock_type: the group's clock_type
 | 
				
			||||||
 * @cfg: the config to set
 | 
					 * @cfg: the config to set
 | 
				
			||||||
 */
 | 
					 */
 | 
				
			||||||
void throttle_config(ThrottleState *ts,
 | 
					void throttle_config(ThrottleState *ts,
 | 
				
			||||||
                     ThrottleTimers *tt,
 | 
					                     QEMUClockType clock_type,
 | 
				
			||||||
                     ThrottleConfig *cfg)
 | 
					                     ThrottleConfig *cfg)
 | 
				
			||||||
{
 | 
					{
 | 
				
			||||||
    int i;
 | 
					    int i;
 | 
				
			||||||
@ -414,11 +406,7 @@ void throttle_config(ThrottleState *ts,
 | 
				
			|||||||
        throttle_fix_bucket(&ts->cfg.buckets[i]);
 | 
					        throttle_fix_bucket(&ts->cfg.buckets[i]);
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    ts->previous_leak = qemu_clock_get_ns(tt->clock_type);
 | 
					    ts->previous_leak = qemu_clock_get_ns(clock_type);
 | 
				
			||||||
 | 
					 | 
				
			||||||
    for (i = 0; i < 2; i++) {
 | 
					 | 
				
			||||||
        throttle_cancel_timer(tt->timers[i]);
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/* used to get config
 | 
					/* used to get config
 | 
				
			||||||
 | 
				
			|||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user