# HG changeset patch
# User Dan Smith <danms(a)us.ibm.com>
# Date 1202243439 28800
# Node ID e6d442b5bf122889708e9ad24545ae0b42b8c3bb
# Parent f8ee9b04d92abf1d74bf4c72fac1f3a4128923dd
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.
Signed-off-by: Dan Smith <danms(a)us.ibm.com>
diff -r f8ee9b04d92a -r e6d442b5bf12 src/Virt_RASD.c
--- a/src/Virt_RASD.c Tue Feb 05 13:37:51 2008 +0100
+++ b/src/Virt_RASD.c Tue Feb 05 12:30:39 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,158 @@ char *rasd_to_xml(CMPIInstance *rasd)
{
/* FIXME: Remove this */
return NULL;
+}
+
+static bool proc_set_physical_ref(const CMPIBroker *broker,
+ uint32_t physnum,
+ CMPIInstance *rasd)
+{
+ CMPIObjectPath *op = NULL;
+ CMPIStatus s;
+ char hostname[255];
+ char *devid = NULL;
+ CMPIArray *array;
+ 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;
+ }
+
+ array = CMNewArray(broker, 1, CMPI_instance, &s);
+ if ((array == NULL) || (s.rc != CMPI_RC_OK)) {
+ CU_DEBUG("Failed to make array");
+ goto out;
+ }
+
+ CMSetArrayElementAt(array, 0, (CMPIValue *)&inst, CMPI_instance);
+ CMSetProperty(rasd, "HostResource",
+ (CMPIValue *)&array, CMPI_instanceA);
+
+ result = true;
+ out:
+ free(devid);
+
+ return result;
+}
+
+static uint32_t proc_get_cpu(const CMPIBroker *broker,
+ virDomainPtr dom,
+ struct virt_device *dev)
+{
+ virVcpuInfoPtr vinfo = NULL;
+ virDomainInfo info;
+ int ret;
+ uint32_t cpu = -1;
+
+ 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;
+ }
+
+ ret = virDomainGetVcpus(dom, vinfo, info.nrVirtCpu, NULL, 0);
+ if (ret < info.nrVirtCpu) {
+ CU_DEBUG("Failed to get VCPU info for %s",
+ virDomainGetName(dom));
+ goto out;
+ }
+
+ cpu = vinfo[dev->dev.vcpu.number].cpu;
+
+ CU_DEBUG("VCPU %i is pinned to CPU %i",
+ dev->dev.vcpu.number,
+ cpu);
+ out:
+ free(vinfo);
+
+ return cpu;
+}
+
+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;
+ CMPIStatus s;
+ uint32_t pcpu;
+
+ 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;
+ }
+
+ pcpu = proc_get_cpu(broker, dom, dev);
+ if (pcpu >= 0)
+ proc_set_physical_ref(broker, pcpu, inst);
+
+ out:
+ virDomainFree(dom);
+ virConnectClose(conn);
+
+ return s;
}
static CMPIInstance *rasd_from_vdev(const CMPIBroker *broker,
@@ -159,6 +312,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 */