Kevin Wolf <kwolf@xxxxxxxxxx> writes: > This switches qemu-img from a QemuOpts-based parser for --object to > user_creatable_process_cmdline() which uses a keyval parser and enforces > the QAPI schema. > > Apart from being a cleanup, this makes non-scalar properties accessible. > > Signed-off-by: Kevin Wolf <kwolf@xxxxxxxxxx> > Acked-by: Peter Krempa <pkrempa@xxxxxxxxxx> > --- > qemu-img.c | 251 ++++++++++------------------------------------------- > 1 file changed, 45 insertions(+), 206 deletions(-) > > diff --git a/qemu-img.c b/qemu-img.c > index e2952fe955..babb5573ab 100644 > --- a/qemu-img.c > +++ b/qemu-img.c > @@ -226,23 +226,6 @@ 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 bool qemu_img_object_print_help(const char *type, QemuOpts *opts) > -{ > - if (user_creatable_print_help(type, opts)) { > - exit(0); > - } > - return true; > -} > - > /* > * Is @optarg safe for accumulate_options()? > * It is when multiple of them can be joined together separated by ','. > @@ -566,14 +549,9 @@ static int img_create(int argc, char **argv) > case 'u': > flags |= BDRV_O_NO_BACKING; > break; > - case OPTION_OBJECT: { > - QemuOpts *opts; > - opts = qemu_opts_parse_noisily(&qemu_object_opts, > - optarg, true); > - if (!opts) { > - goto fail; > - } > - } break; > + case OPTION_OBJECT: > + user_creatable_process_cmdline(optarg); > + break; > } > } > > @@ -589,12 +567,6 @@ static int img_create(int argc, char **argv) > } > optind++; > > - if (qemu_opts_foreach(&qemu_object_opts, > - user_creatable_add_opts_foreach, > - qemu_img_object_print_help, &error_fatal)) { > - goto fail; > - } > - > /* Get image size, if specified */ > if (optind < argc) { > int64_t sval; > @@ -804,14 +776,9 @@ static int img_check(int argc, char **argv) > case 'U': > force_share = true; > break; > - case OPTION_OBJECT: { > - QemuOpts *opts; > - opts = qemu_opts_parse_noisily(&qemu_object_opts, > - optarg, true); > - if (!opts) { > - return 1; > - } > - } break; > + case OPTION_OBJECT: > + user_creatable_process_cmdline(optarg); > + break; > case OPTION_IMAGE_OPTS: > image_opts = true; > break; > @@ -831,12 +798,6 @@ static int img_check(int argc, char **argv) > return 1; > } > > - if (qemu_opts_foreach(&qemu_object_opts, > - user_creatable_add_opts_foreach, > - qemu_img_object_print_help, &error_fatal)) { > - return 1; > - } > - > ret = bdrv_parse_cache_mode(cache, &flags, &writethrough); > if (ret < 0) { > error_report("Invalid source cache option: %s", cache); > @@ -1034,14 +995,9 @@ static int img_commit(int argc, char **argv) > return 1; > } > break; > - case OPTION_OBJECT: { > - QemuOpts *opts; > - opts = qemu_opts_parse_noisily(&qemu_object_opts, > - optarg, true); > - if (!opts) { > - return 1; > - } > - } break; > + case OPTION_OBJECT: > + user_creatable_process_cmdline(optarg); > + break; > case OPTION_IMAGE_OPTS: > image_opts = true; > break; > @@ -1058,12 +1014,6 @@ static int img_commit(int argc, char **argv) > } > filename = argv[optind++]; > > - if (qemu_opts_foreach(&qemu_object_opts, > - user_creatable_add_opts_foreach, > - qemu_img_object_print_help, &error_fatal)) { > - return 1; > - } > - > flags = BDRV_O_RDWR | BDRV_O_UNMAP; > ret = bdrv_parse_cache_mode(cache, &flags, &writethrough); > if (ret < 0) { > @@ -1353,7 +1303,7 @@ static int check_empty_sectors(BlockBackend *blk, int64_t offset, > /* > * Compares two images. Exit codes: > * > - * 0 - Images are identical > + * 0 - Images are identical or the requested help was printed > * 1 - Images differ > * >1 - Error occurred > */ > @@ -1423,15 +1373,21 @@ static int img_compare(int argc, char **argv) > case 'U': > force_share = true; > break; > - case OPTION_OBJECT: { > - QemuOpts *opts; > - opts = qemu_opts_parse_noisily(&qemu_object_opts, > - optarg, true); > - if (!opts) { > - ret = 2; > - goto out4; > + case OPTION_OBJECT: > + { > + Error *local_err = NULL; > + > + if (!user_creatable_add_from_str(optarg, &local_err)) { > + if (local_err) { > + error_report_err(local_err); > + exit(2); > + } else { > + /* Help was printed */ > + exit(EXIT_SUCCESS); > + } > + } > + break; > } > - } break; > case OPTION_IMAGE_OPTS: > image_opts = true; > break; Why is this one different? The others all call user_creatable_process_cmdline(). > @@ -1450,13 +1406,6 @@ static int img_compare(int argc, char **argv) > filename1 = argv[optind++]; > filename2 = argv[optind++]; > > - if (qemu_opts_foreach(&qemu_object_opts, > - user_creatable_add_opts_foreach, > - qemu_img_object_print_help, &error_fatal)) { > - ret = 2; > - goto out4; > - } > - > /* Initialize before goto out */ > qemu_progress_init(progress, 2.0); > > @@ -1641,7 +1590,6 @@ out2: > blk_unref(blk1); > out3: > qemu_progress_end(); > -out4: > return ret; > } > [...]