os-cmpi-xen

view src/Xen_DiskSettingData.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 69ad830f2a6e
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: Jim Fehlig, <jfehlig@novell.com>
18 // Contributors:
19 // Description: A class used to represent the settings of Xen virtual
20 // block device (vbd). The settings are available for
21 // inspection/manipulation regardless of domain state.
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>
46 #include "cmpitrace.h"
47 #include "xen_utils.h"
48 #include "provider_common.h"
51 /* C struct to store the data for all resources. */
52 typedef struct {
53 xen_vbd_set *disks;
54 unsigned int currentdisknum;
55 } _RESOURCES;
58 /* Xen session object. Initialize when the provider is loaded, close when
59 * provider unloaded. */
60 static xen_utils_session *session = NULL;
63 static int load()
64 {
65 /* Initialized Xen session object. */
66 if (!session)
67 xen_utils_xen_init(&session);
69 return 1;
70 }
73 static int unload(CMPIBoolean terminating)
74 {
75 (void) terminating;
77 if (session) {
78 xen_utils_xen_close(session);
79 session = NULL;
80 }
82 return 1;
83 }
86 static int beginEnum(void **res_list, CMPIStatus *status)
87 {
88 _RESOURCES *resources;
89 xen_domain_resources *res = NULL;
90 xen_vbd_set *all_disks = NULL;
91 xen_vm_record *vm_rec = NULL;
93 resources = (_RESOURCES *)calloc(1, sizeof(_RESOURCES));
94 if (resources == NULL)
95 return 0;
97 if (!xen_utils_validate_session(&session)) {
98 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
99 ("--- Unable to establish connection with Xend"));
100 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
101 "Unable to establish connection with Xend");
102 return 0;
103 }
105 /* Get a list of domain resources. */
106 if (!xen_utils_get_domain_resources(session, &res))
107 goto Error;
109 /* Create list of disk resources from disks found in each domain. */
110 while (xen_utils_get_next_domain_resource(session, res, &vm_rec)) {
111 xen_vbd_set *vbd_set;
112 if (!xen_vm_get_vbds(session->xen, &vbd_set, vm_rec->handle))
113 goto Error;
115 if (!xen_vbd_set_concat(&all_disks, vbd_set))
116 goto Error;
118 xen_vm_record_free(vm_rec);
119 }
121 resources->disks = all_disks;
122 resources->currentdisknum = 0;
124 *res_list = (void *)resources;
125 return 1;
127 Error:
128 if (session && session->xen) {
129 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
130 ("--- failed to retrieve vbd resource from Xend:"));
131 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
132 xen_utils_trace_error(session->xen));
133 }
135 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
136 "Failed to retrieve vbd resources from Xend");
138 xen_vm_record_free(vm_rec);
139 xen_utils_free_domain_resources(res);
140 free(resources);
141 return 0;
142 }
145 static void endEnum(void *res_list)
146 {
147 _RESOURCES *resources = (_RESOURCES *)res_list;
149 if (resources) {
150 if (resources->disks)
151 xen_vbd_set_free(resources->disks);
152 free(resources);
153 }
154 }
157 static int getNext(void *res_list, void **res, CMPIStatus *status)
158 {
159 _RESOURCES *resources = (_RESOURCES *)res_list;
160 xen_vbd_record *vbd_rec;
162 if (resources == NULL || resources->disks == NULL)
163 return 0;
165 /* Check if reached the end of the list of disks. */
166 if (resources->currentdisknum == resources->disks->size)
167 return 0;
169 if (!xen_utils_validate_session(&session)) {
170 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
171 ("--- Unable to establish connection with Xend"));
172 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
173 "Unable to establish connection with Xend");
174 return 0;
175 }
177 /* Get the current disk record. */
178 if (!xen_vbd_get_record(session->xen, &vbd_rec,
179 resources->disks->contents[resources->currentdisknum])) {
180 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
181 ("--- failed to retrieve vbd resource from Xend:"));
182 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
183 xen_utils_trace_error(session->xen));
184 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
185 "Failed to retrieve vbd resource from Xend");
186 return 0;
187 }
189 resources->currentdisknum++;
190 *res = (void *)vbd_rec;
191 return 1;
192 }
195 static int get(void *res_list, void **res, CMPIStatus *status)
196 {
197 if (res == NULL || *res == NULL)
198 return 0;
199 /*
200 * WARNING!
201 * What needs to be done here? It looks as though inst2res() will have
202 * been called on parameter res before a call to this function - in
203 * which case res will be populated.
204 */
205 return 1;
206 }
209 static void release(void *res)
210 {
211 xen_vbd_record_free(res);
212 }
215 static int add(void **res_list, void *res, CMPIStatus *status)
216 {
217 xen_vbd_record *new_vbd_rec = (xen_vbd_record *)res;
219 (void)res_list;
221 if (new_vbd_rec == NULL || new_vbd_rec->vm == NULL)
222 return 0;
224 if (!xen_utils_validate_session(&session)) {
225 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
226 ("--- Unable to establish connection with Xend"));
227 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
228 "Unable to establish connection with Xend");
229 return 0;
230 }
232 xen_vbd new_vbd;
233 if (!xen_vbd_create(session->xen, &new_vbd, new_vbd_rec)) {
234 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
235 ("--- xen_vbd_create failed:"));
236 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
237 xen_utils_trace_error(session->xen));
238 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
239 "xen_vbd_create failed");
240 return 0;
241 }
243 xen_vbd_free(new_vbd);
244 return 1;
245 }
248 static int delete(void **res_list, void *res, CMPIStatus *status)
249 {
250 xen_vbd_record *vbd_rec = (xen_vbd_record *)res;
252 (void)res_list;
254 if (vbd_rec == NULL)
255 return 0;
257 if (!xen_utils_validate_session(&session)) {
258 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
259 ("--- Unable to establish connection with Xend"));
260 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
261 "Unable to establish connection with Xend");
262 return 0;
263 }
265 if (!xen_vbd_destroy(session->xen, vbd_rec->handle)) {
266 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
267 ("--- xen_vbd_destroy failed:"));
268 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
269 xen_utils_trace_error(session->xen));
270 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
271 "xen_vbd_destroy failed");
272 return 0;
273 }
275 return 1;
276 }
279 static int modify(void **res_list, void *res, CMPIStatus *status)
280 {
281 return -1; /* unsupported */
282 }
285 /* Set CMPIInstance properties from the resource data. */
286 static int res2inst(void *res, CMPIInstance *inst, CMPIStatus *status)
287 {
288 xen_vbd_record *vbd_rec = (xen_vbd_record *)res;
289 char buf[MAX_INSTANCEID_LEN];
291 if (vbd_rec == NULL || CMIsNullObject(inst))
292 return 0;
294 if (!xen_utils_validate_session(&session)) {
295 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
296 ("--- Unable to establish connection with Xend"));
297 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
298 "Unable to establish connection with Xend");
299 return 0;
300 }
302 xen_vm_record_opt *vm_rec_opt = vbd_rec->vm;
303 if (vm_rec_opt->is_record) {
304 snprintf(buf, MAX_INSTANCEID_LEN, "Xen:%s:%s",
305 vm_rec_opt->u.record->name_label, vbd_rec->uuid);
306 }
307 else {
308 char *name = NULL;
310 if (!xen_vm_get_name_label(session->xen, &name, vm_rec_opt->u.handle))
311 return 0;
312 snprintf(buf, MAX_INSTANCEID_LEN, "Xen:%s:%s",
313 name, vbd_rec->uuid);
314 free(name);
315 }
317 /* Set the CMPIInstance properties from the resource data. */
318 CMSetProperty(inst, "InstanceID",(CMPIValue *)buf, CMPI_chars);
319 CMSetProperty(inst, "ElementName",(CMPIValue *)vbd_rec->device, CMPI_chars);
321 int type = 19; /* 19 == Storage Extent */
322 CMSetProperty(inst, "ResourceType",(CMPIValue *)&type, CMPI_uint16);
324 int virtualized = 3; /* 3 == Virtualized */
325 CMSetProperty(inst, "ConsumerVisibility" ,
326 (CMPIValue *)&virtualized, CMPI_uint16);
328 /*
329 * TODO: Need to figure this out. May have to adhoc some up and
330 * coming virtual storage-related profile.
331 */
332 unsigned long long disks = 1;
333 CMSetProperty(inst, "Reservation",(CMPIValue *)&disks, CMPI_uint64);
334 CMSetProperty(inst, "Limit",(CMPIValue *)&disks, CMPI_uint64);
335 CMSetProperty(inst, "AllocationUnits",(CMPIValue *)"Blocks", CMPI_chars);
336 CMSetProperty(inst, "VirtualQuantity",(CMPIValue *)&disks, CMPI_uint64);
338 int alloctype = 1;
339 CMSetProperty(inst, "AutomaticAllocation" ,
340 (CMPIValue *)&alloctype, CMPI_boolean);
341 CMSetProperty(inst, "AutomaticDeallocation" ,
342 (CMPIValue *)&alloctype, CMPI_boolean);
344 char *mode;
345 if (vbd_rec->mode == XEN_VBD_MODE_RW)
346 mode = "w";
347 else
348 mode = "r";
350 xen_vdi_record_opt *vdi_rec_opt = vbd_rec->vdi;
351 char *image;
352 xen_string_string_map *vdi_params = NULL;
353 if (xen_vdi_get_other_config(session->xen, &vdi_params, vdi_rec_opt->u.handle)) {
354 if ((image = xen_utils_get_value_from_map(vdi_params, "location"))) {
355 snprintf(buf, MAX_INSTANCEID_LEN, "%s,%s,%s",
356 image, vbd_rec->device, mode);
357 CMSetProperty(inst, "DiskConfigInfo",(CMPIValue *)buf, CMPI_chars);
358 }
359 }
361 xen_string_string_map_free(vdi_params);
363 /*
364 * TODO:
365 * PoolID, Weight, HostResource (mapped device in dom0)
366 */
368 return 1;
369 }
372 /* Set resource data from the CMPIInstance properties. */
373 static int inst2res(CMPIInstance *inst, void **res, CMPIStatus *status)
374 {
375 CMPIData data;
376 char *inst_id;
377 char uuid[MAX_SYSTEM_NAME_LEN];
378 int ccode;
380 if (CMIsNullObject(inst) || res == NULL)
381 return 0;
383 data = CMGetProperty(inst, "InstanceID", status);
384 if ((status->rc != CMPI_RC_OK) || CMIsNullValue(data))
385 return 0;
387 inst_id = CMGetCharPtr(data.value.string);
388 if ((inst_id == NULL) || (*inst_id == '\0'))
389 return 0;
391 /* Extract the disk uuid from InstanceID property. */
392 if (!_CMPIStrncpyDeviceNameFromID(uuid, inst_id, MAX_SYSTEM_NAME_LEN))
393 return 0;
395 if (!xen_utils_validate_session(&session)) {
396 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
397 ("--- Unable to establish connection with Xend"));
398 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
399 "Unable to establish connection with Xend");
400 return 0;
401 }
403 if (!xen_vbd_get_record(session->xen, (xen_vbd_record **)res, (xen_vbd)uuid)) {
404 _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,
405 ("--- xen_vbd_get_record failed:"));
406 _SBLIM_TRACE_FUNCTION(_SBLIM_TRACE_LEVEL_ERROR,
407 xen_utils_trace_error(session->xen));
408 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED,
409 "xen_vbd_get_record failed");
410 return 0;
411 }
413 return 1;
414 }
417 /* Setup the CMPILR function tables and CMPILR instance provider entry point.*/
418 /* CMPILRInstanceMIStub(<CLASS_NAME>,<PROVIDER_NAME>,<CMPIInstanceMI_HANDLE>) */
419 CMPILRInstanceMIStub(Xen_DiskSettingData, Xen_DiskSettingData, mi)