[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
[Qemu-block] [PATCH 14/17] qemu-img: allow specifying image as a set of
From: |
Daniel P. Berrange |
Subject: |
[Qemu-block] [PATCH 14/17] qemu-img: allow specifying image as a set of options args |
Date: |
Mon, 19 Oct 2015 16:09:46 +0100 |
Currently qemu-img allows an image filename to be passed on the
command line, but does not have a way to set any options except
the format eg
qemu-img info https://127.0.0.1/images/centos7.iso
This adds a --source arg (that is mutually exclusive with a
positional filename arg and -f arg) that accepts a full option
string, as well as the original syntax eg
qemu-img info driver=http,url=https://127.0.0.1/images,sslverify=off
Signed-off-by: Daniel P. Berrange <address@hidden>
---
include/qemu/option.h | 1 +
qemu-img.c | 474 ++++++++++++++++++++++++++++++++++++++++++--------
util/qemu-option.c | 6 +
3 files changed, 407 insertions(+), 74 deletions(-)
diff --git a/include/qemu/option.h b/include/qemu/option.h
index 71f5f27..caf5a3b 100644
--- a/include/qemu/option.h
+++ b/include/qemu/option.h
@@ -104,6 +104,7 @@ int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc
func, void *opaque,
Error **errp);
QemuOpts *qemu_opts_find(QemuOptsList *list, const char *id);
+QemuOpts *qemu_opts_next(QemuOpts *opts);
QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
int fail_if_exists, Error **errp);
void qemu_opts_reset(QemuOptsList *list);
diff --git a/qemu-img.c b/qemu-img.c
index 1578e0b..30869fe 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -38,6 +38,7 @@
#include "block/blockjob.h"
#include "block/qapi.h"
#include <getopt.h>
+#include <err.h>
#define QEMU_IMG_VERSION "qemu-img version " QEMU_VERSION QEMU_PKGVERSION \
", Copyright (c) 2004-2008 Fabrice Bellard\n"
@@ -51,6 +52,8 @@ enum {
OPTION_OUTPUT = 256,
OPTION_BACKING_CHAIN = 257,
OPTION_OBJECT = 258,
+ OPTION_SOURCE = 259,
+ OPTION_TARGET = 260,
};
typedef enum OutputFormat {
@@ -172,6 +175,16 @@ static QemuOptsList qemu_object_opts = {
},
};
+static QemuOptsList qemu_source_opts = {
+ .name = "source",
+ .implied_opt_name = "file",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_source_opts.head),
+ .desc = {
+ { }
+ },
+};
+
+
static int object_create(void *opaque, QemuOpts *opts, Error **errp)
{
Error *err = NULL;
@@ -266,9 +279,31 @@ static int print_block_option_help(const char *filename,
const char *fmt)
return 0;
}
-static BlockBackend *img_open(const char *id, const char *filename,
- const char *fmt, int flags,
- bool require_io, bool quiet)
+static BlockBackend *img_open_opts(const char *id,
+ QemuOpts *opts, int flags)
+{
+ QDict *options;
+ Error *local_err = NULL;
+ char *file = NULL;
+ BlockBackend *blk;
+ file = g_strdup(qemu_opt_get(opts, "file"));
+ qemu_opt_unset(opts, "file");
+ options = qemu_opts_to_qdict(opts, NULL);
+ blk = blk_new_open(id, file, NULL, options, flags, &local_err);
+ if (!blk) {
+ error_report("Could not open '%s': %s", file ? file : "",
+ error_get_pretty(local_err));
+ g_free(file);
+ error_free(local_err);
+ return NULL;
+ }
+ g_free(file);
+ return blk;
+}
+
+static BlockBackend *img_open_file(const char *id, const char *filename,
+ const char *fmt, int flags,
+ bool require_io, bool quiet)
{
BlockBackend *blk;
BlockDriverState *bs;
@@ -576,7 +611,7 @@ static int img_check(int argc, char **argv)
{
int c, ret;
OutputFormat output_format = OFORMAT_HUMAN;
- const char *filename, *fmt, *output, *cache;
+ const char *filename = NULL, *fmt, *output, *cache;
BlockBackend *blk;
BlockDriverState *bs;
int fix = 0;
@@ -596,6 +631,7 @@ static int img_check(int argc, char **argv)
{"repair", required_argument, 0, 'r'},
{"output", required_argument, 0, OPTION_OUTPUT},
{"object", required_argument, 0, OPTION_OBJECT},
+ {"source", required_argument, 0, OPTION_SOURCE},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "hf:r:T:q",
@@ -639,12 +675,29 @@ static int img_check(int argc, char **argv)
exit(1);
}
break;
+ case OPTION_SOURCE:
+ if (filename) {
+ errx(EXIT_FAILURE, "--source can only be specified once");
+ }
+ filename = optarg;
+ opts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
- if (optind != argc - 1) {
- error_exit("Expecting one image file name");
+ if (filename) {
+ if (optind != argc) {
+ error_exit("--source and filename are mutually exclusive");
+ }
+ } else {
+ if (optind != argc - 1) {
+ error_exit("Expecting one image file name");
+ }
+ filename = argv[optind++];
}
- filename = argv[optind++];
if (output && !strcmp(output, "json")) {
output_format = OFORMAT_JSON;
@@ -667,7 +720,15 @@ static int img_check(int argc, char **argv)
return 1;
}
- blk = img_open("image", filename, fmt, flags, true, quiet);
+ opts = qemu_opts_find(&qemu_source_opts, NULL);
+ if (opts) {
+ if (fmt) {
+ errx(EXIT_FAILURE, "--source and --format are mutually exclusive");
+ }
+ blk = img_open_opts("image", opts, flags);
+ } else {
+ blk = img_open_file("image", filename, fmt, flags, true, quiet);
+ }
if (!blk) {
return 1;
}
@@ -775,7 +836,7 @@ static void run_block_job(BlockJob *job, Error **errp)
static int img_commit(int argc, char **argv)
{
int c, ret, flags;
- const char *filename, *fmt, *cache, *base;
+ const char *filename = NULL, *fmt, *cache, *base;
BlockBackend *blk;
BlockDriverState *bs, *base_bs;
bool progress = false, quiet = false, drop = false;
@@ -791,6 +852,7 @@ static int img_commit(int argc, char **argv)
static const struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"object", required_argument, 0, OPTION_OBJECT},
+ {"source", required_argument, 0, OPTION_SOURCE},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "f:ht:b:dpq",
@@ -830,6 +892,17 @@ static int img_commit(int argc, char **argv)
exit(1);
}
break;
+ case OPTION_SOURCE:
+ if (filename) {
+ errx(EXIT_FAILURE, "--source can only be specified once");
+ }
+ filename = optarg;
+ opts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
@@ -838,10 +911,16 @@ static int img_commit(int argc, char **argv)
progress = false;
}
- if (optind != argc - 1) {
- error_exit("Expecting one image file name");
+ if (filename) {
+ if (optind != argc) {
+ error_exit("--source and filename are mutually exclusive");
+ }
+ } else {
+ if (optind != argc - 1) {
+ error_exit("Expecting one image file name");
+ }
+ filename = argv[optind++];
}
- filename = argv[optind++];
if (qemu_opts_foreach(qemu_find_opts("object"),
object_create,
@@ -856,7 +935,15 @@ static int img_commit(int argc, char **argv)
return 1;
}
- blk = img_open("image", filename, fmt, flags, true, quiet);
+ opts = qemu_opts_find(&qemu_source_opts, NULL);
+ if (opts) {
+ if (fmt) {
+ errx(EXIT_FAILURE, "--source and --format are mutually exclusive");
+ }
+ blk = img_open_opts("image", opts, flags);
+ } else {
+ blk = img_open_file("image", filename, fmt, flags, true, quiet);
+ }
if (!blk) {
return 1;
}
@@ -1090,7 +1177,8 @@ static int check_empty_sectors(BlockBackend *blk, int64_t
sect_num,
*/
static int img_compare(int argc, char **argv)
{
- const char *fmt1 = NULL, *fmt2 = NULL, *cache, *filename1, *filename2;
+ const char *fmt1 = NULL, *fmt2 = NULL, *cache,
+ *filename1 = NULL, *filename2 = NULL;
BlockBackend *blk1, *blk2;
BlockDriverState *bs1, *bs2;
int64_t total_sectors1, total_sectors2;
@@ -1113,6 +1201,7 @@ static int img_compare(int argc, char **argv)
static const struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"object", required_argument, 0, OPTION_OBJECT},
+ {"source", required_argument, 0, OPTION_SOURCE},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "hf:F:T:pqs",
@@ -1150,6 +1239,20 @@ static int img_compare(int argc, char **argv)
exit(1);
}
break;
+ case OPTION_SOURCE:
+ if (filename2) {
+ errx(EXIT_FAILURE, "--source can only be specified twice");
+ } else if (filename1) {
+ filename2 = optarg;
+ } else {
+ filename1 = optarg;
+ }
+ opts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
@@ -1158,12 +1261,20 @@ static int img_compare(int argc, char **argv)
progress = false;
}
-
- if (optind != argc - 2) {
- error_exit("Expecting two image file names");
+ if (filename1) {
+ if (optind != argc) {
+ error_exit("--source and filenames are mutually exclusive");
+ }
+ if (!filename2) {
+ error_exit("Expecting two --source arguments");
+ }
+ } else {
+ if (optind != argc - 2) {
+ error_exit("Expecting two image file names");
+ }
+ filename1 = argv[optind++];
+ filename2 = argv[optind++];
}
- filename1 = argv[optind++];
- filename2 = argv[optind++];
if (qemu_opts_foreach(qemu_find_opts("object"),
object_create,
@@ -1182,18 +1293,38 @@ static int img_compare(int argc, char **argv)
goto out3;
}
- blk1 = img_open("image_1", filename1, fmt1, flags, true, quiet);
- if (!blk1) {
- ret = 2;
- goto out3;
- }
- bs1 = blk_bs(blk1);
+ opts = qemu_opts_find(&qemu_source_opts, NULL);
+ if (opts) {
+ if (fmt1 || fmt2) {
+ error_report("--source and -f or -F are mutuall exclusive");
+ goto out3;
+ }
- blk2 = img_open("image_2", filename2, fmt2, flags, true, quiet);
- if (!blk2) {
- ret = 2;
- goto out2;
+ blk1 = img_open_opts("image_1", opts, flags);
+ if (!blk1) {
+ ret = 2;
+ goto out3;
+ }
+
+ blk2 = img_open_opts("image_2", qemu_opts_next(opts), flags);
+ if (!blk2) {
+ ret = 2;
+ goto out3;
+ }
+ } else {
+ blk1 = img_open_file("image_1", filename1, fmt1, flags, true, quiet);
+ if (!blk1) {
+ ret = 2;
+ goto out3;
+ }
+
+ blk2 = img_open_file("image_2", filename2, fmt2, flags, true, quiet);
+ if (!blk2) {
+ ret = 2;
+ goto out2;
+ }
}
+ bs1 = blk_bs(blk1);
bs2 = blk_bs(blk2);
buf1 = blk_blockalign(blk1, IO_BUF_SIZE);
@@ -1660,10 +1791,11 @@ fail:
static int img_convert(int argc, char **argv)
{
- int c, bs_n, bs_i, compress, cluster_sectors, skip_create;
+ int c, bs_n = 0, bs_i, compress, cluster_sectors, skip_create;
int64_t ret = 0;
int progress = 0, flags, src_flags;
- const char *fmt, *out_fmt, *cache, *src_cache, *out_baseimg, *out_filename;
+ const char *fmt, *out_fmt, *cache, *src_cache,
+ *out_baseimg, *out_filename = NULL;
BlockDriver *drv, *proto_drv;
BlockBackend **blk = NULL, *out_blk = NULL;
BlockDriverState **bs = NULL, *out_bs = NULL;
@@ -1694,6 +1826,7 @@ static int img_convert(int argc, char **argv)
static const struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"object", required_argument, 0, OPTION_OBJECT},
+ {"source", required_argument, 0, OPTION_SOURCE},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "hf:O:B:ce6o:s:l:S:pt:T:qn",
@@ -1795,6 +1928,14 @@ static int img_convert(int argc, char **argv)
exit(1);
}
break;
+ case OPTION_SOURCE:
+ bs_n++;
+ opts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
@@ -1810,20 +1951,33 @@ static int img_convert(int argc, char **argv)
}
qemu_progress_init(progress, 1.0);
-
- bs_n = argc - optind - 1;
- out_filename = bs_n >= 1 ? argv[argc - 1] : NULL;
+ if (!bs_n) {
+ out_filename = (argc - optind - 1) >= 1 ? argv[argc - 1] : NULL;
+ }
if (options && has_help_option(options)) {
ret = print_block_option_help(out_filename, out_fmt);
goto out;
}
- if (bs_n < 1) {
- error_exit("Must specify image file name");
+ if (bs_n) {
+ if (argc > (optind + 1)) {
+ error_exit("--source and filenames are mutually exclusive");
+ }
+ if (argc != (optind + 1)) {
+ error_exit("Must specify target image file name");
+ }
+ if (!bs_n) {
+ error_exit("At least one --source arg is expected with --target");
+ }
+ out_filename = argv[argc - 1];
+ } else {
+ bs_n = argc - optind - 1;
+ if (bs_n < 1) {
+ error_exit("Must specify image file name");
+ }
}
-
if (bs_n > 1 && out_baseimg) {
error_report("-B makes no sense when concatenating multiple input "
"images");
@@ -1845,11 +1999,21 @@ static int img_convert(int argc, char **argv)
bs_sectors = g_new(int64_t, bs_n);
total_sectors = 0;
+ opts = qemu_opts_find(&qemu_source_opts, NULL);
for (bs_i = 0; bs_i < bs_n; bs_i++) {
char *id = bs_n > 1 ? g_strdup_printf("source_%d", bs_i)
: g_strdup("source");
- blk[bs_i] = img_open(id, argv[optind + bs_i], fmt, src_flags,
- true, quiet);
+ if (opts) {
+ if (fmt) {
+ error_report("--source and -f are mutually exclusive");
+ goto out;
+ }
+ blk[bs_i] = img_open_opts(id, opts, src_flags);
+ opts = qemu_opts_next(opts);
+ } else {
+ blk[bs_i] = img_open_file(id, argv[optind + bs_i], fmt, src_flags,
+ true, quiet);
+ }
g_free(id);
if (!blk[bs_i]) {
ret = -1;
@@ -1993,7 +2157,12 @@ static int img_convert(int argc, char **argv)
goto out;
}
- out_blk = img_open("target", out_filename, out_fmt, flags, true, quiet);
+ /* XXX we could allow a --target OPTSRING and then use
+ * img_open_opts here, but then we have trouble with
+ * the bdrv_create() call which takes different params
+ */
+ out_blk = img_open_file("target", out_filename,
+ out_fmt, flags, true, quiet);
if (!out_blk) {
ret = -1;
goto out;
@@ -2160,7 +2329,8 @@ static gboolean str_equal_func(gconstpointer a,
gconstpointer b)
* image file. If there was an error a message will have been printed to
* stderr.
*/
-static ImageInfoList *collect_image_info_list(const char *filename,
+static ImageInfoList *collect_image_info_list(QemuOpts *opts,
+ const char *filename,
const char *fmt,
bool chain)
{
@@ -2184,8 +2354,19 @@ static ImageInfoList *collect_image_info_list(const char
*filename,
}
g_hash_table_insert(filenames, (gpointer)filename, NULL);
- blk = img_open("image", filename, fmt,
- BDRV_O_FLAGS | BDRV_O_NO_BACKING, false, false);
+ if (opts) {
+ if (fmt) {
+ error_report("--source and -f are mutually exclusive");
+ goto err;
+ }
+ blk = img_open_opts("image", opts,
+ BDRV_O_FLAGS | BDRV_O_NO_BACKING);
+ opts = NULL;
+ } else {
+ blk = img_open_file("image", filename, fmt,
+ BDRV_O_FLAGS | BDRV_O_NO_BACKING,
+ false, false);
+ }
if (!blk) {
goto err;
}
@@ -2231,7 +2412,7 @@ static int img_info(int argc, char **argv)
int c;
OutputFormat output_format = OFORMAT_HUMAN;
bool chain = false;
- const char *filename, *fmt, *output;
+ const char *filename = NULL, *fmt, *output;
ImageInfoList *list;
QemuOpts *opts;
@@ -2245,6 +2426,7 @@ static int img_info(int argc, char **argv)
{"output", required_argument, 0, OPTION_OUTPUT},
{"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN},
{"object", required_argument, 0, OPTION_OBJECT},
+ {"source", required_argument, 0, OPTION_SOURCE},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "f:h",
@@ -2273,12 +2455,29 @@ static int img_info(int argc, char **argv)
exit(1);
}
break;
+ case OPTION_SOURCE:
+ if (filename) {
+ error_exit("--source can only be specified once");
+ }
+ filename = optarg;
+ opts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
- if (optind != argc - 1) {
- error_exit("Expecting one image file name");
+ if (filename) {
+ if (optind != argc) {
+ error_exit("--source and filename are mutually exclusive");
+ }
+ } else {
+ if (optind != argc - 1) {
+ error_exit("Expecting one image file name");
+ }
+ filename = argv[optind++];
}
- filename = argv[optind++];
if (output && !strcmp(output, "json")) {
output_format = OFORMAT_JSON;
@@ -2295,7 +2494,8 @@ static int img_info(int argc, char **argv)
exit(1);
}
- list = collect_image_info_list(filename, fmt, chain);
+ list = collect_image_info_list(qemu_opts_find(&qemu_source_opts, NULL),
+ filename, fmt, chain);
if (!list) {
return 1;
}
@@ -2414,7 +2614,7 @@ static int img_map(int argc, char **argv)
OutputFormat output_format = OFORMAT_HUMAN;
BlockBackend *blk;
BlockDriverState *bs;
- const char *filename, *fmt, *output;
+ const char *filename = NULL, *fmt, *output;
int64_t length;
MapEntry curr = { .length = 0 }, next;
int ret = 0;
@@ -2429,6 +2629,7 @@ static int img_map(int argc, char **argv)
{"format", required_argument, 0, 'f'},
{"output", required_argument, 0, OPTION_OUTPUT},
{"object", required_argument, 0, OPTION_OBJECT},
+ {"source", required_argument, 0, OPTION_SOURCE},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "f:h",
@@ -2454,12 +2655,29 @@ static int img_map(int argc, char **argv)
exit(1);
}
break;
+ case OPTION_SOURCE:
+ if (filename) {
+ error_exit("--source can only be specified once");
+ }
+ filename = optarg;
+ opts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
- if (optind != argc - 1) {
- error_exit("Expecting one image file name");
+ if (filename) {
+ if (optind != argc) {
+ error_exit("--source and filename are mutually exclusive");
+ }
+ } else {
+ if (optind != argc - 1) {
+ error_exit("Expecting one image file name");
+ }
+ filename = argv[optind];
}
- filename = argv[optind];
if (output && !strcmp(output, "json")) {
output_format = OFORMAT_JSON;
@@ -2476,7 +2694,15 @@ static int img_map(int argc, char **argv)
exit(1);
}
- blk = img_open("image", filename, fmt, BDRV_O_FLAGS, true, false);
+ opts = qemu_opts_find(&qemu_source_opts, NULL);
+ if (opts) {
+ if (fmt) {
+ errx(EXIT_FAILURE, "--source and --format are mutually exclusive");
+ }
+ blk = img_open_opts("image", opts, BDRV_O_FLAGS);
+ } else {
+ blk = img_open_file("image", filename, fmt, BDRV_O_FLAGS, true, false);
+ }
if (!blk) {
return 1;
}
@@ -2535,7 +2761,7 @@ static int img_snapshot(int argc, char **argv)
BlockBackend *blk;
BlockDriverState *bs;
QEMUSnapshotInfo sn;
- char *filename, *snapshot_name = NULL;
+ char *filename = NULL, *snapshot_name = NULL;
int c, ret = 0, bdrv_oflags;
int action = 0;
qemu_timeval tv;
@@ -2550,6 +2776,7 @@ static int img_snapshot(int argc, char **argv)
static const struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"object", required_argument, 0, OPTION_OBJECT},
+ {"source", required_argument, 0, OPTION_SOURCE},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "la:c:d:hq",
@@ -2604,13 +2831,30 @@ static int img_snapshot(int argc, char **argv)
exit(1);
}
break;
+ case OPTION_SOURCE:
+ if (filename) {
+ error_exit("--source can only be specified once");
+ }
+ filename = optarg;
+ opts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
- if (optind != argc - 1) {
- error_exit("Expecting one image file name");
+ if (filename) {
+ if (optind != argc) {
+ error_exit("--source and filename are mutually exclusive");
+ }
+ } else {
+ if (optind != argc - 1) {
+ error_exit("Expecting one image file name");
+ }
+ filename = argv[optind++];
}
- filename = argv[optind++];
if (qemu_opts_foreach(qemu_find_opts("object"),
object_create,
@@ -2619,7 +2863,12 @@ static int img_snapshot(int argc, char **argv)
}
/* Open the image */
- blk = img_open("image", filename, NULL, bdrv_oflags, true, quiet);
+ opts = qemu_opts_find(&qemu_source_opts, NULL);
+ if (opts) {
+ blk = img_open_opts("image", opts, bdrv_oflags);
+ } else {
+ blk = img_open_file("image", filename, NULL, bdrv_oflags, true, quiet);
+ }
if (!blk) {
return 1;
}
@@ -2677,7 +2926,7 @@ static int img_rebase(int argc, char **argv)
{
BlockBackend *blk = NULL, *blk_old_backing = NULL, *blk_new_backing = NULL;
BlockDriverState *bs = NULL;
- char *filename;
+ char *filename = NULL;
const char *fmt, *cache, *src_cache, *out_basefmt, *out_baseimg;
int c, flags, src_flags, ret;
int unsafe = 0;
@@ -2697,6 +2946,7 @@ static int img_rebase(int argc, char **argv)
static const struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"object", required_argument, 0, OPTION_OBJECT},
+ {"source", required_argument, 0, OPTION_SOURCE},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "hf:F:b:upt:T:q",
@@ -2740,6 +2990,13 @@ static int img_rebase(int argc, char **argv)
exit(1);
}
break;
+ case OPTION_SOURCE:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
@@ -2747,13 +3004,20 @@ static int img_rebase(int argc, char **argv)
progress = 0;
}
- if (optind != argc - 1) {
- error_exit("Expecting one image file name");
+ if (filename) {
+ if (optind != argc) {
+ error_exit("--source and filename are mutually exclusive");
+ }
+ } else {
+ if (optind != argc - 1) {
+ error_exit("Expecting one image file name");
+ }
+ filename = argv[optind++];
}
+
if (!unsafe && !out_baseimg) {
error_exit("Must specify backing file (-b) or use unsafe mode (-u)");
}
- filename = argv[optind++];
if (qemu_opts_foreach(qemu_find_opts("object"),
object_create,
@@ -2784,7 +3048,17 @@ static int img_rebase(int argc, char **argv)
* Ignore the old backing file for unsafe rebase in case we want to correct
* the reference to a renamed or moved backing file.
*/
- blk = img_open("image", filename, fmt, flags, true, quiet);
+ opts = qemu_opts_find(&qemu_source_opts, NULL);
+ if (opts) {
+ if (fmt) {
+ error_report("--source and --format are mutually exclusive");
+ ret = -1;
+ goto out;
+ }
+ blk = img_open_opts("image", opts, flags);
+ } else {
+ blk = img_open_file("image", filename, fmt, flags, true, quiet);
+ }
if (!blk) {
ret = -1;
goto out;
@@ -3016,7 +3290,7 @@ static int img_resize(int argc, char **argv)
{
Error *err = NULL;
int c, ret, relative;
- const char *filename, *fmt, *size;
+ const char *filename = NULL, *fmt, *size;
int64_t n, total_size;
bool quiet = false;
BlockBackend *blk = NULL;
@@ -3052,6 +3326,7 @@ static int img_resize(int argc, char **argv)
static const struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"object", required_argument, 0, OPTION_OBJECT},
+ {"source", required_argument, 0, OPTION_SOURCE},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "f:hq",
@@ -3077,12 +3352,25 @@ static int img_resize(int argc, char **argv)
exit(1);
}
break;
+ case OPTION_SOURCE:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
- if (optind != argc - 1) {
- error_exit("Expecting one image file name");
+ if (filename) {
+ if (optind != argc) {
+ error_exit("--source and filename are mutually exclusive");
+ }
+ } else {
+ if (optind != argc - 1) {
+ error_exit("Expecting one image file name");
+ }
+ filename = argv[optind++];
}
- filename = argv[optind++];
if (qemu_opts_foreach(qemu_find_opts("object"),
object_create,
@@ -3117,8 +3405,18 @@ static int img_resize(int argc, char **argv)
n = qemu_opt_get_size(param, BLOCK_OPT_SIZE, 0);
qemu_opts_del(param);
- blk = img_open("image", filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR,
- true, quiet);
+ opts = qemu_opts_find(&qemu_source_opts, NULL);
+ if (opts) {
+ if (fmt) {
+ error_report("--source and --format are mutually exclusive");
+ ret = -1;
+ goto out;
+ }
+ blk = img_open_opts("image", opts, BDRV_O_FLAGS | BDRV_O_RDWR);
+ } else {
+ blk = img_open_file("image", filename, fmt, BDRV_O_FLAGS | BDRV_O_RDWR,
+ true, quiet);
+ }
if (!blk) {
ret = -1;
goto out;
@@ -3171,7 +3469,7 @@ static int img_amend(int argc, char **argv)
char *options = NULL;
QemuOptsList *create_opts = NULL;
QemuOpts *opts = NULL;
- const char *fmt = NULL, *filename, *cache;
+ const char *fmt = NULL, *filename = NULL, *cache;
int flags;
bool quiet = false, progress = false;
BlockBackend *blk = NULL;
@@ -3183,6 +3481,7 @@ static int img_amend(int argc, char **argv)
static const struct option long_options[] = {
{"help", no_argument, 0, 'h'},
{"object", required_argument, 0, OPTION_OBJECT},
+ {"source", required_argument, 0, OPTION_SOURCE},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "ho:f:t:pq",
@@ -3229,6 +3528,13 @@ static int img_amend(int argc, char **argv)
exit(1);
}
break;
+ case OPTION_SOURCE:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("source"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
@@ -3236,6 +3542,12 @@ static int img_amend(int argc, char **argv)
error_exit("Must specify options (-o)");
}
+ if (filename) {
+ if (optind != argc) {
+ error_exit("--source and filename are mutually exclusive");
+ }
+ }
+
if (qemu_opts_foreach(qemu_find_opts("object"),
object_create,
NULL, NULL)) {
@@ -3247,7 +3559,9 @@ static int img_amend(int argc, char **argv)
}
qemu_progress_init(progress, 1.0);
- filename = (optind == argc - 1) ? argv[argc - 1] : NULL;
+ if (!filename) {
+ filename = (optind == argc - 1) ? argv[argc - 1] : NULL;
+ }
if (fmt && has_help_option(options)) {
/* If a format is explicitly specified (and possibly no filename is
* given), print option help here */
@@ -3255,8 +3569,9 @@ static int img_amend(int argc, char **argv)
goto out;
}
- if (optind != argc - 1) {
- error_report("Expecting one image file name");
+ if (!filename &&
+ (optind != argc - 1)) {
+ error_exit("Expecting one image file name");
ret = -1;
goto out;
}
@@ -3268,7 +3583,17 @@ static int img_amend(int argc, char **argv)
goto out;
}
- blk = img_open("image", filename, fmt, flags, true, quiet);
+ opts = qemu_opts_find(&qemu_source_opts, NULL);
+ if (opts) {
+ if (fmt) {
+ error_report("--source and --format are mutually exclusive");
+ ret = -1;
+ goto out;
+ }
+ blk = img_open_opts("image", opts, BDRV_O_FLAGS | BDRV_O_RDWR);
+ } else {
+ blk = img_open_file("image", filename, fmt, flags, true, quiet);
+ }
if (!blk) {
ret = -1;
goto out;
@@ -3366,6 +3691,7 @@ int main(int argc, char **argv)
module_call_init(MODULE_INIT_QOM);
qemu_add_opts(&qemu_object_opts);
+ qemu_add_opts(&qemu_source_opts);
/* find the command */
for (cmd = img_cmds; cmd->name != NULL; cmd++) {
diff --git a/util/qemu-option.c b/util/qemu-option.c
index a50ecea..48e1cc5 100644
--- a/util/qemu-option.c
+++ b/util/qemu-option.c
@@ -637,6 +637,12 @@ QemuOpts *qemu_opts_find(QemuOptsList *list, const char
*id)
return NULL;
}
+
+QemuOpts *qemu_opts_next(QemuOpts *opts)
+{
+ return QTAILQ_NEXT(opts, next);
+}
+
QemuOpts *qemu_opts_create(QemuOptsList *list, const char *id,
int fail_if_exists, Error **errp)
{
--
2.4.3
- Re: [Qemu-block] [Qemu-devel] [PATCH 07/17] qcow2: add a 'keyid' parameter to qcow2 options, (continued)
- [Qemu-block] [PATCH 06/17] qcow: add a 'keyid' parameter to qcow options, Daniel P. Berrange, 2015/10/19
- [Qemu-block] [PATCH 10/17] qemu-nbd: add support for --object command line arg, Daniel P. Berrange, 2015/10/19
- [Qemu-block] [PATCH 08/17] qom: add user_creatable_add & user_creatable_del methods, Daniel P. Berrange, 2015/10/19
- [Qemu-block] [PATCH 09/17] qemu-img: add support for --object command line arg, Daniel P. Berrange, 2015/10/19
- [Qemu-block] [PATCH 13/17] qemu-nbd: allow specifying image as a set of options args, Daniel P. Berrange, 2015/10/19
- [Qemu-block] [PATCH 11/17] qemu-io: add support for --object command line arg, Daniel P. Berrange, 2015/10/19
- [Qemu-block] [PATCH 12/17] qemu-io: allow specifying image as a set of options args, Daniel P. Berrange, 2015/10/19
- [Qemu-block] [PATCH 16/17] block: remove all encryption handling APIs, Daniel P. Berrange, 2015/10/19
- [Qemu-block] [PATCH 15/17] block: rip out all traces of password prompting, Daniel P. Berrange, 2015/10/19
- [Qemu-block] [PATCH 14/17] qemu-img: allow specifying image as a set of options args,
Daniel P. Berrange <=
- [Qemu-block] [PATCH 17/17] block: remove support for writing to qcow/qcow2 encrypted images, Daniel P. Berrange, 2015/10/19
- Re: [Qemu-block] [Qemu-devel] [PATCH 00/17] Framework for securely passing secrets to QEMU, Alex Bennée, 2015/10/19
- Re: [Qemu-block] [Qemu-devel] [PATCH 00/17] Framework for securely passing secrets to QEMU, Dr. David Alan Gilbert, 2015/10/19
- Re: [Qemu-block] [PATCH 00/17] Framework for securely passing secrets to QEMU, Stefan Hajnoczi, 2015/10/23