os-cmpi-xen

view src/Xen_Disk.c @ 109:64e363d418df

Minor changes to cmpilr interface:
- Propogated CMPIStatus structure through to resource files in cmpilr.[ch]
- Functions in cmpilr function table now return int and any data in
caller-provided pointer

This allows functions such as CMPILR_enumInstanceNames to return success when
no instances exist - instead of an exception which will terminate any
enumInstanceNames call chain from originated on superclass.

Updated providers to changes in cmpilr interface.

Signed-off-by: Jim Fehlig <jfehlig@novell.com>
author Jim Fehlig <jfehlig@novell.com>
date Fri May 11 17:17:46 2007 -0600 (2007-05-11)
parents 1ada37af7d08
children 27a7e302adf7
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 resources->disks = all_disks;
132 resources->currentdisknum = 0;
134 *res_list = (void *)resources;
135 return 1;
137 Error:
138 if (session && session->xen) {
139 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
140 ("--- failed to retrieve vbd resources from Xend:"));
141 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
142 xen_utils_trace_error(session->xen));
143 }
145 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
146 "Failed to retrieve vbd resources from Xend");
148 xen_vm_record_free(vm_rec);
149 xen_utils_free_domain_resources(res);
150 free(resources);
151 return 0;
152 }
155 static void endEnum(void *res_list)
156 {
157 _RESOURCES *resources = (_RESOURCES *)res_list;
159 if (resources) {
160 if (resources->disks)
161 xen_vbd_set_free(resources->disks);
162 free(resources);
163 }
164 }
167 static int getNext(void *res_list, void **res, CMPIStatus *status)
168 {
169 _RESOURCES *resources = (_RESOURCES *)res_list;
170 xen_vbd_record *vbd_rec;
172 if (resources == NULL || resources->disks == NULL || res == NULL)
173 return 0;
175 /* Check if reached the end of the list of disks. */
176 if (resources->currentdisknum == resources->disks->size)
177 return 0;
179 if (!xen_utils_validate_session(&session)) {
180 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
181 ("--- Unable to establish connection with Xend"));
182 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
183 "Unable to establish connection with Xend");
184 return 0;
185 }
187 /* Get the current disk record. */
188 if (!xen_vbd_get_record(session->xen, &vbd_rec,
189 resources->disks->contents[resources->currentdisknum])) {
190 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
191 ("--- failed to retrieve vbd resources from Xend:"));
192 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
193 xen_utils_trace_error(session->xen));
194 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
195 "Failed to retrieve vbd resource from Xend");
196 return 0;
197 }
199 resources->currentdisknum++;
200 *res = (void *)vbd_rec;
201 return 1;
202 }
205 static int get(void *res_list, void **res, CMPIStatus *status)
206 {
207 if (res == NULL || *res == NULL)
208 return 0;
209 /*
210 * WARNING!
211 * What needs to be done here? It looks as though inst2res() will have
212 * been called on parameter res before a call to this function - in
213 * which case res will be populated.
214 */
215 return 1;
216 }
219 static void release(void *res)
220 {
221 xen_vbd_record_free(res);
222 }
225 static int add(void **res_list, void *res, CMPIStatus *status)
226 {
227 xen_vbd_record *new_vbd_rec = (xen_vbd_record *)res;
229 (void)res_list;
231 if (new_vbd_rec == NULL || new_vbd_rec->vm == NULL)
232 return 0;
234 if (!xen_utils_validate_session(&session)) {
235 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
236 ("--- Unable to establish connection with Xend"));
237 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
238 "Unable to establish connection with Xend");
239 return 0;
240 }
242 xen_vbd new_vbd;
243 if (!xen_vbd_create(session->xen, &new_vbd, new_vbd_rec)) {
244 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
245 ("--- xen_vbd_create failed:"));
246 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
247 xen_utils_trace_error(session->xen));
248 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
249 "xen_vbd_create failed");
250 return 0;
251 }
253 xen_vbd_free(new_vbd);
254 return 1;
255 }
258 static int delete(void **res_list, void *res, CMPIStatus *status)
259 {
260 xen_vbd_record *vbd_rec = (xen_vbd_record *)res;
262 (void)res_list;
264 if (vbd_rec == NULL)
265 return 0;
267 if (!xen_utils_validate_session(&session)) {
268 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
269 ("--- Unable to establish connection with Xend"));
270 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
271 "Unable to establish connection with Xend");
272 return 0;
273 }
275 if (!xen_vbd_destroy(session->xen, vbd_rec->handle)) {
276 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
277 ("--- xen_vbd_create failed:"));
278 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
279 xen_utils_trace_error(session->xen));
280 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
281 "xen_vbd_destroy failed");
282 return 0;
283 }
285 return 1;
286 }
289 static int modify(void **res_list, void *res, CMPIStatus *status)
290 {
291 return -1; /* unsupported */
292 }
295 /* Set CMPIInstance properties from the resource data. */
296 static int res2inst(void *res, CMPIInstance *inst, CMPIStatus *status)
297 {
298 xen_vm_record *alloced_vm_rec = NULL;
299 xen_vm_record *vm_rec;
300 xen_vbd_record *vbd_rec = (xen_vbd_record *)res;
301 char buf[MAX_INSTANCEID_LEN];
303 if (vbd_rec == NULL || CMIsNullObject(inst))
304 return 0;
306 if (!xen_utils_validate_session(&session)) {
307 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
308 ("--- Unable to establish connection with Xend"));
309 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
310 "Unable to establish connection with Xend");
311 return 0;
312 }
314 xen_vm_record_opt *vm_rec_opt = vbd_rec->vm;
315 if (vm_rec_opt->is_record) {
316 vm_rec = vm_rec_opt->u.record;
317 }
318 else {
319 if (!xen_vm_get_record(session->xen, &vm_rec, vm_rec_opt->u.handle)) {
320 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
321 ("--- xen_vm_get_record failed:"));
322 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
323 xen_utils_trace_error(session->xen));
324 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
325 "xen_vm_get_record failed");
326 return 0;
327 }
328 alloced_vm_rec = vm_rec;
329 }
331 CMSetProperty(inst, "SystemCreationClassName",
332 (CMPIValue *)"Xen_ComputerSystem", CMPI_chars);
333 CMSetProperty(inst, "SystemName",
334 (CMPIValue *)vm_rec->name_label, CMPI_chars);
335 CMSetProperty(inst, "CreationClassName",
336 (CMPIValue *)"Xen_Disk", CMPI_chars);
337 CMSetProperty(inst, "DeviceID",
338 (CMPIValue *)vbd_rec->uuid, CMPI_chars);
339 CMSetProperty(inst, "Caption",
340 (CMPIValue *)"Disk", CMPI_chars);
341 CMSetProperty(inst, "Description",
342 (CMPIValue *)"Xen Virtual Disk", CMPI_chars);
343 CMSetProperty(inst, "Purpose",
344 (CMPIValue *)"Virtual Disk for Xen Domain", CMPI_chars);
345 CMSetProperty(inst, "Name",
346 (CMPIValue *)vbd_rec->device, CMPI_chars);
347 CMSetProperty(inst, "DeviceName",
348 (CMPIValue *)vbd_rec->device, CMPI_chars);
350 char *mode;
351 int access;
352 if (vbd_rec->mode == XEN_VBD_MODE_RW) {
353 mode = "w";
354 access = 3;
355 }
356 else {
357 mode = "r";
358 access = 1;
359 }
361 CMSetProperty(inst, "Mode",(CMPIValue *)mode, CMPI_chars);
362 CMSetProperty(inst, "Access",(CMPIValue *)&access, CMPI_uint16);
364 xen_vdi_record_opt *vdi_rec_opt = vbd_rec->vdi;
365 char *image;
366 xen_string_string_map *vdi_params = NULL;
367 if (xen_vdi_get_other_config(session->xen, &vdi_params, vdi_rec_opt->u.handle)) {
368 if ((image = xen_utils_get_value_from_map(vdi_params, "location"))) {
369 CMSetProperty(inst, "Device",(CMPIValue *)image, CMPI_chars);
370 snprintf(buf, MAX_INSTANCEID_LEN, "%s,%s,%s",
371 image, vbd_rec->device, mode);
372 CMSetProperty(inst, "DiskConfigInfo",(CMPIValue *)buf, CMPI_chars);
373 }
374 }
376 xen_string_string_map_free(vdi_params);
378 if (vm_rec->power_state != XEN_VM_POWER_STATE_HALTED) {
379 CMSetProperty(inst, "Status", (CMPIValue *)"OK", CMPI_chars);
380 } else {
381 CMSetProperty(inst, "Status", (CMPIValue *)"No Contact", CMPI_chars);
382 }
384 if (alloced_vm_rec)
385 xen_vm_record_free(alloced_vm_rec);
387 return 1;
388 }
391 /* Set resource data from the CMPIInstance properties. */
392 static int inst2res(CMPIInstance *inst, void **res, CMPIStatus *status)
393 {
394 CMPIData data;
395 char *dev_uuid;
396 char uuid[MAX_SYSTEM_NAME_LEN];
397 int ccode;
399 if (CMIsNullObject(inst) || res == NULL)
400 return 0;
402 data = CMGetProperty(inst, "DeviceID", status);
403 if ((status->rc != CMPI_RC_OK) || CMIsNullValue(data))
404 return 0;
406 dev_uuid = CMGetCharPtr(data.value.string);
407 if ((dev_uuid == NULL) || (*dev_uuid == '\0'))
408 return 0;
410 if (!xen_utils_validate_session(&session)) {
411 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
412 ("--- Unable to establish connection with Xend"));
413 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
414 "Unable to establish connection with Xend");
415 return 0;
416 }
418 xen_vbd_record *vbd_rec;
419 if (!xen_vbd_get_record(session->xen, &vbd_rec, (xen_vbd)dev_uuid)) {
420 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
421 ("--- xen_vbd_get_record failed:"));
422 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
423 xen_utils_trace_error(session->xen));
424 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
425 "xen_vbd_get_record failed");
426 return 0;
427 }
429 /* TODO:
430 * For now Xen_Disk instances only exist when domain is not inactive,
431 * so return NOT_FOUND.
432 * Should disks be one of the few logical devices that do exist even
433 * when domain is inactive?
434 */
435 enum xen_vm_power_state pstate;
436 if (!xen_vm_get_power_state(session->xen, &pstate, vbd_rec->vm->u.handle)) {
437 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
438 ("--- xen_vm_get_power_state failed:"));
439 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
440 xen_utils_trace_error(session->xen));
441 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
442 "Unable to determine vm power state");
443 xen_vbd_record_free(vbd_rec);
445 return 0;
446 }
448 if (pstate == XEN_VM_POWER_STATE_HALTED) {
449 CMSetStatus(status, CMPI_RC_ERR_NOT_FOUND);
450 xen_vbd_record_free(vbd_rec);
451 return 0;
452 }
454 *res = (void *)vbd_rec;
455 return 1;
456 }
459 /* Setup the CMPILR function tables and CMPILR instance provider entry point.*/
460 /* CMPILRInstanceMIStub(<CLASS_NAME>,<PROVIDER_NAME>,<CMPIInstanceMI_HANDLE>) */
461 CMPILRInstanceMIStub(Xen_Disk, Xen_Disk, mi)