/* * GetInstance() - return the instance data for the specified instance only */ static CMPIStatus GetInstance(CMPIInstanceMI * self, const CMPIContext * context, const CMPIResult * results, const CMPIObjectPath * reference, const char ** properties) { Target_Type _context; Target_Type _result; Target_Type _reference; Target_Type _properties; CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations */ _SBLIM_TRACE(1,("GetInstance() called, self %p, context %p, results %p, reference %p, properties %p", self, context, results, reference, properties)); TARGET_THREAD_BEGIN_BLOCK; _context = SWIG_NewPointerObj((void*) context, SWIGTYPE_p__CMPIContext, 0); _result = SWIG_NewPointerObj((void*) results, SWIGTYPE_p__CMPIResult, 0); _reference = SWIG_NewPointerObj((void*) reference, SWIGTYPE_p__CMPIObjectPath, 0); _properties = proplist2target(properties); /* For Python, TargetCall() packs all arguments into a tuple and releases this tuple, * effectively DECREFing all elements */ TargetCall((ProviderMIHandle*)self->hdl, &status, "get_instance", 4, _context, _result, _reference, _properties); TARGET_THREAD_END_BLOCK; _SBLIM_TRACE(1,("GetInstance() %s", (status.rc == CMPI_RC_OK)? "succeeded":"failed")); return status; }
/* * EnumInstances() - return a list of all the instances (i.e. return all the instance data) */ static CMPIStatus EnumInstances(CMPIInstanceMI * self, const CMPIContext * context, const CMPIResult * result, const CMPIObjectPath * reference, const char ** properties) { Target_Type _context; Target_Type _result; Target_Type _reference; Target_Type _properties; CMPIStatus status = {CMPI_RC_OK, NULL}; /* Return status of CIM operations */ /* char * namespace = CMGetCharPtr(CMGetNameSpace(reference, NULL)); Our current CIM namespace */ _SBLIM_TRACE(1,("EnumInstances() called, self %p, context %p, result %p, reference %p, properties %p", self, context, result, reference, properties)); TARGET_THREAD_BEGIN_BLOCK; _context = SWIG_NewPointerObj((void*) context, SWIGTYPE_p__CMPIContext, 0); _result = SWIG_NewPointerObj((void*) result, SWIGTYPE_p__CMPIResult, 0); _reference = SWIG_NewPointerObj((void*) reference, SWIGTYPE_p__CMPIObjectPath, 0); _properties = proplist2target(properties); TargetCall((ProviderMIHandle*)self->hdl, &status, "enum_instances", 4, _context, _result, _reference, _properties); TARGET_THREAD_END_BLOCK; _SBLIM_TRACE(1,("EnumInstances() %s", (status.rc == CMPI_RC_OK)? "succeeded":"failed")); return status; }
/* * CreateInstance() - create a new instance from the specified instance data. */ static CMPIStatus CreateInstance(CMPIInstanceMI * self, const CMPIContext * context, const CMPIResult * results, const CMPIObjectPath * reference, const CMPIInstance * newinstance) { Target_Type _context; Target_Type _result; Target_Type _reference; Target_Type _newinst; CMPIStatus status = {CMPI_RC_ERR_NOT_SUPPORTED, NULL}; /* Return status of CIM operations. */ /* Creating new instances is not supported for this class. */ _SBLIM_TRACE(1,("CreateInstance() called, context %p, results %p, reference %p, newinstance %p", context, results, reference, newinstance)); TARGET_THREAD_BEGIN_BLOCK; _context = SWIG_NewPointerObj((void*) context, SWIGTYPE_p__CMPIContext, 0); _result = SWIG_NewPointerObj((void*) results, SWIGTYPE_p__CMPIResult, 0); _reference = SWIG_NewPointerObj((void*) reference, SWIGTYPE_p__CMPIObjectPath, 0); _newinst = SWIG_NewPointerObj((void*) newinstance, SWIGTYPE_p__CMPIInstance, 0); TargetCall((ProviderMIHandle*)self->hdl, &status, "create_instance", 4, _context, _result, _reference, _newinst); TARGET_THREAD_END_BLOCK; _SBLIM_TRACE(1,("CreateInstance() %s", (status.rc == CMPI_RC_OK)? "succeeded":"failed")); return status; }
/* * DeleteInstance() - delete/remove the specified instance. */ static CMPIStatus DeleteInstance(CMPIInstanceMI * self, const CMPIContext * context, const CMPIResult * results, const CMPIObjectPath * reference) { Target_Type _context; Target_Type _result; Target_Type _reference; CMPIStatus status = {CMPI_RC_OK, NULL}; _SBLIM_TRACE(1,("DeleteInstance() called, context %p, results %p, reference %p", context, results, reference)); TARGET_THREAD_BEGIN_BLOCK; _context = SWIG_NewPointerObj((void*) context, SWIGTYPE_p__CMPIContext, 0); _result = SWIG_NewPointerObj((void*) results, SWIGTYPE_p__CMPIResult, 0); _reference = SWIG_NewPointerObj((void*) reference, SWIGTYPE_p__CMPIObjectPath, 0); TargetCall((ProviderMIHandle*)self->hdl, &status, "delete_instance", 3, _context, _result, _reference); TARGET_THREAD_END_BLOCK; _SBLIM_TRACE(1,("DeleteInstance() %s", (status.rc == CMPI_RC_OK)? "succeeded":"failed")); return status; }
static CMPIStatus associatorNames( CMPIAssociationMI* self, const CMPIContext* ctx, const CMPIResult* rslt, const CMPIObjectPath* objName, const char* assocClass, const char* resultClass, const char* role, const char* resultRole) { Target_Type _ctx; Target_Type _rslt; Target_Type _objName ; Target_Type _assocClass; Target_Type _resultClass; Target_Type _role; Target_Type _resultRole; CMPIStatus status = {CMPI_RC_ERR_NOT_SUPPORTED, NULL}; _SBLIM_TRACE(1,("associatorNames() called, ctx %p, rslt %p, objName %p, assocClass %s, resultClass %s, role %s, resultRole %s", ctx, rslt, objName, assocClass, resultClass, role, resultRole)); TARGET_THREAD_BEGIN_BLOCK; _ctx = SWIG_NewPointerObj((void*) ctx, SWIGTYPE_p__CMPIContext, 0); _rslt = SWIG_NewPointerObj((void*) rslt, SWIGTYPE_p__CMPIResult, 0); _objName = SWIG_NewPointerObj((void*) objName, SWIGTYPE_p__CMPIObjectPath, 0); _assocClass = (Target_Type)NULL; _resultClass = (Target_Type)NULL; _role = (Target_Type)NULL; _resultRole = (Target_Type)NULL; if (assocClass != NULL) { _assocClass = string2target(assocClass); } if (resultClass != NULL) { _resultClass = string2target(resultClass); } if (role != NULL) { _role = string2target(role); } if (resultRole != NULL) { _resultRole = string2target(resultRole); } TargetCall((ProviderMIHandle*)self->hdl, &status, "associator_names", 7, _ctx, _rslt, _objName, _assocClass, _resultClass, _role, _resultRole); TARGET_THREAD_END_BLOCK; _SBLIM_TRACE(1,("associatorNames() %s", (status.rc == CMPI_RC_OK)? "succeeded":"failed")); return status; }
/****************************************************************************** * disk_rasd_modify * * This function modifyies an existing disk identified by the RASD InstanceID * with the settings passed in as part of the RASD * * Returns 1 on Success and 0 on failure. *******************************************************************************/ int disk_rasd_modify( xen_utils_session *session, xen_vbd_record *vbd_rec_template, xen_vdi_record *vdi_rec_template ) { xen_vdi current_vdi = NULL; xen_vbd vbd = NULL; xen_vdi vdi = NULL; xen_vbd_record *current_vbd_rec = NULL; xen_vdi_record *current_vdi_rec = NULL; bool is_empty = false; if (!vbd_rec_template || !vdi_rec_template) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("--- No VBD or VDI template has been specified")); return 0; } if (xen_vbd_get_by_uuid(session->xen, &vbd, vbd_rec_template->uuid)) { if (vdi_rec_template->uuid && !xen_vdi_get_by_uuid(session->xen, &vdi, vdi_rec_template->uuid)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("--- VDI specified -%s-", vdi_rec_template->uuid)); if (*(vdi_rec_template->uuid) == '\0') { //This is okay, assume we are being asked to eject existing VDI RESET_XEN_ERROR(session->xen) } } }
static VALUE load_provider(VALUE arg) { const char *classname = (const char *)arg; VALUE req; /* result of rb_require */ if (classname == NULL || *classname == 0) { _SBLIM_TRACE(1,("Ruby: load_provider(%s) no class given", classname)); return Qfalse; } char *filename = alloca(strlen(classname) * 2 + 1); decamelize(classname, filename); ruby_script(filename); _SBLIM_TRACE(1,("<%d> Ruby: loading (%s)", getpid(), filename)); req = rb_require(filename); /* Qtrue == just loaded, Qfalse = already loaded, else: fail */ if ((req != Qtrue) && (req != Qfalse)) { _SBLIM_TRACE(1,("<%d> require '%s' failed", getpid(), filename)); return Qnil; } /* Get Cmpi::Provider */ VALUE val = rb_const_get(rb_cObject, rb_intern(RB_MODULE_NAME)); if (NIL_P(val)) { _SBLIM_TRACE(1,("<%d> No such module '%s'", getpid(), RB_MODULE_NAME)); return val; } val = rb_const_get(val, rb_intern(classname)); if (NIL_P(val)) { _SBLIM_TRACE(1,("<%d> No such class '%s::%s'", getpid(), RB_MODULE_NAME, classname)); } return val; }
/***************************************************************************** * Enumerates all xen objects identified by the CIM classname * * @param in broker - CMPI services factory broker * @param in ft - xen backend provider function table * @param in classnem - CIM classname identifying the xen object * @param in ctx - caller's context * @param in properties - properties that the caller is interested in * @param out res-list - xen resource list * @return CMPIrc error codes *****************************************************************************/ CMPIrc prov_pxy_begin( const CMPIBroker *broker, const XenProviderInstanceFT* ft, const char *classname, void *ctx, bool refs_only, const char **properties, void **res_list ) { CMPIrc rc = CMPI_RC_OK; provider_resource_list *resources = NULL; xen_utils_session *session = NULL; (void)properties; if(res_list == NULL) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,("Error res_list = NULL")); return CMPI_RC_ERR_FAILED; } if(!xen_utils_validate_session(&session, ctx)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("--- Unable to establish connection with Xen")); return CMPI_RC_ERR_FAILED; } resources = (provider_resource_list *)calloc(1, sizeof(provider_resource_list)); if(resources == NULL) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,("Could not allocate memory for resources")); return CMPI_RC_ERR_FAILED; } resources->broker = broker; resources->classname = classname; resources->session = session; resources->ref_only = refs_only; _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Begin enumerating %s", classname)); /* Make Xen call to populate the resources list */ rc = ft->xen_resource_list_enum(session, resources); if(rc != CMPI_RC_OK) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,("Error Did not get xen resource list")); goto Error; } *res_list = (void *)resources; return rc; Error: xen_utils_trace_error(session->xen, __FILE__, __LINE__); ft->xen_resource_list_cleanup(resources); xen_utils_cleanup_session(session); if(resources) free(resources); return CMPI_RC_ERR_FAILED; }
/***************************************************************************** * Function to cleanup the resource * * @param - provider_resource to be freed * @return CMPIrc error codes ****************************************************************************/ static CMPIrc xen_resource_record_cleanup(provider_resource *prov_res) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("xen_resource_record_cleanup")); kvp *kvp_obj = (kvp *)prov_res->ctx; if(kvp_obj) { xen_utils_free_kvp(kvp_obj); } _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("xen_resource_record_cleanup complete")); return CMPI_RC_OK; }
/****************************************************************************** * get_sr * * Get the SR pointed to by the sr-Info lable * (could be a label or could be the uuid). * * Returns 1 on Success and 0 on failure. *******************************************************************************/ static int _get_sr( const CMPIBroker *broker, xen_utils_session *session, char* sr_info, /* in - GUID or name-label */ bool sr_uuid, /* info string is GUID and not name-label */ xen_sr* sr, /* out - handle to SR */ CMPIStatus* status) /* out - status of call */ { bool success = true; xen_sr_set* srs ; if (sr_uuid) { if (!xen_sr_get_by_uuid(session->xen, sr, sr_info)) success = false; } else { if (!xen_sr_get_by_name_label(session->xen, &srs, sr_info)) success = false; if (srs->size != 1) { char error_msg[XEN_UTILS_ERROR_BUF_LEN]; sprintf(error_msg, "SR set for %s returned %d, expecting just 1\n", sr_info, srs->size); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, (error_msg)); xen_sr_set_free(srs); success = false; } else { *sr = srs->contents[0]; srs->contents[0] = NULL; xen_sr_set_free(srs); } } return success; }
static int TargetInitialize(ProviderMIHandle* hdl, CMPIStatus* st) { VALUE args[6] = { Qnil }; VALUE gc = Qnil; int error = 0; int have_lock = 0; /* Set _CMPI_INIT, protected by _CMPI_INIT_MUTEX * so we call ruby_finalize() only once. */ if (pthread_mutex_lock(&_CMPI_INIT_MUTEX)) { perror("Can't lock _CMPI_INIT_MUTEX"); abort(); } if (_TARGET_INIT == 0) { _TARGET_INIT = 1; /* safe, since mutex is locked */ error = RbGlobalInitialize(hdl->broker, st); } #if 0 else { /* Enforce GC.disable in provider upcalls; Ruby 1.9 crashes without */ gc = rb_const_get(rb_cObject, rb_intern("GC")); if (NIL_P(gc)) { _SBLIM_TRACE(0,("<%d> No such module 'GC'", getpid())); } else { rb_funcall(gc, rb_intern("disable"), 0 ); } } #endif pthread_mutex_unlock(&_CMPI_INIT_MUTEX); if (error != 0) { if (st != NULL) { st->rc = CMPI_RC_ERR_INVALID_CLASS; st->msg = CMNewString(hdl->broker, "Failed to init Ruby", NULL); } goto fail; } _SBLIM_TRACE(1,("<%d> TargetInitialize(Ruby) called, miName '%s', stack @ %p, pthread %p", getpid(), hdl->miName, &have_lock, pthread_self())); if (pthread_mutex_trylock(&_stack_init_mutex) == 0) { have_lock = 1; _SBLIM_TRACE(1,("<%d> RUBY_INIT_STACK for pthread %p", getpid(), pthread_self())); RUBY_INIT_STACK }
static CMPIStatus Cleanup( ProviderMIHandle * miHdl, const CMPIContext * context, CMPIBoolean terminating) { _SBLIM_TRACE(1,("Cleanup() called, miHdl %p, miHdl->implementation %p, context %p, terminating %d", miHdl, miHdl->implementation, context, terminating)); CMPIStatus status = {CMPI_RC_OK, NULL}; if (miHdl->implementation != Target_Null) { Target_Type _context; Target_Type _terminating; TARGET_THREAD_BEGIN_BLOCK; _context = SWIG_NewPointerObj((void*) context, SWIGTYPE_p__CMPIContext, 0); _terminating = Target_Bool(terminating); TargetCall(miHdl, &status, "cleanup", 2, _context, _terminating); TARGET_THREAD_END_BLOCK; _SBLIM_TRACE(1,("Cleanup() %d", status.rc)); } if (!terminating && (status.rc == CMPI_RC_DO_NOT_UNLOAD || status.rc == CMPI_RC_NEVER_UNLOAD)) { _SBLIM_TRACE(1,("Cleanup() Provider requested not to be unloaded.")); return status; } TargetCleanup(miHdl); if (miHdl != NULL) { free(miHdl->miName); // we must free the miHdl - it is our ProviderMIHandle. // it is pointed to by the CMPI<type>MI * that the broker holds onto... // the broker is responsible for freeing the CMPI<type>MI* free(miHdl); miHdl = NULL; } _SBLIM_TRACE(1,("Cleanup() %s", (status.rc == CMPI_RC_OK)? "succeeded":"failed")); return status; }
/***************************************************************************** * 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; }
/***************************************************************************** * Gets the next xen resource from the xen resource list * * @param in ft - xen backend provider function table * @param in res_list - xen resource list * @param in properties - CIM properties caller's interested in * @param out res - next xen provider resource in the list * @return CMPIrc error codes *****************************************************************************/ CMPIrc prov_pxy_getnext( const XenProviderInstanceFT* ft, void *res_list, const char **properties, void **res ) { CMPIrc rc = CMPI_RC_OK; provider_resource_list *resources_list = (provider_resource_list *)res_list; (void)properties; if(resources_list == NULL || res == NULL) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Error getnext:resource_list or res is NULL")); return CMPI_RC_ERR_FAILED; } /* Get the current resource record. */ RESET_XEN_ERROR(resources_list->session->xen); provider_resource *prov_res = calloc(1, sizeof(provider_resource)); if(prov_res == NULL) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR,("Error calloc failed")); return CMPI_RC_ERR_FAILED; } /* Copy over the broker and other useful data to the provider's resource */ prov_res->broker = resources_list->broker; prov_res->classname = resources_list->classname; prov_res->session = resources_list->session; prov_res->ref_only = resources_list->ref_only; prov_res->cleanupsession = false; rc = ft->xen_resource_record_getnext(resources_list, resources_list->session, prov_res); if(rc != CMPI_RC_OK) { if(rc != CMPI_RC_ERR_NOT_FOUND) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Error getnext OK not received ")); resources_list->current_resource++; /*Failure to retrieve this record - continue anyway */ } ft->xen_resource_record_cleanup(prov_res); free(prov_res); return rc; } resources_list->current_resource++; /*increment the resource index for the next round */ *res = (void *)prov_res; return CMPI_RC_OK; }
/****************************************************************************** * Function to cleanup provider specific resource, this function is * called at various places in Xen_ProviderGeneric.c * * @param resources - handle to the provider_resource_list to be * be cleaned up. Clean up the provider specific part of the * resource. * @return CMPIrc error codes *****************************************************************************/ static CMPIrc xen_resource_list_cleanup( provider_resource_list *resources ) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Entering xen_resource_list_cleanup")); kvp_set *set = resources->ctx; xen_utils_free_kvpset(set); return CMPI_RC_OK; }
/***************************************************************************** * Function to get a provider specific resource identified by an id * * @param res_uuid - resource identifier for the provider specific resource * @param session - handle to the xen_utils_session object * @param prov_res - provide_resource object to be filled in with the provider * specific resource * @return CMPIrc error codes *****************************************************************************/ static CMPIrc xen_resource_record_get_from_id( char *res_uuid, /* in */ xen_utils_session *session, /* in */ provider_resource *prov_res /* in , out */ ) { char vm_uuid[MAX_INSTANCEID_LEN]; char key[MAX_KVP_KEY_LEN]; char *value=NULL; CMPIrc cim_rc = CMPI_RC_ERR_FAILED; kvp *kvp=NULL; /* Parse the DeviceID */ _CMPIStrncpyDeviceNameFromID(key, res_uuid, sizeof(key)); _CMPIStrncpySystemNameFromID(vm_uuid, res_uuid, sizeof(vm_uuid)); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("xen_resource_get_from_id (%s=%s)", key, vm_uuid)); Xen_KVP_RC rc = xen_utils_get_from_kvp_store(session, vm_uuid, key, &value); if (rc != Xen_KVP_RC_OK) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Failure to retrieve key %s for vm %s", key, vm_uuid)); goto exit; } if(!xen_utils_create_kvp(key, value, vm_uuid, &kvp)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Failed to create KVP key")); goto exit; } prov_res->ctx = kvp; cim_rc = CMPI_RC_OK; exit: /* Free the KVP value string */ if (value) free(value); return cim_rc; }
static CMPIStatus IndicationCleanup(CMPIIndicationMI * self, const CMPIContext * context, CMPIBoolean terminating) { CMPIStatus st; _SBLIM_TRACE(1,("Cleanup() called for Indication provider %s", ((ProviderMIHandle *)self->hdl)->miName)); st = Cleanup((ProviderMIHandle*)self->hdl, context, terminating); if (terminating && st.rc == CMPI_RC_OK) free(self); return st; }
/***************************************************************************** * Cleansup the xen resource list * * @param in ft - xen backend provider function table * @param in res_list - xen resource list * @return CMPIrc error codes *****************************************************************************/ void prov_pxy_end( const XenProviderInstanceFT* ft, void *res_list) { provider_resource_list *resources = (provider_resource_list *)res_list; if(resources) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("End enumerating %s", resources->classname)); ft->xen_resource_list_cleanup(resources); xen_utils_cleanup_session(resources->session); free(resources); } }
/* * ExecQuery() - return a list of all the instances that satisfy the desired query filter. */ static CMPIStatus ExecQuery(CMPIInstanceMI * self, const CMPIContext * context, const CMPIResult * results, const CMPIObjectPath * reference, const char * query, const char * language) { Target_Type _context; Target_Type _result; Target_Type _reference; Target_Type _query; Target_Type _lang; CMPIStatus status = {CMPI_RC_ERR_NOT_SUPPORTED, NULL}; /* Return status of CIM operations. */ _SBLIM_TRACE(1,("ExecQuery() called, context %p, results %p, reference %p, query %s, language %s", context, results, reference, query, language)); TARGET_THREAD_BEGIN_BLOCK; _context = SWIG_NewPointerObj((void*) context, SWIGTYPE_p__CMPIContext, 0); _result = SWIG_NewPointerObj((void*) results, SWIGTYPE_p__CMPIResult, 0); _reference = SWIG_NewPointerObj((void*) reference, SWIGTYPE_p__CMPIObjectPath, 0); _query = string2target(query); _lang = string2target(language); TargetCall((ProviderMIHandle*)self->hdl, &status, "exec_query", 5, _context, _result, _reference, _query, _lang); TARGET_THREAD_END_BLOCK; /* Query filtering is not supported for this class. */ _SBLIM_TRACE(1,("ExecQuery() %s", (status.rc == CMPI_RC_OK)? "succeeded":"failed")); return status; }
/***************************************************************************** * Creates a new backend xen resource identified by the the CIM instance * This is not in use none of Xen's providers allow creation of a xen object * via the object's CreateInstance method. Instead specific 'extrinsic' methjods * are provided in a 'service' factory object. * * @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 added * @param in caller_id - CIM caller's credentials * @param in res - newly added resource * @return CMPIrc error codes *****************************************************************************/ CMPIrc prov_pxy_add( const CMPIBroker *broker, const XenProviderInstanceFT* ft, const void *res_id, struct xen_call_context *caller_id, const void *res ) { (void)res_id; (void)res; xen_utils_session *session = NULL; 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; } _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("Add an instance")); CMPIrc rc = ft->xen_resource_add(broker, session, res_id); xen_utils_cleanup_session(session); return rc; }
static CMPIrc processorpool_set_properties( const CMPIBroker *broker, provider_resource *resource, CMPIInstance *inst) { uint64_t prop_val_64; int prop_val_32; char buf[MAX_INSTANCEID_LEN]; xen_host_record *host_rec = ((local_host_resource *)resource->ctx)->host_rec; _CMPICreateNewDeviceInstanceID(buf, MAX_INSTANCEID_LEN, host_rec->uuid, "ProcessorPool"); CMSetProperty(inst, "InstanceID", (CMPIValue *)buf, CMPI_chars); CMSetProperty(inst, "PoolID", (CMPIValue *)host_rec->uuid, CMPI_chars); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("setting ProcessorPool properties -InstanceID: %s", buf)); prop_val_32 = DMTF_ResourceType_Processor; CMSetProperty(inst, "ResourceType", (CMPIValue *)&prop_val_32, CMPI_uint16); CMSetProperty(inst, "ResourceSubType", (CMPIValue *) "xen:vcpu", CMPI_chars); CMSetProperty(inst, "AllocationUnits", (CMPIValue *)"count", CMPI_chars); /* Capacity is the number of items in xen_host_cpu_set. */ prop_val_64 = host_rec->host_cpus->size; CMSetProperty(inst, "Capacity", (CMPIValue *)&prop_val_64, CMPI_uint64); CMSetProperty(inst, "Caption", (CMPIValue *)"Xen Virtual Processor Pool", CMPI_chars); CMSetProperty(inst, "Description", (CMPIValue *)host_rec->name_description, CMPI_chars); CMSetProperty(inst, "ElementName", (CMPIValue *)host_rec->name_label, CMPI_chars); prop_val_32 = DMTF_HealthState_OK; CMSetProperty(inst, "HealthState", (CMPIValue *)&prop_val_32, CMPI_uint16); //CMSetProperty(inst, "InstallDate", (CMPIValue *)&installDate, CMPI_dateTime); CMSetProperty(inst, "Name", (CMPIValue *)"Xen Virtual Processor Pool", CMPI_chars); prop_val_32 = DMTF_OperationalStatus_OK; CMPIArray *arr = CMNewArray(broker, 1, CMPI_uint16, NULL); CMSetArrayElementAt(arr, 0, (CMPIValue *)&prop_val_32, CMPI_uint16); CMSetProperty(inst, "OperationalStatus", (CMPIValue *) &arr, CMPI_uint16A); //CMSetProperty(inst, "OtherResourceType", (CMPIValue *)other_resource_type, CMPI_String); prop_val_32 = 1; CMSetProperty(inst, "Primordial" , (CMPIValue *)&prop_val_32, CMPI_boolean); //CMSetProperty(inst, "Status", (CMPIValue *)status, CMPI_chars); // CMSetProperty(inst, "StatusDescriptions", (CMPIValue *)status_descs, CMPI_chars); /* Does Xen implement reservation of CPUs by VMs ? */ prop_val_64 = 0; CMSetProperty(inst, "Reserved", (CMPIValue *)&prop_val_64, CMPI_uint64); // CMSetProperty(inst, "Unreservable", (CMPIValue *)unreservable, CMPI_uint16); return CMPI_RC_OK; }
static int RbGlobalInitialize(const CMPIBroker* broker, CMPIStatus* st) { char *loadpath; VALUE searchpath; _SBLIM_TRACE(1,("<%d> Ruby: RbGlobalInitialize, stack @ %p", getpid(), &searchpath)); ruby_init(); ruby_init_loadpath(); extern void SWIG_init(); SWIG_init(); searchpath = rb_gv_get("$:"); /* Append /usr/share/cmpi to $: */ rb_ary_push(searchpath, rb_str_new2("/usr/share/cmpi")); /* Check RUBY_PROVIDERS_DIR_ENV if its a dir, append to $: */ loadpath = getenv(RUBY_PROVIDERS_DIR_ENV); if (loadpath) { struct stat buf; if (stat(loadpath, &buf)) { _SBLIM_TRACE(1,("<%d> Can't stat $%s '%s'", getpid(), RUBY_PROVIDERS_DIR_ENV, loadpath)); return -1; } if ((buf.st_mode & S_IFDIR) == 0) { _SBLIM_TRACE(1,("<%d> Not a directory: $%s '%s'", getpid(), RUBY_PROVIDERS_DIR_ENV, loadpath)); return -1; } _SBLIM_TRACE(1,("<%d> Loading providers from: $%s '%s'", getpid(), RUBY_PROVIDERS_DIR_ENV, loadpath)); rb_ary_push(searchpath, rb_str_new2(loadpath)); } else { _SBLIM_TRACE(0, ("<%d> Hmm, %s not set ?!", getpid(), RUBY_PROVIDERS_DIR_ENV)); } return 0; }
static CMPIString * get_exc_trace(const CMPIBroker* broker) { VALUE exception = rb_gv_get("$!"); /* get last exception */ VALUE reason = rb_funcall(exception, rb_intern("to_s"), 0 ); VALUE trace = rb_gv_get("$@"); /* get last exception trace */ VALUE backtrace; char* tmp; CMPIString *result; if (NIL_P(exception)) { _SBLIM_TRACE(1,("<%d> Ruby: get_exc_trace: no exception", getpid())); return NULL; } if (NIL_P(trace)) { _SBLIM_TRACE(1,("<%d> Ruby: get_exc_trace: no trace ($@ is nil)", getpid())); return NULL; } backtrace = rb_funcall(trace, rb_intern("join"), 1, rb_str_new("\n\t", 2)); tmp = fmtstr("%s\n\t%s", StringValuePtr(reason), StringValuePtr(backtrace)); result = broker->eft->newString(broker, tmp, NULL); free(tmp); return result; }
/***************************************************************************** * Function to get the next xen resource in the resource list * * @param resources_list - handle to the provide_resource_list object * @param session - handle to the xen_utils_session object * @param prov_res - handle to the next provider_resource to be filled in. * @return CMPIrc error codes *****************************************************************************/ static CMPIrc xen_resource_record_getnext( provider_resource_list *resources_list, /* in */ xen_utils_session *session, /* in */ provider_resource *prov_res /* in , out */ ) { kvp *kvp_cpy; _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("getnext")); kvp_set *kvp_set = resources_list->ctx; if (kvp_set == NULL || resources_list->current_resource == kvp_set->size) return CMPI_RC_ERR_NOT_FOUND; kvp *kvp = &kvp_set->contents[resources_list->current_resource]; /* Copying KVP in order to allow the ProxyProvider to free this individual record, and later the complete list */ xen_utils_kvp_copy(kvp, &kvp_cpy); prov_res->ctx = kvp_cpy; _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("contents %s", kvp_cpy->key)); return CMPI_RC_OK; }
/************************************************************************ * Function that sets the properties of a CIM object with values from the * provider specific resource. * * @param resource - provider specific resource to get values from * @param inst - CIM object whose properties are being set * @return CMPIrc return values *************************************************************************/ static CMPIrc xen_resource_set_properties( provider_resource *resource, CMPIInstance *inst) { xen_host_record* host_rec = NULL; xen_host_cpu_record *cpu_rec = (xen_host_cpu_record *)resource->ctx; if(cpu_rec->host->is_record) host_rec = cpu_rec->host->u.record; else xen_host_get_record(resource->session->xen, &host_rec, cpu_rec->host->u.handle); _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_INFO, ("setting properties on %s", resource->classname)); if(xen_utils_class_is_subclass_of(resource->broker, hp_cn, resource->classname)) return hostprocessor_set_properties(resource, host_rec, inst); else return processor_metric_set_properties(resource->broker, resource, host_rec, inst); }
/***************************************************************************** * Set CIM instance properties based on backend xen resource data * * @param in ft - xen backend provider function table * @param in/out inst - CIM instance whose properties are to be set * @param in res - xen resource * @param in properties - CIM properties that caller cares about * @return CMPIrc error codes *****************************************************************************/ CMPIrc prov_pxy_setproperties( const XenProviderInstanceFT* ft, CMPIInstance *inst, const void *res, const char **properties) { provider_resource *resource = (provider_resource *) res; if(res == NULL || CMIsNullObject(inst)) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("Invalid input parameter")); return CMPI_RC_ERR_FAILED; } RESET_XEN_ERROR(resource->session->xen); /* Setup a filter to only return the desired properties. */ const char **keys = ft->xen_resource_get_keys(resource->broker, resource->classname); CMSetPropertyFilter(inst, properties, keys); return ft->xen_resource_set_properties(resource, inst); }
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; }
/******************************************************** * Function to enumerate provider specific resource * * @param session - handle to a xen_utils_session object * @param resources - pointer to the provider_resource_list * object, the provider specific resource defined above * is a member of this struct * @return CMPIrc error codes ********************************************************/ static CMPIrc xen_resource_list_enum( xen_utils_session *session, provider_resource_list *resources ) { xen_network_set *net_set = NULL; if(!xen_network_get_all(session->xen, &net_set) || net_set->size ==0) { _SBLIM_TRACE(_SBLIM_TRACE_LEVEL_ERROR, ("--- Unable to obtain network list")); return CMPI_RC_ERR_FAILED; } local_net_cap_list * ctx = calloc(sizeof(local_net_cap_list), 1); if(ctx == NULL) return CMPI_RC_ERR_FAILED; ctx->network_set = net_set; ctx->currentsettingdatanum = 0; ctx->currentnetnum = 0; resources->ctx = ctx; return CMPI_RC_OK; }
/****************************************************************************** * 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); }