Beispiel #1
0
//! 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;
}
Beispiel #2
0
//!
//! 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;
}
Beispiel #3
0
//!
//! 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);
}
Beispiel #5
0
//!
//! 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;
        }
    }
}
Beispiel #6
0
//!
//! 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);
}
Beispiel #7
0
//!
//! 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);
}
Beispiel #9
0
//!
//! 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;
        }
    }
}
Beispiel #10
0
/**
 * 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);
}
Beispiel #12
0
//!
//! 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);
}
Beispiel #13
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);
}
Beispiel #14
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 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);
}
Beispiel #16
0
//!
//!
//!
//! @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);
}
Beispiel #17
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);
}
Beispiel #18
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);
}
Beispiel #19
0
//!
//! 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;
}
Beispiel #20
0
//!
//! 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;
}
Beispiel #21
0
//!
//! 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;
}
Beispiel #22
0
//!
//! 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);
}
Beispiel #23
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;
}
Beispiel #24
0
//!
//! 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);
}
Beispiel #25
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);
}
Beispiel #27
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);
}
Beispiel #28
0
//!
//! 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);
}
Beispiel #30
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;
}