Block patches for the block queue

-----BEGIN PGP SIGNATURE-----
 
 iQEcBAABAgAGBQJZLDDwAAoJEPQH2wBh1c9ABMIH/2TbW4IhYcQ6ONgRbRMK//at
 /WxRbRb6B+POHFKQta6qNuFW/fkhnQ7JiZhkwvcudehx84zn+LaUHbIASzbvI3Fv
 Jf/rFZBOh8L+O8aBRn0Ax6u6NecIg8Sq4F1QiKd9I0j99cSjYQgKNCNpFAov61Dq
 eGo+D1Bz9x2tL7WH5swWUQ5+62ko5zvbRpZP45ADVhHS0HUlLGBqnwKMmoF2COqJ
 cZ3gDyV0Gk3ZOa0fi0t0us2mLhi9bo1ZKUmRQn6lNT1lpBFu5RlQ43mZih1uZyEs
 1sCOgD9qlZF5gsxe8sYIN9QTTwaB7QgyBJCckhSg3NV16k1oM2Q97kV5mCQGQkY=
 =BasH
 -----END PGP SIGNATURE-----

Merge remote-tracking branch 'mreitz/tags/pull-block-2017-05-29-v3' into queue-block

Block patches for the block queue

# gpg: Signature made Mon May 29 16:32:16 2017 CEST
# gpg:                using RSA key 0xF407DB0061D5CF40
# gpg: Good signature from "Max Reitz <mreitz@redhat.com>"
# Primary key fingerprint: 91BE B60A 30DB 3E88 57D1  1829 F407 DB00 61D5 CF40

* mreitz/tags/pull-block-2017-05-29-v3:
  block/file-*: *_parse_filename() and colons
  block: Fix backing paths for filenames with colons
  block: Tweak error message related to qemu-img amend
  qemu-img: Fix leakage of options on error
  qemu-img: copy *key-secret opts when opening newly created files
  qemu-img: introduce --target-image-opts for 'convert' command
  qemu-img: fix --image-opts usage with dd command
  qemu-img: add support for --object with 'dd' command
  qemu-img: Fix documentation of convert
  qcow2: remove extra local_error variable

Signed-off-by: Kevin Wolf <kwolf@redhat.com>
This commit is contained in:
Kevin Wolf 2017-05-29 16:34:27 +02:00
commit 42a4812841
10 changed files with 188 additions and 70 deletions

50
block.c
View File

@ -163,11 +163,16 @@ void path_combine(char *dest, int dest_size,
if (path_is_absolute(filename)) { if (path_is_absolute(filename)) {
pstrcpy(dest, dest_size, filename); pstrcpy(dest, dest_size, filename);
} else { } else {
p = strchr(base_path, ':'); const char *protocol_stripped = NULL;
if (p)
p++; if (path_has_protocol(base_path)) {
else protocol_stripped = strchr(base_path, ':');
p = base_path; if (protocol_stripped) {
protocol_stripped++;
}
}
p = protocol_stripped ?: base_path;
p1 = strrchr(base_path, '/'); p1 = strrchr(base_path, '/');
#ifdef _WIN32 #ifdef _WIN32
{ {
@ -192,6 +197,41 @@ void path_combine(char *dest, int dest_size,
} }
} }
/*
* Helper function for bdrv_parse_filename() implementations to remove optional
* protocol prefixes (especially "file:") from a filename and for putting the
* stripped filename into the options QDict if there is such a prefix.
*/
void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix,
QDict *options)
{
if (strstart(filename, prefix, &filename)) {
/* Stripping the explicit protocol prefix may result in a protocol
* prefix being (wrongly) detected (if the filename contains a colon) */
if (path_has_protocol(filename)) {
QString *fat_filename;
/* This means there is some colon before the first slash; therefore,
* this cannot be an absolute path */
assert(!path_is_absolute(filename));
/* And we can thus fix the protocol detection issue by prefixing it
* by "./" */
fat_filename = qstring_from_str("./");
qstring_append(fat_filename, filename);
assert(!path_has_protocol(qstring_get_str(fat_filename)));
qdict_put(options, "filename", fat_filename);
} else {
/* If no protocol prefix was detected, we can use the shortened
* filename as-is */
qdict_put_str(options, "filename", filename);
}
}
}
/* Returns whether the image file is opened as read-only. Note that this can /* Returns whether the image file is opened as read-only. Note that this can
* return false and writing to the image file is still not possible because the * return false and writing to the image file is still not possible because the
* image is inactivated. */ * image is inactivated. */

View File

@ -381,12 +381,7 @@ static void raw_parse_flags(int bdrv_flags, int *open_flags)
static void raw_parse_filename(const char *filename, QDict *options, static void raw_parse_filename(const char *filename, QDict *options,
Error **errp) Error **errp)
{ {
/* The filename does not have to be prefixed by the protocol name, since bdrv_parse_filename_strip_prefix(filename, "file:", options);
* "file" is the default protocol; therefore, the return value of this
* function call can be ignored. */
strstart(filename, "file:", &filename);
qdict_put_str(options, "filename", filename);
} }
static QemuOptsList raw_runtime_opts = { static QemuOptsList raw_runtime_opts = {
@ -2395,10 +2390,7 @@ static int check_hdev_writable(BDRVRawState *s)
static void hdev_parse_filename(const char *filename, QDict *options, static void hdev_parse_filename(const char *filename, QDict *options,
Error **errp) Error **errp)
{ {
/* The prefix is optional, just as for "file". */ bdrv_parse_filename_strip_prefix(filename, "host_device:", options);
strstart(filename, "host_device:", &filename);
qdict_put_str(options, "filename", filename);
} }
static bool hdev_is_sg(BlockDriverState *bs) static bool hdev_is_sg(BlockDriverState *bs)
@ -2697,10 +2689,7 @@ static BlockDriver bdrv_host_device = {
static void cdrom_parse_filename(const char *filename, QDict *options, static void cdrom_parse_filename(const char *filename, QDict *options,
Error **errp) Error **errp)
{ {
/* The prefix is optional, just as for "file". */ bdrv_parse_filename_strip_prefix(filename, "host_cdrom:", options);
strstart(filename, "host_cdrom:", &filename);
qdict_put_str(options, "filename", filename);
} }
#endif #endif

View File

@ -276,12 +276,7 @@ static void raw_parse_flags(int flags, bool use_aio, int *access_flags,
static void raw_parse_filename(const char *filename, QDict *options, static void raw_parse_filename(const char *filename, QDict *options,
Error **errp) Error **errp)
{ {
/* The filename does not have to be prefixed by the protocol name, since bdrv_parse_filename_strip_prefix(filename, "file:", options);
* "file" is the default protocol; therefore, the return value of this
* function call can be ignored. */
strstart(filename, "file:", &filename);
qdict_put_str(options, "filename", filename);
} }
static QemuOptsList raw_runtime_opts = { static QemuOptsList raw_runtime_opts = {
@ -671,10 +666,7 @@ static int hdev_probe_device(const char *filename)
static void hdev_parse_filename(const char *filename, QDict *options, static void hdev_parse_filename(const char *filename, QDict *options,
Error **errp) Error **errp)
{ {
/* The prefix is optional, just as for "file". */ bdrv_parse_filename_strip_prefix(filename, "host_device:", options);
strstart(filename, "host_device:", &filename);
qdict_put_str(options, "filename", filename);
} }
static int hdev_open(BlockDriverState *bs, QDict *options, int flags, static int hdev_open(BlockDriverState *bs, QDict *options, int flags,

View File

@ -1797,7 +1797,8 @@ static int expand_zero_clusters_in_l1(BlockDriverState *bs, uint64_t *l1_table,
} }
if (offset_into_cluster(s, offset)) { if (offset_into_cluster(s, offset)) {
qcow2_signal_corruption(bs, true, -1, -1, "Data cluster offset " qcow2_signal_corruption(bs, true, -1, -1,
"Cluster allocation offset "
"%#" PRIx64 " unaligned (L2 offset: %#" "%#" PRIx64 " unaligned (L2 offset: %#"
PRIx64 ", L2 index: %#x)", offset, PRIx64 ", L2 index: %#x)", offset,
l2_offset, j); l2_offset, j);

View File

@ -3222,7 +3222,6 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
if (s->refcount_bits != refcount_bits) { if (s->refcount_bits != refcount_bits) {
int refcount_order = ctz32(refcount_bits); int refcount_order = ctz32(refcount_bits);
Error *local_error = NULL;
if (new_version < 3 && refcount_bits != 16) { if (new_version < 3 && refcount_bits != 16) {
error_report("Different refcount widths than 16 bits require " error_report("Different refcount widths than 16 bits require "
@ -3234,9 +3233,9 @@ static int qcow2_amend_options(BlockDriverState *bs, QemuOpts *opts,
helper_cb_info.current_operation = QCOW2_CHANGING_REFCOUNT_ORDER; helper_cb_info.current_operation = QCOW2_CHANGING_REFCOUNT_ORDER;
ret = qcow2_change_refcount_order(bs, refcount_order, ret = qcow2_change_refcount_order(bs, refcount_order,
&qcow2_amend_helper_cb, &qcow2_amend_helper_cb,
&helper_cb_info, &local_error); &helper_cb_info, &local_err);
if (ret < 0) { if (ret < 0) {
error_report_err(local_error); error_report_err(local_err);
return ret; return ret;
} }
} }

View File

@ -682,6 +682,9 @@ int get_tmp_filename(char *filename, int size);
BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size, BlockDriver *bdrv_probe_all(const uint8_t *buf, int buf_size,
const char *filename); const char *filename);
void bdrv_parse_filename_strip_prefix(const char *filename, const char *prefix,
QDict *options);
/** /**
* bdrv_add_before_write_notifier: * bdrv_add_before_write_notifier:

View File

@ -40,9 +40,9 @@ STEXI
ETEXI ETEXI
DEF("convert", img_convert, DEF("convert", img_convert,
"convert [--object objectdef] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename") "convert [--object objectdef] [--image-opts] [--target-image-opts] [-U] [-c] [-p] [-q] [-n] [-f fmt] [-t cache] [-T src_cache] [-O output_fmt] [-B backing_file] [-o options] [-s snapshot_id_or_name] [-l snapshot_param] [-S sparse_size] [-m num_coroutines] [-W] filename [filename2 [...]] output_filename")
STEXI STEXI
@item convert [--object @var{objectdef}] [--image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename} @item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-U] [-c] [-p] [-q] [-n] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-O @var{output_fmt}] [-B @var{backing_file}] [-o @var{options}] [-s @var{snapshot_id_or_name}] [-l @var{snapshot_param}] [-S @var{sparse_size}] [-m @var{num_coroutines}] [-W] @var{filename} [@var{filename2} [...]] @var{output_filename}
ETEXI ETEXI
DEF("dd", img_dd, DEF("dd", img_dd,

View File

@ -60,6 +60,7 @@ enum {
OPTION_PATTERN = 260, OPTION_PATTERN = 260,
OPTION_FLUSH_INTERVAL = 261, OPTION_FLUSH_INTERVAL = 261,
OPTION_NO_DRAIN = 262, OPTION_NO_DRAIN = 262,
OPTION_TARGET_IMAGE_OPTS = 263,
}; };
typedef enum OutputFormat { typedef enum OutputFormat {
@ -294,6 +295,7 @@ static BlockBackend *img_open_opts(const char *optstr,
if (qdict_haskey(options, BDRV_OPT_FORCE_SHARE) if (qdict_haskey(options, BDRV_OPT_FORCE_SHARE)
&& !qdict_get_bool(options, BDRV_OPT_FORCE_SHARE)) { && !qdict_get_bool(options, BDRV_OPT_FORCE_SHARE)) {
error_report("--force-share/-U conflicts with image options"); error_report("--force-share/-U conflicts with image options");
QDECREF(options);
return NULL; return NULL;
} }
qdict_put(options, BDRV_OPT_FORCE_SHARE, qbool_from_bool(true)); qdict_put(options, BDRV_OPT_FORCE_SHARE, qbool_from_bool(true));
@ -313,14 +315,17 @@ static BlockBackend *img_open_opts(const char *optstr,
} }
static BlockBackend *img_open_file(const char *filename, static BlockBackend *img_open_file(const char *filename,
QDict *options,
const char *fmt, int flags, const char *fmt, int flags,
bool writethrough, bool quiet, bool writethrough, bool quiet,
bool force_share) bool force_share)
{ {
BlockBackend *blk; BlockBackend *blk;
Error *local_err = NULL; Error *local_err = NULL;
QDict *options = qdict_new();
if (!options) {
options = qdict_new();
}
if (fmt) { if (fmt) {
qdict_put_str(options, "driver", fmt); qdict_put_str(options, "driver", fmt);
} }
@ -343,6 +348,35 @@ static BlockBackend *img_open_file(const char *filename,
} }
static int img_add_key_secrets(void *opaque,
const char *name, const char *value,
Error **errp)
{
QDict *options = opaque;
if (g_str_has_suffix(name, "key-secret")) {
qdict_put(options, name, qstring_from_str(value));
}
return 0;
}
static BlockBackend *img_open_new_file(const char *filename,
QemuOpts *create_opts,
const char *fmt, int flags,
bool writethrough, bool quiet,
bool force_share)
{
QDict *options = NULL;
options = qdict_new();
qemu_opt_foreach(create_opts, img_add_key_secrets, options, &error_abort);
return img_open_file(filename, options, fmt, flags, writethrough, quiet,
force_share);
}
static BlockBackend *img_open(bool image_opts, static BlockBackend *img_open(bool image_opts,
const char *filename, const char *filename,
const char *fmt, int flags, bool writethrough, const char *fmt, int flags, bool writethrough,
@ -363,7 +397,7 @@ static BlockBackend *img_open(bool image_opts,
blk = img_open_opts(filename, opts, flags, writethrough, quiet, blk = img_open_opts(filename, opts, flags, writethrough, quiet,
force_share); force_share);
} else { } else {
blk = img_open_file(filename, fmt, flags, writethrough, quiet, blk = img_open_file(filename, NULL, fmt, flags, writethrough, quiet,
force_share); force_share);
} }
return blk; return blk;
@ -1913,10 +1947,10 @@ static int convert_do_copy(ImgConvertState *s)
static int img_convert(int argc, char **argv) static int img_convert(int argc, char **argv)
{ {
int c, bs_i, flags, src_flags = 0; int c, bs_i, flags, src_flags = 0;
const char *fmt = NULL, *out_fmt = "raw", *cache = "unsafe", const char *fmt = NULL, *out_fmt = NULL, *cache = "unsafe",
*src_cache = BDRV_DEFAULT_CACHE, *out_baseimg = NULL, *src_cache = BDRV_DEFAULT_CACHE, *out_baseimg = NULL,
*out_filename, *out_baseimg_param, *snapshot_name = NULL; *out_filename, *out_baseimg_param, *snapshot_name = NULL;
BlockDriver *drv, *proto_drv; BlockDriver *drv = NULL, *proto_drv = NULL;
BlockDriverInfo bdi; BlockDriverInfo bdi;
BlockDriverState *out_bs; BlockDriverState *out_bs;
QemuOpts *opts = NULL, *sn_opts = NULL; QemuOpts *opts = NULL, *sn_opts = NULL;
@ -1924,7 +1958,7 @@ static int img_convert(int argc, char **argv)
char *options = NULL; char *options = NULL;
Error *local_err = NULL; Error *local_err = NULL;
bool writethrough, src_writethrough, quiet = false, image_opts = false, bool writethrough, src_writethrough, quiet = false, image_opts = false,
skip_create = false, progress = false; skip_create = false, progress = false, tgt_image_opts = false;
int64_t ret = -EINVAL; int64_t ret = -EINVAL;
bool force_share = false; bool force_share = false;
@ -1942,6 +1976,7 @@ static int img_convert(int argc, char **argv)
{"object", required_argument, 0, OPTION_OBJECT}, {"object", required_argument, 0, OPTION_OBJECT},
{"image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{"force-share", no_argument, 0, 'U'}, {"force-share", no_argument, 0, 'U'},
{"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS},
{0, 0, 0, 0} {0, 0, 0, 0}
}; };
c = getopt_long(argc, argv, ":hf:O:B:ce6o:s:l:S:pt:T:qnm:WU", c = getopt_long(argc, argv, ":hf:O:B:ce6o:s:l:S:pt:T:qnm:WU",
@ -2062,9 +2097,16 @@ static int img_convert(int argc, char **argv)
case OPTION_IMAGE_OPTS: case OPTION_IMAGE_OPTS:
image_opts = true; image_opts = true;
break; break;
case OPTION_TARGET_IMAGE_OPTS:
tgt_image_opts = true;
break;
} }
} }
if (!out_fmt && !tgt_image_opts) {
out_fmt = "raw";
}
if (qemu_opts_foreach(&qemu_object_opts, if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach, user_creatable_add_opts_foreach,
NULL, NULL)) { NULL, NULL)) {
@ -2076,12 +2118,22 @@ static int img_convert(int argc, char **argv)
goto fail_getopt; goto fail_getopt;
} }
if (tgt_image_opts && !skip_create) {
error_report("--target-image-opts requires use of -n flag");
goto fail_getopt;
}
s.src_num = argc - optind - 1; s.src_num = argc - optind - 1;
out_filename = s.src_num >= 1 ? argv[argc - 1] : NULL; out_filename = s.src_num >= 1 ? argv[argc - 1] : NULL;
if (options && has_help_option(options)) { if (options && has_help_option(options)) {
ret = print_block_option_help(out_filename, out_fmt); if (out_fmt) {
goto fail_getopt; ret = print_block_option_help(out_filename, out_fmt);
goto fail_getopt;
} else {
error_report("Option help requires a format be specified");
goto fail_getopt;
}
} }
if (s.src_num < 1) { if (s.src_num < 1) {
@ -2146,22 +2198,22 @@ static int img_convert(int argc, char **argv)
goto out; goto out;
} }
/* Find driver and parse its options */
drv = bdrv_find_format(out_fmt);
if (!drv) {
error_report("Unknown file format '%s'", out_fmt);
ret = -1;
goto out;
}
proto_drv = bdrv_find_protocol(out_filename, true, &local_err);
if (!proto_drv) {
error_report_err(local_err);
ret = -1;
goto out;
}
if (!skip_create) { if (!skip_create) {
/* Find driver and parse its options */
drv = bdrv_find_format(out_fmt);
if (!drv) {
error_report("Unknown file format '%s'", out_fmt);
ret = -1;
goto out;
}
proto_drv = bdrv_find_protocol(out_filename, true, &local_err);
if (!proto_drv) {
error_report_err(local_err);
ret = -1;
goto out;
}
if (!drv->create_opts) { if (!drv->create_opts) {
error_report("Format driver '%s' does not support image creation", error_report("Format driver '%s' does not support image creation",
drv->format_name); drv->format_name);
@ -2218,7 +2270,7 @@ static int img_convert(int argc, char **argv)
const char *preallocation = const char *preallocation =
qemu_opt_get(opts, BLOCK_OPT_PREALLOC); qemu_opt_get(opts, BLOCK_OPT_PREALLOC);
if (!drv->bdrv_co_pwritev_compressed) { if (drv && !drv->bdrv_co_pwritev_compressed) {
error_report("Compression not supported for this file format"); error_report("Compression not supported for this file format");
ret = -1; ret = -1;
goto out; goto out;
@ -2258,19 +2310,30 @@ static int img_convert(int argc, char **argv)
goto out; goto out;
} }
/* XXX we should allow --image-opts to trigger use of if (skip_create) {
* img_open() here, but then we have trouble with s.target = img_open(tgt_image_opts, out_filename, out_fmt,
* the bdrv_create() call which takes different params. flags, writethrough, quiet, false);
* Not critical right now, so fix can wait... } else {
*/ /* TODO ultimately we should allow --target-image-opts
s.target = img_open_file(out_filename, out_fmt, flags, writethrough, quiet, * to be used even when -n is not given.
false); * That has to wait for bdrv_create to be improved
* to allow filenames in option syntax
*/
s.target = img_open_new_file(out_filename, opts, out_fmt,
flags, writethrough, quiet, false);
}
if (!s.target) { if (!s.target) {
ret = -1; ret = -1;
goto out; goto out;
} }
out_bs = blk_bs(s.target); out_bs = blk_bs(s.target);
if (s.compressed && !out_bs->drv->bdrv_co_pwritev_compressed) {
error_report("Compression not supported for this file format");
ret = -1;
goto out;
}
/* increase bufsectors from the default 4096 (2M) if opt_transfer /* increase bufsectors from the default 4096 (2M) if opt_transfer
* or discard_alignment of the out_bs is greater. Limit to 32768 (16MB) * or discard_alignment of the out_bs is greater. Limit to 32768 (16MB)
* as maximum. */ * as maximum. */
@ -4158,6 +4221,7 @@ static int img_dd(int argc, char **argv)
}; };
const struct option long_options[] = { const struct option long_options[] = {
{ "help", no_argument, 0, 'h'}, { "help", no_argument, 0, 'h'},
{ "object", required_argument, 0, OPTION_OBJECT},
{ "image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, { "image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
{ "force-share", no_argument, 0, 'U'}, { "force-share", no_argument, 0, 'U'},
{ 0, 0, 0, 0 } { 0, 0, 0, 0 }
@ -4186,6 +4250,15 @@ static int img_dd(int argc, char **argv)
case 'U': case 'U':
force_share = true; force_share = true;
break; break;
case OPTION_OBJECT: {
QemuOpts *opts;
opts = qemu_opts_parse_noisily(&qemu_object_opts,
optarg, true);
if (!opts) {
ret = -1;
goto out;
}
} break;
case OPTION_IMAGE_OPTS: case OPTION_IMAGE_OPTS:
image_opts = true; image_opts = true;
break; break;
@ -4230,6 +4303,14 @@ static int img_dd(int argc, char **argv)
ret = -1; ret = -1;
goto out; goto out;
} }
if (qemu_opts_foreach(&qemu_object_opts,
user_creatable_add_opts_foreach,
NULL, NULL)) {
ret = -1;
goto out;
}
blk1 = img_open(image_opts, in.filename, fmt, 0, false, false, blk1 = img_open(image_opts, in.filename, fmt, 0, false, false,
force_share); force_share);
@ -4298,8 +4379,13 @@ static int img_dd(int argc, char **argv)
goto out; goto out;
} }
blk2 = img_open(image_opts, out.filename, out_fmt, BDRV_O_RDWR, /* TODO, we can't honour --image-opts for the target,
false, false, false); * since it needs to be given in a format compatible
* with the bdrv_create() call above which does not
* support image-opts style.
*/
blk2 = img_open_file(out.filename, NULL, out_fmt, BDRV_O_RDWR,
false, false, false);
if (!blk2) { if (!blk2) {
ret = -1; ret = -1;

View File

@ -45,9 +45,17 @@ keys.
@item --image-opts @item --image-opts
Indicates that the @var{filename} parameter is to be interpreted as a Indicates that the source @var{filename} parameter is to be interpreted as a
full option string, not a plain filename. This parameter is mutually full option string, not a plain filename. This parameter is mutually
exclusive with the @var{-f} and @var{-F} parameters. exclusive with the @var{-f} parameter.
@item --target-image-opts
Indicates that the @var{output_filename} parameter(s) are to be interpreted as
a full option string, not a plain filename. This parameter is mutually
exclusive with the @var{-O} parameters. It is currently required to also use
the @var{-n} parameter to skip image creation. This restriction may be relaxed
in a future release.
@item fmt @item fmt
is the disk image format. It is guessed automatically in most cases. See below is the disk image format. It is guessed automatically in most cases. See below

View File

@ -143,7 +143,7 @@ read failed: Input/output error
Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864 Formatting 'TEST_DIR/t.IMGFMT', fmt=IMGFMT size=67108864
wrote 65536/65536 bytes at offset 0 wrote 65536/65536 bytes at offset 0
64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec) 64 KiB, X ops; XX:XX:XX.X (XXX YYY/sec and XXX ops/sec)
qcow2: Marking image as corrupt: Data cluster offset 0x52a00 unaligned (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed qcow2: Marking image as corrupt: Cluster allocation offset 0x52a00 unaligned (L2 offset: 0x40000, L2 index: 0); further corruption events will be suppressed
qemu-img: Error while amending options: Input/output error qemu-img: Error while amending options: Input/output error
=== Testing unaligned reftable entry === === Testing unaligned reftable entry ===