<html><body>
<p>I have tested it.<br>
There is no cimtest coming as this can be tested by wbemcli or any cim browser.<br>
I am still exploring and may decide to write a cimtest. For now, it is just wbemcli.<br>
<br>
-Sharad<br>
<br>
<tt>Chip Vincent <cvincent@linux.vnet.ibm.com> wrote on 03/04/2011 04:48:46 PM:<br>
<br>
> Chip Vincent <cvincent@linux.vnet.ibm.com> </tt><br>
<tt>> 03/04/11 04:48 PM</tt><br>
<tt>> <br>
> Please respond to<br>
> cvincent@linux.vnet.ibm.com</tt><br>
<tt>> <br>
> To</tt><br>
<tt>> <br>
> List for discussion and development of libvirt CIM <libvirt-cim@redhat.com></tt><br>
<tt>> <br>
> cc</tt><br>
<tt>> <br>
> Sharad Mishra/Beaverton/IBM@IBMUS</tt><br>
<tt>> <br>
> Subject</tt><br>
<tt>> <br>
> Re: [Libvirt-cim] [PATCH] Query switch to find its vsi capabilities</tt><br>
<tt>> <br>
> +1. I have not tested since I don't have the hardware. BTW, is there a <br>
> cimtest update coming for this function?<br>
> <br>
> On 03/02/2011 11:24 AM, Sharad Mishra wrote:<br>
> > # HG changeset patch<br>
> > # User Sharad Mishra<snmishra@us.ibm.com><br>
> > # Date 1299082247 28800<br>
> > # Node ID 134137bc4f2505fc3576b312b8ef2c63a510fa68<br>
> > # Parent  432922275bea75a769cf058209bdb81198f3b360<br>
> > Query switch to find its vsi capabilities.<br>
> ><br>
> > This patch adds a new 'SwitchService' provider that will query the<br>
> switch to check if it supports VSI.<br>
> ><br>
> > Signed-off-by: Sharad Mishra<snmishra@us.ibm.com><br>
> ><br>
> > diff -r 432922275bea -r 134137bc4f25 Makefile.am<br>
> > --- a/Makefile.am   Fri Jan 21 15:59:27 2011 -0500<br>
> > +++ b/Makefile.am   Wed Mar 02 08:10:47 2011 -0800<br>
> > @@ -28,6 +28,7 @@<br>
> >      schema/ElementConformsToProfile.mof \<br>
> >      schema/ComputerSystemIndication.mof \<br>
> >      schema/ResourceAllocationSettingDataIndication.mof \<br>
> > +   schema/SwitchService.mof \<br>
> >      schema/ComputerSystemMigrationIndication.mof \<br>
> >      schema/Virt_ResourceAllocationSettingData.mof \<br>
> >      schema/ResourceAllocationSettingData.mof \<br>
> > @@ -108,6 +109,7 @@<br>
> >      schema/HostedResourcePool.registration \<br>
> >      schema/ComputerSystemIndication.registration \<br>
> >      schema/ResourceAllocationSettingDataIndication.registration \<br>
> > +   schema/SwitchService.registration \<br>
> >      schema/ComputerSystemMigrationIndication.registration \<br>
> >      schema/ResourceAllocationSettingData.registration \<br>
> >      schema/ResourcePoolConfigurationService.registration \<br>
> > diff -r 432922275bea -r 134137bc4f25 schema/SwitchService.mof<br>
> > --- /dev/null   Thu Jan 01 00:00:00 1970 +0000<br>
> > +++ b/schema/SwitchService.mof   Wed Mar 02 08:10:47 2011 -0800<br>
> > @@ -0,0 +1,27 @@<br>
> > +// Copyright IBM Corp. 2011<br>
> > +<br>
> > +[Provider("cmpi::Virt_SwitchService")]<br>
> > +class Xen_SwitchService : CIM_SwitchService<br>
> > +{<br>
> > +    [Description("Flag to determine if VSI is supported on the switch")]<br>
> > +    boolean IsVSISupported;<br>
> > +<br>
> > +};<br>
> > +<br>
> > +[Provider("cmpi::Virt_SwitchService")]<br>
> > +class KVM_SwitchService : CIM_SwitchService<br>
> > +{<br>
> > +    [Description("Flag to determine if VSI is supported on the switch")]<br>
> > +    boolean IsVSISupported;<br>
> > +<br>
> > +};<br>
> > +<br>
> > +[Provider("cmpi::Virt_SwitchService")]<br>
> > +class LXC_SwitchService : CIM_SwitchService<br>
> > +{<br>
> > +    [Description("Flag to determine if VSI is supported on the switch")]<br>
> > +    boolean IsVSISupported;<br>
> > +<br>
> > +};<br>
> > +<br>
> > +<br>
> > diff -r 432922275bea -r 134137bc4f25 schema/SwitchService.registration<br>
> > --- /dev/null   Thu Jan 01 00:00:00 1970 +0000<br>
> > +++ b/schema/SwitchService.registration   Wed Mar 02 08:10:47 2011 -0800<br>
> > @@ -0,0 +1,6 @@<br>
> > +# Copyright IBM Corp. 2011<br>
> > +# Classname Namespace ProviderName ProviderModule ProviderTypes<br>
> > +Xen_SwitchService root/virt Virt_SwitchService Virt_SwitchService instance<br>
> > +KVM_SwitchService root/virt Virt_SwitchService Virt_SwitchService instance<br>
> > +LXC_SwitchService root/virt Virt_SwitchService Virt_SwitchService instance<br>
> > +<br>
> > diff -r 432922275bea -r 134137bc4f25 src/Makefile.am<br>
> > --- a/src/Makefile.am   Fri Jan 21 15:59:27 2011 -0500<br>
> > +++ b/src/Makefile.am   Wed Mar 02 08:10:47 2011 -0800<br>
> > @@ -49,6 +49,7 @@<br>
> >                          libVirt_SystemDevice.la \<br>
> >                          libVirt_ComputerSystemIndication.la \<br>
> >                          <br>
> libVirt_ResourceAllocationSettingDataIndication.la \<br>
> > +                       libVirt_SwitchService.la \<br>
> >                          libVirt_ComputerSystemMigrationIndication.la \<br>
> >                          libVirt_VirtualSystemManagementCapabilities.la \<br>
> >                          libVirt_AllocationCapabilities.la \<br>
> > @@ -91,6 +92,10 @@<br>
> >   libVirt_ResourceAllocationSettingDataIndication_la_SOURCES = <br>
> Virt_ResourceAllocationSettingDataIndication.c<br>
> >   libVirt_ResourceAllocationSettingDataIndication_la_LIBADD = -<br>
> lVirt_ComputerSystem<br>
> ><br>
> > +libVirt_SwitchService_la_DEPENDENCIES = libVirt_ComputerSystem.la<br>
> > +libVirt_SwitchService_la_SOURCES = Virt_SwitchService.c<br>
> > +libVirt_SwitchService_la_LIBADD = -lVirt_ComputerSystem<br>
> > +<br>
> >   libVirt_ComputerSystemMigrationIndication_la_DEPENDENCIES = <br>
> libVirt_ComputerSystem.la<br>
> >   libVirt_ComputerSystemMigrationIndication_la_SOURCES = <br>
> Virt_ComputerSystemMigrationIndication.c<br>
> >   libVirt_ComputerSystemMigrationIndication_la_LIBADD = -<br>
> lVirt_ComputerSystem<br>
> > diff -r 432922275bea -r 134137bc4f25 src/Virt_SwitchService.c<br>
> > --- /dev/null   Thu Jan 01 00:00:00 1970 +0000<br>
> > +++ b/src/Virt_SwitchService.c   Wed Mar 02 08:10:47 2011 -0800<br>
> > @@ -0,0 +1,297 @@<br>
> > +/*<br>
> > + * Copyright IBM Corp. 2011<br>
> > + *<br>
> > + * Authors:<br>
> > + *  Sharad Mishra<snmishra@us.ibm.com><br>
> > + *<br>
> > + * This library is free software; you can redistribute it and/or<br>
> > + * modify it under the terms of the GNU Lesser General Public<br>
> > + * License as published by the Free Software Foundation; either<br>
> > + * version 2.1 of the License, or (at your option) any later version.<br>
> > + *<br>
> > + * This library is distributed in the hope that it will be useful,<br>
> > + * but WITHOUT ANY WARRANTY; without even the implied warranty of<br>
> > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU<br>
> > + * Lesser General Public License for more details.<br>
> > + *<br>
> > + * You should have received a copy of the GNU Lesser General Public<br>
> > + * License along with this library; if not, write to the Free Software<br>
> > + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA<br>
> > + */<br>
> > +#include<stdio.h><br>
> > +#include<stdlib.h><br>
> > +#include<unistd.h><br>
> > +#include<string.h><br>
> > +#include<stdbool.h><br>
> > +#include<errno.h><br>
> > +<br>
> > +#include<cmpidt.h><br>
> > +#include<cmpift.h><br>
> > +#include<cmpimacs.h><br>
> > +<br>
> > +#include<libcmpiutil/libcmpiutil.h><br>
> > +#include<libcmpiutil/std_instance.h><br>
> > +<br>
> > +#include "misc_util.h"<br>
> > +#include "config.h"<br>
> > +<br>
> > +#define MAX_LEN 512<br>
> > +#define CMD "/sbin/ifconfig -a | /bin/grep eth | /bin/awk '{print$1}'"<br>
> > +<br>
> > +const static CMPIBroker *_BROKER;<br>
> > +<br>
> > +static CMPIStatus check_vsi_support(char *command)<br>
> > +{<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>
> > +        int  matched = 0;<br>
> > +<br>
> > +        // Run lldptool command to find vsi support.<br>
> > +        stream = popen(command, "r");<br>
> > +        if (stream == NULL) {<br>
> > +                CU_DEBUG("Failed to open pipe to read vsi support");<br>
> > +                cu_statusf(_BROKER,&s,<br>
> > +                           CMPI_RC_ERR_NOT_FOUND,<br>
> > +                           "Failed to open pipe");<br>
> > +                goto out;<br>
> > +        }<br>
> > +<br>
> > +        // Read the output of the command.<br>
> > +        while (fgets(buff, MAX_LEN, stream) != NULL) {<br>
> > +                int i = 0;<br>
> > +                while (searchStr[i] != NULL) {<br>
> > +                        int len = strlen(searchStr[i]);<br>
> > +                        /* Read value which is stored in 'buff' has newline<br>
> > +                           at the end, we remove it for comparison. */<br>
> > +                        if (strncmp(buff, searchStr[i], (len - 1)) == 0) {<br>
> > +                                /* 'matched' flag is incremented each time<br>
> > +                                   we find that read string <br>
> (output of lldptool<br>
> > +                                   command) and searchStrings are same. */<br>
> > +                                matched++;<br>
> > +                                break;<br>
> > +                        }<br>
> > +                        i++;<br>
> > +                }<br>
> > +                /* All the search strings were found in the output of this<br>
> > +                   command. */<br>
> > +                if (matched == 2) {<br>
> > +                        cu_statusf(_BROKER,&s, CMPI_RC_OK, "VSI <br>
> supported");<br>
> > +                        goto out;;<br>
> > +                }<br>
> > +        }<br>
> > +        cu_statusf(_BROKER,&s,<br>
> > +                   CMPI_RC_ERR_NOT_FOUND,<br>
> > +                   "No VSI Support found");<br>
> > +<br>
> > + out:<br>
> > +        pclose(stream);<br>
> > +        return s;<br>
> > +}<br>
> > +<br>
> > +static char **run_command(char *func, int *len, CMPIStatus *s) {<br>
> > +<br>
> > +        char buff[MAX_LEN];<br>
> > +        FILE *stream = NULL;<br>
> > +        char **arr = NULL;<br>
> > +        char *string = NULL;<br>
> > +        int i = 0;<br>
> > +<br>
> > +        // run the command.<br>
> > +        stream = popen(func, "r");<br>
> > +        if (stream == NULL) {<br>
> > +                CU_DEBUG("Failed to open pipe to run command");<br>
> > +                cu_statusf(_BROKER, s,<br>
> > +                           CMPI_RC_ERR_NOT_FOUND,<br>
> > +                           "Failed to open pipe");<br>
> > +                return NULL;<br>
> > +        }<br>
> > +<br>
> > +        // read output of command.<br>
> > +        while (fgets(buff, MAX_LEN, stream) != NULL) {<br>
> > +                int len = strlen(buff) - 1;<br>
> > +                char **tmp_list = NULL;<br>
> > +<br>
> > +                // dynamically increase size as more interfaces are found.<br>
> > +                tmp_list = (char **)realloc(arr,<br>
> > +                                            (i + 1) *<br>
> > +                                            sizeof(char *));<br>
> > +                if (tmp_list == NULL) {<br>
> > +                        CU_DEBUG("Failed to allocate memory");<br>
> > +                        cu_statusf(_BROKER, s,<br>
> > +                                   CMPI_RC_ERR_NOT_FOUND,<br>
> > +                                   "Failed to realloc");<br>
> > +                        return NULL;<br>
> > +                }<br>
> > +<br>
> > +                arr = tmp_list;<br>
> > +<br>
> > +                string = calloc(len, sizeof(char));<br>
> > +                if (string == NULL) {<br>
> > +                        CU_DEBUG("Failed to allocate memory");<br>
> > +                        cu_statusf(_BROKER, s,<br>
> > +                                   CMPI_RC_ERR_NOT_FOUND,<br>
> > +                                   "Failed to calloc");<br>
> > +                        return NULL;<br>
> > +                }<br>
> > +                strncpy(string,  buff, len);<br>
> > +                arr[i] = string;<br>
> > +                i++;<br>
> > +        }<br>
> > +<br>
> > +        pclose(stream);<br>
> > +        *len = i;<br>
> > +        return arr;<br>
> > +}<br>
> > +<br>
> > +static CMPIStatus get_switchservice(const CMPIObjectPath *reference,<br>
> > +                         CMPIInstance **_inst,<br>
> > +                         const CMPIBroker *broker,<br>
> > +                         const CMPIContext *context,<br>
> > +                         bool is_get_inst)<br>
> > +{<br>
> > +        CMPIStatus s = {CMPI_RC_OK, NULL};<br>
> > +        CMPIInstance *inst = NULL;<br>
> > +        virConnectPtr conn = NULL;<br>
> > +        bool vsi = false;<br>
> > +        int count = 0;<br>
> > +        int i;<br>
> > +        char **if_list;<br>
> > +        char cmd[MAX_LEN];<br>
> > +<br>
> > +        *_inst = NULL;<br>
> > +        conn = connect_by_classname(broker, CLASSNAME(reference),&s);<br>
> > +        if (conn == NULL) {<br>
> > +                if (is_get_inst)<br>
> > +                        cu_statusf(broker,&s,<br>
> > +                                   CMPI_RC_ERR_NOT_FOUND,<br>
> > +                                   "No such instance");<br>
> > +<br>
> > +                return s;<br>
> > +        }<br>
> > +<br>
> > +        inst = get_typed_instance(broker,<br>
> > +                                  pfx_from_conn(conn),<br>
> > +                                  "SwitchService",<br>
> > +                                  NAMESPACE(reference));<br>
> > +<br>
> > +        if (inst == NULL) {<br>
> > +                CU_DEBUG("Failed to get typed instance");<br>
> > +                cu_statusf(broker,&s,<br>
> > +                           CMPI_RC_ERR_FAILED,<br>
> > +                           "Failed to create instance");<br>
> > +                goto out;<br>
> > +        }<br>
> > +<br>
> > +        CMSetProperty(inst, "Name",<br>
> > +                      (CMPIValue *)"Switch Virtualization Capabilities",<br>
> > +                      CMPI_chars);<br>
> > +<br>
> > +        if_list = run_command(CMD,&count,&s);<br>
> > +        if (if_list == 0) {<br>
> > +                CU_DEBUG("Failed to get network interfaces");<br>
> > +                cu_statusf(broker,&s,<br>
> > +                           CMPI_RC_ERR_FAILED,<br>
> > +                           "Failed to get network interfaces");<br>
> > +                goto out;<br>
> > +        }<br>
> > +<br>
> > +        CU_DEBUG("Found %d interfaces", count);<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>
> > +                s = check_vsi_support(cmd);<br>
> > +                if (s.rc == CMPI_RC_OK) {<br>
> > +                        vsi = true;<br>
> > +                        break;<br>
> > +                }<br>
> > +                else<br>
> > +                        vsi = false;<br>
> > +        }<br>
> > +<br>
> > +        CMSetProperty(inst, "IsVSISupported", (CMPIValue *)&vsi, <br>
> CMPI_boolean);<br>
> > +        s.rc = CMPI_RC_OK;<br>
> > +<br>
> > + out:<br>
> > +        virConnectClose(conn);<br>
> > +        *_inst = inst;<br>
> > +<br>
> > +        return s;<br>
> > +<br>
> > +}<br>
> > +<br>
> > +static CMPIStatus return_switchservice(const CMPIContext *context,<br>
> > +                            const CMPIObjectPath *reference,<br>
> > +                            const CMPIResult *results,<br>
> > +                            bool name_only,<br>
> > +                            bool is_get_inst)<br>
> > +{<br>
> > +        CMPIStatus s = {CMPI_RC_OK, NULL};<br>
> > +        CMPIInstance *inst;<br>
> > +<br>
> > +        s = get_switchservice(reference,&inst, _BROKER, context, <br>
> is_get_inst);<br>
> > +        if (s.rc != CMPI_RC_OK || inst == NULL)<br>
> > +                goto out;<br>
> > +<br>
> > +        if (name_only)<br>
> > +                cu_return_instance_name(results, inst);<br>
> > +        else<br>
> > +                CMReturnInstance(results, inst);<br>
> > + out:<br>
> > +        return s;<br>
> > +}<br>
> > +<br>
> > +static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self,<br>
> > +                                    const CMPIContext *context,<br>
> > +                                    const CMPIResult *results,<br>
> > +                                    const CMPIObjectPath *ref)<br>
> > +{<br>
> > +        return return_switchservice(context, ref, results, true, false);<br>
> > +}<br>
> > +<br>
> > +static CMPIStatus EnumInstances(CMPIInstanceMI *self,<br>
> > +                                const CMPIContext *context,<br>
> > +                                const CMPIResult *results,<br>
> > +                                const CMPIObjectPath *ref,<br>
> > +                                const char **properties)<br>
> > +{<br>
> > +<br>
> > +        return return_switchservice(context, ref, results, false, false);<br>
> > +}<br>
> > +<br>
> > +static CMPIStatus GetInstance(CMPIInstanceMI *self,<br>
> > +                              const CMPIContext *context,<br>
> > +                              const CMPIResult *results,<br>
> > +                              const CMPIObjectPath *ref,<br>
> > +                              const char **properties)<br>
> > +{<br>
> > +        return return_switchservice(context, ref, results, false, true);<br>
> > +}<br>
> > +<br>
> > +DEFAULT_CI();<br>
> > +DEFAULT_MI();<br>
> > +DEFAULT_DI();<br>
> > +DEFAULT_EQ();<br>
> > +DEFAULT_INST_CLEANUP();<br>
> > +<br>
> > +STD_InstanceMIStub(,<br>
> > +                   Virt_SwitchService,<br>
> > +                   _BROKER,<br>
> > +                   libvirt_cim_init());<br>
> > +<br>
> > +/*<br>
> > + * Local Variables:<br>
> > + * mode: C<br>
> > + * c-set-style: "K&R"<br>
> > + * tab-width: 8<br>
> > + * c-basic-offset: 8<br>
> > + * indent-tabs-mode: nil<br>
> > + * End:<br>
> > + */<br>
> > +<br>
> ><br>
> > _______________________________________________<br>
> > Libvirt-cim mailing list<br>
> > Libvirt-cim@redhat.com<br>
> > <a href="https://www.redhat.com/mailman/listinfo/libvirt-cim">https://www.redhat.com/mailman/listinfo/libvirt-cim</a><br>
> <br>
> -- <br>
> Chip Vincent<br>
> Open Virtualization<br>
> IBM Linux Technology Center<br>
> cvincent@linux.vnet.ibm.com<br>
</tt></body></html>