int chirp_matrix_delete(const char *host, const char *path, time_t stoptime) { char *tmp; int nfiles; int i; int result; char *line; result = chirp_reli_getfile_buffer(host, path, &line, stoptime); if(result < 0) return -1; tmp = strtok(line, SEPCHARS); tmp = strtok(NULL, SEPCHARS); tmp = strtok(NULL, SEPCHARS); tmp = strtok(NULL, SEPCHARS); tmp = strtok(NULL, SEPCHARS); nfiles = atoi(tmp); for(i = 0; i < nfiles; i++) { char *dhost = strtok(NULL, SEPCHARS); char *dpath = strtok(NULL, SEPCHARS); char *s = strrchr(dpath, '/'); if(s) *s = 0; chirp_reli_rmall(dhost, dpath, stoptime); } return chirp_reli_unlink(host, path, stoptime); }
INT64_T chirp_multi_getfile_buffer(const char *volume, const char *path, char **buffer, time_t stoptime) { struct file_info info; if(!chirp_multi_lookup(volume, path, &info, stoptime)) return -1; return chirp_reli_getfile_buffer(info.rhost, info.rpath, buffer, stoptime); }
static int chirp_multi_lookup(const char *volume, const char *path, struct file_info *info, time_t stoptime) { int result, fields; char *buffer; if(!chirp_multi_lpath(volume, path, info->lpath, stoptime)) return 0; result = chirp_reli_getfile_buffer(current_volume->host, info->lpath, &buffer, stoptime); if(result <= 0) return 0; fields = sscanf(buffer, "%s %s", info->rhost, info->rpath); free(buffer); debug(D_MULTI, "lookup: /multi/%s%s at /chirp/%s/%s", volume, path, info->rhost, info->rpath); if(fields == 2) { return 1; } else { errno = EIO; return 0; } }
struct chirp_matrix *chirp_matrix_open(const char *host, const char *path, time_t stoptime) { int result, i; char *line; char *tmp; struct chirp_matrix *matrix; matrix = xxmalloc(sizeof(*matrix)); result = chirp_reli_getfile_buffer(host, path, &line, stoptime); if(result < 0) { debug(D_CHIRP, "matrix: could not create metadata file /chirp/%s/%s: %s\n", host, path, strerror(errno)); return 0; } tmp = strtok(line, SEPCHARS); matrix->width = atoi(tmp); tmp = strtok(NULL, SEPCHARS); matrix->height = atoi(tmp); tmp = strtok(NULL, SEPCHARS); matrix->element_size = atoi(tmp); tmp = strtok(NULL, SEPCHARS); matrix->nhosts = atoi(tmp); tmp = strtok(NULL, SEPCHARS); matrix->nfiles = atoi(tmp); matrix->n_row_per_file = matrix->height / matrix->nfiles; if(matrix->height % matrix->nfiles) matrix->n_row_per_file++; matrix->rfiles = malloc(sizeof(struct chirp_file *) * matrix->nfiles); matrix->bulkio = malloc(sizeof(struct chirp_bulkio) * matrix->nfiles); for(i = 0; i < matrix->nfiles; i++) { char *host = strtok(NULL, SEPCHARS); char *path = strtok(NULL, SEPCHARS); matrix->rfiles[i] = chirp_reli_open(host, path, O_RDWR | O_CREAT, 0755, stoptime); if(!matrix->rfiles[i]) { int j; for(j = 0; j < i; j++) chirp_reli_close(matrix->rfiles[i], stoptime); free(line); return 0; } } free(line); return matrix; }
INT64_T chirp_global_getfile_buffer(const char *host, const char *path, char **buffer, time_t stoptime) { if(is_multi_path(host)) { char mhost[CHIRP_PATH_MAX]; char mpath[CHIRP_PATH_MAX]; parse_multi_path(path, mhost, mpath); return chirp_multi_getfile_buffer(mhost, mpath, buffer, stoptime); } else if(not_empty(path)) { return chirp_reli_getfile_buffer(host, path, buffer, stoptime); } else if(not_empty(host)) { if(server_lookup(host, stoptime)) { errno = EISDIR; return -1; } else { errno = EACCES; return -1; } } else { errno = EACCES; return -1; } }
int chirp_matrix_setacl(const char *host, const char *path, const char *subject, const char *rights, time_t stoptime) { int result, i, j; char *line; char *tmp; struct chirp_matrix *matrix; matrix = xxmalloc(sizeof(*matrix)); result = chirp_reli_getfile_buffer(host, path, &line, stoptime); if(result < 0) return 0; tmp = strtok(line, SEPCHARS); matrix->width = atoi(tmp); tmp = strtok(NULL, SEPCHARS); matrix->height = atoi(tmp); tmp = strtok(NULL, SEPCHARS); matrix->element_size = atoi(tmp); tmp = strtok(NULL, SEPCHARS); matrix->nhosts = atoi(tmp); tmp = strtok(NULL, SEPCHARS); matrix->nfiles = atoi(tmp); matrix->n_row_per_file = matrix->height / matrix->nfiles; if(matrix->height % matrix->nfiles) matrix->n_row_per_file++; char *matpathdir = xxmalloc((strlen(path) + 1) * sizeof(char)); strcpy(matpathdir, path); for(j = 1; j < (int) strlen(matpathdir); j++) if(matpathdir[j] == '/') { matpathdir[j] = '\0'; result = chirp_reli_setacl(host, matpathdir, subject, rights, stoptime); if(result < 0) { debug(D_CHIRP, "matrix: setting acl for /chirp/%s/%s failed: %s\n", host, matpathdir, strerror(errno)); return result; } matpathdir[j] = '/'; } free(matpathdir); matpathdir = NULL; for(i = 0; i < matrix->nfiles; i++) { char *fhost = strtok(NULL, SEPCHARS); char *fpath = strtok(NULL, SEPCHARS); matpathdir = xxmalloc((strlen(fpath) + 1) * sizeof(char)); strcpy(matpathdir, fpath); for(j = 1; j < (int) strlen(matpathdir); j++) if(matpathdir[j] == '/') { matpathdir[j] = '\0'; result = chirp_reli_setacl(fhost, matpathdir, subject, rights, stoptime); if(result < 0) { debug(D_CHIRP, "matrix: setting acl for /chirp/%s/%s failed: %s\n", fhost, matpathdir, strerror(errno)); return result; } matpathdir[j] = '/'; } free(matpathdir); matpathdir = NULL; } return 0; }
struct chirp_volume *chirp_volume_open(const char *volume, time_t stoptime) { struct chirp_volume *v; char filename[CHIRP_PATH_MAX]; char *buffer; char *name; char *c; int result; debug(D_MULTI, "opening volume %s", volume); /* The volume name must have at least one at-sign in order to indicate the volname. */ c = strchr(volume, '@'); if(!c) { errno = ENOENT; return 0; } v = xxmalloc(sizeof(*v)); strcpy(v->name, volume); /* The stuff preceding the first at-sign is the name of the host containing the directory. */ strcpy(v->host, v->name); c = strchr(v->host, '@'); /* The rest is the logical name of the volume. */ strcpy(v->root, c); *c = 0; /* Convert any remaning at-signs to slashes */ for(c = v->root; *c; c++) { if(*c == '@') *c = '/'; } /* Fetch the filesystem key */ sprintf(filename, "%s/key", v->root); result = chirp_reli_getfile_buffer(v->host, filename, &buffer, stoptime); if(result < 0) { debug(D_CHIRP, "couldn't open %s: %s", filename, strerror(errno)); free(v); errno = ENOENT; return 0; } strcpy(v->key, buffer); string_chomp(v->key); free(buffer); /* Fetch the list of hosts */ sprintf(filename, "%s/hosts", v->root); result = chirp_reli_getfile_buffer(v->host, filename, &buffer, stoptime); if(result < 0) { debug(D_CHIRP, "couldn't open %s: %s", filename, strerror(errno)); free(v); errno = ENOENT; return 0; } /* Get an upper bound on the servers by counting the whitespace */ int maxservers = 0; for(c = buffer; *c; c++) if(isspace((int) *c)) maxservers++; /* Allocate space for an array of servers */ v->servers = malloc(sizeof(struct chirp_server *) * maxservers); v->nservers = 0; debug(D_MULTI, "estimating %d servers", maxservers); /* Break into whitespace and initialize the servers. */ name = strtok(buffer, " \t\n"); while(name) { debug(D_MULTI, "server: %s", name); struct chirp_server *s = xxmalloc(sizeof(*s)); strcpy(s->name, name); s->priority = 0; s->prepared = 0; v->servers[v->nservers++] = s; name = strtok(0, " \t\n"); } /* randomly initialize the priority of the servers */ int i; int n = rand() % v->nservers; for(i = 0; i < n; i++) v->servers[i]->priority++; free(buffer); return v; }