コード例 #1
0
void DCOPY_do_cleanup(DCOPY_operation_t* op, \
                      CIRCLE_handle* handle)
{
    char* newop;

    /*
     * Truncate file on last chunk (synchronous mode can write past end of file)
     */
    int64_t bytes_written = (int64_t)(op->chunk + 1) * (int64_t)DCOPY_user_opts.chunk_size;
    if(bytes_written >= op->file_size) {
        /* truncate file to appropriate size, to do this before
         * setting permissions in case file does not have write permission */
        DCOPY_truncate_file(op, handle);

        /* since we still may access the file in the compare step,
         * delay setting permissions and timestamps until final phase */
    }

    /*
     * Add work item to compare source and destination if user requested it.
     */
    if(DCOPY_user_opts.compare) {
        newop = DCOPY_encode_operation(COMPARE, op->chunk, op->operand, \
                                       op->source_base_offset, \
                                       op->dest_base_appendix, op->file_size);

        handle->enqueue(newop);
        free(newop);
    }

    return;
}
コード例 #2
0
ファイル: common.c プロジェクト: hpc/fileutils
void DCOPY_retry_failed_operation(DCOPY_operation_code_t target, \
                                  CIRCLE_handle* handle, \
                                  DCOPY_operation_t* op)
{
    char* new_op;

    if(DCOPY_user_opts.reliable_filesystem) {
        MFU_LOG(MFU_LOG_ERR, "Not retrying failed operation. " \
            "Reliable filesystem is specified. (op=%d chunk=%ld src=%s dst=%s)",
            target, op->chunk, op->operand, op->dest_full_path);

        DCOPY_abort(EXIT_FAILURE);
    }
    else {
        MFU_LOG(MFU_LOG_INFO, "Attempting to retry operation.");

        new_op = DCOPY_encode_operation(target, op->chunk, op->operand, \
                                        op->source_base_offset, \
                                        op->dest_base_appendix, op->file_size);

        handle->enqueue(new_op);
        mfu_free(&new_op);
    }

    return;
}
コード例 #3
0
ファイル: copy.c プロジェクト: ashayh/dcp
/*
 * Encode and enqueue the cleanup stage for this chunk so the file is
 * truncated and (if specified via getopt) permissions are preserved.
 */
void DCOPY_enqueue_cleanup_stage(DCOPY_operation_t* op, \
                                 CIRCLE_handle* handle)
{
    char* newop;

    newop = DCOPY_encode_operation(CLEANUP, op->chunk, op->operand, \
                                   op->source_base_offset, \
                                   op->dest_base_appendix, op->file_size);

    handle->enqueue(newop);
    free(newop);
}
コード例 #4
0
ファイル: cleanup.c プロジェクト: bringhurst/dcp
void DCOPY_do_cleanup(DCOPY_operation_t* op, \
                      CIRCLE_handle* handle)
{
    char* newop;
    bool ownership_preserved;

    /*
     * Only bother truncating and setting permissions on the first chunk of
     * the file.
     */
    if(op->chunk == 0) {

        if(DCOPY_user_opts.preserve) {
            /* build destination object name */
            char dest_path_recursive[PATH_MAX];
            char dest_path_file_to_file[PATH_MAX];

            if(op->dest_base_appendix == NULL) {
                sprintf(dest_path_recursive, "%s/%s", \
                        DCOPY_user_opts.dest_path, \
                        op->operand + op->source_base_offset + 1);

                strncpy(dest_path_file_to_file, DCOPY_user_opts.dest_path, PATH_MAX);
            }
            else {
                sprintf(dest_path_recursive, "%s/%s/%s", \
                        DCOPY_user_opts.dest_path, \
                        op->dest_base_appendix, \
                        op->operand + op->source_base_offset + 1);

                sprintf(dest_path_file_to_file, "%s/%s", \
                        DCOPY_user_opts.dest_path, \
                        op->dest_base_appendix);
            }

            /* get stat of source object */
            struct stat64 statbuf;

            if(lstat64(op->operand, &statbuf) == 0) {
                ownership_preserved = DCOPY_set_preserve_ownership(op, handle, &statbuf, dest_path_recursive);
                DCOPY_set_preserve_permissions(op, handle, ownership_preserved, &statbuf, dest_path_recursive);
                DCOPY_set_preserve_timestamps(op, handle, &statbuf, dest_path_recursive);
            }
            else {
                /*
                        LOG(DCOPY_LOG_ERR, "Could not determine if `%s' is a directory. %s", path, strerror(errno));
                */
            }
        }

        DCOPY_truncate_file(op, handle);
    }

    /*
     * If the user is feeling brave, this is where we let them skip the
     * comparison stage.
     */
    if(!DCOPY_user_opts.skip_compare) {
        newop = DCOPY_encode_operation(COMPARE, op->chunk, op->operand, \
                                       op->source_base_offset, \
                                       op->dest_base_appendix, op->file_size);

        handle->enqueue(newop);
        free(newop);
    }

    return;
}
コード例 #5
0
ファイル: handle_args.c プロジェクト: ashayh/dcp
/**
 * Analyze all file path inputs and place on the work queue.
 *
 * We start off with all of the following potential options in mind and prune
 * them until we figure out what situation we have.
 *
 * Libcircle only calls this function from rank 0, so there's no need to check
 * the current rank here.
 *
 * Source must overwrite destination.
 *   - Single file to single file
 *
 * Must return an error. Impossible condition.
 *   - Single directory to single file
 *   - Many file to single file
 *   - Many directory to single file
 *   - Many directory and many file to single file
 *
 * All Sources must be placed inside destination.
 *   - Single file to single directory
 *   - Single directory to single directory
 *   - Many file to single directory
 *   - Many directory to single directory
 *   - Many file and many directory to single directory
 *
 * @param handle the libcircle primary queue handle.
 */
void DCOPY_enqueue_work_objects(CIRCLE_handle* handle)
{
    bool dest_is_dir = DCOPY_dest_is_dir();
    bool dest_is_file  = !dest_is_dir;

    char* opts_dest_path_dirname;
    char* src_path_dirname;

    uint32_t number_of_source_files = DCOPY_source_file_count();

    if(number_of_source_files < 1) {
        LOG(DCOPY_LOG_ERR, "At least one valid source file must be specified.");
        DCOPY_abort(EXIT_FAILURE);
    }

    if(dest_is_file) {
        LOG(DCOPY_LOG_DBG, "Infered that the destination is a file.");

        /*
         * If the destination is a file, there must be only one source object, and it
         * must be a file.
         */
        if(number_of_source_files == 1 && DCOPY_is_regular_file(DCOPY_user_opts.src_path[0])) {
            /* Make a copy of the dest path so we can run dirname on it. */
            size_t dest_size = sizeof(char) * PATH_MAX;
            opts_dest_path_dirname = (char*) malloc(dest_size);

            if(opts_dest_path_dirname == NULL) {
                LOG(DCOPY_LOG_DBG, "Failed to allocate %llu bytes for dest path.", (long long unsigned) dest_size);
                DCOPY_abort(EXIT_FAILURE);
            }

            int dest_written = snprintf(opts_dest_path_dirname, dest_size, "%s", DCOPY_user_opts.dest_path);

            if(dest_written < 0 || (size_t)(dest_written) > dest_size - 1) {
                LOG(DCOPY_LOG_DBG, "Destination path too long.");
                DCOPY_abort(EXIT_FAILURE);
            }

            opts_dest_path_dirname = dirname(opts_dest_path_dirname);

            /* Make a copy of the src path so we can run dirname on it. */
            size_t src_size = sizeof(char) * PATH_MAX;
            src_path_dirname = (char*) malloc(sizeof(char) * PATH_MAX);

            if(src_path_dirname == NULL) {
                LOG(DCOPY_LOG_DBG, "Failed to allocate %llu bytes for dest path.", (long long unsigned) src_size);
                DCOPY_abort(EXIT_FAILURE);
            }

            int src_written = snprintf(src_path_dirname, src_size, "%s", DCOPY_user_opts.src_path[0]);

            if(src_written < 0 || (size_t)(src_written) > src_size - 1) {
                LOG(DCOPY_LOG_DBG, "Source path too long.");
                DCOPY_abort(EXIT_FAILURE);
            }

            src_path_dirname = dirname(src_path_dirname);

            /* LOG(DCOPY_LOG_DBG, "Enqueueing only a single source path `%s'.", DCOPY_user_opts.src_path[0]); */
            char* op = DCOPY_encode_operation(TREEWALK, 0, DCOPY_user_opts.src_path[0], \
                                              (uint16_t)strlen(src_path_dirname), NULL, 0);

            handle->enqueue(op);
            free(op);

            free(opts_dest_path_dirname);
            free(src_path_dirname);
        }
        else {
            /*
             * Determine if we're trying to copy one or more directories into
             * a file.
             */
            int i;

            for(i = 0; i < DCOPY_user_opts.num_src_paths; i++) {
                char* src_path = DCOPY_user_opts.src_path[i];

                if(DCOPY_is_directory(src_path)) {
                    LOG(DCOPY_LOG_ERR, "Copying a directory into a file is not supported.");
                    DCOPY_abort(EXIT_FAILURE);
                }
            }

            /*
             * The only remaining possible condition is that the user wants to
             * copy multiple files into a single file (hopefully).
             */
            LOG(DCOPY_LOG_ERR, "Copying several files into a single file is not supported.");
            DCOPY_abort(EXIT_FAILURE);
        }
    }
    else if(dest_is_dir) {
        LOG(DCOPY_LOG_DBG, "Infered that the destination is a directory.");
        bool dest_already_exists = DCOPY_is_directory(DCOPY_user_opts.dest_path);

        int i;

        for(i = 0; i < DCOPY_user_opts.num_src_paths; i++) {
            char* src_path = DCOPY_user_opts.src_path[i];
            LOG(DCOPY_LOG_DBG, "Enqueueing source path `%s'.", src_path);

            char* src_path_basename = NULL;
            size_t src_len = strlen(src_path) + 1;
            char* src_path_basename_tmp = (char*) malloc(src_len);

            if(src_path_basename_tmp == NULL) {
                LOG(DCOPY_LOG_ERR, "Failed to allocate tmp for src_path_basename.");
                DCOPY_abort(EXIT_FAILURE);
            }

            /*
             * If the destination directory already exists, we want to place
             * new files inside it. To do this, we send a path fragment along
             * with the source path message and append it to the options dest
             * path whenever the options dest path is used.
             */
            if(dest_already_exists && !DCOPY_user_opts.conditional) {
                /* Make a copy of the src path so we can run basename on it. */
                strncpy(src_path_basename_tmp, src_path, src_len);
                src_path_basename = basename(src_path_basename_tmp);
            }

            char* op = DCOPY_encode_operation(TREEWALK, 0, src_path, \
                                              (uint16_t)(src_len - 1), \
                                              src_path_basename, 0);
            handle->enqueue(op);
            free(src_path_basename_tmp);
        }
    }
    else {
        /*
         * This is the catch-all for all of the object types we haven't
         * implemented yet.
         */
        LOG(DCOPY_LOG_ERR, "We've encountered an unsupported filetype.");
        DCOPY_abort(EXIT_FAILURE);
    }

    /* TODO: print mode we're using to DBG. */
}