From: John Snow <jsnow@redhat.com>
To: qemu-block@nongnu.org, qemu-devel@nongnu.org
Cc: Max Reitz <mreitz@redhat.com>,
Markus Armbruster <armbru@redhat.com>,
Kevin Wolf <kwolf@redhat.com>, Eric Blake <eblake@redhat.com>,
Vladimir Sementsov-Ogievskiy <vsementsov@virtuozzo.com>,
John Snow <jsnow@redhat.com>
Subject: [Qemu-devel] [RFC PATCH 10/12] qemu-img: split off common chunk of map command
Date: Fri, 11 May 2018 21:25:35 -0400 [thread overview]
Message-ID: <20180512012537.22478-11-jsnow@redhat.com> (raw)
In-Reply-To: <20180512012537.22478-1-jsnow@redhat.com>
It will be re-used for a bitmap listing command.
Signed-off-by: John Snow <jsnow@redhat.com>
---
qemu-img.c | 192 +++++++++++++++++++++++++++++++++++--------------------------
1 file changed, 110 insertions(+), 82 deletions(-)
diff --git a/qemu-img.c b/qemu-img.c
index ea62d2d61e..e31e38f674 100644
--- a/qemu-img.c
+++ b/qemu-img.c
@@ -69,8 +69,8 @@ enum {
};
typedef enum OutputFormat {
- OFORMAT_JSON,
OFORMAT_HUMAN,
+ OFORMAT_JSON,
} OutputFormat;
/* Default to cache=writeback as data integrity is not important for qemu-img */
@@ -2728,96 +2728,122 @@ static inline bool entry_mergeable(const MapEntry *curr, const MapEntry *next)
return true;
}
+typedef struct CommonOpts {
+ OutputFormat output_format;
+ const char *filename;
+ const char *fmt;
+ bool force_share;
+ bool image_opts;
+} CommonOpts;
+
+static int parse_opts_common(CommonOpts *opts, int argc, char **argv)
+{
+ int c;
+
+ for (;;) {
+ int option_index = 0;
+ static const struct option long_options[] = {
+ {"help", no_argument, 0, 'h'},
+ {"format", required_argument, 0, 'f'},
+ {"output", required_argument, 0, OPTION_OUTPUT},
+ {"object", required_argument, 0, OPTION_OBJECT},
+ {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
+ {"force-share", no_argument, 0, 'U'},
+ {0, 0, 0, 0}
+ };
+ c = getopt_long(argc, argv, ":f:hU",
+ long_options, &option_index);
+ if (c == -1) {
+ break;
+ }
+ switch (c) {
+ case ':':
+ missing_argument(argv[optind - 1]);
+ break;
+ case '?':
+ unrecognized_option(argv[optind - 1]);
+ break;
+ case 'h':
+ help();
+ break;
+ case 'f':
+ opts->fmt = optarg;
+ break;
+ case 'U':
+ opts->force_share = true;
+ break;
+ case OPTION_OUTPUT:
+ if (optarg && !strcmp(optarg, "json")) {
+ opts->output_format = OFORMAT_JSON;
+ } else if (optarg && !strcmp(optarg, "human")) {
+ opts->output_format = OFORMAT_HUMAN;
+ } else {
+ error_report("--output must be used with human or json as argument.");
+ return -EINVAL;
+ }
+ break;
+ case OPTION_OBJECT: {
+ QemuOpts *opts;
+ opts = qemu_opts_parse_noisily(&qemu_object_opts,
+ optarg, true);
+ if (!opts) {
+ return -EINVAL;
+ }
+ } break;
+ case OPTION_IMAGE_OPTS:
+ opts->image_opts = true;
+ break;
+ }
+ }
+ if (qemu_opts_foreach(&qemu_object_opts,
+ user_creatable_add_opts_foreach,
+ NULL, NULL)) {
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static void parse_positional(int argc, char *argv[],
+ bool opt, const char **str, const char *name) {
+ if (!opt && optind >= argc) {
+ error_exit("Expecting '%s' positional parameter", name);
+ } else if (optind < argc) {
+ *str = argv[optind++];
+ }
+}
+
+static void parse_unexpected(int argc, char *argv[]) {
+ if (optind != argc) {
+ error_exit("Unexpected argument '%s'\n", argv[optind]);
+ }
+}
+
static int img_map(int argc, char **argv)
{
- int c;
- OutputFormat output_format = OFORMAT_HUMAN;
BlockBackend *blk;
BlockDriverState *bs;
- const char *filename, *fmt, *output;
int64_t length;
+ int ret = 0;
MapEntry curr = { .length = 0 }, next;
- int ret = 0;
- bool image_opts = false;
- bool force_share = false;
+ CommonOpts *opts;
- fmt = NULL;
- output = NULL;
- for (;;) {
- int option_index = 0;
- static const struct option long_options[] = {
- {"help", no_argument, 0, 'h'},
- {"format", required_argument, 0, 'f'},
- {"output", required_argument, 0, OPTION_OUTPUT},
- {"object", required_argument, 0, OPTION_OBJECT},
- {"image-opts", no_argument, 0, OPTION_IMAGE_OPTS},
- {"force-share", no_argument, 0, 'U'},
- {0, 0, 0, 0}
- };
- c = getopt_long(argc, argv, ":f:hU",
- long_options, &option_index);
- if (c == -1) {
- break;
- }
- switch (c) {
- case ':':
- missing_argument(argv[optind - 1]);
- break;
- case '?':
- unrecognized_option(argv[optind - 1]);
- break;
- case 'h':
- help();
- break;
- case 'f':
- fmt = optarg;
- break;
- case 'U':
- force_share = true;
- break;
- case OPTION_OUTPUT:
- output = optarg;
- break;
- case OPTION_OBJECT: {
- QemuOpts *opts;
- opts = qemu_opts_parse_noisily(&qemu_object_opts,
- optarg, true);
- if (!opts) {
- return 1;
- }
- } break;
- case OPTION_IMAGE_OPTS:
- image_opts = true;
- break;
- }
- }
- if (optind != argc - 1) {
- error_exit("Expecting one image file name");
- }
- filename = argv[optind];
-
- if (output && !strcmp(output, "json")) {
- output_format = OFORMAT_JSON;
- } else if (output && !strcmp(output, "human")) {
- output_format = OFORMAT_HUMAN;
- } else if (output) {
- error_report("--output must be used with human or json as argument.");
- return 1;
- }
-
- if (qemu_opts_foreach(&qemu_object_opts,
- user_creatable_add_opts_foreach,
- NULL, NULL)) {
- return 1;
+ opts = g_new0(CommonOpts, 1);
+ if (parse_opts_common(opts, argc, argv)) {
+ return EXIT_FAILURE;
}
+ parse_positional(argc, argv, 0, &opts->filename, "filename");
+ parse_unexpected(argc, argv);
- blk = img_open(image_opts, filename, fmt, 0, false, false, force_share);
+ blk = img_open(opts->image_opts, opts->filename, opts->fmt, 0,
+ false, false, opts->force_share);
if (!blk) {
- return 1;
+ ret = -1;
+ goto out1;
}
bs = blk_bs(blk);
- if (output_format == OFORMAT_HUMAN) {
+ if (opts->output_format == OFORMAT_HUMAN) {
printf("%-16s%-16s%-16s%s\n", "Offset", "Length", "Mapped to", "File");
}
@@ -2832,7 +2858,7 @@ static int img_map(int argc, char **argv)
if (ret < 0) {
error_report("Could not read file metadata: %s", strerror(-ret));
- goto out;
+ goto out2;
}
if (entry_mergeable(&curr, &next)) {
@@ -2841,15 +2867,17 @@ static int img_map(int argc, char **argv)
}
if (curr.length > 0) {
- dump_map_entry(output_format, &curr, &next);
+ dump_map_entry(opts->output_format, &curr, &next);
}
curr = next;
}
- dump_map_entry(output_format, &curr, NULL);
+ dump_map_entry(opts->output_format, &curr, NULL);
-out:
+out2:
blk_unref(blk);
+out1:
+ g_free(opts);
return ret < 0;
}
--
2.14.3
next prev parent reply other threads:[~2018-05-12 1:25 UTC|newest]
Thread overview: 37+ messages / expand[flat|nested] mbox.gz Atom feed top
2018-05-12 1:25 [Qemu-devel] [RFC PATCH 00/12] qemu-img: add bitmap queries John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 01/12] qcow2-bitmap: cache bm_list John Snow
2018-05-14 11:55 ` Vladimir Sementsov-Ogievskiy
2018-05-14 12:15 ` Vladimir Sementsov-Ogievskiy
2018-05-15 20:38 ` John Snow
2018-05-15 20:27 ` John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 02/12] qcow2/dirty-bitmap: cache loaded bitmaps John Snow
2018-05-14 12:33 ` Vladimir Sementsov-Ogievskiy
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 03/12] block/qcow2-bitmap: avoid adjusting bm->flags for RO bitmaps John Snow
2018-05-14 12:44 ` Vladimir Sementsov-Ogievskiy
2018-05-15 20:59 ` John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 04/12] qcow2/dirty-bitmaps: load IN_USE bitmaps if disk is RO John Snow
2018-05-14 12:55 ` Vladimir Sementsov-Ogievskiy
2018-05-15 20:52 ` John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 05/12] qcow2-bitmap: track bitmap type John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 06/12] qapi: add bitmap info John Snow
2018-05-14 14:30 ` Vladimir Sementsov-Ogievskiy
2018-05-15 20:56 ` John Snow
2018-05-16 21:15 ` John Snow
2018-05-17 10:01 ` Vladimir Sementsov-Ogievskiy
2018-05-17 16:43 ` John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 07/12] qcow2-bitmap: add basic bitmaps info John Snow
2018-05-14 15:12 ` Vladimir Sementsov-Ogievskiy
2018-05-15 21:03 ` John Snow
2018-05-16 21:17 ` John Snow
2018-05-17 10:03 ` Vladimir Sementsov-Ogievskiy
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 08/12] qjson: allow caller to ask for arbitrary indent John Snow
2018-05-16 21:34 ` Eric Blake
2018-05-16 21:49 ` John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 09/12] qapi/block-core: add BitmapMapping and BitmapEntry structs John Snow
2018-05-16 21:37 ` Eric Blake
2018-05-16 21:55 ` John Snow
2018-05-12 1:25 ` John Snow [this message]
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 11/12] qemu-img: add bitmap dump John Snow
2018-05-12 1:25 ` [Qemu-devel] [RFC PATCH 12/12] qemu-img: add bitmap clear John Snow
2018-05-12 1:38 ` [Qemu-devel] [RFC PATCH 00/12] qemu-img: add bitmap queries no-reply
2018-05-14 11:32 ` Vladimir Sementsov-Ogievskiy
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=20180512012537.22478-11-jsnow@redhat.com \
--to=jsnow@redhat.com \
--cc=armbru@redhat.com \
--cc=eblake@redhat.com \
--cc=kwolf@redhat.com \
--cc=mreitz@redhat.com \
--cc=qemu-block@nongnu.org \
--cc=qemu-devel@nongnu.org \
--cc=vsementsov@virtuozzo.com \
/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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).