<div dir="ltr">John,<br><div><div class="gmail_extra"><br><div class="gmail_quote">On Fri, Sep 14, 2018 at 5:04 PM, John Ferlan <span dir="ltr"><<a href="mailto:jferlan@redhat.com" target="_blank">jferlan@redhat.com</a>></span> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span><br>
<br>
On 09/11/2018 08:59 AM, Fabiano Fidêncio wrote:<br>
> There are still a few places using virConfGetValue(), checking for the<br>
> specific type of the pointers and so on. However, those places are not<br>
> going to be converted as:<br>
> - Using virConfGetValue*() would trigger virReportError() in the current<br>
> code, which would cause, at least, some misleading messages for whoever<br>
> has to debug this code path;<br>
> - Expanding virConfValue*() to support strings as other types (for<br>
> instance, as boolean or long) does not seem to be neither the safest nor<br>
> the preferential path to take.<br>
> <br>
> Signed-off-by: Fabiano Fidêncio <<a href="mailto:fidencio@redhat.com" target="_blank">fidencio@redhat.com</a>><br>
> ---<br>
>  src/xenconfig/xen_common.c | 163 +++++++++++++++++-------------<wbr>-------<br>
>  1 file changed, 75 insertions(+), 88 deletions(-)<br>
> <br>
<br>
</span>/me thinks much of the above probably should have gone under the ---<br>
indicating your knowledge of more places, but the decision to not change<br>
them for the stated reasons. That commit message doesn't necessarily<br>
describe the subsequent changes...<br>
<br>
Perhaps a generic commit messages such as:<br>
<br>
Change to using virConfGetValueString rather than open coding for<br>
instances in which error messages are expected to be generated.<br></blockquote><div><br></div><div>Okay!<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span><br>
> diff --git a/src/xenconfig/xen_common.c b/src/xenconfig/xen_common.c<br>
> index fdca9845aa..c31ebfb270 100644<br>
> --- a/src/xenconfig/xen_common.c<br>
> +++ b/src/xenconfig/xen_common.c<br>
> @@ -145,31 +145,19 @@ xenConfigCopyStringInternal(vi<wbr>rConfPtr conf,<br>
>                              char **value,<br>
>                              int allowMissing)<br>
>  {<br>
> -    virConfValuePtr val;<br>
> +    int rc;<br>
>  <br>
>      *value = NULL;<br>
> -    if (!(val = virConfGetValue(conf, name))) {<br>
> -        if (allowMissing)<br>
> -            return 0;<br>
> -        virReportError(VIR_ERR_INTERNA<wbr>L_ERROR,<br>
> -                       _("config value %s was missing"), name);<br>
> -        return -1;<br>
> -    }<br>
> +    rc = virConfGetValueString(conf, name, value);<br>
<br>
</span>I believe this should be:<br>
<br>
    if ((rc = virConfGetValueString(conf, name, value)) < 0)<br>
        return -1;<br>
<br>
otherwise, we could get to the allowMissing w/ rc == -1 and return 0<br>
even though previously for a VIR_STRDUP failure we'd return -1. We'd<br>
also overwrite the no memory error from VIR_STRDUP failure.<br></blockquote><div><br></div><div>Fixed locally, thanks!<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<div><div class="m_-2737757638475093403h5"><br>
<br>
> +    if (rc == 1 && *value)<br>
> +        return 0;<br>
>  <br>
> -    if (val->type != VIR_CONF_STRING) {<br>
> -        virReportError(VIR_ERR_INTERNA<wbr>L_ERROR,<br>
> -                       _("config value %s was not a string"), name);<br>
> -        return -1;<br>
> -    }<br>
> -    if (!val->str) {<br>
> -        if (allowMissing)<br>
> -            return 0;<br>
> -        virReportError(VIR_ERR_INTERNA<wbr>L_ERROR,<br>
> -                       _("config value %s was missing"), name);<br>
> -        return -1;<br>
> -    }<br>
> +    if (allowMissing)<br>
> +        return 0;<br>
>  <br>
> -    return VIR_STRDUP(*value, val->str);<br>
> +    virReportError(VIR_ERR_INTERNA<wbr>L_ERROR,<br>
> +                   _("config value %s was missing"), name);<br>
> +    return -1;<br>
>  }<br>
>  <br>
>  <br>
> @@ -193,7 +181,7 @@ xenConfigCopyStringOpt(virConf<wbr>Ptr conf, const char *name, char **value)<br>
>  static int<br>
>  xenConfigGetUUID(virConfPtr conf, const char *name, unsigned char *uuid)<br>
>  {<br>
> -    virConfValuePtr val;<br>
> +    char *string = NULL;<br>
>  <br>
>      if (!uuid || !name || !conf) {<br>
>          virReportError(VIR_ERR_INVALID<wbr>_ARG, "%s",<br>
> @@ -201,7 +189,7 @@ xenConfigGetUUID(virConfPtr conf, const char *name, unsigned char *uuid)<br>
>          return -1;<br>
>      }<br>
>  <br>
> -    if (!(val = virConfGetValue(conf, name))) {<br>
> +    if (virConfGetValueString(conf, name, &string) < 0) {<br>
<br>
</div></div>This is not the same check - < 0 is returned on errors (!STRING and<br>
VIR_STRDUP failure).<br>
<br>
I think you should use:<br>
<br>
    rc = virConfGetValueString(conf, name, &string);<br>
<br>
and then continue from there with the rc and/or string checks.<br></blockquote><div><br></div><div>Fixed locally, thanks!<br></div><div> <br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span><br>
>          if (virUUIDGenerate(uuid) < 0) {<br>
>              virReportError(VIR_ERR_INTERNA<wbr>L_ERROR,<br>
>                             "%s", _("Failed to generate UUID"));<br>
> @@ -211,24 +199,20 @@ xenConfigGetUUID(virConfPtr conf, const char *name, unsigned char *uuid)<br>
>          }<br>
>      }<br>
>  <br>
> -    if (val->type != VIR_CONF_STRING) {<br>
> -        virReportError(VIR_ERR_CONF_SY<wbr>NTAX,<br>
> -                       _("config value %s not a string"), name);<br>
> -        return -1;<br>
> -    }<br>
> -<br>
> -    if (!val->str) {<br>
> +    if (!string) {<br>
<br>
</span>I think this would be if virConfGetValueString returns 1, but !string<br>
because VIR_STRDUP(*value, NULL) would return NULL in *value.<br></blockquote><div><br></div><div>Fixed locally, thanks!</div> <blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span><br>
>          virReportError(VIR_ERR_CONF_SY<wbr>NTAX,<br>
>                         _("%s can't be empty"), name);<br>
>          return -1;<br>
>      }<br>
>  <br>
> -    if (virUUIDParse(val->str, uuid) < 0) {<br>
> +    if (virUUIDParse(string, uuid) < 0) {<br>
>          virReportError(VIR_ERR_CONF_SY<wbr>NTAX,<br>
> -                       _("%s not parseable"), val->str);<br>
> +                       _("%s not parseable"), string);<br>
> +        VIR_FREE(string);<br>
>          return -1;<br>
>      }<br>
>  <br>
> +    VIR_FREE(string);<br>
>      return 0;<br>
>  }<br>
>  <br>
> @@ -242,23 +226,16 @@ xenConfigGetString(virConfPtr conf,<br>
>                     const char **value,<br>
>                     const char *def)<br>
>  {<br>
> -    virConfValuePtr val;<br>
> +    char *string = NULL;<br>
>  <br>
> -    *value = NULL;<br>
> -    if (!(val = virConfGetValue(conf, name))) {<br>
> +    if (virConfGetValueString(conf, name, &string) < 0) {<br>
<br>
</span>more of the same here as from previous < 0 is error, while ret == 0<br>
would be this case<br></blockquote><div><br></div><div>Fixed locally, thanks!<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span><br>
>          *value = def;<br>
> -        return 0;<br>
> -    }<br>
> -<br>
> -    if (val->type != VIR_CONF_STRING) {<br>
> -        virReportError(VIR_ERR_INTERNA<wbr>L_ERROR,<br>
> -                       _("config value %s was malformed"), name);<br>
>          return -1;<br>
>      }<br>
> -    if (!val->str)<br>
> +    if (!string)<br>
<br>
</span>and if rc == 1 and !string<br>
<span><br>
>          *value = def;<br>
>      else<br>
> -        *value = val->str;<br>
> +        *value = string;<br>
<br>
</span>And the problem here is that @string would be leaked since it's a<br>
VIR_STRDUP of val->str, the @*def is a const char of something.<br>
<span><br></span></blockquote><div><br></div><div><div>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?<br></div><div></div><br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><span>
>      return 0;<br>
>  }<br>
>  <br>
> @@ -469,27 +446,30 @@ xenParsePCI(char *entry)<br>
>  static int<br>
>  xenParsePCIList(virConfPtr conf, virDomainDefPtr def)<br>
>  {<br>
> -    virConfValuePtr list = virConfGetValue(conf, "pci");<br>
> +    char **pcis = NULL, **entries;<br>
> +    int ret = -1;<br>
>  <br>
> -    if (!list || list->type != VIR_CONF_LIST)<br>
> +    if (virConfGetValueStringList(con<wbr>f, "pci", false, &pcis) <= 0)<br>
<br>
</span>Again, not the same checks... Not sure this particular one can be used.<br>
The < 0 is an error path...<br></blockquote><div><br></div><div>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.</div><div><br></div><div>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.</div><div><br></div><div>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.<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
I'm imagining many of the rest are similar.  Probably should have split<br>
things up into single patches for each method (as painful as it is) so<br>
that it's easier to review and easier to pick and choose what doesn't<br>
work and what does.<br>
<br>
BTW: I would do all the virConfGetValueString's first... Then tackle the<br>
virConfGetValueStringList's - since it doesn't cause one to context<br>
switch "too much" between two different API's.<br></blockquote><div><br></div><div><br></div><div>Sure, I'll submit a new version soon (after having your feedback in the question above).<br></div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<span class="m_-2737757638475093403HOEnZb"><font color="#888888"><br>
John<br>
</font></span><div class="m_-2737757638475093403HOEnZb"><div class="m_-2737757638475093403h5"><br>
>          return 0;<br>
>  <br>
> -    for (list = list->list; list; list = list->next) {<br>
> +    for (entries = pcis; *entries; entries++) {<br>
> +        char *entry = *entries;<br>
>          virDomainHostdevDefPtr hostdev;<br>
>  <br>
> -        if ((list->type != VIR_CONF_STRING) || (list->str == NULL))<br>
> -            continue;<br>
> -<br>
> -        if (!(hostdev = xenParsePCI(list->str)))<br>
> -            return -1;<br>
> +        if (!(hostdev = xenParsePCI(entry)))<br>
> +            goto cleanup;<br>
>  <br>
>          if (VIR_APPEND_ELEMENT(def->hostd<wbr>evs, def->nhostdevs, hostdev) < 0) {<br>
>              virDomainHostdevDefFree(hostde<wbr>v);<br>
> -            return -1;<br>
> +            goto cleanup;<br>
>          }<br>
>      }<br>
>  <br>
> -    return 0;<br>
> +    ret = 0;<br>
> +<br>
> + cleanup:<br>
> +    virStringListFree(pcis);<br>
> +    return ret;<br>
>  }<br>
>  <br>
>  <br>
> @@ -603,10 +583,11 @@ xenParseCPUFeatures(virConfPtr conf,<br>
>  static int<br>
>  xenParseVfb(virConfPtr conf, virDomainDefPtr def)<br>
>  {<br>
> +    int ret = -1;<br>
>      int val;<br>
> +    char **vfbs = NULL;<br>
>      char *listenAddr = NULL;<br>
>      int hvm = def->os.type == VIR_DOMAIN_OSTYPE_HVM;<br>
> -    virConfValuePtr list;<br>
>      virDomainGraphicsDefPtr graphics = NULL;<br>
>  <br>
>      if (hvm) {<br>
> @@ -662,17 +643,24 @@ xenParseVfb(virConfPtr conf, virDomainDefPtr def)<br>
>      }<br>
>  <br>
>      if (!hvm && def->graphics == NULL) { /* New PV guests use this format */<br>
> -        list = virConfGetValue(conf, "vfb");<br>
> -        if (list && list->type == VIR_CONF_LIST &&<br>
> -            list->list && list->list->type == VIR_CONF_STRING &&<br>
> -            list->list->str) {<br>
> +        char **entries;<br>
> +        int rc;<br>
> +<br>
> +        rc = virConfGetValueStringList(conf<wbr>, "vfb", false, &vfbs);<br>
> +        if (rc <= 0) {<br>
> +            ret = 0;<br>
> +            goto cleanup;<br>
> +        }<br>
> +<br>
> +        for (entries = vfbs; *entries; entries++) {<br>
>              char vfb[MAX_VFB];<br>
>              char *key = vfb;<br>
> +            char *entry = *entries;<br>
>  <br>
> -            if (virStrcpyStatic(vfb, list->list->str) < 0) {<br>
> +            if (virStrcpyStatic(vfb, entry) < 0) {<br>
>                  virReportError(VIR_ERR_INTERNA<wbr>L_ERROR,<br>
>                                 _("VFB %s too big for destination"),<br>
> -                               list->list->str);<br>
> +                               entry);<br>
>                  goto cleanup;<br>
>              }<br>
>  <br>
> @@ -745,21 +733,23 @@ xenParseVfb(virConfPtr conf, virDomainDefPtr def)<br>
>          }<br>
>      }<br>
>  <br>
> -    return 0;<br>
> +    ret = 0;<br>
>  <br>
>   cleanup:<br>
>      virDomainGraphicsDefFree(graph<wbr>ics);<br>
>      VIR_FREE(listenAddr);<br>
> -    return -1;<br>
> +    virStringListFree(vfbs);<br>
> +    return ret;<br>
>  }<br>
>  <br>
>  <br>
>  static int<br>
>  xenParseCharDev(virConfPtr conf, virDomainDefPtr def, const char *nativeFormat)<br>
>  {<br>
> +    char **serials = NULL;<br>
>      const char *str;<br>
> -    virConfValuePtr value = NULL;<br>
>      virDomainChrDefPtr chr = NULL;<br>
> +    int ret = -1;<br>
>  <br>
>      if (def->os.type == VIR_DOMAIN_OSTYPE_HVM) {<br>
>          if (xenConfigGetString(conf, "parallel", &str, NULL) < 0)<br>
> @@ -779,8 +769,8 @@ xenParseCharDev(virConfPtr conf, virDomainDefPtr def, const char *nativeFormat)<br>
>          }<br>
>  <br>
>          /* Try to get the list of values to support multiple serial ports */<br>
> -        value = virConfGetValue(conf, "serial");<br>
> -        if (value && value->type == VIR_CONF_LIST) {<br>
> +        if (virConfGetValueStringList(con<wbr>f, "serial", false, &serials) == 1) {<br>
> +            char **entries;<br>
>              int portnum = -1;<br>
>  <br>
>              if (STREQ(nativeFormat, XEN_CONFIG_FORMAT_XM)) {<br>
> @@ -789,18 +779,12 @@ xenParseCharDev(virConfPtr conf, virDomainDefPtr def, const char *nativeFormat)<br>
>                  goto cleanup;<br>
>              }<br>
>  <br>
> -            value = value->list;<br>
> -            while (value) {<br>
> -                char *port = NULL;<br>
> +            for (entries = serials; *entries; entries++) {<br>
> +                char *port = *entries;<br>
>  <br>
> -                if ((value->type != VIR_CONF_STRING) || (value->str == NULL))<br>
> -                    goto cleanup;<br>
> -                port = value->str;<br>
>                  portnum++;<br>
> -                if (STREQ(port, "none")) {<br>
> -                    value = value->next;<br>
> +                if (STREQ(port, "none"))<br>
>                      continue;<br>
> -                }<br>
>  <br>
>                  if (!(chr = xenParseSxprChar(port, NULL)))<br>
>                      goto cleanup;<br>
> @@ -808,8 +792,6 @@ xenParseCharDev(virConfPtr conf, virDomainDefPtr def, const char *nativeFormat)<br>
>                  chr->target.port = portnum;<br>
>                  if (VIR_APPEND_ELEMENT(def->seria<wbr>ls, def->nserials, chr) < 0)<br>
>                      goto cleanup;<br>
> -<br>
> -                value = value->next;<br>
>              }<br>
>          } else {<br>
>              /* If domain is not using multiple serial ports we parse data old way */<br>
> @@ -825,6 +807,7 @@ xenParseCharDev(virConfPtr conf, virDomainDefPtr def, const char *nativeFormat)<br>
>                  chr->target.port = 0;<br>
>                  def->serials[0] = chr;<br>
>                  def->nserials++;<br>
> +                chr = NULL;<br>
>              }<br>
>          }<br>
>      } else {<br>
> @@ -838,11 +821,12 @@ xenParseCharDev(virConfPtr conf, virDomainDefPtr def, const char *nativeFormat)<br>
>          def->consoles[0]->targetType = VIR_DOMAIN_CHR_CONSOLE_TARGET_<wbr>TYPE_XEN;<br>
>      }<br>
>  <br>
> -    return 0;<br>
> +    ret = 0;<br>
>  <br>
>   cleanup:<br>
>      virDomainChrDefFree(chr);<br>
> -    return -1;<br>
> +    virStringListFree(serials);<br>
> +    return ret;<br>
>  }<br>
>  <br>
>  <br>
> @@ -1031,29 +1015,32 @@ xenParseVif(char *entry, const char *vif_typename)<br>
>  static int<br>
>  xenParseVifList(virConfPtr conf, virDomainDefPtr def, const char *vif_typename)<br>
>  {<br>
> -    virConfValuePtr list = virConfGetValue(conf, "vif");<br>
> +    char **vifs = NULL, **entries;<br>
> +    int ret = -1;<br>
>  <br>
> -    if (!list || list->type != VIR_CONF_LIST)<br>
> +    if (virConfGetValueStringList(con<wbr>f, "vif", false, &vifs) <= 0)<br>
>          return 0;<br>
>  <br>
> -    for (list = list->list; list; list = list->next) {<br>
> +    for (entries = vifs; *entries; entries++) {<br>
>          virDomainNetDefPtr net = NULL;<br>
> +        char *entry = *entries;<br>
>          int rc;<br>
>  <br>
> -        if ((list->type != VIR_CONF_STRING) || (list->str == NULL))<br>
> -            continue;<br>
> -<br>
> -        if (!(net = xenParseVif(list->str, vif_typename)))<br>
> -            return -1;<br>
> +        if (!(net = xenParseVif(entry, vif_typename)))<br>
> +            goto cleanup;<br>
>  <br>
>          rc = VIR_APPEND_ELEMENT(def->nets, def->nnets, net);<br>
>          if (rc < 0) {<br>
>              virDomainNetDefFree(net);<br>
> -            return -1;<br>
> +            goto cleanup;<br>
>          }<br>
>      }<br>
>  <br>
> -    return 0;<br>
> +    ret = 0;<br>
> +<br>
> + cleanup:<br>
> +    virStringListFree(vifs);<br>
> +    return ret;<br>
>  }<br>
>  <br>
>  <br>
> <br>
</div></div></blockquote></div><br></div></div></div>