os-cmpi-xen

view src/Xen_VirtualSystemManagementService.c @ 92:66600aae1e53

Added support for receiving type CIMInstance for EmbeddedInstance method parameters.
OpenWBEM and sfcb cimoms now support providing CIMInstances - i.e. the cimoms
handle parsing the embedded instances. Support for parsing MOF-encoded string
remains for the time.

Signed-off-by: Jim Fehlig
author Jim Fehlig <jfehlig@novell.com>
date Fri Mar 09 16:52:35 2007 -0700 (2007-03-09)
parents 93600f4355d8
children 44127f60b2da
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 // Contributors: Jim Fehlig, <jfehlig@novell.com>
19 // Description:
20 // ============================================================================
22 /**
23 * TODO:
24 * 1. Currently not checking if incoming embedded settings are valid in
25 * the various extrinsic method code paths within InvokeMethod().
26 */
28 #include <string.h>
29 #include <stdio.h>
30 #include <unistd.h>
31 #include <assert.h>
33 #include <xen_vm.h>
34 #include <xen_vif.h>
35 #include <xen_vbd.h>
36 #include <xen_console.h>
37 #include <xen_string_string_map.h>
39 /* Include utility functions */
40 #include "cmpiutil.h"
42 /* Include _SBLIM_TRACE() logging support */
43 #include "cmpitrace.h"
45 /* Include Xen utilities */
46 #include "xen_utils.h"
48 /* Include the abstract resource access functions and abstracted _RESOURCES and _RESOURCE data types. */
49 #include "Xen_VirtualSystemManagementService_Resource.h"
51 /* Include the required CMPI data types, function headers, and macros */
52 #include "cmpidt.h"
53 #include "cmpift.h"
54 #include "cmpimacs.h"
56 #include "provider_common.h"
57 #include "xen_utils.h"
60 // ----------------------------------------------------------------------------
61 // COMMON GLOBAL VARIABLES
62 // ----------------------------------------------------------------------------
64 /* Handle to the CIM broker. Initialized when the provider lib is loaded. */
65 static const CMPIBroker *_BROKER;
67 /* Xen session object. Initialize when the provider is loaded, close when
68 * provider unloaded. */
69 static xen_utils_session *session = NULL;
72 // ============================================================================
73 // CMPI INSTANCE PROVIDER FUNCTION TABLE
74 // ============================================================================
76 // ----------------------------------------------------------------------------
77 // Info for the class supported by the instance provider
78 // ----------------------------------------------------------------------------
80 /* Name of the class implemented by this instance provider. */
81 /*** CUSTOMIZE FOR EACH PROVIDER ***/
82 static char * _CLASSNAME = "Xen_VirtualSystemManagementService";
84 /* NULL terminated list of key properties of this class. */
85 /*** CUSTOMIZE FOR EACH PROVIDER ***/
86 const static char * _KEYNAMES[] = {"SystemName", "SystemCreationClassName", "Name", "CreationClassName", NULL};
89 static int create_vm(CMPIInstance* vsSettingsInst,
90 CMPIArray *resourceSettings,
91 xen_vm *result, CMPIStatus *status);
92 static int add_resource_to_vm(xen_vm_record *vmRec,
93 CMPIInstance *sourceSettingInst,
94 CMPIObjectPath **resultSetting,
95 char *namespace,
96 CMPIStatus *status);
97 static void remove_vm(xen_vm vm);
98 static int vssd2xenconfig(CMPIInstance *vssd, xen_vm_record *vm_rec, CMPIStatus *status);
99 static int proc_rasd2vmconfig(CMPIInstance *proc_rasd, xen_vm_record *vm_rec,
100 CMPIStatus *status);
101 static int mem_rasd2vmconfig(CMPIInstance *instance, xen_vm_record *vm_rec,
102 CMPIStatus *status);
103 static int disk_rasd2vmconfig(CMPIInstance *instance, xen_vbd_record **vbd_rec,
104 CMPIStatus *status);
105 static int nic_rasd2vmconfig(CMPIInstance *instance, xen_vif_record **vif_rec,
106 CMPIStatus *status);
107 static int con_rasd2vmconfig(CMPIInstance *instance, xen_console_record *con_rec,
108 CMPIStatus *status);
109 static CMPIInstance *parse_embedded_instance(char *instanceStr);
113 // ----------------------------------------------------------------------------
114 // Cleanup()
115 // Perform any necessary cleanup immediately before this provider is unloaded.
116 // ----------------------------------------------------------------------------
117 static CMPIStatus Cleanup(
118 CMPIInstanceMI * self, /* [in] Handle to this provider (i.e. 'self'). */
119 const CMPIContext * context, /* [in] Additional context info, if any. */
120 CMPIBoolean terminating) /* [in] True if MB is terminating */
121 {
122 CMPIStatus status = { CMPI_RC_OK, NULL }; /* Return status of CIM operations. */
124 _SBLIM_ENTER("Cleanup");
125 _SBLIM_TRACE(2, ("--- self=\"%s\"", self->ft->miName));
126 _SBLIM_TRACE(2, ("--- context=\"%s\"", CMGetCharPtr(CDToString(_BROKER, context, NULL))));
128 if (session) {
129 xen_utils_xen_close(session);
130 session = NULL;
131 }
132 _SBLIM_RETURNSTATUS(status);
133 }
135 // ----------------------------------------------------------------------------
136 // EnumInstanceNames()
137 // Return a list of all the instances names (return their object paths only).
138 // ----------------------------------------------------------------------------
139 static CMPIStatus EnumInstanceNames(
140 CMPIInstanceMI * self, /* [in] Handle to this provider (i.e. 'self'). */
141 const CMPIContext * context, /* [in] Additional context info, if any. */
142 const CMPIResult * results, /* [out] Results of this operation. */
143 const CMPIObjectPath * reference) /* [in] Contains target namespace and classname. */
144 {
145 CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations. */
146 _RESOURCES * resources = NULL; /* Handle to the list of system resources. */
147 _RESOURCE * resource; /* Handle to each system resource. */
148 char * namespace = CMGetCharPtr(CMGetNameSpace(reference, NULL)); /* Target namespace. */
149 int found = 0; /* Found any instances? */
151 _SBLIM_ENTER("EnumInstanceNames");
152 _SBLIM_TRACE(2, ("--- self=\"%s\"", self->ft->miName));
153 _SBLIM_TRACE(2, ("--- context=\"%s\"", CMGetCharPtr(CDToString(_BROKER, context, NULL))));
154 _SBLIM_TRACE(2, ("--- reference=\"%s\"", CMGetCharPtr(CDToString(_BROKER, reference, NULL))));
155 _SBLIM_TRACE(2, ("--- namespace=\"%s\"", namespace));
157 if (strcmp(namespace, HOST_INSTRUMENTATION_NS) == 0) {
158 _SBLIM_TRACE(1,("--- \"%s\" is not a valid namespace for %s", namespace, _CLASSNAME));
159 goto exit;
160 }
162 /* Get a handle to the list of system resources. */
163 if (!Xen_VirtualSystemManagementService_getResources(&resources)) {
164 _SBLIM_TRACE(1,("--- _getResources() failed"));
165 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to get list of system resources");
166 goto exit;
167 }
169 /* Enumerate thru the list of system resources and return a CMPIInstance for each. */
170 while (Xen_VirtualSystemManagementService_getNextResource(session, resources, &resource)) {
171 /* Create a new CMPIInstance to store this resource. */
172 CMPIInstance * instance = _CMNewInstance(_BROKER, namespace, _CLASSNAME, &status);
173 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(instance)) {
174 _SBLIM_TRACE(1,("--- CMNewInstance() failed - %s", CMGetCharPtr(status.msg)));
175 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERROR, "Cannot create new CMPIInstance");
176 goto exit;
177 }
179 /* Set the instance property values from the resource data. */
180 if (!Xen_VirtualSystemManagementService_setInstanceFromResource(resource, instance, _BROKER)) {
181 _SBLIM_TRACE(1,("--- _setInstanceFromResource() failed"));
182 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to set property values from resource data");
183 goto exit;
184 }
186 /* Free the resource data. */
187 if (!Xen_VirtualSystemManagementService_freeResource(resource)) {
188 _SBLIM_TRACE(1,("--- _freeResource() failed"));
189 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to free resource data");
190 goto exit;
191 }
193 /* Return the CMPIObjectPath for this instance. */
194 CMPIObjectPath * objectpath = CMGetObjectPath(instance, &status);
195 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(objectpath)) {
196 _SBLIM_TRACE(1,("--- CMGetObjectPath() failed - %s", CMGetCharPtr(status.msg)));
197 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERROR, "Cannot get CMPIObjectPath for instance");
198 goto exit;
199 }
200 CMSetNameSpace(objectpath, namespace); /* Note - CMGetObjectPath() does not preserve the namespace! */
202 _SBLIM_TRACE(3,("--- objectpath=\"%s\"", CMGetCharPtr(CDToString(_BROKER, objectpath, NULL))));
203 CMReturnObjectPath(results, objectpath);
204 found++;
205 }
207 _SBLIM_TRACE(2,("--- %d object paths found", found));
208 CMReturnDone(results);
210 exit:
211 /* Free the list of system resources. */
212 if (!Xen_VirtualSystemManagementService_freeResources(resources)) {
213 _SBLIM_TRACE(1,("--- _freeResources() failed"));
214 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to free list of system resources");
215 }
217 _SBLIM_RETURNSTATUS(status);
218 }
220 // ----------------------------------------------------------------------------
221 // EnumInstances()
222 // Return a list of all the instances (return all the instance data).
223 // ----------------------------------------------------------------------------
224 static CMPIStatus EnumInstances(
225 CMPIInstanceMI * self, /* [in] Handle to this provider (i.e. 'self'). */
226 const CMPIContext * context, /* [in] Additional context info, if any. */
227 const CMPIResult * results, /* [out] Results of this operation. */
228 const CMPIObjectPath * reference, /* [in] Contains target namespace and classname. */
229 const char ** properties) /* [in] List of desired properties (NULL=all). */
230 {
231 CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations. */
232 _RESOURCES * resources = NULL; /* Handle to the list of system resources. */
233 _RESOURCE * resource; /* Handle to each system resource. */
234 char * namespace = CMGetCharPtr(CMGetNameSpace(reference, NULL)); /* Target namespace. */
235 int found = 0; /* Found any resource instances? */
237 _SBLIM_ENTER("EnumInstances");
238 _SBLIM_TRACE(2, ("--- self=\"%s\"", self->ft->miName));
239 _SBLIM_TRACE(2, ("--- context=\"%s\"", CMGetCharPtr(CDToString(_BROKER, context, NULL))));
240 _SBLIM_TRACE(2, ("--- reference=\"%s\"", CMGetCharPtr(CDToString(_BROKER, reference, NULL))));
241 _SBLIM_TRACE(2, ("--- namespace=\"%s\"", namespace));
243 if (strcmp(namespace, HOST_INSTRUMENTATION_NS) == 0) {
244 _SBLIM_TRACE(1,("--- \"%s\" is not a valid namespace for %s", namespace, _CLASSNAME));
245 goto exit;
246 }
248 /* Get a handle to the list of system resources. */
249 if (!Xen_VirtualSystemManagementService_getResources(&resources)) {
250 _SBLIM_TRACE(1,("--- _getResources() failed"));
251 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to get list of system resources");
252 goto exit;
253 }
255 /* Enumerate thru the list of system resources and return a CMPIInstance for each. */
256 while (Xen_VirtualSystemManagementService_getNextResource(session, resources, &resource)) {
257 /* Create a new CMPIInstance to store this resource. */
258 CMPIInstance * instance = _CMNewInstance(_BROKER, namespace, _CLASSNAME, &status);
259 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(instance)) {
260 _SBLIM_TRACE(1,("--- CMNewInstance() failed - %s", CMGetCharPtr(status.msg)));
261 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERROR, "Cannot create new CMPIInstance");
262 goto exit;
263 }
265 /* Setup a filter to only return the desired properties. */
266 status = CMSetPropertyFilter(instance, properties, _KEYNAMES);
267 if (status.rc != CMPI_RC_OK) {
268 _SBLIM_TRACE(1, ("--- CMSetPropertyFilter() failed - %s", CMGetCharPtr(status.msg)));
269 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Cannot set property filter");
270 goto exit;
271 }
273 /* Set the instance property values from the resource data. */
274 if (!Xen_VirtualSystemManagementService_setInstanceFromResource(resource, instance, _BROKER)) {
275 _SBLIM_TRACE(1,("--- _setInstanceFromResource() failed"));
276 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to set property values from resource data");
277 goto exit;
278 }
280 /* Free the resource data. */
281 if (!Xen_VirtualSystemManagementService_freeResource(resource)) {
282 _SBLIM_TRACE(1,("--- _freeResource() failed"));
283 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to free resource data");
284 goto exit;
285 }
287 /* Return the CMPIInstance for this instance. */
288 _SBLIM_TRACE(3,("--- instance=\"%s\"", CMGetCharPtr(CDToString(_BROKER, instance, NULL))));
289 CMReturnInstance(results, instance);
290 found++;
291 }
293 _SBLIM_TRACE(2,("--- %d instances found", found));
294 CMReturnDone(results);
296 exit:
297 /* Free the list of system resources. */
298 if (!Xen_VirtualSystemManagementService_freeResources(resources)) {
299 _SBLIM_TRACE(1,("--- _freeResources() failed"));
300 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to free list of system resources");
301 }
303 _SBLIM_RETURNSTATUS(status);
304 }
306 // ----------------------------------------------------------------------------
307 // GetInstance()
308 // Return the instance data for the specified instance only.
309 // ----------------------------------------------------------------------------
310 static CMPIStatus GetInstance(
311 CMPIInstanceMI * self, /* [in] Handle to this provider (i.e. 'self'). */
312 const CMPIContext * context, /* [in] Additional context info, if any. */
313 const CMPIResult * results, /* [out] Results of this operation. */
314 const CMPIObjectPath * reference, /* [in] Contains the target namespace, classname and object path. */
315 const char ** properties) /* [in] List of desired properties (NULL=all). */
316 {
317 CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations. */
318 _RESOURCES * resources = NULL; /* Handle to the list of system resources. */
319 _RESOURCE * resource; /* Handle to the system resource. */
320 char * namespace = CMGetCharPtr(CMGetNameSpace(reference, NULL)); /* Target namespace. */
321 int found = 0; /* Found the target instance? */
323 _SBLIM_ENTER("GetInstance");
324 _SBLIM_TRACE(2, ("--- self=\"%s\"", self->ft->miName));
325 _SBLIM_TRACE(2, ("--- context=\"%s\"", CMGetCharPtr(CDToString(_BROKER, context, NULL))));
326 _SBLIM_TRACE(2, ("--- reference=\"%s\"", CMGetCharPtr(CDToString(_BROKER, reference, NULL))));
327 _SBLIM_TRACE(2, ("--- namespace=\"%s\"", namespace));
329 if (strcmp(namespace, HOST_INSTRUMENTATION_NS) == 0) {
330 _SBLIM_TRACE(1,("--- \"%s\" is not a valid namespace for %s", namespace, _CLASSNAME));
331 goto exit;
332 }
334 /* Get a handle to the list of system resources. */
335 if (!Xen_VirtualSystemManagementService_getResources(&resources)) {
336 _SBLIM_TRACE(1,("--- _getResources() failed"));
337 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to get list of system resources");
338 goto exit;
339 }
341 /* Get the target resource. */
342 found = Xen_VirtualSystemManagementService_getResourceForObjectPath(session, resources, &resource, reference);
343 if (!found || (resource == NULL)) {
344 _SBLIM_TRACE(1,("--- Target instance not found"));
345 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_NOT_FOUND, "Target instance not found");
346 goto exit;
347 }
349 /* Create a new CMPIInstance to store this resource. */
350 CMPIInstance * instance = _CMNewInstance(_BROKER, namespace, _CLASSNAME, &status);
351 if ((status.rc != CMPI_RC_OK) || CMIsNullObject(instance)) {
352 _SBLIM_TRACE(1,("--- CMNewInstance() failed - %s", CMGetCharPtr(status.msg)));
353 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERROR, "Cannot create new CMPIInstance");
354 goto exit;
355 }
357 /* Setup a filter to only return the desired properties. */
358 status = CMSetPropertyFilter(instance, properties, _KEYNAMES);
359 if (status.rc != CMPI_RC_OK) {
360 _SBLIM_TRACE(1, ("--- CMSetPropertyFilter() failed - %s", CMGetCharPtr(status.msg)));
361 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Cannot set property filter");
362 goto exit;
363 }
365 /* Set the instance property values from the resource data. */
366 if (!Xen_VirtualSystemManagementService_setInstanceFromResource(resource, instance, _BROKER)) {
367 _SBLIM_TRACE(1,("--- _setInstanceFromResource() failed"));
368 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to set property values from resource data");
369 goto exit;
370 }
372 /* Free the resource data. */
373 if (!Xen_VirtualSystemManagementService_freeResource(resource)) {
374 _SBLIM_TRACE(1,("--- _freeResource() failed"));
375 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to free resource data");
376 goto exit;
377 }
379 /* Return the CMPIInstance for this instance. */
380 _SBLIM_TRACE(3,("--- instance=\"%s\"", CMGetCharPtr(CDToString(_BROKER, instance, NULL))));
381 CMReturnInstance(results, instance);
383 _SBLIM_TRACE(2,("--- instance found"));
384 CMReturnDone(results);
386 exit:
387 /* Free the list of system resources. */
388 if (!Xen_VirtualSystemManagementService_freeResources(resources)) {
389 _SBLIM_TRACE(1,("--- _freeResources() failed"));
390 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to free list of system resources");
391 }
393 _SBLIM_RETURNSTATUS(status);
394 }
396 // ----------------------------------------------------------------------------
397 // SetInstance()
398 // Save modified instance data for the specified instance.
399 // ----------------------------------------------------------------------------
400 static CMPIStatus SetInstance(
401 CMPIInstanceMI * self, /* [in] Handle to this provider (i.e. 'self'). */
402 const CMPIContext * context, /* [in] Additional context info, if any. */
403 const CMPIResult * results, /* [out] Results of this operation. */
404 const CMPIObjectPath * reference, /* [in] Contains the target namespace, classname and object path. */
405 const CMPIInstance * newinstance, /* [in] Contains the new instance data. */
406 const char **properties)
407 {
408 CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations. */
409 _RESOURCES * resources = NULL; /* Handle to the list of system resources. */
410 _RESOURCE * resource; /* Handle to the system resource. */
411 char * namespace = CMGetCharPtr(CMGetNameSpace(reference, NULL)); /* Target namespace. */
412 int found = 0; /* Found the target instance? */
414 _SBLIM_ENTER("SetInstance");
415 _SBLIM_TRACE(2, ("--- self=\"%s\"", self->ft->miName));
416 _SBLIM_TRACE(2, ("--- context=\"%s\"", CMGetCharPtr(CDToString(_BROKER, context, NULL))));
417 _SBLIM_TRACE(2, ("--- reference=\"%s\"", CMGetCharPtr(CDToString(_BROKER, reference, NULL))));
418 _SBLIM_TRACE(2, ("--- newinstance=\"%s\"", CMGetCharPtr(CDToString(_BROKER, newinstance, NULL))));
419 _SBLIM_TRACE(2, ("--- namespace=\"%s\"", namespace));
421 if (strcmp(namespace, HOST_INSTRUMENTATION_NS) == 0) {
422 _SBLIM_TRACE(1,("--- \"%s\" is not a valid namespace for %s", namespace, _CLASSNAME));
423 goto exit;
424 }
426 /* Get a handle to the list of system resources. */
427 if (!Xen_VirtualSystemManagementService_getResources(&resources)) {
428 _SBLIM_TRACE(1,("--- _getResources() failed"));
429 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to get list of system resources");
430 goto exit;
431 }
433 /* Get the target resource. */
434 found = Xen_VirtualSystemManagementService_getResourceForObjectPath(session, resources, &resource, reference);
435 if (!found || (resource == NULL)) {
436 _SBLIM_TRACE(1,("--- Target instance not found"));
437 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_NOT_FOUND, "Target instance not found");
438 goto exit;
439 }
441 _SBLIM_TRACE(2,("--- instance found"));
443 /* Update the target resource data with the new instance property values. */
444 int rc = Xen_VirtualSystemManagementService_setResourceFromInstance(resource, newinstance, _BROKER);
446 /* Free the resource data. */
447 if (!Xen_VirtualSystemManagementService_freeResource(resource)) {
448 _SBLIM_TRACE(1,("--- _freeResource() failed"));
449 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to free resource data");
450 goto exit;
451 }
453 if (rc != 1) {
454 if (rc == -1) {
455 _SBLIM_TRACE(1,("--- _setResourceFromInstance() unsupported"));
456 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_NOT_SUPPORTED, NULL);
457 } else {
458 _SBLIM_TRACE(1,("--- _setResourceFromInstance() failed"));
459 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to set resource data from instance properties");
460 }
461 goto exit;
462 }
464 exit:
465 /* Free the list of system resources. */
466 if (!Xen_VirtualSystemManagementService_freeResources(resources)) {
467 _SBLIM_TRACE(1,("--- _freeResources() failed"));
468 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to free list of system resources");
469 }
471 _SBLIM_RETURNSTATUS(status);
472 }
474 // ----------------------------------------------------------------------------
475 // CreateInstance()
476 // Create a new instance from the specified instance data.
477 // ----------------------------------------------------------------------------
478 static CMPIStatus CreateInstance(
479 CMPIInstanceMI * self, /* [in] Handle to this provider (i.e. 'self'). */
480 const CMPIContext * context, /* [in] Additional context info, if any. */
481 const CMPIResult * results, /* [out] Results of this operation. */
482 const CMPIObjectPath * reference, /* [in] Contains the target namespace, classname and object path. */
483 const CMPIInstance * newinstance) /* [in] Contains the new instance data. */
484 {
485 CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations. */
486 _RESOURCES * resources = NULL; /* Handle to the list of system resources. */
487 _RESOURCE * resource; /* Handle to the system resource. */
488 char * namespace = CMGetCharPtr(CMGetNameSpace(reference, NULL)); /* Target namespace. */
489 int found = 0; /* Found the target instance? */
491 _SBLIM_ENTER("CreateInstance");
492 _SBLIM_TRACE(2, ("--- self=\"%s\"", self->ft->miName));
493 _SBLIM_TRACE(2, ("--- context=\"%s\"", CMGetCharPtr(CDToString(_BROKER, context, NULL))));
494 _SBLIM_TRACE(2, ("--- reference=\"%s\"", CMGetCharPtr(CDToString(_BROKER, reference, NULL))));
495 _SBLIM_TRACE(2, ("--- newinstance=\"%s\"", CMGetCharPtr(CDToString(_BROKER, newinstance, NULL))));
496 _SBLIM_TRACE(2, ("--- namespace=\"%s\"", namespace));
498 if (strcmp(namespace, HOST_INSTRUMENTATION_NS) == 0) {
499 _SBLIM_TRACE(1,("--- \"%s\" is not a valid namespace for %s", namespace, _CLASSNAME));
500 goto exit;
501 }
503 /* WORKAROUND FOR PEGASUS BUG?! reference does not contain object path, only namespace & classname. */
504 reference = CMGetObjectPath(newinstance, NULL);
506 /* Get a handle to the list of system resources. */
507 if (!Xen_VirtualSystemManagementService_getResources(&resources)) {
508 _SBLIM_TRACE(1,("--- _getResources() failed"));
509 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to get list of system resources");
510 goto exit;
511 }
513 /* Get the target resource. */
514 found = Xen_VirtualSystemManagementService_getResourceForObjectPath(session, resources, &resource, reference);
516 /* Free the resource data. */
517 if (!Xen_VirtualSystemManagementService_freeResource(resource)) {
518 _SBLIM_TRACE(1,("--- _freeResource() failed"));
519 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to free resource data");
520 goto exit;
521 }
523 if (found) {
524 _SBLIM_TRACE(1,("--- Target instance already exists"));
525 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_ALREADY_EXISTS, "Target instance already exists");
526 goto exit;
527 }
529 /* Create a new resource with the new instance property values. */
530 int rc = Xen_VirtualSystemManagementService_createResourceFromInstance(resources, &resource, newinstance, _BROKER);
531 if (rc != 1) {
532 if (rc == -1) {
533 _SBLIM_TRACE(1,("--- _createResourceFromInstance() unsupported"));
534 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_NOT_SUPPORTED, NULL);
535 } else {
536 _SBLIM_TRACE(1,("--- _createResourceFromInstance() failed"));
537 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to create resource data from instance properties");
538 }
539 goto exit;
540 }
542 /* Return the object path for the newly created instance. */
543 CMPIObjectPath * objectpath = CMGetObjectPath(newinstance, NULL);
544 CMSetNameSpace(objectpath, namespace);
545 CMReturnObjectPath(results, objectpath);
546 CMReturnDone(results);
548 exit:
549 /* Free the list of system resources. */
550 if (!Xen_VirtualSystemManagementService_freeResources(resources)) {
551 _SBLIM_TRACE(1,("--- _freeResources() failed"));
552 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to free list of system resources");
553 }
555 _SBLIM_RETURNSTATUS(status);
556 }
558 // ----------------------------------------------------------------------------
559 // DeleteInstance()
560 // Delete or remove the specified instance from the system.
561 // ----------------------------------------------------------------------------
562 static CMPIStatus DeleteInstance(
563 CMPIInstanceMI * self, /* [in] Handle to this provider (i.e. 'self'). */
564 const CMPIContext * context, /* [in] Additional context info, if any. */
565 const CMPIResult * results, /* [out] Results of this operation. */
566 const CMPIObjectPath * reference) /* [in] Contains the target namespace, classname and object path. */
567 {
568 CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations. */
569 _RESOURCES * resources = NULL; /* Handle to the list of system resources. */
570 _RESOURCE * resource; /* Handle to the system resource. */
571 char * namespace = CMGetCharPtr(CMGetNameSpace(reference, NULL)); /* Target namespace. */
572 int found = 0; /* Found the target instance? */
574 _SBLIM_ENTER("DeleteInstance");
575 _SBLIM_TRACE(2, ("--- self=\"%s\"", self->ft->miName));
576 _SBLIM_TRACE(2, ("--- context=\"%s\"", CMGetCharPtr(CDToString(_BROKER, context, NULL))));
577 _SBLIM_TRACE(2, ("--- reference=\"%s\"", CMGetCharPtr(CDToString(_BROKER, reference, NULL))));
578 _SBLIM_TRACE(2, ("--- namespace=\"%s\"", namespace));
580 if (strcmp(namespace, HOST_INSTRUMENTATION_NS) == 0) {
581 _SBLIM_TRACE(1,("--- \"%s\" is not a valid namespace for %s", namespace, _CLASSNAME));
582 goto exit;
583 }
585 /* Get a handle to the list of system resources. */
586 if (!Xen_VirtualSystemManagementService_getResources(&resources)) {
587 _SBLIM_TRACE(1,("--- _getResources() failed"));
588 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to get list of system resources");
589 goto exit;
590 }
592 /* Get the target resource. */
593 found = Xen_VirtualSystemManagementService_getResourceForObjectPath(session, resources, &resource, reference);
594 if (!found || (resource == NULL)) {
595 _SBLIM_TRACE(1,("--- Target instance not found"));
596 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_NOT_FOUND, "Target instance not found");
597 goto exit;
598 }
600 _SBLIM_TRACE(2,("--- instance found"));
602 /* Delete the target resource. */
603 int rc = Xen_VirtualSystemManagementService_deleteResource(resources, resource);
605 /* Free the resource data. */
606 if (!Xen_VirtualSystemManagementService_freeResource(resource)) {
607 _SBLIM_TRACE(1,("--- _freeResource() failed"));
608 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to free resource data");
609 goto exit;
610 }
612 if (rc != 1) {
613 if (rc == -1) {
614 _SBLIM_TRACE(1,("--- __deleteResource() unsupported"));
615 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_NOT_SUPPORTED, NULL);
616 } else {
617 _SBLIM_TRACE(1,("--- _deleteResource() failed"));
618 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to delete resource");
619 }
620 goto exit;
621 }
623 exit:
624 /* Free the list of system resources. */
625 if (!Xen_VirtualSystemManagementService_freeResources(resources)) {
626 _SBLIM_TRACE(1,("--- _freeResources() failed"));
627 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to free list of system resources");
628 }
630 _SBLIM_RETURNSTATUS(status);
631 }
634 // ----------------------------------------------------------------------------
635 // ExecQuery()
636 // Return a list of all the instances that satisfy the specified query filter.
637 // ----------------------------------------------------------------------------
638 static CMPIStatus ExecQuery(
639 CMPIInstanceMI * self, /* [in] Handle to this provider (i.e. 'self'). */
640 const CMPIContext * context, /* [in] Additional context info, if any. */
641 const CMPIResult * results, /* [out] Results of this operation. */
642 const CMPIObjectPath * reference, /* [in] Contains the target namespace and classname. */
643 const char * language, /* [in] Name of the query language. */
644 const char * query) /* [in] Text of the query written in the query language. */
645 {
646 CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations. */
647 char * namespace = CMGetCharPtr(CMGetNameSpace(reference, NULL)); /* Target namespace. */
649 _SBLIM_ENTER("ExecQuery");
650 _SBLIM_TRACE(2, ("--- self=\"%s\"", self->ft->miName));
651 _SBLIM_TRACE(2, ("--- context=\"%s\"", CMGetCharPtr(CDToString(_BROKER, context, NULL))));
652 _SBLIM_TRACE(2, ("--- reference=\"%s\"", CMGetCharPtr(CDToString(_BROKER, reference, NULL))));
653 _SBLIM_TRACE(2, ("--- language=\"%s\"", language));
654 _SBLIM_TRACE(2, ("--- query=\"%s\"", query));
655 _SBLIM_TRACE(2, ("--- namespace=\"%s\"", namespace));
657 if (strcmp(namespace, HOST_INSTRUMENTATION_NS) == 0) {
658 _SBLIM_TRACE(1,("--- \"%s\" is not a valid namespace for %s", namespace, _CLASSNAME));
659 goto exit;
660 }
662 /* EXECQUERY() IS NOT YET SUPPORTED FOR THIS CLASS */
663 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_NOT_SUPPORTED, NULL);
665 CMReturnDone(results);
667 exit:
668 _SBLIM_RETURNSTATUS(status);
669 }
671 // ----------------------------------------------------------------------------
672 // InstInitialize()
673 // Perform any necessary initialization immediately after the instance provider
674 // is first loaded.
675 // ----------------------------------------------------------------------------
676 static void InstInitialize(
677 CMPIInstanceMI * self, /* [in] Handle to this provider (i.e. 'self'). */
678 const CMPIContext * context) /* [in] Additional context info, if any. */
679 {
680 _SBLIM_ENTER("InstInitialize");
681 _SBLIM_TRACE(2, ("--- self=\"%s\"", self->ft->miName));
682 // _SBLIM_TRACE(2, ("--- context=\"%s\"", CMGetCharPtr(CDToString(_BROKER, context, NULL))));
684 /* Initialized Xen session object. */
685 if (session == NULL)
686 xen_utils_xen_init(&session);
688 _SBLIM_RETURN();
689 }
692 // ============================================================================
693 // CMPI INSTANCE PROVIDER FUNCTION TABLE SETUP
694 // ============================================================================
695 CMInstanceMIStub( , Xen_VirtualSystemManagementService, _BROKER, InstInitialize(&mi, ctx));
698 // ============================================================================
699 // CMPI METHOD PROVIDER FUNCTION TABLE
700 // ============================================================================
702 // ----------------------------------------------------------------------------
703 // MethodCleanup()
704 // Perform any necessary cleanup immediately before this provider is unloaded.
705 // ----------------------------------------------------------------------------
706 static CMPIStatus MethodCleanup(
707 CMPIMethodMI * self, /* [in] Handle to this provider (i.e. 'self'). */
708 const CMPIContext * context, /* [in] Additional context info, if any. */
709 CMPIBoolean terminating) /* [in] True if MB is terminating */
710 {
711 CMPIStatus status = { CMPI_RC_OK, NULL }; /* Return status of CIM operations. */
713 _SBLIM_ENTER("MethodCleanup");
714 _SBLIM_TRACE(2, ("--- self=\"%s\"", self->ft->miName));
715 _SBLIM_TRACE(2, ("--- context=\"%s\"", CMGetCharPtr(CDToString(_BROKER, context, NULL))));
717 if (session) {
718 xen_utils_xen_close(session);
719 session = NULL;
720 }
721 _SBLIM_RETURNSTATUS(status);
722 }
724 // ----------------------------------------------------------------------------
725 // InvokeMethod()
726 // Execute an extrinsic method on the specified instance.
727 // ----------------------------------------------------------------------------
728 static CMPIStatus InvokeMethod(
729 CMPIMethodMI * self, /* [in] Handle to this provider (i.e. 'self') */
730 const CMPIContext * context, /* [in] Additional context info, if any */
731 const CMPIResult * results, /* [out] Results of this operation */
732 const CMPIObjectPath * reference, /* [in] Contains the CIM namespace, classname and desired object path */
733 const char * methodname, /* [in] Name of the method to apply against the reference object */
734 const CMPIArgs * argsin, /* [in] Method input arguments */
735 CMPIArgs * argsout) /* [in] Method output arguments */
736 {
737 CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations */
738 char * namespace = CMGetCharPtr(CMGetNameSpace(reference, NULL)); /* Target namespace. */
739 int rc = 0;
740 int argsInCount;
741 _RESOURCES * resources; /* Handle to the list of system resources. */
742 CMPIData argdata;
743 char error_msg[XEN_UTILS_ERROR_BUF_LEN];
745 _SBLIM_ENTER("InvokeMethod");
746 _SBLIM_TRACE(2, ("--- self=\"%s\"", self->ft->miName));
747 _SBLIM_TRACE(2, ("--- context=\"%s\"", CMGetCharPtr(CDToString(_BROKER, context, NULL))));
748 _SBLIM_TRACE(2, ("--- reference=\"%s\"", CMGetCharPtr(CDToString(_BROKER, reference, NULL))));
749 _SBLIM_TRACE(2, ("--- methodname=\"%s\"", methodname));
750 _SBLIM_TRACE(2, ("--- namespace=\"%s\"", namespace));
752 if (!xen_utils_validate_session(&session)) {
753 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_METHOD_NOT_AVAILABLE, "Unable to connect to xen daemon");
754 goto Exit;
755 }
757 argsInCount = CMGetArgCount(argsin, NULL);
758 _SBLIM_TRACE(2, ("--- # argsin=%d", argsInCount));
760 /* Get a handle to the list of system resources. */
761 if (!Xen_VirtualSystemManagementService_getResources(&resources)) {
762 _SBLIM_TRACE(1,("--- _getResources() failed"));
763 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to get list of system resources");
764 rc = 2;
765 goto Exit;
766 }
768 /* Start/stop the service. */
769 if (strcmp(methodname, "StartService") == 0) {
770 if (!Xen_VirtualSystemManagementService_enableResource(session, resources, NULL)) {
771 _SBLIM_TRACE(1,("--- StartService() failed"));
772 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Method operation failed");
773 rc = 2;
774 goto Exit;
775 }
776 }
777 else if (strcmp(methodname, "StopService") == 0) {
778 if (!Xen_VirtualSystemManagementService_disableResource(session, resources, NULL)) {
779 _SBLIM_TRACE(1,("--- StopService() failed"));
780 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Method operation failed");
781 rc = 2;
782 goto Exit;
783 }
784 }
785 else if (strcmp(methodname, "DefineSystem") == 0) {
786 if (argsInCount != 3) {
787 _SBLIM_TRACE(1,("--- Incorrect number of method arguments"));
788 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Incorrect number of method arguments");
789 rc = 5;
790 goto Exit;
791 }
793 /* Get embedded instance of VirtualSystemSettingData. */
794 argdata = CMGetArgAt(argsin, 0, NULL, &status);
795 if ((status.rc != CMPI_RC_OK) || CMIsNullValue(argdata)) {
796 _SBLIM_TRACE(1,("--- CMGetArgAt(0) failed"));
797 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Cannot get method input argument");
798 rc = 5;
799 goto Exit;
800 }
802 CMPIInstance* vsSettingDataInst;
803 if (argdata.type == CMPI_string)
804 {
805 char *vsSettingData = CMGetCharPtr(argdata.value.string);
806 _SBLIM_TRACE(2,("--- Got string with embedded instance =\"%s\"", vsSettingData));
808 vsSettingDataInst = parse_embedded_instance(vsSettingData);
809 if (vsSettingDataInst == NULL) { /* parser returns zero for success, non-zero for error */
810 _SBLIM_TRACE(1,("--- Error parsing VirtualSystemSettingData: \"%s\"",vsSettingData));
811 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Cannot parse VirtualSystemSettingData");
812 rc = 5;
813 goto Exit;
814 }
815 }
816 else if (argdata.type == CMPI_instance)
817 {
818 vsSettingDataInst = argdata.value.inst;
819 _SBLIM_TRACE(2,("--- Got embedded instance for vsSettingData"));
820 }
821 else
822 {
823 _SBLIM_TRACE(1,("--- Invalid setting type - %s", _CMPITypeName(argdata.type)));
824 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Invalid setting type");
825 rc = 5;
826 goto Exit;
827 }
829 /* Get input array of ResourceAllocationSettingData instances. */
830 argdata = CMGetArgAt(argsin, 1, NULL, &status);
831 if ((status.rc != CMPI_RC_OK) || CMIsNullValue(argdata)) {
832 _SBLIM_TRACE(1,("--- CMGetArgAt(1) failed"));
833 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Cannot get method input argument");
834 rc = 5;
835 goto Exit;
836 }
838 /* Check that the input arg is an array. */
839 if (!CMIsArray(argdata) || CMIsNullObject(argdata.value.array)) {
840 _SBLIM_TRACE(1,("--- Invalid method argument type. Array expected"));
841 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Invalid method argument type. Array expected");
842 rc = 5;
843 goto Exit;
844 }
846 CMPIArray *resourceSettings = argdata.value.array;
847 xen_vm vm;
848 if (!create_vm(vsSettingDataInst, resourceSettings, &vm, &status))
849 {
850 _SBLIM_TRACE(1,("--- create_vm() failed"));
851 /* status set in create_vm */
852 rc = 3;
853 goto Exit;
854 }
856 /* Return the objectpath for the resulting DomU in the output args */
857 CMPIObjectPath * op = CMNewObjectPath(_BROKER, namespace, "Xen_ComputerSystem", NULL);
858 CMAddKey(op, "CreationClassName", (CMPIValue *)"Xen_ComputerSystem", CMPI_chars);
859 char *vm_name;
860 if (!xen_vm_get_name_label(session->xen, &vm_name, vm)) {
861 /* Can't get the name after all of this work! Unwind this mess. */
862 remove_vm(vm);
863 xen_vm_free(vm);
864 _SBLIM_TRACE(1,("--- Unable to retrieve name of new VM"));
865 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to create the virtual system");
866 rc = 3;
867 goto Exit;
868 }
870 CMAddKey(op, "Name", (CMPIValue *)vm_name, CMPI_chars);
871 /*
872 * WARNING: J. Fehlig
873 * What does this do?
874 *
875 * CMSetHostAndNameSpaceFromObjectPath(op, reference);
876 *
877 */
878 _SBLIM_TRACE(2,("--- VirtualSystem=%s", CMGetCharPtr(CDToString(_BROKER, op, NULL))));
879 CMAddArg(argsout, "ResultingSystem", (CMPIValue*)&op, CMPI_ref);
880 xen_vm_free(vm);
882 _SBLIM_TRACE(2, ("--- DefineSystem completed with success"));
883 }
884 else if (strcmp(methodname, "AddResourceSettings") == 0) {
885 /* TODO */
886 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_METHOD_NOT_AVAILABLE, NULL);
887 rc = 1;
888 goto Exit;
889 }
890 else if (strcmp(methodname, "AddResourceSetting") == 0) {
891 if (argsInCount != 2) {
892 _SBLIM_TRACE(1,("--- Incorrect number of method arguments"));
893 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Incorrect number of method arguments");
894 rc = 5;
895 goto Exit;
896 }
898 /* Get vm record based on VirtualSystemSettingData object path. */
899 argdata = CMGetArgAt(argsin, 0, NULL, &status);
900 if ((status.rc != CMPI_RC_OK) || CMIsNullValue(argdata)) {
901 _SBLIM_TRACE(1,("--- CMGetArgAt(0) failed"));
902 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Cannot get method input argument");
903 rc = 5;
904 goto Exit;
905 }
907 if (argdata.type != CMPI_ref) {
908 _SBLIM_TRACE(1,("--- Invalid setting type - %s", _CMPITypeName(argdata.type)));
909 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Invalid setting type");
910 rc = 5;
911 goto Exit;
912 }
914 _SBLIM_TRACE(2, ("--- domain object path=\"%s\"", CMGetCharPtr(CDToString(_BROKER, argdata.value.ref, NULL))));
916 xen_vm_record *vmRec;
917 if (!xen_utils_get_domain_from_sd_OP(session, &vmRec, argdata.value.ref)) {
918 _SBLIM_TRACE(1,("--- Unable to retrieve domain record from object path"));
919 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Unable to retrieve domain record from object path");
920 rc = 5;
921 goto Exit;
922 }
924 /*
925 * Get input ResourceAllocationSettingData instance
926 * that will be added to domain.
927 */
928 argdata = CMGetArgAt(argsin, 1, NULL, &status);
929 if ((status.rc != CMPI_RC_OK) || CMIsNullValue(argdata)) {
930 _SBLIM_TRACE(1,("--- CMGetArgAt(1) failed"));
931 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Cannot get method input argument");
932 xen_vm_record_free(vmRec);
933 rc = 5;
934 goto Exit;
935 }
937 CMPIInstance* newSettingInst;
938 if (argdata.type == CMPI_string){
939 char* newSetting = CMGetCharPtr(argdata.value.string);
940 _SBLIM_TRACE(2,("--- newSetting=\"%s\"", newSetting));
941 newSettingInst = parse_embedded_instance(newSetting);
942 if (newSettingInst == NULL) { /* parser returns zero for success, non-zero for error */
943 _SBLIM_TRACE(1,("--- Error parsing ResourceSettingData: \"%s\"",newSetting));
944 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Cannot parse ResourceSettingData");
945 rc = 5;
946 goto Exit;
947 }
948 }
949 else if (argdata.type == CMPI_instance) {
950 newSettingInst = argdata.value.inst;
951 }
952 else {
953 _SBLIM_TRACE(1,("--- Invalid setting type - %s", _CMPITypeName(argdata.type)));
954 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Invalid setting type");
955 rc = 5;
956 goto Exit;
957 }
960 CMPIObjectPath *resultSetting;
961 if (!add_resource_to_vm(vmRec, newSettingInst, &resultSetting, namespace, &status))
962 {
963 _SBLIM_TRACE(1,("--- add_resource_to_vm() failed"));
964 /* status set in add_resource_to_vm */
965 xen_vm_record_free(vmRec);
966 rc = 3;
967 goto Exit;
968 }
970 CMAddArg(argsout, "ResultingResourceSetting",
971 (CMPIValue*)&resultSetting, CMPI_ref);
972 xen_vm_record_free(vmRec);
974 _SBLIM_TRACE(2, ("--- AddResourceSetting completed with success"));
975 }
976 else if (strcmp(methodname, "ModifyResourceSettings") == 0) {
977 /* TODO */
978 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_NOT_SUPPORTED, NULL);
979 rc = 1;
980 goto Exit;
981 }
982 else if (strcmp(methodname, "RemoveResourceSettings") == 0) {
983 /* TODO */
984 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_NOT_SUPPORTED, NULL);
985 rc = 1;
986 goto Exit;
987 }
988 else if (strcmp(methodname, "ModifySystemSettings") == 0) {
989 /* TODO */
990 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_NOT_SUPPORTED, NULL);
991 rc = 1;
992 goto Exit;
993 }
994 else if (strcmp(methodname, "DestroySystem") == 0) {
995 /* Check that the method has the correct number of arguments. */
996 if (argsInCount != 1) {
997 _SBLIM_TRACE(1,("--- Incorrect number of method arguments"));
998 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Incorrect number of method arguments");
999 rc = 5;
1000 goto Exit;
1003 /* Get object path of domain */
1004 argdata = CMGetArgAt(argsin, 0, NULL, &status);
1005 if ((status.rc != CMPI_RC_OK) || CMIsNullValue(argdata)) {
1006 _SBLIM_TRACE(1,("--- CMGetArgAt(0) failed"));
1007 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Cannot get method input argument");
1008 rc = 5;
1009 goto Exit;
1012 if ((argdata.type != CMPI_ref) || CMIsNullObject(argdata.value.ref)) {
1013 _SBLIM_TRACE(1,("--- Invalid parameter type - %s", _CMPITypeName(argdata.type)));
1014 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_INVALID_PARAMETER, "Invalid method input argument");
1015 rc = 5;
1016 goto Exit;
1019 CMPIData namedata = CMGetKey(argdata.value.ref, "Name", &status);
1020 char *domainname = CMGetCharPtr(namedata.value.string);
1021 _SBLIM_TRACE(1,("--- domainname = %s", domainname));
1022 xen_vm_set *vms;
1023 if (!xen_vm_get_by_name_label(session->xen, &vms, domainname)) {
1024 _SBLIM_TRACE(1,("--- Target instance not found"));
1025 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_NOT_FOUND, "Target instance not found");
1026 rc = 3;
1027 goto Exit;
1029 assert(vms->size == 1);
1030 xen_vm vm = vms->contents[0];
1031 enum xen_vm_power_state power_state;
1032 if (!xen_vm_get_power_state(session->xen, &power_state, vm)) {
1033 XEN_UTILS_GET_ERROR_STRING(error_msg, session->xen);
1034 _SBLIM_TRACE(1,("--- Unable to retrieve power state of vm - error = %s", error_msg));
1035 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Unable to determine power state of virtual system");
1036 rc = 3;
1037 goto Exit;
1040 _SBLIM_TRACE(1,("--- retrieved power state of vm - %", power_state));
1042 if (power_state != XEN_VM_POWER_STATE_HALTED) {
1043 _SBLIM_TRACE(1,("--- calling xen_vm_clean_shutdown"));
1044 if (!xen_vm_clean_shutdown(session->xen, vm)) {
1045 _SBLIM_TRACE(1, ("--- xen_vm_clean_shutdown() failed"));
1046 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to shutdown VirtualSystem");
1047 rc = 3;
1048 goto Exit;
1052 _SBLIM_TRACE(1,("--- calling xen_vm_destroy"));
1053 if (!xen_vm_destroy(session->xen, vm)) {
1054 _SBLIM_TRACE(1,("--- xen_vm_destroy failed"));
1055 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_FAILED, "Failed to destroy the virtual system");
1056 rc = 3;
1057 goto Exit;
1061 else {
1062 _SBLIM_TRACE(1,("--- Method \"%s\" is not supported", methodname));
1063 CMSetStatusWithChars(_BROKER, &status, CMPI_RC_ERR_METHOD_NOT_AVAILABLE, NULL);
1064 rc = 5;
1065 goto Exit;
1068 Exit:
1070 CMReturnData(results, (CMPIValue *)&rc, CMPI_uint32);
1071 CMReturnDone(results);
1072 _SBLIM_RETURNSTATUS(status);
1076 // ----------------------------------------------------------------------------
1077 // MethodInitialize()
1078 // Perform any necessary initialization immediately after the method provider
1079 // is first loaded.
1080 // ----------------------------------------------------------------------------
1081 static void MethodInitialize(
1082 CMPIMethodMI * self, /* [in] Handle to this provider (i.e. 'self'). */
1083 const CMPIContext * context) /* [in] Additional context info, if any. */
1085 _SBLIM_ENTER("MethodInitialize");
1086 _SBLIM_TRACE(2, ("--- self=\"%s\"", self->ft->miName));
1087 // _SBLIM_TRACE(2, ("--- context=\"%s\"", CMGetCharPtr(CDToString(_BROKER, context, NULL))));
1089 /* Initialized Xen session object. */
1090 if (session == NULL)
1091 xen_utils_xen_init(&session);
1093 _SBLIM_RETURN();
1096 // ============================================================================
1097 // CMPI METHOD PROVIDER FUNCTION TABLE SETUP
1098 // ============================================================================
1099 CMMethodMIStub( , Xen_VirtualSystemManagementService, _BROKER, MethodInitialize(&mi, ctx));
1102 /*
1103 * Wild macro to support adding devices (vbd, vif) to as list of such
1104 * devices. To be used only in create_vm where list of devices is
1105 * collected from the incoming RASDs.
1106 */
1107 #define ADD_DEVICE_TO_LIST(list, device, type) \
1108 { \
1109 if (list == NULL) { \
1110 list = type ## _set_alloc(1); \
1111 if (list == NULL) { \
1112 _SBLIM_TRACE(1, \
1113 ("Cannot malloc memory for xen device settings list")); \
1114 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERROR_SYSTEM, \
1115 "Unable to malloc memory"); \
1116 type ## _free(device); \
1117 goto Error; \
1118 } \
1119 list->size = 1; \
1120 list->contents[0] = device; \
1121 } \
1122 /* List is not empty. Grow the list and add the new device */ \
1123 else { \
1124 int new_len = sizeof(type ## _set) + ((list->size + 1) * sizeof(type)); \
1125 list = realloc(list, new_len); \
1126 if (list == NULL) { \
1127 _SBLIM_TRACE(1, \
1128 ("Cannot malloc memory for xen device settings list")); \
1129 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERROR_SYSTEM, \
1130 "Unable to malloc memory"); \
1131 type ## _free(device); \
1132 goto Error; \
1133 } \
1134 list->contents[list->size] = device; \
1135 list->size++; \
1136 } \
1137 } \
1140 static int create_vm(CMPIInstance* vsSettingsInst,
1141 CMPIArray *resourceSettings,
1142 xen_vm *result, CMPIStatus *status)
1144 CMPIObjectPath *objectpath;
1145 char *settingclassname;
1146 xen_vm_record *vm_rec;
1147 xen_vbd_record_set *vbds = NULL;
1148 xen_vif_record_set *vifs = NULL;
1149 xen_console_record *con_rec = NULL;
1150 xen_vm vm = NULL;
1151 int i;
1152 int ccode;
1153 char error_msg[XEN_UTILS_ERROR_BUF_LEN];
1155 vm_rec = xen_vm_record_alloc();
1156 if (vm_rec == NULL) {
1157 _SBLIM_TRACE(1,("--- Cannot malloc memory for vm record"));
1158 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERROR_SYSTEM, "Unable to malloc memory");
1159 return 0;
1162 objectpath = CMGetObjectPath(vsSettingsInst, NULL);
1163 _SBLIM_TRACE(2,("--- objectpath=%s", CMGetCharPtr(CDToString(_BROKER, objectpath, NULL))));
1165 /* Get the class type of the setting data instance */
1166 settingclassname = CMGetCharPtr(CMGetClassName(objectpath, NULL));
1167 _SBLIM_TRACE(2,("--- settingclassname=%s", settingclassname));
1169 /* Ensure we have a Xen_ComputerSystemSettingData */
1170 if (strcmp(settingclassname,"Xen_ComputerSystemSettingData") != 0) {
1171 _SBLIM_TRACE(1,("--- Unrecognized setting data class - %s", settingclassname));
1172 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "Unrecognized setting data class");
1173 return 0;
1176 /* Convert the domain settings to respective xen settings. */
1177 if (!vssd2xenconfig(vsSettingsInst, vm_rec, status)) {
1178 _SBLIM_TRACE(1,("--- failed to convert VSSD to xen_vmrecord"));
1179 xen_vm_record_free(vm_rec);
1180 return 0;
1183 /* Convert resource settings to their respecitve xen settings. */
1184 CMPIInstance *instance;
1185 char *setting;
1186 for (i = 0; i < CMGetArrayCount(resourceSettings, NULL); i++) {
1187 CMPIData settingdata = CMGetArrayElementAt(resourceSettings, i, status);
1188 if ((status->rc != CMPI_RC_OK) || CMIsNullValue(settingdata)) {
1189 _SBLIM_TRACE(1,("--- CMGetArrayElementAt(%d) failed", i));
1190 goto Error;
1193 /* Check that the array element is an (embedded) instance */
1194 if (settingdata.type == CMPI_string) {
1195 setting = CMGetCharPtr(settingdata.value.string);
1196 _SBLIM_TRACE(2,("--- Got string with embedded instance = %s", setting));
1198 instance = parse_embedded_instance(setting);
1199 if (instance == NULL) {
1200 _SBLIM_TRACE(1,("--- unable to parse setting data %s", setting));
1201 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "Unable to parse resource setting data parameter");
1202 goto Error;
1205 else if (settingdata.type == CMPI_instance) {
1206 instance = settingdata.value.inst;
1207 _SBLIM_TRACE(2,("--- Got embedded instance for setting"));
1209 else {
1210 _SBLIM_TRACE(1,("--- Invalid setting type - %s", _CMPITypeName(settingdata.type)));
1211 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "Invalid resource setting data parameter");
1212 goto Error;
1215 _SBLIM_TRACE(2,("--- instance=%s", CMGetCharPtr(CDToString(_BROKER, instance, NULL))));
1216 objectpath = CMGetObjectPath(instance, NULL);
1217 _SBLIM_TRACE(2,("--- objectpath=%s", CMGetCharPtr(CDToString(_BROKER, objectpath, NULL))));
1219 /* Get the class type of the setting data instance */
1220 settingclassname = CMGetCharPtr(CMGetClassName(objectpath, NULL));
1221 _SBLIM_TRACE(2,("--- settingclassname=%s", settingclassname));
1223 /* Populate config with instance data from the virtual device. */
1224 if (strcmp(settingclassname,"Xen_ProcessorSettingData") == 0) {
1225 _SBLIM_TRACE(2,("--- adding Xen_ProcessorSettingData to configuration"));
1227 if (!proc_rasd2vmconfig(instance, vm_rec, status)) {
1228 _SBLIM_TRACE(1,("--- Error parsing processor settings"));
1229 goto Error;
1232 else if (strcmp(settingclassname,"Xen_MemorySettingData") == 0) {
1233 _SBLIM_TRACE(2,("--- adding Xen_MemorySettingData to configuration"));
1235 /* Fail if duplicate memory rasd's? */
1236 if (vm_rec->memory_dynamic_max > 0) {
1237 _SBLIM_TRACE(1,("--- More than one memroy setting data specified"));
1238 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER,
1239 "More than one memory setting data specified");
1240 goto Error;
1243 if (!mem_rasd2vmconfig(instance, vm_rec, status)) {
1244 _SBLIM_TRACE(1,("--- Error parsing memory settings"));
1245 goto Error;
1248 else if (strcmp(settingclassname,"Xen_DiskSettingData") == 0) {
1249 _SBLIM_TRACE(2,("--- adding Xen_DiskSettingData to configuration"));
1251 xen_vbd_record *vbd_rec;
1252 if (!disk_rasd2vmconfig(instance, &vbd_rec, status)) {
1253 _SBLIM_TRACE(1,("--- Error parsing disk settings"));
1254 goto Error;
1257 ADD_DEVICE_TO_LIST(vbds, vbd_rec, xen_vbd_record);
1259 else if (strcmp(settingclassname,"Xen_NetworkPortSettingData") == 0) {
1260 _SBLIM_TRACE(2,("--- adding Xen_NetworkPortSettingData to configuration"));
1262 xen_vif_record *vif_rec;
1263 if (!nic_rasd2vmconfig(instance, &vif_rec, status)) {
1264 _SBLIM_TRACE(1,("--- Error parsing network port settings"));
1265 goto Error;
1268 ADD_DEVICE_TO_LIST(vifs, vif_rec, xen_vif_record);
1270 else if (strcmp(settingclassname,"Xen_ConsoleSettingData") == 0) {
1271 _SBLIM_TRACE(2,("--- adding Xen_ConsoleSettingData to configuration"));
1273 con_rec = xen_console_record_alloc();
1274 if (con_rec == NULL) {
1275 _SBLIM_TRACE(1,("--- Cannot malloc memory for console record"));
1276 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERROR_SYSTEM, "Unable to malloc memory");
1277 goto Error;
1280 if (!con_rasd2vmconfig(instance, con_rec, status)) {
1281 _SBLIM_TRACE(1,("--- Error parsing console settings"));
1282 goto Error;
1285 else {
1286 _SBLIM_TRACE(1,("--- Unrecognized setting data class - %s", settingclassname));
1287 goto Error;
1291 /* We have all of the settings. First create the vm. */
1292 if (!xen_vm_create(session->xen, &vm, vm_rec)) {
1293 XEN_UTILS_GET_ERROR_STRING(error_msg, session->xen);
1294 _SBLIM_TRACE(1,("--- xen_vm_create failed: %s", error_msg));
1295 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED, error_msg);
1296 goto Error;
1299 xen_vm_record_opt vm_record_opt =
1301 .u.handle = vm
1302 };
1304 /* Add all of the virutal block devices. */
1305 for (i = 0; i < vbds->size; i++) {
1307 xen_vbd_record *vbd_rec = vbds->contents[i];
1308 vbd_rec->vm = &vm_record_opt;
1309 xen_vbd new_vbd;
1310 ccode = xen_vbd_create(session->xen, &new_vbd, vbd_rec);
1311 /* Set vm field of vbd record to NULL so it is not freed */
1312 vbd_rec->vm = NULL;
1313 if (!ccode)
1315 XEN_UTILS_GET_ERROR_STRING(error_msg, session->xen);
1316 _SBLIM_TRACE(1,("--- xen_vdb_create failed: %s", error_msg));
1317 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED, error_msg);
1318 goto Error;
1320 xen_vbd_free(new_vbd);
1323 /* Add all of the virutal network devices. */
1324 for (i = 0; i < vifs->size; i++) {
1325 xen_vif_record *vif_rec = vifs->contents[i];
1326 vif_rec->vm = &vm_record_opt;
1327 xen_vif new_vif;
1328 ccode = xen_vif_create(session->xen, &new_vif, vif_rec);
1329 /* Set vm field of vif record to NULL so it is not freed */
1330 vif_rec->vm = NULL;
1331 if (!ccode)
1333 XEN_UTILS_GET_ERROR_STRING(error_msg, session->xen);
1334 _SBLIM_TRACE(1,("--- xen_vif_create failed %s", error_msg));
1335 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED, error_msg);
1336 goto Error;
1338 xen_vif_free(new_vif);
1341 /* Add console device if specified */
1342 if (con_rec) {
1343 con_rec->vm = &vm_record_opt;
1344 xen_console new_con;
1345 ccode = xen_console_create(session->xen, &new_con, con_rec);
1346 /* Set vm field of console record to NULL so it is not freed */
1347 con_rec->vm = NULL;
1348 if (!ccode)
1350 XEN_UTILS_GET_ERROR_STRING(error_msg, session->xen);
1351 _SBLIM_TRACE(1,("--- xen_console_create failed %s", error_msg));
1352 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED, error_msg);
1353 goto Error;
1355 xen_console_free(new_con);
1358 xen_console_record_free(con_rec);
1359 xen_vbd_record_set_free(vbds);
1360 xen_vif_record_set_free(vifs);
1361 xen_vm_record_free(vm_rec);
1363 *result = vm;
1365 return 1;
1367 /* Unwind if we failed.
1368 * remove_vm will nuke any vifs / vbds created and the vm.
1369 */
1370 Error:
1371 if (vm) {
1372 remove_vm(vm);
1373 xen_vm_free(vm);
1375 xen_console_record_free(con_rec);
1376 xen_vbd_record_set_free(vbds);
1377 xen_vif_record_set_free(vifs);
1378 xen_vm_record_free(vm_rec);
1379 *result = NULL;
1381 return 0;
1385 static int add_resource_to_vm(xen_vm_record *vmRec,
1386 CMPIInstance *sourceSettingInst,
1387 CMPIObjectPath **resultSetting,
1388 char *namespace,
1389 CMPIStatus *status)
1391 CMPIObjectPath *op;
1392 char *settingclassname;
1393 CMPIData propertyvalue;
1394 int ccode;
1395 char instId[MAX_INSTANCEID_LEN];
1396 char error_msg[XEN_UTILS_ERROR_BUF_LEN];
1397 xen_vm_record_opt vm_record_opt =
1399 .u.handle = vmRec->handle
1401 };
1403 _SBLIM_TRACE(2,("--- instance=%s", CMGetCharPtr(CDToString(_BROKER, sourceSettingInst, NULL))));
1404 op = CMGetObjectPath(sourceSettingInst, NULL);
1405 _SBLIM_TRACE(2,("--- objectpath=%s", CMGetCharPtr(CDToString(_BROKER, op, NULL))));
1407 /* Get the class type of the setting data instance */
1408 settingclassname = CMGetCharPtr(CMGetClassName(op, NULL));
1409 _SBLIM_TRACE(2,("--- settingclassname=%s", settingclassname));
1411 /* Add the resource to the domain. */
1412 if (strcmp(settingclassname,"Xen_ProcessorSettingData") == 0) {
1413 #if 1
1414 _SBLIM_TRACE(1,("--- Adding processors not currently supported"));
1415 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED, "Adding processors not currently supported");
1416 return 0;
1418 #else
1419 /* Code for adding processors -- when Xen API supports it. */
1420 _SBLIM_TRACE(2,("--- adding Xen_ProcessorSettingData to configuration"));
1421 propertyvalue = CMGetProperty(sourceSettingInst, "VirtualQuantity", status);
1422 if ((status->rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue)) {
1423 _SBLIM_TRACE(1,("--- Unable to determine VirtualQuantity in Processor RASD"));
1424 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "VirtualQuantity not specified in ResourceSetting");
1425 return 0;
1428 /* Adding cpus means just that - adding to existing amount */
1429 uint64_t cpus = propertyvalue.value.uint64 + vmRec->vcpus_number;
1430 /*
1431 * TODO:
1432 * 1. CPU weights and other scheduling parameters?
1433 */
1434 if (!xen_vm_set_vcpus_number(session->xen,
1435 vmRec->handle,
1436 cpus)) {
1437 XEN_UTILS_GET_ERROR_STRING(error_msg, session->xen);
1438 _SBLIM_TRACE(1,("--- xen_vm_set_vcpus_number failed: %s", error_msg));
1439 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED, error_msg);
1440 return 0;
1443 /* Create new object path for setting */
1444 *resultSetting = CMNewObjectPath(_BROKER, namespace, "Xen_ProcessorSettingData", NULL);
1445 snprintf(instId, MAX_INSTANCEID_LEN, "Xen:%s:Processor", vmRec->name_label);
1446 CMAddKey(*resultSetting, "InstanceID", (CMPIValue *)instId, CMPI_chars);
1447 #endif
1449 else if (strcmp(settingclassname,"Xen_MemorySettingData") == 0) {
1450 #if 1
1451 _SBLIM_TRACE(1,("--- Adding memory not currently supported"));
1452 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED, "Adding memory not currently supported");
1453 return 0;
1455 #else
1456 /* Code for adding memory -- when Xen API supports it. */
1457 _SBLIM_TRACE(2,("--- adding Xen_MemorySettingData to configuration"));
1458 propertyvalue = CMGetProperty(sourceSettingInst, "VirtualQuantity", status);
1459 if ((status->rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue)) {
1460 _SBLIM_TRACE(1,("--- Unable to determine VirtualQuantity in Memory RASD"));
1461 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "VirtualQuantity not specified in ResourceSetting");
1462 return 0;
1465 /* Adding memory means just that - adding to existing amount */
1466 uint64_t mem = propertyvalue.value.uint64 + vmRec->memory_dynamic_max;
1467 if (!xen_vm_set_memory_dynamic_max(session->xen,
1468 vmRec->handle,
1469 mem)) {
1470 XEN_UTILS_GET_ERROR_STRING(error_msg, session->xen);
1471 _SBLIM_TRACE(1,("--- xen_vm_set_memory_dynamic_max failed: %s", error_msg));
1472 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED, error_msg);
1473 return 0;
1476 /* Add object path to output array */
1477 *resultSetting = CMNewObjectPath(_BROKER, namespace, "Xen_MemorySettingData", NULL);
1478 snprintf(instId, MAX_INSTANCEID_LEN, "Xen:%s:Memory1", vmRec->name_label);
1479 CMAddKey(*resultSetting, "InstanceID", (CMPIValue *)instId, CMPI_chars);
1480 #endif
1482 else if (strcmp(settingclassname,"Xen_DiskSettingData") == 0) {
1483 _SBLIM_TRACE(2,("--- adding Xen_DiskSettingData to configuration"));
1485 xen_vbd_record *vbd_rec;
1486 if (!disk_rasd2vmconfig(sourceSettingInst, &vbd_rec, status)) {
1487 /* status set in disk_rasd2vmconfig */
1488 _SBLIM_TRACE(1,("--- Error parsing disk settings"));
1489 return 0;
1492 vbd_rec->vm = &vm_record_opt;
1493 xen_vbd new_vbd;
1494 ccode = xen_vbd_create(session->xen, &new_vbd, vbd_rec);
1495 /* Set vm field of vbd record to NULL so it is not freed */
1496 vbd_rec->vm = NULL;
1497 xen_vbd_record_free(vbd_rec);
1498 if (!ccode)
1500 XEN_UTILS_GET_ERROR_STRING(error_msg, session->xen);
1501 _SBLIM_TRACE(1,("--- xen_vdb_create failed: %s", error_msg));
1502 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED, error_msg);
1503 return 0;
1505 xen_vbd_free(new_vbd);
1507 /* Add object path to output array */
1508 *resultSetting = CMNewObjectPath(_BROKER, namespace, "Xen_DiskSettingData", NULL);
1509 snprintf(instId, MAX_INSTANCEID_LEN, "Xen:%s:Disk", vmRec->name_label);
1510 CMAddKey(*resultSetting, "InstanceID", (CMPIValue *)instId, CMPI_chars);
1512 else if (strcmp(settingclassname,"Xen_NetworkPortSettingData") == 0) {
1513 _SBLIM_TRACE(2,("--- adding Xen_NetworkPortSettingData to configuration"));
1514 xen_vif_record *vif_rec;
1515 if (!nic_rasd2vmconfig(sourceSettingInst, &vif_rec, status)) {
1516 /* status set in disk_rasd2vmconfig */
1517 _SBLIM_TRACE(1,("--- Error parsing network port settings"));
1518 return 0;
1521 vif_rec->vm = &vm_record_opt;
1522 xen_vif new_vif;
1523 ccode = xen_vif_create(session->xen, &new_vif, vif_rec);
1524 /* Set vm field of vif record to NULL so it is not freed */
1525 vif_rec->vm = NULL;
1526 xen_vif_record_free(vif_rec);
1527 if (!ccode)
1529 XEN_UTILS_GET_ERROR_STRING(error_msg, session->xen);
1530 _SBLIM_TRACE(1,("--- xen_vif_create failed %s", error_msg));
1531 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_FAILED, error_msg);
1532 return 0;
1534 xen_vif_free(new_vif);
1536 /* Add object path to output array */
1537 *resultSetting = CMNewObjectPath(_BROKER, namespace, "Xen_NetworkPortSettingData", NULL);
1538 snprintf(instId, MAX_INSTANCEID_LEN, "Xen:%s:Vif", vmRec->name_label);
1539 CMAddKey(*resultSetting, "InstanceID", (CMPIValue *)instId, CMPI_chars);
1541 else {
1542 _SBLIM_TRACE(1,("--- Unrecognized setting data class - %s", settingclassname));
1543 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "Unrecognized ResourceSetting");
1544 return 0;
1547 return 1;
1551 static void remove_vm(xen_vm vm)
1553 xen_vbd_set *vbds;
1554 xen_vif_set *vifs;
1555 int i;
1557 if (xen_vm_get_vbds(session->xen, &vbds, vm)) {
1558 for (i = 0; i < vbds->size; i++)
1559 xen_vbd_destroy(session->xen, vbds->contents[i]);
1562 if (xen_vm_get_vifs(session->xen, &vifs, vm)) {
1563 for (i = 0; i < vifs->size; i++)
1564 xen_vif_destroy(session->xen, vifs->contents[i]);
1567 xen_vm_destroy(session->xen, vm);
1571 static int vssd2xenconfig(CMPIInstance *vssd, xen_vm_record *vm_rec, CMPIStatus *status)
1573 CMPIData propertyvalue;
1574 char *vsType;;
1576 /*
1577 * Get domain name.
1578 * WARNING!
1579 * Do we fail if VirtualSystemIdentifier is not specified?
1580 */
1581 propertyvalue = CMGetProperty(vssd, "VirtualSystemIdentifier", status);
1582 if ((status->rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue)) {
1583 _SBLIM_TRACE(1,("--- failed to retrieve VirtualSystemIndentifier property value"));
1584 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "Unable to retrieve VirtualSystemIdentifier (name) property from virtual system setting data");
1585 return 0;
1587 vm_rec->name_label = strdup(CMGetCharPtr(propertyvalue.value.string));
1589 /* Get UUID, if specified */
1590 propertyvalue = CMGetProperty(vssd, "UUID", status);
1591 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue))
1592 vm_rec->uuid = strdup(CMGetCharPtr(propertyvalue.value.string));
1594 propertyvalue = CMGetProperty(vssd, "localtime", status);
1595 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue))
1596 vm_rec->platform_localtime = propertyvalue.value.boolean;
1598 propertyvalue = CMGetProperty(vssd, "OnPoweroff", status);
1599 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue))
1600 vm_rec->actions_after_shutdown = propertyvalue.value.uint16;
1602 propertyvalue = CMGetProperty(vssd, "OnReboot", status);
1603 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue))
1604 vm_rec->actions_after_reboot = propertyvalue.value.uint16;
1606 propertyvalue = CMGetProperty(vssd, "OnCrash", status);
1607 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue))
1608 vm_rec->actions_after_crash = propertyvalue.value.uint16;
1610 /* Paravirtual or HVM domain? */
1611 propertyvalue = CMGetProperty(vssd, "VirtualSystemType", status);
1612 if ((status->rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue)) {
1613 _SBLIM_TRACE(1,("--- VirtualSystemType not specified"));
1614 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER,
1615 "VirtualSystemType not specified");
1616 return 0;
1619 vsType = CMGetCharPtr(propertyvalue.value.string);
1620 if (vsType == NULL) {
1621 _SBLIM_TRACE(1,("--- VirtualSystemType not specified"));
1622 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER,
1623 "VirtualSystemType not specified");
1624 return 0;
1627 if (strcasecmp(vsType, "Xen Paravirtual") == 0) {
1629 propertyvalue = CMGetProperty(vssd, "Bootloader", status);
1630 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) {
1631 vm_rec->pv_bootloader = strdup(CMGetCharPtr(propertyvalue.value.string));
1633 /* If Bootloader specified, get options. */
1634 /* WARNING!
1635 * Should we ensure that BootloaderOptions is specified if
1636 * Bootloader is specified? For domUloader probably but
1637 * pygrub should work with no options.
1638 */
1639 propertyvalue = CMGetProperty(vssd, "BootloaderOptions", status);
1640 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) {
1641 vm_rec->pv_bootloader_args = strdup(CMGetCharPtr(propertyvalue.value.string));
1645 /* Only honor Kernel if Bootloader not specified. */
1646 propertyvalue = CMGetProperty(vssd, "Kernel", status);
1647 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue) &&
1648 vm_rec->pv_bootloader == NULL) {
1649 vm_rec->pv_kernel = strdup(CMGetCharPtr(propertyvalue.value.string));
1651 /* If Kernel specified, get RAMDisk. */
1652 /* WARNING!
1653 * Should we ensure that RAMDisk is specified if
1654 * Kernel is specified? For Unix'ish guests we probably need
1655 * RAMDisk but what about OS's with no notion of RAMDisk?
1656 */
1657 propertyvalue = CMGetProperty(vssd, "RAMDisk", status);
1658 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) {
1659 vm_rec->pv_ramdisk = strdup(CMGetCharPtr(propertyvalue.value.string));
1663 propertyvalue = CMGetProperty(vssd, "KernelOptions", status);
1664 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) {
1665 vm_rec->pv_args = strdup(CMGetCharPtr(propertyvalue.value.string));
1668 else if (strcasecmp(vsType, "Xen HVM") == 0) {
1669 propertyvalue = CMGetProperty(vssd, "BootOrder", status);
1670 if ((status->rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue)) {
1671 _SBLIM_TRACE(1,("--- No BootOrder specified for HVM guest"));
1672 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER,
1673 "No BootOrder specified for HVM guest");
1674 return 0;
1676 vm_rec->hvm_boot = strdup(CMGetCharPtr(propertyvalue.value.string));
1678 propertyvalue = CMGetProperty(vssd, "stdvga", status);
1679 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue))
1680 vm_rec->platform_std_vga = propertyvalue.value.boolean;
1682 else {
1683 _SBLIM_TRACE(1,("--- Invalid VirtualSystemType %s specified", vsType));
1684 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER,
1685 "Invalid VirtualSystemType specified");
1686 return 0;
1689 return 1;
1693 static int proc_rasd2vmconfig(CMPIInstance *proc_rasd, xen_vm_record *vm_rec,
1694 CMPIStatus *status)
1696 CMPIData propertyvalue;
1698 propertyvalue = CMGetProperty(proc_rasd, "VirtualQuantity", status);
1699 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) {
1700 /*
1701 * TODO:
1702 * 1. Handle defaults if processors not specified.
1703 * 2. CPU weights and other scheduling parameters?
1704 */
1705 vm_rec->vcpus_number = propertyvalue.value.uint64;
1707 return 1;
1710 return 0;
1714 static int mem_rasd2vmconfig(CMPIInstance *mem_rasd, xen_vm_record *vm_rec,
1715 CMPIStatus *status)
1717 CMPIData propertyvalue;
1719 propertyvalue = CMGetProperty(mem_rasd, "VirtualQuantity", status);
1720 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) {
1721 /*
1722 * TODO:
1723 * 1. Handle defaults if memory is not specified.
1724 * 2. What is semantics of these fields? For now
1725 * set them all to the requested value.
1726 */
1727 vm_rec->memory_static_max = propertyvalue.value.uint64;
1728 vm_rec->memory_dynamic_max = propertyvalue.value.uint64;
1729 vm_rec->memory_static_min = propertyvalue.value.uint64;
1730 vm_rec->memory_dynamic_min = propertyvalue.value.uint64;
1732 return 1;
1735 return 0;
1739 static int disk_rasd2vmconfig(CMPIInstance *disk_rasd, xen_vbd_record **vbd_rec,
1740 CMPIStatus *status)
1742 CMPIData propertyvalue;
1744 propertyvalue = CMGetProperty(disk_rasd, "DiskConfigInfo", status);
1745 if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) {
1746 *vbd_rec = xen_vbd_record_alloc();
1747 if (*vbd_rec == NULL) {
1748 _SBLIM_TRACE(1,("--- Cannot malloc memory for virtual block device"));
1749 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERROR_SYSTEM, "Unable to malloc memory");
1750 return 0;
1753 /* Extract the image, dev and mode params from the DiskConfigInfo string */
1754 char *tok;
1755 char *next_tok;
1756 char *string = strdup(CMGetCharPtr(propertyvalue.value.string));
1757 tok = strtok_r(string, ",", &next_tok);
1758 if (tok == NULL) {
1759 _SBLIM_TRACE(1,("--- Malformed DiskConfigInfo property in disk setting data"));
1760 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "Invalid disk setting data");
1761 free(string);
1762 goto Error;
1764 (*vbd_rec)->image = strdup(tok);
1766 if ((tok = strtok_r(NULL, ",", &next_tok)) == NULL) {
1767 _SBLIM_TRACE(1,("--- Malformed DiskConfigInfo property in disk setting data"));
1768 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "Invalid disk setting data");
1769 free(string);
1770 goto Error;
1772 (*vbd_rec)->device = strdup(tok);
1774 if ((tok = strtok_r(NULL, ",", &next_tok)) == NULL) {
1775 _SBLIM_TRACE(1,("--- Malformed DiskConfigInfo property in disk setting data"));
1776 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "Invalid disk setting data");
1777 free(string);
1778 goto Error;
1780 if (strcmp(tok, "w") == 0)
1781 (*vbd_rec)->mode = XEN_VBD_MODE_RW;
1782 else
1783 (*vbd_rec)->mode = XEN_VBD_MODE_RO;
1785 free(string);
1786 _SBLIM_TRACE(2,("--- uname = %s", (*vbd_rec)->image));
1787 _SBLIM_TRACE(2,("--- dev = %s", (*vbd_rec)->device));
1788 _SBLIM_TRACE(2,("--- mode = %s",
1789 (*vbd_rec)->mode == XEN_VBD_MODE_RW ? "RW" : "RO"));
1791 return 1;
1794 Error:
1795 /* frees fields as well */
1796 xen_vbd_record_free(*vbd_rec);
1797 *vbd_rec = NULL;
1799 return 0;
1803 static int nic_rasd2vmconfig(CMPIInstance *nic_rasd, xen_vif_record **vif_rec,
1804 CMPIStatus *status)
1806 CMPIData propertyvalue;
1808 /* Set the domain config data from the Xen_NetworkPortSettingData. */
1809 propertyvalue = CMGetProperty(nic_rasd, "NICConfigInfo", status);
1810 if ((status->rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue)) {
1811 _SBLIM_TRACE(1,("--- No NICConfigInfo specified in network port setting data"));
1812 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "No NICConfigInfo specified in network port setting data");
1814 *vif_rec = NULL;
1815 return 0;
1818 *vif_rec = xen_vif_record_alloc();
1819 if (*vif_rec == NULL) {
1820 _SBLIM_TRACE(1,("--- Cannot malloc memory for virtual network device"));
1821 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERROR_SYSTEM, "Unable to malloc memory");
1822 return 0;
1825 /* Extract the type, mac and network params from the NicConfigInfo
1826 * string. Expected syntax is "key=value,key=value" */
1827 char * next_tok;
1828 char * string = strdup(CMGetCharPtr(propertyvalue.value.string));
1829 char *tok = strtok_r(string, ",", &next_tok);
1830 while (tok) {
1831 if (strncmp(tok, "mac", 3) == 0)
1832 (*vif_rec)->mac = strdup(tok + 4);
1833 /*
1834 * TODO:
1835 * Map other config items in the NIC info to xen_vif_record struct.
1836 */
1838 tok = strtok_r(NULL, ",", &next_tok);
1841 free(string);
1842 _SBLIM_TRACE(2,("--- mac = %s",
1843 (*vif_rec)->mac ? (*vif_rec)->mac : "not specified"));
1845 return 1;
1849 static int con_rasd2vmconfig(CMPIInstance *con_rasd, xen_console_record *con_rec,
1850 CMPIStatus *status)
1852 CMPIStatus local_status = {CMPI_RC_OK, NULL};
1853 CMPIData propertyvalue;
1855 propertyvalue = CMGetProperty(con_rasd, "Protocol", &local_status);
1856 if ((local_status.rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue)) {
1857 _SBLIM_TRACE(1,("--- No protocol field specified in console setting data"));
1858 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "No protocol specified in console setting data");
1859 return 0;
1862 switch (propertyvalue.value.uint16) {
1863 case 0:
1864 con_rec->protocol = XEN_CONSOLE_PROTOCOL_VT100;
1865 break;
1866 case 1:
1867 con_rec->protocol = XEN_CONSOLE_PROTOCOL_RFB;
1868 break;
1869 case 2:
1870 con_rec->protocol = XEN_CONSOLE_PROTOCOL_RDP;
1871 break;
1872 default:
1873 _SBLIM_TRACE(1,("--- Invalid protocol specified in console setting data"));
1874 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "Invalid protocol specified in console setting data");
1875 return 0;
1878 /*
1879 * Get any additional config from ConsoleConfigInfo.
1880 * Expected syntax is "key=value,key=value"
1881 */
1882 propertyvalue = CMGetProperty(con_rasd, "ConsoleConfigInfo", &local_status);
1883 if ((local_status.rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) {
1884 /* Count number of config items */
1885 int num_items = 0;
1886 char *next_tok;
1887 char *string = strdup(CMGetCharPtr(propertyvalue.value.string));
1888 char *tok = strtok_r(string, ",", &next_tok);
1889 while (tok) {
1890 num_items++;
1891 tok = strtok_r(NULL, ",", &next_tok);
1893 free(string);
1895 xen_string_string_map *con_params = xen_string_string_map_alloc(num_items);
1896 if (con_params == NULL) {
1897 _SBLIM_TRACE(1,("--- Cannot malloc memory for console options"));
1898 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERROR_SYSTEM, "Unable to malloc memory");
1899 return 0;
1902 /*
1903 * Go back through the options and populate the string map.
1904 */
1905 string = strdup(CMGetCharPtr(propertyvalue.value.string));
1906 tok = strtok_r(string, ",", &next_tok);
1907 /* If tok is NULL, then string contains only 1 key/value pair */
1908 if (tok == NULL)
1909 tok = string;
1910 int i = 0;
1911 while (tok) {
1912 char *val = strchr(tok, '=');
1913 if (val == NULL) {
1914 _SBLIM_TRACE(1,("--- Invalid console option specified in console setting data"));
1915 CMSetStatusWithChars(_BROKER, status, CMPI_RC_ERR_INVALID_PARAMETER, "Invalid console option specified in console setting data");
1916 xen_string_string_map_free(con_params);
1917 free(string);
1918 return 0;
1920 *val = '\0';
1921 val++;
1922 con_params->contents[i].key = strdup(tok);
1923 con_params->contents[i].val = strdup(val);
1924 i++;
1925 tok = strtok_r(NULL, ",", &next_tok);
1928 con_rec->other_config = con_params;
1929 free(string);
1932 return 1;
1937 // >>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>>
1938 // THE FOLLOWING CODE IS REQUIRED UNTIL EMBEDDEDOBJECT SUPPORT IS WORKING!!!
1939 //
1940 static CMPIInstance *parse_embedded_instance(char *instanceStr)
1942 char filename[L_tmpnam];
1943 FILE *fd;
1944 int rc;
1945 CMPIInstance *instance;
1947 _SBLIM_TRACE(2,("--- parsing instance: \"%s\"", instanceStr));
1949 /* Store the embedded Xen_*SettingData string data in a file for parsing */
1950 tmpnam(filename);
1951 fd = fopen(filename, "w");
1952 fprintf(fd, "%s", instanceStr);
1953 fclose(fd);
1955 fd = fopen(filename, "r");
1956 Xen_SettingDatayyrestart(fd);
1958 /* Parse the embedded Xen_*SettingData string data into a CMPIInstance */
1959 rc = Xen_SettingDatayyparseinstance(_BROKER, &instance);
1960 fclose(fd);
1961 remove(filename);
1962 if (rc != 0) { /* parser returns zero for success, non-zero for error */
1963 _SBLIM_TRACE(1,("--- error parsing instance"));
1964 return NULL;
1967 _SBLIM_TRACE(2,("--- parsed instance: \"%s\"",
1968 CMGetCharPtr(CDToString(_BROKER, instance, NULL))));
1969 return instance;