[Libvirt-cim] [PATCH 3/3] make lldptool command and support output configurable

WangXu cngesaint at outlook.com
Sun Apr 28 02:28:18 UTC 2013



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


More information about the Libvirt-cim mailing list