> # HG changeset patch
> # User Sharad Mishra <snmishra@us.ibm.com>
> # Date 1318954618 25200
> # Node ID d07f99a0279030e62046bbdc3ac378f9dc6473af
> # Parent  fb09136deb494008eb3aacee420ad74da7d7c294
> <Incomplete> SROV support in libvirt-cim
>
> This patch is the patch to add SRIOV support in libvirt-cim.
> This patch is not complete. Work on it was halted since the
> exploiter of this feature is not ready to consume it. And there
> are other features that need to be added which are in demand in
> near future.
>
> SRIOV support adds Enumeration of node devices to see what is
> available. Then it adds Virtual Functions (VFs), removes VFs and
> modifies VFs. It also adds support to detach a node. This link
> shows the steps -
>
> http://docs.fedoraproject.org/en-US/Fedora/13/html/
> Virtualization_Guide/sect-Para-virtualized_Windows_Drivers_Guide-
> How_SR_IOV_Libvirt_Works.html
>
> Step 6 above is for enum node devices.
> Step 8 is detach VF.
> Step 9 is add VF to guest.
> Similar to step 9 will be removeVF and modifyVF.
>
> So far, we have "sorta" implemented enum node device.
>
> Signed-off-by: Sharad Mishra <snmishra@us.ibm.com>
>
> diff -r fb09136deb49 -r d07f99a02790 Makefile.am
> --- a/Makefile.am   Tue Aug 30 08:48:36 2011 -0700
> +++ b/Makefile.am   Tue Oct 18 09:16:58 2011 -0700
> @@ -29,6 +29,7 @@
>     schema/ComputerSystemIndication.mof \
>     schema/ResourceAllocationSettingDataIndication.mof \
>     schema/SwitchService.mof \
> +   schema/VirtualSystemPCIDevice.mof \
>     schema/ComputerSystemMigrationIndication.mof \
>     schema/Virt_ResourceAllocationSettingData.mof \
>     schema/ResourceAllocationSettingData.mof \
> @@ -116,6 +117,7 @@
>     schema/ComputerSystemIndication.registration \
>     schema/ResourceAllocationSettingDataIndication.registration \
>     schema/SwitchService.registration \
> +   schema/VirtualSystemPCIDevice.registration \
>     schema/ComputerSystemMigrationIndication.registration \
>     schema/ResourceAllocationSettingData.registration \
>     schema/ResourcePoolConfigurationService.registration \
> diff -r fb09136deb49 -r d07f99a02790 libxkutil/Makefile.am
> --- a/libxkutil/Makefile.am   Tue Aug 30 08:48:36 2011 -0700
> +++ b/libxkutil/Makefile.am   Tue Oct 18 09:16:58 2011 -0700
> @@ -5,12 +5,14 @@
>              -DLIBVIRTCIM_CONF=\"@sysconfdir@/@PACKAGE@.conf\"
>  
>  noinst_HEADERS = cs_util.h misc_util.h device_parsing.h xmlgen.h
> infostore.h \
> -                 pool_parsing.h acl_parsing.h
> +                 pool_parsing.h acl_parsing.h node_parsing.h
>  
>  lib_LTLIBRARIES = libxkutil.la
>  
>  libxkutil_la_SOURCES = cs_util_instance.c misc_util.c device_parsing.c \
> -                       xmlgen.c infostore.c pool_parsing.c acl_parsing.c
> +                       xmlgen.c infostore.c pool_parsing.c acl_parsing.c \
> +                       node_parsing.c
> +
>  libxkutil_la_LDFLAGS = -version-info @VERSION_INFO@
>  libxkutil_la_LIBADD = @LIBVIRT_LIBS@ \
>              @LIBUUID_LIBS@
> diff -r fb09136deb49 -r d07f99a02790 libxkutil/node_parsing.c
> --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
> +++ b/libxkutil/node_parsing.c   Tue Oct 18 09:16:58 2011 -0700
> @@ -0,0 +1,184 @@
> +/*
> + * Copyright IBM Corp. 2011
> + *
> + * Authors:
> + *  Sharad Mishra <snmishra@us.ibm.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
> + */
> +#include <stdio.h>
> +#include <string.h>
> +#include <stdlib.h>
> +#include <stdbool.h>
> +#include <inttypes.h>
> +#include <sys/stat.h>
> +#include <libxml/tree.h>
> +#include <libxml/parser.h>
> +#include <libxml/xpath.h>
> +#include "misc_util.h"
> +
> +#include <libcmpiutil/libcmpiutil.h>
> +
> +#include "node_parsing.h"
> +
> +static void cleanup_pci_device(struct pci_device pci) {
> +
> +        free(pci.product);
> +        free(pci.vendor);
> +}
> +
> +void cleanup_node_device(struct node_device **node)
> +{
> +        struct node_device *_node = *node;
> +
> +        if ((node == NULL) || (*node == NULL))
> +                return;
> +
> +        if (XSTREQ(_node->capability, "pci"))
> +                cleanup_pci_device(_node->device_info.pci);
> +
> +        free(_node->name);
> +        free(_node->parent);
> +        free(_node->capability);
> +        free(_node);
> +
> +        *node = NULL;
> +}
> +
> +CMPIStatus get_node_from_xml(const CMPIBroker *broker,
> +                      const CMPIObjectPath *reference,
> +                      virConnectPtr conn,
> +                      char *xml,
> +                      CMPIInstance **_inst)
> +{
> +        int len;
> +        xmlDoc *xmldoc;
> +        xmlXPathContext *xpathctx;
> +        xmlXPathObject *xpathobj;
> +        const xmlChar *xpathstr = (xmlChar *)"/device";
> +        CMPIStatus s = {CMPI_RC_OK, NULL};
> +        CMPIInstance *inst = NULL;
> +        char *val = NULL;
> +        char *tmpstr = NULL;
> +        xmlNode **nodes = NULL;
> +        xmlNode *child;
> +        uint8_t ival;
> +
> +        CU_DEBUG("Node XML : %s", xml);
> +   len = strlen(xml) + 1;
> +
> +        inst = get_typed_instance(broker,
> +                                  pfx_from_conn(conn),
> +                                  "VirtualSystemPCIDevice",
> +                                  NAMESPACE(reference));
> +        if (inst == NULL) {
> +                cu_statusf(broker, &s,
> +                           CMPI_RC_ERR_FAILED,
> +                           "Unable to init VirtualSystemPCIDevice instance");
> +                goto err1;
> +        }
> +
> +
> +        if ((xmldoc = xmlParseMemory(xml, len)) == NULL) {
> +                CU_DEBUG("xmlParseMemory failed");
> +                goto err1;
> +        }
> +
> +        if ((xpathctx = xmlXPathNewContext(xmldoc)) == NULL) {
> +                CU_DEBUG("xmlXPathNewContext failed");
> +                goto err2;
> +        }
> +
> +        if ((xpathobj = xmlXPathEvalExpression(xpathstr, xpathctx))== NULL) {
> +                CU_DEBUG("xmlXPathEvalExpression failed");
> +                goto err3;
> +        }
> +
> +        nodes = xpathobj->nodesetval->nodeTab;
> +
> +        for (child = nodes[0]->children; child != NULL; child =
> child->next) {
> +                if (XSTREQ(child->name, "name")) {
> +                        val = get_node_content(child);
> +CU_DEBUG("val is %s", val);
> +                        if (val != NULL)
> +                                s = CMSetProperty(inst, "Name",
> +                                              (CMPIValue *)val,
> +                                              CMPI_chars);
> +                } else if (XSTREQ(child->name, "capability")) {
> +                        child = child->children;
> +CU_DEBUG("found capabi s.rc is %d, s.msg is %s", s.rc, s.msg);
> +                        continue;
> +                } else if (XSTREQ(child->name, "bus")) {
> +CU_DEBUG("found bus");
> +                        val = get_node_content(child);
> +CU_DEBUG("val is %s", val);
> +ival = atoi(val);
> +CU_DEBUG("len is %d", ival);
> +                        s = CMSetProperty(inst, "BusNumber",
> +                                      (CMPIValue *)&ival,
> +                                      CMPI_uint8);
> +                } else if (XSTREQ(child->name, "slot")) {
> +CU_DEBUG("found slot  rs is %d msg is %s", s.rc, s.msg);
> +                        val = get_node_content(child);
> +CU_DEBUG("val is %s", val);
> +ival = atoi(val);
> +CU_DEBUG("len is %d", ival);
> +                        s = CMSetProperty(inst, "DeviceNumber",
> +                                      (CMPIValue *)&ival,
> +                                      CMPI_uint8);
> +                } else if (XSTREQ(child->name, "function")) {
> +CU_DEBUG("found function rc is %d, msg is %s", s.rc, s.msg);
> +                        val = get_node_content(child);
> +CU_DEBUG("val is %s", val);
> +ival = atoi(val);
> +CU_DEBUG("len_16 is %d", ival);
> +                        s = CMSetProperty(inst, "FunctionNumber",
> +                                      (CMPIValue *)&ival,
> +                                      CMPI_uint8);
> +                } else if (XSTREQ(child->name, "vendor")) {
> +CU_DEBUG("found vendor rc is %d msg is %s", s.rc, s.msg);
> +                        val = get_attr_value(child, "id");
> +CU_DEBUG("val is %s", val);
> +sprintf(tmpstr, "%*2s", val);
> +CU_DEBUG("tmpstr is %s", tmpstr);
> +uint16_t val16 = atoi(tmpstr);
> +CU_DEBUG("len is %d", val16);
> +                        s = CMSetProperty(inst, "VendorID",
> +                                      (CMPIValue *)&val16,
> +                                      CMPI_uint16);
> +                }
> +        }
> +
> +        *_inst = inst;
> +
> +        xmlXPathFreeObject(xpathobj);
> + err3:
> +        xmlXPathFreeContext(xpathctx);
> + err2:
> +        xmlFreeDoc(xmldoc);
> + err1:
> +        return s;
> +}
> +
> +/*
> + * Local Variables:
> + * mode: C
> + * c-set-style: "K&R"
> + * tab-width: 8
> + * c-basic-offset: 8
> + * indent-tabs-mode: nil
> + * End:
> + */
> +
> diff -r fb09136deb49 -r d07f99a02790 libxkutil/node_parsing.h
> --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
> +++ b/libxkutil/node_parsing.h   Tue Oct 18 09:16:58 2011 -0700
> @@ -0,0 +1,63 @@
> +/*
> + * Copyright IBM Corp. 2011
> + *
> + * Authors:
> + *  Sharad Mishra <snmishra@us.ibm.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307  USA
> + */
> +
> +
> +#include "cmpidt.h"
> +#include "cmpift.h"
> +#include "cmpimacs.h"
> +#include "device_parsing.h"
> +
> +struct pci_device {
> +        int domain;
> +        int bus;
> +        int slot;
> +        int function;
> +        char *product;
> +        char *vendor;
> +};
> +
> +/* USB and other node devices can be added later. */
> +struct node_device {
> +        char *name;
> +        char *parent;
> +        char *capability;
> +        union {
> +                struct pci_device pci;
> +        } device_info;
> +};
> +
> +void cleanup_node_device(struct node_device **node);
> +CMPIStatus get_node_from_xml(const CMPIBroker *broker,
> +                      const CMPIObjectPath *reference,
> +                      virConnectPtr conn,
> +                      char *xml,
> +                      CMPIInstance **_inst);
> +
> +
> +/*
> + * Local Variables:
> + * mode: C
> + * c-set-style: "K&R"
> + * tab-width: 8
> + * c-basic-offset: 8
> + * indent-tabs-mode: nil
> + * End:
> + */
> diff -r fb09136deb49 -r d07f99a02790 schema/VirtualSystemPCIDevice.mof
> --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
> +++ b/schema/VirtualSystemPCIDevice.mof   Tue Oct 18 09:16:58 2011 -0700
> @@ -0,0 +1,14 @@
> +// Copyright IBM Corp. 2011
> +
> +[Provider("cmpi::Virt_VirtualSystemPCIDevice")]
> +class Xen_VirtualSystemPCIDevice : CIM_PCIDevice {
> +};
> +
> +[Provider("cmpi::Virt_VirtualSystemPCIDevice")]
> +class KVM_VirtualSystemPCIDevice : CIM_PCIDevice {
> +};
> +
> +[Provider("cmpi::Virt_VirtualSystemPCIDevice")]
> +class LXC_VirtualSystemPCIDevice : CIM_PCIDevice {
> +};
> +
> diff -r fb09136deb49 -r d07f99a02790 schema/
> VirtualSystemPCIDevice.registration
> --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
> +++ b/schema/VirtualSystemPCIDevice.registration   Tue Oct 18 09:16:
> 58 2011 -0700
> @@ -0,0 +1,5 @@
> +# Copyright IBM Corp. 2011
> +# Classname Namespace ProviderName ProviderModule ProviderTypes
> +Xen_VirtualSystemPCIDevice root/virt Virt_VirtualSystemPCIDevice
> Virt_VirtualSystemPCIDevice instance method
> +KVM_VirtualSystemPCIDevice root/virt Virt_VirtualSystemPCIDevice
> Virt_VirtualSystemPCIDevice instance method
> +LXC_VirtualSystemPCIDevice root/virt Virt_VirtualSystemPCIDevice
> Virt_VirtualSystemPCIDevice instance method
> diff -r fb09136deb49 -r d07f99a02790 src/Makefile.am
> --- a/src/Makefile.am   Tue Aug 30 08:48:36 2011 -0700
> +++ b/src/Makefile.am   Tue Oct 18 09:16:58 2011 -0700
> @@ -17,6 +17,7 @@
>      Virt_VSSD.h               \
>      Virt_VSMigrationCapabilities.h              \
>      Virt_VSMigrationService.h                   \
> +    Virt_VirtualSystemPCIDevice.h                   \
>      Virt_AllocationCapabilities.h               \
>      Virt_VirtualSystemSnapshotService.h         \
>      Virt_VirtualSystemSnapshotServiceCapabilities.h \
> @@ -53,6 +54,7 @@
>                         libVirt_ComputerSystemIndication.la \
>                         libVirt_ResourceAllocationSettingDataIndication.la \
>                         libVirt_SwitchService.la \
> +                       libVirt_VirtualSystemPCIDevice.la \
>                         libVirt_ComputerSystemMigrationIndication.la \
>                         libVirt_VirtualSystemManagementCapabilities.la \
>                         libVirt_AllocationCapabilities.la \
> @@ -105,6 +107,9 @@
>  libVirt_SwitchService_la_SOURCES = Virt_SwitchService.c
>  libVirt_SwitchService_la_LIBADD = -lVirt_ComputerSystem
>  
> +libVirt_VirtualSystemPCIDevice = libVirt_ComputerSystem.la
> +libVirt_VirtualSystemPCIDevice_la_SOURCES = Virt_VirtualSystemPCIDevice.c
> +
>  libVirt_ComputerSystemMigrationIndication_la_DEPENDENCIES =
> libVirt_ComputerSystem.la
>  libVirt_ComputerSystemMigrationIndication_la_SOURCES =
> Virt_ComputerSystemMigrationIndication.c
>  libVirt_ComputerSystemMigrationIndication_la_LIBADD = -lVirt_ComputerSystem
> diff -r fb09136deb49 -r d07f99a02790 src/Virt_VirtualSystemPCIDevice.c
> --- /dev/null   Thu Jan 01 00:00:00 1970 +0000
> +++ b/src/Virt_VirtualSystemPCIDevice.c   Tue Oct 18 09:16:58 2011 -0700
> @@ -0,0 +1,295 @@
> +/*
> + * Copyright IBM Corp. 2011
> + *
> + * Authors:
> + *  Sharad Mishra <snmishra@us.ibm.com>
> + *
> + * This library is free software; you can redistribute it and/or
> + * modify it under the terms of the GNU Lesser General Public
> + * License as published by the Free Software Foundation; either
> + * version 2.1 of the License, or (at your option) any later version.
> + *
> + * This library is distributed in the hope that it will be useful,
> + * but WITHOUT ANY WARRANTY; without even the implied warranty of
> + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
> + * Lesser General Public License for more details.
> + *
> + * You should have received a copy of the GNU Lesser General Public
> + * License along with this library; if not, write to the Free Software
> + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
> + */
> +#include <stdio.h>
> +#include <stdlib.h>
> +#include <string.h>
> +#include <sys/types.h>
> +#include <sys/wait.h>
> +#include <sys/stat.h>
> +#include <signal.h>
> +#include <unistd.h>
> +#include <dirent.h>
> +#include <errno.h>
> +
> +#include <uuid.h>
> +
> +#include <libvirt/libvirt.h>
> +
> +#include <cmpidt.h>
> +#include <cmpift.h>
> +#include <cmpimacs.h>
> +
> +#include <libcmpiutil/libcmpiutil.h>
> +#include "misc_util.h"
> +#include "node_parsing.h"
> +#include <libcmpiutil/std_instance.h>
> +#include <libcmpiutil/std_invokemethod.h>
> +#include <libcmpiutil/std_indication.h>
> +
> +#include "Virt_VSMigrationService.h"
> +#include "Virt_HostSystem.h"
> +#include "Virt_ComputerSystem.h"
> +#include "Virt_VSMigrationSettingData.h"
> +#include "svpc_types.h"
> +#include "libxkutil/infostore.h"
> +
> +#include "config.h"
> +
> +#include "Virt_VirtualSystemPCIDevice.h"
> +
> +const static CMPIBroker *_BROKER;
> +
> +static CMPIStatus add_sriov_vf(CMPIMethodMI *self,
> +                                const CMPIContext *ctx,
> +                                const CMPIResult *results,
> +                                const CMPIObjectPath *ref,
> +                                const CMPIArgs *argsin,
> +                                CMPIArgs *argsout)
> +{
> +
> +        CMPIStatus s = {CMPI_RC_OK, NULL};
> +
> +        return s;
> +}
> +
> +static CMPIStatus remove_sriov_vf(CMPIMethodMI *self,
> +                                const CMPIContext *ctx,
> +                                const CMPIResult *results,
> +                                const CMPIObjectPath *ref,
> +                                const CMPIArgs *argsin,
> +                                CMPIArgs *argsout)
> +{
> +
> +        CMPIStatus s = {CMPI_RC_OK, NULL};
> +
> +        return s;
> +}
> +
> +static CMPIStatus modify_sriov_vf(CMPIMethodMI *self,
> +                                const CMPIContext *ctx,
> +                                const CMPIResult *results,
> +                                const CMPIObjectPath *ref,
> +                                const CMPIArgs *argsin,
> +                                CMPIArgs *argsout)
> +{
> +
> +        CMPIStatus s = {CMPI_RC_OK, NULL};
> +
> +        return s;
> +}
> +
> +static struct method_handler AddSriovVf = {
> +        .name = "AddSriovVf",
> +        .handler = add_sriov_vf,
> +        .args = {{"ComputerSystem", CMPI_ref, false},
> +                 {"DestinationSystem", CMPI_ref, false},
> +                 {"MigrationSettingData", CMPI_instance, true},
> +                 {"NewSystemSettingData", CMPI_instance, true},
> +                 {"NewResourceSettingData", CMPI_instanceA, true},
> +                 ARG_END
> +        }
> +};
> +
> +static struct method_handler RemoveSriovVf = {
> +        .name = "RemoveSriovVf",
> +        .handler = remove_sriov_vf,
> +        .args = {{"ComputerSystem", CMPI_ref, false},
> +                 {"DestinationHost", CMPI_string, false},
> +                 {"MigrationSettingData", CMPI_instance, true},
> +                 {"NewSystemSettingData", CMPI_instance, true},
> +                 {"NewResourceSettingData", CMPI_instanceA, true},
> +                 ARG_END
> +        }
> +};
> +
> +static struct method_handler ModifySriovVf = {
> +        .name = "ModifySriovVf",
> +        .handler = modify_sriov_vf,
> +        .args = {{"ComputerSystem", CMPI_ref, false},
> +                 {"DestinationSystem", CMPI_ref, false},
> +                 {"MigrationSettingData", CMPI_instance, true},
> +                 {"NewSystemSettingData", CMPI_instance, true},
> +                 {"NewResourceSettingData", CMPI_instanceA, true},
> +                 ARG_END
> +        }
> +};
> +
> +static struct method_handler *my_handlers[] = {
> +        &AddSriovVf,
> +        &RemoveSriovVf,
> +        &ModifySriovVf,
> +        NULL
> +};
> +
> +STDIM_MethodMIStub(, Virt_VSMigrationService, _BROKER,
> +                   libvirt_cim_init(), my_handlers);
> +
> +
> +static CMPIStatus enum_pci(const CMPIBroker *broker,
> +                           const CMPIObjectPath *ref,
> +                           struct inst_list *instlist)
> +{
> +        CMPIStatus s = {CMPI_RC_OK, NULL};
> +        virConnectPtr conn = NULL;
> +        char **names = NULL;
> +        char *nodeXML;
> +        int count;
> +        int i;
> +
> +        conn = connect_by_classname(broker, CLASSNAME(ref), &s);
> +        if (conn == NULL) {
> +               cu_statusf(broker, &s,
> +                          CMPI_RC_ERR_NOT_FOUND,
> +                          "Failed to connect to Hypervisor");
> +                goto out;
> +        }
> +
> +        count = virNodeNumOfDevices(conn, "pci", 0);
> +        if (count < 1) {
> +               cu_statusf(broker, &s,
> +                          CMPI_RC_ERR_NOT_FOUND,
> +                          "Failed to find a PCI device");
> +                goto out;
> +        }
> +
> +        names = calloc(count, sizeof(char *));
> +        if (names == NULL) {
> +               cu_statusf(broker, &s,
> +                          CMPI_RC_ERR_NOT_FOUND,
> +                          "Failed to allocate memory");
> +                goto out;
> +        }
> +        
> +
> +        i = virNodeListDevices(conn, "pci", names, count, 0);
> +        if (i == -1) {
> +               cu_statusf(broker, &s,
> +                          CMPI_RC_ERR_NOT_FOUND,
> +                          "Failed to get PCI devices");
> +                goto out;
> +        }
> +
> +        for  (i=0; i < count; i++) {
> +                CMPIInstance *inst = NULL;
> +
> +                virNodeDevicePtr nptr = virNodeDeviceLookupByName(conn,
> +                                                                  names[i]);
> +                if (nptr == NULL) {
> +                        cu_statusf(broker, &s,
> +                                    CMPI_RC_ERR_NOT_FOUND,
> +                                    "Failed to lookup PCI device by name");
> +                        continue;
> +                }
> +
> +                nodeXML = virNodeDeviceGetXMLDesc(nptr, 0);
> +                if (nodeXML  == NULL) {
> +                        cu_statusf(broker, &s,
> +                                   CMPI_RC_ERR_NOT_FOUND,
> +                                   "Failed to get PCI Device XML
> Description");
> +                        continue;
> +                }
> +
> +                CU_DEBUG("PCI Device node xml is %s", nodeXML);
> +
> +                CMPIStatus stat = get_node_from_xml(broker, ref, conn,
> +                                                    nodeXML, &inst);
> +                if (stat.rc != CMPI_RC_OK)
> +                        continue;
> +
> +                inst_list_add(instlist, inst);

> +        }
> +        
> + out:
> +        virConnectClose(conn);
> +
> +        return s;
> +}
> +
> +static CMPIStatus return_pci(const CMPIContext *context,
> +                             const CMPIObjectPath *ref,
> +                             const CMPIResult *results,
> +                             bool name_only,
> +                             bool is_get_inst)
> +{
> +        struct inst_list list;
> +        CMPIStatus s;
> +
> +        inst_list_init(&list);
> +        s = enum_pci(_BROKER, ref, &list);
> +        if (s.rc != CMPI_RC_OK)
> +                goto out;
> +
> +        if (name_only)
> +                cu_return_instance_names(results, &list);
> +        else
> +                cu_return_instances(results, &list);
> + out:
> +        inst_list_free(&list);
> +        return s;
> +}
> +
> +static CMPIStatus EnumInstanceNames(CMPIInstanceMI *self,
> +                                    const CMPIContext *context,
> +                                    const CMPIResult *results,
> +                                    const CMPIObjectPath *ref)
> +{
> +        return return_pci(context, ref, results, true, false);
> +}
> +
> +static CMPIStatus EnumInstances(CMPIInstanceMI *self,
> +                                const CMPIContext *context,
> +                                const CMPIResult *results,
> +                                const CMPIObjectPath *ref,
> +                                const char **properties)
> +{
> +
> +        return return_pci(context, ref, results, false, false);
> +}
> +
> +
> +static CMPIStatus GetInstance(CMPIInstanceMI *self,
> +                              const CMPIContext *context,
> +                              const CMPIResult *results,
> +                              const CMPIObjectPath *ref,
> +                              const char **properties)
> +{
> +        return return_pci(context, ref, results, false, true);
> +}
> +
> +DEFAULT_CI();
> +DEFAULT_MI(); > +DEFAULT_DI();
> +DEFAULT_EQ();
> +DEFAULT_INST_CLEANUP();
> +
> +STD_InstanceMIStub(,
> +                   Virt_VirtualSystemPCIDevice,
> +                   _BROKER,
> +                   libvirt_cim_init());
> +/*
> + * Local Variables:
> + * mode: C
> + * c-set-style: "K&R"
> + * tab-width: 8
> + * c-basic-offset: 8
> + * indent-tabs-mode: nil
> + * End:
> + */