~ubuntu-branches/ubuntu/vivid/cctools/vivid

« back to all changes in this revision

Viewing changes to chirp/src/chirp_matrix.c

  • Committer: Bazaar Package Importer
  • Author(s): Michael Hanke
  • Date: 2011-05-07 09:05:00 UTC
  • Revision ID: james.westby@ubuntu.com-20110507090500-lqpmdtwndor6e7os
Tags: upstream-3.3.2
ImportĀ upstreamĀ versionĀ 3.3.2

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/*
 
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.
 
5
*/
 
6
 
 
7
#include "chirp_reli.h"
 
8
#include "auth_all.h"
 
9
#include "debug.h"
 
10
#include "chirp_matrix.h"
 
11
#include "xmalloc.h"
 
12
#include "username.h"
 
13
#include "stringtools.h"
 
14
#include "macros.h"
 
15
 
 
16
#include <time.h>
 
17
#include <stdio.h>
 
18
#include <time.h>
 
19
#include <string.h>
 
20
#include <errno.h>
 
21
#include <stdlib.h>
 
22
#include <sys/time.h>
 
23
#include <sys/wait.h>
 
24
 
 
25
#define SEPCHARS " \n"
 
26
#define SEPCHARS2 "/"
 
27
 
 
28
struct chirp_matrix {
 
29
        int width;
 
30
        int height;
 
31
        int element_size;
 
32
        int nhosts;
 
33
        int nfiles;
 
34
        int n_row_per_file;
 
35
        struct chirp_file **rfiles;
 
36
        struct chirp_bulkio *bulkio;
 
37
};
 
38
 
 
39
 
 
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)
 
41
{
 
42
        char host_file[CHIRP_LINE_MAX];
 
43
        int result,i;
 
44
        char **hosts;
 
45
 
 
46
        int nfiles = nhosts;
 
47
        while(1) {
 
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) {
 
52
                        nfiles *=2;
 
53
                        continue;
 
54
                } else {
 
55
                        break;
 
56
                }
 
57
        }
 
58
 
 
59
        char line[CHIRP_LINE_MAX*nfiles];
 
60
 
 
61
        FILE * file = NULL;
 
62
        if(getenv("CHIRP_HOSTS")) {
 
63
                sprintf(host_file,"%s",getenv("CHIRP_HOSTS"));
 
64
                file = fopen(host_file,"r");
 
65
        }
 
66
 
 
67
        if(!file) {
 
68
            if(getenv("HOME")) {
 
69
                sprintf(host_file,"%s/.chirp/hosts",getenv("HOME"));
 
70
                file = fopen(host_file,"r");
 
71
            }
 
72
        }
 
73
 
 
74
        if(!file) {
 
75
            sprintf(host_file,"./chirp_hosts");
 
76
            file = fopen(host_file,"r");
 
77
            if(!file)
 
78
            {
 
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);
 
83
                fclose(file);
 
84
                file = fopen(host_file,"r");
 
85
            }
 
86
        }
 
87
 
 
88
 
 
89
        if(!file) {
 
90
                debug(D_NOTICE|D_CHIRP,"matrix: could not open host list in %s: %s\n",host_file,strerror(errno));
 
91
                errno = EINVAL;
 
92
                return 0;
 
93
        }
 
94
 
 
95
        hosts = malloc(sizeof(*hosts)*nhosts);
 
96
 
 
97
        for(i=0;i<nhosts;i++) {
 
98
                if(!fgets(line,sizeof(line),file)) {
 
99
                        rewind(file);
 
100
                        fgets(line,sizeof(line),file);
 
101
                }
 
102
                hosts[i] = strdup(line);
 
103
                int len = strlen(hosts[i]);
 
104
                hosts[i][len-1] = '\0';
 
105
        }
 
106
 
 
107
        fclose(file);
 
108
 
 
109
        sprintf(line,"%d\n%d\n%d\n%d\n%d\n",width,height,element_size,nhosts,nfiles);
 
110
 
 
111
        char datapath1[CHIRP_LINE_MAX];
 
112
        char datapath2[CHIRP_LINE_MAX];
 
113
        char datapath3[CHIRP_LINE_MAX];
 
114
        char username[USERNAME_MAX];
 
115
 
 
116
        char cookie[16];
 
117
 
 
118
        username_get(username);
 
119
        string_cookie(cookie,sizeof(cookie));
 
120
 
 
121
        sprintf(datapath1,"/%s",username);
 
122
        sprintf(datapath2,"/%s/matrixdata",username);
 
123
        sprintf(datapath3,"/%s/matrixdata/%s",username,cookie);
 
124
        
 
125
        for(i=0;i<nfiles;i++)
 
126
        {
 
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);
 
131
                
 
132
                sprintf(&line[strlen(line)],"%s %s/data.%d\n",datahost,datapath3,i);
 
133
        }
 
134
 
 
135
        for(i=0;i<nhosts;i++) {
 
136
            free(hosts[i]);
 
137
        }
 
138
        free(hosts);
 
139
 
 
140
        char metapath[CHIRP_LINE_MAX];
 
141
        strcpy(metapath,path);
 
142
        result = chirp_reli_putfile_buffer(host,path,line,0700,strlen(line),stoptime);
 
143
        if(result<0) {
 
144
            for(i = 1; i < strlen(metapath); i++)
 
145
                if(metapath[i] == '/') {
 
146
                    metapath[i] = '\0';
 
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));
 
150
                        return 0;
 
151
                    }
 
152
                    metapath[i] = '/';
 
153
                }
 
154
            result = chirp_reli_putfile_buffer(host,path,line,0700,strlen(line),stoptime);
 
155
            if(result<0) {
 
156
                debug(D_CHIRP,"matrix: could not create metadata file /chirp/%s/%s: %s\n",host,path,strerror(errno));
 
157
                return 0;
 
158
            }
 
159
        }
 
160
        debug(D_CHIRP,"matrix: created matrix %s/%s -- now opening\n",host,path);
 
161
        return chirp_matrix_open(host,path,stoptime);
 
162
}
 
163
 
 
164
struct chirp_matrix * chirp_matrix_open( const char * host, const char *path, time_t stoptime )
 
165
{
 
166
 
 
167
        int result,i;
 
168
        char* line;
 
169
        char* tmp;
 
170
        struct chirp_matrix *matrix;
 
171
 
 
172
        matrix = xxmalloc(sizeof(*matrix));
 
173
 
 
174
        result = chirp_reli_getfile_buffer(host,path,&line,stoptime);
 
175
        if(result<0) {
 
176
            debug(D_CHIRP,"matrix: could not create metadata file /chirp/%s/%s: %s\n",host,path,strerror(errno));
 
177
            return 0;
 
178
        }
 
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);
 
189
 
 
190
        matrix->n_row_per_file = matrix->height / matrix->nfiles;
 
191
        if(matrix->height%matrix->nfiles) matrix->n_row_per_file++;
 
192
 
 
193
        matrix->rfiles = malloc(sizeof(struct chirp_file*)*matrix->nfiles);
 
194
        matrix->bulkio = malloc(sizeof(struct chirp_bulkio)*matrix->nfiles);
 
195
 
 
196
        for(i = 0;i<matrix->nfiles;i++)
 
197
        {
 
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]) {
 
202
                        int j;
 
203
                        for(j=0;j<i;j++) chirp_reli_close(matrix->rfiles[i],stoptime);
 
204
                        free(line);
 
205
                        return 0;
 
206
                }
 
207
        }
 
208
 
 
209
        free(line);
 
210
 
 
211
 
 
212
        return matrix;
 
213
}
 
214
 
 
215
 
 
216
int chirp_matrix_width( struct chirp_matrix *a )
 
217
{
 
218
        return a->width;
 
219
}
 
220
 
 
221
int chirp_matrix_height( struct chirp_matrix *a )
 
222
{
 
223
        return a->height;
 
224
}
 
225
 
 
226
int chirp_matrix_element_size( struct chirp_matrix *a )
 
227
{
 
228
        return a->element_size;
 
229
}
 
230
 
 
231
int chirp_matrix_nhosts( struct chirp_matrix *a )
 
232
{
 
233
        return a->nhosts;
 
234
}
 
235
 
 
236
int chirp_matrix_nfiles( struct chirp_matrix *a )
 
237
{
 
238
        return a->nfiles;
 
239
}
 
240
 
 
241
int  chirp_matrix_get(struct chirp_matrix *a, int i, int j, void *data, time_t stoptime )
 
242
{
 
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);
 
246
}
 
247
 
 
248
int  chirp_matrix_get_row( struct chirp_matrix *a, int j, void *data, time_t stoptime )
 
249
{
 
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);
 
253
}
 
254
 
 
255
int  chirp_matrix_set( struct chirp_matrix *a, int i, int j, const void *data, time_t stoptime )
 
256
{
 
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);
 
260
}
 
261
 
 
262
int  chirp_matrix_set_row( struct chirp_matrix *a, int j, const void *data , time_t stoptime)
 
263
{
 
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);
 
267
}
 
268
 
 
269
int  chirp_matrix_set_range( struct chirp_matrix *a, int x, int y, int width, int height, const void *data, time_t stoptime)
 
270
{
 
271
        if(x<0 || y<0 || width<1 || height<1 || (x+width)>a->width || (y+height)>a->height) {
 
272
                errno = EINVAL;
 
273
                return -1;
 
274
        }
 
275
 
 
276
        int j = 0;
 
277
        const char *cdata = data;
 
278
 
 
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;
 
286
        }
 
287
 
 
288
        return j*width*a->element_size;
 
289
}
 
290
 
 
291
int  chirp_matrix_get_range( struct chirp_matrix *a, int x, int y, int width, int height, void *data, time_t stoptime)
 
292
{
 
293
        if(x<0 || y<0 || width<1 || height<1 || (x+width)>a->width || (y+height)>a->height) {
 
294
                errno = EINVAL;
 
295
                return -1;
 
296
        }
 
297
 
 
298
        int j = 0;
 
299
        char *cdata = data;
 
300
 
 
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;
 
308
        }
 
309
 
 
310
        return j*width*a->element_size;
 
311
}
 
312
 
 
313
int  chirp_matrix_get_col( struct chirp_matrix *a, int i, void *data, time_t stoptime )
 
314
{
 
315
        INT64_T offset= i*a->element_size;
 
316
        int length = a->element_size*a->n_row_per_file;
 
317
        int j;
 
318
 
 
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;
 
327
                b->offset = offset;
 
328
        }
 
329
 
 
330
        return chirp_reli_bulkio(a->bulkio,a->nfiles,stoptime);
 
331
}
 
332
 
 
333
 
 
334
int chirp_matrix_set_col( struct chirp_matrix *a, int i,const void *data, time_t stoptime )
 
335
{
 
336
        INT64_T offset= i*a->element_size;
 
337
        int length = a->element_size*a->n_row_per_file;
 
338
        int j;
 
339
 
 
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;
 
348
                b->offset = offset;
 
349
        }
 
350
 
 
351
        return chirp_reli_bulkio(a->bulkio,a->nfiles,stoptime);
 
352
}
 
353
 
 
354
int chirp_matrix_setacl( const char *host, const char *path,  const char *subject, const char *rights, time_t stoptime)
 
355
{
 
356
 
 
357
        int result,i,j;
 
358
        char* line;
 
359
        char* tmp;
 
360
        struct chirp_matrix *matrix;
 
361
 
 
362
        matrix = xxmalloc(sizeof(*matrix));
 
363
 
 
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);
 
376
 
 
377
        matrix->n_row_per_file = matrix->height / matrix->nfiles;
 
378
        if(matrix->height%matrix->nfiles) matrix->n_row_per_file++;
 
379
 
 
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);
 
386
                if(result < 0) {
 
387
                    debug(D_CHIRP,"matrix: setting acl for /chirp/%s/%s failed: %s\n",host,matpathdir,strerror(errno));
 
388
                    return result;
 
389
                }
 
390
                matpathdir[j] = '/';
 
391
            }
 
392
        free(matpathdir);
 
393
        matpathdir=NULL;
 
394
        
 
395
        for(i = 0;i<matrix->nfiles;i++)
 
396
        {
 
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);
 
405
                        if(result < 0) {
 
406
                            debug(D_CHIRP,"matrix: setting acl for /chirp/%s/%s failed: %s\n",fhost,matpathdir,strerror(errno));
 
407
                            return result;
 
408
                        }
 
409
                        matpathdir[j] = '/';
 
410
                    }
 
411
                free(matpathdir);
 
412
                matpathdir=NULL;
 
413
        }
 
414
 
 
415
        return 0;
 
416
}
 
417
 
 
418
void chirp_matrix_fsync( struct chirp_matrix *a, time_t stoptime )
 
419
{
 
420
        int i;
 
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];
 
425
        }
 
426
        chirp_reli_bulkio(a->bulkio,a->nfiles,stoptime);
 
427
}
 
428
 
 
429
void chirp_matrix_close( struct chirp_matrix *a, time_t stoptime)
 
430
{
 
431
        int i;
 
432
        for(i=0;i<a->nfiles;i++) chirp_reli_close(a->rfiles[i],stoptime);
 
433
        free(a->bulkio);
 
434
        free(a->rfiles);
 
435
        free(a);
 
436
}
 
437
 
 
438
int chirp_matrix_delete( const char *host, const char *path, time_t stoptime )
 
439
{
 
440
 
 
441
        char *tmp;
 
442
        int nfiles;
 
443
        int i;
 
444
        int result;
 
445
        char *line;
 
446
 
 
447
        result = chirp_reli_getfile_buffer(host,path,&line,stoptime);
 
448
        if(result<0) return -1;
 
449
 
 
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);
 
455
 
 
456
        nfiles = atoi(tmp);
 
457
 
 
458
        for(i = 0;i<nfiles;i++)
 
459
        {
 
460
                char *dhost = strtok(NULL,SEPCHARS);
 
461
                char *dpath = strtok(NULL,SEPCHARS);
 
462
                char *s = strrchr(dpath,'/');
 
463
                if(s) *s = 0;
 
464
                chirp_reli_rmall(dhost,dpath,stoptime);
 
465
        }
 
466
 
 
467
        return chirp_reli_unlink(host,path,stoptime);
 
468
}