os-cmpi-xen

view src/Xen_Processor.c @ 121:4868ace2726b

Add initial consistence checks in test suite for Xen_MemoryPool, Xen_ProcessorPool and Xen_VirtualSystemManagementService.

Signed-off-by: Luke Szymanski <Lukasz.Szymanski@Unisys.com>
author Jim Fehlig <jfehlig@novell.com>
date Fri Jun 08 10:22:05 2007 -0600 (2007-06-08)
parents 5a5f465c4191
children ce72210a88c6
line source
1 // Copyright (C) 2006 IBM Corporation
2 //
3 // This library is free software; you can redistribute it and/or
4 // modify it under the terms of the GNU Lesser General Public
5 // License as published by the Free Software Foundation; either
6 // version 2.1 of the License, or (at your option) any later version.
7 //
8 // This library is distributed in the hope that it will be useful,
9 // but WITHOUT ANY WARRANTY; without even the implied warranty of
10 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
11 // Lesser General Public License for more details.
12 //
13 // You should have received a copy of the GNU Lesser General Public
14 // License along with this library; if not, write to the Free Software
15 // Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
16 // ============================================================================
17 // Authors: Dr. Gareth S. Bestor, <bestor@us.ibm.com>
18 // Tokunbo Adeshiyan, <tokunbo@us.ibm.com>
19 // Contributors: Jim Fehlig, <jfehlig@novell.com>
20 // Raj Subrahmanian <raj.subrahmanian@unisys.com>
21 // Description:
22 // ============================================================================
24 /* Common declarations for each CMPI "Cimpler" instance provider */
25 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
26 #include "cmpidt.h"
27 #include "cmpimacs.h"
28 #include "cmpilr.h"
31 static const CMPIInstanceMI* mi;
34 #define _BROKER (((CMPIResource*)(mi->hdl))->brkr)
35 #define _CLASS (((CMPIResource*)(mi->hdl))->cn)
36 // <<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<<
38 #include <stdlib.h>
39 #include <assert.h>
41 #include <xen_common.h>
42 #include <xen_host.h>
43 #include <xen_vm.h>
44 #include <xen_vm_metrics.h>
46 #include "cmpitrace.h"
47 #include "xen_utils.h"
50 /* C struct to store data for a single resource. */
51 typedef struct _RESOURCE_S {
52 struct _RESOURCE_S *next;
53 unsigned int vcpu_id;
54 char *domain_name;
55 } _RESOURCE;
58 /* C struct to store the data for all resources. */
59 typedef struct {
60 _RESOURCE* vcpus;
61 _RESOURCE* cur_vcpu;
62 } _RESOURCES;
65 /* Xen session object. Initialize when the provider is loaded, close when
66 * provider unloaded. */
67 static xen_utils_session *session = NULL;
70 static int load()
71 {
72 /* Initialized Xen session object. */
73 if (!session)
74 xen_utils_xen_init(&session);
76 return 1;
77 }
80 static int unload(CMPIBoolean terminating)
81 {
82 (void) terminating;
84 if (session) {
85 xen_utils_xen_close(session);
86 session = NULL;
87 }
89 return 1;
90 }
93 static int beginEnum(void **res_list, CMPIStatus *status)
94 {
95 _RESOURCES *resources;
96 xen_vm_set *vms;
97 xen_vm_metrics vm_metrics;
98 xen_vm_record *vm_rec;
99 size_t vm_ndx;
100 int64_t vcpus_ndx;
102 if (!xen_utils_validate_session(&session)) {
103 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
104 ("--- Unable to establish connection with Xend"));
105 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
106 "Unable to establish connection with Xend");
107 return 0;
108 }
110 /* malloc a new handle for the resources list. */
111 resources = (_RESOURCES *)calloc(1, sizeof(_RESOURCES));
112 if (resources == NULL)
113 return 0;
115 if(!xen_host_get_resident_vms(session->xen, &vms, session->host)) {
116 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
117 ("--- Failed to retrieve list of domains from host"));
118 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
119 "Failed to retrieve list of domains from host");
120 free(resources);
121 return 0;
122 }
124 /*
125 * Iterate through domains. For those not halted, create a
126 * vcpu resource for each vcpu in use by the domain.
127 */
128 for (vm_ndx = 0; vm_ndx < vms->size; vm_ndx++) {
129 int64_t vcpus_number;
131 vm_rec = NULL;
132 vm_metrics = NULL;
133 if (!xen_vm_get_record(session->xen, &vm_rec, vms->contents[vm_ndx])) {
134 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
135 ("--- Failed to retrieve VM record from xend"));
136 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
137 "Failed to retrieve VM record from xend");
138 goto Error;
139 }
141 if (vm_rec->power_state == XEN_VM_POWER_STATE_HALTED) {
142 xen_vm_record_free(vm_rec);
143 continue;
144 }
146 xen_vm_get_metrics(session->xen, &vm_metrics, vms->contents[vm_ndx]);
147 xen_vm_metrics_get_vcpus_number(session->xen, &vcpus_number, vm_metrics);
148 if (!session->xen->ok) {
149 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
150 ("--- Failed to retrieve domain vcpu data from xend"));
151 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
152 "Failed to retrieve domain vcpu data from xend");
153 goto Error;
154 }
156 for (vcpus_ndx = 0; vcpus_ndx < vcpus_number; vcpus_ndx++) {
157 _RESOURCE *vcpu = (_RESOURCE *)calloc(1, sizeof(_RESOURCE));
158 if (vcpu == NULL )
159 goto Error;
161 vcpu->vcpu_id = vcpus_ndx;
162 vcpu->domain_name = strdup(vm_rec->name_label);
164 if (resources->vcpus == NULL)
165 resources->vcpus = vcpu;
166 else
167 resources->cur_vcpu->next = vcpu;
169 resources->cur_vcpu = vcpu;
170 }
172 xen_vm_record_free(vm_rec);
173 xen_vm_metrics_free(vm_metrics);
174 }
176 xen_vm_set_free(vms);
178 /* Set cur_vcpu to beginning of resource list. */
179 resources->cur_vcpu = resources->vcpus;
180 *res_list = (void *)resources;
181 return 1;
183 Error:
184 xen_vm_record_free(vm_rec);
185 xen_vm_metrics_free(vm_metrics);
186 xen_vm_set_free(vms);
187 free(resources);
188 return 0;
189 }
192 static void endEnum(void *res_list)
193 {
194 if (res_list) {
195 _RESOURCE *res = ((_RESOURCES *)res_list)->vcpus;
196 while (res) {
197 free(res->domain_name);
198 _RESOURCE *temp = res->next;
199 free(res);
200 res = temp;
201 }
202 free(res_list);
203 }
204 }
207 /* Iterator to get the next resource from the resources list. */
208 static int getNext(void *res_list, void **res, CMPIStatus *status)
209 {
210 _RESOURCES *resources = (_RESOURCES *)res_list;
211 _RESOURCE *resource;
213 if (resources == NULL)
214 return 0;
216 if (resources->cur_vcpu == NULL)
217 return 0;
219 /* A resource's life is independent of resources list. Make a copy. */
220 resource = (_RESOURCE *)malloc(sizeof(_RESOURCE));
221 if (resource == NULL) {
222 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
223 ("--- Failed to malloc memory for processor resource"));
224 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
225 "Failed to malloc memory for processor resource");
226 return 0;
227 }
229 resource->vcpu_id = resources->cur_vcpu->vcpu_id;
230 resource->domain_name = strdup(resources->cur_vcpu->domain_name);
232 /* Move to the next resource in the list. */
233 resources->cur_vcpu = resources->cur_vcpu->next;
235 *res = resource;
236 return 1;
237 }
240 static int get(void *res_list, void **res, CMPIStatus *status)
241 {
242 if (res == NULL || *res == NULL)
243 return 0;
244 /*
245 * WARNING!
246 * What needs to be done here? It looks as though inst2res() will have
247 * been called on parameter res before a call to this function - in
248 * which case res will be populated.
249 */
250 return 1;
251 }
254 static void release(void *res)
255 {
256 _RESOURCE *resource = (_RESOURCE *)res;
258 if (resource) {
259 if (resource->domain_name)
260 free(resource->domain_name);
261 free(resource);
262 }
263 }
266 static int add(void **res_list, void *res, CMPIStatus *status)
267 {
268 return -1; /* unsupported */
269 }
272 static int delete(void **res_list, void *res, CMPIStatus *status)
273 {
274 return -1; /* unsupported */
275 }
278 static int modify(void **res_list, void *res, CMPIStatus *status)
279 {
280 return -1; /* unsupported */
281 }
284 /* Set CMPIInstance properties from the resource data. */
285 static int res2inst(void *res, CMPIInstance *inst, CMPIStatus *status)
286 {
287 if (res == NULL)
288 return 0;
289 if (CMIsNullObject(inst))
290 return 0;
292 _RESOURCE *resource = (_RESOURCE *)res;
294 /* Set the CMPIInstance properties from the resource data. */
295 CMSetProperty(inst, "SystemCreationClassName",
296 (CMPIValue *)"Xen_ComputerSystem", CMPI_chars);
297 CMSetProperty(inst, "SystemName",
298 (CMPIValue *)resource->domain_name, CMPI_chars);
299 CMSetProperty(inst, "CreationClassName",
300 (CMPIValue *)"Xen_Processor", CMPI_chars);
302 char deviceid[1024];
303 sprintf(deviceid, "VCPU%d", resource->vcpu_id);
304 CMSetProperty(inst, "DeviceID",(CMPIValue *)deviceid, CMPI_chars);
306 CMSetProperty(inst, "Caption",(CMPIValue *)"Processor", CMPI_chars);
307 CMSetProperty(inst, "Description",
308 (CMPIValue *)"Xen Virtual Processor", CMPI_chars);
309 CMSetProperty(inst, "Purpose",(CMPIValue *)"Processor", CMPI_chars);
310 CMSetProperty(inst, "Name",(CMPIValue *)deviceid, CMPI_chars);
311 CMSetProperty(inst, "Status", (CMPIValue *)"OK", CMPI_chars);
313 return 1;
314 }
317 /* Set resource data from the CMPIInstance properties. */
318 static int inst2res(CMPIInstance *inst, void **res, CMPIStatus *status)
319 {
320 CMPIData data;
321 char *prop_val;
322 _RESOURCE *resource;
324 if (CMIsNullObject(inst) || res == NULL)
325 return 0;
327 /* Obtain the target domain name from instance's "SystemName" property. */
328 data = CMGetProperty(inst, "SystemName", status);
329 if ((status->rc != CMPI_RC_OK) || CMIsNullValue(data))
330 return 0;
332 prop_val = CMGetCharPtr(data.value.string);
333 if ((prop_val == NULL) || (*prop_val == '\0'))
334 return 0;
336 /* Create resource. */
337 resource = (_RESOURCE *)malloc(sizeof(_RESOURCE));
338 if (resource == NULL) {
339 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
340 ("--- Failed to malloc memory for processor resource"));
341 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
342 "Failed to malloc memory for processor resource");
343 return 0;
344 }
346 /* Populate domain_name and vcpu_id fields. */
347 resource->domain_name = strdup(prop_val);
349 /* Set the vcpu_id from the DeviceID */
350 data = CMGetProperty(inst, "DeviceID", status);
351 if ((status->rc != CMPI_RC_OK) || CMIsNullValue(data)) {
352 free(resource->domain_name);
353 free(resource);
354 return 0;
355 }
357 prop_val = CMGetCharPtr(data.value.string);
358 if ((prop_val == NULL) || (*prop_val == '\0')) {
359 free(resource->domain_name);
360 free(resource);
361 return 0;
362 }
364 char *p;
365 if ((p = strstr(prop_val, "VCPU")) == NULL) {
366 free(resource->domain_name);
367 free(resource);
368 return 0;
369 }
371 resource->vcpu_id = atoi(p + 4);
373 *res = (void *)resource;
374 return 1;
375 }
378 /* Setup the CMPILR function tables and CMPILR instance provider entry point.*/
379 /* CMPILRInstanceMIStub(<CLASS_NAME>,<PROVIDER_NAME>,<CMPIInstanceMI_HANDLE>) */
380 CMPILRInstanceMIStub(Xen_Processor, Xen_Processor, mi)