diff options
42 files changed, 449 insertions, 438 deletions
diff --git a/Makefile.target b/Makefile.target index 8be9b9a596..3261383fd3 100644 --- a/Makefile.target +++ b/Makefile.target @@ -92,12 +92,6 @@ tci-dis.o: QEMU_CFLAGS += -I$(SRC_PATH)/tcg -I$(SRC_PATH)/tcg/tci $(libobj-y): $(GENERATED_HEADERS) -translate.o: translate.c cpu.h - -translate-all.o: translate-all.c cpu.h - -tcg/tcg.o: cpu.h - # HELPER_CFLAGS is used for all the code compiled with static register # variables op_helper.o ldst_helper.o user-exec.o: QEMU_CFLAGS += $(HELPER_CFLAGS) diff --git a/block-migration.c b/block-migration.c index 423c5a07b6..2b7edbc3d7 100644 --- a/block-migration.c +++ b/block-migration.c @@ -251,22 +251,12 @@ static int mig_save_device_bulk(Monitor *mon, QEMUFile *f, blk->aiocb = bdrv_aio_readv(bs, cur_sector, &blk->qiov, nr_sectors, blk_mig_read_cb, blk); - if (!blk->aiocb) { - goto error; - } block_mig_state.submitted++; bdrv_reset_dirty(bs, cur_sector, nr_sectors); bmds->cur_sector = cur_sector + nr_sectors; return (bmds->cur_sector >= total_sectors); - -error: - monitor_printf(mon, "Error reading sector %" PRId64 "\n", cur_sector); - qemu_file_set_error(f, -EIO); - g_free(blk->buf); - g_free(blk); - return 0; } static void set_dirty_tracking(int enable) @@ -413,9 +403,6 @@ static int mig_save_device_dirty(Monitor *mon, QEMUFile *f, blk->aiocb = bdrv_aio_readv(bmds->bs, sector, &blk->qiov, nr_sectors, blk_mig_read_cb, blk); - if (!blk->aiocb) { - goto error; - } block_mig_state.submitted++; bmds_set_aio_inflight(bmds, sector, nr_sectors, 1); } else { @@ -2812,7 +2812,6 @@ static int multiwrite_merge(BlockDriverState *bs, BlockRequest *reqs, */ int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs) { - BlockDriverAIOCB *acb; MultiwriteCB *mcb; int i; @@ -2843,59 +2842,14 @@ int bdrv_aio_multiwrite(BlockDriverState *bs, BlockRequest *reqs, int num_reqs) trace_bdrv_aio_multiwrite(mcb, mcb->num_callbacks, num_reqs); - /* - * Run the aio requests. As soon as one request can't be submitted - * successfully, fail all requests that are not yet submitted (we must - * return failure for all requests anyway) - * - * num_requests cannot be set to the right value immediately: If - * bdrv_aio_writev fails for some request, num_requests would be too high - * and therefore multiwrite_cb() would never recognize the multiwrite - * request as completed. We also cannot use the loop variable i to set it - * when the first request fails because the callback may already have been - * called for previously submitted requests. Thus, num_requests must be - * incremented for each request that is submitted. - * - * The problem that callbacks may be called early also means that we need - * to take care that num_requests doesn't become 0 before all requests are - * submitted - multiwrite_cb() would consider the multiwrite request - * completed. A dummy request that is "completed" by a manual call to - * multiwrite_cb() takes care of this. - */ - mcb->num_requests = 1; - - // Run the aio requests + /* Run the aio requests. */ + mcb->num_requests = num_reqs; for (i = 0; i < num_reqs; i++) { - mcb->num_requests++; - acb = bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov, + bdrv_aio_writev(bs, reqs[i].sector, reqs[i].qiov, reqs[i].nb_sectors, multiwrite_cb, mcb); - - if (acb == NULL) { - // We can only fail the whole thing if no request has been - // submitted yet. Otherwise we'll wait for the submitted AIOs to - // complete and report the error in the callback. - if (i == 0) { - trace_bdrv_aio_multiwrite_earlyfail(mcb); - goto fail; - } else { - trace_bdrv_aio_multiwrite_latefail(mcb, i); - multiwrite_cb(mcb, -EIO); - break; - } - } } - /* Complete the dummy request */ - multiwrite_cb(mcb, 0); - return 0; - -fail: - for (i = 0; i < mcb->num_callbacks; i++) { - reqs[i].error = -EIO; - } - g_free(mcb); - return -1; } void bdrv_aio_cancel(BlockDriverAIOCB *acb) @@ -3123,9 +3077,7 @@ static BlockDriverAIOCB *bdrv_aio_rw_vector(BlockDriverState *bs, acb->is_write = is_write; acb->qiov = qiov; acb->bounce = qemu_blockalign(bs, qiov->size); - - if (!acb->bh) - acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); + acb->bh = qemu_bh_new(bdrv_aio_bh_cb, acb); if (is_write) { qemu_iovec_to_buffer(acb->qiov, acb->bounce); @@ -22,7 +22,7 @@ typedef struct QEMUSnapshotInfo { /* the following fields are informative. They are not needed for the consistency of the snapshot */ char name[256]; /* user chosen name */ - uint32_t vm_state_size; /* VM state info size */ + uint64_t vm_state_size; /* VM state info size */ uint32_t date_sec; /* UTC date of the snapshot */ uint32_t date_nsec; uint64_t vm_clock_nsec; /* VM clock relative to boot */ diff --git a/block/blkverify.c b/block/blkverify.c index 483f3b3cfe..4ca8584b88 100644 --- a/block/blkverify.c +++ b/block/blkverify.c @@ -310,14 +310,10 @@ static BlockDriverAIOCB *blkverify_aio_readv(BlockDriverState *bs, qemu_iovec_init(&acb->raw_qiov, acb->qiov->niov); blkverify_iovec_clone(&acb->raw_qiov, qiov, acb->buf); - if (!bdrv_aio_readv(s->test_file, sector_num, qiov, nb_sectors, - blkverify_aio_cb, acb)) { - blkverify_aio_cb(acb, -EIO); - } - if (!bdrv_aio_readv(bs->file, sector_num, &acb->raw_qiov, nb_sectors, - blkverify_aio_cb, acb)) { - blkverify_aio_cb(acb, -EIO); - } + bdrv_aio_readv(s->test_file, sector_num, qiov, nb_sectors, + blkverify_aio_cb, acb); + bdrv_aio_readv(bs->file, sector_num, &acb->raw_qiov, nb_sectors, + blkverify_aio_cb, acb); return &acb->common; } @@ -329,14 +325,10 @@ static BlockDriverAIOCB *blkverify_aio_writev(BlockDriverState *bs, BlkverifyAIOCB *acb = blkverify_aio_get(bs, true, sector_num, qiov, nb_sectors, cb, opaque); - if (!bdrv_aio_writev(s->test_file, sector_num, qiov, nb_sectors, - blkverify_aio_cb, acb)) { - blkverify_aio_cb(acb, -EIO); - } - if (!bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, - blkverify_aio_cb, acb)) { - blkverify_aio_cb(acb, -EIO); - } + bdrv_aio_writev(s->test_file, sector_num, qiov, nb_sectors, + blkverify_aio_cb, acb); + bdrv_aio_writev(bs->file, sector_num, qiov, nb_sectors, + blkverify_aio_cb, acb); return &acb->common; } diff --git a/block/cow.c b/block/cow.c index 3c527358c6..bb5927c6aa 100644 --- a/block/cow.c +++ b/block/cow.c @@ -64,15 +64,26 @@ static int cow_open(BlockDriverState *bs, int flags) struct cow_header_v2 cow_header; int bitmap_size; int64_t size; + int ret; /* see if it is a cow image */ - if (bdrv_pread(bs->file, 0, &cow_header, sizeof(cow_header)) != - sizeof(cow_header)) { + ret = bdrv_pread(bs->file, 0, &cow_header, sizeof(cow_header)); + if (ret < 0) { + goto fail; + } + + if (be32_to_cpu(cow_header.magic) != COW_MAGIC) { + ret = -EINVAL; goto fail; } - if (be32_to_cpu(cow_header.magic) != COW_MAGIC || - be32_to_cpu(cow_header.version) != COW_VERSION) { + if (be32_to_cpu(cow_header.version) != COW_VERSION) { + char version[64]; + snprintf(version, sizeof(version), + "COW version %d", cow_header.version); + qerror_report(QERR_UNKNOWN_BLOCK_FORMAT_FEATURE, + bs->device_name, "cow", version); + ret = -ENOTSUP; goto fail; } @@ -88,7 +99,7 @@ static int cow_open(BlockDriverState *bs, int flags) qemu_co_mutex_init(&s->lock); return 0; fail: - return -1; + return ret; } /* @@ -182,17 +193,19 @@ static int coroutine_fn cow_read(BlockDriverState *bs, int64_t sector_num, ret = bdrv_pread(bs->file, s->cow_sectors_offset + sector_num * 512, buf, n * 512); - if (ret != n * 512) - return -1; + if (ret < 0) { + return ret; + } } else { if (bs->backing_hd) { /* read from the base image */ ret = bdrv_read(bs->backing_hd, sector_num, buf, n); - if (ret < 0) - return -1; + if (ret < 0) { + return ret; + } } else { - memset(buf, 0, n * 512); - } + memset(buf, 0, n * 512); + } } nb_sectors -= n; sector_num += n; @@ -220,8 +233,9 @@ static int cow_write(BlockDriverState *bs, int64_t sector_num, ret = bdrv_pwrite(bs->file, s->cow_sectors_offset + sector_num * 512, buf, nb_sectors * 512); - if (ret != nb_sectors * 512) - return -1; + if (ret < 0) { + return ret; + } return cow_update_bitmap(bs, sector_num, nb_sectors); } @@ -288,14 +302,14 @@ static int cow_create(const char *filename, QEMUOptionParameter *options) cow_header.sectorsize = cpu_to_be32(512); cow_header.size = cpu_to_be64(image_sectors * 512); ret = bdrv_pwrite(cow_bs, 0, &cow_header, sizeof(cow_header)); - if (ret != sizeof(cow_header)) { + if (ret < 0) { goto exit; } /* resize to include at least all the bitmap */ ret = bdrv_truncate(cow_bs, sizeof(cow_header) + ((image_sectors + 7) >> 3)); - if (ret) { + if (ret < 0) { goto exit; } diff --git a/block/curl.c b/block/curl.c index 4209ac88ce..e9102e3e20 100644 --- a/block/curl.c +++ b/block/curl.c @@ -509,10 +509,6 @@ static BlockDriverAIOCB *curl_aio_readv(BlockDriverState *bs, acb = qemu_aio_get(&curl_aio_pool, bs, cb, opaque); - if (!acb) { - return NULL; - } - acb->qiov = qiov; acb->sector_num = sector_num; acb->nb_sectors = nb_sectors; diff --git a/block/qcow2-snapshot.c b/block/qcow2-snapshot.c index c3112bf71a..7d3fde5a8a 100644 --- a/block/qcow2-snapshot.c +++ b/block/qcow2-snapshot.c @@ -46,6 +46,10 @@ typedef struct QEMU_PACKED QCowSnapshotHeader { /* name follows */ } QCowSnapshotHeader; +typedef struct QEMU_PACKED QCowSnapshotExtraData { + uint64_t vm_state_size_large; +} QCowSnapshotExtraData; + void qcow2_free_snapshots(BlockDriverState *bs) { BDRVQcowState *s = bs->opaque; @@ -64,6 +68,7 @@ int qcow2_read_snapshots(BlockDriverState *bs) { BDRVQcowState *s = bs->opaque; QCowSnapshotHeader h; + QCowSnapshotExtraData extra; QCowSnapshot *sn; int i, id_str_size, name_size; int64_t offset; @@ -100,9 +105,18 @@ int qcow2_read_snapshots(BlockDriverState *bs) id_str_size = be16_to_cpu(h.id_str_size); name_size = be16_to_cpu(h.name_size); - /* Skip extra data */ + /* Read extra data */ + ret = bdrv_pread(bs->file, offset, &extra, + MIN(sizeof(extra), extra_data_size)); + if (ret < 0) { + goto fail; + } offset += extra_data_size; + if (extra_data_size >= 8) { + sn->vm_state_size = be64_to_cpu(extra.vm_state_size_large); + } + /* Read snapshot ID */ sn->id_str = g_malloc(id_str_size + 1); ret = bdrv_pread(bs->file, offset, sn->id_str, id_str_size); @@ -136,6 +150,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs) BDRVQcowState *s = bs->opaque; QCowSnapshot *sn; QCowSnapshotHeader h; + QCowSnapshotExtraData extra; int i, name_size, id_str_size, snapshots_size; struct { uint32_t nb_snapshots; @@ -150,6 +165,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs) sn = s->snapshots + i; offset = align_offset(offset, 8); offset += sizeof(h); + offset += sizeof(extra); offset += strlen(sn->id_str); offset += strlen(sn->name); } @@ -169,10 +185,18 @@ static int qcow2_write_snapshots(BlockDriverState *bs) memset(&h, 0, sizeof(h)); h.l1_table_offset = cpu_to_be64(sn->l1_table_offset); h.l1_size = cpu_to_be32(sn->l1_size); - h.vm_state_size = cpu_to_be32(sn->vm_state_size); + /* If it doesn't fit in 32 bit, older implementations should treat it + * as a disk-only snapshot rather than truncate the VM state */ + if (sn->vm_state_size <= 0xffffffff) { + h.vm_state_size = cpu_to_be32(sn->vm_state_size); + } h.date_sec = cpu_to_be32(sn->date_sec); h.date_nsec = cpu_to_be32(sn->date_nsec); h.vm_clock_nsec = cpu_to_be64(sn->vm_clock_nsec); + h.extra_data_size = cpu_to_be32(sizeof(extra)); + + memset(&extra, 0, sizeof(extra)); + extra.vm_state_size_large = cpu_to_be64(sn->vm_state_size); id_str_size = strlen(sn->id_str); name_size = strlen(sn->name); @@ -186,6 +210,12 @@ static int qcow2_write_snapshots(BlockDriverState *bs) } offset += sizeof(h); + ret = bdrv_pwrite(bs->file, offset, &extra, sizeof(extra)); + if (ret < 0) { + goto fail; + } + offset += sizeof(extra); + ret = bdrv_pwrite(bs->file, offset, sn->id_str, id_str_size); if (ret < 0) { goto fail; diff --git a/block/qcow2.c b/block/qcow2.c index 37cd4424d4..aa32e8d01a 100644 --- a/block/qcow2.c +++ b/block/qcow2.c @@ -635,6 +635,7 @@ static void qcow2_close(BlockDriverState *bs) g_free(s->cluster_cache); qemu_vfree(s->cluster_data); qcow2_refcount_close(bs); + qcow2_free_snapshots(bs); } static void qcow2_invalidate_cache(BlockDriverState *bs) diff --git a/block/qcow2.h b/block/qcow2.h index 4e44eea5ef..99e45361f5 100644 --- a/block/qcow2.h +++ b/block/qcow2.h @@ -78,7 +78,7 @@ typedef struct QCowSnapshot { uint32_t l1_size; char *id_str; char *name; - uint32_t vm_state_size; + uint64_t vm_state_size; uint32_t date_sec; uint32_t date_nsec; uint64_t vm_clock_nsec; diff --git a/block/qed-table.c b/block/qed-table.c index 8ee844346c..ce07b05549 100644 --- a/block/qed-table.c +++ b/block/qed-table.c @@ -54,7 +54,6 @@ static void qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table, QEDReadTableCB *read_table_cb = gencb_alloc(sizeof(*read_table_cb), cb, opaque); QEMUIOVector *qiov = &read_table_cb->qiov; - BlockDriverAIOCB *aiocb; trace_qed_read_table(s, offset, table); @@ -64,12 +63,9 @@ static void qed_read_table(BDRVQEDState *s, uint64_t offset, QEDTable *table, read_table_cb->iov.iov_len = s->header.cluster_size * s->header.table_size, qemu_iovec_init_external(qiov, &read_table_cb->iov, 1); - aiocb = bdrv_aio_readv(s->bs->file, offset / BDRV_SECTOR_SIZE, qiov, - qiov->size / BDRV_SECTOR_SIZE, - qed_read_table_cb, read_table_cb); - if (!aiocb) { - qed_read_table_cb(read_table_cb, -EIO); - } + bdrv_aio_readv(s->bs->file, offset / BDRV_SECTOR_SIZE, qiov, + qiov->size / BDRV_SECTOR_SIZE, + qed_read_table_cb, read_table_cb); } typedef struct { @@ -127,7 +123,6 @@ static void qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table, BlockDriverCompletionFunc *cb, void *opaque) { QEDWriteTableCB *write_table_cb; - BlockDriverAIOCB *aiocb; unsigned int sector_mask = BDRV_SECTOR_SIZE / sizeof(uint64_t) - 1; unsigned int start, end, i; size_t len_bytes; @@ -158,13 +153,10 @@ static void qed_write_table(BDRVQEDState *s, uint64_t offset, QEDTable *table, /* Adjust for offset into table */ offset += start * sizeof(uint64_t); - aiocb = bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE, - &write_table_cb->qiov, - write_table_cb->qiov.size / BDRV_SECTOR_SIZE, - qed_write_table_cb, write_table_cb); - if (!aiocb) { - qed_write_table_cb(write_table_cb, -EIO); - } + bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE, + &write_table_cb->qiov, + write_table_cb->qiov.size / BDRV_SECTOR_SIZE, + qed_write_table_cb, write_table_cb); } /** diff --git a/block/qed.c b/block/qed.c index 22e467202f..8da3ebe9d4 100644 --- a/block/qed.c +++ b/block/qed.c @@ -123,7 +123,6 @@ static void qed_write_header_read_cb(void *opaque, int ret) { QEDWriteHeaderCB *write_header_cb = opaque; BDRVQEDState *s = write_header_cb->s; - BlockDriverAIOCB *acb; if (ret) { qed_write_header_cb(write_header_cb, ret); @@ -133,12 +132,9 @@ static void qed_write_header_read_cb(void *opaque, int ret) /* Update header */ qed_header_cpu_to_le(&s->header, (QEDHeader *)write_header_cb->buf); - acb = bdrv_aio_writev(s->bs->file, 0, &write_header_cb->qiov, - write_header_cb->nsectors, qed_write_header_cb, - write_header_cb); - if (!acb) { - qed_write_header_cb(write_header_cb, -EIO); - } + bdrv_aio_writev(s->bs->file, 0, &write_header_cb->qiov, + write_header_cb->nsectors, qed_write_header_cb, + write_header_cb); } /** @@ -156,7 +152,6 @@ static void qed_write_header(BDRVQEDState *s, BlockDriverCompletionFunc cb, * them, and write back. */ - BlockDriverAIOCB *acb; int nsectors = (sizeof(QEDHeader) + BDRV_SECTOR_SIZE - 1) / BDRV_SECTOR_SIZE; size_t len = nsectors * BDRV_SECTOR_SIZE; @@ -170,11 +165,8 @@ static void qed_write_header(BDRVQEDState *s, BlockDriverCompletionFunc cb, write_header_cb->iov.iov_len = len; qemu_iovec_init_external(&write_header_cb->qiov, &write_header_cb->iov, 1); - acb = bdrv_aio_readv(s->bs->file, 0, &write_header_cb->qiov, nsectors, - qed_write_header_read_cb, write_header_cb); - if (!acb) { - qed_write_header_cb(write_header_cb, -EIO); - } + bdrv_aio_readv(s->bs->file, 0, &write_header_cb->qiov, nsectors, + qed_write_header_read_cb, write_header_cb); } static uint64_t qed_max_image_size(uint32_t cluster_size, uint32_t table_size) @@ -728,7 +720,6 @@ static void qed_read_backing_file(BDRVQEDState *s, uint64_t pos, QEMUIOVector *qiov, BlockDriverCompletionFunc *cb, void *opaque) { - BlockDriverAIOCB *aiocb; uint64_t backing_length = 0; size_t size; @@ -760,11 +751,8 @@ static void qed_read_backing_file(BDRVQEDState *s, uint64_t pos, size = MIN((uint64_t)backing_length - pos, qiov->size); BLKDBG_EVENT(s->bs->file, BLKDBG_READ_BACKING); - aiocb = bdrv_aio_readv(s->bs->backing_hd, pos / BDRV_SECTOR_SIZE, - qiov, size / BDRV_SECTOR_SIZE, cb, opaque); - if (!aiocb) { - cb(opaque, -EIO); - } + bdrv_aio_readv(s->bs->backing_hd, pos / BDRV_SECTOR_SIZE, + qiov, size / BDRV_SECTOR_SIZE, cb, opaque); } typedef struct { @@ -786,7 +774,6 @@ static void qed_copy_from_backing_file_write(void *opaque, int ret) { CopyFromBackingFileCB *copy_cb = opaque; BDRVQEDState *s = copy_cb->s; - BlockDriverAIOCB *aiocb; if (ret) { qed_copy_from_backing_file_cb(copy_cb, ret); @@ -794,13 +781,9 @@ static void qed_copy_from_backing_file_write(void *opaque, int ret) } BLKDBG_EVENT(s->bs->file, BLKDBG_COW_WRITE); - aiocb = bdrv_aio_writev(s->bs->file, copy_cb->offset / BDRV_SECTOR_SIZE, - ©_cb->qiov, - copy_cb->qiov.size / BDRV_SECTOR_SIZE, - qed_copy_from_backing_file_cb, copy_cb); - if (!aiocb) { - qed_copy_from_backing_file_cb(copy_cb, -EIO); - } + bdrv_aio_writev(s->bs->file, copy_cb->offset / BDRV_SECTOR_SIZE, + ©_cb->qiov, copy_cb->qiov.size / BDRV_SECTOR_SIZE, + qed_copy_from_backing_file_cb, copy_cb); } /** @@ -1022,7 +1005,6 @@ static void qed_aio_write_main(void *opaque, int ret) uint64_t offset = acb->cur_cluster + qed_offset_into_cluster(s, acb->cur_pos); BlockDriverCompletionFunc *next_fn; - BlockDriverAIOCB *file_acb; trace_qed_aio_write_main(s, acb, ret, offset, acb->cur_qiov.size); @@ -1042,13 +1024,9 @@ static void qed_aio_write_main(void *opaque, int ret) } BLKDBG_EVENT(s->bs->file, BLKDBG_WRITE_AIO); - file_acb = bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE, - &acb->cur_qiov, - acb->cur_qiov.size / BDRV_SECTOR_SIZE, - next_fn, acb); - if (!file_acb) { - qed_aio_complete(acb, -EIO); - } + bdrv_aio_writev(s->bs->file, offset / BDRV_SECTOR_SIZE, + &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE, + next_fn, acb); } /** @@ -1215,7 +1193,6 @@ static void qed_aio_read_data(void *opaque, int ret, QEDAIOCB *acb = opaque; BDRVQEDState *s = acb_to_s(acb); BlockDriverState *bs = acb->common.bs; - BlockDriverAIOCB *file_acb; /* Adjust offset into cluster */ offset += qed_offset_into_cluster(s, acb->cur_pos); @@ -1240,14 +1217,9 @@ static void qed_aio_read_data(void *opaque, int ret, } BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO); - file_acb = bdrv_aio_readv(bs->file, offset / BDRV_SECTOR_SIZE, - &acb->cur_qiov, - acb->cur_qiov.size / BDRV_SECTOR_SIZE, - qed_aio_next_io, acb); - if (!file_acb) { - ret = -EIO; - goto err; - } + bdrv_aio_readv(bs->file, offset / BDRV_SECTOR_SIZE, + &acb->cur_qiov, acb->cur_qiov.size / BDRV_SECTOR_SIZE, + qed_aio_next_io, acb); return; err: diff --git a/block/rbd.c b/block/rbd.c index 9088c52d24..7a2384c8f9 100644 --- a/block/rbd.c +++ b/block/rbd.c @@ -632,9 +632,6 @@ static BlockDriverAIOCB *rbd_aio_rw_vector(BlockDriverState *bs, BDRVRBDState *s = bs->opaque; acb = qemu_aio_get(&rbd_aio_pool, bs, cb, opaque); - if (!acb) { - return NULL; - } acb->write = write; acb->qiov = qiov; acb->bounce = qemu_blockalign(bs, qiov->size); @@ -808,7 +805,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs, } while (snap_count == -ERANGE); if (snap_count <= 0) { - return snap_count; + goto done; } sn_tab = g_malloc0(snap_count * sizeof(QEMUSnapshotInfo)); @@ -827,6 +824,7 @@ static int qemu_rbd_snap_list(BlockDriverState *bs, } rbd_snap_list_end(snaps); + done: *psn_tab = sn_tab; return snap_count; } diff --git a/block/vdi.c b/block/vdi.c index e1d8cffc2d..31cdfabdea 100644 --- a/block/vdi.c +++ b/block/vdi.c @@ -515,28 +515,26 @@ static VdiAIOCB *vdi_aio_setup(BlockDriverState *bs, int64_t sector_num, bs, sector_num, qiov, nb_sectors, cb, opaque, is_write); acb = qemu_aio_get(&vdi_aio_pool, bs, cb, opaque); - if (acb) { - acb->hd_aiocb = NULL; - acb->sector_num = sector_num; - acb->qiov = qiov; - acb->is_write = is_write; - - if (qiov->niov > 1) { - acb->buf = qemu_blockalign(bs, qiov->size); - acb->orig_buf = acb->buf; - if (is_write) { - qemu_iovec_to_buffer(qiov, acb->buf); - } - } else { - acb->buf = (uint8_t *)qiov->iov->iov_base; + acb->hd_aiocb = NULL; + acb->sector_num = sector_num; + acb->qiov = qiov; + acb->is_write = is_write; + + if (qiov->niov > 1) { + acb->buf = qemu_blockalign(bs, qiov->size); + acb->orig_buf = acb->buf; + if (is_write) { + qemu_iovec_to_buffer(qiov, acb->buf); } - acb->nb_sectors = nb_sectors; - acb->n_sectors = 0; - acb->bmap_first = VDI_UNALLOCATED; - acb->bmap_last = VDI_UNALLOCATED; - acb->block_buffer = NULL; - acb->header_modified = 0; - } + } else { + acb->buf = (uint8_t *)qiov->iov->iov_base; + } + acb->nb_sectors = nb_sectors; + acb->n_sectors = 0; + acb->bmap_first = VDI_UNALLOCATED; + acb->bmap_last = VDI_UNALLOCATED; + acb->block_buffer = NULL; + acb->header_modified = 0; return acb; } @@ -633,10 +631,6 @@ static void vdi_aio_read_cb(void *opaque, int ret) qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); acb->hd_aiocb = bdrv_aio_readv(bs->file, offset, &acb->hd_qiov, n_sectors, vdi_aio_read_cb, acb); - if (acb->hd_aiocb == NULL) { - ret = -EIO; - goto done; - } } return; done: @@ -657,10 +651,6 @@ static BlockDriverAIOCB *vdi_aio_readv(BlockDriverState *bs, logout("\n"); acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 0); - if (!acb) { - return NULL; - } - ret = vdi_schedule_bh(vdi_aio_rw_bh, acb); if (ret < 0) { if (acb->qiov->niov > 1) { @@ -708,10 +698,6 @@ static void vdi_aio_write_cb(void *opaque, int ret) qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); acb->hd_aiocb = bdrv_aio_writev(bs->file, 0, &acb->hd_qiov, 1, vdi_aio_write_cb, acb); - if (acb->hd_aiocb == NULL) { - ret = -EIO; - goto done; - } return; } else if (VDI_IS_ALLOCATED(acb->bmap_first)) { /* One or more new blocks were allocated. */ @@ -738,10 +724,6 @@ static void vdi_aio_write_cb(void *opaque, int ret) n_sectors, bmap_first); acb->hd_aiocb = bdrv_aio_writev(bs->file, offset, &acb->hd_qiov, n_sectors, vdi_aio_write_cb, acb); - if (acb->hd_aiocb == NULL) { - ret = -EIO; - goto done; - } return; } ret = 0; @@ -789,10 +771,6 @@ static void vdi_aio_write_cb(void *opaque, int ret) acb->hd_aiocb = bdrv_aio_writev(bs->file, offset, &acb->hd_qiov, s->block_sectors, vdi_aio_write_cb, acb); - if (acb->hd_aiocb == NULL) { - ret = -EIO; - goto done; - } } else { uint64_t offset = s->header.offset_data / SECTOR_SIZE + (uint64_t)bmap_entry * s->block_sectors + @@ -802,10 +780,6 @@ static void vdi_aio_write_cb(void *opaque, int ret) qemu_iovec_init_external(&acb->hd_qiov, &acb->hd_iov, 1); acb->hd_aiocb = bdrv_aio_writev(bs->file, offset, &acb->hd_qiov, n_sectors, vdi_aio_write_cb, acb); - if (acb->hd_aiocb == NULL) { - ret = -EIO; - goto done; - } } return; @@ -827,10 +801,6 @@ static BlockDriverAIOCB *vdi_aio_writev(BlockDriverState *bs, logout("\n"); acb = vdi_aio_setup(bs, sector_num, qiov, nb_sectors, cb, opaque, 1); - if (!acb) { - return NULL; - } - ret = vdi_schedule_bh(vdi_aio_rw_bh, acb); if (ret < 0) { if (acb->qiov->niov > 1) { @@ -1082,7 +1082,7 @@ fi # check that the C compiler works. cat > $TMPC <<EOF -int main(void) {} +int main(void) { return 0; } EOF if compile_object ; then @@ -1274,11 +1274,11 @@ if test "$nptl" != "no" ; then cat > $TMPC <<EOF #include <sched.h> #include <linux/futex.h> -void foo() -{ +int main(void) { #if !defined(CLONE_SETTLS) || !defined(FUTEX_WAIT) #error bork #endif + return 0; } EOF @@ -1317,10 +1317,30 @@ fi if test "$xen" != "no" ; then xen_libs="-lxenstore -lxenctrl -lxenguest" - # Xen unstable + # First we test whether Xen headers and libraries are available. + # If no, we are done and there is no Xen support. + # If yes, more tests are run to detect the Xen version. + + # Xen (any) cat > $TMPC <<EOF #include <xenctrl.h> #include <xs.h> +int main(void) { + return 0; +} +EOF + if ! compile_prog "" "$xen_libs" ; then + # Xen not found + if test "$xen" = "yes" ; then + feature_not_found "xen" + fi + xen=no + + # Xen unstable + elif ( + cat > $TMPC <<EOF +#include <xenctrl.h> +#include <xs.h> #include <stdint.h> #include <xen/hvm/hvm_info_table.h> #if !defined(HVM_MAX_VCPUS) @@ -1336,7 +1356,8 @@ int main(void) { return 0; } EOF - if compile_prog "" "$xen_libs" ; then + compile_prog "" "$xen_libs" + ) ; then xen_ctrl_version=410 xen=yes @@ -1407,10 +1428,10 @@ EOF xen_ctrl_version=330 xen=yes - # Xen not found or unsupported + # Xen version unsupported else if test "$xen" = "yes" ; then - feature_not_found "xen" + feature_not_found "xen (unsupported version)" fi xen=no fi @@ -1670,6 +1691,7 @@ fi # xfsctl() probe, used for raw-posix if test "$xfs" != "no" ; then cat > $TMPC << EOF +#include <stddef.h> /* NULL */ #include <xfs/xfs.h> int main(void) { @@ -1841,7 +1863,11 @@ if test "$curses" != "no" ; then #ifdef __OpenBSD__ #define resize_term resizeterm #endif -int main(void) { resize_term(0, 0); return curses_version(); } +int main(void) { + const char *s = curses_version(); + resize_term(0, 0); + return s != 0; +} EOF for curses_lib in $curses_list; do if compile_prog "" "$curses_lib" ; then @@ -1947,7 +1973,12 @@ PTHREADLIBS_LIST="-pthread -lpthread -lpthreadGC2" pthread=no cat > $TMPC << EOF #include <pthread.h> -int main(void) { pthread_create(0,0,0,0); return 0; } +static void *f(void *p) { return NULL; } +int main(void) { + pthread_t thread; + pthread_create(&thread, 0, f, 0); + return 0; +} EOF if compile_prog "" "" ; then pthread=yes @@ -2051,7 +2082,7 @@ cat > $TMPC <<EOF #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> -int main(void) { struct iovec iov; return 0; } +int main(void) { return sizeof(struct iovec); } EOF iovec=no if compile_prog "" "" ; then @@ -2064,7 +2095,7 @@ cat > $TMPC <<EOF #include <sys/types.h> #include <sys/uio.h> #include <unistd.h> -int main(void) { preadv; } +int main(void) { return preadv == preadv; } EOF preadv=no if compile_prog "" "" ; then @@ -2097,7 +2128,7 @@ if test "$opengl" != "no" ; then #include <X11/Xlib.h> #include <GL/gl.h> #include <GL/glx.h> -int main(void) { GL_VERSION; return 0; } +int main(void) { return GL_VERSION != 0; } EOF if compile_prog "" "-lGL" ; then opengl=yes @@ -2228,7 +2259,7 @@ cat > $TMPC << EOF int main(void) { - int len, fd; + int len, fd = 0; len = tee(STDIN_FILENO, STDOUT_FILENO, INT_MAX, SPLICE_F_NONBLOCK); splice(STDIN_FILENO, NULL, fd, NULL, len, SPLICE_F_MOVE); return 0; @@ -2242,7 +2273,6 @@ fi # signalfd probe signalfd="no" cat > $TMPC << EOF -#define _GNU_SOURCE #include <unistd.h> #include <sys/syscall.h> #include <signal.h> @@ -2260,8 +2290,7 @@ cat > $TMPC << EOF int main(void) { - int efd = eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); - return 0; + return eventfd(0, EFD_NONBLOCK | EFD_CLOEXEC); } EOF if compile_prog "" "" ; then @@ -2361,8 +2390,7 @@ int main(void) * warning but not an error, and will proceed to fail the * qemu compile where we compile with -Werror.) */ - epoll_create1; - return 0; + return epoll_create1 == epoll_create1; } EOF if compile_prog "$ARCH_CFLAGS" "" ; then @@ -2441,7 +2469,7 @@ fi cat > $TMPC <<EOF #include <signal.h> #include <time.h> -int main(void) { clockid_t id; return clock_gettime(id, NULL); } +int main(void) { return clock_gettime(CLOCK_REALTIME, NULL); } EOF if compile_prog "" "" ; then @@ -2651,7 +2679,7 @@ ucontext_coroutine=no if test "$darwin" != "yes"; then cat > $TMPC << EOF #include <ucontext.h> -int main(void) { makecontext(0, 0, 0); } +int main(void) { makecontext(0, 0, 0); return 0; } EOF if compile_prog "" "" ; then ucontext_coroutine=yes @@ -2664,7 +2692,7 @@ fi open_by_hande_at=no cat > $TMPC << EOF #include <fcntl.h> -int main(void) { struct file_handle fh; open_by_handle_at(0, &fh, 0); } +int main(void) { struct file_handle fh; return open_by_handle_at(0, &fh, 0); } EOF if compile_prog "" "" ; then open_by_handle_at=yes @@ -2677,6 +2705,7 @@ linux_magic_h=no cat > $TMPC << EOF #include <linux/magic.h> int main(void) { + return 0; } EOF if compile_prog "" "" ; then diff --git a/coroutine-ucontext.c b/coroutine-ucontext.c index 2b8d3e9c12..3d01075b06 100644 --- a/coroutine-ucontext.c +++ b/coroutine-ucontext.c @@ -35,6 +35,10 @@ enum { POOL_MAX_SIZE = 64, }; +/** Free list to speed up creation */ +static QLIST_HEAD(, Coroutine) pool = QLIST_HEAD_INITIALIZER(pool); +static unsigned int pool_size; + typedef struct { Coroutine base; void *stack; @@ -48,10 +52,6 @@ typedef struct { /** Currently executing coroutine */ Coroutine *current; - /** Free list to speed up creation */ - QLIST_HEAD(, Coroutine) pool; - unsigned int pool_size; - /** The default coroutine */ CoroutineUContext leader; } CoroutineThreadState; @@ -75,7 +75,6 @@ static CoroutineThreadState *coroutine_get_thread_state(void) if (!s) { s = g_malloc0(sizeof(*s)); s->current = &s->leader.base; - QLIST_INIT(&s->pool); pthread_setspecific(thread_state_key, s); } return s; @@ -84,14 +83,19 @@ static CoroutineThreadState *coroutine_get_thread_state(void) static void qemu_coroutine_thread_cleanup(void *opaque) { CoroutineThreadState *s = opaque; + + g_free(s); +} + +static void __attribute__((destructor)) coroutine_cleanup(void) +{ Coroutine *co; Coroutine *tmp; - QLIST_FOREACH_SAFE(co, &s->pool, pool_next, tmp) { + QLIST_FOREACH_SAFE(co, &pool, pool_next, tmp) { g_free(DO_UPCAST(CoroutineUContext, base, co)->stack); g_free(co); } - g_free(s); } static void __attribute__((constructor)) coroutine_init(void) @@ -169,13 +173,12 @@ static Coroutine *coroutine_new(void) Coroutine *qemu_coroutine_new(void) { - CoroutineThreadState *s = coroutine_get_thread_state(); Coroutine *co; - co = QLIST_FIRST(&s->pool); + co = QLIST_FIRST(&pool); if (co) { QLIST_REMOVE(co, pool_next); - s->pool_size--; + pool_size--; } else { co = coroutine_new(); } @@ -184,13 +187,12 @@ Coroutine *qemu_coroutine_new(void) void qemu_coroutine_delete(Coroutine *co_) { - CoroutineThreadState *s = coroutine_get_thread_state(); CoroutineUContext *co = DO_UPCAST(CoroutineUContext, base, co_); - if (s->pool_size < POOL_MAX_SIZE) { - QLIST_INSERT_HEAD(&s->pool, &co->base, pool_next); + if (pool_size < POOL_MAX_SIZE) { + QLIST_INSERT_HEAD(&pool, &co->base, pool_next); co->base.caller = NULL; - s->pool_size++; + pool_size++; return; } @@ -217,7 +217,10 @@ void qemu_iovec_destroy(QEMUIOVector *qiov) { assert(qiov->nalloc != -1); + qemu_iovec_reset(qiov); g_free(qiov->iov); + qiov->nalloc = 0; + qiov->iov = NULL; } void qemu_iovec_reset(QEMUIOVector *qiov) diff --git a/dma-helpers.c b/dma-helpers.c index 9d6b6fa1fd..f08cdb5454 100644 --- a/dma-helpers.c +++ b/dma-helpers.c @@ -142,9 +142,7 @@ static void dma_bdrv_cb(void *opaque, int ret) dbs->acb = dbs->io_func(dbs->bs, dbs->sector_num, &dbs->iov, dbs->iov.size / 512, dma_bdrv_cb, dbs); - if (!dbs->acb) { - dma_complete(dbs, -EIO); - } + assert(dbs->acb); } static void dma_aio_cancel(BlockDriverAIOCB *acb) diff --git a/docs/migration.txt b/docs/migration.txt index 4848c1e52d..f3ddd2f1a8 100644 --- a/docs/migration.txt +++ b/docs/migration.txt @@ -219,6 +219,18 @@ The functions to do that are inside a vmstate definition, and are called: Example: You can look at hpet.c, that uses the three function to massage the state that is transferred. +If you use memory API functions that update memory layout outside +initialization (i.e., in response to a guest action), this is a strong +indication that you need to call these functions in a post_load callback. +Examples of such memory API functions are: + + - memory_region_add_subregion() + - memory_region_del_subregion() + - memory_region_set_readonly() + - memory_region_set_enabled() + - memory_region_set_address() + - memory_region_set_alias_offset() + === Subsections === The use of version_id allows to be able to migrate from older versions diff --git a/docs/specs/qcow2.txt b/docs/specs/qcow2.txt index e792953c8f..b6adcaddb7 100644 --- a/docs/specs/qcow2.txt +++ b/docs/specs/qcow2.txt @@ -253,7 +253,13 @@ Snapshot table entry: 36 - 39: Size of extra data in the table entry (used for future extensions of the format) - variable: Extra data for future extensions. Must be ignored. + variable: Extra data for future extensions. Unknown fields must be + ignored. Currently defined are (offset relative to snapshot + table entry): + + Byte 40 - 47: Size of the VM state in bytes. 0 if no VM + state is saved. If this field is present, + the 32-bit value in bytes 32-35 is ignored. variable: Unique ID string for the snapshot (not null terminated) diff --git a/hw/cirrus_vga.c b/hw/cirrus_vga.c index 1388a203eb..f7b1d3d785 100644 --- a/hw/cirrus_vga.c +++ b/hw/cirrus_vga.c @@ -205,7 +205,7 @@ typedef struct CirrusVGAState { bool linear_vram; /* vga.vram mapped over cirrus_linear_io */ MemoryRegion low_mem_container; /* container for 0xa0000-0xc0000 */ MemoryRegion low_mem; /* always mapped, overridden by: */ - MemoryRegion *cirrus_bank[2]; /* aliases at 0xa0000-0xb0000 */ + MemoryRegion cirrus_bank[2]; /* aliases at 0xa0000-0xb0000 */ uint32_t cirrus_addr_mask; uint32_t linear_mmio_mask; uint8_t cirrus_shadow_gr0; @@ -2363,40 +2363,16 @@ static const MemoryRegionOps cirrus_linear_bitblt_io_ops = { }, }; -static void unmap_bank(CirrusVGAState *s, unsigned bank) -{ - if (s->cirrus_bank[bank]) { - memory_region_del_subregion(&s->low_mem_container, - s->cirrus_bank[bank]); - memory_region_destroy(s->cirrus_bank[bank]); - g_free(s->cirrus_bank[bank]); - s->cirrus_bank[bank] = NULL; - } -} - static void map_linear_vram_bank(CirrusVGAState *s, unsigned bank) { - MemoryRegion *mr; - static const char *names[] = { "vga.bank0", "vga.bank1" }; - - if (!(s->cirrus_srcptr != s->cirrus_srcptr_end) + MemoryRegion *mr = &s->cirrus_bank[bank]; + bool enabled = !(s->cirrus_srcptr != s->cirrus_srcptr_end) && !((s->vga.sr[0x07] & 0x01) == 0) && !((s->vga.gr[0x0B] & 0x14) == 0x14) - && !(s->vga.gr[0x0B] & 0x02)) { - - mr = g_malloc(sizeof(*mr)); - memory_region_init_alias(mr, names[bank], &s->vga.vram, - s->cirrus_bank_base[bank], 0x8000); - memory_region_add_subregion_overlap( - &s->low_mem_container, - 0x8000 * bank, - mr, - 1); - unmap_bank(s, bank); - s->cirrus_bank[bank] = mr; - } else { - unmap_bank(s, bank); - } + && !(s->vga.gr[0x0B] & 0x02); + + memory_region_set_enabled(mr, enabled); + memory_region_set_alias_offset(mr, s->cirrus_bank_base[bank]); } static void map_linear_vram(CirrusVGAState *s) @@ -2415,8 +2391,8 @@ static void unmap_linear_vram(CirrusVGAState *s) s->linear_vram = false; memory_region_del_subregion(&s->pci_bar, &s->vga.vram); } - unmap_bank(s, 0); - unmap_bank(s, 1); + memory_region_set_enabled(&s->cirrus_bank[0], false); + memory_region_set_enabled(&s->cirrus_bank[1], false); } /* Compute the memory access functions */ @@ -2856,6 +2832,14 @@ static void cirrus_init_common(CirrusVGAState * s, int device_id, int is_pci, memory_region_init_io(&s->low_mem, &cirrus_vga_mem_ops, s, "cirrus-low-memory", 0x20000); memory_region_add_subregion(&s->low_mem_container, 0, &s->low_mem); + for (i = 0; i < 2; ++i) { + static const char *names[] = { "vga.bank0", "vga.bank1" }; + MemoryRegion *bank = &s->cirrus_bank[i]; + memory_region_init_alias(bank, names[i], &s->vga.vram, 0, 0x8000); + memory_region_set_enabled(bank, false); + memory_region_add_subregion_overlap(&s->low_mem_container, i * 0x8000, + bank, 1); + } memory_region_add_subregion_overlap(system_memory, isa_mem_base + 0x000a0000, &s->low_mem_container, diff --git a/hw/ide/atapi.c b/hw/ide/atapi.c index 8af1cfdd7e..0adb27b799 100644 --- a/hw/ide/atapi.c +++ b/hw/ide/atapi.c @@ -352,14 +352,8 @@ static void ide_atapi_cmd_read_dma_cb(void *opaque, int ret) s->bus->dma->aiocb = bdrv_aio_readv(s->bs, (int64_t)s->lba << 2, &s->bus->dma->qiov, n * 4, ide_atapi_cmd_read_dma_cb, s); - if (!s->bus->dma->aiocb) { - /* Note: media not present is the most likely case */ - ide_atapi_cmd_error(s, NOT_READY, - ASC_MEDIUM_NOT_PRESENT); - goto eot; - } - return; + eot: bdrv_acct_done(s->bs, &s->acct); s->bus->dma->ops->add_status(s->bus->dma, BM_STATUS_INT); diff --git a/hw/ide/core.c b/hw/ide/core.c index 49847bd3ea..56b219b504 100644 --- a/hw/ide/core.c +++ b/hw/ide/core.c @@ -493,7 +493,7 @@ void ide_sector_read(IDEState *s) } } -static void dma_buf_commit(IDEState *s, int is_write) +static void dma_buf_commit(IDEState *s) { qemu_sglist_destroy(&s->sg); } @@ -532,7 +532,7 @@ static int ide_handle_rw_error(IDEState *s, int error, int op) bdrv_iostatus_set_err(s->bs, error); } else { if (op & BM_STATUS_DMA_RETRY) { - dma_buf_commit(s, 0); + dma_buf_commit(s); ide_dma_error(s); } else { ide_rw_error(s); @@ -549,7 +549,6 @@ void ide_dma_cb(void *opaque, int ret) int n; int64_t sector_num; -handle_rw_error: if (ret < 0) { int op = BM_STATUS_DMA_RETRY; @@ -566,7 +565,7 @@ handle_rw_error: n = s->io_buffer_size >> 9; sector_num = ide_get_sector(s); if (n > 0) { - dma_buf_commit(s, ide_cmd_is_read(s)); + dma_buf_commit(s); sector_num += n; ide_set_sector(s, sector_num); s->nsector -= n; @@ -608,11 +607,6 @@ handle_rw_error: ide_issue_trim, ide_dma_cb, s, true); break; } - - if (!s->bus->dma->aiocb) { - ret = -1; - goto handle_rw_error; - } return; eot: @@ -718,18 +712,13 @@ static void ide_flush_cb(void *opaque, int ret) void ide_flush_cache(IDEState *s) { - BlockDriverAIOCB *acb; - if (s->bs == NULL) { ide_flush_cb(s, 0); return; } bdrv_acct_start(s->bs, &s->acct, 0, BDRV_ACCT_FLUSH); - acb = bdrv_aio_flush(s->bs, ide_flush_cb, s); - if (acb == NULL) { - ide_flush_cb(s, -EIO); - } + bdrv_aio_flush(s->bs, ide_flush_cb, s); } static void ide_cfata_metadata_inquiry(IDEState *s) diff --git a/hw/ide/macio.c b/hw/ide/macio.c index c09d2e0a35..abbc41b59e 100644 --- a/hw/ide/macio.c +++ b/hw/ide/macio.c @@ -84,13 +84,6 @@ static void pmac_ide_atapi_transfer_cb(void *opaque, int ret) m->aiocb = dma_bdrv_read(s->bs, &s->sg, (int64_t)(s->lba << 2) + (s->io_buffer_index >> 9), pmac_ide_atapi_transfer_cb, io); - if (!m->aiocb) { - qemu_sglist_destroy(&s->sg); - /* Note: media not present is the most likely case */ - ide_atapi_cmd_error(s, NOT_READY, - ASC_MEDIUM_NOT_PRESENT); - goto done; - } return; done: @@ -159,10 +152,8 @@ static void pmac_ide_transfer_cb(void *opaque, int ret) ide_issue_trim, pmac_ide_transfer_cb, s, true); break; } - - if (!m->aiocb) - pmac_ide_transfer_cb(io, -1); return; + done: if (s->dma_cmd == IDE_DMA_READ || s->dma_cmd == IDE_DMA_WRITE) { bdrv_acct_done(s->bs, &s->acct); diff --git a/hw/pc_piix.c b/hw/pc_piix.c index 166c2fc25a..b9bb09d1e0 100644 --- a/hw/pc_piix.c +++ b/hw/pc_piix.c @@ -321,6 +321,14 @@ static QEMUMachine pc_machine_v1_0 = { .is_default = 1, }; +static QEMUMachine pc_machine_v0_15 = { + .name = "pc-0.15", + .desc = "Standard PC", + .init = pc_init_pci, + .max_cpus = 255, + .is_default = 1, +}; + static QEMUMachine pc_machine_v0_14 = { .name = "pc-0.14", .desc = "Standard PC", @@ -335,6 +343,22 @@ static QEMUMachine pc_machine_v0_14 = { .driver = "qxl-vga", .property = "revision", .value = stringify(2), + },{ + .driver = "virtio-blk-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-serial-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-net-pci", + .property = "event_idx", + .value = "off", + },{ + .driver = "virtio-balloon-pci", + .property = "event_idx", + .value = "off", }, { /* end of list */ } }, @@ -375,6 +399,10 @@ static QEMUMachine pc_machine_v0_13 = { .property = "event_idx", .value = "off", },{ + .driver = "virtio-balloon-pci", + .property = "event_idx", + .value = "off", + },{ .driver = "AC97", .property = "use_broken_id", .value = stringify(1), @@ -422,6 +450,10 @@ static QEMUMachine pc_machine_v0_12 = { .property = "event_idx", .value = "off", },{ + .driver = "virtio-balloon-pci", + .property = "event_idx", + .value = "off", + },{ .driver = "AC97", .property = "use_broken_id", .value = stringify(1), @@ -477,6 +509,10 @@ static QEMUMachine pc_machine_v0_11 = { .property = "event_idx", .value = "off", },{ + .driver = "virtio-balloon-pci", + .property = "event_idx", + .value = "off", + },{ .driver = "AC97", .property = "use_broken_id", .value = stringify(1), @@ -544,6 +580,10 @@ static QEMUMachine pc_machine_v0_10 = { .property = "event_idx", .value = "off", },{ + .driver = "virtio-balloon-pci", + .property = "event_idx", + .value = "off", + },{ .driver = "AC97", .property = "use_broken_id", .value = stringify(1), @@ -572,6 +612,7 @@ static QEMUMachine xenfv_machine = { static void pc_machine_init(void) { qemu_register_machine(&pc_machine_v1_0); + qemu_register_machine(&pc_machine_v0_15); qemu_register_machine(&pc_machine_v0_14); qemu_register_machine(&pc_machine_v0_13); qemu_register_machine(&pc_machine_v0_12); diff --git a/hw/piix_pci.c b/hw/piix_pci.c index d785d4ba07..43c85aa3d8 100644 --- a/hw/piix_pci.c +++ b/hw/piix_pci.c @@ -81,7 +81,6 @@ struct PCII440FXState { PAMMemoryRegion pam_regions[13]; MemoryRegion smram_region; uint8_t smm_enabled; - bool smram_enabled; PIIX3State *piix3; }; @@ -141,6 +140,7 @@ static void i440fx_update_memory_mappings(PCII440FXState *d) { int i, r; uint32_t smram; + bool smram_enabled; memory_region_transaction_begin(); update_pam(d, 0xf0000, 0x100000, (d->dev.config[I440FX_PAM] >> 4) & 3, @@ -151,18 +151,8 @@ static void i440fx_update_memory_mappings(PCII440FXState *d) &d->pam_regions[i+1]); } smram = d->dev.config[I440FX_SMRAM]; - if ((d->smm_enabled && (smram & 0x08)) || (smram & 0x40)) { - if (!d->smram_enabled) { - memory_region_del_subregion(d->system_memory, &d->smram_region); - d->smram_enabled = true; - } - } else { - if (d->smram_enabled) { - memory_region_add_subregion_overlap(d->system_memory, 0xa0000, - &d->smram_region, 1); - d->smram_enabled = false; - } - } + smram_enabled = (d->smm_enabled && (smram & 0x08)) || (smram & 0x40); + memory_region_set_enabled(&d->smram_region, !smram_enabled); memory_region_transaction_commit(); } @@ -308,7 +298,9 @@ static PCIBus *i440fx_common_init(const char *device_name, } memory_region_init_alias(&f->smram_region, "smram-region", f->pci_address_space, 0xa0000, 0x20000); - f->smram_enabled = true; + memory_region_add_subregion_overlap(f->system_memory, 0xa0000, + &f->smram_region, 1); + memory_region_set_enabled(&f->smram_region, false); /* Xen supports additional interrupt routes from the PCI devices to * the IOAPIC: the four pins of each PCI device on the bus are also @@ -324,9 +316,8 @@ static PCIBus *i440fx_common_init(const char *device_name, pci_create_simple_multifunction(b, -1, true, "PIIX3")); pci_bus_irqs(b, piix3_set_irq, pci_slot_get_pirq, piix3, PIIX_NUM_PIRQS); - - qdev_property_add_child(dev, "piix3", &piix3->dev.qdev, NULL); } + qdev_property_add_child(dev, "piix3", &piix3->dev.qdev, NULL); piix3->pic = pic; (*pi440fx_state)->piix3 = piix3; diff --git a/hw/scsi-disk.c b/hw/scsi-disk.c index 673948c51f..505accdde5 100644 --- a/hw/scsi-disk.c +++ b/hw/scsi-disk.c @@ -217,9 +217,6 @@ static void scsi_read_data(SCSIRequest *req) bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_READ); r->req.aiocb = bdrv_aio_readv(s->qdev.conf.bs, r->sector, &r->qiov, n, scsi_read_complete, r); - if (r->req.aiocb == NULL) { - scsi_read_complete(r, -EIO); - } } /* @@ -327,9 +324,6 @@ static void scsi_write_data(SCSIRequest *req) bdrv_acct_start(s->qdev.conf.bs, &r->acct, n * BDRV_SECTOR_SIZE, BDRV_ACCT_WRITE); r->req.aiocb = bdrv_aio_writev(s->qdev.conf.bs, r->sector, &r->qiov, n, scsi_write_complete, r); - if (r->req.aiocb == NULL) { - scsi_write_complete(r, -ENOMEM); - } } else { /* Called for the first time. Ask the driver to send us more data. */ scsi_write_complete(r, 0); @@ -1332,9 +1326,6 @@ static int32_t scsi_send_command(SCSIRequest *req, uint8_t *buf) scsi_req_ref(&r->req); bdrv_acct_start(s->qdev.conf.bs, &r->acct, 0, BDRV_ACCT_FLUSH); r->req.aiocb = bdrv_aio_flush(s->qdev.conf.bs, scsi_flush_complete, r); - if (r->req.aiocb == NULL) { - scsi_flush_complete(r, -EIO); - } return 0; case READ_6: case READ_10: diff --git a/hw/scsi-generic.c b/hw/scsi-generic.c index e62044f395..6f7d3db775 100644 --- a/hw/scsi-generic.c +++ b/hw/scsi-generic.c @@ -152,10 +152,6 @@ static int execute_command(BlockDriverState *bdrv, r->io_header.flags |= SG_FLAG_DIRECT_IO; r->req.aiocb = bdrv_aio_ioctl(bdrv, SG_IO, &r->io_header, complete, r); - if (r->req.aiocb == NULL) { - BADF("execute_command: read failed !\n"); - return -ENOMEM; - } return 0; } diff --git a/hw/stellaris.c b/hw/stellaris.c index ce62a98158..7a73074982 100644 --- a/hw/stellaris.c +++ b/hw/stellaris.c @@ -621,6 +621,7 @@ static void ssys_reset(void *opaque) s->rcgc[0] = 1; s->scgc[0] = 1; s->dcgc[0] = 1; + ssys_calculate_system_clock(s); } static int stellaris_sys_post_load(void *opaque, int version_id) diff --git a/hw/virtio-blk.c b/hw/virtio-blk.c index 4b0d113ba8..ef27421d46 100644 --- a/hw/virtio-blk.c +++ b/hw/virtio-blk.c @@ -288,19 +288,13 @@ static void virtio_submit_multiwrite(BlockDriverState *bs, MultiReqBuffer *mrb) static void virtio_blk_handle_flush(VirtIOBlockReq *req, MultiReqBuffer *mrb) { - BlockDriverAIOCB *acb; - bdrv_acct_start(req->dev->bs, &req->acct, 0, BDRV_ACCT_FLUSH); /* * Make sure all outstanding writes are posted to the backing device. */ virtio_submit_multiwrite(req->dev->bs, mrb); - - acb = bdrv_aio_flush(req->dev->bs, virtio_blk_flush_complete, req); - if (!acb) { - virtio_blk_flush_complete(req, -EIO); - } + bdrv_aio_flush(req->dev->bs, virtio_blk_flush_complete, req); } static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb) @@ -340,7 +334,6 @@ static void virtio_blk_handle_write(VirtIOBlockReq *req, MultiReqBuffer *mrb) static void virtio_blk_handle_read(VirtIOBlockReq *req) { - BlockDriverAIOCB *acb; uint64_t sector; sector = ldq_p(&req->out->sector); @@ -355,13 +348,9 @@ static void virtio_blk_handle_read(VirtIOBlockReq *req) virtio_blk_rw_complete(req, -EIO); return; } - - acb = bdrv_aio_readv(req->dev->bs, sector, &req->qiov, - req->qiov.size / BDRV_SECTOR_SIZE, - virtio_blk_rw_complete, req); - if (!acb) { - virtio_blk_rw_complete(req, -EIO); - } + bdrv_aio_readv(req->dev->bs, sector, &req->qiov, + req->qiov.size / BDRV_SECTOR_SIZE, + virtio_blk_rw_complete, req); } static void virtio_blk_handle_request(VirtIOBlockReq *req, @@ -977,7 +977,8 @@ int kvm_cpu_exec(CPUState *env) ret = EXCP_INTERRUPT; break; } - DPRINTF("kvm run failed %s\n", strerror(-run_ret)); + fprintf(stderr, "error: kvm run failed %s\n", + strerror(-run_ret)); abort(); } diff --git a/linux-aio.c b/linux-aio.c index 1c635ef12d..d2fc2e7d02 100644 --- a/linux-aio.c +++ b/linux-aio.c @@ -166,8 +166,6 @@ BlockDriverAIOCB *laio_submit(BlockDriverState *bs, void *aio_ctx, int fd, off_t offset = sector_num * 512; laiocb = qemu_aio_get(&laio_pool, bs, cb, opaque); - if (!laiocb) - return NULL; laiocb->nbytes = nb_sectors * 512; laiocb->ctx = s; laiocb->ret = -EINPROGRESS; @@ -22,6 +22,7 @@ #include "exec-obsolete.h" unsigned memory_region_transaction_depth = 0; +static bool memory_region_update_pending = false; typedef struct AddrRange AddrRange; @@ -531,6 +532,10 @@ static void render_memory_region(FlatView *view, FlatRange fr; AddrRange tmp; + if (!mr->enabled) { + return; + } + int128_addto(&base, int128_make64(mr->addr)); readonly |= mr->readonly; @@ -753,9 +758,14 @@ static void address_space_update_topology(AddressSpace *as) address_space_update_ioeventfds(as); } -static void memory_region_update_topology(void) +static void memory_region_update_topology(MemoryRegion *mr) { if (memory_region_transaction_depth) { + memory_region_update_pending |= !mr || mr->enabled; + return; + } + + if (mr && !mr->enabled) { return; } @@ -765,6 +775,8 @@ static void memory_region_update_topology(void) if (address_space_io.root) { address_space_update_topology(&address_space_io); } + + memory_region_update_pending = false; } void memory_region_transaction_begin(void) @@ -776,7 +788,9 @@ void memory_region_transaction_commit(void) { assert(memory_region_transaction_depth); --memory_region_transaction_depth; - memory_region_update_topology(); + if (!memory_region_transaction_depth && memory_region_update_pending) { + memory_region_update_topology(NULL); + } } static void memory_region_destructor_none(MemoryRegion *mr) @@ -816,6 +830,7 @@ void memory_region_init(MemoryRegion *mr, } mr->addr = 0; mr->offset = 0; + mr->enabled = true; mr->terminates = false; mr->readable = true; mr->readonly = false; @@ -1061,7 +1076,7 @@ void memory_region_set_log(MemoryRegion *mr, bool log, unsigned client) uint8_t mask = 1 << client; mr->dirty_log_mask = (mr->dirty_log_mask & ~mask) | (log * mask); - memory_region_update_topology(); + memory_region_update_topology(mr); } bool memory_region_get_dirty(MemoryRegion *mr, target_phys_addr_t addr, @@ -1093,7 +1108,7 @@ void memory_region_set_readonly(MemoryRegion *mr, bool readonly) { if (mr->readonly != readonly) { mr->readonly = readonly; - memory_region_update_topology(); + memory_region_update_topology(mr); } } @@ -1101,7 +1116,7 @@ void memory_region_rom_device_set_readable(MemoryRegion *mr, bool readable) { if (mr->readable != readable) { mr->readable = readable; - memory_region_update_topology(); + memory_region_update_topology(mr); } } @@ -1206,7 +1221,7 @@ void memory_region_add_eventfd(MemoryRegion *mr, memmove(&mr->ioeventfds[i+1], &mr->ioeventfds[i], sizeof(*mr->ioeventfds) * (mr->ioeventfd_nb-1 - i)); mr->ioeventfds[i] = mrfd; - memory_region_update_topology(); + memory_region_update_topology(mr); } void memory_region_del_eventfd(MemoryRegion *mr, @@ -1236,7 +1251,7 @@ void memory_region_del_eventfd(MemoryRegion *mr, --mr->ioeventfd_nb; mr->ioeventfds = g_realloc(mr->ioeventfds, sizeof(*mr->ioeventfds)*mr->ioeventfd_nb + 1); - memory_region_update_topology(); + memory_region_update_topology(mr); } static void memory_region_add_subregion_common(MemoryRegion *mr, @@ -1277,7 +1292,7 @@ static void memory_region_add_subregion_common(MemoryRegion *mr, } QTAILQ_INSERT_TAIL(&mr->subregions, subregion, subregions_link); done: - memory_region_update_topology(); + memory_region_update_topology(mr); } @@ -1306,19 +1321,63 @@ void memory_region_del_subregion(MemoryRegion *mr, assert(subregion->parent == mr); subregion->parent = NULL; QTAILQ_REMOVE(&mr->subregions, subregion, subregions_link); - memory_region_update_topology(); + memory_region_update_topology(mr); +} + +void memory_region_set_enabled(MemoryRegion *mr, bool enabled) +{ + if (enabled == mr->enabled) { + return; + } + mr->enabled = enabled; + memory_region_update_topology(NULL); +} + +void memory_region_set_address(MemoryRegion *mr, target_phys_addr_t addr) +{ + MemoryRegion *parent = mr->parent; + unsigned priority = mr->priority; + bool may_overlap = mr->may_overlap; + + if (addr == mr->addr || !parent) { + mr->addr = addr; + return; + } + + memory_region_transaction_begin(); + memory_region_del_subregion(parent, mr); + if (may_overlap) { + memory_region_add_subregion_overlap(parent, addr, mr, priority); + } else { + memory_region_add_subregion(parent, addr, mr); + } + memory_region_transaction_commit(); +} + +void memory_region_set_alias_offset(MemoryRegion *mr, target_phys_addr_t offset) +{ + target_phys_addr_t old_offset = mr->alias_offset; + + assert(mr->alias); + mr->alias_offset = offset; + + if (offset == old_offset || !mr->parent) { + return; + } + + memory_region_update_topology(mr); } void set_system_memory_map(MemoryRegion *mr) { address_space_memory.root = mr; - memory_region_update_topology(); + memory_region_update_topology(NULL); } void set_system_io_map(MemoryRegion *mr) { address_space_io.root = mr; - memory_region_update_topology(); + memory_region_update_topology(NULL); } typedef struct MemoryRegionList MemoryRegionList; @@ -123,6 +123,7 @@ struct MemoryRegion { bool terminates; bool readable; bool readonly; /* For RAM regions */ + bool enabled; MemoryRegion *alias; target_phys_addr_t alias_offset; unsigned priority; @@ -501,6 +502,44 @@ void memory_region_add_subregion_overlap(MemoryRegion *mr, void memory_region_del_subregion(MemoryRegion *mr, MemoryRegion *subregion); +/* + * memory_region_set_enabled: dynamically enable or disable a region + * + * Enables or disables a memory region. A disabled memory region + * ignores all accesses to itself and its subregions. It does not + * obscure sibling subregions with lower priority - it simply behaves as + * if it was removed from the hierarchy. + * + * Regions default to being enabled. + * + * @mr: the region to be updated + * @enabled: whether to enable or disable the region + */ +void memory_region_set_enabled(MemoryRegion *mr, bool enabled); + +/* + * memory_region_set_address: dynamically update the address of a region + * + * Dynamically updates the address of a region, relative to its parent. + * May be used on regions are currently part of a memory hierarchy. + * + * @mr: the region to be updated + * @addr: new address, relative to parent region + */ +void memory_region_set_address(MemoryRegion *mr, target_phys_addr_t addr); + +/* + * memory_region_set_alias_offset: dynamically update a memory alias's offset + * + * Dynamically updates the offset into the target region that an alias points + * to, as if the fourth argument to memory_region_init_alias() has changed. + * + * @mr: the #MemoryRegion to be updated; should be an alias. + * @offset: the new offset into the target memory region + */ +void memory_region_set_alias_offset(MemoryRegion *mr, + target_phys_addr_t offset); + /** * memory_region_transaction_begin: Start a transaction. * diff --git a/net/slirp.c b/net/slirp.c index 6646ecb1c8..18e07ba609 100644 --- a/net/slirp.c +++ b/net/slirp.c @@ -351,7 +351,7 @@ void net_slirp_hostfwd_remove(Monitor *mon, const QDict *qdict) host_addr, host_port); monitor_printf(mon, "host forwarding rule for %s %s\n", src_str, - err ? "removed" : "not found"); + err ? "not found" : "removed"); return; fail_syntax: diff --git a/posix-aio-compat.c b/posix-aio-compat.c index c380ec148c..cccb673d2e 100644 --- a/posix-aio-compat.c +++ b/posix-aio-compat.c @@ -611,8 +611,6 @@ BlockDriverAIOCB *paio_submit(BlockDriverState *bs, int fd, struct qemu_paiocb *acb; acb = qemu_aio_get(&raw_aio_pool, bs, cb, opaque); - if (!acb) - return NULL; acb->aio_type = type; acb->aio_fildes = fd; @@ -638,8 +636,6 @@ BlockDriverAIOCB *paio_ioctl(BlockDriverState *bs, int fd, struct qemu_paiocb *acb; acb = qemu_aio_get(&raw_aio_pool, bs, cb, opaque); - if (!acb) - return NULL; acb->aio_type = QEMU_AIO_IOCTL; acb->aio_fildes = fd; acb->aio_offset = 0; diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx index 4be00a5edd..49dce7c928 100644 --- a/qemu-img-cmds.hx +++ b/qemu-img-cmds.hx @@ -24,13 +24,13 @@ ETEXI DEF("commit", img_commit, "commit [-f fmt] [-t cache] filename") STEXI -@item commit [-f @var{fmt}] @var{filename} +@item commit [-f @var{fmt}] [-t @var{cache}] @var{filename} ETEXI DEF("convert", img_convert, "convert [-c] [-p] [-f fmt] [-t cache] [-O output_fmt] [-o options] [-s snapshot_name] [-S sparse_size] filename [filename2 [...]] output_filename") STEXI -@item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename} +@item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename} ETEXI DEF("info", img_info, @@ -48,7 +48,7 @@ ETEXI DEF("rebase", img_rebase, "rebase [-f fmt] [-t cache] [-p] [-u] -b backing_file [-F backing_fmt] filename") STEXI -@item rebase [-f @var{fmt}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename} +@item rebase [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename} ETEXI DEF("resize", img_resize, diff --git a/qemu-img.c b/qemu-img.c index 8bdae66490..01cc0d35ad 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -1420,6 +1420,8 @@ static int img_rebase(int argc, char **argv) */ if (!unsafe) { uint64_t num_sectors; + uint64_t old_backing_num_sectors; + uint64_t new_backing_num_sectors; uint64_t sector; int n; uint8_t * buf_old; @@ -1430,6 +1432,8 @@ static int img_rebase(int argc, char **argv) buf_new = qemu_blockalign(bs, IO_BUF_SIZE); bdrv_get_geometry(bs, &num_sectors); + bdrv_get_geometry(bs_old_backing, &old_backing_num_sectors); + bdrv_get_geometry(bs_new_backing, &new_backing_num_sectors); local_progress = (float)100 / (num_sectors / MIN(num_sectors, IO_BUF_SIZE / 512)); @@ -1448,16 +1452,36 @@ static int img_rebase(int argc, char **argv) continue; } - /* Read old and new backing file */ - ret = bdrv_read(bs_old_backing, sector, buf_old, n); - if (ret < 0) { - error_report("error while reading from old backing file"); - goto out; + /* + * Read old and new backing file and take into consideration that + * backing files may be smaller than the COW image. + */ + if (sector >= old_backing_num_sectors) { + memset(buf_old, 0, n * BDRV_SECTOR_SIZE); + } else { + if (sector + n > old_backing_num_sectors) { + n = old_backing_num_sectors - sector; + } + + ret = bdrv_read(bs_old_backing, sector, buf_old, n); + if (ret < 0) { + error_report("error while reading from old backing file"); + goto out; + } } - ret = bdrv_read(bs_new_backing, sector, buf_new, n); - if (ret < 0) { - error_report("error while reading from new backing file"); - goto out; + + if (sector >= new_backing_num_sectors) { + memset(buf_new, 0, n * BDRV_SECTOR_SIZE); + } else { + if (sector + n > new_backing_num_sectors) { + n = new_backing_num_sectors - sector; + } + + ret = bdrv_read(bs_new_backing, sector, buf_new, n); + if (ret < 0) { + error_report("error while reading from new backing file"); + goto out; + } } /* If they differ, we need to write to the COW file */ diff --git a/qemu-img.texi b/qemu-img.texi index 70fa321dff..b2ca3a542c 100644 --- a/qemu-img.texi +++ b/qemu-img.texi @@ -45,6 +45,10 @@ indicates the consecutive number of bytes that must contain only zeros for qemu-img to create a sparse image during conversion. This value is rounded down to the nearest 512 bytes. You may use the common size suffixes like @code{k} for kilobytes. +@item -t @var{cache} +specifies the cache mode that should be used with the (destination) file. See +the documentation of the emulator's @code{-drive cache=...} option for allowed +values. @end table Parameters to snapshot subcommand: @@ -87,11 +91,11 @@ this case. @var{backing_file} will never be modified unless you use the 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. -@item commit [-f @var{fmt}] @var{filename} +@item commit [-f @var{fmt}] [-t @var{cache}] @var{filename} Commit the changes recorded in @var{filename} in its base image. -@item convert [-c] [-p] [-f @var{fmt}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename} +@item convert [-c] [-p] [-f @var{fmt}] [-t @var{cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_name}] [-S @var{sparse_size}] @var{filename} [@var{filename2} [...]] @var{output_filename} Convert the disk image @var{filename} or a snapshot @var{snapshot_name} to disk image @var{output_filename} using format @var{output_fmt}. It can be optionally compressed (@code{-c} @@ -121,7 +125,7 @@ they are displayed too. List, apply, create or delete snapshots in image @var{filename}. -@item rebase [-f @var{fmt}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename} +@item rebase [-f @var{fmt}] [-t @var{cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename} Changes the backing file of an image. Only the formats @code{qcow2} and @code{qed} support changing the backing file. @@ -244,14 +244,10 @@ static void aio_rw_done(void *opaque, int ret) static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total) { - BlockDriverAIOCB *acb; int async_ret = NOT_DONE; - acb = bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9, - aio_rw_done, &async_ret); - if (!acb) { - return -EIO; - } + bdrv_aio_readv(bs, offset >> 9, qiov, qiov->size >> 9, + aio_rw_done, &async_ret); while (async_ret == NOT_DONE) { qemu_aio_wait(); } @@ -262,15 +258,10 @@ static int do_aio_readv(QEMUIOVector *qiov, int64_t offset, int *total) static int do_aio_writev(QEMUIOVector *qiov, int64_t offset, int *total) { - BlockDriverAIOCB *acb; int async_ret = NOT_DONE; - acb = bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9, - aio_rw_done, &async_ret); - if (!acb) { - return -EIO; - } - + bdrv_aio_writev(bs, offset >> 9, qiov, qiov->size >> 9, + aio_rw_done, &async_ret); while (async_ret == NOT_DONE) { qemu_aio_wait(); } @@ -1151,7 +1142,6 @@ static int aio_read_f(int argc, char **argv) { int nr_iov, c; struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx)); - BlockDriverAIOCB *acb; while ((c = getopt(argc, argv, "CP:qv")) != EOF) { switch (c) { @@ -1206,14 +1196,8 @@ static int aio_read_f(int argc, char **argv) } gettimeofday(&ctx->t1, NULL); - acb = bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov, - ctx->qiov.size >> 9, aio_read_done, ctx); - if (!acb) { - free(ctx->buf); - free(ctx); - return -EIO; - } - + bdrv_aio_readv(bs, ctx->offset >> 9, &ctx->qiov, + ctx->qiov.size >> 9, aio_read_done, ctx); return 0; } @@ -1254,7 +1238,6 @@ static int aio_write_f(int argc, char **argv) int nr_iov, c; int pattern = 0xcd; struct aio_ctx *ctx = calloc(1, sizeof(struct aio_ctx)); - BlockDriverAIOCB *acb; while ((c = getopt(argc, argv, "CqP:")) != EOF) { switch (c) { @@ -1305,14 +1288,8 @@ static int aio_write_f(int argc, char **argv) } gettimeofday(&ctx->t1, NULL); - acb = bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov, - ctx->qiov.size >> 9, aio_write_done, ctx); - if (!acb) { - free(ctx->buf); - free(ctx); - return -EIO; - } - + bdrv_aio_writev(bs, ctx->offset >> 9, &ctx->qiov, + ctx->qiov.size >> 9, aio_write_done, ctx); return 0; } @@ -2002,7 +2002,7 @@ void do_savevm(Monitor *mon, const QDict *qdict) int ret; QEMUFile *f; int saved_vm_running; - uint32_t vm_state_size; + uint64_t vm_state_size; #ifdef _WIN32 struct _timeb tb; struct tm *ptm; diff --git a/trace-events b/trace-events index bf1cf57032..514849aed8 100644 --- a/trace-events +++ b/trace-events @@ -59,8 +59,6 @@ virtio_console_chr_event(unsigned int port, int event) "port %u, event %d" bdrv_open_common(void *bs, const char *filename, int flags, const char *format_name) "bs %p filename \"%s\" flags %#x format_name \"%s\"" multiwrite_cb(void *mcb, int ret) "mcb %p ret %d" bdrv_aio_multiwrite(void *mcb, int num_callbacks, int num_reqs) "mcb %p num_callbacks %d num_reqs %d" -bdrv_aio_multiwrite_earlyfail(void *mcb) "mcb %p" -bdrv_aio_multiwrite_latefail(void *mcb, int i) "mcb %p i %d" bdrv_aio_discard(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p" bdrv_aio_flush(void *bs, void *opaque) "bs %p opaque %p" bdrv_aio_readv(void *bs, int64_t sector_num, int nb_sectors, void *opaque) "bs %p sector_num %"PRId64" nb_sectors %d opaque %p" |