I'm afraid that vsi_support_key_string and llpdtool_query_options may can not lead to memory leak.
After checked code carefully, I found that's static varaible in get method so no matter how many
get method called, just one memory space allocated. So please do not worry about them.


From: cngesaint@outlook.com
To: libvirt-cim@redhat.com
Date: Sun, 28 Apr 2013 02:28:18 +0000
Subject: Re: [Libvirt-cim] [PATCH 3/3] make lldptool command and support output configurable



> Date: Thu, 25 Apr 2013 14:08:51 -0400
> From: jferlan@redhat.com
> To: libvirt-cim@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@redhat.com
> https://www.redhat.com/mailman/listinfo/libvirt-cim

_______________________________________________ Libvirt-cim mailing list Libvirt-cim@redhat.com https://www.redhat.com/mailman/listinfo/libvirt-cim