//! Reads the list of enabled sensors from Eucalyptus configuration //! files and ensures that only those are enabled on the system. int update_sensors_list() { int ret = EUCA_OK; char **names = NULL; char *tmpstr = configFileValue(SENSOR_LIST_CONF_PARAM_NAME); if (tmpstr == NULL) { LOGDEBUG("%s parameter is missing from config file\n", SENSOR_LIST_CONF_PARAM_NAME); } else { names = from_var_to_char_list(tmpstr); EUCA_FREE(tmpstr); } char **sensors = { NULL }; // if no config value or an empty list if (names != NULL) { sensors = names; } ret = conf_stats((const char **)sensors); if (names) { for (int i=0; names[i]; i++) { EUCA_FREE(names[i]); } EUCA_FREE(names); } return ret; }
//! //! downloads a digest of an image and compares it to file at old_digest_path //! //! @param[in] url //! @param[in] old_digest_path //! //! @return 0 if same, -1 if different, EUCA_INVALID_ERROR if error //! int walrus_verify_digest(const char *url, const char *old_digest_path) { int e = EUCA_INVALID_ERROR; char *new_digest; char *old_digest = file2strn(old_digest_path, 2000000); if (old_digest == NULL) { logprintfl(EUCAERROR, "failed to read old digest %s\n", old_digest_path); return e; } if ((new_digest = walrus_get_digest(url)) != NULL) { // compare the two if (strcmp(new_digest, old_digest)) { e = -1; } else { e = EUCA_OK; } EUCA_FREE(new_digest); } EUCA_FREE(old_digest); return e; }
//! //! Frees a semaphore. //! //! @param[in] pSem a pointer to the semaphore to free if not NULL //! //! @see SEM_FREE() //! //! @pre The pSem field should not be NULL //! //! @post If pSem isn't NULL, the semaphore will be uninitialized and the memory will be freed //! //! @note It is recommended to use the SEM_FREE() macro as this will ensured that pSem will be //! explicitedly set to NULL uppon returning from this call. //! void sem_free(sem * pSem) { DECLARE_ARG; // Make sure we were provided with a valid semaphore if (pSem) { // Is this a posix semaphore? if (pSem->posix) { // Close the posix semaphore sem_close(pSem->posix); // If we had the exclusive flag set, then unlink if (pSem->flags & O_EXCL) { sem_unlink(pSem->name); } } // If this is a SYS V semaphore if (pSem->sysv > 0) { semctl(pSem->sysv, 0, IPC_RMID, arg); } // If we use mutex, we need to destroy it. if (pSem->usemutex) { pthread_mutex_destroy(&(pSem->mutex)); } // Free the memory for the name before freeing the semaphore structure memory EUCA_FREE(pSem->name); EUCA_FREE(pSem); } }
//! //! destroy an NC stub structure //! //! @param[in] pStub a pointer to the node controller (NC) stub structure //! //! @return Always returns EUCA_OK //! int scStubDestroy(scStub * pStub) { EUCA_FREE(pStub->client_home); EUCA_FREE(pStub->endpoint_uri); EUCA_FREE(pStub->node_name); EUCA_FREE(pStub); return (EUCA_OK); }
//! //! Refactored logic for detaching a local iSCSI device and unexporting the volume. To be invoked only by other functions in this file after acquiring the necessary lock. //! //! @param[in] sc_url - The URL to reach the cluster's SC at. //! @param[in] use_ws_sec - boolean to determine use of WS-SEC. //! @param[in] ws_sec_policy_file - Policy file path for WS-SEC //! @param[in] vol_data - The ebs_volume_data struct pointer //! @param[in] connect_string - The connection string to use for local connection //! @param[in] local_ip - The local host's external IP //! @param[in] local_iqn - The local host's IQN //! @param[in] do_rescan - Set to false to indicate no rescan should be done on disconnect, or true to use rescan //! //! @return EUCA_OK on success, EUCA_ERROR on failure //! //! @pre //! //! @post //! //! @note should be invoked only by functions in this file that acquired the necessary lock. //! static int cleanup_volume_attachment(char *sc_url, int use_ws_sec, char *ws_sec_policy_file, ebs_volume_data * vol_data, char *connect_string, char *local_ip, char *local_iqn, int do_rescan) { int rc = 0; char *reencrypted_token = NULL; char *refreshedDev = NULL; if (vol_data == NULL || connect_string == NULL || local_ip == NULL || local_iqn == NULL) { LOGERROR("Cannot cleanup volume attachment. Got NULL input parameters.\n"); return EUCA_ERROR; } LOGDEBUG("[%s] attempting to disconnect iscsi target\n", vol_data->volumeId); if (disconnect_iscsi_target(connect_string, do_rescan) != 0) { LOGERROR("[%s] failed to disconnect iscsi target\n", vol_data->volumeId); LOGDEBUG("Skipping SC Call due to previous errors\n"); return EUCA_ERROR; } if (sc_url == NULL || strlen(sc_url) <= 0) { LOGERROR("[%s] Cannot invoke SC UnexportVolume, SC URL is invalid\n", vol_data->volumeId); return EUCA_ERROR; } rc = re_encrypt_token(vol_data->token, &reencrypted_token); if (rc != EUCA_OK || reencrypted_token == NULL || strlen(reencrypted_token) <= 0) { LOGERROR("Failed on re-encryption of token for call to SC\n"); if (reencrypted_token != NULL) { EUCA_FREE(reencrypted_token); } return EUCA_ERROR; } else { LOGTRACE("Re-encrypted token for %s is %s\n", vol_data->volumeId, reencrypted_token); } threadCorrelationId* corr_id = get_corrid(); LOGTRACE("Calling scClientCall with url: %s and token %s\n", sc_url, vol_data->token); if (scClientCall( corr_id == NULL ? NULL : corr_id->correlation_id, NULL, use_ws_sec, ws_sec_policy_file, request_timeout_sec, sc_url, "UnexportVolume", vol_data->volumeId, reencrypted_token, local_ip, local_iqn) != EUCA_OK) { EUCA_FREE(reencrypted_token); LOGERROR("ERROR unexporting volume %s\n", vol_data->volumeId); return EUCA_ERROR; } else { EUCA_FREE(reencrypted_token); //Ok, now refresh local session to be sure it's gone. //Should return error of not found. refreshedDev = get_iscsi_target(connect_string); if (refreshedDev) { //Failure, should have NULL. return EUCA_ERROR; } else { //We're good return EUCA_OK; } } }
//! //! given path=A/B/C and only A existing, create A/B and, unless //! is_file_path==1, also create A/B/C directory //! //! @param[in] path //! @param[in] is_file_path //! @param[in] user //! @param[in] group //! @param[in] mode //! //! @return 0 = path already existed, 1 = created OK, -1 = error //! int ensure_directories_exist(const char *path, int is_file_path, const char *user, const char *group, mode_t mode) { int ret = 0; int i = 0; int len = strlen(path); int try_dir = 0; char *path_copy = NULL; struct stat buf = { 0 }; if (len > 0) path_copy = strdup(path); if (path_copy == NULL) return (-1); for (i = 0; i < len; i++) { try_dir = 0; if ((path[i] == '/') && (i > 0)) { // dir path, not root path_copy[i] = '\0'; try_dir = 1; } else if ((path[i] != '/') && ((i + 1) == len)) { // last one if (!is_file_path) try_dir = 1; } if (try_dir) { if (stat(path_copy, &buf) == -1) { LOGINFO("creating path %s\n", path_copy); if (mkdir(path_copy, mode) == -1) { LOGERROR("failed to create path %s: %s\n", path_copy, strerror(errno)); EUCA_FREE(path_copy); return (-1); } ret = 1; // we created a directory if (diskutil_ch(path_copy, user, group, mode) != EUCA_OK) { LOGERROR("failed to change perms on path %s\n", path_copy); EUCA_FREE(path_copy); return (-1); } } path_copy[i] = '/'; // restore the slash } } EUCA_FREE(path_copy); return (ret); }
//! //! Main entry point of the application //! //! @param[in] argc the number of parameter passed on the command line //! @param[in] argv the list of arguments //! //! @return EUCA_OK on success or EUCA_ERROR on failure. //! int main(int argc, char **argv) { //char *sc_url_prefix = "sc://"; //char *sc_ur1 = "http://192.168.1.1:8773/services/Storage"; //char *sc_ur1_slash = "http://192.168.1.1:8773/services/Storage/"; //char *sc_hostname_url = "http://testhost.com:8773/services/Storage"; //char *sc_hostname_ur1_slash = "http://testhost.com:8773/services/Storage/"; char *serialized1 = "sc://vol-123ABCD,10aavaeosvas-sd-adsf-asdfa-vasdva"; char *serialized2 = "sc://vol-123ABCD,10aavaeosvas-sd-adsf-asdfa-vasdva"; ebs_volume_data test_struct1 = { "testtoken123", "vol-AB123DD" }; ebs_volume_data test_struct2 = { "1aoivlna-adflnew-aavaa0an12zc", "vol-123ABCD" }; char *output = NULL; ebs_volume_data *ebs_out = NULL; int result; printf("Testing serialization\n"); result = serialize_volume(&test_struct1, &output); printf("Got serialized output: %s\n", output); EUCA_FREE(output); result = serialize_volume(&test_struct2, &output); printf("Got serialized output: %s\n", output); EUCA_FREE(output); printf("Testing de-serialization\n"); result = deserialize_volume(serialized1, &ebs_out); printf("Input %s\n\tGot de-serialized: %s %s\n", serialized1, ebs_out->volumeId, ebs_out->token); EUCA_FREE(ebs_out); result = deserialize_volume(serialized2, &ebs_out); printf("Input %s\n\tGot de-serialized: %s %s\n", serialized2, ebs_out->volumeId, ebs_out->token); EUCA_FREE(ebs_out); //int replace_sc_url(const char * volume_string, const char * scUrl, char * restrict dest_string) /*printf("Testing url replacement\n"); char url_out1[512]; result = replace_sc_url(serialized1, "http://localhost.com:8773/services/Storage", url_out1); printf("Result string %s\n", url_out1); char url_out2[512]; result = replace_sc_url(serialized2, "http://192.168.1.1:8773/services/Storage/", url_out2); printf("Result string %s\n", url_out2); char url_out3[512]; result = replace_sc_url(serialized3, "http://localhost.com:8773/services/Storage", url_out3); printf("Result string %s\n", url_out3); */ return (0); }
int loop_through_volumes(const char *xml_path, eucaVolume volumes[EUCA_MAX_VOLUMES]){ char volxpath[128] = ""; #define MKVOLPATH(_suffix) snprintf(volxpath, sizeof(volxpath), "/instance/volumes/volume[%d]/%s", (i + 1), _suffix); #define MKLIBVIRTVOLPATH(_suffix) snprintf(volxpath, sizeof(volxpath), "/instance/volumes/volume[%d]/libvirt/disk/%s", (i + 1), _suffix); #define XGET_STR_FREE(_XPATH, _dest) \ { \ if (get_xpath_content_at(xml_path, (_XPATH), 0, _dest, sizeof(_dest)) == NULL) { \ fprintf(stderr, "failed to read %s from %s\n", (_XPATH), xml_path); \ for (int z = 0; res_array[z] != NULL; z++) \ EUCA_FREE(res_array[z]); \ EUCA_FREE(res_array); \ return (EUCA_ERROR); \ } \ } char **res_array = NULL; if ((res_array = get_xpath_content(xml_path, "/instance/volumes/volume")) != NULL) { for (int i = 0; (res_array[i] != NULL) && (i < EUCA_MAX_VOLUMES); i++) { eucaVolume *v = &volumes[i]; MKVOLPATH("id"); XGET_STR_FREE(volxpath, v->id); MKVOLPATH("attachmentToken"); XGET_STR_FREE(volxpath, v->attachment_token); MKVOLPATH("stateName"); XGET_STR_FREE(volxpath, v->state); MKVOLPATH("connectionString"); XGET_STR_FREE(volxpath, v->connection_string); MKVOLPATH("devName"); XGET_STR_FREE(volxpath, v->device); MKVOLPATH("libvirt"); if (strcmp(v->state, VOL_STATE_ATTACHING) && strcmp(v->state, VOL_STATE_ATTACHING_FAILED) && get_xpath_xml(xml_path, volxpath, v->libvirt_XML, sizeof(v->libvirt_XML)) != EUCA_OK) { fprintf(stderr, "failed to read '%s' from '%s'\n", volxpath, xml_path); for (int z = 0; res_array[z] != NULL; z++) EUCA_FREE(res_array[z]); EUCA_FREE(res_array); return (EUCA_ERROR); } MKLIBVIRTVOLPATH("serial"); XGET_STR_FREE(volxpath, v->serial); MKLIBVIRTVOLPATH("target/@bus"); XGET_STR_FREE(volxpath, v->bus); } // Free our allocated memory for (int i = 0; res_array[i] != NULL; i++) EUCA_FREE(res_array[i]); EUCA_FREE(res_array); } return (EUCA_OK); }
//! //! Frees an allocated metadata structure. //! //! @param[in,out] ppMeta a pointer to the node controller (NC) metadata structure //! //! @see allocate_metadata() //! //! @pre The \p ppMeta field should not be NULL //! //! @post If the metadata pointer is valid, the structure is freed and \p (*ppMeta) will be set to NULL. //! void free_metadata(ncMetadata ** ppMeta) { ncMetadata *pMeta = NULL; if (ppMeta != NULL) { if ((pMeta = (*ppMeta)) != NULL) { EUCA_FREE(pMeta->correlationId); EUCA_FREE(pMeta->userId); EUCA_FREE(pMeta); *ppMeta = NULL; } } }
/** * Deletes a ebtables rule specified in the argument. * * @param ebth [in] pointer to the EB table handler structure * @param tablename [in] a string pointer to the table name * @param chainname [in] a string pointer to the chain name * @param findrule [in] a string pointer to the rule to be deleted * * @return 0 if the rule given in the argument is successfully deleted. 1 otherwise. */ int ebt_chain_flush_rule(ebt_handler *ebth, char *tablename, char *chainname, char *findrule) { ebt_table *table = NULL; ebt_chain *chain = NULL; ebt_rule *rule = NULL; ebt_rule *newrules = NULL; int i; int nridx; if (!ebth || !tablename || !chainname || !findrule || !ebth->init) { return (EUCA_INVALID_ERROR); } table = ebt_handler_find_table(ebth, tablename); if (!table) { return (EUCA_INVALID_ERROR); } chain = ebt_table_find_chain(ebth, tablename, chainname); if (!chain) { return (EUCA_INVALID_ERROR); } rule = ebt_chain_find_rule(ebth, tablename, chainname, findrule); if (rule) { if (chain->max_rules > 1) { newrules = realloc(newrules, sizeof (ebt_rule) * (chain->max_rules - 1)); if (!newrules) { LOGFATAL("out of memory!\n"); exit(1); } bzero(newrules, sizeof (ebt_rule) * (chain->max_rules - 1)); nridx = 0; for (i = 0; i < chain->max_rules; i++) { if (strcmp(chain->rules[i].ebtrule, findrule)) { snprintf(newrules[nridx].ebtrule, 1024, "%s", chain->rules[i].ebtrule); nridx++; } } EUCA_FREE(chain->rules); chain->rules = newrules; chain->max_rules = nridx; } else { EUCA_FREE(chain->rules); chain->max_rules = 0; chain->counters[0] = '\0'; } } else { LOGDEBUG("Could not find (%s) from chain %s at table %s\n", findrule, chainname, tablename); return (2); } return (0); }
//! //! Function description. //! //! @param[in] file //! //! @return //! //! @see //! //! @pre List of pre-conditions //! //! @post List of post conditions //! //! @note //! int atomic_file_sort_tmpfile(atomic_file * file) { int currlines = 0; int i = 0; int fd = 0; int ret = 0; char **contents = NULL; char buf[4096] = ""; char tmpfile[EUCA_MAX_PATH] = ""; FILE *IFH = NULL; FILE *OFH = NULL; snprintf(tmpfile, EUCA_MAX_PATH, "%s-XXXXXX", file->dest); if ((fd = safe_mkstemp(tmpfile)) < 0) { LOGERROR("cannot open tmpfile '%s': check permissions\n", tmpfile); return (1); } if (chmod(tmpfile, 0600)) { LOGWARN("chmod failed: was able to create tmpfile '%s', but could not change file permissions\n", tmpfile); } close(fd); buf[0] = '\0'; if ((IFH = fopen(file->tmpfile, "r")) != NULL) { while (fgets(buf, 4096, IFH)) { currlines++; if ((contents = realloc(contents, sizeof(char *) * currlines)) == NULL) { LOGFATAL("out of memory!\n"); exit(1); } contents[currlines - 1] = strdup(buf); } fclose(IFH); if (contents) { qsort(contents, currlines, sizeof(char *), strcmp_ptr); if ((OFH = fopen(tmpfile, "w")) != NULL) { for (i = 0; i < currlines; i++) { fprintf(OFH, "%s", contents[i]); EUCA_FREE(contents[i]); } fclose(OFH); if (rename(tmpfile, file->tmpfile)) { LOGERROR("could not rename (move) source file '%s' to dest file '%s': check permissions\n", tmpfile, file->tmpfile); ret = 1; } } EUCA_FREE(contents); } } return (ret); }
//! //! Function description. //! //! @param[in] file //! //! @return //! //! @see //! //! @pre List of pre-conditions //! //! @post List of post conditions //! //! @note //! int atomic_file_free(atomic_file * file) { if (!file) return (1); if (file->lasthash) EUCA_FREE(file->lasthash); if (file->currhash) EUCA_FREE(file->currhash); bzero(file, sizeof(atomic_file)); return (0); }
//! //! read file 'path' into a new string //! //! @param[in] path //! //! @return the string content of the given file //! //! @note the caller must free the memory when done. //! char *file2str(const char *path) { int fp = 0; int bytes = 0; int bytes_total = 0; int to_read = 0; char *p = NULL; char *content = NULL; off_t file_size = 0; struct stat mystat = { 0 }; if (stat(path, &mystat) < 0) { LOGERROR("errno: %d could not stat file %s\n", errno, path); return (content); } file_size = mystat.st_size; if ((content = EUCA_ALLOC((file_size + 1), sizeof(char))) == NULL) { LOGERROR("out of memory reading file %s\n", path); return (content); } if ((fp = open(path, O_RDONLY)) < 0) { LOGERROR("errno: %d failed to open file %s\n", errno, path); EUCA_FREE(content); return (content); } p = content; to_read = (((SSIZE_MAX) < file_size) ? (SSIZE_MAX) : file_size); while ((bytes = read(fp, p, to_read)) > 0) { bytes_total += bytes; p += bytes; if (to_read > (file_size - bytes_total)) { to_read = file_size - bytes_total; } } close(fp); if (bytes < 0) { LOGERROR("failed to read file %s\n", path); EUCA_FREE(content); return (content); } *p = '\0'; return (content); }
//! //! Function description. //! //! @param[in] file //! //! @return //! //! @see //! //! @pre List of pre-conditions //! //! @post List of post conditions //! //! @note //! int atomic_file_sort_tmpfile(atomic_file * file) { int cmp = 0; int currlines = 0; int i = 0; int fd = 0; int ret = 0; char **contents = NULL; char buf[4096] = ""; char tmpfile[MAX_PATH] = ""; FILE *IFH = NULL; FILE *OFH = NULL; snprintf(tmpfile, MAX_PATH, "%s-XXXXXX", file->dest); if ((fd = safe_mkstemp(tmpfile)) < 0) { LOGERROR("cannot open tmpfile '%s'\n", tmpfile); return (1); } chmod(tmpfile, 0644); close(fd); buf[0] = '\0'; if ((IFH = fopen(file->tmpfile, "r")) != NULL) { while (fgets(buf, 4096, IFH)) { currlines++; if ((contents = realloc(contents, sizeof(char *) * currlines)) == NULL) { LOGFATAL("out of memory!\n"); exit(1); } contents[currlines - 1] = strdup(buf); } fclose(IFH); if (contents) { qsort(contents, currlines, sizeof(char *), strcmp_ptr); if ((OFH = fopen(tmpfile, "w")) != NULL) { for (i = 0; i < currlines; i++) { fprintf(OFH, "%s", contents[i]); EUCA_FREE(contents[i]); } fclose(OFH); rename(tmpfile, file->tmpfile); } EUCA_FREE(contents); } } return (ret); }
//! //! Handle the client describe resource request //! //! @param[in] pStub a pointer to the node controller (NC) stub structure //! @param[in] pMeta a pointer to the node controller (NC) metadata structure //! @param[in] resourceType UNUSED //! @param[out] outRes a list of resources we retrieved data for //! //! @return EUCA_OK on success or EUCA_ERROR on failure. //! int ncDescribeResourceStub(ncStub * pStub, ncMetadata * pMeta, char *resourceType, ncResource ** outRes) { int ret = EUCA_OK; ncResource *res = NULL; loadNcStuff(); if (myconfig->res.memorySizeMax <= 0) { // not initialized? res = allocate_resource("OK", "iqn.1993-08.org.debian:01:736a4e92c588", 1024000, 1024000, 30000000, 30000000, 4096, 4096, "none"); if (!res) { LOGERROR("fakeNC: describeResource(): failed to allocate fake resource\n"); ret = EUCA_ERROR; } else { memcpy(&(myconfig->res), res, sizeof(ncResource)); EUCA_FREE(res); } } if (!ret) { res = EUCA_ALLOC(1, sizeof(ncResource)); memcpy(res, &(myconfig->res), sizeof(ncResource)); *outRes = res; } else { *outRes = NULL; } saveNcStuff(); return (ret); }
//! //! //! //! @param[in] file //! //! @return 0 on success or 1 on failure //! int check_block(const char *file) { int rc = 0; char *rpath = NULL; struct stat mystat = { 0 }; if (!file) { LOGERROR("Invalid file name"); return (1); } if ((rpath = realpath(file, NULL)) == NULL) { LOGERROR("No canonical file found for %s", file); return (1); } rc = lstat(rpath, &mystat); EUCA_FREE(rpath); if ((rc < 0) || !S_ISBLK(mystat.st_mode)) { LOGERROR("No stat information found for %s", rpath); return (1); } return (0); }
//! //! Responsible for flushing any networking artifacts implemented by this //! network driver. //! //! @param[in] pGni a pointer to the Global Network Information structure //! //! @return 0 on success or 1 if any failure occurred. //! //! @see //! //! @pre //! The driver must be initialized already //! //! @post //! On success, all networking mode artifacts will be flushed from the system. If any //! failure occurred. The system is left in a non-deterministic state and a subsequent //! call to this API may resolve the remaining issues. //! static int network_driver_system_flush(globalNetworkInfo *pGni) { int rc = 0; int ret = 0; LOGINFO("Flushing '%s' network driver artifacts.\n", DRIVER_NAME()); // Is our driver initialized? if (!IS_INITIALIZED()) { LOGERROR("Failed to flush the networking artifacts for '%s' network driver. Driver not initialized.\n", DRIVER_NAME()); return (1); } // if (PEER_IS_NC(eucanetdPeer)) { if (pMidoConfig) { if ((rc = do_midonet_teardown(pMidoConfig)) != 0) { ret = 1; } else { EUCA_FREE(pMidoConfig); pMidoConfig = NULL; gInitialized = FALSE; } } // } return (0); }
//! //! Removes an instance from an instance linked list //! //! @param[in,out] ppHead a pointer to the pointer to the head of the list //! @param[in] pInstance a pointer to the instance to remove from the list //! //! @return EUCA_OK on success or the following error code: //! \li EUCA_INVALID_ERROR: if any of our parameters do not meet the pre-conditions //! \li EUCA_NOT_FOUND_ERROR: if the instance is not part of this list //! //! @pre \li Both \p ppHead and \p pInstance field must not be NULL //! \li The instance must exist in this list //! //! @post The instance is removed from the list. If this instance was the head of the list, //! the \p ppHead field will be updated to point to the new head (next instance in list //! from previous head). //! int remove_instance(bunchOfInstances ** ppHead, ncInstance * pInstance) { u32 count = 0; bunchOfInstances *pHead = NULL; bunchOfInstances *pPrevious = NULL; // Make sure our parameters are valid if (ppHead && pInstance) { for (pHead = *ppHead; pHead; pPrevious = pHead, pHead = pHead->next) { count = (*ppHead)->count; if (!strcmp(pHead->instance->instanceId, pInstance->instanceId)) { if (pPrevious) { pPrevious->next = pHead->next; } else { *ppHead = pHead->next; } if (*ppHead) { (*ppHead)->count = count - 1; } EUCA_FREE(pHead); return (EUCA_OK); } } return (EUCA_NOT_FOUND_ERROR); } return (EUCA_INVALID_ERROR); }
//! //! Serializes the ebs_volume_data struct into a single string that is //! pointed to by the 'dest' argument //! //! @param[in] vol_data //! @param[in] dest //! //! @return //! //! @pre //! //! @post //! //! @note //! int serialize_volume(ebs_volume_data * vol_data, char **dest) { int out_size = -1; char *working_string = NULL; int working_size = -1; if (vol_data == NULL) { LOGTRACE("Cannot serialize a NULL to volume string\n"); return EUCA_ERROR; } working_size = strlen(vol_data->token) + 1 + strlen(vol_data->volumeId) + 1; working_string = EUCA_ZALLOC(1, working_size); if (working_string == NULL) { LOGERROR("Cannot allocate memory!\n"); return EUCA_ERROR; } //Ensure / at end of scURL out_size = snprintf(working_string, working_size, "%s%s,%s", VOLUME_STRING_PREFIX, vol_data->volumeId, vol_data->token); if (out_size <= 0 || out_size > working_size) { EUCA_FREE(working_string); return EUCA_ERROR; } LOGTRACE("Serialized volume struct into %s\n", working_string); *dest = working_string; return EUCA_OK; }
//! //! downloads a digest and returns it as a new string (or NULL if error) //! that the caller must free //! //! @param[in] url //! //! @return the digested string. //! //! @see file2strn() //! //! @note the caller must free the returned memory when done. //! char *walrus_get_digest(const char *url) { char *digest_str = NULL; char *digest_path = strdup("/tmp/walrus-digest-XXXXXX"); if (!digest_path) { logprintfl(EUCAERROR, "out of memory (failed to allocate digest path)\n"); return digest_path; } int tmp_fd = safe_mkstemp(digest_path); if (tmp_fd < 0) { logprintfl(EUCAERROR, "failed to create a digest file %s\n", digest_path); } else { close(tmp_fd); // walrus_ routine will reopen the file // download a fresh digest if (walrus_object_by_url(url, digest_path, 0) != 0) { logprintfl(EUCAERROR, "failed to download digest to %s\n", digest_path); } else { digest_str = file2strn(digest_path, 2000000); } unlink(digest_path); } EUCA_FREE(digest_path); return digest_str; }
//! //! Detach a local device that is iSCSI and disconnect the session. //! //! @param[in] sc_url - The URL to reach the cluster's SC at. //! @param[in] use_ws_sec - boolean to determine use of WS-SEC. //! @param[in] ws_sec_policy_file - Policy file path for WS-SEC //! @param[in] attachment_token - The volume/token string received in the request that will be used //! @param[in] connect_string - The connect string used for attachment, to be re-used on disconnect //! @param[in] local_ip - The local host's external IP //! @param[in] local_iqn - The local host's IQN //! //! @return //! //! @pre //! //! @post //! //! @note should only be invoked after detachment from the guest //! int disconnect_ebs_volume(char *sc_url, int use_ws_sec, char *ws_sec_policy_file, char *attachment_token, char *connect_string, char *local_ip, char *local_iqn) { int ret = EUCA_ERROR; int norescan = 0; //send a 0 to indicate no rescan requested ebs_volume_data *vol_data = NULL; if (attachment_token == NULL || connect_string == NULL || local_ip == NULL || local_iqn == NULL) { LOGERROR("Cannont disconnect ebs volume. Got NULL input parameters.\n"); return EUCA_ERROR; } LOGTRACE("Disconnecting an EBS volume\n"); if (deserialize_volume(attachment_token, &vol_data) != EUCA_OK) { LOGERROR("Could not deserialize attachment token string %s\n", attachment_token); return EUCA_ERROR; } LOGTRACE("Requesting volume lock\n"); sem_p(vol_sem); { LOGTRACE("Got volume lock\n"); ret = cleanup_volume_attachment(sc_url, use_ws_sec, ws_sec_policy_file, vol_data, connect_string, local_ip, local_iqn, norescan); LOGTRACE("cleanup_volume_attachment returned: %d\n", ret); LOGTRACE("Releasing volume lock\n"); } sem_v(vol_sem); LOGTRACE("Released volume lock\n"); EUCA_FREE(vol_data); return ret; }
//! //! This API is invoked when eucanetd catches an USR1 or USR2 signal. //! //! @param[in] pGni a pointer to the Global Network Information structure //! @param[in] signal received signal //! //! @return 0 on success, 1 otherwise. //! //! @see //! //! @pre //! - pGni must not be NULL //! - The driver must be initialized prior to calling this API. //! //! @post //! //! @note //! static int network_driver_handle_signal(globalNetworkInfo *pGni, int signal) { LOGTRACE("Handling singal %d for '%s' network driver.\n", signal, DRIVER_NAME()); // Is the driver initialized? if (!IS_INITIALIZED()) { LOGERROR("Failed to handle signal. Driver '%s' not initialized.\n", DRIVER_NAME()); return (1); } // Is the global network view structure NULL? if (!pGni) { LOGERROR("Failed to handle signal for '%s' network driver. Invalid parameters provided.\n", DRIVER_NAME()); return (1); } switch (signal) { case SIGUSR1: mido_info_midonetapi(); mido_info_http_count_total(); mido_info_midocache(); char *bgprecovery = NULL; bgprecovery = discover_mido_bgps(pMidoConfig); if (bgprecovery && strlen(bgprecovery)) { LOGINFO("\nmido BGP configuration (for manual recovery):\n%s\n", bgprecovery); } EUCA_FREE(bgprecovery); break; case SIGUSR2: LOGINFO("Going to invalidate midocache\n"); midocache_invalid = 1; break; default: break; } return (0); }
//! Decrypts the encrypted token and re-encrypts with the public cloud cert. //! Used for preparation for request to SC for Export/Unexport. //! //! @param[in] in_token - the token encrypted with the NC public key //! @param[in] out_token - the same token encrypted with CLC public key //! //! @return //! static int re_encrypt_token(char *in_token, char **out_token) { char *tmp_token = NULL; char redacted_token[512]; if (in_token == NULL) { LOGERROR("Cannot re-encrypt NULL token\n"); *out_token = NULL; return EUCA_ERROR; } if (decrypt_string_with_node(in_token, &tmp_token) != EUCA_OK || tmp_token == NULL) { LOGERROR("Failed decryption of token %s\n", in_token); *out_token = NULL; return EUCA_ERROR; } if (redact_token(tmp_token, redacted_token) != EUCA_OK) { LOGTRACE("Error redacting token value for log output. Continuing."); } else { LOGTRACE("Decrypted, redacted token: %s\n", redacted_token); } if (encrypt_string_with_cloud(tmp_token, out_token) != EUCA_OK || *out_token == NULL) { LOGERROR("Failed re-encryption of token %s\n", in_token); EUCA_FREE(tmp_token); *out_token = NULL; return EUCA_ERROR; } return EUCA_OK; }
//! //! Initialize the network driver. //! //! @param[in] pConfig a pointer to our application configuration //! //! @return 0 on success or 1 if any failure occurred. //! //! @see //! //! @pre //! - The core application configuration must be completed prior calling //! - The driver should not be already initialized (if its the case, a no-op will occur) //! - The pConfig parameter must not be NULL //! //! @post //! On success the driver is properly configured. On failure, the state of //! the driver is non-deterministic. If the driver was previously initialized, //! this will result into a no-op. //! //! @note //! static int network_driver_init(eucanetdConfig * pConfig) { int rc = 0; LOGINFO("Initializing '%s' network driver.\n", DRIVER_NAME()); // Make sure our given pointer is valid if (!pConfig) { LOGERROR("Failure to initialize '%s' networking mode. Invalid configuration parameter provided.\n", DRIVER_NAME()); return (1); } // Are we already initialized? if (IS_INITIALIZED()) { LOGERROR("Networking '%s' mode already initialized. Skipping!\n", DRIVER_NAME()); return (0); } pMidoConfig = EUCA_ZALLOC_C(1, sizeof (mido_config)); pMidoConfig->config = pConfig; //rc = initialize_mido(pMidoConfig, pConfig->eucahome, pConfig->flushmode, pConfig->disable_l2_isolation, pConfig->midoeucanetdhost, pConfig->midogwhosts, // pConfig->midopubnw, pConfig->midopubgwip, "169.254.0.0", "17"); rc = initialize_mido(pMidoConfig, pConfig, "169.254.0.0", "17"); if (rc) { LOGERROR("could not initialize mido: please ensure that all required config options for VPCMIDO mode are set\n"); EUCA_FREE(pMidoConfig); return (1); } // We are now initialized gInitialized = TRUE; return (0); }
/** * Initialize this network driver. * - The core application configuration must be completed prior calling * - The driver should not be already initialized (if its the case, a no-op will occur) * - The pConfig parameter must not be NULL * * @param pConfig [in] a pointer to eucanetd system-wide configuration * @param pGni [in] a pointer to the Global Network Information structure * @return 0 on success. Integer number on failure. */ static int network_driver_init(eucanetdConfig *pConfig, globalNetworkInfo *pGni) { int rc = 0; LOGDEBUG("Initializing '%s' network driver.\n", DRIVER_NAME()); // Make sure our given pointer is valid if (!pConfig) { LOGERROR("Failure to initialize '%s' networking mode. Invalid configuration parameter provided.\n", DRIVER_NAME()); return (1); } // Are we already initialized? if (IS_INITIALIZED()) { LOGERROR("Networking '%s' mode already initialized. Skipping!\n", DRIVER_NAME()); return (0); } if (!pMidoConfig) { pMidoConfig = EUCA_ZALLOC_C(1, sizeof (mido_config)); } pMidoConfig->config = pConfig; rc = initialize_mido(pMidoConfig, pConfig, pGni); if (rc) { LOGERROR("could not initialize mido: please ensure that all required config options for VPCMIDO mode are set\n"); free_mido_config(pMidoConfig); EUCA_FREE(pMidoConfig); return (1); } // We are now initialized gInitialized = TRUE; return (0); }
//! //! Splits an input CIDR into network address and network mask (slashnet) parts. //! If netmask is not found, /32 is assumed. Input is not validated (whether it //! is a CIDR). //! //! @param[in] ipname a CIDR string (assumed to be in network address/slashnet) //! @param[out] ippart Network address of the given CIDR. //! @param[out] nmpart Slashnet of the given CIDR //! //! @return 0 on success, 1 otherwise. //! //! @see //! //! @pre //! //! @post //! //! @note //! int cidrsplit(char *ipname, char **ippart, int *nmpart) { char *idx = NULL; char *ipname_dup = NULL; if (!ipname || !ippart || !nmpart) { LOGERROR("invalid input\n"); return (1); } *ippart = NULL; *nmpart = 0; ipname_dup = strdup(ipname); idx = strchr(ipname_dup, '/'); if (idx) { //nm part is present *idx = '\0'; idx++; *nmpart = atoi(idx); if (*nmpart < 0 || *nmpart > 32) { LOGERROR("invalid netmask specified from input '%s': setting netmask to '/32'\n", ipname); *nmpart = 32; } *ippart = strdup(ipname); } else { // nm part is not present, use /32 *nmpart = 32; *ippart = strdup(ipname); } EUCA_FREE(ipname_dup); return (0); }
//! //! Initialize the NC state structure for the KVM hypervisor. //! //! @param[in] nc a pointer to the NC state structure to initialize //! //! @return Always return EUCA_OK //! static int doInitialize(struct nc_state_t *nc) { #define GET_VALUE(_name, _var) \ { \ if (get_value (s, (_name), &(_var))) { \ logprintfl (EUCAFATAL, "did not find %s in output from %s\n", (_name), nc->get_info_cmd_path); \ EUCA_FREE(s); \ return (EUCA_FATAL_ERROR); \ } \ } char *s = NULL; // set up paths of Eucalyptus commands NC relies on snprintf(nc->get_info_cmd_path, MAX_PATH, EUCALYPTUS_GET_KVM_INFO, nc->home, nc->home); strcpy(nc->uri, HYPERVISOR_URI); nc->convert_to_disk = 1; nc->capability = HYPERVISOR_HARDWARE; //! @todo indicate virtio support? s = system_output(nc->get_info_cmd_path); GET_VALUE("nr_cores", nc->cores_max); GET_VALUE("total_memory", nc->mem_max); EUCA_FREE(s); // we leave 256M to the host nc->mem_max -= 256; return (EUCA_OK); }
//! //! Function description. //! //! @param[in] ebth pointer to the EB table handler structure //! @param[in] tablename a string pointer to the table name //! @param[in] chainmatch a string pointer to the list of characters to match //! //! @return //! //! @see //! //! @pre //! //! @post //! //! @note //! int ebt_table_deletechainmatch(ebt_handler * ebth, char *tablename, char *chainmatch) { int i, found = 0; ebt_table *table = NULL; if (!ebth || !tablename || !chainmatch || !ebth->init) { return (1); } table = ebt_handler_find_table(ebth, tablename); if (!table) { return (1); } found = 0; for (i = 0; i < table->max_chains && !found; i++) { if (strstr(table->chains[i].name, chainmatch)) { EUCA_FREE(table->chains[i].rules); bzero(&(table->chains[i]), sizeof(ebt_chain)); snprintf(table->chains[i].name, 64, "EMPTY"); } } return (0); }
//! //! Release all resources of the given ips_handler. //! //! @param[in] ipsh pointer to the IP set handler structure //! //! @return 0 on success. 1 otherwise. //! //! @see //! //! @pre //! //! @post //! //! @note //! int ips_handler_close(ips_handler * ipsh) { int i = 0; if (!ipsh || !ipsh->init) { LOGDEBUG("Invalid argument. NULL or uninitialized ips_handler.\n"); return (1); } for (i = 0; i < ipsh->max_sets; i++) { EUCA_FREE(ipsh->sets[i].member_ips); EUCA_FREE(ipsh->sets[i].member_nms); } EUCA_FREE(ipsh->sets); unlink(ipsh->ips_file); return (0); }
//! //! //! //! @param[in] req //! @param[in] prev_art //! //! @return A pointer to the newly created artifact //! artifact *prepare_requirements(imager_request * req, artifact * prev_art) { artifact *result = NULL; artifact *sentinel = NULL; prepare_params *state = NULL; assert(req); assert(req->internal); assert(prev_art == NULL); state = (prepare_params *) req->internal; // compute tree of dependencies sentinel = vbr_alloc_tree(&(state->vm), // the struct containing the VBR state->bootable, // TRUE when hypervisors can't take a kernel/ramdisk state->work, // TRUE when disk will be used by hypervisor on this host FALSE, // this is not a migration destination state->sshkey, // the SSH key state->id); // ID is for logging if (sentinel == NULL) err("failed to prepare image %s", state->id); assert(sentinel->deps[0]); result = sentinel->deps[0]; // result should be disk, not the dummy sentinel EUCA_FREE(sentinel); if (state->out) { // specified ID trumps generated one euca_strncpy(result->id, state->out, sizeof(result->id)); } return result; }