[Libvirt-cim] [PATCH] (#2) Make the ProcRASD show CPU pinning information

Dan Smith danms at us.ibm.com
Wed Feb 6 16:48:20 UTC 2008


# HG changeset patch
# User Dan Smith <danms at us.ibm.com>
# Date 1202316457 28800
# Node ID 1f9cfddac518f134de81cae833e20120b38b673d
# Parent  c7dd4a8358a187a3469c3d8a177950625898a227
(#2) Make the ProcRASD show CPU pinning information

This is done by embedding instances of the physical processor objects into
the HostResource[] field of the ProcRASD (per the MOF).

In order for the linkage to be present, you need sblim-cmpi-base.

Changes:
 - Actually report the correct pinning information

Signed-off-by: Dan Smith <danms at us.ibm.com>

diff -r c7dd4a8358a1 -r 1f9cfddac518 src/Virt_RASD.c
--- a/src/Virt_RASD.c	Wed Feb 06 07:00:00 2008 -0800
+++ b/src/Virt_RASD.c	Wed Feb 06 08:47:37 2008 -0800
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <inttypes.h>
 #include <sys/stat.h>
+#include <unistd.h>
 
 #include <cmpidt.h>
 #include <cmpift.h>
@@ -91,6 +92,195 @@ char *rasd_to_xml(CMPIInstance *rasd)
 {
         /* FIXME: Remove this */
         return NULL;
+}
+
+static bool proc_get_physical_ref(const CMPIBroker *broker,
+                                  uint32_t physnum,
+                                  struct inst_list *list)
+{
+        CMPIObjectPath *op = NULL;
+        CMPIStatus s;
+        char hostname[255];
+        char *devid = NULL;
+        CMPIInstance *inst;
+        bool result = false;
+
+        if (asprintf(&devid, "%i", physnum) == -1) {
+                CU_DEBUG("Failed to create DeviceID string");
+                goto out;
+        }
+
+        if (gethostname(hostname, sizeof(hostname)) == -1) {
+                CU_DEBUG("Hostname overflow");
+                goto out;
+        }
+
+        op = CMNewObjectPath(broker, "root/cimv2", "Linux_Processor", &s);
+        if ((op == NULL) || (s.rc != CMPI_RC_OK)) {
+                CU_DEBUG("Failed to get ObjectPath for processor");
+                goto out;
+        }
+
+        CMAddKey(op, "CreationClassName",
+                 (CMPIValue *)"Linux_Processor",
+                 CMPI_chars);
+        CMAddKey(op, "SystemName",
+                 (CMPIValue *)hostname,
+                 CMPI_chars);
+        CMAddKey(op, "SystemCreationClassName",
+                 (CMPIValue *)"Linux_ComputerSystem",
+                 CMPI_chars);
+        CMAddKey(op, "DeviceID",
+                 (CMPIValue *)devid,
+                 CMPI_chars);
+
+        inst = CMNewInstance(broker, op, &s);
+        if ((inst == NULL) || (s.rc != CMPI_RC_OK)) {
+                CU_DEBUG("Failed to make instance");
+                goto out;
+        }
+
+        inst_list_add(list, inst);
+
+        result = true;
+ out:
+        free(devid);
+
+        return result;
+}
+
+static uint32_t proc_set_cpu(const CMPIBroker *broker,
+                             virNodeInfoPtr node,
+                             virDomainPtr dom,
+                             struct virt_device *dev,
+                             struct inst_list *list)
+{
+        virVcpuInfoPtr vinfo = NULL;
+        virDomainInfo info;
+        uint8_t *cpumaps = NULL;
+        int ret;
+        int i;
+        int vcpu = dev->dev.vcpu.number;;
+        int maplen = VIR_CPU_MAPLEN(VIR_NODEINFO_MAXCPUS(*node));;
+
+        ret = virDomainGetInfo(dom, &info);
+        if (ret == -1) {
+                CU_DEBUG("Failed to get info for domain `%s'",
+                         virDomainGetName(dom));
+                goto out;
+        }
+
+        if (dev->dev.vcpu.number >= info.nrVirtCpu) {
+                CU_DEBUG("VCPU %i higher than max of %i for %s",
+                         dev->dev.vcpu.number,
+                         info.nrVirtCpu,
+                         virDomainGetName(dom));
+                goto out;
+        }
+
+        vinfo = calloc(info.nrVirtCpu, sizeof(*vinfo));
+        if (vinfo == NULL) {
+                CU_DEBUG("Failed to allocate memory for %i virVcpuInfo",
+                         info.nrVirtCpu);
+                goto out;
+        }
+
+        cpumaps = calloc(info.nrVirtCpu, maplen);
+        if (cpumaps == NULL) {
+                CU_DEBUG("Failed to allocate memory for %ix%i maps",
+                         info.nrVirtCpu, maplen);
+                goto out;
+        }
+
+        ret = virDomainGetVcpus(dom, vinfo, info.nrVirtCpu, cpumaps, maplen);
+        if (ret < info.nrVirtCpu) {
+                CU_DEBUG("Failed to get VCPU info for %s",
+                         virDomainGetName(dom));
+                goto out;
+        }
+
+        for (i = 0; i < VIR_NODEINFO_MAXCPUS(*node); i++) {
+                if (VIR_CPU_USABLE(cpumaps, maplen, vcpu, i)) {
+                        CU_DEBUG("VCPU %i pinned to physical %i",
+                                 vcpu, i);
+                        proc_get_physical_ref(broker, i, list);
+                } else {
+                        CU_DEBUG("VCPU %i not pinned to physical %i",
+                                 vcpu, i);
+                }
+        }
+ out:
+        free(vinfo);
+        free(cpumaps);
+
+        return 0;
+}
+
+static CMPIStatus proc_rasd_from_vdev(const CMPIBroker *broker,
+                                      struct virt_device *dev,
+                                      const char *host,
+                                      const CMPIObjectPath *ref,
+                                      CMPIInstance *inst)
+{
+        virConnectPtr conn = NULL;
+        virDomainPtr dom = NULL;
+        virNodeInfo node;
+        CMPIStatus s;
+        CMPIArray *array;
+        struct inst_list list;
+
+        inst_list_init(&list);
+
+        conn = connect_by_classname(broker, CLASSNAME(ref), &s);
+        if (conn == NULL) {
+                cu_statusf(broker, &s,
+                           CMPI_RC_ERR_FAILED,
+                           "Failed to connect for ProcRASD (%s)",
+                           CLASSNAME(ref));
+                goto out;
+        }
+
+        dom = virDomainLookupByName(conn, host);
+        if (dom == NULL) {
+                cu_statusf(broker, &s,
+                           CMPI_RC_ERR_NOT_FOUND,
+                           "Unable to get domain for ProcRASD: %s", host);
+                goto out;
+        }
+
+        if (virNodeGetInfo(virDomainGetConnect(dom), &node) == -1) {
+                cu_statusf(broker, &s,
+                           CMPI_RC_ERR_FAILED,
+                           "Unable to get node info");
+                goto out;
+        }
+
+        proc_set_cpu(broker, &node, dom, dev, &list);
+
+        if (list.cur > 0) {
+                int i;
+
+                array = CMNewArray(broker,
+                                   list.cur,
+                                   CMPI_instance,
+                                   &s);
+                for (i = 0; i < list.cur; i++) {
+                        CMSetArrayElementAt(array,
+                                            i,
+                                            (CMPIValue *)&list.list[i],
+                                            CMPI_instance);
+                }
+
+                CMSetProperty(inst, "HostResource",
+                              (CMPIValue *)&array, CMPI_instanceA);
+        }
+
+ out:
+        inst_list_free(&list);
+        virDomainFree(dom);
+        virConnectClose(conn);
+
+        return s;
 }
 
 static CMPIInstance *rasd_from_vdev(const CMPIBroker *broker,
@@ -159,6 +349,8 @@ static CMPIInstance *rasd_from_vdev(cons
                               (CMPIValue *)&dev->dev.mem.size, CMPI_uint64);
                 CMSetProperty(inst, "Limit",
                               (CMPIValue *)&dev->dev.mem.maxsize, CMPI_uint64);
+        } else if (dev->type == VIRT_DEV_VCPU) {
+                proc_rasd_from_vdev(broker, dev, host, ref, inst);
         }
 
         /* FIXME: Put the HostResource in place */




More information about the Libvirt-cim mailing list