<html>
<head>
<style><!--
.hmmessage P
{
margin:0px;
padding:0px
}
body.hmmessage
{
font-size: 12pt;
font-family:΢ÈíÑźÚ
}
--></style></head>
<body class='hmmessage'><div dir='ltr'><br><br><div><div id="SkyDrivePlaceholder"></div>> Date: Thu, 25 Apr 2013 14:08:51 -0400<br>> From: jferlan@redhat.com<br>> To: libvirt-cim@redhat.com<br>> Subject: Re: [Libvirt-cim] [PATCH 3/3] make lldptool command and support   output configurable<br>> <br>> <br>> For some reason the original email never made it into my inbox, so I've<br>> had to cut-n-paste from the mail list archives and I hope I picked the<br>> right message-id for the messages to line up properly!!!<br>> <br>> <br>> <br>> > From: Xu Wang <cngesaint outlook com><br>> > <br>> <br>> There's no commit message?<br>> <br>> > Signed-off-by: Xu Wang <cngesaint outlook com><br>> > ---<br>> >  libvirt-cim.conf         |   14 ++++++++++<br>> >  libxkutil/misc_util.c    |   18 +++++++++++++<br>> >  libxkutil/misc_util.h    |    2 +<br>> >  src/Virt_SwitchService.c |   63 ++++++++++++++++++++++++++++++++++++++--------<br>> >  4 files changed, 86 insertions(+), 11 deletions(-)<br>> > <br>> > diff --git a/libvirt-cim.conf b/libvirt-cim.conf<br>> > index 3244ee3..396dac9 100644<br>> > --- a/libvirt-cim.conf<br>> > +++ b/libvirt-cim.conf<br>> > @@ -38,3 +38,17 @@<br>> >  #  Default value: false<br>> >  #<br>> >  # force_use_qemu = false;<br>> > +<br>> > +# lldptool_query_options (string)<br>> > +#  Defines the command used in SwitchService to query VEPA support, will be<br>> > +#  used as "lldptool -i [INTERFACE] [OPTIONS]"<br>> > +#<br>> > +# lldptool_query_options = "-t -g ncb -V evbcfg";<br>> > +<br>> > +# vsi_support_key_string (string)<br>> > +#  Defines the string used in SwitchService to search in lldptool's output<br>> > +#  When lldptool updates its output, please update the new output into the<br>> > +#  output set. add comma between items.<br>> > +#<br>> > +# vsi_support_key_string = "{   supported forwarding mode: (0x40) reflective relay,"<br>> > +#                          " supported capabilities: (0x7) RTE ECP VDP}";<br>> <br>> The code later indicates all the strings have to be there; however, the<br>> comments here do not match that.  There's also no mention here that at<br>> most 8 lines can be added.  Hopefully we never need to go beyond that<br>> number (however arbitrary 8 is).  Is the semicolon mandatory? Seems to<br>> me whatever format is required needs to be well documented.<br>I'll supplement about format of vsi_support_key_string and limit of items about it<br>into comment.<br>> <br>> With respect to the strings and the parsing done, should I 'assume' that<br>> the config_lookup_string() will know how to read the config file where<br>> elements span multiple lines.... In particular, is<br>> <br>> "line1,"<br>> "line2"<br>> <br>> read/returned as "line1,line2"?<br>> <br>> I would think a continuation "\" marker would be necessary:<br>> <br>> "line1," \<br>> "line2"<br>It's OK without slash (It was successful under my test). I haven't test for<br>the format like above.<br>> <br>> I would also think the comma would be outside the quotes, but don't have<br>> experience with the API in question.<br>The application read vsi_support_key_string as a whole string and use comma<br>to slice them (e.g.,above string will be devided into 2 parts, one before<br>comma and the other one after comma)<br>> <br>> Since I don't have a way to test this - I'm curious while coding this up<br>> if you checked that both lines were read when parsing?<br>You can adjust value of vsi_support_key_string and then the output of CU_DEBUG<br>in the log would changed as your change. I made every item would write into <br>/var/log/libvirt-cim/debug.txt<br>> <br>> Secondarily, there's some extraneous spaces which perhaps need to be<br>> cleaned up. Since the code later on will separate based on ",".  What<br>> happens if message #3 comes along some day as:<br>> <br>> "support feature1, feature2, and feature3: (0x83) mumbly fratz"<br>I took many cases into consideration. At last I think all special symbols are<br>not safe because all of them could appear in the future output. So I picked ",". <br>If someday "," appeared in output, there are just two places need to be updated.<br>Firstly, delimiter set in the variable delim (now is "," "{" and "}"). Secondly, <br>content of vsi_support_key_string and its comments. If you have any better<br>suggestions please let me know.<br>> <br>> <br>> <br>> <br>> > diff --git a/libxkutil/misc_util.c b/libxkutil/misc_util.c<br>> > index 4c0b0a1..6ce8dca 100644<br>> > --- a/libxkutil/misc_util.c<br>> > +++ b/libxkutil/misc_util.c<br>> > @@ -244,6 +244,24 @@ const char *get_mig_ssh_tmp_key(void)<br>> >          return prop.value_string;<br>> >  }<br>> >  <br>> > +const char *get_lldptool_query_options(void)<br>> > +{<br>> > +        static LibvirtcimConfigProperty prop = {<br>> > +                          "lldptool_query_options", CONFIG_STRING, {0}, 0};<br>> > +<br>> > +        libvirt_cim_config_get(&prop);<br>> > +        return prop.value_string;<br>> > +}<br>> > +<br>> > +const char *get_vsi_support_key_string(void)<br>> > +{<br>> > +        static LibvirtcimConfigProperty prop = {<br>> > +                          "vsi_support_key_string", CONFIG_STRING, {0}, 0};;<br>> > +<br>> > +        libvirt_cim_config_get(&prop);<br>> > +        return prop.value_string;<br>> > +}<br>> > +<br>> >  virConnectPtr connect_by_classname(const CMPIBroker *broker,<br>> >                                     const char *classname,<br>> >                                     CMPIStatus *s)<br>> > diff --git a/libxkutil/misc_util.h b/libxkutil/misc_util.h<br>> > index 9e6b419..4eb588d 100644<br>> > --- a/libxkutil/misc_util.h<br>> > +++ b/libxkutil/misc_util.h<br>> > @@ -155,6 +155,8 @@ int virt_set_status(const CMPIBroker *broker,<br>> >  /* get libvirt-cim config */<br>> >  const char *get_mig_ssh_tmp_key(void);<br>> >  bool get_force_use_qemu(void);<br>> > +const char *get_lldptool_query_options(void);<br>> > +const char *get_vsi_support_key_string(void);<br>> >  <br>> >  /*<br>> >   * Local Variables:<br>> > diff --git a/src/Virt_SwitchService.c b/src/Virt_SwitchService.c<br>> > index 8991426..f7bafbf 100644<br>> > --- a/src/Virt_SwitchService.c<br>> > +++ b/src/Virt_SwitchService.c<br>> > @@ -46,12 +46,26 @@ static CMPIStatus check_vsi_support(char *command)<br>> >          CMPIStatus s = {CMPI_RC_OK, NULL};<br>> >          char buff[MAX_LEN];<br>> >          FILE *stream = NULL;<br>> > -        const char *searchStr[] = {"  supported forwarding mode: "<br>> > -                                   "(0x40) reflective relay",<br>> > -                                   "     supported capabilities: "<br>> > -                                   "(0x07) RTE ECP VDP",<br>> > -                                   NULL};<br>> > -        int  matched = 0;<br>> > +        char *searchStr[8]; /* maximum items of vsi support output */<br>> > +        int count = 0;<br>> > +        const char *user_settings = get_vsi_support_key_string();<br>> > +        char *vsi_support_key_string = NULL;<br>> > +        char *delim = "{},";<br>> > +        int matched = 0;<br>> > +        char *temp = NULL;<br>> > +<br>> > +        if (!user_settings) {<br>> > +                user_settings = "{ supported forwarding mode: "<br>> > +                                "(0x40) reflective relay,"<br>> > +                                "   supported capabilities: "<br>> > +                                "(0x7) RTE ECP VDP}";<br>> > +        }<br>> > +<br>> > +        vsi_support_key_string = strdup(user_settings);<br>> <br>> There's a memory leak hear if 'user_settings' is returned from the api.<br>> That code will strdup() whatever is returned, it's returned here,<br>> strdup()'d again and leaked.<br>Yes, so it is.<br>> <br>> <br>> > +        if (vsi_support_key_string == NULL) {<br>> > +                CU_DEBUG("strdup vsi_support_key_string failed!");<br>> <br>> I think you need to call cu_statusf here; otherwise, 's' returns as<br>> {CMPI_RC_OK, NULL}<br>> <br>> > +                goto out;<br>> > +        }<br>> >  <br>> >          // Run lldptool command to find vsi support.<br>> >          stream = popen(command, "r");<br>> > @@ -63,6 +77,25 @@ static CMPIStatus check_vsi_support(char *command)<br>> >                  goto out;<br>> >          }<br>> >  <br>> > +        /* Slice vsi_support_key_string into items */<br>> > +        searchStr[count] = strtok_r(vsi_support_key_string, delim, &temp);<br>> > +        if (searchStr[count] == NULL) {<br>> > +                CU_DEBUG("searchStr fetch failed when calling strtok_r!");<br>> > +        } else {<br>> > +                CU_DEBUG("searchStr[%d]: %s", count, searchStr[count]);<br>> > +                count++;<br>> > +        }<br>> > +<br>> > +        while ((searchStr[count] = strtok_r(NULL, delim, &temp))) {<br>> > +                if (count >= 7) {<br>> > +                        CU_DEBUG("WARN: searchStr is full, left aborted!");<br>> > +                        break;<br>> > +                } else {<br>> > +                        CU_DEBUG("searchStr[%d]: %s", count, searchStr[count]);<br>> > +                        count++;<br>> > +                }<br>> > +        }<br>> > +<br>> <br>> What if count == 0?  That is can the element in the conf file be "{}"?<br>Because the condition of vsi_support_key_string was set in the configuration<br>file is the default output items for vsi support check need to be updated.<br>So the level of vsi_support_key_string is higher than default. That's the use<br>of keyword in the .conf file. So if a void content in the .conf file is not<br>needed and should be commented out. I'll add this point into comment of .conf<br>file.<br>> <br>> >          // Read the output of the command.<br>> >          while (fgets(buff, MAX_LEN, stream) != NULL) {<br>> >                  int i = 0;<br>> > @@ -81,16 +114,18 @@ static CMPIStatus check_vsi_support(char *command)<br>> >                  }<br>> >                  /* All the search strings were found in the output of this<br>> >                     command. */<br>> > -                if (matched == 2) {<br>> > +                if (matched == count) {<br>> >                          cu_statusf(_BROKER, &s, CMPI_RC_OK, "VSI supported");<br>> > -                        goto out;;<br>> > +                        goto out;<br>> >                  }<br>> >          }<br>> > +<br>> >          cu_statusf(_BROKER, &s,<br>> >                     CMPI_RC_ERR_NOT_FOUND,<br>> >                     "No VSI Support found");<br>> >  <br>> > - out:       <br>> > + out:<br>> > +        free(vsi_support_key_string);<br>> >          if (stream != NULL)<br>> >                  pclose(stream);<br>> >          return s;<br>> > @@ -214,6 +249,7 @@ static CMPIStatus get_switchservice(const CMPIObjectPath *reference,<br>> >          int i;<br>> >          char **if_list;<br>> >          char cmd[MAX_LEN];<br>> > +        const char *lldptool_query_options = NULL;<br>> >  <br>> >          *_inst = NULL;<br>> >          conn = connect_by_classname(broker, CLASSNAME(reference), &s);<br>> > @@ -257,10 +293,15 @@ static CMPIStatus get_switchservice(const CMPIObjectPath *reference,<br>> >  <br>> >          CU_DEBUG("Found %d interfaces", count);<br>> >  <br>> > +        lldptool_query_options = get_lldptool_query_options();<br>> > +        if (!lldptool_query_options) {<br>> > +                lldptool_query_options = "-t -g ncb -V evbcfg";<br>> > +        }<br>> <br>> Memory leak if we are successful from get_lldptool_query_options()<br>free() will be added.<br>> <br>> John<br>> <br>> >  <br>> >          for (i=0; i<count; i++) {<br>> > -                sprintf(cmd, "lldptool -i %s -t -V evbcfg", if_list[i]);<br>> > -                CU_DEBUG("running command %s ...", cmd);<br>> > +                sprintf(cmd, "lldptool -i %s %s",<br>> > +                        if_list[i], lldptool_query_options);<br>> > +                CU_DEBUG("running command [%s]", cmd);<br>> >                  s = check_vsi_support(cmd); <br>> >                  if (s.rc == CMPI_RC_OK) {<br>> >                          vsi = true;<br>> > -- <br>> > 1.7.1<br>> <br>> _______________________________________________<br>> Libvirt-cim mailing list<br>> Libvirt-cim@redhat.com<br>> https://www.redhat.com/mailman/listinfo/libvirt-cim<br></div>                                          </div></body>
</html>