From: "Daniel P. Berrange" <berrange@redhat.com>
To: qemu-devel@nongnu.org
Cc: "Kevin Wolf" <kwolf@redhat.com>,
qemu-block@nongnu.org, "Markus Armbruster" <armbru@redhat.com>,
"Paolo Bonzini" <pbonzini@redhat.com>,
"Andreas Färber" <afaerber@suse.de>
Subject: [Qemu-devel] [PATCH v3 02/10] qemu-img: add support for --object command line arg
Date: Tue, 19 Jan 2016 10:37:04 +0000 [thread overview]
Message-ID: <1453199832-22523-3-git-send-email-berrange@redhat.com> (raw)
In-Reply-To: <1453199832-22523-1-git-send-email-berrange@redhat.com>
Allow creation of user creatable object types with qemu-img
via a new --object command line arg. This will be used to supply
passwords and/or encryption keys to the various block driver
backends via the recently added 'secret' object type.
# printf letmein > mypasswd.txt
# qemu-img info --object secret,id=sec0,file=mypasswd.txt \
...other info args...
Signed-off-by: Daniel P. Berrange <berrange@redhat.com>
---
qemu-img-cmds.hx | 44 ++++-----
qemu-img.c | 266 +++++++++++++++++++++++++++++++++++++++++++++++++++++--
qemu-img.texi | 8 ++
3 files changed, 288 insertions(+), 30 deletions(-)
diff --git a/qemu-img-cmds.hx b/qemu-img-cmds.hx
index 9567774..5bb1de7 100644
--- a/qemu-img-cmds.hx
+++ b/qemu-img-cmds.hx
@@ -10,68 +10,68 @@ STEXI
ETEXI
DEF("check", img_check,
- "check [-q] [-f fmt] [--output=ofmt] [-r [leaks | all]] [-T src_cache] filename")
+ "check [-q] [--object objectdef] [-f fmt] [--output=ofmt] [-r [leaks | all]] [-T src_cache] filename")
STEXI
-@item check [-q] [-f @var{fmt}] [--output=@var{ofmt}] [-r [leaks | all]] [-T @var{src_cache}] @var{filename}
+@item check [--object objectdef] [-q] [-f @var{fmt}] [--output=@var{ofmt}] [-r [leaks | all]] [-T @var{src_cache}] @var{filename}
ETEXI
DEF("create", img_create,
- "create [-q] [-f fmt] [-o options] filename [size]")
+ "create [-q] [--object objectdef] [-f fmt] [-o options] filename [size]")
STEXI
-@item create [-q] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}]
+@item create [--object objectdef] [-q] [-f @var{fmt}] [-o @var{options}] @var{filename} [@var{size}]
ETEXI
DEF("commit", img_commit,
- "commit [-q] [-f fmt] [-t cache] [-b base] [-d] [-p] filename")
+ "commit [-q] [--object objectdef] [-f fmt] [-t cache] [-b base] [-d] [-p] filename")
STEXI
-@item commit [-q] [-f @var{fmt}] [-t @var{cache}] [-b @var{base}] [-d] [-p] @var{filename}
+@item commit [--object objectdef] [-q] [-f @var{fmt}] [-t @var{cache}] [-b @var{base}] [-d] [-p] @var{filename}
ETEXI
DEF("compare", img_compare,
- "compare [-f fmt] [-F fmt] [-T src_cache] [-p] [-q] [-s] filename1 filename2")
+ "compare [--object objectdef] [-f fmt] [-F fmt] [-T src_cache] [-p] [-q] [-s] filename1 filename2")
STEXI
-@item compare [-f @var{fmt}] [-F @var{fmt}] [-T @var{src_cache}] [-p] [-q] [-s] @var{filename1} @var{filename2}
+@item compare [--object objectdef] [-f @var{fmt}] [-F @var{fmt}] [-T @var{src_cache}] [-p] [-q] [-s] @var{filename1} @var{filename2}
ETEXI
DEF("convert", img_convert,
- "convert [-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] [-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 [-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 objectdef] [-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("info", img_info,
- "info [-f fmt] [--output=ofmt] [--backing-chain] filename")
+ "info [--object objectdef] [-f fmt] [--output=ofmt] [--backing-chain] filename")
STEXI
-@item info [-f @var{fmt}] [--output=@var{ofmt}] [--backing-chain] @var{filename}
+@item info [--object objectdef] [-f @var{fmt}] [--output=@var{ofmt}] [--backing-chain] @var{filename}
ETEXI
DEF("map", img_map,
- "map [-f fmt] [--output=ofmt] filename")
+ "map [--object objectdef] [-f fmt] [--output=ofmt] filename")
STEXI
-@item map [-f @var{fmt}] [--output=@var{ofmt}] @var{filename}
+@item map [--object objectdef] [-f @var{fmt}] [--output=@var{ofmt}] @var{filename}
ETEXI
DEF("snapshot", img_snapshot,
- "snapshot [-q] [-l | -a snapshot | -c snapshot | -d snapshot] filename")
+ "snapshot [--object objectdef] [-q] [-l | -a snapshot | -c snapshot | -d snapshot] filename")
STEXI
-@item snapshot [-q] [-l | -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot}] @var{filename}
+@item snapshot [--object objectdef] [-q] [-l | -a @var{snapshot} | -c @var{snapshot} | -d @var{snapshot}] @var{filename}
ETEXI
DEF("rebase", img_rebase,
- "rebase [-q] [-f fmt] [-t cache] [-T src_cache] [-p] [-u] -b backing_file [-F backing_fmt] filename")
+ "rebase [--object objectdef] [-q] [-f fmt] [-t cache] [-T src_cache] [-p] [-u] -b backing_file [-F backing_fmt] filename")
STEXI
-@item rebase [-q] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
+@item rebase [--object objectdef] [-q] [-f @var{fmt}] [-t @var{cache}] [-T @var{src_cache}] [-p] [-u] -b @var{backing_file} [-F @var{backing_fmt}] @var{filename}
ETEXI
DEF("resize", img_resize,
- "resize [-q] filename [+ | -]size")
+ "resize [--object objectdef] [-q] filename [+ | -]size")
STEXI
-@item resize [-q] @var{filename} [+ | -]@var{size}
+@item resize [--object objectdef] [-q] @var{filename} [+ | -]@var{size}
ETEXI
DEF("amend", img_amend,
- "amend [-p] [-q] [-f fmt] [-t cache] -o options filename")
+ "amend [--object objectdef] [-p] [-q] [-f fmt] [-t cache] -o options filename")
STEXI
-@item amend [-p] [-q] [-f @var{fmt}] [-t @var{cache}] -o @var{options} @var{filename}
+@item amend [--object objectdef] [-p] [-q] [-f @var{fmt}] [-t @var{cache}] -o @var{options} @var{filename}
@end table
ETEXI
diff --git a/qemu-img.c b/qemu-img.c
index a5949e6..a5019e6 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -23,12 +23,15 @@
*/
#include "qapi-visit.h"
#include "qapi/qmp-output-visitor.h"
+#include "qapi/opts-visitor.h"
#include "qapi/qmp/qerror.h"
#include "qapi/qmp/qjson.h"
#include "qemu-common.h"
+#include "qemu/config-file.h"
#include "qemu/option.h"
#include "qemu/error-report.h"
#include "qemu/osdep.h"
+#include "qom/object_interfaces.h"
#include "sysemu/sysemu.h"
#include "sysemu/block-backend.h"
#include "block/block_int.h"
@@ -47,6 +50,7 @@ typedef struct img_cmd_t {
enum {
OPTION_OUTPUT = 256,
OPTION_BACKING_CHAIN = 257,
+ OPTION_OBJECT = 258,
};
typedef enum OutputFormat {
@@ -94,6 +98,10 @@ static void QEMU_NORETURN help(void)
"\n"
"Command parameters:\n"
" 'filename' is a disk image filename\n"
+ " 'objectdef' is a QEMU user creatable object definition. See the @code{qemu(1)}\n"
+ " manual page for a description of the object properties. The common object\n"
+ " type that it makes sense to define is the @code{secret} object, which is used\n"
+ " to supply passwords and/or encryption keys.\n"
" 'fmt' is the disk image format. It is guessed automatically in most cases\n"
" 'cache' is the cache mode used to write the output disk image, the valid\n"
" options are: 'none', 'writeback' (default, except for convert), 'writethrough',\n"
@@ -154,6 +162,34 @@ static void QEMU_NORETURN help(void)
exit(EXIT_SUCCESS);
}
+static QemuOptsList qemu_object_opts = {
+ .name = "object",
+ .implied_opt_name = "qom-type",
+ .head = QTAILQ_HEAD_INITIALIZER(qemu_object_opts.head),
+ .desc = {
+ { }
+ },
+};
+
+static int object_create(void *opaque, QemuOpts *opts, Error **errp)
+{
+ Error *err = NULL;
+ OptsVisitor *ov;
+ QDict *pdict;
+
+ ov = opts_visitor_new(opts);
+ pdict = qemu_opts_to_qdict(opts, NULL);
+
+ user_creatable_add(pdict, opts_get_visitor(ov), &err);
+ opts_visitor_cleanup(ov);
+ QDECREF(pdict);
+ if (err) {
+ error_propagate(errp, err);
+ return -1;
+ }
+ return 0;
+}
+
static int GCC_FMT_ATTR(2, 3) qprintf(bool quiet, const char *fmt, ...)
{
int ret = 0;
@@ -273,9 +309,17 @@ static int img_create(int argc, char **argv)
char *options = NULL;
Error *local_err = NULL;
bool quiet = false;
+ QemuOpts *opts;
for(;;) {
- c = getopt(argc, argv, "F:b:f:he6o:q");
+ int option_index = 0;
+ static const struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {"object", required_argument, 0, OPTION_OBJECT},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, "F:b:f:he6o:q",
+ long_options, &option_index);
if (c == -1) {
break;
}
@@ -317,6 +361,13 @@ static int img_create(int argc, char **argv)
case 'q':
quiet = true;
break;
+ case OPTION_OBJECT:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
@@ -332,6 +383,12 @@ static int img_create(int argc, char **argv)
}
optind++;
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create,
+ NULL, NULL)) {
+ exit(1);
+ }
+
/* Get image size, if specified */
if (optind < argc) {
int64_t sval;
@@ -489,6 +546,7 @@ static int img_check(int argc, char **argv)
int flags = BDRV_O_FLAGS | BDRV_O_CHECK;
ImageCheck *check;
bool quiet = false;
+ QemuOpts *opts;
fmt = NULL;
output = NULL;
@@ -500,6 +558,7 @@ static int img_check(int argc, char **argv)
{"format", required_argument, 0, 'f'},
{"repair", required_argument, 0, 'r'},
{"output", required_argument, 0, OPTION_OUTPUT},
+ {"object", required_argument, 0, OPTION_OBJECT},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "hf:r:T:q",
@@ -536,6 +595,13 @@ static int img_check(int argc, char **argv)
case 'q':
quiet = true;
break;
+ case OPTION_OBJECT:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
if (optind != argc - 1) {
@@ -552,6 +618,12 @@ static int img_check(int argc, char **argv)
return 1;
}
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create,
+ NULL, NULL)) {
+ exit(1);
+ }
+
ret = bdrv_parse_cache_flags(cache, &flags);
if (ret < 0) {
error_report("Invalid source cache option: %s", cache);
@@ -670,12 +742,20 @@ static int img_commit(int argc, char **argv)
bool progress = false, quiet = false, drop = false;
Error *local_err = NULL;
CommonBlockJobCBInfo cbi;
+ QemuOpts *opts;
fmt = NULL;
cache = BDRV_DEFAULT_CACHE;
base = NULL;
for(;;) {
- c = getopt(argc, argv, "f:ht:b:dpq");
+ int option_index = 0;
+ static const struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {"object", required_argument, 0, OPTION_OBJECT},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, "f:ht:b:dpq",
+ long_options, &option_index);
if (c == -1) {
break;
}
@@ -704,6 +784,13 @@ static int img_commit(int argc, char **argv)
case 'q':
quiet = true;
break;
+ case OPTION_OBJECT:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
@@ -717,6 +804,12 @@ static int img_commit(int argc, char **argv)
}
filename = argv[optind++];
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create,
+ NULL, NULL)) {
+ exit(1);
+ }
+
flags = BDRV_O_RDWR | BDRV_O_UNMAP;
ret = bdrv_parse_cache_flags(cache, &flags);
if (ret < 0) {
@@ -973,10 +1066,18 @@ static int img_compare(int argc, char **argv)
int64_t nb_sectors;
int c, pnum;
uint64_t progress_base;
+ QemuOpts *opts;
cache = BDRV_DEFAULT_CACHE;
for (;;) {
- c = getopt(argc, argv, "hf:F:T:pqs");
+ int option_index = 0;
+ static const struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {"object", required_argument, 0, OPTION_OBJECT},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, "hf:F:T:pqs",
+ long_options, &option_index);
if (c == -1) {
break;
}
@@ -1003,6 +1104,13 @@ static int img_compare(int argc, char **argv)
case 's':
strict = true;
break;
+ case OPTION_OBJECT:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
@@ -1018,6 +1126,12 @@ static int img_compare(int argc, char **argv)
filename1 = argv[optind++];
filename2 = argv[optind++];
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create,
+ NULL, NULL)) {
+ exit(1);
+ }
+
/* Initialize before goto out */
qemu_progress_init(progress, 2.0);
@@ -1537,7 +1651,14 @@ static int img_convert(int argc, char **argv)
compress = 0;
skip_create = 0;
for(;;) {
- c = getopt(argc, argv, "hf:O:B:ce6o:s:l:S:pt:T:qn");
+ int option_index = 0;
+ static const struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {"object", required_argument, 0, OPTION_OBJECT},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, "hf:O:B:ce6o:s:l:S:pt:T:qn",
+ long_options, &option_index);
if (c == -1) {
break;
}
@@ -1628,9 +1749,22 @@ static int img_convert(int argc, char **argv)
case 'n':
skip_create = 1;
break;
+ case OPTION_OBJECT:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create,
+ NULL, NULL)) {
+ exit(1);
+ }
+
/* Initialize before goto out */
if (quiet) {
progress = 0;
@@ -2060,6 +2194,7 @@ static int img_info(int argc, char **argv)
bool chain = false;
const char *filename, *fmt, *output;
ImageInfoList *list;
+ QemuOpts *opts;
fmt = NULL;
output = NULL;
@@ -2070,6 +2205,7 @@ static int img_info(int argc, char **argv)
{"format", required_argument, 0, 'f'},
{"output", required_argument, 0, OPTION_OUTPUT},
{"backing-chain", no_argument, 0, OPTION_BACKING_CHAIN},
+ {"object", required_argument, 0, OPTION_OBJECT},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "f:h",
@@ -2091,6 +2227,13 @@ static int img_info(int argc, char **argv)
case OPTION_BACKING_CHAIN:
chain = true;
break;
+ case OPTION_OBJECT:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
if (optind != argc - 1) {
@@ -2107,6 +2250,12 @@ static int img_info(int argc, char **argv)
return 1;
}
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create,
+ NULL, NULL)) {
+ exit(1);
+ }
+
list = collect_image_info_list(filename, fmt, chain);
if (!list) {
return 1;
@@ -2230,6 +2379,7 @@ static int img_map(int argc, char **argv)
int64_t length;
MapEntry curr = { .length = 0 }, next;
int ret = 0;
+ QemuOpts *opts;
fmt = NULL;
output = NULL;
@@ -2239,6 +2389,7 @@ static int img_map(int argc, char **argv)
{"help", no_argument, 0, 'h'},
{"format", required_argument, 0, 'f'},
{"output", required_argument, 0, OPTION_OUTPUT},
+ {"object", required_argument, 0, OPTION_OBJECT},
{0, 0, 0, 0}
};
c = getopt_long(argc, argv, "f:h",
@@ -2257,6 +2408,13 @@ static int img_map(int argc, char **argv)
case OPTION_OUTPUT:
output = optarg;
break;
+ case OPTION_OBJECT:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
if (optind != argc - 1) {
@@ -2273,6 +2431,12 @@ static int img_map(int argc, char **argv)
return 1;
}
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create,
+ NULL, NULL)) {
+ exit(1);
+ }
+
blk = img_open("image", filename, fmt, BDRV_O_FLAGS, true, false);
if (!blk) {
return 1;
@@ -2338,11 +2502,19 @@ static int img_snapshot(int argc, char **argv)
qemu_timeval tv;
bool quiet = false;
Error *err = NULL;
+ QemuOpts *opts;
bdrv_oflags = BDRV_O_FLAGS | BDRV_O_RDWR;
/* Parse commandline parameters */
for(;;) {
- c = getopt(argc, argv, "la:c:d:hq");
+ int option_index = 0;
+ static const struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {"object", required_argument, 0, OPTION_OBJECT},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, "la:c:d:hq",
+ long_options, &option_index);
if (c == -1) {
break;
}
@@ -2386,6 +2558,13 @@ static int img_snapshot(int argc, char **argv)
case 'q':
quiet = true;
break;
+ case OPTION_OBJECT:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
@@ -2394,6 +2573,12 @@ static int img_snapshot(int argc, char **argv)
}
filename = argv[optind++];
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create,
+ NULL, NULL)) {
+ exit(1);
+ }
+
/* Open the image */
blk = img_open("image", filename, NULL, bdrv_oflags, true, quiet);
if (!blk) {
@@ -2459,6 +2644,7 @@ static int img_rebase(int argc, char **argv)
int progress = 0;
bool quiet = false;
Error *local_err = NULL;
+ QemuOpts *opts;
/* Parse commandline parameters */
fmt = NULL;
@@ -2467,7 +2653,14 @@ static int img_rebase(int argc, char **argv)
out_baseimg = NULL;
out_basefmt = NULL;
for(;;) {
- c = getopt(argc, argv, "hf:F:b:upt:T:q");
+ int option_index = 0;
+ static const struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {"object", required_argument, 0, OPTION_OBJECT},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, "hf:F:b:upt:T:q",
+ long_options, &option_index);
if (c == -1) {
break;
}
@@ -2500,6 +2693,13 @@ static int img_rebase(int argc, char **argv)
case 'q':
quiet = true;
break;
+ case OPTION_OBJECT:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
@@ -2515,6 +2715,12 @@ static int img_rebase(int argc, char **argv)
}
filename = argv[optind++];
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create,
+ NULL, NULL)) {
+ exit(1);
+ }
+
qemu_progress_init(progress, 2.0);
qemu_progress_print(0, 100);
@@ -2775,6 +2981,7 @@ static int img_resize(int argc, char **argv)
bool quiet = false;
BlockBackend *blk = NULL;
QemuOpts *param;
+ QemuOpts *opts;
static QemuOptsList resize_options = {
.name = "resize_options",
.head = QTAILQ_HEAD_INITIALIZER(resize_options.head),
@@ -2801,7 +3008,14 @@ static int img_resize(int argc, char **argv)
/* Parse getopt arguments */
fmt = NULL;
for(;;) {
- c = getopt(argc, argv, "f:hq");
+ int option_index = 0;
+ static const struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {"object", required_argument, 0, OPTION_OBJECT},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, "f:hq",
+ long_options, &option_index);
if (c == -1) {
break;
}
@@ -2816,6 +3030,13 @@ static int img_resize(int argc, char **argv)
case 'q':
quiet = true;
break;
+ case OPTION_OBJECT:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
if (optind != argc - 1) {
@@ -2823,6 +3044,12 @@ static int img_resize(int argc, char **argv)
}
filename = argv[optind++];
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create,
+ NULL, NULL)) {
+ exit(1);
+ }
+
/* Choose grow, shrink, or absolute resize mode */
switch (size[0]) {
case '+':
@@ -2913,7 +3140,14 @@ static int img_amend(int argc, char **argv)
cache = BDRV_DEFAULT_CACHE;
for (;;) {
- c = getopt(argc, argv, "ho:f:t:pq");
+ int option_index = 0;
+ static const struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {"object", required_argument, 0, OPTION_OBJECT},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, "ho:f:t:pq",
+ long_options, &option_index);
if (c == -1) {
break;
}
@@ -2949,6 +3183,13 @@ static int img_amend(int argc, char **argv)
case 'q':
quiet = true;
break;
+ case OPTION_OBJECT:
+ opts = qemu_opts_parse_noisily(qemu_find_opts("object"),
+ optarg, true);
+ if (!opts) {
+ exit(1);
+ }
+ break;
}
}
@@ -2956,6 +3197,12 @@ static int img_amend(int argc, char **argv)
error_exit("Must specify options (-o)");
}
+ if (qemu_opts_foreach(qemu_find_opts("object"),
+ object_create,
+ NULL, NULL)) {
+ exit(1);
+ }
+
if (quiet) {
progress = false;
}
@@ -3078,6 +3325,9 @@ int main(int argc, char **argv)
}
cmdname = argv[1];
+ module_call_init(MODULE_INIT_QOM);
+ qemu_add_opts(&qemu_object_opts);
+
/* find the command */
for (cmd = img_cmds; cmd->name != NULL; cmd++) {
if (!strcmp(cmdname, cmd->name)) {
diff --git a/qemu-img.texi b/qemu-img.texi
index 55c6be3..da93272 100644
--- a/qemu-img.texi
+++ b/qemu-img.texi
@@ -24,6 +24,14 @@ Command parameters:
@table @var
@item filename
is a disk image filename
+
+@item --object @var{objectdef}
+
+is a QEMU user creatable object definition. See the @code{qemu(1)} manual
+page for a description of the object properties. The only object type that
+it makes sense to define is the @code{secret} object, which is used to
+supply passwords and/or encryption keys.
+
@item fmt
is the disk image format. It is guessed automatically in most cases. See below
for a description of the supported disk formats.
--
2.5.0
next prev parent reply other threads:[~2016-01-19 10:37 UTC|newest]
Thread overview: 12+ messages / expand[flat|nested] mbox.gz Atom feed top
2016-01-19 10:37 [Qemu-devel] [PATCH v3 00/10] Make qemu-img/qemu-nbd/qemu-io CLI more flexible Daniel P. Berrange
2016-01-19 10:37 ` [Qemu-devel] [PATCH v3 01/10] qom: add helpers for UserCreatable object types Daniel P. Berrange
2016-01-19 10:37 ` Daniel P. Berrange [this message]
2016-01-21 16:19 ` [Qemu-devel] [PATCH v3 02/10] qemu-img: add support for --object command line arg Daniel P. Berrange
2016-01-19 10:37 ` [Qemu-devel] [PATCH v3 03/10] qemu-nbd: " Daniel P. Berrange
2016-01-19 10:37 ` [Qemu-devel] [PATCH v3 04/10] qemu-io: " Daniel P. Berrange
2016-01-19 10:37 ` [Qemu-devel] [PATCH v3 05/10] qemu-io: allow specifying image as a set of options args Daniel P. Berrange
2016-01-19 10:37 ` [Qemu-devel] [PATCH v3 06/10] qemu-nbd: " Daniel P. Berrange
2016-01-19 10:37 ` [Qemu-devel] [PATCH v3 07/10] qemu-img: " Daniel P. Berrange
2016-01-19 10:37 ` [Qemu-devel] [PATCH v3 08/10] qemu-nbd: don't overlap long option values with short options Daniel P. Berrange
2016-01-19 10:37 ` [Qemu-devel] [PATCH v3 09/10] qemu-nbd: use no_argument/required_argument constants Daniel P. Berrange
2016-01-19 10:37 ` [Qemu-devel] [PATCH v3 10/10] qemu-io: " Daniel P. Berrange
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=1453199832-22523-3-git-send-email-berrange@redhat.com \
--to=berrange@redhat.com \
--cc=afaerber@suse.de \
--cc=armbru@redhat.com \
--cc=kwolf@redhat.com \
--cc=pbonzini@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.