提交 f78b6f9b 编写于 作者: P Peter Maydell

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

Block layer patches

# gpg: Signature made Tue 23 Jan 2018 12:38:36 GMT
# 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: (29 commits)
  iotests: Disable some tests for compat=0.10
  iotests: Split 177 into two parts for compat=0.10
  iotests: Make 059 pass on machines with little RAM
  iotests: Filter compat-dependent info in 198
  iotests: Make 191 work with qcow2 options
  iotests: Make 184 image-less
  iotests: Make 089 compatible with compat=0.10
  iotests: Fix 067 for compat=0.10
  iotests: Fix 059's reference output
  iotests: Fix 051 for compat=0.10
  iotests: Fix 020 for vmdk
  iotests: Skip 103 for refcount_bits=1
  iotests: Forbid 020 for non-file protocols
  iotests: Drop format-specific in _filter_img_info
  iotests: Fix _img_info for backslashes
  block/vmdk: Add blkdebug events
  block/qcow: Add blkdebug events
  qcow2: No persistent dirty bitmaps for compat=0.10
  block/vmdk: Fix , instead of ; at end of line
  qemu-iotests: Fix locking issue in 102
  ...
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
......@@ -379,6 +379,7 @@ static int get_cluster_offset(BlockDriverState *bs,
/* update the L1 entry */
s->l1_table[l1_index] = l2_offset;
tmp = cpu_to_be64(l2_offset);
BLKDBG_EVENT(bs->file, BLKDBG_L1_UPDATE);
ret = bdrv_pwrite_sync(bs->file,
s->l1_table_offset + l1_index * sizeof(tmp),
&tmp, sizeof(tmp));
......@@ -409,6 +410,7 @@ static int get_cluster_offset(BlockDriverState *bs,
}
}
l2_table = s->l2_cache + (min_index << s->l2_bits);
BLKDBG_EVENT(bs->file, BLKDBG_L2_LOAD);
if (new_l2_table) {
memset(l2_table, 0, s->l2_size * sizeof(uint64_t));
ret = bdrv_pwrite_sync(bs->file, l2_offset, l2_table,
......@@ -432,6 +434,7 @@ static int get_cluster_offset(BlockDriverState *bs,
((cluster_offset & QCOW_OFLAG_COMPRESSED) && allocate == 1)) {
if (!allocate)
return 0;
BLKDBG_EVENT(bs->file, BLKDBG_CLUSTER_ALLOC);
/* allocate a new cluster */
if ((cluster_offset & QCOW_OFLAG_COMPRESSED) &&
(n_end - n_start) < s->cluster_sectors) {
......@@ -447,6 +450,7 @@ static int get_cluster_offset(BlockDriverState *bs,
}
cluster_offset = QEMU_ALIGN_UP(cluster_offset, s->cluster_size);
/* write the cluster content */
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
ret = bdrv_pwrite(bs->file, cluster_offset, s->cluster_cache,
s->cluster_size);
if (ret < 0) {
......@@ -486,6 +490,7 @@ static int get_cluster_offset(BlockDriverState *bs,
NULL) < 0) {
return -EIO;
}
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
ret = bdrv_pwrite(bs->file,
cluster_offset + i * 512,
s->cluster_data, 512);
......@@ -503,6 +508,11 @@ static int get_cluster_offset(BlockDriverState *bs,
/* update L2 table */
tmp = cpu_to_be64(cluster_offset);
l2_table[l2_index] = tmp;
if (allocate == 2) {
BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE_COMPRESSED);
} else {
BLKDBG_EVENT(bs->file, BLKDBG_L2_UPDATE);
}
ret = bdrv_pwrite_sync(bs->file, l2_offset + l2_index * sizeof(tmp),
&tmp, sizeof(tmp));
if (ret < 0) {
......@@ -579,6 +589,7 @@ static int decompress_cluster(BlockDriverState *bs, uint64_t cluster_offset)
if (s->cluster_cache_offset != coffset) {
csize = cluster_offset >> (63 - s->cluster_bits);
csize &= (s->cluster_size - 1);
BLKDBG_EVENT(bs->file, BLKDBG_READ_COMPRESSED);
ret = bdrv_pread(bs->file, coffset, s->cluster_data, csize);
if (ret != csize)
return -1;
......@@ -635,6 +646,8 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
hd_iov.iov_len = n * 512;
qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
qemu_co_mutex_unlock(&s->lock);
/* qcow2 emits this on bs->file instead of bs->backing */
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
ret = bdrv_co_readv(bs->backing, sector_num, n, &hd_qiov);
qemu_co_mutex_lock(&s->lock);
if (ret < 0) {
......@@ -661,6 +674,7 @@ static coroutine_fn int qcow_co_readv(BlockDriverState *bs, int64_t sector_num,
hd_iov.iov_len = n * 512;
qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
qemu_co_mutex_unlock(&s->lock);
BLKDBG_EVENT(bs->file, BLKDBG_READ_AIO);
ret = bdrv_co_readv(bs->file,
(cluster_offset >> 9) + index_in_cluster,
n, &hd_qiov);
......@@ -754,6 +768,7 @@ static coroutine_fn int qcow_co_writev(BlockDriverState *bs, int64_t sector_num,
hd_iov.iov_len = n * 512;
qemu_iovec_init_external(&hd_qiov, &hd_iov, 1);
qemu_co_mutex_unlock(&s->lock);
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_AIO);
ret = bdrv_co_writev(bs->file,
(cluster_offset >> 9) + index_in_cluster,
n, &hd_qiov);
......@@ -1048,6 +1063,7 @@ qcow_co_pwritev_compressed(BlockDriverState *bs, uint64_t offset,
.iov_len = out_len,
};
qemu_iovec_init_external(&hd_qiov, &iov, 1);
BLKDBG_EVENT(bs->file, BLKDBG_WRITE_COMPRESSED);
ret = bdrv_co_pwritev(bs->file, cluster_offset, out_len, &hd_qiov, 0);
if (ret < 0) {
goto fail;
......
......@@ -1449,6 +1449,16 @@ bool qcow2_can_store_new_dirty_bitmap(BlockDriverState *bs,
bool found;
Qcow2BitmapList *bm_list;
if (s->qcow_version < 3) {
/* Without autoclear_features, we would always have to assume
* that a program without persistent dirty bitmap support has
* accessed this qcow2 file when opening it, and would thus
* have to drop all dirty bitmaps (defeating their purpose).
*/
error_setg(errp, "Cannot store dirty bitmaps in qcow2 v2 files");
goto fail;
}
if (check_constraints_on_bitmap(bs, name, granularity, errp) != 0) {
goto fail;
}
......
......@@ -1508,7 +1508,7 @@ enum {
static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
void **refcount_table,
int64_t *refcount_table_size, int64_t l2_offset,
int flags)
int flags, BdrvCheckMode fix)
{
BDRVQcow2State *s = bs->opaque;
uint64_t *l2_table, l2_entry;
......@@ -1579,6 +1579,57 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
next_contiguous_offset = offset + s->cluster_size;
}
/* Correct offsets are cluster aligned */
if (offset_into_cluster(s, offset)) {
if (qcow2_get_cluster_type(l2_entry) ==
QCOW2_CLUSTER_ZERO_ALLOC)
{
fprintf(stderr, "%s offset=%" PRIx64 ": Preallocated zero "
"cluster is not properly aligned; L2 entry "
"corrupted.\n",
fix & BDRV_FIX_ERRORS ? "Repairing" : "ERROR",
offset);
if (fix & BDRV_FIX_ERRORS) {
uint64_t l2e_offset =
l2_offset + (uint64_t)i * sizeof(uint64_t);
l2_entry = QCOW_OFLAG_ZERO;
l2_table[i] = cpu_to_be64(l2_entry);
ret = qcow2_pre_write_overlap_check(bs,
QCOW2_OL_ACTIVE_L2 | QCOW2_OL_INACTIVE_L2,
l2e_offset, sizeof(uint64_t));
if (ret < 0) {
fprintf(stderr, "ERROR: Overlap check failed\n");
res->check_errors++;
/* Something is seriously wrong, so abort checking
* this L2 table */
goto fail;
}
ret = bdrv_pwrite_sync(bs->file, l2e_offset,
&l2_table[i], sizeof(uint64_t));
if (ret < 0) {
fprintf(stderr, "ERROR: Failed to overwrite L2 "
"table entry: %s\n", strerror(-ret));
res->check_errors++;
/* Do not abort, continue checking the rest of this
* L2 table's entries */
} else {
res->corruptions_fixed++;
/* Skip marking the cluster as used
* (it is unused now) */
continue;
}
} else {
res->corruptions++;
}
} else {
fprintf(stderr, "ERROR offset=%" PRIx64 ": Data cluster is "
"not properly aligned; L2 entry corrupted.\n", offset);
res->corruptions++;
}
}
/* Mark cluster as used */
ret = qcow2_inc_refcounts_imrt(bs, res,
refcount_table, refcount_table_size,
......@@ -1586,13 +1637,6 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
if (ret < 0) {
goto fail;
}
/* Correct offsets are cluster aligned */
if (offset_into_cluster(s, offset)) {
fprintf(stderr, "ERROR offset=%" PRIx64 ": Cluster is not "
"properly aligned; L2 entry corrupted.\n", offset);
res->corruptions++;
}
break;
}
......@@ -1626,7 +1670,7 @@ static int check_refcounts_l1(BlockDriverState *bs,
void **refcount_table,
int64_t *refcount_table_size,
int64_t l1_table_offset, int l1_size,
int flags)
int flags, BdrvCheckMode fix)
{
BDRVQcow2State *s = bs->opaque;
uint64_t *l1_table = NULL, l2_offset, l1_size2;
......@@ -1681,7 +1725,8 @@ static int check_refcounts_l1(BlockDriverState *bs,
/* Process and check L2 entries */
ret = check_refcounts_l2(bs, res, refcount_table,
refcount_table_size, l2_offset, flags);
refcount_table_size, l2_offset, flags,
fix);
if (ret < 0) {
goto fail;
}
......@@ -1957,7 +2002,8 @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
/* current L1 table */
ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
s->l1_table_offset, s->l1_size, CHECK_FRAG_INFO);
s->l1_table_offset, s->l1_size, CHECK_FRAG_INFO,
fix);
if (ret < 0) {
return ret;
}
......@@ -1966,7 +2012,7 @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
for (i = 0; i < s->nb_snapshots; i++) {
sn = s->snapshots + i;
ret = check_refcounts_l1(bs, res, refcount_table, nb_clusters,
sn->l1_table_offset, sn->l1_size, 0);
sn->l1_table_offset, sn->l1_size, 0, fix);
if (ret < 0) {
return ret;
}
......
......@@ -302,9 +302,17 @@ static int qcow2_read_extensions(BlockDriverState *bs, uint64_t start_offset,
}
if (!(s->autoclear_features & QCOW2_AUTOCLEAR_BITMAPS)) {
warn_report("a program lacking bitmap support "
"modified this file, so all bitmaps are now "
"considered inconsistent");
if (s->qcow_version < 3) {
/* Let's be a bit more specific */
warn_report("This qcow2 v2 image contains bitmaps, but "
"they may have been modified by a program "
"without persistent bitmap support; so now "
"they must all be considered inconsistent");
} else {
warn_report("a program lacking bitmap support "
"modified this file, so all bitmaps are now "
"considered inconsistent");
}
error_printf("Some clusters may be leaked, "
"run 'qemu-img check -r' on the image "
"file to fix.");
......
......@@ -1075,6 +1075,8 @@ static int get_whole_cluster(BlockDriverState *bs,
/* Read backing data before skip range */
if (skip_start_bytes > 0) {
if (bs->backing) {
/* qcow2 emits this on bs->file instead of bs->backing */
BLKDBG_EVENT(extent->file, BLKDBG_COW_READ);
ret = bdrv_pread(bs->backing, offset, whole_grain,
skip_start_bytes);
if (ret < 0) {
......@@ -1082,6 +1084,7 @@ static int get_whole_cluster(BlockDriverState *bs,
goto exit;
}
}
BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE);
ret = bdrv_pwrite(extent->file, cluster_offset, whole_grain,
skip_start_bytes);
if (ret < 0) {
......@@ -1092,6 +1095,8 @@ static int get_whole_cluster(BlockDriverState *bs,
/* Read backing data after skip range */
if (skip_end_bytes < cluster_bytes) {
if (bs->backing) {
/* qcow2 emits this on bs->file instead of bs->backing */
BLKDBG_EVENT(extent->file, BLKDBG_COW_READ);
ret = bdrv_pread(bs->backing, offset + skip_end_bytes,
whole_grain + skip_end_bytes,
cluster_bytes - skip_end_bytes);
......@@ -1100,6 +1105,7 @@ static int get_whole_cluster(BlockDriverState *bs,
goto exit;
}
}
BLKDBG_EVENT(extent->file, BLKDBG_COW_WRITE);
ret = bdrv_pwrite(extent->file, cluster_offset + skip_end_bytes,
whole_grain + skip_end_bytes,
cluster_bytes - skip_end_bytes);
......@@ -1120,6 +1126,7 @@ static int vmdk_L2update(VmdkExtent *extent, VmdkMetaData *m_data,
{
offset = cpu_to_le32(offset);
/* update L2 table */
BLKDBG_EVENT(extent->file, BLKDBG_L2_UPDATE);
if (bdrv_pwrite_sync(extent->file,
((int64_t)m_data->l2_offset * 512)
+ (m_data->l2_index * sizeof(offset)),
......@@ -1218,6 +1225,7 @@ static int get_cluster_offset(BlockDriverState *bs,
}
}
l2_table = extent->l2_cache + (min_index * extent->l2_size);
BLKDBG_EVENT(extent->file, BLKDBG_L2_LOAD);
if (bdrv_pread(extent->file,
(int64_t)l2_offset * 512,
l2_table,
......@@ -1393,12 +1401,16 @@ static int vmdk_write_extent(VmdkExtent *extent, int64_t cluster_offset,
.iov_len = n_bytes,
};
qemu_iovec_init_external(&local_qiov, &iov, 1);
BLKDBG_EVENT(extent->file, BLKDBG_WRITE_COMPRESSED);
} else {
qemu_iovec_init(&local_qiov, qiov->niov);
qemu_iovec_concat(&local_qiov, qiov, qiov_offset, n_bytes);
BLKDBG_EVENT(extent->file, BLKDBG_WRITE_AIO);
}
write_offset = cluster_offset + offset_in_cluster,
write_offset = cluster_offset + offset_in_cluster;
ret = bdrv_co_pwritev(extent->file, write_offset, n_bytes,
&local_qiov, 0);
......@@ -1437,6 +1449,7 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
if (!extent->compressed) {
BLKDBG_EVENT(extent->file, BLKDBG_READ_AIO);
ret = bdrv_co_preadv(extent->file,
cluster_offset + offset_in_cluster, bytes,
qiov, 0);
......@@ -1450,6 +1463,7 @@ static int vmdk_read_extent(VmdkExtent *extent, int64_t cluster_offset,
buf_bytes = cluster_bytes * 2;
cluster_buf = g_malloc(buf_bytes);
uncomp_buf = g_malloc(cluster_bytes);
BLKDBG_EVENT(extent->file, BLKDBG_READ_COMPRESSED);
ret = bdrv_pread(extent->file,
cluster_offset,
cluster_buf, buf_bytes);
......@@ -1527,6 +1541,8 @@ vmdk_co_preadv(BlockDriverState *bs, uint64_t offset, uint64_t bytes,
qemu_iovec_reset(&local_qiov);
qemu_iovec_concat(&local_qiov, qiov, bytes_done, n_bytes);
/* qcow2 emits this on bs->file instead of bs->backing */
BLKDBG_EVENT(bs->file, BLKDBG_READ_BACKING_AIO);
ret = bdrv_co_preadv(bs->backing, offset, n_bytes,
&local_qiov, 0);
if (ret < 0) {
......
......@@ -60,6 +60,11 @@ static QTAILQ_HEAD(, BlockDriverState) monitor_bdrv_states =
static int do_open_tray(const char *blk_name, const char *qdev_id,
bool force, Error **errp);
static void blockdev_remove_medium(bool has_device, const char *device,
bool has_id, const char *id, Error **errp);
static void blockdev_insert_medium(bool has_device, const char *device,
bool has_id, const char *id,
const char *node_name, Error **errp);
static const char *const if_name[IF_COUNT] = {
[IF_NONE] = "none",
......@@ -2323,7 +2328,7 @@ void qmp_eject(bool has_device, const char *device,
}
error_free(local_err);
qmp_x_blockdev_remove_medium(has_device, device, has_id, id, errp);
blockdev_remove_medium(has_device, device, has_id, id, errp);
}
void qmp_block_passwd(bool has_device, const char *device,
......@@ -2446,8 +2451,8 @@ void qmp_blockdev_close_tray(bool has_device, const char *device,
}
}
void qmp_x_blockdev_remove_medium(bool has_device, const char *device,
bool has_id, const char *id, Error **errp)
static void blockdev_remove_medium(bool has_device, const char *device,
bool has_id, const char *id, Error **errp)
{
BlockBackend *blk;
BlockDriverState *bs;
......@@ -2503,6 +2508,11 @@ out:
aio_context_release(aio_context);
}
void qmp_blockdev_remove_medium(const char *id, Error **errp)
{
blockdev_remove_medium(false, NULL, true, id, errp);
}
static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
BlockDriverState *bs, Error **errp)
{
......@@ -2548,9 +2558,9 @@ static void qmp_blockdev_insert_anon_medium(BlockBackend *blk,
}
}
void qmp_x_blockdev_insert_medium(bool has_device, const char *device,
bool has_id, const char *id,
const char *node_name, Error **errp)
static void blockdev_insert_medium(bool has_device, const char *device,
bool has_id, const char *id,
const char *node_name, Error **errp)
{
BlockBackend *blk;
BlockDriverState *bs;
......@@ -2576,6 +2586,12 @@ void qmp_x_blockdev_insert_medium(bool has_device, const char *device,
qmp_blockdev_insert_anon_medium(blk, bs, errp);
}
void qmp_blockdev_insert_medium(const char *id, const char *node_name,
Error **errp)
{
blockdev_insert_medium(false, NULL, true, id, node_name, errp);
}
void qmp_blockdev_change_medium(bool has_device, const char *device,
bool has_id, const char *id,
const char *filename,
......@@ -2650,7 +2666,7 @@ void qmp_blockdev_change_medium(bool has_device, const char *device,
error_free(err);
err = NULL;
qmp_x_blockdev_remove_medium(has_device, device, has_id, id, &err);
blockdev_remove_medium(has_device, device, has_id, id, &err);
if (err) {
error_propagate(errp, err);
goto fail;
......
......@@ -91,7 +91,19 @@ static uint8_t nvme_sq_empty(NvmeSQueue *sq)
return sq->head == sq->tail;
}
static void nvme_isr_notify(NvmeCtrl *n, NvmeCQueue *cq)
static void nvme_irq_check(NvmeCtrl *n)
{
if (msix_enabled(&(n->parent_obj))) {
return;
}
if (~n->bar.intms & n->irq_status) {
pci_irq_assert(&n->parent_obj);
} else {
pci_irq_deassert(&n->parent_obj);
}
}
static void nvme_irq_assert(NvmeCtrl *n, NvmeCQueue *cq)
{
if (cq->irq_enabled) {
if (msix_enabled(&(n->parent_obj))) {
......@@ -99,13 +111,28 @@ static void nvme_isr_notify(NvmeCtrl *n, NvmeCQueue *cq)
msix_notify(&(n->parent_obj), cq->vector);
} else {
trace_nvme_irq_pin();
pci_irq_pulse(&n->parent_obj);
assert(cq->cqid < 64);
n->irq_status |= 1 << cq->cqid;
nvme_irq_check(n);
}
} else {
trace_nvme_irq_masked();
}
}
static void nvme_irq_deassert(NvmeCtrl *n, NvmeCQueue *cq)
{
if (cq->irq_enabled) {
if (msix_enabled(&(n->parent_obj))) {
return;
} else {
assert(cq->cqid < 64);
n->irq_status &= ~(1 << cq->cqid);
nvme_irq_check(n);
}
}
}
static uint16_t nvme_map_prp(QEMUSGList *qsg, QEMUIOVector *iov, uint64_t prp1,
uint64_t prp2, uint32_t len, NvmeCtrl *n)
{
......@@ -242,7 +269,7 @@ static void nvme_post_cqes(void *opaque)
sizeof(req->cqe));
QTAILQ_INSERT_TAIL(&sq->req_list, req, entry);
}
nvme_isr_notify(n, cq);
nvme_irq_assert(n, cq);
}
static void nvme_enqueue_req_completion(NvmeCQueue *cq, NvmeRequest *req)
......@@ -905,6 +932,7 @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
n->bar.intmc = n->bar.intms;
trace_nvme_mmio_intm_set(data & 0xffffffff,
n->bar.intmc);
nvme_irq_check(n);
break;
case 0x10: /* INTMC */
if (unlikely(msix_enabled(&(n->parent_obj)))) {
......@@ -917,6 +945,7 @@ static void nvme_write_bar(NvmeCtrl *n, hwaddr offset, uint64_t data,
n->bar.intmc = n->bar.intms;
trace_nvme_mmio_intm_clr(data & 0xffffffff,
n->bar.intmc);
nvme_irq_check(n);
break;
case 0x14: /* CC */
trace_nvme_mmio_cfg(data & 0xffffffff);
......@@ -1085,8 +1114,8 @@ static void nvme_process_db(NvmeCtrl *n, hwaddr addr, int val)
timer_mod(cq->timer, qemu_clock_get_ns(QEMU_CLOCK_VIRTUAL) + 500);
}
if (cq->tail != cq->head) {
nvme_isr_notify(n, cq);
if (cq->tail == cq->head) {
nvme_irq_deassert(n, cq);
}
} else {
/* Submission queue doorbell write */
......
......@@ -775,6 +775,7 @@ typedef struct NvmeCtrl {
uint32_t cmbsz;
uint32_t cmbloc;
uint8_t *cmbuf;
uint64_t irq_status;
char *serial;
NvmeNamespace *namespaces;
......
......@@ -3421,7 +3421,7 @@
'*id': 'str' } }
##
# @x-blockdev-remove-medium:
# @blockdev-remove-medium:
#
# Removes a medium (a block driver state tree) from a block device. That block
# device's tray must currently be open (unless there is no attached guest
......@@ -3429,18 +3429,13 @@
#
# If the tray is open and there is no medium inserted, this will be a no-op.
#
# @device: Block device name (deprecated, use @id instead)
#
# @id: The name or QOM path of the guest device (since: 2.8)
#
# Note: This command is still a work in progress and is considered experimental.
# Stay away from it unless you want to help with its development.
# @id: The name or QOM path of the guest device
#
# Since: 2.5
# Since: 2.12
#
# Example:
#
# -> { "execute": "x-blockdev-remove-medium",
# -> { "execute": "blockdev-remove-medium",
# "arguments": { "id": "ide0-1-0" } }
#
# <- { "error": { "class": "GenericError",
......@@ -3458,33 +3453,27 @@
#
# <- { "return": {} }
#
# -> { "execute": "x-blockdev-remove-medium",
# -> { "execute": "blockdev-remove-medium",
# "arguments": { "id": "ide0-1-0" } }
#
# <- { "return": {} }
#
##
{ 'command': 'x-blockdev-remove-medium',
'data': { '*device': 'str',
'*id': 'str' } }
{ 'command': 'blockdev-remove-medium',
'data': { 'id': 'str' } }
##
# @x-blockdev-insert-medium:
# @blockdev-insert-medium:
#
# Inserts a medium (a block driver state tree) into a block device. That block
# device's tray must currently be open (unless there is no attached guest
# device) and there must be no medium inserted already.
#
# @device: Block device name (deprecated, use @id instead)
#
# @id: The name or QOM path of the guest device (since: 2.8)
# @id: The name or QOM path of the guest device
#
# @node-name: name of a node in the block driver state graph
#
# Note: This command is still a work in progress and is considered experimental.
# Stay away from it unless you want to help with its development.
#
# Since: 2.5
# Since: 2.12
#
# Example:
#
......@@ -3496,16 +3485,15 @@
# "filename": "fedora.iso" } } }
# <- { "return": {} }
#
# -> { "execute": "x-blockdev-insert-medium",
# -> { "execute": "blockdev-insert-medium",
# "arguments": { "id": "ide0-1-0",
# "node-name": "node0" } }
#
# <- { "return": {} }
#
##
{ 'command': 'x-blockdev-insert-medium',
'data': { '*device': 'str',
'*id': 'str',
{ 'command': 'blockdev-insert-medium',
'data': { 'id': 'str',
'node-name': 'str'} }
......@@ -3533,8 +3521,8 @@
#
# Changes the medium inserted into a block device by ejecting the current medium
# and loading a new image file which is inserted as the new medium (this command
# combines blockdev-open-tray, x-blockdev-remove-medium,
# x-blockdev-insert-medium and blockdev-close-tray).
# combines blockdev-open-tray, blockdev-remove-medium, blockdev-insert-medium
# and blockdev-close-tray).
#
# @device: Block device name (deprecated, use @id instead)
#
......
......@@ -18,6 +18,7 @@ test-aio
test-aio-multithread
test-arm-mptimer
test-base64
test-bdrv-drain
test-bitops
test-bitcnt
test-blockjob
......
......@@ -1578,9 +1578,9 @@ static void test_atapi_tray(void)
QDict *rsp;
fd = prepare_iso(iso_size, &tx, &iso);
ahci = ahci_boot_and_enable("-drive if=none,id=drive0,file=%s,format=raw "
ahci = ahci_boot_and_enable("-blockdev node-name=drive0,driver=file,filename=%s "
"-M q35 "
"-device ide-cd,drive=drive0 ", iso);
"-device ide-cd,id=cd0,drive=drive0 ", iso);
port = ahci_port_select(ahci);
ahci_atapi_eject(ahci, port);
......@@ -1591,13 +1591,13 @@ static void test_atapi_tray(void)
/* Remove media */
qmp_async("{'execute': 'blockdev-open-tray', "
"'arguments': {'device': 'drive0'}}");
"'arguments': {'id': 'cd0'}}");
atapi_wait_tray(true);
rsp = qmp_receive();
QDECREF(rsp);
qmp_discard_response("{'execute': 'x-blockdev-remove-medium', "
"'arguments': {'device': 'drive0'}}");
qmp_discard_response("{'execute': 'blockdev-remove-medium', "
"'arguments': {'id': 'cd0'}}");
/* Test the tray without a medium */
ahci_atapi_load(ahci, port);
......@@ -1612,13 +1612,13 @@ static void test_atapi_tray(void)
"'driver': 'raw', "
"'file': { 'driver': 'file', "
"'filename': %s }}}", iso);
qmp_discard_response("{'execute': 'x-blockdev-insert-medium',"
"'arguments': { 'device': 'drive0', "
qmp_discard_response("{'execute': 'blockdev-insert-medium',"
"'arguments': { 'id': 'cd0', "
"'node-name': 'node0' }}");
/* Again, the event shows up first */
qmp_async("{'execute': 'blockdev-close-tray', "
"'arguments': {'device': 'drive0'}}");
"'arguments': {'id': 'cd0'}}");
atapi_wait_tray(false);
rsp = qmp_receive();
QDECREF(rsp);
......
......@@ -42,18 +42,12 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
# Any format supporting backing files
_supported_fmt qcow qcow2 vmdk qed
_supported_proto generic
_unsupported_proto vxhs
_supported_proto file
_supported_os Linux
_unsupported_imgopts "subformat=monolithicFlat" \
"subformat=twoGbMaxExtentFlat" \
"subformat=twoGbMaxExtentSparse"
# NFS does not support bdrv_reopen_prepare thus qemu-img commit fails.
if [ "$IMGPROTO" = "nfs" ]; then
_notrun "image protocol $IMGPROTO does not support bdrv_commit"
fi
TEST_OFFSETS="0 4294967296"
TEST_IMG_SAVE="$TEST_IMG"
......@@ -117,10 +111,12 @@ echo
echo 'Testing failing commit'
echo
TEST_IMG="$TEST_IMG.base" _make_test_img 1M
# Create an image with a null backing file to which committing will fail (with
# ENOSPC so we can distinguish the result from some generic EIO which may be
# generated anywhere in the block layer)
_make_test_img -b "json:{'driver': 'raw',
_make_test_img -b "json:{'driver': '$IMGFMT',
'file': {
'driver': 'blkdebug',
'inject-error': [{
......@@ -129,14 +125,15 @@ _make_test_img -b "json:{'driver': 'raw',
'once': true
}],
'image': {
'driver': 'null-co'
'driver': 'file',
'filename': '$TEST_IMG.base'
}}}"
# Just write anything so committing will not be a no-op
$QEMU_IO -c 'writev 0 64k' "$TEST_IMG" | _filter_qemu_io
$QEMU_IMG commit "$TEST_IMG"
_cleanup_test_img
_cleanup
# success, all done
echo "*** done"
......
......@@ -1078,7 +1078,8 @@ No errors were found on the image.
Testing failing commit
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 backing_file=json:{'driver': 'raw',,
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=1048576
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1048576 backing_file=json:{'driver': 'IMGFMT',,
'file': {
'driver': 'blkdebug',,
'inject-error': [{
......@@ -1087,7 +1088,8 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=1073741824 backing_file=json:{'d
'once': true
}],,
'image': {
'driver': 'null-co'
'driver': 'file',,
'filename': 'TEST_DIR/t.IMGFMT.base'
}}}
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
......
......@@ -131,6 +131,8 @@ echo
echo === Enable and disable lazy refcounting on the command line, plus some invalid values ===
echo
_make_test_img -o compat=1.1 "$size"
run_qemu -drive file="$TEST_IMG",format=qcow2,lazy-refcounts=on
run_qemu -drive file="$TEST_IMG",format=qcow2,lazy-refcounts=off
run_qemu -drive file="$TEST_IMG",format=qcow2,lazy-refcounts=
......
......@@ -77,6 +77,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.backing.driver=qcow2,file.backing.f
=== Enable and disable lazy refcounting on the command line, plus some invalid values ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) quit
......
......@@ -77,6 +77,7 @@ QEMU_PROG: -drive file=TEST_DIR/t.qcow2,file.backing.driver=qcow2,file.backing.f
=== Enable and disable lazy refcounting on the command line, plus some invalid values ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,lazy-refcounts=on
QEMU X.Y.Z monitor - type 'help' for more information
(qemu) quit
......
......@@ -152,7 +152,9 @@ done
echo
echo "=== Testing afl image with a very large capacity ==="
_use_sample_img afl9.vmdk.bz2
_img_info
# The sed makes this test pass on machines with little RAM
# (and also with 32 bit builds)
_img_info | sed -e 's/Cannot allocate memory/Invalid argument/'
_cleanup_test_img
# success, all done
......
......@@ -2358,5 +2358,5 @@ Offset Length Mapped to File
0x140000000 0x10000 0x50000 TEST_DIR/t-s003.vmdk
=== Testing afl image with a very large capacity ===
qemu-img: Can't get image size 'TEST_DIR/afl9.IMGFMT': File too large
qemu-img: Could not open 'TEST_DIR/afl9.IMGFMT': Could not open 'TEST_DIR/afl9.IMGFMT': Invalid argument
*** done
......@@ -335,7 +335,8 @@ poke_file "$TEST_IMG" "$l2_offset" "\x80\x00\x00\x00\x00\x00\x2a\x01"
# Let's write to it!
$QEMU_IO -c "write 0 64k" "$TEST_IMG" | _filter_qemu_io
# Can't repair this yet (TODO: We can just deallocate the cluster)
echo '--- Repairing ---'
_check_test_img -r all
echo
echo '=== Discarding with an unaligned refblock ==='
......
......@@ -317,6 +317,15 @@ discard 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: Preallocated zero cluster offset 0x2a00 unaligned (guest offset: 0); further corruption events will be suppressed
write failed: Input/output error
--- Repairing ---
Repairing offset=2a00: Preallocated zero cluster is not properly aligned; L2 entry corrupted.
The following inconsistencies were found and repaired:
0 leaked clusters
1 corruptions
Double checking the fixed image now...
No errors were found on the image.
=== Discarding with an unaligned refblock ===
......
......@@ -57,7 +57,8 @@ function run_qemu()
{
do_run_qemu "$@" 2>&1 | _filter_testdir | _filter_qmp | _filter_qemu \
| _filter_actual_image_size \
| _filter_generated_node_ids | _filter_qmp_events
| _filter_generated_node_ids | _filter_qmp_events \
| _filter_img_info
}
size=128M
......
......@@ -3,7 +3,7 @@ Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728
=== -drive/-device and device_del ===
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virtio-blk,drive=disk,id=virtio0
Testing: -drive file=TEST_DIR/t.IMGFMT,format=IMGFMT,if=none,id=disk -device virtio-blk,drive=disk,id=virtio0
{
QMP_VERSION
}
......@@ -23,26 +23,17 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti
"detect_zeroes": "off",
"image": {
"virtual-size": 134217728,
"filename": "TEST_DIR/t.qcow2",
"filename": "TEST_DIR/t.IMGFMT",
"cluster-size": 65536,
"format": "qcow2",
"format": "IMGFMT",
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"refcount-bits": 16,
"corrupt": false
}
},
"dirty-flag": false
},
"iops_wr": 0,
"ro": false,
"node-name": "NODE_NAME",
"backing_file_depth": 0,
"drv": "qcow2",
"drv": "IMGFMT",
"iops": 0,
"bps_wr": 0,
"write_threshold": 0,
......@@ -54,7 +45,7 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"file": "TEST_DIR/t.IMGFMT",
"encryption_key_missing": false
},
"qdev": "/machine/peripheral/virtio0/virtio-backend",
......@@ -81,7 +72,7 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk -device virti
=== -drive/device_add and device_del ===
Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk
Testing: -drive file=TEST_DIR/t.IMGFMT,format=IMGFMT,if=none,id=disk
{
QMP_VERSION
}
......@@ -100,26 +91,17 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk
"detect_zeroes": "off",
"image": {
"virtual-size": 134217728,
"filename": "TEST_DIR/t.qcow2",
"filename": "TEST_DIR/t.IMGFMT",
"cluster-size": 65536,
"format": "qcow2",
"format": "IMGFMT",
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"refcount-bits": 16,
"corrupt": false
}
},
"dirty-flag": false
},
"iops_wr": 0,
"ro": false,
"node-name": "NODE_NAME",
"backing_file_depth": 0,
"drv": "qcow2",
"drv": "IMGFMT",
"iops": 0,
"bps_wr": 0,
"write_threshold": 0,
......@@ -131,7 +113,7 @@ Testing: -drive file=TEST_DIR/t.qcow2,format=qcow2,if=none,id=disk
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"file": "TEST_DIR/t.IMGFMT",
"encryption_key_missing": false
},
"type": "unknown"
......@@ -183,26 +165,17 @@ Testing:
"detect_zeroes": "off",
"image": {
"virtual-size": 134217728,
"filename": "TEST_DIR/t.qcow2",
"filename": "TEST_DIR/t.IMGFMT",
"cluster-size": 65536,
"format": "qcow2",
"format": "IMGFMT",
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"refcount-bits": 16,
"corrupt": false
}
},
"dirty-flag": false
},
"iops_wr": 0,
"ro": false,
"node-name": "NODE_NAME",
"backing_file_depth": 0,
"drv": "qcow2",
"drv": "IMGFMT",
"iops": 0,
"bps_wr": 0,
"write_threshold": 0,
......@@ -214,7 +187,7 @@ Testing:
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"file": "TEST_DIR/t.IMGFMT",
"encryption_key_missing": false
},
"type": "unknown"
......@@ -263,26 +236,17 @@ Testing:
"detect_zeroes": "off",
"image": {
"virtual-size": 134217728,
"filename": "TEST_DIR/t.qcow2",
"filename": "TEST_DIR/t.IMGFMT",
"cluster-size": 65536,
"format": "qcow2",
"format": "IMGFMT",
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"refcount-bits": 16,
"corrupt": false
}
},
"dirty-flag": false
},
"iops_wr": 0,
"ro": false,
"node-name": "disk",
"backing_file_depth": 0,
"drv": "qcow2",
"drv": "IMGFMT",
"iops": 0,
"bps_wr": 0,
"write_threshold": 0,
......@@ -294,7 +258,7 @@ Testing:
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"file": "TEST_DIR/t.IMGFMT",
"encryption_key_missing": false
},
{
......@@ -302,7 +266,7 @@ Testing:
"detect_zeroes": "off",
"image": {
"virtual-size": 197120,
"filename": "TEST_DIR/t.qcow2",
"filename": "TEST_DIR/t.IMGFMT",
"format": "file",
"actual-size": SIZE,
"dirty-flag": false
......@@ -323,7 +287,7 @@ Testing:
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"file": "TEST_DIR/t.IMGFMT",
"encryption_key_missing": false
}
]
......@@ -347,26 +311,17 @@ Testing:
"detect_zeroes": "off",
"image": {
"virtual-size": 134217728,
"filename": "TEST_DIR/t.qcow2",
"filename": "TEST_DIR/t.IMGFMT",
"cluster-size": 65536,
"format": "qcow2",
"format": "IMGFMT",
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"refcount-bits": 16,
"corrupt": false
}
},
"dirty-flag": false
},
"iops_wr": 0,
"ro": false,
"node-name": "disk",
"backing_file_depth": 0,
"drv": "qcow2",
"drv": "IMGFMT",
"iops": 0,
"bps_wr": 0,
"write_threshold": 0,
......@@ -378,7 +333,7 @@ Testing:
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"file": "TEST_DIR/t.IMGFMT",
"encryption_key_missing": false
},
{
......@@ -386,7 +341,7 @@ Testing:
"detect_zeroes": "off",
"image": {
"virtual-size": 197120,
"filename": "TEST_DIR/t.qcow2",
"filename": "TEST_DIR/t.IMGFMT",
"format": "file",
"actual-size": SIZE,
"dirty-flag": false
......@@ -407,7 +362,7 @@ Testing:
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"file": "TEST_DIR/t.IMGFMT",
"encryption_key_missing": false
}
]
......
......@@ -41,8 +41,9 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
# Internal snapshots are (currently) impossible with refcount_bits=1
_unsupported_imgopts 'refcount_bits=1[^0-9]'
# - Internal snapshots are (currently) impossible with refcount_bits=1
# - This is generally a test for compat=1.1 images
_unsupported_imgopts 'refcount_bits=1[^0-9]' 'compat=0.10'
header_size=104
......
......@@ -119,11 +119,11 @@ echo
# Both options given directly and those given in the filename should be used
$QEMU_IO -c "open -o driver=qcow2 json:{\"file.filename\":\"$TEST_IMG\"}" \
-c "info" 2>&1 | _filter_testdir | _filter_imgfmt
-c "info" 2>&1 | _filter_img_info
# Options given directly should be prioritized over those given in the filename
$QEMU_IO -c "open -o driver=qcow2 json:{\"driver\":\"raw\",\"file.filename\":\"$TEST_IMG\"}" \
-c "info" 2>&1 | _filter_testdir | _filter_imgfmt
-c "info" 2>&1 | _filter_img_info
# success, all done
......
......@@ -38,17 +38,7 @@ cluster_size: 65536
format name: IMGFMT
cluster size: 64 KiB
vm state offset: 512 MiB
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
format name: IMGFMT
cluster size: 64 KiB
vm state offset: 512 MiB
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
corrupt: false
*** done
......@@ -348,9 +348,9 @@ class ThrottleTestRemovableMedia(iotests.QMPTestCase):
# Now eject cd0 and insert cd1
result = self.vm.qmp("blockdev-open-tray", id='dev0')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp("x-blockdev-remove-medium", id='dev0')
result = self.vm.qmp("blockdev-remove-medium", id='dev0')
self.assert_qmp(result, 'return', {})
result = self.vm.qmp("x-blockdev-insert-medium", id='dev0', node_name='cd1')
result = self.vm.qmp("blockdev-insert-medium", id='dev0', node_name='cd1')
self.assert_qmp(result, 'return', {})
# Check that the I/O limits are still the same
......@@ -359,7 +359,7 @@ class ThrottleTestRemovableMedia(iotests.QMPTestCase):
self.assert_qmp(result, 'return[0]/inserted/bps', 50)
# Eject cd1
result = self.vm.qmp("x-blockdev-remove-medium", id='dev0')
result = self.vm.qmp("blockdev-remove-medium", id='dev0')
self.assert_qmp(result, 'return', {})
# Check that we can't set limits if the device has no medium
......
......@@ -69,7 +69,12 @@ $QEMU_IO -c 'write 0 64k' "$TEST_IMG" | _filter_qemu_io
qemu_comm_method=monitor _launch_qemu -drive if=none,file="$TEST_IMG",id=drv0
$QEMU_IMG resize -f raw --shrink "$TEST_IMG" $((5 * 64 * 1024))
# Wait for a prompt to appear (so we know qemu has opened the image)
_send_qemu_cmd '' '(qemu)'
$QEMU_IMG resize --shrink --image-opts \
"driver=raw,file.driver=file,file.filename=$TEST_IMG,file.locking=off" \
$((5 * 64 * 1024))
_send_qemu_cmd $QEMU_HANDLE 'qemu-io drv0 map' 'allocated' \
| sed -e 's/^(qemu).*qemu-io drv0 map...$/(qemu) qemu-io drv0 map/'
......
......@@ -14,8 +14,9 @@ Offset Length Mapped to File
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=65536
wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Image resized.
QEMU X.Y.Z monitor - type 'help' for more information
Image resized.
(qemu)
(qemu) qemu-io drv0 map
64 KiB (0x10000) bytes allocated at offset 0 bytes (0x0)
*** done
......@@ -40,6 +40,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto file nfs
_supported_os Linux
# Internal snapshots are (currently) impossible with refcount_bits=1
_unsupported_imgopts 'refcount_bits=1[^0-9]'
IMG_SIZE=64K
......
此差异已折叠。
......@@ -45,6 +45,8 @@ _supported_fmt qcow2
_supported_proto generic
_unsupported_proto vxhs
_supported_os Linux
# We are going to use lazy-refcounts
_unsupported_imgopts 'compat=0.10'
qemu_comm_method="monitor"
......
......@@ -41,6 +41,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
# We are going to use lazy-refcounts
_unsupported_imgopts 'compat=0.10'
_make_test_img 64M
......
......@@ -133,7 +133,7 @@ class TestBlockdevDel(iotests.QMPTestCase):
# Insert a BlockDriverState
def insertDrive(self, device, node):
self.checkBlockDriverState(node)
result = self.vm.qmp('x-blockdev-insert-medium',
result = self.vm.qmp('blockdev-insert-medium',
id = device, node_name = node)
self.assert_qmp(result, 'return', {})
self.checkBlockDriverState(node)
......
......@@ -51,36 +51,30 @@ class BaseClass(iotests.QMPTestCase):
target_real_backing = None
def setUp(self):
qemu_img('create', '-f', iotests.imgfmt, back0_img, '1M')
qemu_img('create', '-f', iotests.imgfmt, back0_img, '1440K')
qemu_img('create', '-f', iotests.imgfmt, '-b', back0_img, back1_img)
qemu_img('create', '-f', iotests.imgfmt, '-b', back1_img, back2_img)
qemu_img('create', '-f', iotests.imgfmt, '-b', back2_img, source_img)
self.vm = iotests.VM()
self.vm.add_drive(None, '', 'none')
self.vm.launch()
# Add the BDS via blockdev-add so it stays around after the mirror block
# job has been completed
result = self.vm.qmp('blockdev-add',
node_name='source',
driver=iotests.imgfmt,
file={'driver': 'file',
'filename': source_img})
self.assert_qmp(result, 'return', {})
result = self.vm.qmp('x-blockdev-insert-medium',
device='drive0', node_name='source')
self.assert_qmp(result, 'return', {})
blockdev = {'node-name': 'source',
'driver': iotests.imgfmt,
'file': {'driver': 'file',
'filename': source_img}}
self.vm.add_blockdev(self.qmp_to_opts(blockdev))
self.vm.add_device('floppy,id=qdev0,drive=source')
self.vm.launch()
self.assertIntactSourceBackingChain()
if self.existing:
if self.target_backing:
qemu_img('create', '-f', iotests.imgfmt,
'-b', self.target_backing, target_img, '1M')
'-b', self.target_backing, target_img, '1440K')
else:
qemu_img('create', '-f', iotests.imgfmt, target_img, '1M')
qemu_img('create', '-f', iotests.imgfmt, target_img, '1440K')
if self.cmd == 'blockdev-mirror':
options = { 'node-name': 'target',
......@@ -104,11 +98,11 @@ class BaseClass(iotests.QMPTestCase):
except OSError:
pass
def findBlockNode(self, node_name, id=None):
if id:
def findBlockNode(self, node_name, qdev=None):
if qdev:
result = self.vm.qmp('query-block')
for device in result['return']:
if device['device'] == id:
if device['qdev'] == qdev:
if node_name:
self.assert_qmp(device, 'inserted/node-name', node_name)
return device['inserted']
......@@ -118,7 +112,7 @@ class BaseClass(iotests.QMPTestCase):
if node['node-name'] == node_name:
return node
self.fail('Cannot find node %s/%s' % (id, node_name))
self.fail('Cannot find node %s/%s' % (qdev, node_name))
def assertIntactSourceBackingChain(self):
node = self.findBlockNode('source')
......@@ -155,22 +149,23 @@ class BaseClass(iotests.QMPTestCase):
class MirrorBaseClass(BaseClass):
def runMirror(self, sync):
if self.cmd == 'blockdev-mirror':
result = self.vm.qmp(self.cmd, device='drive0', sync=sync,
target='target')
result = self.vm.qmp(self.cmd, job_id='mirror-job', device='source',
sync=sync, target='target')
else:
if self.existing:
mode = 'existing'
else:
mode = 'absolute-paths'
result = self.vm.qmp(self.cmd, device='drive0', sync=sync,
target=target_img, format=iotests.imgfmt,
mode=mode, node_name='target')
result = self.vm.qmp(self.cmd, job_id='mirror-job', device='source',
sync=sync, target=target_img,
format=iotests.imgfmt, mode=mode,
node_name='target')
self.assert_qmp(result, 'return', {})
self.vm.event_wait('BLOCK_JOB_READY')
result = self.vm.qmp('block-job-complete', device='drive0')
result = self.vm.qmp('block-job-complete', device='mirror-job')
self.assert_qmp(result, 'return', {})
self.vm.event_wait('BLOCK_JOB_COMPLETED')
......@@ -178,21 +173,21 @@ class MirrorBaseClass(BaseClass):
def testFull(self):
self.runMirror('full')
node = self.findBlockNode('target', 'drive0')
node = self.findBlockNode('target', 'qdev0')
self.assertCorrectBackingImage(node, None)
self.assertIntactSourceBackingChain()
def testTop(self):
self.runMirror('top')
node = self.findBlockNode('target', 'drive0')
node = self.findBlockNode('target', 'qdev0')
self.assertCorrectBackingImage(node, back2_img)
self.assertIntactSourceBackingChain()
def testNone(self):
self.runMirror('none')
node = self.findBlockNode('target', 'drive0')
node = self.findBlockNode('target', 'qdev0')
self.assertCorrectBackingImage(node, source_img)
self.assertIntactSourceBackingChain()
......@@ -233,17 +228,18 @@ class TestCommit(BaseClass):
existing = False
def testCommit(self):
result = self.vm.qmp('block-commit', device='drive0', base=back1_img)
result = self.vm.qmp('block-commit', job_id='commit-job',
device='source', base=back1_img)
self.assert_qmp(result, 'return', {})
self.vm.event_wait('BLOCK_JOB_READY')
result = self.vm.qmp('block-job-complete', device='drive0')
result = self.vm.qmp('block-job-complete', device='commit-job')
self.assert_qmp(result, 'return', {})
self.vm.event_wait('BLOCK_JOB_COMPLETED')
node = self.findBlockNode(None, 'drive0')
node = self.findBlockNode(None, 'qdev0')
self.assert_qmp(node, 'image' + '/backing-image' * 0 + '/filename',
back1_img)
self.assert_qmp(node, 'image' + '/backing-image' * 1 + '/filename',
......
......@@ -48,6 +48,8 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto file
_supported_os Linux
# Persistent dirty bitmaps require compat=1.1
_unsupported_imgopts 'compat=0.10'
function run_qemu()
{
......
......@@ -2,7 +2,7 @@
#
# Test corner cases with unusual block geometries
#
# Copyright (C) 2016-2017 Red Hat, Inc.
# Copyright (C) 2016-2018 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
......@@ -37,13 +37,15 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
. ./common.rc
. ./common.filter
# This test is runnable under compat=0.10; see test 204 for additional
# tests specific to compat=1.1.
_supported_fmt qcow2
_supported_proto file
CLUSTER_SIZE=1M
size=128M
options=driver=blkdebug,image.driver=qcow2
nested_opts=image.file.driver=file,image.file.filename=$TEST_IMG
echo
echo "== setting up files =="
......@@ -51,7 +53,7 @@ echo "== setting up files =="
TEST_IMG="$TEST_IMG.base" _make_test_img $size
$QEMU_IO -c "write -P 11 0 $size" "$TEST_IMG.base" | _filter_qemu_io
_make_test_img -b "$TEST_IMG.base"
$QEMU_IO -c "write -P 22 0 110M" "$TEST_IMG" | _filter_qemu_io
$QEMU_IO -c "write -P 22 0 $size" "$TEST_IMG" | _filter_qemu_io
# Limited to 64k max-transfer
echo
......@@ -81,13 +83,6 @@ limits=align=512,opt-write-zero=15M,max-write-zero=15M,opt-discard=15M,max-disca
$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \
-c "discard 80000001 30M" | _filter_qemu_io
echo
echo "== block status smaller than alignment =="
limits=align=4k
$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \
-c "alloc 1 1" -c "alloc 0x6dffff0 1000" -c "alloc 127m 5P" \
-c map | _filter_qemu_io
echo
echo "== verify image content =="
......@@ -110,13 +105,10 @@ function verify_io()
echo read -P 0 32M 32M
echo read -P 22 64M 13M
echo read -P $discarded 77M 29M
echo read -P 22 106M 4M
echo read -P 11 110M 18M
echo read -P 22 106M 22M
}
verify_io | $QEMU_IO -r "$TEST_IMG" | _filter_qemu_io
$QEMU_IMG map --image-opts "$options,$nested_opts,align=4k" \
| _filter_qemu_img_map
_check_test_img
......
......@@ -5,8 +5,8 @@ Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
wrote 134217728/134217728 bytes at offset 0
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
wrote 115343360/115343360 bytes at offset 0
110 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
wrote 134217728/134217728 bytes at offset 0
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== constrained alignment and max-transfer ==
wrote 131072/131072 bytes at offset 1000
......@@ -26,13 +26,6 @@ wrote 33554432/33554432 bytes at offset 33554432
discard 31457280/31457280 bytes at offset 80000001
30 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== block status smaller than alignment ==
1/1 bytes allocated at offset 1 bytes
16/1000 bytes allocated at offset 110 MiB
0/1048576 bytes allocated at offset 127 MiB
110 MiB (0x6e00000) bytes allocated at offset 0 bytes (0x0)
18 MiB (0x1200000) bytes not allocated at offset 110 MiB (0x6e00000)
== verify image content ==
read 1000/1000 bytes at offset 0
1000 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
......@@ -50,14 +43,7 @@ read 13631488/13631488 bytes at offset 67108864
13 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 30408704/30408704 bytes at offset 80740352
29 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 4194304/4194304 bytes at offset 111149056
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 18874368/18874368 bytes at offset 115343360
18 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Offset Length File
0 0x800000 TEST_DIR/t.IMGFMT
0x900000 0x2400000 TEST_DIR/t.IMGFMT
0x3c00000 0x1100000 TEST_DIR/t.IMGFMT
0x6a00000 0x400000 TEST_DIR/t.IMGFMT
read 23068672/23068672 bytes at offset 111149056
22 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
No errors were found on the image.
*** done
......@@ -27,18 +27,12 @@ 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
trap "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
function do_run_qemu()
......@@ -55,7 +49,6 @@ function run_qemu()
| _filter_actual_image_size
}
_make_test_img 64M
test_throttle=$($QEMU_IMG --help|grep throttle)
[ "$test_throttle" = "" ] && _supported_fmt throttle
......@@ -66,12 +59,8 @@ run_qemu <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "blockdev-add",
"arguments": {
"driver": "$IMGFMT",
"node-name": "disk0",
"file": {
"driver": "file",
"filename": "$TEST_IMG"
}
"driver": "null-co",
"node-name": "disk0"
}
}
{ "execute": "object-add",
......@@ -181,12 +170,8 @@ run_qemu <<EOF
{ "execute": "qmp_capabilities" }
{ "execute": "blockdev-add",
"arguments": {
"driver": "$IMGFMT",
"node-name": "disk0",
"file": {
"driver": "file",
"filename": "$TEST_IMG"
}
"driver": "null-co",
"node-name": "disk0"
}
}
{ "execute": "blockdev-add",
......
QA output created by 184
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
== checking interface ==
Testing:
......@@ -28,12 +27,9 @@ Testing:
"iops_rd": 0,
"detect_zeroes": "off",
"image": {
"virtual-size": 67108864,
"filename": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"qcow2\", \"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/t.qcow2\"}}}",
"cluster-size": 65536,
"format": "throttle",
"actual-size": SIZE,
"dirty-flag": false
"virtual-size": 1073741824,
"filename": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"null-co\"}}",
"format": "throttle"
},
"iops_wr": 0,
"ro": false,
......@@ -51,34 +47,22 @@ Testing:
"direct": false,
"writeback": true
},
"file": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"qcow2\", \"file\": {\"driver\": \"file\", \"filename\": \"TEST_DIR/t.qcow2\"}}}",
"file": "json:{\"throttle-group\": \"group0\", \"driver\": \"throttle\", \"file\": {\"driver\": \"null-co\"}}",
"encryption_key_missing": false
},
{
"iops_rd": 0,
"detect_zeroes": "off",
"image": {
"virtual-size": 67108864,
"filename": "TEST_DIR/t.qcow2",
"cluster-size": 65536,
"format": "qcow2",
"actual-size": SIZE,
"format-specific": {
"type": "qcow2",
"data": {
"compat": "1.1",
"lazy-refcounts": false,
"refcount-bits": 16,
"corrupt": false
}
},
"dirty-flag": false
"virtual-size": 1073741824,
"filename": "null-co://",
"format": "null-co"
},
"iops_wr": 0,
"ro": false,
"node-name": "disk0",
"backing_file_depth": 0,
"drv": "qcow2",
"drv": "null-co",
"iops": 0,
"bps_wr": 0,
"write_threshold": 0,
......@@ -90,36 +74,7 @@ Testing:
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"encryption_key_missing": false
},
{
"iops_rd": 0,
"detect_zeroes": "off",
"image": {
"virtual-size": 197120,
"filename": "TEST_DIR/t.qcow2",
"format": "file",
"actual-size": SIZE,
"dirty-flag": false
},
"iops_wr": 0,
"ro": false,
"node-name": "NODE_NAME",
"backing_file_depth": 0,
"drv": "file",
"iops": 0,
"bps_wr": 0,
"write_threshold": 0,
"encrypted": false,
"bps": 0,
"bps_rd": 0,
"cache": {
"no-flush": false,
"direct": false,
"writeback": true
},
"file": "TEST_DIR/t.qcow2",
"file": "null-co://",
"encryption_key_missing": false
}
]
......
......@@ -45,7 +45,6 @@ trap "_cleanup; exit \$status" 0 1 2 3 15
. ./common.qemu
_supported_fmt qcow2
_unsupported_imgopts compat=0.10
_supported_proto file
_supported_os Linux
......@@ -92,7 +91,7 @@ echo === Check that both top and top2 point to base now ===
echo
_send_qemu_cmd $h "{ 'execute': 'query-named-block-nodes' }" "^}" |
_filter_generated_node_ids | _filter_actual_image_size
_filter_generated_node_ids | _filter_actual_image_size | _filter_img_info
_send_qemu_cmd $h "{ 'execute': 'quit' }" "^}"
wait=1 _cleanup_qemu
......@@ -140,7 +139,7 @@ echo === Check that both top and top2 point to base now ===
echo
_send_qemu_cmd $h "{ 'execute': 'query-named-block-nodes' }" "^}" |
_filter_generated_node_ids | _filter_actual_image_size
_filter_generated_node_ids | _filter_actual_image_size | _filter_img_info
_send_qemu_cmd $h "{ 'execute': 'quit' }" "^}"
wait=1 _cleanup_qemu
......
此差异已折叠。
......@@ -91,11 +91,15 @@ $QEMU_IO --object $SECRET0 --object $SECRET1 -c "read -P 0x9 0 $size" --image-op
echo
echo "== checking image base =="
$QEMU_IMG info --image-opts $IMGSPECBASE | _filter_img_info | _filter_testdir | sed -e "/^disk size:/ D"
$QEMU_IMG info --image-opts $IMGSPECBASE | _filter_img_info --format-specific \
| sed -e "/^disk size:/ D" -e '/refcount bits:/ D' -e '/compat:/ D' \
-e '/lazy refcounts:/ D' -e '/corrupt:/ D'
echo
echo "== checking image layer =="
$QEMU_IMG info --image-opts $IMGSPECLAYER | _filter_img_info | _filter_testdir | sed -e "/^disk size:/ D"
$QEMU_IMG info --image-opts $IMGSPECLAYER | _filter_img_info --format-specific \
| sed -e "/^disk size:/ D" -e '/refcount bits:/ D' -e '/compat:/ D' \
-e '/lazy refcounts:/ D' -e '/corrupt:/ D'
# success, all done
......
......@@ -36,9 +36,6 @@ image: json:{"encrypt.key-secret": "sec0", "driver": "IMGFMT", "file": {"driver"
file format: IMGFMT
virtual size: 16M (16777216 bytes)
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
encrypt:
ivgen alg: plain64
hash alg: sha256
......@@ -75,7 +72,6 @@ Format specific information:
key offset: 1810432
payload offset: 2068480
master key iters: 1024
corrupt: false
== checking image layer ==
image: json:{"encrypt.key-secret": "sec1", "driver": "IMGFMT", "file": {"driver": "file", "filename": "TEST_DIR/t.IMGFMT"}}
......@@ -83,9 +79,6 @@ file format: IMGFMT
virtual size: 16M (16777216 bytes)
backing file: TEST_DIR/t.IMGFMT.base
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
encrypt:
ivgen alg: plain64
hash alg: sha256
......@@ -122,5 +115,4 @@ Format specific information:
key offset: 1810432
payload offset: 2068480
master key iters: 1024
corrupt: false
*** done
#!/bin/bash
#
# Test savevm and loadvm after live migration with postcopy flag
#
# Copyright (C) 2017, IBM Corporation.
#
# This file is derived from tests/qemu-iotests/181 by Kevin Wolf
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see <http://www.gnu.org/licenses/>.
seq=`basename $0`
echo "QA output created by $seq"
status=1 # failure is the default!
MIG_SOCKET="${TEST_DIR}/migrate"
# get standard environment, filters and checks
. ./common.rc
. ./common.filter
. ./common.qemu
_cleanup()
{
rm -f "${MIG_SOCKET}"
_cleanup_test_img
_cleanup_qemu
}
trap "_cleanup; exit \$status" 0 1 2 3 15
_supported_fmt qcow2
_supported_proto generic
_supported_os Linux
# Internal snapshots are (currently) impossible with refcount_bits=1
# This was taken from test 080
_unsupported_imgopts 'refcount_bits=1[^0-9]'
size=64M
_make_test_img $size
echo
echo === Starting VMs ===
echo
qemu_comm_method="monitor"
if [ "$IMGOPTSSYNTAX" = "true" ]; then
_launch_qemu \
-drive "${TEST_IMG}",cache=${CACHEMODE},id=disk
else
_launch_qemu \
-drive file="${TEST_IMG}",cache=${CACHEMODE},driver=$IMGFMT,id=disk
fi
src=$QEMU_HANDLE
if [ "$IMGOPTSSYNTAX" = "true" ]; then
_launch_qemu \
-drive "${TEST_IMG}",cache=${CACHEMODE},id=disk \
-incoming "unix:${MIG_SOCKET}"
else
_launch_qemu \
-drive file="${TEST_IMG}",cache=${CACHEMODE},driver=$IMGFMT,id=disk \
-incoming "unix:${MIG_SOCKET}"
fi
dest=$QEMU_HANDLE
echo
echo === Set \'migrate_set_capability postcopy-ram on\' and migrate ===
echo
silent=yes
_send_qemu_cmd $dest 'migrate_set_capability postcopy-ram on' "(qemu)"
_send_qemu_cmd $src 'migrate_set_capability postcopy-ram on' "(qemu)"
_send_qemu_cmd $src "migrate -d unix:${MIG_SOCKET}" "(qemu)"
QEMU_COMM_TIMEOUT=1 qemu_cmd_repeat=10 silent=yes \
_send_qemu_cmd $src "info migrate" "completed\|failed"
silent=yes _send_qemu_cmd $src "" "(qemu)"
echo
echo === Check if migration was successful ===
echo
QEMU_COMM_TIMEOUT=1 silent=yes \
_send_qemu_cmd $src "info migrate" "completed"
silent=yes _send_qemu_cmd $src "" "(qemu)"
echo
echo === On destination, execute savevm and loadvm ===
echo
silent=
_send_qemu_cmd $dest 'savevm state1' "(qemu)"
_send_qemu_cmd $dest 'loadvm state1' "(qemu)"
echo
echo === Shut down and check image ===
echo
_send_qemu_cmd $src 'quit' ""
_send_qemu_cmd $dest 'quit' ""
wait=1 _cleanup_qemu
_check_test_img
# success, all done
echo "*** done"
status=0
QA output created by 201
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
=== Starting VMs ===
=== Set 'migrate_set_capability postcopy-ram on' and migrate ===
=== Check if migration was successful ===
=== On destination, execute savevm and loadvm ===
(qemu) savevm state1
(qemu) loadvm state1
=== Shut down and check image ===
(qemu) quit
(qemu) quit
No errors were found on the image.
*** done
#!/bin/bash
#
# Test corner cases with unusual block geometries
#
# Copyright (C) 2016-2018 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=eblake@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
# This test assumes that discard leaves zero clusters; see test 177 for
# other tests that also work in older images
_unsupported_imgopts 'compat=0.10'
CLUSTER_SIZE=1M
size=128M
options=driver=blkdebug,image.driver=qcow2
nested_opts=image.file.driver=file,image.file.filename=$TEST_IMG
echo
echo "== setting up files =="
TEST_IMG="$TEST_IMG.base" _make_test_img $size
$QEMU_IO -c "write -P 11 0 $size" "$TEST_IMG.base" | _filter_qemu_io
_make_test_img -b "$TEST_IMG.base"
$QEMU_IO -c "write -P 22 0 110M" "$TEST_IMG" | _filter_qemu_io
# Limited to 64k max-transfer
echo
echo "== constrained alignment and max-transfer =="
limits=align=4k,max-transfer=64k
$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \
-c "write -P 33 1000 128k" -c "read -P 33 1000 128k" | _filter_qemu_io
echo
echo "== write zero with constrained max-transfer =="
limits=align=512,max-transfer=64k,opt-write-zero=$CLUSTER_SIZE
$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \
-c "write -z 8003584 2093056" | _filter_qemu_io
# non-power-of-2 write-zero/discard alignments
echo
echo "== non-power-of-2 write zeroes limits =="
limits=align=512,opt-write-zero=15M,max-write-zero=15M,opt-discard=15M,max-discard=15M
$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \
-c "write -z 32M 32M" | _filter_qemu_io
echo
echo "== non-power-of-2 discard limits =="
limits=align=512,opt-write-zero=15M,max-write-zero=15M,opt-discard=15M,max-discard=15M
$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \
-c "discard 80000001 30M" | _filter_qemu_io
echo
echo "== block status smaller than alignment =="
limits=align=4k
$QEMU_IO -c "open -o $options,$limits blkdebug::$TEST_IMG" \
-c "alloc 1 1" -c "alloc 0x6dffff0 1000" -c "alloc 127m 5P" \
-c map | _filter_qemu_io
echo
echo "== verify image content =="
function verify_io()
{
echo read -P 22 0 1000
echo read -P 33 1000 128k
echo read -P 22 132072 7871512
echo read -P 0 8003584 2093056
echo read -P 22 10096640 23457792
echo read -P 0 32M 32M
echo read -P 22 64M 13M
echo read -P 0 77M 29M
echo read -P 22 106M 4M
echo read -P 11 110M 18M
}
verify_io | $QEMU_IO -r "$TEST_IMG" | _filter_qemu_io
$QEMU_IMG map --image-opts "$options,$nested_opts,align=4k" \
| _filter_qemu_img_map
_check_test_img
# success, all done
echo "*** done"
status=0
QA output created by 204
== setting up files ==
Formatting 'TEST_DIR/t.IMGFMT.base', fmt=IMGFMT size=134217728
wrote 134217728/134217728 bytes at offset 0
128 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=134217728 backing_file=TEST_DIR/t.IMGFMT.base
wrote 115343360/115343360 bytes at offset 0
110 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== constrained alignment and max-transfer ==
wrote 131072/131072 bytes at offset 1000
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 131072/131072 bytes at offset 1000
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== write zero with constrained max-transfer ==
wrote 2093056/2093056 bytes at offset 8003584
1.996 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== non-power-of-2 write zeroes limits ==
wrote 33554432/33554432 bytes at offset 33554432
32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== non-power-of-2 discard limits ==
discard 31457280/31457280 bytes at offset 80000001
30 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
== block status smaller than alignment ==
1/1 bytes allocated at offset 1 bytes
16/1000 bytes allocated at offset 110 MiB
0/1048576 bytes allocated at offset 127 MiB
110 MiB (0x6e00000) bytes allocated at offset 0 bytes (0x0)
18 MiB (0x1200000) bytes not allocated at offset 110 MiB (0x6e00000)
== verify image content ==
read 1000/1000 bytes at offset 0
1000 bytes, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 131072/131072 bytes at offset 1000
128 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 7871512/7871512 bytes at offset 132072
7.507 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 2093056/2093056 bytes at offset 8003584
1.996 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 23457792/23457792 bytes at offset 10096640
22.371 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 33554432/33554432 bytes at offset 33554432
32 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 13631488/13631488 bytes at offset 67108864
13 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 30408704/30408704 bytes at offset 80740352
29 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 4194304/4194304 bytes at offset 111149056
4 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
read 18874368/18874368 bytes at offset 115343360
18 MiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
Offset Length File
0 0x800000 TEST_DIR/t.IMGFMT
0x900000 0x2400000 TEST_DIR/t.IMGFMT
0x3c00000 0x1100000 TEST_DIR/t.IMGFMT
0x6a00000 0x400000 TEST_DIR/t.IMGFMT
No errors were found on the image.
*** done
......@@ -140,6 +140,15 @@ _filter_img_create()
_filter_img_info()
{
if [[ "$1" == "--format-specific" ]]; then
local format_specific=1
shift
else
local format_specific=0
fi
discard=0
regex_json_spec_start='^ *"format-specific": \{'
sed -e "s#$IMGPROTO:$TEST_DIR#TEST_DIR#g" \
-e "s#$TEST_DIR#TEST_DIR#g" \
-e "s#$IMGFMT#IMGFMT#g" \
......@@ -160,7 +169,25 @@ _filter_img_info()
-e "/block_state_zero: \\(on\\|off\\)/d" \
-e "/log_size: [0-9]\\+/d" \
-e "s/iters: [0-9]\\+/iters: 1024/" \
-e "s/uuid: [-a-f0-9]\\+/uuid: 00000000-0000-0000-0000-000000000000/"
-e "s/uuid: [-a-f0-9]\\+/uuid: 00000000-0000-0000-0000-000000000000/" | \
while IFS='' read -r line; do
if [[ $format_specific == 1 ]]; then
discard=0
elif [[ $line == "Format specific information:" ]]; then
discard=1
elif [[ $line =~ $regex_json_spec_start ]]; then
discard=2
regex_json_spec_end="^${line%%[^ ]*}\\},? *$"
fi
if [[ $discard == 0 ]]; then
echo "$line"
elif [[ $discard == 1 && ! $line ]]; then
echo
discard=0
elif [[ $discard == 2 && $line =~ $regex_json_spec_end ]]; then
discard=0
fi
done
}
# filter out offsets and file names from qemu-img map; good for both
......
......@@ -338,7 +338,7 @@ _img_info()
-e "s#$IMGFMT#IMGFMT#g" \
-e "/^disk size:/ D" \
-e "/actual-size/ D" | \
while IFS='' read line; do
while IFS='' read -r line; do
if [[ $format_specific == 1 ]]; then
discard=0
elif [[ $line == "Format specific information:" ]]; then
......
......@@ -197,5 +197,7 @@
197 rw auto quick
198 rw auto
200 rw auto
201 rw auto migration
202 rw auto quick
203 rw auto
204 rw auto quick
......@@ -244,7 +244,9 @@ static int qemu_lock_fcntl(int fd, int64_t start, int64_t len, int fl_type)
.l_type = fl_type,
};
qemu_probe_lock_ops();
ret = fcntl(fd, fcntl_op_setlk, &fl);
do {
ret = fcntl(fd, fcntl_op_setlk, &fl);
} while (ret == -1 && errno == EINTR);
return ret == -1 ? -errno : 0;
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册