Esempio n. 1
0
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;

}
Esempio n. 2
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;
}
Esempio n. 3
0
/*****************************************************************************
 * 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;
}
Esempio n. 6
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);
        } 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;
}
Esempio n. 7
0
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;
}
Esempio n. 8
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;
}
Esempio n. 10
0
/*****************************************************************************
 * 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;
}