// Old version using open, write // Still here because of the ability to use different modes int chirp_put_one_file(char *local, char *remote, char *mode, int perm) { struct chirp_client *client; // We connect each time, so that we don't have thousands // of idle connections hanging around the master CONNECT_STARTER(client); FILE *rfd; if (strcmp(local, "-") == 0) { rfd = stdin; } else { rfd = ::safe_fopen_wrapper_follow(local, "rb"); } if (rfd == NULL) { fprintf(stderr, "Can't open local file %s\n", local); DISCONNECT_AND_RETURN(client, -1); } int wfd = chirp_client_open(client, remote, mode, perm); if (wfd < 0) { ::fclose(rfd); fprintf(stderr, "Can't chirp_client_open %s:%d\n", remote, wfd); DISCONNECT_AND_RETURN(client, -1); } char buf[8192]; int num_read = 0; do { num_read = ::fread(buf, 1, 8192, rfd); if (num_read < 0) { fclose(rfd); fprintf(stderr, "local read error on %s\n", local); CLOSE_DISCONNECT_AND_RETURN(client, wfd, -1); } // EOF if (num_read == 0) { break; } int num_written = chirp_client_write(client, wfd, buf, num_read); if (num_written != num_read) { fclose(rfd); fprintf(stderr, "Couldn't chirp_write as much as we read\n"); CLOSE_DISCONNECT_AND_RETURN(client, wfd, -1); } } while (num_read > 0); ::fclose(rfd); CLOSE_DISCONNECT_AND_RETURN(client, wfd, 0); }
struct chirp_file * chirp_reli_open( const char *host, const char *path, INT64_T flags, INT64_T mode, time_t stoptime ) { struct chirp_file *file; int delay=0; time_t nexttry; INT64_T result; struct chirp_stat buf; time_t current; while(1) { struct chirp_client *client = connect_to_host(host,stoptime); if(client) { result = chirp_client_open(client,path,flags,mode,&buf,stoptime); if(result>=0) { file = xxmalloc(sizeof(*file)); strcpy(file->host,host); strcpy(file->path,path); memcpy(&file->info,&buf,sizeof(buf)); file->fd = result; file->flags = flags & ~(O_CREAT|O_TRUNC); file->mode = mode; file->serial = chirp_client_serial(client); file->stale = 0; file->buffer = malloc(chirp_reli_blocksize); file->buffer_offset = 0; file->buffer_valid = 0; file->buffer_dirty = 0; return file; } else { if(errno!=ECONNRESET) return 0; } invalidate_host(host); } else { if(errno==ENOENT) return 0; } if(time(0)>=stoptime) { errno = ECONNRESET; return 0; } if(delay>=2) debug(D_NOTICE,"couldn't connect to %s: still trying...\n",host); debug(D_CHIRP,"couldn't talk to %s: %s\n",host,strerror(errno)); current = time(0); nexttry = MIN(stoptime,current+delay); debug(D_CHIRP,"try again in %d seconds\n",(int)(nexttry-current)); sleep_until(nexttry); if(delay==0) { delay = 1; } else { delay = MIN(delay*2,MAX_DELAY); } } }
static INT64_T connect_to_file( struct chirp_client *client, struct chirp_file *file, time_t stoptime ) { struct chirp_stat buf; if(file->stale) { errno = ESTALE; return -1; } if(chirp_client_serial(client)==file->serial) return 1; debug(D_CHIRP,"verifying: %s",file->path); file->fd = chirp_client_open(client,file->path,file->flags,file->mode,&buf,stoptime); file->serial = chirp_client_serial(client); if(file->fd>=0) { if(buf.cst_dev!=file->info.cst_dev) { debug(D_CHIRP,"stale: device changed: %s",file->path); file->stale = 1; errno = ESTALE; return 0; } else if(buf.cst_ino!=file->info.cst_ino) { debug(D_CHIRP,"stale: inode changed: %s",file->path); file->stale = 1; errno = ESTALE; return 0; } else if(buf.cst_rdev!=file->info.cst_rdev) { debug(D_CHIRP,"stale: rdev changed: %s",file->path); file->stale = 1; errno = ESTALE; return 0; } else { debug(D_CHIRP,"uptodate: %s",file->path); file->stale = 0; return 1; } } else { if(errno!=ECONNRESET) { debug(D_CHIRP,"stale: %s: %s",strerror(errno),file->path); file->stale = 1; errno = ESTALE; return 0; } } return 1; }
int chirp_write(int argc, char **argv) { int fileOffset = 2; int offset = 0; int stride_length = 0; int stride_skip = 0; bool more = true; while (more && fileOffset + 1 < argc) { if (strcmp(argv[fileOffset], "-offset") == 0) { offset = strtol(argv[fileOffset + 1], NULL, 10); fileOffset += 2; more = true; } else if (strcmp(argv[fileOffset], "-stride") == 0 && fileOffset + 2 < argc) { stride_length = strtol(argv[fileOffset + 1], NULL, 10); stride_skip = strtol(argv[fileOffset + 2], NULL, 10); fileOffset += 3; more = true; } else { more = false; } } int length = 0; bool backward_compat = false; if(fileOffset + 2 == argc) { //backward compat backward_compat = true; if(stride_length != 0 || stride_skip != 0) { length = stride_length; } else { length = 1024; } } else if(fileOffset + 3 == argc) { length = strtol(argv[fileOffset + 2], NULL, 10); } else { printf("condor_chirp write [-offset offset] [-stride length skip] " "remote_file local_file length %d %d\n",fileOffset , argc); return -1; } char *remote_file = argv[fileOffset]; char *local_file = argv[fileOffset+1]; struct chirp_client *client = 0; CONNECT_STARTER(client); int num_read = 0, num_written = 0, add = 0; FILE *rfd; char *buf; // Use stdin or a local file if (strcmp(local_file, "-") == 0) { rfd = stdin; } else { rfd = ::safe_fopen_wrapper_follow(local_file, "rb"); if (!rfd) { fprintf(stderr, "Can't open local file %s\n", local_file); DISCONNECT_AND_RETURN(client, -1); } } // Open the remote file int fd = chirp_client_open(client, remote_file, "w", 0); if(fd < 0) { fclose(rfd); DISCONNECT_AND_RETURN(client, fd); } buf = (char*)malloc(length+1); if ( ! buf) { errno = ENOMEM; CLOSE_DISCONNECT_AND_RETURN(client, fd, -1); } int ret_val = -1; // Use pwrite if(stride_length == 0 && stride_skip == 0) { //offset is remote offset so we don't read using the offset value num_read = ::fread(buf, 1, length, rfd); if (num_read < 0) { fclose(rfd); free((char*)buf); fprintf(stderr, "Local read error on %s\n", local_file); CLOSE_DISCONNECT_AND_RETURN(client, fd, -1); } ret_val = chirp_client_pwrite(client, fd, buf, num_read, offset); } else { if (!backward_compat){ num_read = ::fread(buf, 1, length, rfd); if (num_read < 0) { fclose(rfd); free((char*)buf); fprintf(stderr, "Local read error on %s\n", local_file); CLOSE_DISCONNECT_AND_RETURN(client, fd, -1); } ret_val = chirp_client_swrite(client, fd, buf, length, offset, stride_length, stride_skip); } else { unsigned int total = 0; do { num_read = ::fread(buf, 1, length, rfd); if (num_read < 0) { fclose(rfd); free((char*)buf); fprintf(stderr, "Local read error on %s\n", local_file); CLOSE_DISCONNECT_AND_RETURN(client, fd, -1); } // EOF if (num_read == 0) { break; } // Use pwrite num_written = chirp_client_pwrite(client, fd, buf, num_read, offset+add); // Make sure we wrote the expected number of bytes if(num_written != num_read) { fclose(rfd); free((char*)buf); fprintf(stderr, "pwrite unable to write %d bytes\n", num_read); CLOSE_DISCONNECT_AND_RETURN(client, fd, -1); } total += num_written; if(stride_length != 0 || stride_skip != 0) { add += stride_skip; } else { add += num_read; } } while (num_read > 0); ret_val = total; } } fclose(rfd); free((char*)buf); CLOSE_DISCONNECT_AND_RETURN(client, fd, ret_val); }
int chirp_read(int argc, char **argv) { int fileOffset = 2; int offset = 0; int stride_length = 0; int stride_skip = 0; bool more = true; while (more && fileOffset + 1 < argc) { if (strcmp(argv[fileOffset], "-offset") == 0) { offset = strtol(argv[fileOffset + 1], NULL, 10); fileOffset += 2; more = true; } else if (strcmp(argv[fileOffset], "-stride") == 0 && fileOffset + 2 < argc) { stride_length = strtol(argv[fileOffset + 1], NULL, 10); stride_skip = strtol(argv[fileOffset + 2], NULL, 10); fileOffset += 3; more = true; } else { more = false; } } if(fileOffset + 2 != argc) { printf("condor_chirp read [-offset offset] [-stride length skip] " "remotepath length\n"); return -1; } char *path = argv[fileOffset]; int length = strtol(argv[fileOffset + 1], NULL, 10); struct chirp_client *client = 0; CONNECT_STARTER(client); int fd = chirp_client_open(client, path, "r", 0); if(fd < 0) { DISCONNECT_AND_RETURN(client, fd); } void* buf = malloc(length+1); int ret_val = -1; // Use read if(offset == 0 && stride_length == 0 && stride_skip == 0) { ret_val = chirp_client_read(client, fd, buf, length); } // Use pread else if(offset != 0 && stride_length == 0 && stride_skip == 0) { ret_val = chirp_client_pread(client, fd, buf, length, offset); } // Use sread else { ret_val = chirp_client_sread(client, fd, buf, length, offset, stride_length, stride_skip); } if(ret_val >= 0) { char* to_print = (char*)buf; to_print[length] = '\0'; printf("%s\n", to_print); } free(buf); CLOSE_DISCONNECT_AND_RETURN(client, fd, ret_val); }