//!
//! Do a clone of an instance backing store to another location.
//!
//! @param[in] instance pointer to the instance
//! @param[in] filePrefix the
//! @param[in] blockPath the path where we need to clone
//!
//! @return EUCA_OK on success or the following error codes:
//!         \li EUCA_IO_ERROR: if we fail to copy the data.
//!         \li EUCA_NOT_FOUND_ERROR: if we cannot find the blobstore to clone.
//!         \li EUCA_PERMISSION_ERROR: if we fail to create/open the destination blobstore
//!
//! @pre \li The instance parameter must not be NULL.
//!      \li The filePrefix and blockPath parameters must not be NULL and should be valid strings.
//!
//! @note
//!
int clone_bundling_backing(ncInstance * instance, const char *filePrefix, char *blockPath)
{
    int ret = EUCA_OK;
    int found = -1;
    char path[EUCA_MAX_PATH] = "";
    char work_regex[1024] = "";
    char id[BLOBSTORE_MAX_PATH] = "";
    char workPath[BLOBSTORE_MAX_PATH] = "";
    blockblob *src_blob = NULL;
    blockblob *dest_blob = NULL;
    blockblob *bb = NULL;
    blockblob_meta *bm = NULL;
    blockblob_meta *next = NULL;
    blockblob_meta *matches = NULL;

    set_path(path, sizeof(path), instance, NULL);
    set_id2(instance, "/.*", work_regex, sizeof(work_regex));

    if ((found = blobstore_search(work_bs, work_regex, &matches) <= 0)) {
        LOGERROR("[%s] failed to find blob in %s %d\n", instance->instanceId, path, found);
        return (EUCA_NOT_FOUND_ERROR);
    }

    for (bm = matches; bm; bm = bm->next) {
        bb = blockblob_open(work_bs, bm->id, 0, 0, NULL, FIND_TIMEOUT_USEC);
        if ((bb != NULL) && (bb->snapshot_type == BLOBSTORE_SNAPSHOT_DM) && (strstr(bb->blocks_path, "emi-") != NULL)) {
            // root image contains substr 'emi-'
            src_blob = bb;
            break;
        } else if (bb != NULL) {
            blockblob_close(bb);
        }
    }

    if (!src_blob) {
        LOGERROR("[%s] couldn't find the blob to clone from", instance->instanceId);
        ret = EUCA_NOT_FOUND_ERROR;
        goto error;
    }

    set_id(instance, NULL, workPath, sizeof(workPath));
    snprintf(id, sizeof(id), "%s/bundle/%s", workPath, filePrefix);

    // open destination blob
    dest_blob = blockblob_open(work_bs, id, src_blob->size_bytes, BLOBSTORE_FLAG_CREAT | BLOBSTORE_FLAG_EXCL, NULL, FIND_TIMEOUT_USEC);
    if (!dest_blob) {
        LOGERROR("[%s] couldn't create the destination blob for bundling (%s)", instance->instanceId, id);
        ret = EUCA_PERMISSION_ERROR;
        goto error;
    }

    if (strlen(dest_blob->blocks_path) > 0)
        snprintf(blockPath, EUCA_MAX_PATH, "%s", dest_blob->blocks_path);

    // copy blob (will 'dd' eventually)
    if (blockblob_copy(src_blob, 0, dest_blob, 0, src_blob->size_bytes) != EUCA_OK) {
        LOGERROR("[%s] couldn't copy block blob for bundling (%s)", instance->instanceId, id);
        ret = EUCA_IO_ERROR;
        goto error;
    }

error:
    // free the search results
    for (bm = matches; bm; bm = next) {
        next = bm->next;
        EUCA_FREE(bm);
    }

    // Close our blockblobs
    BLOCKBLOB_CLOSE(src_blob);
    BLOCKBLOB_CLOSE(dest_blob);
    return (ret);
}
Beispiel #2
0
int clone_bundling_backing (ncInstance *instance, const char* filePrefix, char* blockPath)
{
    char path[MAX_PATH];
    char work_regex [1024];
    char id [BLOBSTORE_MAX_PATH];
    char workPath [BLOBSTORE_MAX_PATH];
    int ret = OK;
    int found=-1;
    blockblob *src_blob = NULL, *dest_blob = NULL;
    blockblob_meta *matches = NULL;
    
    set_path (path, sizeof (path), instance, NULL);
    set_id2 (instance, "/.*", work_regex, sizeof (work_regex));
    
    if( (found=blobstore_search (work_bs, work_regex, &matches) <= 0 ) ) {
        logprintfl (EUCAERROR, "[%s] error: failed to find blob in %s %d\n", instance->instanceId, path, found);
        return ERROR;
    }
    
    for (blockblob_meta * bm = matches; bm; bm=bm->next) {
        blockblob * bb = blockblob_open (work_bs, bm->id, 0, 0, NULL, FIND_TIMEOUT_USEC);
        if (bb!=NULL && bb->snapshot_type == BLOBSTORE_SNAPSHOT_DM && strstr(bb->blocks_path,"emi-") != NULL) { // root image contains substr 'emi-'
            src_blob = bb;
            break;
        } else if (bb!=NULL) {
            blockblob_close(bb);
        }
    } 
    if (!src_blob) {
        logprintfl (EUCAERROR, "[%s] couldn't find the blob to clone from", instance->instanceId);
        goto error;
    }
    set_id (instance, NULL, workPath, sizeof (workPath));
    snprintf (id, sizeof(id), "%s/%s", workPath, filePrefix);
    
    // open destination blob 
    dest_blob = blockblob_open (work_bs, id, src_blob->size_bytes, BLOBSTORE_FLAG_CREAT | BLOBSTORE_FLAG_EXCL, NULL, FIND_TIMEOUT_USEC); 
    if (!dest_blob) {
        logprintfl (EUCAERROR, "[%s] couldn't create the destination blob for bundling (%s)", instance->instanceId, id);
        goto error;
    }
    
    if (strlen (dest_blob->blocks_path) > 0)
        snprintf (blockPath, MAX_PATH, "%s", dest_blob->blocks_path);
    
    // copy blob (will 'dd' eventually)
    if (blockblob_copy (src_blob, 0, dest_blob, 0, src_blob->size_bytes) != OK) {
        logprintfl (EUCAERROR, "[%s] couldn't copy block blob for bundling (%s)", instance->instanceId, id);
        goto error;
    }
    
    goto free;
 error: 
    ret = ERROR; 
 free:
    // free the search results
    for (blockblob_meta * bm = matches; bm;) {
        blockblob_meta * next = bm->next;
        free (bm);
        bm = next;
    } 
    
    if(src_blob)
        blockblob_close(src_blob);
    if(dest_blob)
        blockblob_close(dest_blob);
    return ret;
}