[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]
Re: [Qemu-devel] [PATCH v25 11/31] change block layer to support both Qe
From: |
Chun Yan Liu |
Subject: |
Re: [Qemu-devel] [PATCH v25 11/31] change block layer to support both QemuOpts and QEMUOptionParamter |
Date: |
Wed, 23 Apr 2014 00:44:35 -0600 |
>>> On 4/22/2014 at 07:17 AM, in message <address@hidden>, Eric Blake
<address@hidden> wrote:
> On 04/10/2014 11:54 AM, Chunyan Liu wrote:
> > Change block layer to support both QemuOpts and QEMUOptionParameter.
> > After this patch, it will change backend drivers one by one. At the end,
> > QEMUOptionParameter will be removed and only QemuOpts is kept.
> >
> > Signed-off-by: Dong Xu Wang <address@hidden>
> > Signed-off-by: Chunyan Liu <address@hidden>
> > ---
>
> > @@ -419,8 +420,27 @@ static void coroutine_fn bdrv_create_co_entry(void
> *opaque)
> >
> > CreateCo *cco = opaque;
>
> > + if (cco->drv->bdrv_create2) {
> > + QemuOptsList *opts_list = NULL;
> > + QemuOpts *opts = NULL;
> > + if (!cco->opts) {
>
> Isn't your conversion pair-wise per driver, in that you always pair
> bdrv_create2 with options, and bdrv_create with opts? That is, won't
> cco->opts always be false if cco->drv->bdrv_create2 is non-NULL, since
> we already guaranteed that there is at most one of the two creation
> function callbacks defined? Maybe you have a missing assertion at the
> point where the callbacks are registered? [1]
To handle both QEMUOptionParameter and QemuOpts, we convert
QEMUOptionParameter to QemuOpts first for unified processing.
And according to v22 discussion, it's better to convert back to
QEMUOptionParameter at the last moment.
https://lists.gnu.org/archive/html/qemu-devel/2014-03/msg02181.html.
For bdrv_create, either do this in bdrv_create(), or here in
bdrv_create_co_entry(). bdrv_create() just calls bdrv_create_co_entry
to do the work. Do you think we should finish conversion in bdrv_create()
before calling bdrv_create_co_entry()?
>
> > + opts_list = params_to_opts(cco->options);
> > + cco->opts = opts =
> > + qemu_opts_create(opts_list, NULL, 0, &error_abort);
>
> Ouch. This assigns to cco->opts,...
>
> > + }
> > + ret = cco->drv->bdrv_create2(cco->filename, cco->opts,
> > &local_err);
> > + qemu_opts_del(opts);
>
> ...but this frees the memory. You have modified the caller's opaque
> pointer to point to what is now stale memory. Is this intentional? [2]
Yes. My intension is to avoid deleting cco->opts errorly, only the converted
one from cco->options should be deleted, so I use a temp variable to retrieve
the new allocated opts, just new and delete the temp variable is OK.
The work could also be done as:
if (cco->options) {
opts_list = params_to_opts(cco->options);
cco->opts =
qemu_opts_create(opts_list, NULL, 0, &error_abort);
}
ret = cco->drv->bdrv_create2(cco->filename, cco->opts, &local_err);
if (cco->options) {
qemu_opts_del(cco->opts);
qemu_opts_free(opts_list);
}
>
> > + qemu_opts_free(opts_list);
> > + } else {
> > + QEMUOptionParameter *options = NULL;
> > + if (!cco->options) {
> > + cco->options = options = opts_to_params(cco->opts);
> > + }
> > + ret = cco->drv->bdrv_create(cco->filename, cco->options,
> > &local_err);
> > + free_option_parameters(options);
>
> Same question [2] in the opposite direction for cco->options.
>
>
>
> > @@ -5296,28 +5328,25 @@ void bdrv_img_create(const char *filename, const
> char *fmt,
>
> > /* Parse -o options */
> > if (options) {
> > - param = parse_option_parameters(options, create_options, param);
> > - if (param == NULL) {
> > + if (qemu_opts_do_parse(opts, options, NULL) != 0) {
> > error_setg(errp, "Invalid options for file format '%s'.",
> fmt);
>
> Pre-existing (and probably worth an independent patch to qemu-trivial),
> but error messages typically should not end in '.'
Will add new patch for that.
>
> > +int bdrv_amend_options(BlockDriverState *bs, QEMUOptionParameter *options,
> > + QemuOpts *opts)
> > {
> > - if (bs->drv->bdrv_amend_options == NULL) {
> > + int ret;
> > + assert(!(options && opts));
> > +
> > + if (!bs->drv->bdrv_amend_options && !bs->drv->bdrv_amend_options2) {
>
> Hmm, should we also guarantee that at most one of these callback
> functions exist? [1]
>
> > return -ENOTSUP;
> > }
> > - return bs->drv->bdrv_amend_options(bs, options);
> > + if (bs->drv->bdrv_amend_options2) {
> > + QemuOptsList *tmp_opts_list = NULL;
> > + QemuOpts *tmp_opts = NULL;
> > + if (options) {
> > + tmp_opts_list = params_to_opts(options);
> > + opts = tmp_opts =
> > + qemu_opts_create(tmp_opts_list, NULL, 0, &error_abort);
> > + }
> > + ret = bs->drv->bdrv_amend_options2(bs, opts);
> > + qemu_opts_del(tmp_opts);
>
> Why do you need tmp_opts? Isn't manipulation of 'opts' sufficient here?
Same as answer to [2]. The intension is to avoid deleting opts errorly.
>
> > +++ b/include/block/block_int.h
> > @@ -118,6 +118,8 @@ struct BlockDriver {
> > void (*bdrv_rebind)(BlockDriverState *bs);
> > int (*bdrv_create)(const char *filename, QEMUOptionParameter *options,
> > Error **errp);
> > + /* FIXME: will remove the duplicate and rename back to bdrv_create
> later */
> > + int (*bdrv_create2)(const char *filename, QemuOpts *opts, Error
> **errp);
> > int (*bdrv_set_key)(BlockDriverState *bs, const char *key);
> > int (*bdrv_make_empty)(BlockDriverState *bs);
> > /* aio */
> > @@ -217,7 +219,10 @@ struct BlockDriver {
> >
> > /* List of options for creating images, terminated by name == NULL */
> > QEMUOptionParameter *create_options;
> > -
> > + /* FIXME: will replace create_options.
> > + * These two fields are mutually exclusive. At most one is non-NULL.
> > + */
> > + QemuOptsList *create_opts;
>
> Do you also want to mention that create_options may only be set with
> bdrv_create, and that create_opts may only be set with bdrv_create2? [1]
Will add description.
>
>
> > @@ -1340,40 +1340,36 @@ static int img_convert(int argc, char **argv)
>
> >
> > - if (options) {
> > - param = parse_option_parameters(options, create_options, param);
> > - if (param == NULL) {
> > - error_report("Invalid options for file format '%s'.",
> out_fmt);
> > - ret = -1;
> > - goto out;
> > - }
> > - } else {
> > - param = parse_option_parameters("", create_options, param);
> > + opts = qemu_opts_create(create_opts, NULL, 0, &error_abort);
> > + if (options && qemu_opts_do_parse(opts, options, NULL)) {
> > + error_report("Invalid options for file format '%s'.", out_fmt);
>
> Pre-existing, but another instance of trailing '.' in the error message.
>
> Back to [1], rather than asserting in individual functions at use time,
> why not do all the sanity checking up front in bdrv_register()? That
> is, I think it is easier to add:
>
> if (bdrv->bdrv_create) {
> assert(!bdrv->bdrv_create2);
> assert(!bdrv->opts && !bdrv->bdrv_amend_options2);
> } else if (bdrv_{
> assert(!bdrv->options && !bdrv->bdrv_amend_options);
> }
>
> at the point where drivers are registered, rather than having to
> duplicate checks across all points that might use a driver.
That makes sense. But [1] still needs the asserting individually, since
it doesn't use bdrv->create_opts or bdrv->create_options, but the opts or
options passed in.
>
> --
> Eric Blake eblake redhat com +1-919-301-3266
> Libvirt virtualization library http://libvirt.org
>
>
- [Qemu-devel] [PATCH v25 07/31] QemuOpts: add qemu_opts_print_help to replace print_option_help, (continued)
- [Qemu-devel] [PATCH v25 07/31] QemuOpts: add qemu_opts_print_help to replace print_option_help, Chunyan Liu, 2014/04/11
- [Qemu-devel] [PATCH v25 09/31] QemuOpts: add qemu_opts_append to replace append_option_parameters, Chunyan Liu, 2014/04/11
- [Qemu-devel] [PATCH v25 08/31] QemuOpts: add conversion between QEMUOptionParameter to QemuOpts, Chunyan Liu, 2014/04/11
- [Qemu-devel] [PATCH v25 11/31] change block layer to support both QemuOpts and QEMUOptionParamter, Chunyan Liu, 2014/04/11
- Re: [Qemu-devel] [PATCH v25 11/31] change block layer to support both QemuOpts and QEMUOptionParamter, Stefan Hajnoczi, 2014/04/25
- [Qemu-devel] [PATCH v25 10/31] QemuOpts: check NULL input for qemu_opts_del, Chunyan Liu, 2014/04/11
- [Qemu-devel] [PATCH v25 13/31] cow.c: replace QEMUOptionParameter with QemuOpts, Chunyan Liu, 2014/04/11
- [Qemu-devel] [PATCH v25 12/31] vvfat.c: handle cross_driver's create_options and create_opts, Chunyan Liu, 2014/04/11
- [Qemu-devel] [PATCH v25 14/31] gluster.c: replace QEMUOptionParameter with QemuOpts, Chunyan Liu, 2014/04/11
- [Qemu-devel] [PATCH v25 15/31] iscsi.c: replace QEMUOptionParameter with QemuOpts, Chunyan Liu, 2014/04/11