John,

On Fri, Sep 14, 2018 at 5:04 PM, John Ferlan <jfer...@redhat.com> wrote:

>
>
> On 09/11/2018 08:59 AM, Fabiano Fidêncio wrote:
> > There are still a few places using virConfGetValue(), checking for the
> > specific type of the pointers and so on. However, those places are not
> > going to be converted as:
> > - Using virConfGetValue*() would trigger virReportError() in the current
> > code, which would cause, at least, some misleading messages for whoever
> > has to debug this code path;
> > - Expanding virConfValue*() to support strings as other types (for
> > instance, as boolean or long) does not seem to be neither the safest nor
> > the preferential path to take.
> >
> > Signed-off-by: Fabiano Fidêncio <fiden...@redhat.com>
> > ---
> >  src/xenconfig/xen_common.c | 163 +++++++++++++++++--------------------
> >  1 file changed, 75 insertions(+), 88 deletions(-)
> >
>
> /me thinks much of the above probably should have gone under the ---
> indicating your knowledge of more places, but the decision to not change
> them for the stated reasons. That commit message doesn't necessarily
> describe the subsequent changes...
>
> Perhaps a generic commit messages such as:
>
> Change to using virConfGetValueString rather than open coding for
> instances in which error messages are expected to be generated.
>

Okay!


>
> > diff --git a/src/xenconfig/xen_common.c b/src/xenconfig/xen_common.c
> > index fdca9845aa..c31ebfb270 100644
> > --- a/src/xenconfig/xen_common.c
> > +++ b/src/xenconfig/xen_common.c
> > @@ -145,31 +145,19 @@ xenConfigCopyStringInternal(virConfPtr conf,
> >                              char **value,
> >                              int allowMissing)
> >  {
> > -    virConfValuePtr val;
> > +    int rc;
> >
> >      *value = NULL;
> > -    if (!(val = virConfGetValue(conf, name))) {
> > -        if (allowMissing)
> > -            return 0;
> > -        virReportError(VIR_ERR_INTERNAL_ERROR,
> > -                       _("config value %s was missing"), name);
> > -        return -1;
> > -    }
> > +    rc = virConfGetValueString(conf, name, value);
>
> I believe this should be:
>
>     if ((rc = virConfGetValueString(conf, name, value)) < 0)
>         return -1;
>
> otherwise, we could get to the allowMissing w/ rc == -1 and return 0
> even though previously for a VIR_STRDUP failure we'd return -1. We'd
> also overwrite the no memory error from VIR_STRDUP failure.
>

Fixed locally, thanks!


>
>
> > +    if (rc == 1 && *value)
> > +        return 0;
> >
> > -    if (val->type != VIR_CONF_STRING) {
> > -        virReportError(VIR_ERR_INTERNAL_ERROR,
> > -                       _("config value %s was not a string"), name);
> > -        return -1;
> > -    }
> > -    if (!val->str) {
> > -        if (allowMissing)
> > -            return 0;
> > -        virReportError(VIR_ERR_INTERNAL_ERROR,
> > -                       _("config value %s was missing"), name);
> > -        return -1;
> > -    }
> > +    if (allowMissing)
> > +        return 0;
> >
> > -    return VIR_STRDUP(*value, val->str);
> > +    virReportError(VIR_ERR_INTERNAL_ERROR,
> > +                   _("config value %s was missing"), name);
> > +    return -1;
> >  }
> >
> >
> > @@ -193,7 +181,7 @@ xenConfigCopyStringOpt(virConfPtr conf, const char
> *name, char **value)
> >  static int
> >  xenConfigGetUUID(virConfPtr conf, const char *name, unsigned char *uuid)
> >  {
> > -    virConfValuePtr val;
> > +    char *string = NULL;
> >
> >      if (!uuid || !name || !conf) {
> >          virReportError(VIR_ERR_INVALID_ARG, "%s",
> > @@ -201,7 +189,7 @@ xenConfigGetUUID(virConfPtr conf, const char *name,
> unsigned char *uuid)
> >          return -1;
> >      }
> >
> > -    if (!(val = virConfGetValue(conf, name))) {
> > +    if (virConfGetValueString(conf, name, &string) < 0) {
>
> This is not the same check - < 0 is returned on errors (!STRING and
> VIR_STRDUP failure).
>
> I think you should use:
>
>     rc = virConfGetValueString(conf, name, &string);
>
> and then continue from there with the rc and/or string checks.
>

Fixed locally, thanks!


>
> >          if (virUUIDGenerate(uuid) < 0) {
> >              virReportError(VIR_ERR_INTERNAL_ERROR,
> >                             "%s", _("Failed to generate UUID"));
> > @@ -211,24 +199,20 @@ xenConfigGetUUID(virConfPtr conf, const char
> *name, unsigned char *uuid)
> >          }
> >      }
> >
> > -    if (val->type != VIR_CONF_STRING) {
> > -        virReportError(VIR_ERR_CONF_SYNTAX,
> > -                       _("config value %s not a string"), name);
> > -        return -1;
> > -    }
> > -
> > -    if (!val->str) {
> > +    if (!string) {
>
> I think this would be if virConfGetValueString returns 1, but !string
> because VIR_STRDUP(*value, NULL) would return NULL in *value.
>

Fixed locally, thanks!

>
>
> >          virReportError(VIR_ERR_CONF_SYNTAX,
> >                         _("%s can't be empty"), name);
> >          return -1;
> >      }
> >
> > -    if (virUUIDParse(val->str, uuid) < 0) {
> > +    if (virUUIDParse(string, uuid) < 0) {
> >          virReportError(VIR_ERR_CONF_SYNTAX,
> > -                       _("%s not parseable"), val->str);
> > +                       _("%s not parseable"), string);
> > +        VIR_FREE(string);
> >          return -1;
> >      }
> >
> > +    VIR_FREE(string);
> >      return 0;
> >  }
> >
> > @@ -242,23 +226,16 @@ xenConfigGetString(virConfPtr conf,
> >                     const char **value,
> >                     const char *def)
> >  {
> > -    virConfValuePtr val;
> > +    char *string = NULL;
> >
> > -    *value = NULL;
> > -    if (!(val = virConfGetValue(conf, name))) {
> > +    if (virConfGetValueString(conf, name, &string) < 0) {
>
> more of the same here as from previous < 0 is error, while ret == 0
> would be this case
>

Fixed locally, thanks!


>
> >          *value = def;
> > -        return 0;
> > -    }
> > -
> > -    if (val->type != VIR_CONF_STRING) {
> > -        virReportError(VIR_ERR_INTERNAL_ERROR,
> > -                       _("config value %s was malformed"), name);
> >          return -1;
> >      }
> > -    if (!val->str)
> > +    if (!string)
>
> and if rc == 1 and !string
>
> >          *value = def;
> >      else
> > -        *value = val->str;
> > +        *value = string;
>
> And the problem here is that @string would be leaked since it's a
> VIR_STRDUP of val->str, the @*def is a const char of something.
>
>
Here we can just memcpy() the string content and VIR_FREE() the string.
Would you agree with this approach or do you have something else in mind?



> >      return 0;
> >  }
> >
> > @@ -469,27 +446,30 @@ xenParsePCI(char *entry)
> >  static int
> >  xenParsePCIList(virConfPtr conf, virDomainDefPtr def)
> >  {
> > -    virConfValuePtr list = virConfGetValue(conf, "pci");
> > +    char **pcis = NULL, **entries;
> > +    int ret = -1;
> >
> > -    if (!list || list->type != VIR_CONF_LIST)
> > +    if (virConfGetValueStringList(conf, "pci", false, &pcis) <= 0)
>
> Again, not the same checks... Not sure this particular one can be used.
> The < 0 is an error path...
>

I understand your point that we're not doing the same check, but I do
believe that the "<= 0" check here is okay if we want to keep the same
behaviour.

The main issue I see here is that if the list->type is from the wrong type,
virConfGetValueStringList() would end up returning -1 (considering it goes
to the default branch, for instance) and the old code would return 0 for
that case.

So, < 0 is an error path, but I'm not sure how we can differentiate between
the errors we want to return 0 and the ones we want to return -1.


>
> I'm imagining many of the rest are similar.  Probably should have split
> things up into single patches for each method (as painful as it is) so
> that it's easier to review and easier to pick and choose what doesn't
> work and what does.
>
> BTW: I would do all the virConfGetValueString's first... Then tackle the
> virConfGetValueStringList's - since it doesn't cause one to context
> switch "too much" between two different API's.
>


Sure, I'll submit a new version soon (after having your feedback in the
question above).


>
> John
>
> >          return 0;
> >
> > -    for (list = list->list; list; list = list->next) {
> > +    for (entries = pcis; *entries; entries++) {
> > +        char *entry = *entries;
> >          virDomainHostdevDefPtr hostdev;
> >
> > -        if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
> > -            continue;
> > -
> > -        if (!(hostdev = xenParsePCI(list->str)))
> > -            return -1;
> > +        if (!(hostdev = xenParsePCI(entry)))
> > +            goto cleanup;
> >
> >          if (VIR_APPEND_ELEMENT(def->hostdevs, def->nhostdevs, hostdev)
> < 0) {
> >              virDomainHostdevDefFree(hostdev);
> > -            return -1;
> > +            goto cleanup;
> >          }
> >      }
> >
> > -    return 0;
> > +    ret = 0;
> > +
> > + cleanup:
> > +    virStringListFree(pcis);
> > +    return ret;
> >  }
> >
> >
> > @@ -603,10 +583,11 @@ xenParseCPUFeatures(virConfPtr conf,
> >  static int
> >  xenParseVfb(virConfPtr conf, virDomainDefPtr def)
> >  {
> > +    int ret = -1;
> >      int val;
> > +    char **vfbs = NULL;
> >      char *listenAddr = NULL;
> >      int hvm = def->os.type == VIR_DOMAIN_OSTYPE_HVM;
> > -    virConfValuePtr list;
> >      virDomainGraphicsDefPtr graphics = NULL;
> >
> >      if (hvm) {
> > @@ -662,17 +643,24 @@ xenParseVfb(virConfPtr conf, virDomainDefPtr def)
> >      }
> >
> >      if (!hvm && def->graphics == NULL) { /* New PV guests use this
> format */
> > -        list = virConfGetValue(conf, "vfb");
> > -        if (list && list->type == VIR_CONF_LIST &&
> > -            list->list && list->list->type == VIR_CONF_STRING &&
> > -            list->list->str) {
> > +        char **entries;
> > +        int rc;
> > +
> > +        rc = virConfGetValueStringList(conf, "vfb", false, &vfbs);
> > +        if (rc <= 0) {
> > +            ret = 0;
> > +            goto cleanup;
> > +        }
> > +
> > +        for (entries = vfbs; *entries; entries++) {
> >              char vfb[MAX_VFB];
> >              char *key = vfb;
> > +            char *entry = *entries;
> >
> > -            if (virStrcpyStatic(vfb, list->list->str) < 0) {
> > +            if (virStrcpyStatic(vfb, entry) < 0) {
> >                  virReportError(VIR_ERR_INTERNAL_ERROR,
> >                                 _("VFB %s too big for destination"),
> > -                               list->list->str);
> > +                               entry);
> >                  goto cleanup;
> >              }
> >
> > @@ -745,21 +733,23 @@ xenParseVfb(virConfPtr conf, virDomainDefPtr def)
> >          }
> >      }
> >
> > -    return 0;
> > +    ret = 0;
> >
> >   cleanup:
> >      virDomainGraphicsDefFree(graphics);
> >      VIR_FREE(listenAddr);
> > -    return -1;
> > +    virStringListFree(vfbs);
> > +    return ret;
> >  }
> >
> >
> >  static int
> >  xenParseCharDev(virConfPtr conf, virDomainDefPtr def, const char
> *nativeFormat)
> >  {
> > +    char **serials = NULL;
> >      const char *str;
> > -    virConfValuePtr value = NULL;
> >      virDomainChrDefPtr chr = NULL;
> > +    int ret = -1;
> >
> >      if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) {
> >          if (xenConfigGetString(conf, "parallel", &str, NULL) < 0)
> > @@ -779,8 +769,8 @@ xenParseCharDev(virConfPtr conf, virDomainDefPtr
> def, const char *nativeFormat)
> >          }
> >
> >          /* Try to get the list of values to support multiple serial
> ports */
> > -        value = virConfGetValue(conf, "serial");
> > -        if (value && value->type == VIR_CONF_LIST) {
> > +        if (virConfGetValueStringList(conf, "serial", false, &serials)
> == 1) {
> > +            char **entries;
> >              int portnum = -1;
> >
> >              if (STREQ(nativeFormat, XEN_CONFIG_FORMAT_XM)) {
> > @@ -789,18 +779,12 @@ xenParseCharDev(virConfPtr conf, virDomainDefPtr
> def, const char *nativeFormat)
> >                  goto cleanup;
> >              }
> >
> > -            value = value->list;
> > -            while (value) {
> > -                char *port = NULL;
> > +            for (entries = serials; *entries; entries++) {
> > +                char *port = *entries;
> >
> > -                if ((value->type != VIR_CONF_STRING) || (value->str ==
> NULL))
> > -                    goto cleanup;
> > -                port = value->str;
> >                  portnum++;
> > -                if (STREQ(port, "none")) {
> > -                    value = value->next;
> > +                if (STREQ(port, "none"))
> >                      continue;
> > -                }
> >
> >                  if (!(chr = xenParseSxprChar(port, NULL)))
> >                      goto cleanup;
> > @@ -808,8 +792,6 @@ xenParseCharDev(virConfPtr conf, virDomainDefPtr
> def, const char *nativeFormat)
> >                  chr->target.port = portnum;
> >                  if (VIR_APPEND_ELEMENT(def->serials, def->nserials,
> chr) < 0)
> >                      goto cleanup;
> > -
> > -                value = value->next;
> >              }
> >          } else {
> >              /* If domain is not using multiple serial ports we parse
> data old way */
> > @@ -825,6 +807,7 @@ xenParseCharDev(virConfPtr conf, virDomainDefPtr
> def, const char *nativeFormat)
> >                  chr->target.port = 0;
> >                  def->serials[0] = chr;
> >                  def->nserials++;
> > +                chr = NULL;
> >              }
> >          }
> >      } else {
> > @@ -838,11 +821,12 @@ xenParseCharDev(virConfPtr conf, virDomainDefPtr
> def, const char *nativeFormat)
> >          def->consoles[0]->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_
> TYPE_XEN;
> >      }
> >
> > -    return 0;
> > +    ret = 0;
> >
> >   cleanup:
> >      virDomainChrDefFree(chr);
> > -    return -1;
> > +    virStringListFree(serials);
> > +    return ret;
> >  }
> >
> >
> > @@ -1031,29 +1015,32 @@ xenParseVif(char *entry, const char
> *vif_typename)
> >  static int
> >  xenParseVifList(virConfPtr conf, virDomainDefPtr def, const char
> *vif_typename)
> >  {
> > -    virConfValuePtr list = virConfGetValue(conf, "vif");
> > +    char **vifs = NULL, **entries;
> > +    int ret = -1;
> >
> > -    if (!list || list->type != VIR_CONF_LIST)
> > +    if (virConfGetValueStringList(conf, "vif", false, &vifs) <= 0)
> >          return 0;
> >
> > -    for (list = list->list; list; list = list->next) {
> > +    for (entries = vifs; *entries; entries++) {
> >          virDomainNetDefPtr net = NULL;
> > +        char *entry = *entries;
> >          int rc;
> >
> > -        if ((list->type != VIR_CONF_STRING) || (list->str == NULL))
> > -            continue;
> > -
> > -        if (!(net = xenParseVif(list->str, vif_typename)))
> > -            return -1;
> > +        if (!(net = xenParseVif(entry, vif_typename)))
> > +            goto cleanup;
> >
> >          rc = VIR_APPEND_ELEMENT(def->nets, def->nnets, net);
> >          if (rc < 0) {
> >              virDomainNetDefFree(net);
> > -            return -1;
> > +            goto cleanup;
> >          }
> >      }
> >
> > -    return 0;
> > +    ret = 0;
> > +
> > + cleanup:
> > +    virStringListFree(vifs);
> > +    return ret;
> >  }
> >
> >
> >
>
--
libvir-list mailing list
libvir-list@redhat.com
https://www.redhat.com/mailman/listinfo/libvir-list

Reply via email to