提交 4c761374 编写于 作者: P Peter Maydell

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

Block layer patches:

- qcow2: Support for external data files
- qcow2: Default to 4KB for the qcow2 cache entry size
- Apply block driver whitelist for -drive format=help
- Several qemu-iotests improvements

# gpg: Signature made Fri 08 Mar 2019 12:54:27 GMT
# gpg:                using RSA key 7F09B272C88F2FD6
# gpg: Good signature from "Kevin Wolf <kwolf@redhat.com>" [full]
# Primary key fingerprint: DC3D EB15 9A9A F95D 3D74  56FE 7F09 B272 C88F 2FD6

* remotes/kevin/tags/for-upstream: (33 commits)
  qcow2 spec: Describe string header extensions
  qemu-iotests: Add dependency to qemu-nbd tool
  ahci-test: Add dependency to qemu-img tool
  qemu-iotests: amend with external data file
  qemu-iotests: General tests for qcow2 with external data file
  qemu-iotests: Preallocation with external data file
  qcow2: Implement data-file-raw create option
  qcow2: Store data file name in the image
  qcow2: Creating images with external data file
  qcow2: Add basic data-file infrastructure
  qcow2: Support external data file in qemu-img check
  qcow2: Return error for snapshot operation with data file
  qcow2: External file I/O
  qcow2: Prepare qcow2_co_block_status() for data file
  qcow2: Return 0/-errno in qcow2_alloc_compressed_cluster_offset()
  qcow2: Don't assume 0 is an invalid cluster offset
  qcow2: Prepare count_contiguous_clusters() for external data file
  qcow2: Prepare qcow2_get_cluster_type() for external data file
  qcow2: Pass bs to qcow2_get_cluster_type()
  qcow2: Basic definitions for external data files
  ...
Signed-off-by: NPeter Maydell <peter.maydell@linaro.org>
......@@ -426,7 +426,7 @@ BlockDriver *bdrv_find_format(const char *format_name)
return bdrv_do_find_format(format_name);
}
int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
static int bdrv_format_is_whitelisted(const char *format_name, bool read_only)
{
static const char *whitelist_rw[] = {
CONFIG_BDRV_RW_WHITELIST
......@@ -441,13 +441,13 @@ int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
}
for (p = whitelist_rw; *p; p++) {
if (!strcmp(drv->format_name, *p)) {
if (!strcmp(format_name, *p)) {
return 1;
}
}
if (read_only) {
for (p = whitelist_ro; *p; p++) {
if (!strcmp(drv->format_name, *p)) {
if (!strcmp(format_name, *p)) {
return 1;
}
}
......@@ -455,6 +455,11 @@ int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
return 0;
}
int bdrv_is_whitelisted(BlockDriver *drv, bool read_only)
{
return bdrv_format_is_whitelisted(drv->format_name, read_only);
}
bool bdrv_uses_whitelist(void)
{
return use_bdrv_whitelist;
......@@ -4147,7 +4152,7 @@ static int qsort_strcmp(const void *a, const void *b)
}
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
void *opaque)
void *opaque, bool read_only)
{
BlockDriver *drv;
int count = 0;
......@@ -4158,6 +4163,11 @@ void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
if (drv->format_name) {
bool found = false;
int i = count;
if (use_bdrv_whitelist && !bdrv_is_whitelisted(drv, read_only)) {
continue;
}
while (formats && i && !found) {
found = !strcmp(formats[--i], drv->format_name);
}
......@@ -4176,6 +4186,11 @@ void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
bool found = false;
int j = count;
if (use_bdrv_whitelist &&
!bdrv_format_is_whitelisted(format_name, read_only)) {
continue;
}
while (formats && j && !found) {
found = !strcmp(formats[--j], format_name);
}
......
......@@ -778,7 +778,8 @@ static int bitmap_list_store(BlockDriverState *bs, Qcow2BitmapList *bm_list,
* directory in-place (actually, turn-off the extension), which is checked
* in qcow2_check_metadata_overlap() */
ret = qcow2_pre_write_overlap_check(
bs, in_place ? QCOW2_OL_BITMAP_DIRECTORY : 0, dir_offset, dir_size);
bs, in_place ? QCOW2_OL_BITMAP_DIRECTORY : 0, dir_offset, dir_size,
false);
if (ret < 0) {
goto fail;
}
......@@ -1224,7 +1225,7 @@ static uint64_t *store_bitmap_data(BlockDriverState *bs,
memset(buf + write_size, 0, s->cluster_size - write_size);
}
ret = qcow2_pre_write_overlap_check(bs, 0, off, s->cluster_size);
ret = qcow2_pre_write_overlap_check(bs, 0, off, s->cluster_size, false);
if (ret < 0) {
error_setg_errno(errp, -ret, "Qcow2 overlap check failed");
goto fail;
......@@ -1292,7 +1293,7 @@ static int store_bitmap(BlockDriverState *bs, Qcow2Bitmap *bm, Error **errp)
}
ret = qcow2_pre_write_overlap_check(bs, 0, tb_offset,
tb_size * sizeof(tb[0]));
tb_size * sizeof(tb[0]), false);
if (ret < 0) {
error_setg_errno(errp, -ret, "Qcow2 overlap check failed");
goto fail;
......
......@@ -205,13 +205,13 @@ static int qcow2_cache_entry_flush(BlockDriverState *bs, Qcow2Cache *c, int i)
if (c == s->refcount_block_cache) {
ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_REFCOUNT_BLOCK,
c->entries[i].offset, c->table_size);
c->entries[i].offset, c->table_size, false);
} else if (c == s->l2_table_cache) {
ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L2,
c->entries[i].offset, c->table_size);
c->entries[i].offset, c->table_size, false);
} else {
ret = qcow2_pre_write_overlap_check(bs, 0,
c->entries[i].offset, c->table_size);
c->entries[i].offset, c->table_size, false);
}
if (ret < 0) {
......
此差异已折叠。
......@@ -1156,8 +1156,20 @@ void qcow2_free_any_clusters(BlockDriverState *bs, uint64_t l2_entry,
int nb_clusters, enum qcow2_discard_type type)
{
BDRVQcow2State *s = bs->opaque;
QCow2ClusterType ctype = qcow2_get_cluster_type(bs, l2_entry);
switch (qcow2_get_cluster_type(l2_entry)) {
if (has_data_file(bs)) {
if (s->discard_passthrough[type] &&
(ctype == QCOW2_CLUSTER_NORMAL ||
ctype == QCOW2_CLUSTER_ZERO_ALLOC))
{
bdrv_pdiscard(s->data_file, l2_entry & L2E_OFFSET_MASK,
nb_clusters << s->cluster_bits);
}
return;
}
switch (ctype) {
case QCOW2_CLUSTER_COMPRESSED:
{
int nb_csectors;
......@@ -1300,7 +1312,7 @@ int qcow2_update_snapshot_refcount(BlockDriverState *bs,
entry &= ~QCOW_OFLAG_COPIED;
offset = entry & L2E_OFFSET_MASK;
switch (qcow2_get_cluster_type(entry)) {
switch (qcow2_get_cluster_type(bs, entry)) {
case QCOW2_CLUSTER_COMPRESSED:
nb_csectors = ((entry >> s->csize_shift) &
s->csize_mask) + 1;
......@@ -1582,7 +1594,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
for(i = 0; i < s->l2_size; i++) {
l2_entry = be64_to_cpu(l2_table[i]);
switch (qcow2_get_cluster_type(l2_entry)) {
switch (qcow2_get_cluster_type(bs, l2_entry)) {
case QCOW2_CLUSTER_COMPRESSED:
/* Compressed clusters don't have QCOW_OFLAG_COPIED */
if (l2_entry & QCOW_OFLAG_COPIED) {
......@@ -1593,6 +1605,13 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
res->corruptions++;
}
if (has_data_file(bs)) {
fprintf(stderr, "ERROR compressed cluster %d with data file, "
"entry=0x%" PRIx64 "\n", i, l2_entry);
res->corruptions++;
break;
}
/* Mark cluster as used */
nb_csectors = ((l2_entry >> s->csize_shift) &
s->csize_mask) + 1;
......@@ -1633,7 +1652,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
/* Correct offsets are cluster aligned */
if (offset_into_cluster(s, offset)) {
if (qcow2_get_cluster_type(l2_entry) ==
if (qcow2_get_cluster_type(bs, l2_entry) ==
QCOW2_CLUSTER_ZERO_ALLOC)
{
fprintf(stderr, "%s offset=%" PRIx64 ": Preallocated zero "
......@@ -1649,7 +1668,7 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
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));
l2e_offset, sizeof(uint64_t), false);
if (ret < 0) {
fprintf(stderr, "ERROR: Overlap check failed\n");
res->check_errors++;
......@@ -1683,11 +1702,13 @@ static int check_refcounts_l2(BlockDriverState *bs, BdrvCheckResult *res,
}
/* Mark cluster as used */
ret = qcow2_inc_refcounts_imrt(bs, res,
refcount_table, refcount_table_size,
offset, s->cluster_size);
if (ret < 0) {
goto fail;
if (!has_data_file(bs)) {
ret = qcow2_inc_refcounts_imrt(bs, res, refcount_table,
refcount_table_size,
offset, s->cluster_size);
if (ret < 0) {
goto fail;
}
}
break;
}
......@@ -1868,16 +1889,20 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
for (j = 0; j < s->l2_size; j++) {
uint64_t l2_entry = be64_to_cpu(l2_table[j]);
uint64_t data_offset = l2_entry & L2E_OFFSET_MASK;
QCow2ClusterType cluster_type = qcow2_get_cluster_type(l2_entry);
QCow2ClusterType cluster_type = qcow2_get_cluster_type(bs, l2_entry);
if (cluster_type == QCOW2_CLUSTER_NORMAL ||
cluster_type == QCOW2_CLUSTER_ZERO_ALLOC) {
ret = qcow2_get_refcount(bs,
data_offset >> s->cluster_bits,
&refcount);
if (ret < 0) {
/* don't print message nor increment check_errors */
continue;
if (has_data_file(bs)) {
refcount = 1;
} else {
ret = qcow2_get_refcount(bs,
data_offset >> s->cluster_bits,
&refcount);
if (ret < 0) {
/* don't print message nor increment check_errors */
continue;
}
}
if ((refcount == 1) != ((l2_entry & QCOW_OFLAG_COPIED) != 0)) {
fprintf(stderr, "%s OFLAG_COPIED data cluster: "
......@@ -1898,7 +1923,8 @@ static int check_oflag_copied(BlockDriverState *bs, BdrvCheckResult *res,
if (l2_dirty) {
ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L2,
l2_offset, s->cluster_size);
l2_offset, s->cluster_size,
false);
if (ret < 0) {
fprintf(stderr, "ERROR: Could not write L2 table; metadata "
"overlap check failed: %s\n", strerror(-ret));
......@@ -2070,6 +2096,12 @@ static int calculate_refcounts(BlockDriverState *bs, BdrvCheckResult *res,
}
/* snapshots */
if (has_data_file(bs) && s->nb_snapshots) {
fprintf(stderr, "ERROR %d snapshots in image with data file\n",
s->nb_snapshots);
res->corruptions++;
}
for (i = 0; i < s->nb_snapshots; i++) {
sn = s->snapshots + i;
if (offset_into_cluster(s, sn->l1_table_offset)) {
......@@ -2366,7 +2398,7 @@ write_refblocks:
}
ret = qcow2_pre_write_overlap_check(bs, 0, refblock_offset,
s->cluster_size);
s->cluster_size, false);
if (ret < 0) {
fprintf(stderr, "ERROR writing refblock: %s\n", strerror(-ret));
goto fail;
......@@ -2417,7 +2449,8 @@ write_refblocks:
}
ret = qcow2_pre_write_overlap_check(bs, 0, reftable_offset,
reftable_size * sizeof(uint64_t));
reftable_size * sizeof(uint64_t),
false);
if (ret < 0) {
fprintf(stderr, "ERROR writing reftable: %s\n", strerror(-ret));
goto fail;
......@@ -2751,10 +2784,15 @@ QEMU_BUILD_BUG_ON(QCOW2_OL_MAX_BITNR != ARRAY_SIZE(metadata_ol_names));
* overlaps; or a negative value (-errno) on error.
*/
int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
int64_t size)
int64_t size, bool data_file)
{
int ret = qcow2_check_metadata_overlap(bs, ign, offset, size);
int ret;
if (data_file && has_data_file(bs)) {
return 0;
}
ret = qcow2_check_metadata_overlap(bs, ign, offset, size);
if (ret < 0) {
return ret;
} else if (ret > 0) {
......@@ -2855,7 +2893,8 @@ static int flush_refblock(BlockDriverState *bs, uint64_t **reftable,
if (reftable_index < *reftable_size && (*reftable)[reftable_index]) {
offset = (*reftable)[reftable_index];
ret = qcow2_pre_write_overlap_check(bs, 0, offset, s->cluster_size);
ret = qcow2_pre_write_overlap_check(bs, 0, offset, s->cluster_size,
false);
if (ret < 0) {
error_setg_errno(errp, -ret, "Overlap check failed");
return ret;
......@@ -3121,7 +3160,8 @@ int qcow2_change_refcount_order(BlockDriverState *bs, int refcount_order,
/* Write the new reftable */
ret = qcow2_pre_write_overlap_check(bs, 0, new_reftable_offset,
new_reftable_size * sizeof(uint64_t));
new_reftable_size * sizeof(uint64_t),
false);
if (ret < 0) {
error_setg_errno(errp, -ret, "Overlap check failed");
goto done;
......
......@@ -184,7 +184,7 @@ static int qcow2_write_snapshots(BlockDriverState *bs)
/* The snapshot list position has not yet been updated, so these clusters
* must indeed be completely free */
ret = qcow2_pre_write_overlap_check(bs, 0, offset, snapshots_size);
ret = qcow2_pre_write_overlap_check(bs, 0, offset, snapshots_size, false);
if (ret < 0) {
goto fail;
}
......@@ -353,6 +353,10 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
return -EFBIG;
}
if (has_data_file(bs)) {
return -ENOTSUP;
}
memset(sn, 0, sizeof(*sn));
/* Generate an ID */
......@@ -389,7 +393,7 @@ int qcow2_snapshot_create(BlockDriverState *bs, QEMUSnapshotInfo *sn_info)
}
ret = qcow2_pre_write_overlap_check(bs, 0, sn->l1_table_offset,
s->l1_size * sizeof(uint64_t));
s->l1_size * sizeof(uint64_t), false);
if (ret < 0) {
goto fail;
}
......@@ -466,6 +470,10 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
int ret;
uint64_t *sn_l1_table = NULL;
if (has_data_file(bs)) {
return -ENOTSUP;
}
/* Search the snapshot */
snapshot_index = find_snapshot_by_id_or_name(bs, snapshot_id);
if (snapshot_index < 0) {
......@@ -528,7 +536,8 @@ int qcow2_snapshot_goto(BlockDriverState *bs, const char *snapshot_id)
}
ret = qcow2_pre_write_overlap_check(bs, QCOW2_OL_ACTIVE_L1,
s->l1_table_offset, cur_l1_bytes);
s->l1_table_offset, cur_l1_bytes,
false);
if (ret < 0) {
goto fail;
}
......@@ -598,6 +607,10 @@ int qcow2_snapshot_delete(BlockDriverState *bs,
QCowSnapshot sn;
int snapshot_index, ret;
if (has_data_file(bs)) {
return -ENOTSUP;
}
/* Search the snapshot */
snapshot_index = find_snapshot_by_id_and_name(bs, snapshot_id, name);
if (snapshot_index < 0) {
......@@ -669,6 +682,9 @@ int qcow2_snapshot_list(BlockDriverState *bs, QEMUSnapshotInfo **psn_tab)
QCowSnapshot *sn;
int i;
if (has_data_file(bs)) {
return -ENOTSUP;
}
if (!s->nb_snapshots) {
*psn_tab = NULL;
return s->nb_snapshots;
......
此差异已折叠。
......@@ -91,6 +91,7 @@
#define DEFAULT_CLUSTER_SIZE 65536
#define QCOW2_OPT_DATA_FILE "data-file"
#define QCOW2_OPT_LAZY_REFCOUNTS "lazy-refcounts"
#define QCOW2_OPT_DISCARD_REQUEST "pass-discard-request"
#define QCOW2_OPT_DISCARD_SNAPSHOT "pass-discard-snapshot"
......@@ -197,13 +198,16 @@ enum {
/* Incompatible feature bits */
enum {
QCOW2_INCOMPAT_DIRTY_BITNR = 0,
QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
QCOW2_INCOMPAT_CORRUPT = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY
| QCOW2_INCOMPAT_CORRUPT,
QCOW2_INCOMPAT_DIRTY_BITNR = 0,
QCOW2_INCOMPAT_CORRUPT_BITNR = 1,
QCOW2_INCOMPAT_DATA_FILE_BITNR = 2,
QCOW2_INCOMPAT_DIRTY = 1 << QCOW2_INCOMPAT_DIRTY_BITNR,
QCOW2_INCOMPAT_CORRUPT = 1 << QCOW2_INCOMPAT_CORRUPT_BITNR,
QCOW2_INCOMPAT_DATA_FILE = 1 << QCOW2_INCOMPAT_DATA_FILE_BITNR,
QCOW2_INCOMPAT_MASK = QCOW2_INCOMPAT_DIRTY
| QCOW2_INCOMPAT_CORRUPT
| QCOW2_INCOMPAT_DATA_FILE,
};
/* Compatible feature bits */
......@@ -216,10 +220,13 @@ enum {
/* Autoclear feature bits */
enum {
QCOW2_AUTOCLEAR_BITMAPS_BITNR = 0,
QCOW2_AUTOCLEAR_BITMAPS = 1 << QCOW2_AUTOCLEAR_BITMAPS_BITNR,
QCOW2_AUTOCLEAR_BITMAPS_BITNR = 0,
QCOW2_AUTOCLEAR_DATA_FILE_RAW_BITNR = 1,
QCOW2_AUTOCLEAR_BITMAPS = 1 << QCOW2_AUTOCLEAR_BITMAPS_BITNR,
QCOW2_AUTOCLEAR_DATA_FILE_RAW = 1 << QCOW2_AUTOCLEAR_DATA_FILE_RAW_BITNR,
QCOW2_AUTOCLEAR_MASK = QCOW2_AUTOCLEAR_BITMAPS,
QCOW2_AUTOCLEAR_MASK = QCOW2_AUTOCLEAR_BITMAPS
| QCOW2_AUTOCLEAR_DATA_FILE_RAW,
};
enum qcow2_discard_type {
......@@ -337,9 +344,12 @@ typedef struct BDRVQcow2State {
* override) */
char *image_backing_file;
char *image_backing_format;
char *image_data_file;
CoQueue compress_wait_queue;
int nb_compress_threads;
BdrvChild *data_file;
} BDRVQcow2State;
typedef struct Qcow2COWRegion {
......@@ -457,6 +467,20 @@ typedef enum QCow2MetadataOverlap {
#define REFT_OFFSET_MASK 0xfffffffffffffe00ULL
#define INV_OFFSET (-1ULL)
static inline bool has_data_file(BlockDriverState *bs)
{
BDRVQcow2State *s = bs->opaque;
return (s->data_file != bs->file);
}
static inline bool data_file_is_raw(BlockDriverState *bs)
{
BDRVQcow2State *s = bs->opaque;
return !!(s->autoclear_features & QCOW2_AUTOCLEAR_DATA_FILE_RAW);
}
static inline int64_t start_of_cluster(BDRVQcow2State *s, int64_t offset)
{
return offset & ~(s->cluster_size - 1);
......@@ -498,7 +522,8 @@ static inline int64_t qcow2_vm_state_offset(BDRVQcow2State *s)
return (int64_t)s->l1_vm_state_index << (s->cluster_bits + s->l2_bits);
}
static inline QCow2ClusterType qcow2_get_cluster_type(uint64_t l2_entry)
static inline QCow2ClusterType qcow2_get_cluster_type(BlockDriverState *bs,
uint64_t l2_entry)
{
if (l2_entry & QCOW_OFLAG_COMPRESSED) {
return QCOW2_CLUSTER_COMPRESSED;
......@@ -508,7 +533,15 @@ static inline QCow2ClusterType qcow2_get_cluster_type(uint64_t l2_entry)
}
return QCOW2_CLUSTER_ZERO_PLAIN;
} else if (!(l2_entry & L2E_OFFSET_MASK)) {
return QCOW2_CLUSTER_UNALLOCATED;
/* Offset 0 generally means unallocated, but it is ambiguous with
* external data files because 0 is a valid offset there. However, all
* clusters in external data files always have refcount 1, so we can
* rely on QCOW_OFLAG_COPIED to disambiguate. */
if (has_data_file(bs) && (l2_entry & QCOW_OFLAG_COPIED)) {
return QCOW2_CLUSTER_NORMAL;
} else {
return QCOW2_CLUSTER_UNALLOCATED;
}
} else {
return QCOW2_CLUSTER_NORMAL;
}
......@@ -599,7 +632,7 @@ void qcow2_process_discards(BlockDriverState *bs, int ret);
int qcow2_check_metadata_overlap(BlockDriverState *bs, int ign, int64_t offset,
int64_t size);
int qcow2_pre_write_overlap_check(BlockDriverState *bs, int ign, int64_t offset,
int64_t size);
int64_t size, bool data_file);
int qcow2_inc_refcounts_imrt(BlockDriverState *bs, BdrvCheckResult *res,
void **refcount_table,
int64_t *refcount_table_size,
......@@ -624,9 +657,10 @@ int qcow2_get_cluster_offset(BlockDriverState *bs, uint64_t offset,
int qcow2_alloc_cluster_offset(BlockDriverState *bs, uint64_t offset,
unsigned int *bytes, uint64_t *host_offset,
QCowL2Meta **m);
uint64_t qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
uint64_t offset,
int compressed_size);
int qcow2_alloc_compressed_cluster_offset(BlockDriverState *bs,
uint64_t offset,
int compressed_size,
uint64_t *host_offset);
int qcow2_alloc_cluster_link_l2(BlockDriverState *bs, QCowL2Meta *m);
void qcow2_alloc_cluster_abort(BlockDriverState *bs, QCowL2Meta *m);
......
......@@ -531,7 +531,9 @@ static BlockBackend *blockdev_init(const char *file, QDict *bs_opts,
if ((buf = qemu_opt_get(opts, "format")) != NULL) {
if (is_help_option(buf)) {
error_printf("Supported formats:");
bdrv_iterate_format(bdrv_format_print, NULL);
bdrv_iterate_format(bdrv_format_print, NULL, false);
error_printf("\nSupported formats (read-only):");
bdrv_iterate_format(bdrv_format_print, NULL, true);
error_printf("\n");
goto early_err;
}
......
......@@ -97,7 +97,19 @@ in the description of a field.
be written to (unless for regaining
consistency).
Bits 2-63: Reserved (set to 0)
Bit 2: External data file bit. If this bit is set, an
external data file is used. Guest clusters are
then stored in the external data file. For such
images, clusters in the external data file are
not refcounted. The offset field in the
Standard Cluster Descriptor must match the
guest offset and neither compressed clusters
nor internal snapshots are supported.
An External Data File Name header extension may
be present if this bit is set.
Bits 3-63: Reserved (set to 0)
80 - 87: compatible_features
Bitmask of compatible features. An implementation can
......@@ -126,7 +138,21 @@ in the description of a field.
bit is unset, the bitmaps extension data must be
considered inconsistent.
Bits 1-63: Reserved (set to 0)
Bit 1: If this bit is set, the external data file can
be read as a consistent standalone raw image
without looking at the qcow2 metadata.
Setting this bit has a performance impact for
some operations on the image (e.g. writing
zeros requires writing to the data file instead
of only setting the zero flag in the L2 table
entry) and conflicts with backing files.
This bit may only be set if the External Data
File bit (incompatible feature bit 1) is also
set.
Bits 2-63: Reserved (set to 0)
96 - 99: refcount_order
Describes the width of a reference count block entry (width
......@@ -144,10 +170,11 @@ be stored. Each extension has a structure like the following:
Byte 0 - 3: Header extension type:
0x00000000 - End of the header extension area
0xE2792ACA - Backing file format name
0xE2792ACA - Backing file format name string
0x6803f857 - Feature name table
0x23852875 - Bitmaps extension
0x0537be77 - Full disk encryption header pointer
0x44415441 - External data file name string
other - Unknown header extension, can be safely
ignored
......@@ -169,6 +196,16 @@ data of compatible features that it doesn't support. Compatible features that
need space for additional data can use a header extension.
== String header extensions ==
Some header extensions (such as the backing file format name and the external
data file name) are just a single string. In this case, the header extension
length is the string length and the string is not '\0' terminated. (The header
extension padding can make it look like a string is '\0' terminated, but
neither is padding always necessary nor is there a guarantee that zero bytes
are used for padding.)
== Feature name table ==
The feature name table is an optional header extension that contains the name
......@@ -437,6 +474,11 @@ L2 table entry:
This information is only accurate in L2 tables
that are reachable from the active L1 table.
With external data files, all guest clusters have an
implicit refcount of 1 (because of the fixed host = guest
mapping for guest cluster offsets), so this bit should be 1
for all allocated clusters.
Standard Cluster Descriptor:
Bit 0: If set to 1, the cluster reads as all zeros. The host
......@@ -450,8 +492,10 @@ Standard Cluster Descriptor:
1 - 8: Reserved (set to 0)
9 - 55: Bits 9-55 of host cluster offset. Must be aligned to a
cluster boundary. If the offset is 0, the cluster is
unallocated.
cluster boundary. If the offset is 0 and bit 63 is clear,
the cluster is unallocated. The offset may only be 0 with
bit 63 set (indicating a host cluster offset of 0) when an
external data file is used.
56 - 61: Reserved (set to 0)
......
......@@ -158,10 +158,10 @@ refcount cache is as small as possible unless overridden by the user.
Using smaller cache entries
---------------------------
The qcow2 L2 cache stores complete tables by default. This means that
if QEMU needs an entry from an L2 table then the whole table is read
from disk and is kept in the cache. If the cache is full then a
complete table needs to be evicted first.
The qcow2 L2 cache can store complete tables. This means that if QEMU
needs an entry from an L2 table then the whole table is read from disk
and is kept in the cache. If the cache is full then a complete table
needs to be evicted first.
This can be inefficient with large cluster sizes since it results in
more disk I/O and wastes more cache memory.
......@@ -172,6 +172,9 @@ it smaller than the cluster size. This can be configured using the
-drive file=hd.qcow2,l2-cache-size=2097152,l2-cache-entry-size=4096
Since QEMU 4.0 the value of l2-cache-entry-size defaults to 4KB (or
the cluster size if it's smaller).
Some things to take into account:
- The L2 cache entry size has the same restrictions as the cluster
......@@ -185,7 +188,8 @@ Some things to take into account:
- Try different entry sizes to see which one gives faster performance
in your case. The block size of the host filesystem is generally a
good default (usually 4096 bytes in the case of ext4).
good default (usually 4096 bytes in the case of ext4, hence the
default).
- Only the L2 cache can be configured this way. The refcount cache
always uses the cluster size as the entry size.
......@@ -194,7 +198,8 @@ Some things to take into account:
(as explained in the "Choosing the right cache sizes" and "How to
configure the cache sizes" sections in this document) then none of
this is necessary and you can omit the "l2-cache-entry-size"
parameter altogether.
parameter altogether. In this case QEMU makes the entry size
equal to the cluster size by default.
Reducing the memory usage
......
......@@ -472,7 +472,7 @@ void bdrv_next_cleanup(BdrvNextIterator *it);
BlockDriverState *bdrv_next_monitor_owned(BlockDriverState *bs);
bool bdrv_is_encrypted(BlockDriverState *bs);
void bdrv_iterate_format(void (*it)(void *opaque, const char *name),
void *opaque);
void *opaque, bool read_only);
const char *bdrv_get_node_name(const BlockDriverState *bs);
const char *bdrv_get_device_name(const BlockDriverState *bs);
const char *bdrv_get_device_or_node_name(const BlockDriverState *bs);
......
......@@ -56,6 +56,8 @@
#define BLOCK_OPT_NOCOW "nocow"
#define BLOCK_OPT_OBJECT_SIZE "object_size"
#define BLOCK_OPT_REFCOUNT_BITS "refcount_bits"
#define BLOCK_OPT_DATA_FILE "data_file"
#define BLOCK_OPT_DATA_FILE_RAW "data_file_raw"
#define BLOCK_PROBE_BUF_SIZE 512
......
......@@ -59,6 +59,13 @@
#
# @compat: compatibility level
#
# @data-file: the filename of the external data file that is stored in the
# image and used as a default for opening the image (since: 4.0)
#
# @data-file-raw: True if the external data file must stay valid as a
# standalone (read-only) raw image without looking at qcow2
# metadata (since: 4.0)
#
# @lazy-refcounts: on or off; only valid for compat >= 1.1
#
# @corrupt: true if the image has been marked corrupt; only valid for
......@@ -76,6 +83,8 @@
{ 'struct': 'ImageInfoSpecificQCow2',
'data': {
'compat': 'str',
'*data-file': 'str',
'*data-file-raw': 'bool',
'*lazy-refcounts': 'bool',
'*corrupt': 'bool',
'refcount-bits': 'int',
......@@ -3080,6 +3089,12 @@
# encrypted images, except when doing a metadata-only
# probe of the image. (since 2.10)
#
# @data-file: reference to or definition of the external data file.
# This may only be specified for images that require an
# external data file. If it is not specified for such
# an image, the data file name is loaded from the image
# file. (since 4.0)
#
# Since: 2.9
##
{ 'struct': 'BlockdevOptionsQcow2',
......@@ -3094,7 +3109,8 @@
'*l2-cache-entry-size': 'int',
'*refcount-cache-size': 'int',
'*cache-clean-interval': 'int',
'*encrypt': 'BlockdevQcow2Encryption' } }
'*encrypt': 'BlockdevQcow2Encryption',
'*data-file': 'BlockdevRef' } }
##
# @SshHostKeyCheckMode:
......@@ -4130,6 +4146,12 @@
# Driver specific image creation options for qcow2.
#
# @file Node to create the image format on
# @data-file Node to use as an external data file in which all guest
# data is stored so that only metadata remains in the qcow2
# file (since: 4.0)
# @data-file-raw True if the external data file must stay valid as a
# standalone (read-only) raw image without looking at qcow2
# metadata (default: false; since: 4.0)
# @size Size of the virtual disk in bytes
# @version Compatibility level (default: v3)
# @backing-file File name of the backing file if a backing file
......@@ -4145,6 +4167,8 @@
##
{ 'struct': 'BlockdevCreateOptionsQcow2',
'data': { 'file': 'BlockdevRef',
'*data-file': 'BlockdevRef',
'*data-file-raw': 'bool',
'size': 'size',
'*version': 'BlockdevQcow2Version',
'*backing-file': 'str',
......
......@@ -198,7 +198,7 @@ static void QEMU_NORETURN help(void)
" 'skip=N' skip N bs-sized blocks at the start of input\n";
printf("%s\nSupported formats:", help_msg);
bdrv_iterate_format(format_print, NULL);
bdrv_iterate_format(format_print, NULL, false);
printf("\n\n" QEMU_HELP_BOTTOM "\n");
exit(EXIT_SUCCESS);
}
......
......@@ -780,7 +780,7 @@ tests/prom-env-test$(EXESUF): tests/prom-env-test.o $(libqos-obj-y)
tests/rtas-test$(EXESUF): tests/rtas-test.o $(libqos-spapr-obj-y)
tests/fdc-test$(EXESUF): tests/fdc-test.o
tests/ide-test$(EXESUF): tests/ide-test.o $(libqos-pc-obj-y)
tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y)
tests/ahci-test$(EXESUF): tests/ahci-test.o $(libqos-pc-obj-y) qemu-img$(EXESUF)
tests/ipmi-kcs-test$(EXESUF): tests/ipmi-kcs-test.o
tests/ipmi-bt-test$(EXESUF): tests/ipmi-bt-test.o
tests/hd-geo-test$(EXESUF): tests/hd-geo-test.o
......@@ -1101,7 +1101,7 @@ clean-tcg: $(CLEAN_TCG_TARGET_RULES)
QEMU_IOTESTS_HELPERS-$(call land,$(CONFIG_SOFTMMU),$(CONFIG_LINUX)) = tests/qemu-iotests/socket_scm_helper$(EXESUF)
.PHONY: check-tests/qemu-iotests-quick.sh
check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF) qemu-io$(EXESUF) $(QEMU_IOTESTS_HELPERS-y)
check-tests/qemu-iotests-quick.sh: tests/qemu-iotests-quick.sh qemu-img$(EXESUF) qemu-io$(EXESUF) qemu-nbd$(EXESUF) $(QEMU_IOTESTS_HELPERS-y)
$<
.PHONY: $(patsubst %, check-%, $(check-qapi-schema-y))
......
#!/bin/bash
#!/usr/bin/env bash
# Copyright (c) 2013 Kevin Wolf <kwolf@redhat.com>
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test simple read/write using plain bdrv_read/bdrv_write
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test simple read/write using plain bdrv_pread/bdrv_pwrite
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test simple read/write using bdrv_aio_readv/bdrv_aio_writev
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Make sure we can't read and write outside of the image size.
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Make sure qemu-img can create 5TB images
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Check for one possible case of qcow2 refcount corruption.
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test simple asynchronous read/write operations.
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Nolan I qcow2 corruption - incorrectly reports free clusters
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Nolan II qcow2 corruption - wrong used cluster
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test for AIO allocation on the same cluster
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Make sure we can open read-only images
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# qcow2 pattern test, empty and compressed image - 4k cluster patterns
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# qcow2 pattern test, complex patterns including compression and snapshots
# Using patterns for 4k cluster size.
......
#!/bin/bash
#!/usr/bin/env bash
#
# Combined test to grow the refcount table and test snapshots.
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Simple backing file reads
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Merge backing file into test image when converting the image
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# When using a backing file for the output image in qemu-img convert,
# the backing file clusters must not copied. The data must still be
......
#!/bin/bash
#!/usr/bin/env bash
#
# Commit changes to backing file
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test handling of invalid patterns arguments to qemu-io
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test bdrv_load/save_vmstate using the usual patterns
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# qcow2 pattern test with various cluster sizes
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Rebasing COW images
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Resizing images
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# qcow2 error path testing
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test that sub-cluster allocating writes zero the rest of the cluster
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test that backing files can be smaller than the image
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# qcow2 internal snapshots/VM state tests
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test that all qcow2 header extensions survive a header rewrite
#
......
......@@ -117,7 +117,7 @@ header_length 104
Header extension:
magic 0x6803f857
length 144
length 192
data <binary>
Header extension:
......@@ -150,7 +150,7 @@ header_length 104
Header extension:
magic 0x6803f857
length 144
length 192
data <binary>
Header extension:
......@@ -164,7 +164,7 @@ No errors were found on the image.
magic 0x514649fb
version 3
backing_file_offset 0x148
backing_file_offset 0x178
backing_file_size 0x17
cluster_bits 16
size 67108864
......@@ -188,7 +188,7 @@ data 'host_device'
Header extension:
magic 0x6803f857
length 144
length 192
data <binary>
Header extension:
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test that AIO requests are drained before an image is closed. This used
# to segfault because the request coroutine kept running even after the
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test aligned and misaligned write zeroes operations.
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test bdrv_pwrite_zeroes with backing files (see also 154)
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Let a few AIO requests run in parallel and have them access different L2
# tables so that the cache has a chance to get used up.
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test qcow2 feature bits
#
......
......@@ -58,7 +58,7 @@ header_length 104
Header extension:
magic 0x6803f857
length 144
length 192
data <binary>
......@@ -86,7 +86,7 @@ header_length 104
Header extension:
magic 0x6803f857
length 144
length 192
data <binary>
*** done
#!/bin/bash
#!/usr/bin/env bash
#
# Test COW from backing files
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test COW from backing files with AIO
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test qcow2 lazy refcounts
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test qemu-img operation on zero size images
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test that qemu-img info --backing-chain detects infinite loops
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test concurrent cluster allocations
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Regression test for commit b7ab0fea (which was a corruption fix,
# despite the commit message claiming otherwise)
......
#!/bin/bash
#!/usr/bin/env bash
##
## qemu-img compare test
##
......
#!/bin/bash
#!/usr/bin/env bash
#
# Check qemu-img option parsing
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test qemu-img rebase with zero clusters
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test command line configuration of block devices and driver-specific options
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test bdrv_read/bdrv_write using BDRV_O_SNAPSHOT
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test qemu-img convert when image length is not a multiple of cluster size
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test huge qcow2 images
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test export internal snapshot by qemu-nbd, convert it by qemu-img.
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test case for vmdk
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test case for image corruption (overlapping data structures) in qcow2
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test case for image option amendment in qcow2.
#
......@@ -28,7 +28,8 @@ status=1 # failure is the default!
_cleanup()
{
_cleanup_test_img
_cleanup_test_img
rm -f $TEST_IMG.data
}
trap "_cleanup; exit \$status" 0 1 2 3 15
......@@ -250,6 +251,48 @@ $QEMU_IMG snapshot -c foo "$TEST_IMG"
$QEMU_IMG amend -p -o "compat=0.10" "$TEST_IMG"
_check_test_img
echo
echo "=== Testing version downgrade with external data file ==="
echo
IMGOPTS="compat=1.1,data_file=$TEST_IMG.data" _make_test_img 64M
$QEMU_IMG amend -o "compat=0.10" "$TEST_IMG"
_img_info --format-specific
_check_test_img
echo
echo "=== Try changing the external data file ==="
echo
IMGOPTS="compat=1.1" _make_test_img 64M
$QEMU_IMG amend -o "data_file=foo" "$TEST_IMG"
echo
IMGOPTS="compat=1.1,data_file=$TEST_IMG.data" _make_test_img 64M
$QEMU_IMG amend -o "data_file=foo" "$TEST_IMG"
_img_info --format-specific
TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts
echo
$QEMU_IMG amend -o "data_file=" --image-opts "data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG"
_img_info --format-specific
TEST_IMG="data-file.filename=$TEST_IMG.data,file.filename=$TEST_IMG" _img_info --format-specific --image-opts
echo
echo "=== Clearing and setting data-file-raw ==="
echo
IMGOPTS="compat=1.1,data_file=$TEST_IMG.data,data_file_raw=on" _make_test_img 64M
$QEMU_IMG amend -o "data_file_raw=on" "$TEST_IMG"
_img_info --format-specific
_check_test_img
$QEMU_IMG amend -o "data_file_raw=off" "$TEST_IMG"
_img_info --format-specific
_check_test_img
$QEMU_IMG amend -o "data_file_raw=on" "$TEST_IMG"
_img_info --format-specific
_check_test_img
# success, all done
echo "*** done"
rm -f $seq.full
......
......@@ -26,7 +26,7 @@ header_length 104
Header extension:
magic 0x6803f857
length 144
length 192
data <binary>
magic 0x514649fb
......@@ -84,7 +84,7 @@ header_length 104
Header extension:
magic 0x6803f857
length 144
length 192
data <binary>
magic 0x514649fb
......@@ -144,7 +144,7 @@ header_length 104
Header extension:
magic 0x6803f857
length 144
length 192
data <binary>
ERROR cluster 5 refcount=0 reference=1
......@@ -199,7 +199,7 @@ header_length 104
Header extension:
magic 0x6803f857
length 144
length 192
data <binary>
magic 0x514649fb
......@@ -268,7 +268,7 @@ header_length 104
Header extension:
magic 0x6803f857
length 144
length 192
data <binary>
read 65536/65536 bytes at offset 44040192
......@@ -306,7 +306,7 @@ header_length 104
Header extension:
magic 0x6803f857
length 144
length 192
data <binary>
ERROR cluster 5 refcount=0 reference=1
......@@ -335,7 +335,7 @@ header_length 104
Header extension:
magic 0x6803f857
length 144
length 192
data <binary>
read 131072/131072 bytes at offset 0
......@@ -488,4 +488,93 @@ wrote 65536/65536 bytes at offset 3221225472
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
(0.00/100%) (6.25/100%) (12.50/100%) (18.75/100%) (25.00/100%) (31.25/100%) (37.50/100%) (43.75/100%) (50.00/100%) (56.25/100%) (62.50/100%) (68.75/100%) (75.00/100%) (81.25/100%) (87.50/100%) (93.75/100%) (100.00/100%) (100.00/100%)
No errors were found on the image.
=== Testing version downgrade with external data file ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data
qemu-img: Cannot downgrade an image with a data file
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64M (67108864 bytes)
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
data file: TEST_DIR/t.IMGFMT.data
data file raw: false
corrupt: false
No errors were found on the image.
=== Try changing the external data file ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
qemu-img: data-file can only be set for images that use an external data file
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': Could not open 'foo': No such file or directory
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64M (67108864 bytes)
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
data file: foo
data file raw: false
corrupt: false
qemu-img: Could not open 'TEST_DIR/t.IMGFMT': 'data-file' is required for this image
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64M (67108864 bytes)
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
data file raw: false
corrupt: false
=== Clearing and setting data-file-raw ===
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 data_file=TEST_DIR/t.IMGFMT.data data_file_raw=on
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64M (67108864 bytes)
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
data file: TEST_DIR/t.IMGFMT.data
data file raw: true
corrupt: false
No errors were found on the image.
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64M (67108864 bytes)
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
data file: TEST_DIR/t.IMGFMT.data
data file raw: false
corrupt: false
No errors were found on the image.
qemu-img: data-file-raw cannot be set on existing images
image: TEST_DIR/t.IMGFMT
file format: IMGFMT
virtual size: 64M (67108864 bytes)
cluster_size: 65536
Format specific information:
compat: 1.1
lazy refcounts: false
refcount bits: 16
data file: TEST_DIR/t.IMGFMT.data
data file raw: false
corrupt: false
No errors were found on the image.
*** done
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test case for snapshotting images with unallocated zero clusters in
# qcow2
......
#!/bin/bash
#!/usr/bin/env bash
#
# test of qemu-img convert -n - convert without creation
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test VHDX read/write from a sample image created with Hyper-V
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test case for preallocated zero clusters in qcow2
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test automatic deletion of BDSes created by -drive/drive_add
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test case for loading a saved VM state from a qcow2 image
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test case for deleting a backing file
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test VHDX log replay from an image with a journal that needs to be
# replayed
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test case for the QMP blkdebug and blkverify interfaces
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test case for nested image formats
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test count_contiguous_clusters in qcow2
#
......
#!/bin/bash
#!/usr/bin/env bash
##
## qemu-img compare test (qcow2 only ones)
##
......
#!/bin/bash
#!/usr/bin/env bash
#
# cloop format input validation tests
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# parallels format input validation tests
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test concurrent pread/pwrite
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# bochs format input validation tests
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test qcow2 preallocation with different cluster_sizes
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# qcow2 format input validation tests
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test Quorum block driver
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test qemu-img command line parsing
#
......
......@@ -48,6 +48,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -69,6 +71,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -90,6 +94,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -111,6 +117,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -132,6 +140,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -153,6 +163,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -174,6 +186,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -195,6 +209,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -231,6 +247,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -304,6 +322,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -325,6 +345,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -346,6 +368,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -367,6 +391,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -388,6 +414,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -409,6 +437,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -430,6 +460,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -451,6 +483,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -487,6 +521,8 @@ Supported options:
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -568,6 +604,8 @@ Creation options for 'qcow2':
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -590,6 +628,8 @@ Creation options for 'qcow2':
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -612,6 +652,8 @@ Creation options for 'qcow2':
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -634,6 +676,8 @@ Creation options for 'qcow2':
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -656,6 +700,8 @@ Creation options for 'qcow2':
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -678,6 +724,8 @@ Creation options for 'qcow2':
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -700,6 +748,8 @@ Creation options for 'qcow2':
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -722,6 +772,8 @@ Creation options for 'qcow2':
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......@@ -761,6 +813,8 @@ Creation options for 'qcow2':
backing_fmt=<str> - Image format of the base image
cluster_size=<size> - qcow2 cluster size
compat=<str> - Compatibility level (0.10 or 1.1)
data_file=<str> - File name of an external data file
data_file_raw=<bool (on/off)> - The external data file must stay valid as a raw image
encrypt.cipher-alg=<str> - Name of encryption cipher algorithm
encrypt.cipher-mode=<str> - Name of encryption cipher mode
encrypt.format=<str> - Encrypt the image, format choices: 'aes', 'luks'
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test NBD client unexpected disconnect
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test case for VDI header corruption; image too large, and too many blocks.
# Also simple test for creating dynamic and static VDI images.
......
#!/bin/bash
#!/usr/bin/env bash
#
# Live snapshot tests
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test qemu-img progress output
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test unsupported blockdev-add cases
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# vpc (VHD) format input validation tests
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test case for support of JSON filenames
#
......
#!/bin/bash
#!/usr/bin/env bash
#
# Test for discarding compressed clusters on qcow2 images
#
......
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
此差异已折叠。
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册