// internal pread, do a read query with offset on a different descriptor, do not change the position of the current one. ssize_t gridftp_rw_internal_pread(GridFTPFactory * factory, GridFTPFileDesc* desc, void* buffer, size_t s_buff, off_t offset) { // throw Gfal::CoreException gfal_log(GFAL_VERBOSE_TRACE, " -> [GridFTPModule::internal_pread]"); GridFTPSessionHandler handler(factory, desc->url); GridFTPRequestState request_state(&handler); GridFTPStreamState stream_state(&handler); globus_result_t res = globus_ftp_client_partial_get( handler.get_ftp_client_handle(), desc->url.c_str(), handler.get_ftp_client_operationattr(), NULL, offset, offset + s_buff, globus_ftp_client_done_callback, &request_state); gfal_globus_check_result(GFAL_GRIDFTP_SCOPE_INTERNAL_PREAD, res); ssize_t r_size = gridftp_read_stream(GFAL_GRIDFTP_SCOPE_INTERNAL_PREAD, &stream_state, buffer, s_buff); request_state.wait(GFAL_GRIDFTP_SCOPE_INTERNAL_PREAD); gfal_log(GFAL_VERBOSE_TRACE, "[GridFTPModule::internal_pread] <-"); return r_size; }
void ADIOI_GRIDFTP_ReadContig(ADIO_File fd, void *buf, int count, MPI_Datatype datatype, int file_ptr_type, ADIO_Offset offset, ADIO_Status *status, int *error_code) { static char myname[]="ADIOI_GRIDFTP_ReadContig"; int myrank, nprocs, datatype_size; globus_size_t len,bytes_read=0; globus_off_t goff; globus_result_t result; if ( fd->access_mode&MPI_MODE_WRONLY ) { *error_code=MPIR_ERR_MODE_WRONLY; return; } *error_code = MPI_SUCCESS; MPI_Comm_size(fd->comm, &nprocs); MPI_Comm_rank(fd->comm, &myrank); MPI_Type_size(datatype, &datatype_size); if (file_ptr_type != ADIO_EXPLICIT_OFFSET) { offset = fd->fp_ind; } /* Do the gridftp I/O transfer */ goff = (globus_off_t)offset; len = ((globus_size_t)datatype_size)*((globus_size_t)count); globus_mutex_init(&readcontig_ctl_lock, GLOBUS_NULL); globus_cond_init(&readcontig_ctl_cond, GLOBUS_NULL); readcontig_ctl_done=GLOBUS_FALSE; if ( (result=globus_ftp_client_partial_get(&(gridftp_fh[fd->fd_sys]), fd->filename, &(oattr[fd->fd_sys]), GLOBUS_NULL, goff, goff+(globus_off_t)len, readcontig_ctl_cb, GLOBUS_NULL))!=GLOBUS_SUCCESS ) { globus_err_handler("globus_ftp_client_partial_get",myname,result); *error_code=MPI_ERR_IO; ADIOI_Error(fd,*error_code,myname); return; } result=globus_ftp_client_register_read(&(gridftp_fh[fd->fd_sys]), (globus_byte_t *)buf, len, readcontig_data_cb, (void *)(&bytes_read)); if ( result != GLOBUS_SUCCESS ) { globus_err_handler("globus_ftp_client_register_read",myname,result); *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", globus_object_printable_to_string(result)); return; } /* The ctl callback won't start till the data callbacks complete, so it's safe to wait on just the ctl callback */ globus_mutex_lock(&readcontig_ctl_lock); while ( readcontig_ctl_done!=GLOBUS_TRUE ) globus_cond_wait(&readcontig_ctl_cond,&readcontig_ctl_lock); globus_mutex_unlock(&readcontig_ctl_lock); globus_mutex_destroy(&readcontig_ctl_lock); globus_cond_destroy(&readcontig_ctl_cond); #ifdef HAVE_STATUS_SET_BYTES MPIR_Status_set_bytes(status, datatype, bytes_read); #endif if (file_ptr_type != ADIO_EXPLICIT_OFFSET) { fd->fp_ind += bytes_read; fd->fp_sys_posn = fd->fp_ind; } else { fd->fp_sys_posn = offset + bytes_read; } }
void ADIOI_GRIDFTP_ReadDiscontig(ADIO_File fd, void *buf, int count, MPI_Datatype datatype, int file_ptr_type, ADIO_Offset offset, ADIO_Status *status, int *error_code) { char myname[]="ADIOI_GRIDFTP_ReadDiscontig"; int myrank,nprocs; /* size and extent of buffer in memory */ MPI_Aint btype_size,btype_extent; /* size and extent of file record layout */ MPI_Aint ftype_size,ftype_extent; /* size of file elemental type; seeks are done in units of this */ MPI_Aint etype_size; MPI_Aint extent; ADIOI_Flatlist_node *flat_file; int i,buf_contig,boff,nblks; globus_off_t start,end,goff; globus_size_t bytes_read; globus_result_t result; globus_byte_t *tmp; if ( fd->access_mode&MPI_MODE_WRONLY ) { *error_code=MPIR_ERR_MODE_WRONLY; return; } *error_code=MPI_SUCCESS; MPI_Comm_rank(fd->comm,&myrank); MPI_Comm_size(fd->comm,&nprocs); etype_size=fd->etype_size; MPI_Type_size(fd->filetype,&ftype_size); MPI_Type_extent(fd->filetype,&ftype_extent); /* This is arguably unnecessary, as this routine assumes that the buffer in memory is contiguous */ MPI_Type_size(datatype,&btype_size); MPI_Type_extent(datatype,&btype_extent); ADIOI_Datatype_iscontig(datatype,&buf_contig); if ( ( btype_extent!=btype_size ) || ( ! buf_contig ) ) { FPRINTF(stderr,"[%d/%d] %s called with discontigous memory buffer\n", myrank,nprocs,myname); fflush(stderr); *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", 0 ); return; } /* from here we can assume btype_extent==btype_size */ /* Flatten out fd->filetype so we know which blocks to skip */ ADIOI_Flatten_datatype(fd->filetype); flat_file = ADIOI_Flatlist; while (flat_file->type != fd->filetype && flat_file->next!=NULL) flat_file = flat_file->next; /* Figure out how big the area to read is */ start=(globus_off_t)(offset*etype_size); goff=start; boff=0; extent=0; nblks=0; while ( boff < (count*btype_size) ) { int blklen=0; for (i=0;i<flat_file->count;i++) { /* find the length of the next block */ if ( (boff+flat_file->blocklens[i]) < (count*btype_size) ) blklen=flat_file->blocklens[i]; else blklen=(count*btype_size)-boff; /* increment buffer size to be used */ boff+=blklen; /* compute extent -- the nblks*ftype_extent bit is there so we remember how many ftypes we've already been through */ extent=MAX(extent,nblks*ftype_extent+flat_file->indices[i]+blklen); if ( boff>=(count*btype_size) ) break; } nblks++; } if ( extent < count*btype_size ) { fprintf(stderr,"[%d/%d] %s error in computing extent -- extent %d is smaller than total bytes requested %d!\n", myrank,nprocs,myname,extent,count*btype_size); fflush(stderr); *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myanem, __LINE__, MPI_ERR_IO, "**io", 0); return; } end=start+(globus_off_t)extent; tmp=(globus_byte_t *)malloc((size_t)extent*sizeof(globus_byte_t)); /* start up the globus partial read */ globus_mutex_init(&readdiscontig_ctl_lock, GLOBUS_NULL); globus_cond_init(&readdiscontig_ctl_cond, GLOBUS_NULL); readdiscontig_ctl_done=GLOBUS_FALSE; if ( (result=globus_ftp_client_partial_get(&(gridftp_fh[fd->fd_sys]), fd->filename, &(oattr[fd->fd_sys]), GLOBUS_NULL, start, end, readdiscontig_ctl_cb, GLOBUS_NULL))!=GLOBUS_SUCCESS ) { globus_err_handler("globus_ftp_client_partial_get",myname,result); *error_code = MPIO_Err_create_code(MPI_SUCCESS, MPIR_ERR_RECOVERABLE, myanem, __LINE__, MPI_ERR_IO, "**io", "**io %s", globus_object_printable_to_string(result)); return; } /* Do all the actual I/Os */ /* Since globus_ftp_client_register_read() is brain-dead and doesn't let you specify an offset, we have to slurp the entire extent into memory and then parse out the pieces we want... Sucks, doesn't it? This should probably be done in chunks (preferably of a size set using a file hint), but that'll have to come later. --TB */ if ( (result=globus_ftp_client_register_read(&(gridftp_fh[fd->fd_sys]), tmp, (globus_size_t)extent, readdiscontig_data_cb, (void *)(&bytes_read)))!=GLOBUS_SUCCESS ) { globus_err_handler("globus_ftp_client_register_read",myname,result); *error_code = MPIO_Err_create_code(MPI_SUCESS, MPIR_ERR_RECOVERABLE, myname, __LINE__, MPI_ERR_IO, "**io", "**io %s", globus_object_printable_to_string(result)); return; } /* The ctl callback won't start till the data callbacks complete, so it's safe to wait on just the ctl callback */ globus_mutex_lock(&readdiscontig_ctl_lock); while ( readdiscontig_ctl_done!=GLOBUS_TRUE ) globus_cond_wait(&readdiscontig_ctl_cond,&readdiscontig_ctl_lock); globus_mutex_unlock(&readdiscontig_ctl_lock); globus_mutex_destroy(&readdiscontig_ctl_lock); globus_cond_destroy(&readdiscontig_ctl_cond); boff=0; nblks=0; goff=0; while ( boff < (count*btype_size) ) { int i,blklen; for (i=0;i<flat_file->count;i++) { if ( (boff+flat_file->blocklens[i]) < (count*btype_size) ) blklen=flat_file->blocklens[i]; else blklen=(count*btype_size)-boff; if ( blklen > 0 ) { goff=nblks*ftype_extent+flat_file->indices[i]; memcpy((globus_byte_t *)buf+boff,tmp+goff,(size_t)blklen); boff+=blklen; if ( boff>=(count*btype_size) ) break; } } nblks++; } free(tmp); #ifdef HAVE_STATUS_SET_BYTES MPIR_Status_set_bytes(status, datatype, bytes_read); #endif if (file_ptr_type != ADIO_EXPLICIT_OFFSET) { fd->fp_ind += extent; fd->fp_sys_posn = fd->fp_ind; } else { fd->fp_sys_posn = offset + extent; } }
int main(int argc, char *argv[]) { globus_ftp_client_handle_t handle; globus_ftp_client_operationattr_t attr; globus_byte_t buffer[SIZE]; globus_size_t buffer_length = sizeof(buffer); globus_result_t result; char * src; char * dst; globus_ftp_client_handleattr_t handle_attr; globus_off_t start_offset=5; globus_off_t end_offset=15; int i; globus_ftp_control_mode_t mode; globus_module_activate(GLOBUS_FTP_CLIENT_MODULE); globus_ftp_client_handleattr_init(&handle_attr); globus_ftp_client_operationattr_init(&attr); mode = GLOBUS_FTP_CONTROL_MODE_STREAM; /* Parse local arguments */ for(i = 1; i < argc; i++) { if(strcmp(argv[i], "-R") == 0 && i + 2 < argc) { globus_libc_scan_off_t(argv[i+1], &start_offset, GLOBUS_NULL); globus_libc_scan_off_t(argv[i+2], &end_offset, GLOBUS_NULL); test_remove_arg(&argc, argv, &i, 2); } else if(strcmp(argv[i], "-E") == 0 && i < argc) { mode = GLOBUS_FTP_CONTROL_MODE_EXTENDED_BLOCK; test_remove_arg(&argc, argv, &i, 0); } } test_parse_args(argc, argv, &handle_attr, &attr, &src, &dst); if(start_offset < 0) start_offset = 0; if(end_offset < 0) end_offset = 0; globus_mutex_init(&lock, GLOBUS_NULL); globus_cond_init(&cond, GLOBUS_NULL); globus_ftp_client_handle_init(&handle, &handle_attr); globus_ftp_client_operationattr_set_mode(&attr, mode); done = GLOBUS_FALSE; result = globus_ftp_client_partial_get(&handle, src, &attr, GLOBUS_NULL, start_offset, end_offset, done_cb, 0); if(result != GLOBUS_SUCCESS) { error = GLOBUS_TRUE; done = GLOBUS_TRUE; } else { globus_ftp_client_register_read( &handle, buffer, buffer_length, data_cb, 0); } globus_mutex_lock(&lock); while(!done) { globus_cond_wait(&cond, &lock); } globus_mutex_unlock(&lock); globus_ftp_client_handle_destroy(&handle); globus_module_deactivate_all(); if(test_abort_count && error) { return 0; } return error; }