2
Copyright (C) 2008- The University of Notre Dame
3
This software is distributed under the GNU General Public License.
4
See the file COPYING for details.
7
#include "chirp_reli.h"
10
#include "chirp_matrix.h"
13
#include "stringtools.h"
25
#define SEPCHARS " \n"
35
struct chirp_file **rfiles;
36
struct chirp_bulkio *bulkio;
40
struct chirp_matrix * chirp_matrix_create( const char * host, const char *path, int width, int height, int element_size, int nhosts, time_t stoptime)
42
char host_file[CHIRP_LINE_MAX];
48
INT64_T n_row_per_file = height / nfiles;
49
if(height%nfiles) n_row_per_file++;
50
INT64_T file_size = n_row_per_file*width*element_size;
51
if(file_size > GIGABYTE) {
59
char line[CHIRP_LINE_MAX*nfiles];
62
if(getenv("CHIRP_HOSTS")) {
63
sprintf(host_file,"%s",getenv("CHIRP_HOSTS"));
64
file = fopen(host_file,"r");
69
sprintf(host_file,"%s/.chirp/hosts",getenv("HOME"));
70
file = fopen(host_file,"r");
75
sprintf(host_file,"./chirp_hosts");
76
file = fopen(host_file,"r");
79
file = fopen(host_file,"w");
80
char hostname[CHIRP_LINE_MAX];
81
gethostname(hostname,CHIRP_LINE_MAX-1); // get hostname, this may not have domain name, though!
82
fprintf(file,"%s\n",hostname);
84
file = fopen(host_file,"r");
90
debug(D_NOTICE|D_CHIRP,"matrix: could not open host list in %s: %s\n",host_file,strerror(errno));
95
hosts = malloc(sizeof(*hosts)*nhosts);
97
for(i=0;i<nhosts;i++) {
98
if(!fgets(line,sizeof(line),file)) {
100
fgets(line,sizeof(line),file);
102
hosts[i] = strdup(line);
103
int len = strlen(hosts[i]);
104
hosts[i][len-1] = '\0';
109
sprintf(line,"%d\n%d\n%d\n%d\n%d\n",width,height,element_size,nhosts,nfiles);
111
char datapath1[CHIRP_LINE_MAX];
112
char datapath2[CHIRP_LINE_MAX];
113
char datapath3[CHIRP_LINE_MAX];
114
char username[USERNAME_MAX];
118
username_get(username);
119
string_cookie(cookie,sizeof(cookie));
121
sprintf(datapath1,"/%s",username);
122
sprintf(datapath2,"/%s/matrixdata",username);
123
sprintf(datapath3,"/%s/matrixdata/%s",username,cookie);
125
for(i=0;i<nfiles;i++)
127
const char *datahost = hosts[i%nhosts];
128
result = chirp_reli_mkdir(datahost,datapath1,0700,stoptime);
129
result = chirp_reli_mkdir(datahost,datapath2,0700,stoptime);
130
result = chirp_reli_mkdir(datahost,datapath3,0700,stoptime);
132
sprintf(&line[strlen(line)],"%s %s/data.%d\n",datahost,datapath3,i);
135
for(i=0;i<nhosts;i++) {
140
char metapath[CHIRP_LINE_MAX];
141
strcpy(metapath,path);
142
result = chirp_reli_putfile_buffer(host,path,line,0700,strlen(line),stoptime);
144
for(i = 1; i < strlen(metapath); i++)
145
if(metapath[i] == '/') {
147
result = chirp_reli_mkdir(host,metapath,0700,stoptime);
148
if(result < 0 && errno != EEXIST) {
149
debug(D_CHIRP,"matrix: could not build directory /chirp/%s/%s to create metadata file: %s\n",host,metapath,strerror(errno));
154
result = chirp_reli_putfile_buffer(host,path,line,0700,strlen(line),stoptime);
156
debug(D_CHIRP,"matrix: could not create metadata file /chirp/%s/%s: %s\n",host,path,strerror(errno));
160
debug(D_CHIRP,"matrix: created matrix %s/%s -- now opening\n",host,path);
161
return chirp_matrix_open(host,path,stoptime);
164
struct chirp_matrix * chirp_matrix_open( const char * host, const char *path, time_t stoptime )
170
struct chirp_matrix *matrix;
172
matrix = xxmalloc(sizeof(*matrix));
174
result = chirp_reli_getfile_buffer(host,path,&line,stoptime);
176
debug(D_CHIRP,"matrix: could not create metadata file /chirp/%s/%s: %s\n",host,path,strerror(errno));
179
tmp = strtok(line,SEPCHARS);
180
matrix->width = atoi(tmp);
181
tmp = strtok(NULL,SEPCHARS);
182
matrix->height = atoi(tmp);
183
tmp = strtok(NULL,SEPCHARS);
184
matrix->element_size = atoi(tmp);
185
tmp = strtok(NULL,SEPCHARS);
186
matrix->nhosts = atoi(tmp);
187
tmp = strtok(NULL,SEPCHARS);
188
matrix->nfiles = atoi(tmp);
190
matrix->n_row_per_file = matrix->height / matrix->nfiles;
191
if(matrix->height%matrix->nfiles) matrix->n_row_per_file++;
193
matrix->rfiles = malloc(sizeof(struct chirp_file*)*matrix->nfiles);
194
matrix->bulkio = malloc(sizeof(struct chirp_bulkio)*matrix->nfiles);
196
for(i = 0;i<matrix->nfiles;i++)
198
char *host = strtok(NULL,SEPCHARS);
199
char *path = strtok(NULL,SEPCHARS);
200
matrix->rfiles[i] = chirp_reli_open(host,path,O_RDWR|O_CREAT,0755,stoptime);
201
if(!matrix->rfiles[i]) {
203
for(j=0;j<i;j++) chirp_reli_close(matrix->rfiles[i],stoptime);
216
int chirp_matrix_width( struct chirp_matrix *a )
221
int chirp_matrix_height( struct chirp_matrix *a )
226
int chirp_matrix_element_size( struct chirp_matrix *a )
228
return a->element_size;
231
int chirp_matrix_nhosts( struct chirp_matrix *a )
236
int chirp_matrix_nfiles( struct chirp_matrix *a )
241
int chirp_matrix_get(struct chirp_matrix *a, int i, int j, void *data, time_t stoptime )
243
int index = i/a->n_row_per_file;
244
INT64_T offset= ((i%a->n_row_per_file)*a->width + j)*a->element_size;
245
return chirp_reli_pread_unbuffered(a->rfiles[index],data,a->element_size,offset,stoptime);
248
int chirp_matrix_get_row( struct chirp_matrix *a, int j, void *data, time_t stoptime )
250
int index = j/a->n_row_per_file;
251
INT64_T offset= (j%a->n_row_per_file)*a->width*a->element_size;
252
return chirp_reli_pread_unbuffered(a->rfiles[index],data,a->element_size*a->width,offset,stoptime);
255
int chirp_matrix_set( struct chirp_matrix *a, int i, int j, const void *data, time_t stoptime )
257
int index = i/a->n_row_per_file;
258
INT64_T offset= ((i%a->n_row_per_file)*a->width + j)*a->element_size;
259
return chirp_reli_pwrite_unbuffered(a->rfiles[index],data,sizeof(data),offset,stoptime);
262
int chirp_matrix_set_row( struct chirp_matrix *a, int j, const void *data , time_t stoptime)
264
int index = j/a->n_row_per_file;
265
INT64_T offset= (j%a->n_row_per_file)*a->width*a->element_size;
266
return chirp_reli_pwrite_unbuffered(a->rfiles[index],data,a->element_size*a->width,offset,stoptime);
269
int chirp_matrix_set_range( struct chirp_matrix *a, int x, int y, int width, int height, const void *data, time_t stoptime)
271
if(x<0 || y<0 || width<1 || height<1 || (x+width)>a->width || (y+height)>a->height) {
277
const char *cdata = data;
279
for(j=0;j<height;j++) {
280
int index = (y+j)/a->n_row_per_file;
281
INT64_T file_offset = (x+((y+j)%a->n_row_per_file)*a->width)*a->element_size;
282
INT64_T buffer_offset = (j*width)*a->element_size;
283
INT64_T length = width*a->element_size;
284
INT64_T result = chirp_reli_pwrite_unbuffered(a->rfiles[index],&cdata[buffer_offset],length,file_offset,stoptime);
285
if(result!=length) return -1;
288
return j*width*a->element_size;
291
int chirp_matrix_get_range( struct chirp_matrix *a, int x, int y, int width, int height, void *data, time_t stoptime)
293
if(x<0 || y<0 || width<1 || height<1 || (x+width)>a->width || (y+height)>a->height) {
301
for(j=0;j<height;j++) {
302
int index = (y+j)/a->n_row_per_file;
303
INT64_T file_offset = (x+((y+j)%a->n_row_per_file)*a->width)*a->element_size;
304
INT64_T buffer_offset = (j*width)*a->element_size;
305
INT64_T length = width*a->element_size;
306
INT64_T result = chirp_reli_pread_unbuffered(a->rfiles[index],&cdata[buffer_offset],length,file_offset,stoptime);
307
if(result!=length) return -1;
310
return j*width*a->element_size;
313
int chirp_matrix_get_col( struct chirp_matrix *a, int i, void *data, time_t stoptime )
315
INT64_T offset= i*a->element_size;
316
int length = a->element_size*a->n_row_per_file;
319
for(j=0;j<a->nfiles;j++) {
320
struct chirp_bulkio *b = &a->bulkio[j];
321
b->type = CHIRP_BULKIO_SREAD;
322
b->file = a->rfiles[j];
323
b->buffer = data+j*length;
324
b->length = a->n_row_per_file*a->element_size;
325
b->stride_length = a->element_size;
326
b->stride_skip = a->element_size*a->width;
330
return chirp_reli_bulkio(a->bulkio,a->nfiles,stoptime);
334
int chirp_matrix_set_col( struct chirp_matrix *a, int i,const void *data, time_t stoptime )
336
INT64_T offset= i*a->element_size;
337
int length = a->element_size*a->n_row_per_file;
340
for(j=0;j<a->nfiles;j++) {
341
struct chirp_bulkio *b = &a->bulkio[j];
342
b->type = CHIRP_BULKIO_SWRITE;
343
b->file = a->rfiles[j];
344
b->buffer = (char*)(data+j*length);
345
b->length = a->n_row_per_file*a->element_size;
346
b->stride_length = a->element_size;
347
b->stride_skip = a->element_size*a->width;
351
return chirp_reli_bulkio(a->bulkio,a->nfiles,stoptime);
354
int chirp_matrix_setacl( const char *host, const char *path, const char *subject, const char *rights, time_t stoptime)
360
struct chirp_matrix *matrix;
362
matrix = xxmalloc(sizeof(*matrix));
364
result = chirp_reli_getfile_buffer(host,path,&line,stoptime);
365
if(result<0)return 0;
366
tmp = strtok(line,SEPCHARS);
367
matrix->width = atoi(tmp);
368
tmp = strtok(NULL,SEPCHARS);
369
matrix->height = atoi(tmp);
370
tmp = strtok(NULL,SEPCHARS);
371
matrix->element_size = atoi(tmp);
372
tmp = strtok(NULL,SEPCHARS);
373
matrix->nhosts = atoi(tmp);
374
tmp = strtok(NULL,SEPCHARS);
375
matrix->nfiles = atoi(tmp);
377
matrix->n_row_per_file = matrix->height / matrix->nfiles;
378
if(matrix->height%matrix->nfiles) matrix->n_row_per_file++;
380
char* matpathdir = xxmalloc((strlen(path)+1)*sizeof(char));
381
strcpy(matpathdir,path);
382
for(j = 1; j < strlen(matpathdir); j++)
383
if(matpathdir[j] == '/') {
384
matpathdir[j] = '\0';
385
result = chirp_reli_setacl(host,matpathdir,subject,rights,stoptime);
387
debug(D_CHIRP,"matrix: setting acl for /chirp/%s/%s failed: %s\n",host,matpathdir,strerror(errno));
395
for(i = 0;i<matrix->nfiles;i++)
397
char *fhost = strtok(NULL,SEPCHARS);
398
char *fpath = strtok(NULL,SEPCHARS);
399
matpathdir = xxmalloc((strlen(fpath)+1)*sizeof(char));
400
strcpy(matpathdir,fpath);
401
for(j = 1; j < strlen(matpathdir); j++)
402
if(matpathdir[j] == '/') {
403
matpathdir[j] = '\0';
404
result = chirp_reli_setacl(fhost,matpathdir,subject,rights,stoptime);
406
debug(D_CHIRP,"matrix: setting acl for /chirp/%s/%s failed: %s\n",fhost,matpathdir,strerror(errno));
418
void chirp_matrix_fsync( struct chirp_matrix *a, time_t stoptime )
421
for(i=0;i<a->nfiles;i++) {
422
struct chirp_bulkio *b = &a->bulkio[i];
423
b->type = CHIRP_BULKIO_FSYNC;
424
b->file = a->rfiles[i];
426
chirp_reli_bulkio(a->bulkio,a->nfiles,stoptime);
429
void chirp_matrix_close( struct chirp_matrix *a, time_t stoptime)
432
for(i=0;i<a->nfiles;i++) chirp_reli_close(a->rfiles[i],stoptime);
438
int chirp_matrix_delete( const char *host, const char *path, time_t stoptime )
447
result = chirp_reli_getfile_buffer(host,path,&line,stoptime);
448
if(result<0) return -1;
450
tmp = strtok(line,SEPCHARS);
451
tmp = strtok(NULL,SEPCHARS);
452
tmp = strtok(NULL,SEPCHARS);
453
tmp = strtok(NULL,SEPCHARS);
454
tmp = strtok(NULL,SEPCHARS);
458
for(i = 0;i<nfiles;i++)
460
char *dhost = strtok(NULL,SEPCHARS);
461
char *dpath = strtok(NULL,SEPCHARS);
462
char *s = strrchr(dpath,'/');
464
chirp_reli_rmall(dhost,dpath,stoptime);
467
return chirp_reli_unlink(host,path,stoptime);