qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

Re: [Qemu-devel] [PATCH V13 4/6] create some QemuOpts functons


From: Markus Armbruster
Subject: Re: [Qemu-devel] [PATCH V13 4/6] create some QemuOpts functons
Date: Tue, 07 May 2013 09:38:15 +0200
User-agent: Gnus/5.13 (Gnus v5.13) Emacs/24.1 (gnu/linux)

Dong Xu Wang <address@hidden> writes:

> On 2013/5/6 20:20, Markus Armbruster wrote:
>> Dong Xu Wang <address@hidden> writes:
>>
>>> These functions will be used in next commit. qemu_opt_get_(*)_del functions
>>> are used to make sure we have the same behaviors as before: after get an
>>> option value, options++.
>>
>> I don't understand the last sentence.
>>
>>> Signed-off-by: Dong Xu Wang <address@hidden>
>>> ---
>>>   include/qemu/option.h |  11 +++++-
>>>   util/qemu-option.c    | 103 
>>> ++++++++++++++++++++++++++++++++++++++++++++++----
>>>   2 files changed, 105 insertions(+), 9 deletions(-)
>>>
>>> diff --git a/include/qemu/option.h b/include/qemu/option.h
>>> index c7a5c14..d63e447 100644
>>> --- a/include/qemu/option.h
>>> +++ b/include/qemu/option.h
>>> @@ -108,6 +108,7 @@ struct QemuOptsList {
>>>   };
>>>
>>>   const char *qemu_opt_get(QemuOpts *opts, const char *name);
>>> +const char *qemu_opt_get_del(QemuOpts *opts, const char *name);
>>>   /**
>>>    * qemu_opt_has_help_opt:
>>>    * @opts: options to search for a help request
>>> @@ -121,13 +122,18 @@ const char *qemu_opt_get(QemuOpts *opts, const char 
>>> *name);
>>>    */
>>>   bool qemu_opt_has_help_opt(QemuOpts *opts);
>>>   bool qemu_opt_get_bool(QemuOpts *opts, const char *name, bool defval);
>>> +bool qemu_opt_get_bool_del(QemuOpts *opts, const char *name, bool defval);
>>>   uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t 
>>> defval);
>>>   uint64_t qemu_opt_get_size(QemuOpts *opts, const char *name, uint64_t 
>>> defval);
>>> +uint64_t qemu_opt_get_size_del(QemuOpts *opts, const char *name,
>>> +                               uint64_t defval);
>>>   int qemu_opt_set(QemuOpts *opts, const char *name, const char *value);
>>> +int qemu_opt_replace_set(QemuOpts *opts, const char *name, const char 
>>> *value);
>>>   void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
>>>                         Error **errp);
>>>   int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val);
>>>   int qemu_opt_set_number(QemuOpts *opts, const char *name, int64_t val);
>>> +int qemu_opt_replace_set_number(QemuOpts *opts, const char *name, int64_t 
>>> val);
>>>   typedef int (*qemu_opt_loopfunc)(const char *name, const char *value, 
>>> void *opaque);
>>>   int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
>>>                        int abort_on_failure);
>>> @@ -144,7 +150,10 @@ const char *qemu_opts_id(QemuOpts *opts);
>>>   void qemu_opts_del(QemuOpts *opts);
>>>   void qemu_opts_validate(QemuOpts *opts, const QemuOptDesc *desc, Error 
>>> **errp);
>>>   int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char 
>>> *firstname);
>>> -QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params, int 
>>> permit_abbrev);
>>> +int qemu_opts_do_parse_replace(QemuOpts *opts, const char *params,
>>> +                               const char *firstname);
>>> +QemuOpts *qemu_opts_parse(QemuOptsList *list, const char *params,
>>> +                          int permit_abbrev);
>>>   void qemu_opts_set_defaults(QemuOptsList *list, const char *params,
>>>                               int permit_abbrev);
>>>   QemuOpts *qemu_opts_from_qdict(QemuOptsList *list, const QDict *qdict,
>>> diff --git a/util/qemu-option.c b/util/qemu-option.c
>>> index 0488c27..5db6d76 100644
>>> --- a/util/qemu-option.c
>>> +++ b/util/qemu-option.c
>>> @@ -33,6 +33,8 @@
>>>   #include "qapi/qmp/qerror.h"
>>>   #include "qemu/option_int.h"
>>>
>>> +static void qemu_opt_del(QemuOpt *opt);
>>> +
>>>   /*
>>>    * Extracts the name of an option from the parameter string (p points at 
>>> the
>>>    * first byte of the option name)
>>> @@ -549,6 +551,16 @@ const char *qemu_opt_get(QemuOpts *opts, const char 
>>> *name)
>>     const char *qemu_opt_get(QemuOpts *opts, const char *name)
>>     {
>>         QemuOpt *opt = qemu_opt_find(opts, name);
>>         const QemuOptDesc *desc;
>>         desc = find_desc_by_name(opts->list->desc, name);
>>
>>         return opt ? opt->str :
>>>           (desc && desc->def_value_str ? desc->def_value_str : NULL);
>>>   }
>>>
>>> +const char *qemu_opt_get_del(QemuOpts *opts, const char *name)
>>> +{
>>> +    QemuOpt *opt = qemu_opt_find(opts, name);
>>> +    const char *str = opt ? g_strdup(opt->str) : NULL;
>>> +    if (opt) {
>>> +        qemu_opt_del(opt);
>>> +    }
>>> +    return str;
>>> +}
>>> +
>>
>> Unlike qemu_opt_del(), this one doesn't use def_value_str.  Why?  Isn't
>> that a trap for users of this function?
>>
>> Same question for the qemu_opt_get_FOO_del() that follow.

I'm still interested in answers :)

>>>   bool qemu_opt_has_help_opt(QemuOpts *opts)
>>>   {
>>>       QemuOpt *opt;
>>> @@ -577,6 +589,22 @@ bool qemu_opt_get_bool(QemuOpts *opts, const char 
>>> *name, bool defval)
>>>       return opt->value.boolean;
>>>   }
>>>
>>> +bool qemu_opt_get_bool_del(QemuOpts *opts, const char *name, bool defval)
>>> +{
>>> +    QemuOpt *opt = qemu_opt_find(opts, name);
>>> +    bool ret;
>>> +
>>> +    if (opt == NULL) {
>>> +        return defval;
>>> +    }
>>> +    ret = opt->value.boolean;
>>> +    assert(opt->desc && opt->desc->type == QEMU_OPT_BOOL);
>>> +    if (opt) {
>>> +        qemu_opt_del(opt);
>>> +    }
>>> +    return ret;
>>> +}
>>> +
>>>   uint64_t qemu_opt_get_number(QemuOpts *opts, const char *name, uint64_t 
>>> defval)
>>>   {
>>>       QemuOpt *opt = qemu_opt_find(opts, name);
>>> @@ -609,6 +637,23 @@ uint64_t qemu_opt_get_size(QemuOpts *opts, const char 
>>> *name, uint64_t defval)
>>>       return opt->value.uint;
>>>   }
>>>
>>> +uint64_t qemu_opt_get_size_del(QemuOpts *opts, const char *name,
>>> +                               uint64_t defval)
>>> +{
>>> +    QemuOpt *opt = qemu_opt_find(opts, name);
>>> +    uint64_t ret;
>>> +
>>> +    if (opt == NULL) {
>>> +        return defval;
>>> +    }
>>> +    ret = opt->value.uint;
>>> +    assert(opt->desc && opt->desc->type == QEMU_OPT_SIZE);
>>> +    if (opt) {
>>> +        qemu_opt_del(opt);
>>> +    }
>>> +    return ret;
>>> +}
>>> +
>>>   static void qemu_opt_parse(QemuOpt *opt, Error **errp)
>>>   {
>>>       if (opt->desc == NULL)
>>> @@ -646,7 +691,7 @@ static bool opts_accepts_any(const QemuOpts *opts)
>>>   }
>>>
>>>   static void opt_set(QemuOpts *opts, const char *name, const char *value,
>>> -                    bool prepend, Error **errp)
>>> +                    bool prepend, bool replace, Error **errp)
>>>   {
>>>       QemuOpt *opt;
>>>       const QemuOptDesc *desc;
>>> @@ -658,6 +703,11 @@ static void opt_set(QemuOpts *opts, const char *name, 
>>> const char *value,
>>>           return;
>>>       }
>>>
>>> +    opt = qemu_opt_find(opts, name);
>>> +    if (replace && opt) {
>>> +        qemu_opt_del(opt);
>>> +    }
>>> +
>>>       opt = g_malloc0(sizeof(*opt));
>>>       opt->name = g_strdup(name);
>>>       opt->opts = opts;
>>> @@ -667,7 +717,6 @@ static void opt_set(QemuOpts *opts, const char *name, 
>>> const char *value,
>>>           QTAILQ_INSERT_TAIL(&opts->head, opt, next);
>>>       }
>>>       opt->desc = desc;
>>> -    opt->str = g_strdup(value);
>>>       opt->str = g_strdup(value ?: desc->def_value_str);
>>>       qemu_opt_parse(opt, &local_err);
>>>       if (error_is_set(&local_err)) {
>>
>> Here you plug the leak you created in PATCH 1/6.
>>
>>> @@ -680,7 +729,29 @@ int qemu_opt_set(QemuOpts *opts, const char *name, 
>>> const char *value)
>>>   {
>>>       Error *local_err = NULL;
>>>
>>> -    opt_set(opts, name, value, false, &local_err);
>>> +    opt_set(opts, name, value, false, false, &local_err);
>>> +    if (error_is_set(&local_err)) {
>>> +        qerror_report_err(local_err);
>>> +        error_free(local_err);
>>> +        return -1;
>>> +    }
>>> +
>>> +    return 0;
>>> +}
>>> +
>>> +/*
>>> + * If name exists, the function will delete the opt first and then add a 
>>> new
>>> + * one.
>>> + */
>>> +int qemu_opt_replace_set(QemuOpts *opts, const char *name, const char 
>>> *value)
>>> +{
>>> +    Error *local_err = NULL;
>>> +    QemuOpt *opt = qemu_opt_find(opts, name);
>>> +
>>> +    if (opt) {
>>> +        qemu_opt_del(opt);
>>> +    }
>>
>> Why?  Won't opt_set() delete it already?
>>
> No, opt_set will not delete it, but add a new opt. In block layer,

Then I'm confused...

> while parsing options, if the parameter is parsed, it should be
> deleted and won't be used again, so I delete it manually.
>
>> Same question for the qemu_opt_replace_set_FOO() that follow.
>>
>>> +    opt_set(opts, name, value, false, true, &local_err);

... because here you pass true for parameter replace, which I (naively?)
expect to delete the option.  Can you unconfuse me?

>>>       if (error_is_set(&local_err)) {
>>>           qerror_report_err(local_err);
>>>           error_free(local_err);
>>> @@ -693,7 +764,7 @@ int qemu_opt_set(QemuOpts *opts, const char *name, 
>>> const char *value)
>>>   void qemu_opt_set_err(QemuOpts *opts, const char *name, const char *value,
>>>                         Error **errp)
>>>   {
>>> -    opt_set(opts, name, value, false, errp);
>>> +    opt_set(opts, name, value, false, false, errp);
>>>   }
>>>
>>>   int qemu_opt_set_bool(QemuOpts *opts, const char *name, bool val)
>>> @@ -740,6 +811,16 @@ int qemu_opt_set_number(QemuOpts *opts, const char 
>>> *name, int64_t val)
>>>       return 0;
>>>   }
>>>
>>> +int qemu_opt_replace_set_number(QemuOpts *opts, const char *name, int64_t 
>>> val)
>>> +{
>>> +    QemuOpt *opt = qemu_opt_find(opts, name);
>>> +
>>> +    if (opt) {
>>> +        qemu_opt_del(opt);
>>> +    }
>>> +    return qemu_opt_set_number(opts, name, val);
>>> +}
>>> +
>>>   int qemu_opt_foreach(QemuOpts *opts, qemu_opt_loopfunc func, void *opaque,
>>>                        int abort_on_failure)
>>>   {
>>> @@ -917,7 +998,7 @@ int qemu_opts_print(QemuOpts *opts)
>>>   }
>>>
>>>   static int opts_do_parse(QemuOpts *opts, const char *params,
>>> -                         const char *firstname, bool prepend)
>>> +                         const char *firstname, bool prepend, bool replace)
>>>   {
>>>       char option[128], value[1024];
>>>       const char *p,*pe,*pc;
>>> @@ -953,7 +1034,7 @@ static int opts_do_parse(QemuOpts *opts, const char 
>>> *params,
>>>           }
>>>           if (strcmp(option, "id") != 0) {
>>>               /* store and parse */
>>> -            opt_set(opts, option, value, prepend, &local_err);
>>> +            opt_set(opts, option, value, prepend, replace, &local_err);
>>>               if (error_is_set(&local_err)) {
>>>                   qerror_report_err(local_err);
>>>                   error_free(local_err);
>>> @@ -969,7 +1050,13 @@ static int opts_do_parse(QemuOpts *opts, const char 
>>> *params,
>>>
>>>   int qemu_opts_do_parse(QemuOpts *opts, const char *params, const char 
>>> *firstname)
>>>   {
>>> -    return opts_do_parse(opts, params, firstname, false);
>>> +    return opts_do_parse(opts, params, firstname, false, false);
>>> +}
>>> +
>>> +int qemu_opts_do_parse_replace(QemuOpts *opts, const char *params,
>>> +                               const char *firstname)
>>> +{
>>> +    return opts_do_parse(opts, params, firstname, false, true);
>>>   }
>>>
>>>   static QemuOpts *opts_parse(QemuOptsList *list, const char *params,
>>> @@ -1008,7 +1095,7 @@ static QemuOpts *opts_parse(QemuOptsList *list, const 
>>> char *params,
>>>           return NULL;
>>>       }
>>>
>>> -    if (opts_do_parse(opts, params, firstname, defaults) != 0) {
>>> +    if (opts_do_parse(opts, params, firstname, defaults, false) != 0) {
>>>           qemu_opts_del(opts);
>>>           return NULL;
>>>       }
>>
>>



reply via email to

[Prev in Thread] Current Thread [Next in Thread]