2
Copyright (C) 2003-2004 Douglas Thain and the University of Wisconsin
3
Copyright (C) 2005- The University of Notre Dame
4
This software is distributed under the GNU General Public License.
5
See the file COPYING for details.
8
#include "chirp_reli.h"
9
#include "chirp_protocol.h"
10
#include "chirp_client.h"
15
#include "sleeptools.h"
16
#include "hash_table.h"
30
char host[CHIRP_LINE_MAX];
31
char path[CHIRP_LINE_MAX];
32
struct chirp_stat info;
40
INT64_T buffer_offset;
44
struct hash_table *table = 0;
45
static int chirp_reli_blocksize = 65536;
47
INT64_T chirp_reli_blocksize_get()
49
return chirp_reli_blocksize;
52
void chirp_reli_blocksize_set( INT64_T bs )
54
chirp_reli_blocksize = bs;
57
static struct chirp_client * connect_to_host( const char *host, time_t stoptime )
59
struct chirp_client *c;
62
table = hash_table_create(0,0);
66
c = hash_table_lookup(table,host);
69
if(!strncmp(host,"CONDOR",6)) {
70
c = chirp_client_connect_condor(stoptime);
72
c = chirp_client_connect(host,1,stoptime);
76
hash_table_insert(table,host,c);
83
static INT64_T connect_to_file( struct chirp_client *client, struct chirp_file *file, time_t stoptime )
85
struct chirp_stat buf;
92
if(chirp_client_serial(client)==file->serial) return 1;
94
debug(D_CHIRP,"verifying: %s",file->path);
95
file->fd = chirp_client_open(client,file->path,file->flags,file->mode,&buf,stoptime);
96
file->serial = chirp_client_serial(client);
98
if(buf.cst_dev!=file->info.cst_dev) {
99
debug(D_CHIRP,"stale: device changed: %s",file->path);
103
} else if(buf.cst_ino!=file->info.cst_ino) {
104
debug(D_CHIRP,"stale: inode changed: %s",file->path);
108
} else if(buf.cst_rdev!=file->info.cst_rdev) {
109
debug(D_CHIRP,"stale: rdev changed: %s",file->path);
114
debug(D_CHIRP,"uptodate: %s",file->path);
119
if(errno!=ECONNRESET) {
120
debug(D_CHIRP,"stale: %s: %s",strerror(errno),file->path);
130
static void invalidate_host( const char *host )
132
struct chirp_client *c;
133
c = hash_table_remove(table,host);
134
if(c) chirp_client_disconnect(c);
137
struct chirp_file * chirp_reli_open( const char *host, const char *path, INT64_T flags, INT64_T mode, time_t stoptime )
139
struct chirp_file *file;
143
struct chirp_stat buf;
147
struct chirp_client *client = connect_to_host(host,stoptime);
149
result = chirp_client_open(client,path,flags,mode,&buf,stoptime);
151
file = xxmalloc(sizeof(*file));
152
strcpy(file->host,host);
153
strcpy(file->path,path);
154
memcpy(&file->info,&buf,sizeof(buf));
156
file->flags = flags & ~(O_CREAT|O_TRUNC);
158
file->serial = chirp_client_serial(client);
160
file->buffer = malloc(chirp_reli_blocksize);
161
file->buffer_offset = 0;
162
file->buffer_valid = 0;
163
file->buffer_dirty = 0;
166
if(errno!=ECONNRESET) return 0;
168
invalidate_host(host);
170
if(errno==ENOENT) return 0;
172
if(time(0)>=stoptime) {
176
if(delay>=2) debug(D_NOTICE,"couldn't connect to %s: still trying...\n",host);
177
debug(D_CHIRP,"couldn't talk to %s: %s\n",host,strerror(errno));
179
nexttry = MIN(stoptime,current+delay);
180
debug(D_CHIRP,"try again in %d seconds\n",nexttry-current);
181
sleep_until(nexttry);
185
delay = MIN(delay*2,MAX_DELAY);
190
INT64_T chirp_reli_close( struct chirp_file *file, time_t stoptime )
192
struct chirp_client *client = connect_to_host(file->host,stoptime);
193
chirp_reli_flush(file,stoptime);
195
if(chirp_client_serial(client)==file->serial) {
196
chirp_client_close(client,file->fd,stoptime);
204
#define RETRY_FILE( ZZZ ) \
210
struct chirp_client *client = connect_to_host(file->host,stoptime); \
212
if(connect_to_file(client,file,stoptime)) { \
214
if(result>=0 || errno!=ECONNRESET) return result; \
216
if(errno==ESTALE) return -1; \
217
invalidate_host(file->host); \
219
if(errno==ENOENT) return -1; \
220
if(errno==EPERM) return -1; \
221
if(errno==EACCES) return -1; \
223
if(time(0)>=stoptime) { \
224
errno = ECONNRESET; \
227
if(delay>=2) debug(D_NOTICE,"couldn't connect to %s: still trying...\n",file->host); \
228
debug(D_CHIRP,"couldn't talk to %s: %s\n",file->host,strerror(errno)); \
230
nexttry = MIN(stoptime,current+delay); \
231
debug(D_CHIRP,"try again in %d seconds\n",nexttry-current); \
232
sleep_until(nexttry); \
236
delay = MIN(delay*2,MAX_DELAY); \
241
INT64_T chirp_reli_pread_unbuffered( struct chirp_file *file, void *data, INT64_T length, INT64_T offset, time_t stoptime )
243
RETRY_FILE( result = chirp_client_pread(client,file->fd,data,length,offset,stoptime); )
246
static INT64_T chirp_reli_pread_buffered( struct chirp_file *file, void *data, INT64_T length, INT64_T offset, time_t stoptime )
248
if(file->buffer_valid) {
249
if(offset >= file->buffer_offset && offset < (file->buffer_offset+file->buffer_valid) ) {
251
blength = MIN(length,file->buffer_offset+file->buffer_valid-offset);
252
memcpy(data,&file->buffer[offset-file->buffer_offset],blength);
257
chirp_reli_flush(file,stoptime);
259
if(length<=chirp_reli_blocksize) {
260
INT64_T result = chirp_reli_pread_unbuffered(file,file->buffer,chirp_reli_blocksize,offset,stoptime);
262
file->buffer_offset = 0;
263
file->buffer_valid = 0;
264
file->buffer_dirty = 0;
267
file->buffer_offset = offset;
268
file->buffer_valid = result;
269
file->buffer_dirty = 0;
270
result = MIN(result,length);
271
memcpy(data,file->buffer,result);
275
return chirp_reli_pread_unbuffered(file,data,length,offset,stoptime);
279
INT64_T chirp_reli_pread( struct chirp_file *file, void *data, INT64_T length, INT64_T offset, time_t stoptime )
286
actual = chirp_reli_pread_buffered(file,cdata,length,offset,stoptime);
302
INT64_T chirp_reli_pwrite_unbuffered( struct chirp_file *file, const void *data, INT64_T length, INT64_T offset, time_t stoptime )
304
RETRY_FILE( result = chirp_client_pwrite(client,file->fd,data,length,offset,stoptime); )
307
static INT64_T chirp_reli_pwrite_buffered( struct chirp_file *file, const void *data, INT64_T length, INT64_T offset, time_t stoptime )
309
if(length>=chirp_reli_blocksize) {
310
if(chirp_reli_flush(file,stoptime)<0) {
313
return chirp_reli_pwrite_unbuffered(file,data,length,offset,stoptime);
317
if(file->buffer_valid>0) {
318
if( (file->buffer_offset + file->buffer_valid) == offset ) {
319
INT64_T blength = MIN(chirp_reli_blocksize-file->buffer_valid,length);
320
memcpy(&file->buffer[file->buffer_valid],data,blength);
321
file->buffer_valid += blength;
322
file->buffer_dirty = 1;
323
if(file->buffer_valid==chirp_reli_blocksize) {
324
if(chirp_reli_flush(file,stoptime)<0) {
330
if(chirp_reli_flush(file,stoptime)<0) {
338
/* if we got here, then the buffer is empty */
340
file->buffer_offset = offset;
341
file->buffer_valid = length;
342
file->buffer_dirty = 1;
343
memcpy(file->buffer,data,length);
347
INT64_T chirp_reli_pwrite( struct chirp_file *file, const void *data, INT64_T length, INT64_T offset, time_t stoptime )
349
const char *cdata = data;
354
actual = chirp_reli_pwrite_buffered(file,cdata,length,offset,stoptime);
370
INT64_T chirp_reli_sread( struct chirp_file *file, void *data, INT64_T length, INT64_T stride_length, INT64_T stride_offset, INT64_T offset, time_t stoptime )
372
chirp_reli_flush(file,stoptime);
373
RETRY_FILE( result = chirp_client_sread(client,file->fd,data,length,stride_length,stride_offset,offset,stoptime); )
376
INT64_T chirp_reli_swrite( struct chirp_file *file, const void *data, INT64_T length, INT64_T stride_length, INT64_T stride_offset, INT64_T offset, time_t stoptime )
378
chirp_reli_flush(file,stoptime);
379
RETRY_FILE( result = chirp_client_swrite(client,file->fd,data,length,stride_length,stride_offset,offset,stoptime); )
382
INT64_T chirp_reli_fstat( struct chirp_file *file, struct chirp_stat *buf, time_t stoptime )
384
chirp_reli_flush(file,stoptime);
385
RETRY_FILE( result = chirp_client_fstat(client,file->fd,buf,stoptime); )
388
INT64_T chirp_reli_fstatfs( struct chirp_file *file, struct chirp_statfs *buf, time_t stoptime )
390
chirp_reli_flush(file,stoptime);
391
RETRY_FILE( result = chirp_client_fstatfs(client,file->fd,buf,stoptime); )
394
INT64_T chirp_reli_fchown( struct chirp_file *file, INT64_T uid, INT64_T gid, time_t stoptime )
396
chirp_reli_flush(file,stoptime);
397
RETRY_FILE( result = chirp_client_fchown(client,file->fd,uid,gid,stoptime); )
400
INT64_T chirp_reli_fchmod( struct chirp_file *file, INT64_T mode, time_t stoptime )
402
chirp_reli_flush(file,stoptime);
403
RETRY_FILE( result = chirp_client_fchmod(client,file->fd,mode,stoptime); )
406
INT64_T chirp_reli_ftruncate( struct chirp_file *file, INT64_T length, time_t stoptime )
408
chirp_reli_flush(file,stoptime);
409
RETRY_FILE( result = chirp_client_ftruncate(client,file->fd,length,stoptime); )
412
INT64_T chirp_reli_flush( struct chirp_file *file, time_t stoptime )
416
if(file->buffer_valid && file->buffer_dirty) {
417
result = chirp_reli_pwrite_unbuffered(file,file->buffer,file->buffer_valid,file->buffer_offset,stoptime);
422
file->buffer_valid = 0;
423
file->buffer_dirty = 0;
424
file->buffer_offset = 0;
429
INT64_T chirp_reli_fsync( struct chirp_file *file, time_t stoptime )
431
chirp_reli_flush(file,stoptime);
432
RETRY_FILE( result = chirp_client_fsync(client,file->fd,stoptime); );
435
#define RETRY_ATOMIC( ZZZ ) \
441
struct chirp_client *client = connect_to_host(host,stoptime); \
444
if(result>=0 || errno!=ECONNRESET) return result; \
445
invalidate_host(host); \
447
if(errno==ENOENT) return -1; \
448
if(errno==EPERM) return -1; \
449
if(errno==EACCES) return -1; \
451
if(time(0)>=stoptime) { \
452
errno = ECONNRESET; \
455
if(delay>=2) debug(D_NOTICE,"couldn't connect to %s: still trying...\n",host); \
456
debug(D_CHIRP,"couldn't talk to %s: %s\n",host,strerror(errno)); \
458
nexttry = MIN(stoptime,current+delay); \
459
debug(D_CHIRP,"try again in %d seconds\n",nexttry-current); \
460
sleep_until(nexttry); \
464
delay = MIN(delay*2,MAX_DELAY); \
468
INT64_T chirp_reli_whoami( const char *host, char *buf, INT64_T length, time_t stoptime )
470
RETRY_ATOMIC( result = chirp_client_whoami(client,buf,length,stoptime); );
473
INT64_T chirp_reli_whoareyou( const char *host, const char *rhost, char *buffer, INT64_T length, time_t stoptime )
475
RETRY_ATOMIC( result = chirp_client_whoareyou(client,rhost,buffer,length,stoptime); );
478
INT64_T chirp_reli_getfile( const char *host, const char *path, FILE *stream, time_t stoptime )
480
INT64_T pos = ftell(stream);
481
if (pos < 0) pos = 0;
484
fseek(stream,pos,SEEK_SET);\
485
result = chirp_client_getfile(client,path,stream,stoptime);\
486
if(result<0 && ferror(stream)) { errno=EIO; return -1; }\
490
INT64_T chirp_reli_getfile_buffer( const char *host, const char *path, char **buffer, time_t stoptime )
492
RETRY_ATOMIC( result = chirp_client_getfile_buffer(client,path,buffer,stoptime); )
495
INT64_T chirp_reli_putfile( const char *host, const char *path, FILE *stream, INT64_T mode, INT64_T length, time_t stoptime )
498
fseek(stream,0,SEEK_SET);\
499
result = chirp_client_putfile(client,path,stream,mode,length,stoptime);\
500
if(result<0 && ferror(stream)) { errno=EIO; return -1; }\
504
INT64_T chirp_reli_putfile_buffer( const char *host, const char *path, const char *buffer, INT64_T mode, INT64_T length, time_t stoptime )
506
RETRY_ATOMIC( result = chirp_client_putfile_buffer(client,path,buffer,mode,length,stoptime); )
509
INT64_T chirp_reli_getlongdir( const char *host, const char *path, chirp_longdir_t callback, void *arg, time_t stoptime )
511
RETRY_ATOMIC( result = chirp_client_getlongdir(client,path,callback,arg,stoptime); )
514
INT64_T chirp_reli_getdir( const char *host, const char *path, chirp_dir_t callback, void *arg, time_t stoptime )
516
RETRY_ATOMIC( result = chirp_client_getdir(client,path,callback,arg,stoptime); )
519
INT64_T chirp_reli_getacl( const char *host, const char *path, chirp_dir_t callback, void *arg, time_t stoptime )
521
RETRY_ATOMIC( result = chirp_client_getacl(client,path,callback,arg,stoptime); )
524
INT64_T chirp_reli_ticket_create( const char *host, char name[CHIRP_PATH_MAX], unsigned bits, time_t stoptime )
526
RETRY_ATOMIC( result = chirp_client_ticket_create(client,name,bits,stoptime); )
529
INT64_T chirp_reli_ticket_register( const char *host, const char *name, const char *subject, time_t duration, time_t stoptime )
531
RETRY_ATOMIC( result = chirp_client_ticket_register(client,name,subject,duration,stoptime); )
534
INT64_T chirp_reli_ticket_delete( const char *host, const char *name, time_t stoptime )
536
RETRY_ATOMIC( result = chirp_client_ticket_delete(client,name,stoptime); )
539
INT64_T chirp_reli_ticket_list( const char *host, const char *subject, char ***list, time_t stoptime )
541
RETRY_ATOMIC( result = chirp_client_ticket_list(client,subject,list,stoptime); )
544
INT64_T chirp_reli_ticket_get( const char *host, const char *name, char **subject, char **ticket, time_t *duration, char ***rights, time_t stoptime )
546
RETRY_ATOMIC( result = chirp_client_ticket_get(client,name,subject,ticket,duration,rights,stoptime); )
549
INT64_T chirp_reli_ticket_modify( const char *host, const char *name, const char *path, const char *aclmask, time_t stoptime )
551
RETRY_ATOMIC( result = chirp_client_ticket_modify(client,name,path,aclmask,stoptime); )
554
INT64_T chirp_reli_setacl( const char *host, const char *path, const char *subject, const char *rights, time_t stoptime )
556
RETRY_ATOMIC( result = chirp_client_setacl(client,path,subject,rights,stoptime); )
559
INT64_T chirp_reli_resetacl( const char *host, const char *path, const char *rights, time_t stoptime )
561
RETRY_ATOMIC( result = chirp_client_resetacl(client,path,rights,stoptime); )
564
INT64_T chirp_reli_locate( const char *host, const char *path, chirp_loc_t callback, void *arg, time_t stoptime )
566
RETRY_ATOMIC( result = chirp_client_locate(client,path,callback,arg,stoptime); )
569
INT64_T chirp_reli_unlink( const char *host, const char *path, time_t stoptime )
571
RETRY_ATOMIC( result = chirp_client_unlink(client,path,stoptime); )
574
INT64_T chirp_reli_rename( const char *host, const char *path, const char *newpath, time_t stoptime )
576
RETRY_ATOMIC( result = chirp_client_rename(client,path,newpath,stoptime); )
579
INT64_T chirp_reli_link( const char *host, const char *path, const char *newpath, time_t stoptime )
581
RETRY_ATOMIC( result = chirp_client_link(client,path,newpath,stoptime); )
584
INT64_T chirp_reli_symlink( const char *host, const char *path, const char *newpath, time_t stoptime )
586
RETRY_ATOMIC( result = chirp_client_symlink(client,path,newpath,stoptime); )
589
INT64_T chirp_reli_readlink( const char *host, const char *path, char *buf, INT64_T length, time_t stoptime )
591
RETRY_ATOMIC( result = chirp_client_readlink(client,path,buf,length,stoptime); )
594
INT64_T chirp_reli_mkdir( const char *host, const char *path, INT64_T mode, time_t stoptime )
596
RETRY_ATOMIC( result = chirp_client_mkdir(client,path,mode,stoptime); )
599
INT64_T chirp_reli_mkdir_recursive( const char *host, const char *path, INT64_T mode, time_t stoptime )
601
char mypath[CHIRP_PATH_MAX];
604
char *n = strchr(&mypath[1],'/');
607
/* ignore the result here, because there are many reasons we might not have permission to make or view directories above. */
608
chirp_reli_mkdir(host,mypath,mode,stoptime);
613
/* this is the error that really counts */
614
return chirp_reli_mkdir(host,path,mode,stoptime);
617
INT64_T chirp_reli_rmdir( const char *host, const char *path, time_t stoptime )
619
RETRY_ATOMIC( result = chirp_client_rmdir(client,path,stoptime); )
622
INT64_T chirp_reli_rmall( const char *host, const char *path, time_t stoptime )
624
RETRY_ATOMIC( result = chirp_client_rmall(client,path,stoptime); )
627
INT64_T chirp_reli_stat( const char *host, const char *path, struct chirp_stat *buf, time_t stoptime )
629
RETRY_ATOMIC( result = chirp_client_stat(client,path,buf,stoptime); )
632
INT64_T chirp_reli_lstat( const char *host, const char *path, struct chirp_stat *buf, time_t stoptime )
634
RETRY_ATOMIC( result = chirp_client_lstat(client,path,buf,stoptime); )
637
INT64_T chirp_reli_statfs( const char *host, const char *path, struct chirp_statfs *buf, time_t stoptime )
639
RETRY_ATOMIC( result = chirp_client_statfs(client,path,buf,stoptime); )
642
INT64_T chirp_reli_access( const char *host, const char *path, INT64_T mode, time_t stoptime )
644
RETRY_ATOMIC( result = chirp_client_access(client,path,mode,stoptime); )
647
INT64_T chirp_reli_chmod( const char *host, const char *path, INT64_T mode, time_t stoptime )
649
RETRY_ATOMIC( result = chirp_client_chmod(client,path,mode,stoptime); )
652
INT64_T chirp_reli_chown( const char *host, const char *path, INT64_T uid, INT64_T gid, time_t stoptime )
654
RETRY_ATOMIC( result = chirp_client_chown(client,path,uid,gid,stoptime); )
657
INT64_T chirp_reli_lchown( const char *host, const char *path, INT64_T uid, INT64_T gid, time_t stoptime )
659
RETRY_ATOMIC( result = chirp_client_lchown(client,path,uid,gid,stoptime); )
662
INT64_T chirp_reli_truncate( const char *host, const char *path, INT64_T length, time_t stoptime )
664
RETRY_ATOMIC( result = chirp_client_truncate(client,path,length,stoptime); )
667
INT64_T chirp_reli_utime( const char *host, const char *path, time_t actime, time_t modtime, time_t stoptime )
669
RETRY_ATOMIC( result = chirp_client_utime(client,path,actime,modtime,stoptime); )
672
INT64_T chirp_reli_md5( const char *host, const char *path, unsigned char digest[16], time_t stoptime )
674
RETRY_ATOMIC( result = chirp_client_md5(client,path,digest,stoptime); )
677
INT64_T chirp_reli_localpath( const char *host, const char *path, char *localpath, int length, time_t stoptime )
679
RETRY_ATOMIC( result = chirp_client_localpath(client,path,localpath,length,stoptime); )
682
INT64_T chirp_reli_audit( const char *host, const char *path, struct chirp_audit **list, time_t stoptime )
684
RETRY_ATOMIC( result = chirp_client_audit(client,path,list,stoptime); )
687
INT64_T chirp_reli_thirdput( const char *host, const char *path, const char *thirdhost, const char *thirdpath, time_t stoptime )
689
RETRY_ATOMIC( result = chirp_client_thirdput( client, path, thirdhost, thirdpath, stoptime ); )
692
INT64_T chirp_reli_group_create( const char *host, char *group, time_t stoptime )
694
RETRY_ATOMIC ( result = chirp_client_group_create(client,group,stoptime); )
697
INT64_T chirp_reli_group_list( const char *host, const char *group, chirp_dir_t callback, void *arg, time_t stoptime )
699
RETRY_ATOMIC ( result = chirp_client_group_list(client,group,callback,arg,stoptime); )
702
INT64_T chirp_reli_group_add( const char *host, char *group, char *user, time_t stoptime )
704
RETRY_ATOMIC ( result = chirp_client_group_add(client,group,user,stoptime); )
707
INT64_T chirp_reli_group_remove( const char *host, char *group, char *user, time_t stoptime )
709
RETRY_ATOMIC ( result = chirp_client_group_remove(client,group,user,stoptime); )
712
INT64_T chirp_reli_group_lookup(const char* host, const char* group, const char* user, time_t stoptime)
714
RETRY_ATOMIC( result = chirp_client_group_lookup( client, group, user, stoptime ); )
717
INT64_T chirp_reli_group_policy_set( const char *host, char *group, unsigned long int file_duration, unsigned long int dec_duration, time_t stoptime )
719
RETRY_ATOMIC ( result = chirp_client_group_policy_set(client,group,file_duration,dec_duration,stoptime); )
722
INT64_T chirp_reli_group_cache_update( const char* host, const char* group, time_t mod_time, time_t stoptime )
724
RETRY_ATOMIC( result = chirp_client_group_cache_update( client, group, mod_time, stoptime ); )
727
INT64_T chirp_reli_group_policy_get(const char* host, const char* group, int* policy, int* file_duration, int* dec_duration, time_t stoptime)
729
RETRY_ATOMIC( result = chirp_client_group_policy_get( client, group, policy, file_duration, dec_duration, stoptime ); )
732
INT64_T chirp_reli_mkalloc( const char *host, const char *path, INT64_T size, INT64_T mode, time_t stoptime )
734
RETRY_ATOMIC( result = chirp_client_mkalloc(client,path,size,mode,stoptime); )
737
INT64_T chirp_reli_lsalloc( const char *host, const char *path, char *allocpath, INT64_T *total, INT64_T *inuse, time_t stoptime )
739
RETRY_ATOMIC( result = chirp_client_lsalloc(client,path,allocpath,total,inuse,stoptime); )
742
INT64_T chirp_reli_job_begin( const char *host, const char *cwd, const char *input, const char *output, const char *error, const char *cmdline, time_t stoptime )
744
RETRY_ATOMIC( result = chirp_client_job_begin(client,cwd,input,output,error,cmdline,stoptime); )
747
INT64_T chirp_reli_job_commit( const char *host, INT64_T jobid, time_t stoptime )
749
RETRY_ATOMIC( result = chirp_client_job_commit(client,jobid,stoptime); );
752
INT64_T chirp_reli_job_wait( const char *host, INT64_T jobid, struct chirp_job_state *state, int wait_time, time_t stoptime )
754
RETRY_ATOMIC( result = chirp_client_job_wait(client,jobid,state,wait_time,stoptime); );
757
INT64_T chirp_reli_job_kill( const char *host, INT64_T jobid, time_t stoptime )
759
RETRY_ATOMIC( result = chirp_client_job_kill(client,jobid,stoptime); );
762
INT64_T chirp_reli_job_remove( const char *host, INT64_T jobid, time_t stoptime )
764
RETRY_ATOMIC( result = chirp_client_job_remove(client,jobid,stoptime); );
767
INT64_T chirp_reli_job_list( const char *host, chirp_joblist_t callback, void *arg, time_t stoptime )
769
RETRY_ATOMIC( result = chirp_client_job_list(client,callback,arg,stoptime); );
773
struct chirp_dirent *head;
774
struct chirp_dirent *current;
777
static void opendir_callback( const char *path, struct chirp_stat *info, void *vdir )
779
struct chirp_dir *dir = vdir;
780
struct chirp_dirent *d;
782
d = malloc(sizeof(*d));
783
d->name = strdup(path);
791
dir->current->next = d;
796
struct chirp_dir * chirp_reli_opendir( const char *host, const char *path, time_t stoptime )
798
struct chirp_dir *dir = malloc(sizeof(*dir));
801
dir->head = dir->current = 0;
803
result = chirp_reli_getlongdir(host,path,opendir_callback,dir,stoptime);
805
chirp_reli_closedir(dir);
809
dir->current = dir->head;
814
struct chirp_dirent * chirp_reli_readdir( struct chirp_dir *dir )
816
struct chirp_dirent *d;
821
if(d) dir->current = dir->current->next;
826
void chirp_reli_closedir( struct chirp_dir *dir )
828
struct chirp_dirent *next;
833
next = dir->head->next;
834
free(dir->head->name);
841
static INT64_T chirp_reli_bulkio_once( struct chirp_bulkio *v, int count, time_t stoptime )
846
for(i=0;i<count;i++) {
847
struct chirp_bulkio *b = &v[i];
848
struct chirp_client *client;
850
client = connect_to_host(b->file->host,stoptime);
851
if(!client) goto failure;
853
if(connect_to_file(client,b->file,stoptime)<0) goto failure;
855
if(b->type==CHIRP_BULKIO_PREAD) {
856
result = chirp_client_pread_begin(client,b->file->fd,b->buffer,b->length,b->offset,stoptime);
857
} else if(b->type==CHIRP_BULKIO_PWRITE) {
858
result = chirp_client_pwrite_begin(client,b->file->fd,b->buffer,b->length,b->offset,stoptime);
859
} else if(b->type==CHIRP_BULKIO_SREAD) {
860
result = chirp_client_sread_begin(client,b->file->fd,b->buffer,b->length,b->stride_length,b->stride_skip,b->offset,stoptime);
861
} else if(b->type==CHIRP_BULKIO_SWRITE) {
862
result = chirp_client_swrite_begin(client,b->file->fd,b->buffer,b->length,b->stride_length,b->stride_skip,b->offset,stoptime);
863
} else if(b->type==CHIRP_BULKIO_FSTAT) {
864
result = chirp_client_fstat_begin(client,b->file->fd,b->info,stoptime);
865
} else if(b->type==CHIRP_BULKIO_FSYNC) {
866
result = chirp_client_fsync_begin(client,b->file->fd,stoptime);
872
if(result<0 && errno==ECONNRESET) goto failure;
875
for(i=0;i<count;i++) {
876
struct chirp_bulkio *b = &v[i];
877
struct chirp_client *client;
879
client = connect_to_host(b->file->host,stoptime);
880
if(!client) goto failure;
882
if(b->type==CHIRP_BULKIO_PREAD) {
883
result = chirp_client_pread_finish(client,b->file->fd,b->buffer,b->length,b->offset,stoptime);
884
} else if(b->type==CHIRP_BULKIO_PWRITE) {
885
result = chirp_client_pwrite_finish(client,b->file->fd,b->buffer,b->length,b->offset,stoptime);
886
} else if(b->type==CHIRP_BULKIO_SREAD) {
887
result = chirp_client_sread_finish(client,b->file->fd,b->buffer,b->length,b->stride_length,b->stride_skip,b->offset,stoptime);
888
} else if(b->type==CHIRP_BULKIO_SWRITE) {
889
result = chirp_client_swrite_finish(client,b->file->fd,b->buffer,b->length,b->stride_length,b->stride_skip,b->offset,stoptime);
890
} else if(b->type==CHIRP_BULKIO_FSTAT) {
891
result = chirp_client_fstat_finish(client,b->file->fd,b->info,stoptime);
892
} else if(b->type==CHIRP_BULKIO_FSYNC) {
893
result = chirp_client_fsync_finish(client,b->file->fd,stoptime);
899
if(result<0 && errno==ECONNRESET) goto failure;
908
for(i=0;i<count;i++) {
909
struct chirp_bulkio *b = &v[i];
910
invalidate_host(b->file->host);
916
INT64_T chirp_reli_bulkio( struct chirp_bulkio *v, int count, time_t stoptime )
924
result = chirp_reli_bulkio_once(v,count,stoptime);
926
if(result>=0 || errno!=ECONNRESET) return result;
928
if(time(0)>=stoptime) {
932
if(delay>=2) debug(D_NOTICE,"couldn't connect: still trying...\n");
934
nexttry = MIN(stoptime,current+delay);
935
debug(D_CHIRP,"try again in %d seconds\n",nexttry-current);
936
sleep_until(nexttry);
940
delay = MIN(delay*2,MAX_DELAY);
945
void chirp_reli_cleanup_before_fork()
952
hash_table_firstkey(table);
953
while(hash_table_nextkey(table,&host,(void**)&value)) {
954
invalidate_host(host);