Message ID | 20170203120254.15062-6-berrange@redhat.com (mailing list archive) |
---|---|
State | New, archived |
Headers | show |
On 03.02.2017 13:02, Daniel P. Berrange wrote: > The '--image-opts' flags indicates whether the source filename > includes options. The target filename has to remain in the > plain filename format though, since it needs to be passed to > bdrv_create(). When using --skip-create though, it would be > possible to use image-opts syntax. This adds --target-image-opts > to indicate that the target filename includes options. Currently > this mandates use of the --skip-create flag too. > > Signed-off-by: Daniel P. Berrange <berrange@redhat.com> > --- > qemu-img-cmds.hx | 6 +-- > qemu-img.c | 131 ++++++++++++++++++++++++++++++++++++------------------- > qemu-img.texi | 12 ++++- > 3 files changed, 98 insertions(+), 51 deletions(-) Apart from what the commit message says, it also introduces that switch for dd, which I again don't like too much (quelle surprise), if only because it requires conv=nocreat and thus patch 5 to be useful. [...] > diff --git a/qemu-img.c b/qemu-img.c > index 39fcf09..dc4c6eb 100644 > --- a/qemu-img.c > +++ b/qemu-img.c [...] > @@ -1918,7 +1933,7 @@ static int img_convert(int argc, char **argv) > bs_n = argc - optind - 1; > out_filename = bs_n >= 1 ? argv[argc - 1] : NULL; > > - if (options && has_help_option(options)) { > + if (out_fmt && options && has_help_option(options)) { "!out_fmt && options && has_help_option(options)" should probably be an error. > ret = print_block_option_help(out_filename, out_fmt); > goto out; > } > @@ -1987,22 +2002,22 @@ static int img_convert(int argc, char **argv) > 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; > - } > + 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; > - } > + 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 (!drv->create_opts) { > error_report("Format driver '%s' does not support image creation", > drv->format_name); Compression may be used with -n. This involves the check whether drv->bdrv_co_pwritev_compressed is NULL or not -- which is bad if drv is still NULL: $ ./qemu-img create -f qcow2 foo.qcow2 64M Formatting 'foo.qcow2', fmt=qcow2 size=67108864 encryption=off cluster_size=65536 lazy_refcounts=off refcount_bits=16 $ ./qemu-img convert -c -O qcow2 -n null-co:// foo.qcow2 [1] 17179 segmentation fault (core dumped) ./qemu-img convert -c -O qcow2 -n null-co:// foo.qcow Therefore, you should probably only do the check whether compression is supported if drv is non-NULL; and if it is NULL, do the check again after the target image has been opened and its driver is known. [...] > @@ -4064,13 +4090,22 @@ static int img_dd(int argc, char **argv) > arg = NULL; > } > > + if (tgt_image_opts && !(dd.flags & C_NOCREAT)) { > + error_report("--target-image-opts requires use of -n flag"); *conv=nocreat > + goto out; > + } > + > + if (!out_fmt && !tgt_image_opts) { > + out_fmt = "raw"; > + } > + > if (!(dd.flags & C_IF && dd.flags & C_OF)) { > error_report("Must specify both input and output files"); > ret = -1; > goto out; > } > > - if (optionstr && has_help_option(optionstr)) { > + if (out_fmt && optionstr && has_help_option(optionstr)) { Same as in img_convert(). > ret = print_block_option_help(out.filename, out_fmt); > goto out; > } [...] > @@ -4152,7 +4187,6 @@ static int img_dd(int argc, char **argv) > > if (!(dd.flags & C_NOCREAT)) { > qemu_opt_set_number(opts, BLOCK_OPT_SIZE, out_size, &error_abort); > - > ret = bdrv_create(drv, out.filename, opts, &local_err); > if (ret < 0) { > error_reportf_err(local_err, I'm not sure whether this hunk is necessary... [...] > diff --git a/qemu-img.texi b/qemu-img.texi > index 01acfb8..bda3cc3 100644 > --- a/qemu-img.texi > +++ b/qemu-img.texi > @@ -45,9 +45,17 @@ keys. > > @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 > -exclusive with the @var{-f} and @var{-F} parameters. > +exclusive with the @var{-f} parameter. -F is correct, that's the one for qemu-img compare, after all (which takes two source filenames). > + > +@item --target-image-opts > + > +Indicates that the target @var{filename} parameter(s) are to be interpreted a > +a full option string, not a plain filename. This parameter is mutually > +exclusive with the @var{-F} or @var{-O} parameters. It is currently required -F is unrelated to a target ("output") file. Max > +to also use the @var{-n} parameter to skip image creation. This restriction > +will be relaxed in a future release. > > @item fmt > is the disk image format. It is guessed automatically in most cases. See below >
On Fri, Feb 03, 2017 at 11:32:13PM +0100, Max Reitz wrote: > On 03.02.2017 13:02, Daniel P. Berrange wrote: > > The '--image-opts' flags indicates whether the source filename > > includes options. The target filename has to remain in the > > plain filename format though, since it needs to be passed to > > bdrv_create(). When using --skip-create though, it would be > > possible to use image-opts syntax. This adds --target-image-opts > > to indicate that the target filename includes options. Currently > > this mandates use of the --skip-create flag too. > > > > Signed-off-by: Daniel P. Berrange <berrange@redhat.com> > > --- > > qemu-img-cmds.hx | 6 +-- > > qemu-img.c | 131 ++++++++++++++++++++++++++++++++++++------------------- > > qemu-img.texi | 12 ++++- > > 3 files changed, 98 insertions(+), 51 deletions(-) > > Apart from what the commit message says, it also introduces that switch > for dd, which I again don't like too much (quelle surprise), if only > because it requires conv=nocreat and thus patch 5 to be useful. Once again, I'll drop the 'dd' parts of this patch. > > @@ -1918,7 +1933,7 @@ static int img_convert(int argc, char **argv) > > bs_n = argc - optind - 1; > > out_filename = bs_n >= 1 ? argv[argc - 1] : NULL; > > > > - if (options && has_help_option(options)) { > > + if (out_fmt && options && has_help_option(options)) { > > "!out_fmt && options && has_help_option(options)" should probably be an > error. Ok. > > @@ -1987,22 +2002,22 @@ static int img_convert(int argc, char **argv) > > 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; > > - } > > + 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; > > - } > > + 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 (!drv->create_opts) { > > error_report("Format driver '%s' does not support image creation", > > drv->format_name); > > Compression may be used with -n. This involves the check whether > drv->bdrv_co_pwritev_compressed is NULL or not -- which is bad if drv is > still NULL: > > $ ./qemu-img create -f qcow2 foo.qcow2 64M > Formatting 'foo.qcow2', fmt=qcow2 size=67108864 encryption=off > cluster_size=65536 lazy_refcounts=off refcount_bits=16 > $ ./qemu-img convert -c -O qcow2 -n null-co:// foo.qcow2 > [1] 17179 segmentation fault (core dumped) ./qemu-img convert -c -O > qcow2 -n null-co:// foo.qcow > > Therefore, you should probably only do the check whether compression is > supported if drv is non-NULL; and if it is NULL, do the check again > after the target image has been opened and its driver is known. Oh, yes, that's a fun combination. I'll do that. > > diff --git a/qemu-img.texi b/qemu-img.texi > > index 01acfb8..bda3cc3 100644 > > --- a/qemu-img.texi > > +++ b/qemu-img.texi > > @@ -45,9 +45,17 @@ keys. > > > > @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 > > -exclusive with the @var{-f} and @var{-F} parameters. > > +exclusive with the @var{-f} parameter. > > -F is correct, that's the one for qemu-img compare, after all (which > takes two source filenames). > > > + > > +@item --target-image-opts > > + > > +Indicates that the target @var{filename} parameter(s) are to be interpreted a > > +a full option string, not a plain filename. This parameter is mutually > > +exclusive with the @var{-F} or @var{-O} parameters. It is currently required > > -F is unrelated to a target ("output") file. Opps, yes. Regards, Daniel
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx index 2488cbe..13fded9 100644 --- a/qemu-img-cmds.hx +++ b/qemu-img-cmds.hx @@ -40,13 +40,13 @@ STEXI ETEXI DEF("convert", img_convert, - "convert [--object objectdef] [--image-opts] [-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] filename [filename2 [...]] output_filename") + "convert [--object objectdef] [--image-opts] [--target-image-opts] [-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] filename [filename2 [...]] output_filename") STEXI -@item convert [--object @var{objectdef}] [--image-opts] [-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}] @var{filename} [@var{filename2} [...]] @var{output_filename} +@item convert [--object @var{objectdef}] [--image-opts] [--target-image-opts] [-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}] @var{filename} [@var{filename2} [...]] @var{output_filename} ETEXI DEF("dd", img_dd, - "dd [--image-opts] [-f fmt] [-O output_fmt] [-o options] [bs=block_size] [count=blocks] [skip=blocks] [conv=nocreat,notrunc] if=input of=output") + "dd [--image-opts] [--target-image-opts] [-f fmt] [-O output_fmt] [-o options] [bs=block_size] [count=blocks] [skip=blocks] [conv=nocreat,notrunc] if=input of=output") STEXI @item dd [--image-opts] [-f @var{fmt}] [-O @var{output_fmt}] [bs=@var{block_size}] [count=@var{blocks}] [skip=@var{blocks}] [conv=nocreat,notrunc] if=@var{input} of=@var{output} ETEXI diff --git a/qemu-img.c b/qemu-img.c index 39fcf09..dc4c6eb 100644 --- a/qemu-img.c +++ b/qemu-img.c @@ -59,6 +59,7 @@ enum { OPTION_PATTERN = 260, OPTION_FLUSH_INTERVAL = 261, OPTION_NO_DRAIN = 262, + OPTION_TARGET_IMAGE_OPTS = 263, }; typedef enum OutputFormat { @@ -1765,7 +1766,7 @@ static int img_convert(int argc, char **argv) int progress = 0, flags, src_flags; bool writethrough, src_writethrough; const char *fmt, *out_fmt, *cache, *src_cache, *out_baseimg, *out_filename; - BlockDriver *drv, *proto_drv; + BlockDriver *drv = NULL, *proto_drv = NULL; BlockBackend **blk = NULL, *out_blk = NULL; BlockDriverState **bs = NULL, *out_bs = NULL; int64_t total_sectors; @@ -1783,9 +1784,10 @@ static int img_convert(int argc, char **argv) QemuOpts *sn_opts = NULL; ImgConvertState state; bool image_opts = false; + bool tgt_image_opts = false; + out_fmt = NULL; fmt = NULL; - out_fmt = "raw"; cache = "unsafe"; src_cache = BDRV_DEFAULT_CACHE; out_baseimg = NULL; @@ -1796,6 +1798,7 @@ static int img_convert(int argc, char **argv) {"help", no_argument, 0, 'h'}, {"object", required_argument, 0, OPTION_OBJECT}, {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, + {"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS}, {0, 0, 0, 0} }; c = getopt_long(argc, argv, "hf:O:B:ce6o:s:l:S:pt:T:qn", @@ -1900,15 +1903,27 @@ static int img_convert(int argc, char **argv) case OPTION_IMAGE_OPTS: image_opts = true; 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, user_creatable_add_opts_foreach, NULL, NULL)) { goto fail_getopt; } + if (tgt_image_opts && !skip_create) { + error_report("--target-image-opts requires use of -n flag"); + goto fail_getopt; + } + /* Initialize before goto out */ if (quiet) { progress = 0; @@ -1918,7 +1933,7 @@ static int img_convert(int argc, char **argv) bs_n = argc - optind - 1; out_filename = bs_n >= 1 ? argv[argc - 1] : NULL; - if (options && has_help_option(options)) { + if (out_fmt && options && has_help_option(options)) { ret = print_block_option_help(out_filename, out_fmt); goto out; } @@ -1987,22 +2002,22 @@ static int img_convert(int argc, char **argv) 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; - } + 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; - } + 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 (!drv->create_opts) { error_report("Format driver '%s' does not support image creation", drv->format_name); @@ -2091,12 +2106,18 @@ static int img_convert(int argc, char **argv) goto out; } - /* XXX we should allow --image-opts to trigger use of - * img_open() here, but then we have trouble with - * the bdrv_create() call which takes different params. - * Not critical right now, so fix can wait... - */ - out_blk = img_open_file(out_filename, out_fmt, flags, writethrough, quiet); + if (skip_create) { + out_blk = img_open(tgt_image_opts, out_filename, out_fmt, + flags, writethrough, quiet); + } else { + /* TODO ultimately we should allow --target-image-opts + * to be used even when -n is not given. + * That has to wait for bdrv_create to be improved + * to allow filenames in option syntax + */ + out_blk = img_open_file(out_filename, out_fmt, + flags, writethrough, quiet); + } if (!out_blk) { ret = -1; goto out; @@ -3946,8 +3967,9 @@ static int img_dd(int argc, char **argv) QemuOptsList *create_opts = NULL; Error *local_err = NULL; bool image_opts = false; + bool tgt_image_opts = false; int c, i; - const char *out_fmt = "raw"; + const char *out_fmt = NULL; const char *fmt = NULL; char *optionstr = NULL; int64_t size = 0, out_size; @@ -3982,6 +4004,7 @@ static int img_dd(int argc, char **argv) { "help", no_argument, 0, 'h'}, { "object", required_argument, 0, OPTION_OBJECT}, { "image-opts", no_argument, 0, OPTION_IMAGE_OPTS}, + {"target-image-opts", no_argument, 0, OPTION_TARGET_IMAGE_OPTS}, { 0, 0, 0, 0 } }; @@ -4028,6 +4051,9 @@ static int img_dd(int argc, char **argv) case OPTION_IMAGE_OPTS: image_opts = true; break; + case OPTION_TARGET_IMAGE_OPTS: + tgt_image_opts = true; + break; } } @@ -4064,13 +4090,22 @@ static int img_dd(int argc, char **argv) arg = NULL; } + if (tgt_image_opts && !(dd.flags & C_NOCREAT)) { + error_report("--target-image-opts requires use of -n flag"); + goto out; + } + + if (!out_fmt && !tgt_image_opts) { + out_fmt = "raw"; + } + if (!(dd.flags & C_IF && dd.flags & C_OF)) { error_report("Must specify both input and output files"); ret = -1; goto out; } - if (optionstr && has_help_option(optionstr)) { + if (out_fmt && optionstr && has_help_option(optionstr)) { ret = print_block_option_help(out.filename, out_fmt); goto out; } @@ -4088,21 +4123,21 @@ static int img_dd(int argc, char **argv) goto out; } - drv = bdrv_find_format(out_fmt); - if (!drv) { - error_report("Unknown file format"); - ret = -1; - goto out; - } - proto_drv = bdrv_find_protocol(out.filename, true, &local_err); + if (!(dd.flags & C_NOCREAT)) { + drv = bdrv_find_format(out_fmt); + if (!drv) { + error_report("Unknown file format"); + 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 (!proto_drv) { + error_report_err(local_err); + ret = -1; + goto out; + } - if (!(dd.flags & C_NOCREAT)) { if (!drv->create_opts) { error_report("Format driver '%s' does not support image creation", drv->format_name); @@ -4152,7 +4187,6 @@ static int img_dd(int argc, char **argv) if (!(dd.flags & C_NOCREAT)) { qemu_opt_set_number(opts, BLOCK_OPT_SIZE, out_size, &error_abort); - ret = bdrv_create(drv, out.filename, opts, &local_err); if (ret < 0) { error_reportf_err(local_err, @@ -4163,13 +4197,18 @@ static int img_dd(int argc, char **argv) } } - /* TODO, we can't honour --image-opts for the target, - * 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, out_fmt, BDRV_O_RDWR, - false, false); + if (dd.flags & C_NOCREAT) { + blk2 = img_open(tgt_image_opts, out.filename, out_fmt, + BDRV_O_RDWR, false, false); + } else { + /* TODO ultimately we should allow --target-image-opts + * to be used even when -n is not given. + * That has to wait for bdrv_create to be improved + * to allow filenames in option syntax + */ + blk2 = img_open_file(out.filename, out_fmt, + BDRV_O_RDWR, false, false); + } if (!blk2) { ret = -1; diff --git a/qemu-img.texi b/qemu-img.texi index 01acfb8..bda3cc3 100644 --- a/qemu-img.texi +++ b/qemu-img.texi @@ -45,9 +45,17 @@ keys. @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 -exclusive with the @var{-f} and @var{-F} parameters. +exclusive with the @var{-f} parameter. + +@item --target-image-opts + +Indicates that the target @var{filename} parameter(s) are to be interpreted a +a full option string, not a plain filename. This parameter is mutually +exclusive with the @var{-F} or @var{-O} parameters. It is currently required +to also use the @var{-n} parameter to skip image creation. This restriction +will be relaxed in a future release. @item fmt is the disk image format. It is guessed automatically in most cases. See below
The '--image-opts' flags indicates whether the source filename includes options. The target filename has to remain in the plain filename format though, since it needs to be passed to bdrv_create(). When using --skip-create though, it would be possible to use image-opts syntax. This adds --target-image-opts to indicate that the target filename includes options. Currently this mandates use of the --skip-create flag too. Signed-off-by: Daniel P. Berrange <berrange@redhat.com> --- qemu-img-cmds.hx | 6 +-- qemu-img.c | 131 ++++++++++++++++++++++++++++++++++++------------------- qemu-img.texi | 12 ++++- 3 files changed, 98 insertions(+), 51 deletions(-)