os-cmpi-xen

view src/Xen_Disk.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 27a7e302adf7
children 28e8c94e92de
line source
1 // Copyright (C) 2007 Novell, Inc.
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 // Description: A class used to represent a Xen virtual block device (vbd).
21 //
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>
40 #include <xen_common.h>
41 #include <xen_vm.h>
42 #include <xen_vbd.h>
43 #include <xen_vdi.h>
44 #include <xen_string_string_map.h>
45 #include <xen_vm_power_state.h>
47 #include "cmpitrace.h"
48 #include "xen_utils.h"
49 #include "provider_common.h"
52 /* C struct to store the data for all resources. */
53 typedef struct {
54 xen_vbd_set *disks;
55 unsigned int currentdisknum;
56 } _RESOURCES;
59 /* Xen session object. Initialize when the provider is loaded, close when
60 * provider unloaded. */
61 static xen_utils_session *session = NULL;
64 static int load()
65 {
66 /* Initialized Xen session object. */
67 if (!session)
68 xen_utils_xen_init(&session);
70 return 1;
71 }
74 static int unload(CMPIBoolean terminating)
75 {
76 (void) terminating;
78 if (session) {
79 xen_utils_xen_close(session);
80 session = NULL;
81 }
83 return 1;
84 }
87 static int beginEnum(void **res_list, CMPIStatus *status)
88 {
89 _RESOURCES *resources;
90 xen_domain_resources *res = NULL;
91 xen_vbd_set *all_disks = NULL;
92 xen_vm_record *vm_rec = NULL;
94 if (res_list == NULL)
95 return 0;
97 resources = (_RESOURCES *)calloc(1, sizeof(_RESOURCES));
98 if (resources == NULL)
99 return 0;
101 if (!xen_utils_validate_session(&session)) {
102 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
103 ("--- Unable to establish connection with Xend"));
104 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
105 "Unable to establish connection with Xend");
106 return 0;
107 }
109 /* Get a list of domain resources. */
110 if (!xen_utils_get_domain_resources(session, &res))
111 goto Error;
113 /* Create list of disk resources from disks found in each domain. */
114 while (xen_utils_get_next_domain_resource(session, res, &vm_rec)) {
115 /* Ignore halted vms */
116 if (vm_rec->power_state == XEN_VM_POWER_STATE_HALTED) {
117 xen_vm_record_free(vm_rec);
118 continue;
119 }
121 xen_vbd_set *vbd_set;
122 if (!xen_vm_get_vbds(session->xen, &vbd_set, vm_rec->handle))
123 goto Error;
125 if (!xen_vbd_set_concat(&all_disks, vbd_set))
126 goto Error;
128 xen_vm_record_free(vm_rec);
129 }
131 xen_utils_free_domain_resources(res);
133 resources->disks = all_disks;
134 resources->currentdisknum = 0;
136 *res_list = (void *)resources;
137 return 1;
139 Error:
140 if (session && session->xen) {
141 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
142 ("--- failed to retrieve vbd resources from Xend:"));
143 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
144 xen_utils_trace_error(session->xen));
145 }
147 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
148 "Failed to retrieve vbd resources from Xend");
150 xen_vm_record_free(vm_rec);
151 xen_utils_free_domain_resources(res);
152 free(resources);
153 return 0;
154 }
157 static void endEnum(void *res_list)
158 {
159 _RESOURCES *resources = (_RESOURCES *)res_list;
161 if (resources) {
162 if (resources->disks)
163 xen_vbd_set_free(resources->disks);
164 free(resources);
165 }
166 }
169 static int getNext(void *res_list, void **res, CMPIStatus *status)
170 {
171 _RESOURCES *resources = (_RESOURCES *)res_list;
172 xen_vbd_record *vbd_rec;
174 if (resources == NULL || resources->disks == NULL || res == NULL)
175 return 0;
177 /* Check if reached the end of the list of disks. */
178 if (resources->currentdisknum == resources->disks->size)
179 return 0;
181 if (!xen_utils_validate_session(&session)) {
182 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
183 ("--- Unable to establish connection with Xend"));
184 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
185 "Unable to establish connection with Xend");
186 return 0;
187 }
189 /* Get the current disk record. */
190 if (!xen_vbd_get_record(session->xen, &vbd_rec,
191 resources->disks->contents[resources->currentdisknum])) {
192 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
193 ("--- failed to retrieve vbd resources from Xend:"));
194 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
195 xen_utils_trace_error(session->xen));
196 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
197 "Failed to retrieve vbd resource from Xend");
198 return 0;
199 }
201 resources->currentdisknum++;
202 *res = (void *)vbd_rec;
203 return 1;
204 }
207 static int get(void *res_list, void **res, CMPIStatus *status)
208 {
209 if (res == NULL || *res == NULL)
210 return 0;
211 /*
212 * WARNING!
213 * What needs to be done here? It looks as though inst2res() will have
214 * been called on parameter res before a call to this function - in
215 * which case res will be populated.
216 */
217 return 1;
218 }
221 static void release(void *res)
222 {
223 xen_vbd_record_free(res);
224 }
227 static int add(void **res_list, void *res, CMPIStatus *status)
228 {
229 xen_vbd_record *new_vbd_rec = (xen_vbd_record *)res;
231 (void)res_list;
233 if (new_vbd_rec == NULL || new_vbd_rec->vm == NULL)
234 return 0;
236 if (!xen_utils_validate_session(&session)) {
237 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
238 ("--- Unable to establish connection with Xend"));
239 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
240 "Unable to establish connection with Xend");
241 return 0;
242 }
244 xen_vbd new_vbd;
245 if (!xen_vbd_create(session->xen, &new_vbd, new_vbd_rec)) {
246 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
247 ("--- xen_vbd_create failed:"));
248 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
249 xen_utils_trace_error(session->xen));
250 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
251 "xen_vbd_create failed");
252 return 0;
253 }
255 xen_vbd_free(new_vbd);
256 return 1;
257 }
260 static int delete(void **res_list, void *res, CMPIStatus *status)
261 {
262 xen_vbd_record *vbd_rec = (xen_vbd_record *)res;
264 (void)res_list;
266 if (vbd_rec == NULL)
267 return 0;
269 if (!xen_utils_validate_session(&session)) {
270 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
271 ("--- Unable to establish connection with Xend"));
272 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
273 "Unable to establish connection with Xend");
274 return 0;
275 }
277 if (!xen_vbd_destroy(session->xen, vbd_rec->handle)) {
278 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
279 ("--- xen_vbd_create failed:"));
280 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
281 xen_utils_trace_error(session->xen));
282 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
283 "xen_vbd_destroy failed");
284 return 0;
285 }
287 return 1;
288 }
291 static int modify(void **res_list, void *res, CMPIStatus *status)
292 {
293 return -1; /* unsupported */
294 }
297 /* Set CMPIInstance properties from the resource data. */
298 static int res2inst(void *res, CMPIInstance *inst, CMPIStatus *status)
299 {
300 xen_vm_record *alloced_vm_rec = NULL;
301 xen_vm_record *vm_rec;
302 xen_vbd_record *vbd_rec = (xen_vbd_record *)res;
303 char buf[MAX_INSTANCEID_LEN];
305 if (vbd_rec == NULL || CMIsNullObject(inst))
306 return 0;
308 if (!xen_utils_validate_session(&session)) {
309 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
310 ("--- Unable to establish connection with Xend"));
311 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
312 "Unable to establish connection with Xend");
313 return 0;
314 }
316 xen_vm_record_opt *vm_rec_opt = vbd_rec->vm;
317 if (vm_rec_opt->is_record) {
318 vm_rec = vm_rec_opt->u.record;
319 }
320 else {
321 if (!xen_vm_get_record(session->xen, &vm_rec, vm_rec_opt->u.handle)) {
322 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
323 ("--- xen_vm_get_record failed:"));
324 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
325 xen_utils_trace_error(session->xen));
326 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
327 "xen_vm_get_record failed");
328 return 0;
329 }
330 alloced_vm_rec = vm_rec;
331 }
333 CMSetProperty(inst, "SystemCreationClassName",
334 (CMPIValue *)"Xen_ComputerSystem", CMPI_chars);
335 CMSetProperty(inst, "SystemName",
336 (CMPIValue *)vm_rec->name_label, CMPI_chars);
337 CMSetProperty(inst, "CreationClassName",
338 (CMPIValue *)"Xen_Disk", CMPI_chars);
339 CMSetProperty(inst, "DeviceID",
340 (CMPIValue *)vbd_rec->uuid, CMPI_chars);
341 CMSetProperty(inst, "Caption",
342 (CMPIValue *)"Disk", CMPI_chars);
343 CMSetProperty(inst, "Description",
344 (CMPIValue *)"Xen Virtual Disk", CMPI_chars);
345 CMSetProperty(inst, "Purpose",
346 (CMPIValue *)"Virtual Disk for Xen Domain", CMPI_chars);
347 CMSetProperty(inst, "Name",
348 (CMPIValue *)vbd_rec->device, CMPI_chars);
349 CMSetProperty(inst, "DeviceName",
350 (CMPIValue *)vbd_rec->device, CMPI_chars);
352 char *mode;
353 int access;
354 if (vbd_rec->mode == XEN_VBD_MODE_RW) {
355 mode = "w";
356 access = 3;
357 }
358 else {
359 mode = "r";
360 access = 1;
361 }
363 CMSetProperty(inst, "Mode",(CMPIValue *)mode, CMPI_chars);
364 CMSetProperty(inst, "Access",(CMPIValue *)&access, CMPI_uint16);
366 xen_vdi_record_opt *vdi_rec_opt = vbd_rec->vdi;
367 char *image;
368 xen_string_string_map *vdi_params = NULL;
369 if (xen_vdi_get_other_config(session->xen, &vdi_params, vdi_rec_opt->u.handle)) {
370 if ((image = xen_utils_get_value_from_map(vdi_params, "location"))) {
371 CMSetProperty(inst, "Device",(CMPIValue *)image, CMPI_chars);
372 snprintf(buf, MAX_INSTANCEID_LEN, "%s,%s,%s",
373 image, vbd_rec->device, mode);
374 CMSetProperty(inst, "DiskConfigInfo",(CMPIValue *)buf, CMPI_chars);
375 }
376 }
378 xen_string_string_map_free(vdi_params);
380 if (vm_rec->power_state != XEN_VM_POWER_STATE_HALTED) {
381 CMSetProperty(inst, "Status", (CMPIValue *)"OK", CMPI_chars);
382 } else {
383 CMSetProperty(inst, "Status", (CMPIValue *)"No Contact", CMPI_chars);
384 }
386 if (alloced_vm_rec)
387 xen_vm_record_free(alloced_vm_rec);
389 return 1;
390 }
393 /* Set resource data from the CMPIInstance properties. */
394 static int inst2res(CMPIInstance *inst, void **res, CMPIStatus *status)
395 {
396 CMPIData data;
397 char *dev_uuid;
398 char uuid[MAX_SYSTEM_NAME_LEN];
399 int ccode;
401 if (CMIsNullObject(inst) || res == NULL)
402 return 0;
404 data = CMGetProperty(inst, "DeviceID", status);
405 if ((status->rc != CMPI_RC_OK) || CMIsNullValue(data))
406 return 0;
408 dev_uuid = CMGetCharPtr(data.value.string);
409 if ((dev_uuid == NULL) || (*dev_uuid == '\0'))
410 return 0;
412 if (!xen_utils_validate_session(&session)) {
413 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
414 ("--- Unable to establish connection with Xend"));
415 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
416 "Unable to establish connection with Xend");
417 return 0;
418 }
420 xen_vbd_record *vbd_rec;
421 if (!xen_vbd_get_record(session->xen, &vbd_rec, (xen_vbd)dev_uuid)) {
422 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
423 ("--- xen_vbd_get_record failed:"));
424 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
425 xen_utils_trace_error(session->xen));
426 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
427 "xen_vbd_get_record failed");
428 return 0;
429 }
431 /* TODO:
432 * For now Xen_Disk instances only exist when domain is not inactive,
433 * so return NOT_FOUND.
434 * Should disks be one of the few logical devices that do exist even
435 * when domain is inactive?
436 */
437 enum xen_vm_power_state pstate;
438 if (!xen_vm_get_power_state(session->xen, &pstate, vbd_rec->vm->u.handle)) {
439 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
440 ("--- xen_vm_get_power_state failed:"));
441 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
442 xen_utils_trace_error(session->xen));
443 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
444 "Unable to determine vm power state");
445 xen_vbd_record_free(vbd_rec);
447 return 0;
448 }
450 if (pstate == XEN_VM_POWER_STATE_HALTED) {
451 CMSetStatus(status, CMPI_RC_ERR_NOT_FOUND);
452 xen_vbd_record_free(vbd_rec);
453 return 0;
454 }
456 *res = (void *)vbd_rec;
457 return 1;
458 }
461 /* Setup the CMPILR function tables and CMPILR instance provider entry point.*/
462 /* CMPILRInstanceMIStub(<CLASS_NAME>,<PROVIDER_NAME>,<CMPIInstanceMI_HANDLE>) */
463 CMPILRInstanceMIStub(Xen_Disk, Xen_Disk, mi)