<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>