int kvp_rasd_to_kvp_rec( const CMPIBroker *broker, CMPIInstance *kvp_rasd, kvp *kvp_rec, CMPIStatus *status) { CMPIStatus local_status = {CMPI_RC_OK, NULL}; CMPIData propertyvalue; kvp_rec = malloc(sizeof(kvp)); if(kvp_rec == NULL) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("--- Cannot malloc memory for kvp record")); CMSetStatusWithChars(broker, status, CMPI_RC_ERROR_SYSTEM, "Unable to malloc memory"); goto Error; } propertyvalue = CMGetProperty(kvp_rasd, "key", &local_status); if((local_status.rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue)) { kvp_rec->key = strdup(CMGetCharPtr(propertyvalue.value.string)); } propertyvalue = CMGetProperty(kvp_rasd, "value", &local_status); if((local_status.rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue)) { kvp_rec->value = strdup(CMGetCharPtr(propertyvalue.value.string)); } propertyvalue = CMGetProperty(kvp_rasd, "VM_ID", &local_status); if((local_status.rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue)) { kvp_rec->vm_uuid = strdup(CMGetCharPtr(propertyvalue.value.string)); } return 1; Error: return 0; }
/***************************************************************************** * Modify a backend xen resource identified by the the CIM instance based * on the instance's properties * * @param in broker - CMPI factory service broker * @param in ft - xen backend provider function table * @param in res_id - opaque data identifying the CIM object being modified * @param in caller_id - CIM caller's credentials * @param in modified_res - modifed version of the xen resource * @param in properties - CIM properties that caller cares about * @return CMPIrc error codes *****************************************************************************/ CMPIrc prov_pxy_modify( const CMPIBroker *broker, const XenProviderInstanceFT* ft, const void *res_id, struct xen_call_context *caller_id, const void *modified_res, const char **properties) { (void)properties; CMPIData data; CMPIStatus status = {CMPI_RC_OK, NULL}; char *inst_id; xen_utils_session *session = NULL; _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO,("Modify an Instance")); CMPIInstance *inst = (CMPIInstance *)res_id; if(CMIsNullObject(inst)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("input parameter res_id is invalid")); return CMPI_RC_ERR_FAILED; } CMPIObjectPath *op = CMGetObjectPath(inst, &status); CMPIString *cn = CMGetClassName(op, &status); /* Get target resource */ const char *key_prop = ft->xen_resource_get_key_property(broker, CMGetCharPtr(cn)); data = CMGetProperty(inst, key_prop, &status); if((status.rc != CMPI_RC_OK) || CMIsNullValue(data)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Could not get target resource")); return CMPI_RC_ERR_FAILED; } inst_id = CMGetCharPtr(data.value.string); if((inst_id == NULL) || (*inst_id == '\0')) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Could not get inst id")); return CMPI_RC_ERR_FAILED; } if(!xen_utils_validate_session(&session, caller_id)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("--- Unable to establish connection with Xen")); return CMPI_RC_ERR_FAILED; } /* Call the target provider */ status.rc = ft->xen_resource_modify(broker, res_id, modified_res, properties, status, inst_id, session); xen_utils_cleanup_session(session); return status.rc; }
/***************************************************************************** * Delete a backend xen resource identified by the the CIM instance * * @param in broker - CMPI factory service broker * @param in ft - xen backend provider function table * @param in res_id - opaque data identifying the CIM object being deleted * @param in caller_id - CIM caller's credentials * @return CMPIrc error codes *****************************************************************************/ CMPIrc prov_pxy_delete( const CMPIBroker *broker, const XenProviderInstanceFT* ft, const void *res_id, struct xen_call_context *caller_id ) { CMPIInstance *inst = (CMPIInstance *)res_id; CMPIData data; CMPIStatus status = {CMPI_RC_OK, NULL}; _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Delete an instance")); CMPIObjectPath *op = CMGetObjectPath(inst, &status); CMPIString *cn = CMGetClassName(op, &status); xen_utils_session *session = NULL; if(CMIsNullObject(inst)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Invalid parameter")); return CMPI_RC_ERR_FAILED; } const char *key_prop = ft->xen_resource_get_key_property(broker, CMGetCharPtr(cn)); data = CMGetProperty(inst, key_prop ,&status); if((status.rc != CMPI_RC_OK) || CMIsNullValue(data)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Could not get property")); return CMPI_RC_ERR_FAILED; } char *inst_id = CMGetCharPtr(data.value.string); if((inst_id == NULL) || (*inst_id == '\0')) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Could not get inst id")); return CMPI_RC_ERR_FAILED; } if(!xen_utils_validate_session(&session, caller_id)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,("Unable to establish connection with Xen")); return CMPI_RC_ERR_FAILED; } /* get the object and delete it */ status.rc = ft->xen_resource_delete(broker, session, inst_id); xen_utils_cleanup_session(session); return status.rc; }
/****************************************************************************** * Provider export function * Execute an extrinsic method on the specified CIM instance. *****************************************************************************/ static CMPIStatus xen_resource_invoke_method( CMPIMethodMI * self, /* [in] Handle to this provider (i.e. 'self') */ const CMPIBroker *broker, /* [in] CMPI Factory services */ const CMPIContext * context, /* [in] Additional context info, if any */ const CMPIResult * results, /* [out] Results of this operation */ const CMPIObjectPath * reference, /* [in] Contains the CIM namespace, classname and desired object path */ const char * methodname, /* [in] Name of the method to apply against the reference object */ const CMPIArgs * argsin, /* [in] Method input arguments */ CMPIArgs * argsout) /* [in] Method output arguments */ { CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations. */ char * nameSpace = CMGetCharPtr(CMGetNameSpace(reference, NULL)); /* Target namespace. */ unsigned long rc = 0; CMPIData argdata; xen_utils_session * session = NULL; _SBLIM_ENTER("InvokeMethod"); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("--- self=\"%s\"", self->ft->miName)); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("--- methodname=\"%s\"", methodname)); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("--- namespace=\"%s\"", nameSpace)); struct xen_call_context *ctx = NULL; if(!xen_utils_get_call_context(context, &ctx, &status)){ goto Exit; } if (!xen_utils_validate_session(&session, ctx)) { CMSetStatusWithChars(broker, &status, CMPI_RC_ERR_METHOD_NOT_AVAILABLE, "Unable to connect to Xen"); goto Exit; } int argcount = CMGetArgCount(argsin, NULL); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("--- argsin=%d", argcount)); argdata = CMGetKey(reference, "Name", &status); if((status.rc != CMPI_RC_OK) || CMIsNullValue(argdata)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Couldnt find the Virtual System Migration Service to invoke method on")); goto Exit; } /* Check that the method has the correct number of arguments. */ if(strcmp(methodname, "MigrateVirtualSystemToHost") == 0) { rc = MigrateVirtualSystem(broker, context, argsin, argsout, session, true, false, &status); //CMPIObjectPath* job_instance_op = NULL; //CMAddArg(argsout, "Job", (CMPIValue *)&job_instance_op, CMPI_ref); } else if(strcmp(methodname, "MigrateVirtualSystemToSystem") == 0) { rc = MigrateVirtualSystem(broker, context, argsin, argsout, session, false, false, &status); //CMPIObjectPath* job_instance_op = NULL; //CMAddArg(argsout, "Job", (CMPIValue *)&job_instance_op, CMPI_ref); //CMPIObjectPath* newcomputersystem_instance_op = NULL; //CMAddArg(argsout, "NewComputerSystem", (CMPIValue *)&newcomputersystem_instance_op, CMPI_ref); } else if(strcmp(methodname, "CheckVirtualSystemIsMigratableToHost") == 0) { rc = MigrateVirtualSystem(broker, context, argsin, argsout, session, true, true, &status); } else if(strcmp(methodname, "CheckVirtualSystemIsMigratableToSystem") == 0) { rc = MigrateVirtualSystem(broker, context, argsin, argsout, session, false, true, &status); } else status.rc = CMPI_RC_ERR_METHOD_NOT_FOUND; Exit: if(session) xen_utils_cleanup_session(session); if(ctx) xen_utils_free_call_context(ctx); CMReturnData(results, (CMPIValue *)&rc, CMPI_uint32); CMReturnDone(results); _SBLIM_RETURNSTATUS(status); }
/****************************************************************************** * checks for migratability or actually does the migration ******************************************************************************/ int MigrateVirtualSystem( const CMPIBroker *broker, /* in - CMPI Broker that does most of the work */ const CMPIContext *context, /* in - CMPI context for the caller */ const CMPIArgs *argsin, /* in - All the arguments for the method */ const CMPIArgs *argsout, /* out - All the output arguments for the method */ xen_utils_session *session, /* in - Session for making xen calls */ bool host_ip, /* in - The host parameter is an IP address */ bool migrate_check_only, /* in -Check if migration is possible only, dont actually migrate */ CMPIStatus *status) /* out - Report CMPI status of method */ { char *hostid = NULL, *vm_uuid = NULL; CMPIData argdata; xen_vm vm = NULL; xen_host_set *host_set = NULL; CMPIInstance *msd = NULL; xen_host host = NULL; int rc = Xen_VirtualSystemMigrationService_MigrateVirtualSystemToSystem_Invalid_Parameter; CMPIrc statusrc = CMPI_RC_ERR_INVALID_PARAMETER; char *error_msg = "ERROR: Unknown error"; xen_string_string_map *other_config=NULL; /* For now only Live migrations are supported */ if(_GetArgument(broker, argsin, "MigrationSettingData", CMPI_chars, &argdata, status)) { /* Argument passed in as a MOF string, parse it */ msd = xen_utils_parse_embedded_instance(broker, CMGetCharPtr(argdata.value.string)); if (msd == NULL) { // parser returns zero for success, non-zero for error error_msg = "ERROR: Couldnt parse the 'MigrationSettingData' parameter"; goto Exit; } } else /* Argument could have been passed in as an intance */ if(_GetArgument(broker, argsin, "MigrationSettingData", CMPI_instance, &argdata, status)) msd = argdata.value.inst; if(msd != NULL) { CMPIData data = CMGetProperty(msd, "MigrationType", status); if(data.value.uint16 != Xen_VirtualSystemMigrationSettingData_MigrationType_Live) { error_msg = "ERROR: 'MigrationSettingData' contains an invalid MigrationType (Live expected)"; goto Exit; } } /* Host to migrate to */ if(!host_ip) { /* required parameters */ if(!_GetArgument(broker, argsin, "DestinationSystem", CMPI_ref, &argdata, status)){ error_msg = "ERROR: 'DestionationSystem' parameter is missing"; goto Exit; } else { /* This is the CIM reference to an existing Host object */ CMPIData key; key = CMGetKey(argdata.value.ref, "Name", status); if(status->rc != CMPI_RC_OK || CMIsNullValue(key)) { error_msg = "ERROR: 'DestinationSystem' is missing the required 'Name' key"; goto Exit; } hostid = CMGetCharPtr(key.value.string); if(!xen_host_get_by_uuid(session->xen, &host, hostid)) goto Exit; } } else { if(!_GetArgument(broker, argsin, "DestinationHost", CMPI_string, &argdata, status)) { error_msg = "ERROR: 'DestinationHost' parameter is missing"; goto Exit; } else { /* Determing Xen host based on IP address,. Cannot use inet_pton() and so on since DNS may not have been configured properly */ hostid = CMGetCharPtr(argdata.value.string); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Trying to migrate to DestinationHost : %s", hostid)); if(!xen_host_get_all(session->xen, &host_set)) goto Exit; int i=0; for (i=0; i<host_set->size; i++) { xen_host_record *host_rec = NULL; if(!xen_host_get_record(session->xen, &host_rec, host_set->contents[i])) goto Exit; /* DestinationHost could be an IP address or the hostname */ if((host_rec->address && (strcmp(hostid, host_rec->address) == 0)) || (host_rec->hostname && (strcmp(hostid, host_rec->hostname) == 0)) || (host_rec->name_label && (strcmp(hostid, host_rec->name_label) == 0))) { xen_host_record_free(host_rec); host = host_set->contents[i]; host_set->contents[i] = NULL; /* dont free this one */ break; } xen_host_record_free(host_rec); } } } /* VM to migrate - required parameter */ if(!_GetArgument(broker, argsin, "ComputerSystem", CMPI_ref, &argdata, status)) { if(!_GetArgument(broker, argsin, "ComputerSystem", CMPI_string, &argdata, status)) { error_msg = "ERROR: Missing the required 'ComputerSystem' parameter"; goto Exit; } else vm_uuid = CMGetCharPtr(argdata.value.string); } else { argdata = CMGetKey(argdata.value.ref, "Name", status); if(status->rc != CMPI_RC_OK || CMIsNullValue(argdata)) { error_msg = "ERROR: ComputerSystem is missing the required 'Name' key"; goto Exit; } vm_uuid = CMGetCharPtr(argdata.value.string); } status->rc = CMPI_RC_ERR_FAILED; rc = Xen_VirtualSystemMigrationService_MigrateVirtualSystemToSystem_Failed; if(xen_vm_get_by_uuid(session->xen, &vm, vm_uuid)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Migrating %s to %s", vm_uuid, hostid)); if(migrate_check_only) { /* Check to see if migration is possible */ statusrc = CMPI_RC_OK; rc = Xen_VirtualSystemMigrationService_MigrateVirtualSystemToSystem_Completed_with_No_Error; bool migratable = xen_vm_assert_can_boot_here(session->xen, vm, host); if(migratable == false || !session->xen->ok) { migratable = false; // Workaround for kvp migration if(session->xen->error_description_count==1) { if(xen_vm_get_other_config(session->xen, &other_config, vm)) { if(xen_utils_get_from_string_string_map(other_config, "kvp_enabled")) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Overwriting migratable to mark kvp vm as migratable, although its network")); migratable=true; RESET_XEN_ERROR(session->xen); } free(other_config); } else { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Could not get other config.")); } } if(migratable == false && session->xen->error_description) { /* This is not part of the MOF (and is not documented), but nice to have */ char *xen_error = xen_utils_get_xen_error(session->xen); CMAddArg(argsout, "Reason", (CMPIValue *)xen_error, CMPI_chars); free(xen_error); } } CMAddArg(argsout, "IsMigratable", (CMPIValue *)&migratable, CMPI_boolean); } else { /* Do the actual migration, this could take a few minutes */ CMPIObjectPath* job_instance_op = NULL; migrate_job_context *job_context = calloc(1, sizeof(migrate_job_context)); if(!job_context) { error_msg = "ERROR: Couldn't allocate memory for the migrate job."; goto Exit; } job_context->vm = vm; job_context->host = host; if(!job_create(broker, context, session, MIGRATE_VM_TASK_NAME, vm_uuid, migrate_task, job_context, &job_instance_op, status)) { error_msg = "ERROR: Couldn't prepare the Migrate job. Job wasnt started."; goto Exit; } statusrc = CMPI_RC_OK; rc = Xen_VirtualSystemMigrationService_MigrateVirtualSystemToHost_Method_Parameters_Checked___Job_Started; CMAddArg(argsout, "Job", (CMPIValue *)&job_instance_op, CMPI_ref); vm = NULL; /* freed by async thread */ host = NULL; /* freed by async thread */ } } Exit: if(host) xen_host_free(host); if(vm) xen_vm_free(vm); if(host_set) xen_host_set_free(host_set); xen_utils_set_status(broker, status, statusrc, error_msg, session->xen); return rc; }
CMPIStatus TestMethodProviderInvokeMethod ( CMPIMethodMI * mi, const CMPIContext * ctx, const CMPIResult * rslt, const CMPIObjectPath * ref, const char *methodName, const CMPIArgs * in, CMPIArgs * out) { CMPIStatus rc = { CMPI_RC_OK, NULL }; CMPIString *className; CMPIData data; char result[80] = "Hello,"; const char *strCat; const char * name; char *argName = "Message"; CMPIString * str1; CMPIString * str2; CMPIValue val1, val2; /* get the class name from object-path */ className = CMGetClassName(ref, &rc); /* get a pointer to a C char* representation of this String. */ name = CMGetCharsPtr(className, &rc); if(!strcmp(name, _ClassName)) { if(!strcmp ("SayHello", methodName)) { /* gets the number of arguments contained in "in" Args. */ if(CMGetArgCount(in, &rc) > 0) { /* gets a Name argument value */ data = CMGetArg(in, "Name", &rc); /*check for data type and not null value of argument value recieved */ if(data.type == CMPI_string && !(CMIsNullValue(data))) { strCat = CMGetCharsPtr(data.value.string, &rc); strcat(result, strCat); // strcat(result, "!"); /* create the new string to return to client */ str1 = CMNewString(_broker, result, &rc); val1.string = str1; } } else { str1 = CMNewString(_broker, result, &rc); val1.string = str1; } /* create string to add to an array */ str2 = CMNewString(_broker,"Have a good day", &rc); val2.string = str2; /* Adds a value of str2 string to out array argument */ rc = CMAddArg(out, argName, &val2, CMPI_string); } else if (!strcmp("CheckArrayNoType", methodName)) { data = CMGetArg(in, "IntArray", &rc); CMPIType atype=data.value.array->ft->getSimpleType(data.value.array,&rc); sprintf(result,"Datatype is %s",paramType(atype)); str1 = CMNewString(_broker, result, &rc); val1.string = str1; } } CMReturnData (rslt, (CMPIValue *) &val1, CMPI_string); CMReturnDone (rslt); return rc; }
int main() { CMCIClient * cc; CMPIObjectPath * objectpath; CMPIStatus status; CMPIArgs * args; char *cim_host, *cim_host_passwd, *cim_host_userid; CMPIData retval; CMPIValue arg; /* Setup a connection to the CIMOM */ cim_host = getenv("CIM_HOST"); if (cim_host == NULL) cim_host = "localhost"; cim_host_userid = getenv("CIM_HOST_USERID"); if (cim_host_userid == NULL) cim_host_userid = "root"; cim_host_passwd = getenv("CIM_HOST_PASSWD"); if (cim_host_passwd == NULL) cim_host_passwd = "password"; cc = cmciConnect(cim_host, NULL, "5988", cim_host_userid, cim_host_passwd, NULL); printf("\n----------------------------------------------------------\n"); printf("Testing invokeMethod() ...\n"); objectpath = newCMPIObjectPath("root/cimv2", "TST_MethodProperties", NULL); CMAddKey(objectpath, "CreationClassName", "TST_MethodProperties", CMPI_chars); CMAddKey(objectpath, "Id", "Instance #1", CMPI_chars); /*---------------------------------------------------------------------*/ printf("+++T1:passing IN int16_t argument\n"); args = newCMPIArgs(NULL); arg.sint16 = 65535; args->ft->addArg(args, "Property_int16", &arg, CMPI_sint16); retval = cc->ft->invokeMethod( cc, objectpath, "Method_sint16_in", args, NULL, &status); /* Print the results */ printf( "invokeMethod() rc=%d, msg=%s\n", status.rc, (status.msg)? (char *)status.msg->hdl : NULL); if (args) CMRelease(args); if (status.msg) CMRelease(status.msg); if (!status.rc) { char *cv = value2Chars(retval.type,&(retval.value)); printf("result(s):\n\treturn value:%s\n", cv); if (cv != NULL) free(cv); } else goto done; /*---------------------------------------------------------------------*/ printf("+++T2:returning int16_t value\n"); retval = cc->ft->invokeMethod( cc, objectpath, "Method_sint16", NULL, NULL, &status); /* Print the results */ printf( "invokeMethod() rc=%d, msg=%s\n", status.rc, (status.msg)? (char *)status.msg->hdl : NULL); if (!status.rc) { char *cv = value2Chars(retval.type,&(retval.value)); printf("result(s):\n\treturn value:%s\n", cv); if (cv != NULL) free(cv); } if (status.msg) CMRelease(status.msg); /*---------------------------------------------------------------------*/ printf("+++ T3:passing OUT int16_t value\n"); args = newCMPIArgs(NULL); retval = cc->ft->invokeMethod( cc, objectpath, "Method_sint16_out", NULL, args, &status); /* Print the results */ printf( "invokeMethod() rc=%d, msg=%s\n", status.rc, (status.msg)? (char *)status.msg->hdl : NULL); if (args) { char *cv; CMPIData data = CMGetArg(args, "Arg_int16", NULL); if (!CMIsNullValue(data)) { cv = value2Chars(data.type,&(data.value)); printf("\n result(s): OUT Parm:Arg_int16 type: %d value:%s\n", data.type, cv); if (cv != NULL) free(cv); CMRelease(args); } } if (status.msg) CMRelease(status.msg); if (!status.rc) { char *cv = value2Chars(retval.type,&(retval.value)); printf("result(s):\n\treturn value:%s\n", cv); if (cv != NULL) free(cv); } else goto done; /*---------------------------------------------------------------------*/ done: if (objectpath) CMRelease(objectpath); if (cc) CMRelease(cc); return 0; }
/****************************************************************************** * disk_rasd_to_vbd * * This function attempts to parse a Xen_Disk CIM instance and populate a new * VBD record. It also gets the record to the VDI that the VBD attaches to (could * be a newly created VDI, if requested) and a handle to an existing SR as * pointed to by the PoolID field in the CIM instance * * Returns 1 on Success and 0 on failure. *******************************************************************************/ int disk_rasd_to_vbd( const CMPIBroker *broker, xen_utils_session* session, CMPIInstance *disk_rasd, xen_vbd_record **vbd_rec, xen_vdi_record **vdi_rec, xen_sr *sr, CMPIStatus *status) { CMPIData propertyvalue; char *error_msg = "ERROR: Unknown error"; char *sr_label = NULL, *vdi_name_label = NULL, *vdi_name_desc = NULL; char *vbd_device = NULL, *vbd_uuid = NULL, *vdi_uuid = NULL; enum xen_vbd_type vbd_type = XEN_VBD_TYPE_DISK; /* default with Disk (as opposed to CDRom) */ enum xen_vdi_type vdi_type = XEN_VDI_TYPE_USER; bool vbd_readonly = false, vbd_bootable = false;/* defaults for Disk type */ int vbd_mode= XEN_VBD_MODE_RW; /* defaults for Disk type */ int64_t disk_size = -1; /* for CDRoms - this is the size expected */ char buf[MAX_INSTANCEID_LEN]; *vbd_rec = NULL; *vdi_rec = NULL; /* only resource types of 15,16 and 19 are currently supported */ int rc = CMPI_RC_ERR_INVALID_PARAMETER; propertyvalue = CMGetProperty(disk_rasd, "ResourceType", status); if ((status->rc != CMPI_RC_OK) || CMIsNullValue(propertyvalue)) { error_msg = "ERROR: Xen_DiskSettingData has no ResourceType"; goto Error; } int res_type = propertyvalue.value.uint16; if ((res_type == DMTF_ResourceType_CD_Drive) || (res_type == DMTF_ResourceType_DVD_drive)) { vbd_mode = XEN_VBD_MODE_RO; vbd_type = XEN_VBD_TYPE_CD; } else if ((res_type == DMTF_ResourceType_Storage_Extent) || (res_type == DMTF_ResourceType_Disk_Drive)) vbd_type = XEN_VBD_TYPE_DISK; else { error_msg = "ERROR: Xen_DiskSettingData has unsupported ResourceType"; goto Error; } /* Get the instance ID which has the device's UUID in it, if its available This will be usd during deletes and not used during create*/ propertyvalue = CMGetProperty(disk_rasd, "InstanceID", status); if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) { _CMPIStrncpyDeviceNameFromID(buf, CMGetCharPtr(propertyvalue.value.string), sizeof(buf)/sizeof(buf[0])); vbd_uuid = strdup(buf); } /* The HostResource property is used to identify the VDI, if available */ propertyvalue = CMGetProperty(disk_rasd, "HostResource", status); if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) { /* HostResource is always in WBEM URI format and it points to a Xen_DiskImage object reference. Convert it to CMPIObjectPath */ CMPIData data = CMGetArrayElementAt(propertyvalue.value.array, 0, NULL); CMPIObjectPath *obj_path = xen_utils_WBEM_URI_to_CMPIObjectPath( broker, CMGetCharPtr(data.value.string)); if (obj_path) { /* this should be a Xen_DiskImage object reference */ /* Get the DeviceID key */ propertyvalue = CMGetKey(obj_path, "DeviceID", status); if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue) && propertyvalue.type == CMPI_string) { memset(buf, 0, sizeof(buf)); _CMPIStrncpyDeviceNameFromID(buf, CMGetCharPtr(propertyvalue.value.string), sizeof(buf)/sizeof(buf[0])); vdi_uuid = strdup(buf); } } } if (!vdi_uuid) { /* second chance, Try the HostExtentName */ propertyvalue = CMGetProperty(disk_rasd, "HostExtentName", status); if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) vdi_uuid = strdup(CMGetCharPtr(propertyvalue.value.string)); } /* Device is specified as the address on the host bus */ propertyvalue = CMGetProperty(disk_rasd, "AddressOnParent", status); if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) vbd_device = strdup(CMGetCharPtr(propertyvalue.value.string)); propertyvalue = CMGetProperty(disk_rasd, "Bootable", status); if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) vbd_bootable = propertyvalue.value.boolean; propertyvalue = CMGetProperty(disk_rasd, "Access", status); if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) { if (propertyvalue.value.uint16 == Access_Readable) vbd_mode = XEN_VBD_MODE_RO; } /* * The Pool ID property is used to identify the Xen SR * This could be NULL if VDIs are reused or if * the VBD has to be created on the default SR. */ propertyvalue = CMGetProperty(disk_rasd, "PoolID", status); if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) { char *poolid = CMGetCharPtr(propertyvalue.value.string); if (poolid && (*poolid != '\0')) sr_label = strdup(poolid); } propertyvalue = CMGetProperty(disk_rasd, "ElementName", status); if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) vdi_name_label = strdup(CMGetCharPtr(propertyvalue.value.string)); propertyvalue = CMGetProperty(disk_rasd, "Description", status); if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) vdi_name_desc = strdup(CMGetCharPtr(propertyvalue.value.string)); /* Get the disk size from the CIM instance - * If this is a new disk, this property is required * If we are instantiating a CDRom VDI, this is not required */ int64_t multiplier = 1; /* default to bytes */ propertyvalue = CMGetProperty(disk_rasd, "AllocationUnits", status); if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) { char *units = CMGetCharPtr(propertyvalue.value.string); if ((multiplier = xen_utils_get_alloc_units(units)) == 0) { error_msg = "ERROR: Xen_DiskSettingData has unsupported AllocationUnits"; goto Error; } } /* Limit and VirtualQuantity properties mean the same when we create the VBD */ propertyvalue = CMGetProperty(disk_rasd, "VirtualQuantity", status); if ((status->rc == CMPI_RC_OK) && !CMIsNullValue(propertyvalue)) disk_size = (propertyvalue.value.uint64) * multiplier; if (vbd_type == XEN_VBD_TYPE_CD) vdi_type = XEN_VDI_TYPE_USER; /* We have enough information... create the Xen device records so we can */ /* create new devices or identify existing ones */ /* Create the VDI device record */ rc = CMPI_RC_ERR_FAILED; *vdi_rec = xen_vdi_record_alloc(); if (*vdi_rec == NULL) { error_msg = "ERROR: Unable to malloc memory"; goto Error; } (*vdi_rec)->virtual_size = disk_size; #if OSS_XENAPI (*vdi_rec)->other_config = xen_string_string_map_alloc(0); vdi_location = ""; (*vdi_rec)->other_config->contents[0].key= strdup("location"); (*vdi_rec)->other_config->contents[0].val = strdup(vdi_location); (*vdi_rec)->other_config->size = 1; #else (*vdi_rec)->other_config = xen_string_string_map_alloc(0); (*vdi_rec)->other_config->size = 0; #endif (*vdi_rec)->type = vdi_type; (*vdi_rec)->read_only = vbd_readonly; (*vdi_rec)->name_label = vdi_name_label; (*vdi_rec)->name_description = vdi_name_desc; #if XENAPI_VERSION > 400 (*vdi_rec)->managed = true; #endif /* If VDI has already been created, use it */ if (vdi_uuid) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("VDI specified in the RASD: -%s-", vdi_uuid)); (*vdi_rec)->uuid = vdi_uuid; } /* create the VBD record */ *vbd_rec = xen_vbd_record_alloc(); if (*vbd_rec == NULL) { error_msg = "ERROR: Unable to malloc memory"; goto Error; } if (vbd_uuid) (*vbd_rec)->uuid = vbd_uuid; #if XENAPI_VERSION > 400 if (vbd_device) (*vbd_rec)->userdevice = vbd_device; (*vbd_rec)->other_config = xen_string_string_map_alloc(0); #endif (*vbd_rec)->bootable = vbd_bootable; (*vbd_rec)->mode = vbd_mode; (*vbd_rec)->type = vbd_type; (*vbd_rec)->qos_algorithm_params = xen_string_string_map_alloc(0); if (vbd_type == XEN_VBD_TYPE_CD) (*vdi_rec)->sharable = true; else (*vdi_rec)->sharable = false; /* Identify the Storage Repository where this VDI will be created (if its being created) */ if (sr_label) { if (!_get_sr(broker, session, sr_label, true, sr, status)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("--- getting SR for %s failed", sr_label)); goto Error; } free(sr_label); } return 1; Error: if (sr_label) free(sr_label); if (vdi_name_label) { free(vdi_name_label); if (*vdi_rec) (*vdi_rec)->name_label = NULL; } if(vdi_name_desc) { free(vdi_name_desc); } if(vbd_device) { free(vbd_device); } if(vbd_uuid) { free(vbd_uuid); } /* frees fields as well */ if (*vbd_rec) { xen_vbd_record_free(*vbd_rec); *vbd_rec = NULL; } if (*vdi_rec) { xen_vdi_record_free(*vdi_rec); *vdi_rec = NULL; } xen_utils_set_status(broker, status, rc, error_msg, session->xen); return 0; }
CMPIStatus TestMethodProviderInvokeMethod(CMPIMethodMI * mi, const CMPIContext *ctx, const CMPIResult *rslt, const CMPIObjectPath * ref, const char *methodName, const CMPIArgs * in, CMPIArgs * out) { CMPIStatus rc = { CMPI_RC_OK, NULL }; CMPIString *className; CMPIData data; char result[80] = "Hello,"; const char *strCat; const char *name; char *argName = "Message"; CMPIString *str1; CMPIString *str2; CMPIValue val1, val2; /* * get the class name from object-path */ className = CMGetClassName(ref, &rc); /* * get a pointer to a C char* representation of this String. */ name = CMGetCharsPtr(className, &rc); if (!strcmp(name, _ClassName)) { if (!strcmp("SayHello", methodName)) { /* * gets the number of arguments contained in "in" Args. */ if (CMGetArgCount(in, &rc) > 0) { /* * gets a Name argument value */ data = CMGetArg(in, "Name", &rc); /* * check for data type and not null value of argument value * recieved */ if (data.type == CMPI_string && !(CMIsNullValue(data))) { strCat = CMGetCharsPtr(data.value.string, &rc); strcat(result, strCat); // strcat(result, "!"); /* * create the new string to return to client */ str1 = CMNewString(_broker, result, &rc); val1.string = str1; } } else { str1 = CMNewString(_broker, result, &rc); val1.string = str1; } /* * create string to add to an array */ str2 = CMNewString(_broker, "Have a good day", &rc); val2.string = str2; /* * Adds a value of str2 string to out array argument */ rc = CMAddArg(out, argName, &val2, CMPI_string); /* * For: 3048960 method array types not filled in Test provider. */ } else if (!strcmp("CheckArrayNoType", methodName)) { data = CMGetArg(in, "IntArray", &rc); CMPIType atype=data.value.array->ft->getSimpleType(data.value.array,&rc); sprintf(result,"Datatype is %s",paramType(atype)); str1 = CMNewString(_broker, result, &rc); val1.string = str1; /* * This method simulates various provider problems for testing. */ } else if (!strcmp("Misbehave", methodName)) { data = CMGetArg(in, "Action", &rc); const char *strval = NULL; if (data.type == CMPI_string && !(CMIsNullValue(data))) { strval = CMGetCharsPtr(data.value.string, &rc); sprintf(result, "data type is %s, value = %s", paramType(data.type), strval); if (!strcmp(strval,"hang")) { while(sleep(60)); /* to test req handler timeout, etc. */ } else if (!strcmp(strval,"abort")) { abort(); } else if (!strcmp(strval,"fpe")) { #pragma GCC diagnostic ignored "-Wdiv-by-zero" fprintf(stderr,"ouch! %d\n",1/0); #pragma GCC diagnostic warning "-Wdiv-by-zero" } else if (!strcmp(strval,"segfault")) { void (*crashme)(void) = NULL; crashme(); } /* * These tend to behave as if the condition were raised internally */ else if (!strcmp(strval,"sigabrt")) { kill(getpid(), SIGABRT); while(sleep(3)); /* slight pause to ensure we catch signal */ } else if (!strcmp(strval,"sigfpe")) { kill(getpid(), SIGFPE); while(sleep(3)); } else if (!strcmp(strval,"sigsegv")) { kill(getpid(), SIGSEGV); while(sleep(3)); } else if (!strcmp(strval,"sigusr1")) { kill(getpid(), SIGUSR1); /* as if we received a signal from stopBroker() */ while(sleep(3)); } else if (!strcmp(strval,"sigkill")) { kill(getpid(), SIGKILL); /* this is currently not handled by providerDrv*/ while(sleep(3)); } else { sprintf(result, "Action not recognized: %s", strval); fprintf(stderr, "+++ cmpiTestMethodProvider: Action not recognized \"%s\"\n", strval); } /* * create the new string to return to client */ str1 = CMNewString(_broker, result, &rc); val1.string = str1; } } else { sprintf(result, "Unknown method name: %s", methodName); fprintf(stderr, "+++ cmpiTestMethodProvider: Unknown method name \"%s\"\n", methodName); str1 = CMNewString(_broker, result, &rc); val1.string = str1; } } CMReturnData(rslt, (CMPIValue *) & val1, CMPI_string); CMReturnDone(rslt); return rc; }
/***************************************************************************** * Gets a specific xen resource identified by the CIM Instance passed in * * @param in broker - CMPI Broker services * @param in ft - xen backend provider function table * @param in res_id - resource identifying xen object being requested * @param in caller_id - CIM Caller's credentials * @param in properties - CIM properties caller's interested in * @param out res - xen provider resource * @return CMPIrc error codes *****************************************************************************/ CMPIrc prov_pxy_get( const CMPIBroker *broker, const XenProviderInstanceFT* ft, const void *res_id, struct xen_call_context * caller_id, const char **properties, void **res ) { CMPIInstance *inst = (CMPIInstance *)res_id; xen_utils_session *session = NULL; CMPIData data; static CMPIrc rc = CMPI_RC_OK; char *res_uuid=NULL; CMPIStatus status = {CMPI_RC_OK, NULL}; (void)properties; CMPIObjectPath *op = CMGetObjectPath(inst, &status); CMPIString *cn = CMGetClassName(op, &status); if(CMIsNullObject(inst) || res == NULL) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,("Error get(): inst or res is NULL")); return CMPI_RC_ERR_FAILED; } const char *key_prop = ft->xen_resource_get_key_property(broker, CMGetCharPtr(cn)); data = CMGetProperty(inst, key_prop ,&status); if((status.rc != CMPI_RC_OK) || CMIsNullValue(data)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Error key_property %s couldnt be found for class %s", key_prop, CMGetCharPtr(cn))); return CMPI_RC_ERR_INVALID_PARAMETER; } /* Extract the resource identifier string from the CMPIString. */ res_uuid = CMGetCharPtr(data.value.string); if(res_uuid == NULL) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Unable to extrace resource identifier string")); return CMPI_RC_ERR_FAILED; } if(!xen_utils_validate_session(&session, caller_id)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Unable to establish connection with Xen")); return CMPI_RC_ERR_FAILED; } provider_resource *prov_res = calloc(1, sizeof(provider_resource)); if(prov_res == NULL) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Out of memory")); return CMPI_RC_ERR_FAILED; } prov_res->broker = broker; prov_res->classname = CMGetCharPtr(cn); prov_res->session = session; prov_res->cleanupsession = true; rc = ft->xen_resource_record_get_from_id(res_uuid, session, prov_res); if(rc != CMPI_RC_OK) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,("Error get(): get_xen_resource_record_from_id failed")); ft->xen_resource_record_cleanup(prov_res); xen_utils_cleanup_session(session); free(prov_res); return rc; } *res = (void *)prov_res; rc = CMPI_RC_OK; return rc; }