/* Create a set of architectures that the program is registered for */ static char * program_arch_set(char *program, struct gfarm_hash_table **arch_setp) { char *e, *gfarm_file; struct gfarm_path_info pi; struct gfarm_file_section_info *sections; struct gfarm_hash_table *arch_set; int i, nsections, created; e = gfarm_url_make_path(program, &gfarm_file); if (e != NULL) return (e); e = gfarm_path_info_get(gfarm_file, &pi); if (e != NULL) { if (e == GFARM_ERR_NO_SUCH_OBJECT) e = "such program isn't registered"; free(gfarm_file); return (e); } if (!GFARM_S_IS_PROGRAM(pi.status.st_mode)) { gfarm_path_info_free(&pi); free(gfarm_file); return ("specified command is not an executable"); } e = gfarm_file_section_info_get_all_by_file(gfarm_file, &nsections, §ions); gfarm_path_info_free(&pi); free(gfarm_file); if (e != NULL) return ("no binary is registered as the specified command"); arch_set = gfarm_hash_table_alloc(ARCH_SET_HASHTAB_SIZE, gfarm_hash_default, gfarm_hash_key_equal_default); if (arch_set == NULL) { gfarm_file_section_info_free_all(nsections, sections); return (GFARM_ERR_NO_MEMORY); } /* register architectures of the program to `arch_set' */ for (i = 0; i < nsections; i++) { if (gfarm_hash_enter(arch_set, sections[i].section, strlen(sections[i].section) + 1, sizeof(int), &created) == NULL) { free_arch_set(arch_set); gfarm_file_section_info_free_all(nsections, sections); return (GFARM_ERR_NO_MEMORY); } } gfarm_file_section_info_free_all(nsections, sections); *arch_setp = arch_set; return (NULL); }
static char * display_replica_catalog(char *gfarm_url) { char *gfarm_file, *e, *e_save = NULL; int i, j, nsections; struct gfarm_file_section_info *sections; struct gfs_stat st; e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) { fprintf(stderr, "%s: %s\n", gfarm_url, e); return (e); } e = gfs_stat(gfarm_url, &st); if (e != NULL) { free(gfarm_file); fprintf(stderr, "%s: %s\n", gfarm_url, e); return (e); } if (!GFARM_S_ISREG(st.st_mode)) { free(gfarm_file); gfs_stat_free(&st); fprintf(stderr, "%s: not a file\n", gfarm_url); return (e); } if ((st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) != 0) { /* program? */ e = gfarm_file_section_info_get_all_by_file( gfarm_file, &nsections, §ions); } else { e = gfarm_file_section_info_get_sorted_all_serial_by_file( gfarm_file, &nsections, §ions); } gfs_stat_free(&st); if (e != NULL) { free(gfarm_file); fprintf(stderr, "%s: %s\n", gfarm_url, e); return (e); } for (i = 0; i < nsections; i++) { int ncopies; struct gfarm_file_section_copy_info *copies; e = gfarm_file_section_copy_info_get_all_by_section( gfarm_file, sections[i].section, &ncopies, &copies); if (e != NULL) { fprintf(stderr, "%d: %s\n", i, e); if (e_save == NULL) e_save = e; continue; } printf("%s:", sections[i].section); for (j = 0; j < ncopies; j++) printf(" %s", copies[j].hostname); gfarm_file_section_copy_info_free_all(ncopies, copies); printf("\n"); } gfarm_file_section_info_free_all(nsections, sections); free(gfarm_file); return (e_save); }
char * gfarm_file_section_info_remove_all_by_file(char *pathname) { char *error, *error_save; int i, n; struct gfarm_file_section_info *infos; error = gfarm_file_section_info_get_all_by_file(pathname, &n, &infos); if (error != NULL) { if (error == GFARM_ERR_NO_SUCH_OBJECT) return (NULL); return (error); } /* * remove GfarmFileSection's */ error_save = NULL; for (i = 0; i < n; i++) { error = gfarm_file_section_info_remove(pathname, infos[i].section); if (error != NULL && error != GFARM_ERR_NO_SUCH_OBJECT) error_save = error; } gfarm_file_section_info_free_all(n, infos); /* XXX - do not remove parent GFarmPath here */ return (error_save); }
static gfarm_error_t gfs_pio_view_global_ftruncate(GFS_File gf, gfarm_off_t length) { struct gfs_file_global_context *gc = gf->view_context; gfarm_error_t e; int i, fragment, nsections; gfarm_off_t section_length; struct gfarm_file_section_info *sections; char section_string[GFARM_INT32STRLEN + 1]; if (length < 0) return (GFARM_ERR_INVALID_ARGUMENT); if (length >= gc->offsets[gf->pi.status.st_nsections - 1]) fragment = gf->pi.status.st_nsections - 1; else fragment = gfs_pio_view_global_bsearch( length, gc->offsets, gf->pi.status.st_nsections - 1); section_length = length - gc->offsets[fragment]; e = gfs_pio_view_global_move_to(gf, fragment); if (e != GFARM_ERR_NO_ERROR) return (e); e = gfs_pio_truncate(gc->fragment_gf, section_length); if (e != GFARM_ERR_NO_ERROR) return (e); /* * Before updating path_info, try to update most recent information, * because the file mode may be updated by e.g. gfs_chmod(). */ if (gfarm_path_info_get(gf->pi.pathname, &pi) == NULL) { gfarm_path_info_free(&gf->pi); gf->pi = pi; } #if 0 /* We don't store file size in gfarm_path_info, this is just ignored */ gf->pi.status.st_size = length; #endif gf->pi.status.st_nsections = fragment + 1; e = gfarm_path_info_replace(gf->pi.pathname, &gf->pi); if (e != GFARM_ERR_NO_ERROR) return (e); e = gfarm_file_section_info_get_sorted_all_serial_by_file( gf->pi.pathname, &nsections, §ions); if (e != GFARM_ERR_NO_ERROR) return (e); sections[fragment].filesize = section_length; sprintf(section_string, "%d", fragment); e = gfarm_file_section_info_replace(gf->pi.pathname, section_string, §ions[fragment]); for (i = fragment + 1; i < nsections; i++) (void)gfs_unlink_section_internal(gf->pi.pathname, sections[i].section); gfarm_file_section_info_free_all(nsections, sections); return (e); }
char * gfs_unlink(const char *gfarm_url) { char *gfarm_file, *e, *e_save = NULL; int i, j, nsections; struct gfarm_file_section_info *sections; e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) return (e); e = gfarm_file_section_info_get_all_by_file(gfarm_file, &nsections, §ions); if (e != NULL) { e_save = e; nsections = 0; sections = NULL; } /* XXX - should unlink in parallel. */ for (i = 0; i < nsections; i++) { int ncopies; struct gfarm_file_section_copy_info *copies; e = gfarm_file_section_copy_info_get_all_by_section( gfarm_file, sections[i].section, &ncopies, &copies); if (e != NULL) { if (e_save == NULL) e_save = e; continue; } for (j = 0; j < ncopies; j++) { e = gfs_unlink_replica_internal(gfarm_file, sections[i].section, copies[j].hostname); if (e != NULL) { if (e_save == NULL) e_save = e; continue; } } gfarm_file_section_copy_info_free_all(ncopies, copies); } if (sections != NULL) gfarm_file_section_info_free_all(nsections, sections); e = gfarm_file_section_info_remove_all_by_file(gfarm_file); if (e != NULL) e_save = e; e = gfarm_path_info_remove(gfarm_file); if (e != NULL) e_save = e; free(gfarm_file); gfs_uncachedir(); return (e_save); }
char * gfs_stat_canonical_path(char *gfarm_file, struct gfs_stat *s) { char *e; int i, nsections; struct gfarm_file_section_info *sections; struct gfarm_path_info pi; long ino; e = gfs_get_ino(gfarm_file, &ino); if (e != NULL) return (e); e = gfarm_path_info_get(gfarm_file, &pi); if (e != NULL) return (e); *s = pi.status; s->st_ino = ino; s->st_user = strdup(s->st_user); s->st_group = strdup(s->st_group); gfarm_path_info_free(&pi); if (s->st_user == NULL || s->st_group == NULL) { gfs_stat_free(s); return (GFARM_ERR_NO_MEMORY); } if (!GFARM_S_ISREG(s->st_mode)) return (NULL); /* regular file */ e = gfarm_file_section_info_get_all_by_file(gfarm_file, &nsections, §ions); if (e != NULL) { gfs_stat_free(s); /* * If GFARM_ERR_NO_SUCH_OBJECT is returned here, * gfs_stat() incorrectly assumes that this is a directory, * and reports GFARM_ERR_NOT_A_DIRECTORY. */ return (GFARM_ERR_NO_FRAGMENT_INFORMATION); } s->st_size = 0; for (i = 0; i < nsections; i++) s->st_size += sections[i].filesize; s->st_nsections = nsections; gfarm_file_section_info_free_all(nsections, sections); return (NULL); }
static char * gfs_pio_view_global_ftruncate(GFS_File gf, file_offset_t length) { struct gfs_file_global_context *gc = gf->view_context; char *e; int i, fragment, nsections; file_offset_t section_length; struct gfarm_file_section_info *sections; char section_string[GFARM_INT32STRLEN + 1]; if (length < 0) return (GFARM_ERR_INVALID_ARGUMENT); if (length >= gc->offsets[gf->pi.status.st_nsections - 1]) fragment = gf->pi.status.st_nsections - 1; else fragment = gfs_pio_view_global_bsearch( length, gc->offsets, gf->pi.status.st_nsections - 1); section_length = length - gc->offsets[fragment]; e = gfs_pio_view_global_move_to(gf, fragment); if (e != NULL) return (e); e = gfs_pio_truncate(gc->fragment_gf, section_length); if (e != NULL) return (e); gf->pi.status.st_size = length; gf->pi.status.st_nsections = fragment + 1; e = gfarm_path_info_replace(gf->pi.pathname, &gf->pi); if (e != NULL) return (e); e = gfarm_file_section_info_get_sorted_all_serial_by_file( gf->pi.pathname, &nsections, §ions); if (e != NULL) return (e); sections[fragment].filesize = section_length; sprintf(section_string, "%d", fragment); e = gfarm_file_section_info_replace(gf->pi.pathname, section_string, §ions[fragment]); for (i = fragment + 1; i < nsections; i++) (void)gfs_unlink_section_internal(gf->pi.pathname, sections[i].section); gfarm_file_section_info_free_all(nsections, sections); return (e); }
static char * display_replica_catalog(char *gfarm_url) { char *gfarm_file, *e, *e_save; int i, nsections; struct gfarm_file_section_info *sections; struct gfs_stat st; gfarm_mode_t mode; e = gfs_stat(gfarm_url, &st); if (e != NULL) return (e); mode = st.st_mode; gfs_stat_free(&st); if (!GFARM_S_ISREG(mode)) return ("not a regular file"); e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) return (e); if ((mode & (S_IXUSR|S_IXGRP|S_IXOTH)) != 0) { /* program? */ e_save = gfarm_file_section_info_get_all_by_file( gfarm_file, &nsections, §ions); } else { e_save = gfarm_file_section_info_get_sorted_all_serial_by_file( gfarm_file, &nsections, §ions); } if (e_save != NULL) goto free_gfarm_file; for (i = 0; i < nsections; i++) { e = display_section_copies(gfarm_file, sections[i].section); if (e != NULL) { if (e_save == NULL) e_save = e; fprintf(stderr, "%s: %s\n", sections[i].section, e); } } gfarm_file_section_info_free_all(nsections, sections); free_gfarm_file: free(gfarm_file); return (e_save); }
char * gfs_access(const char *gfarm_url, int mode) { char *e, *gfarm_file; struct gfarm_path_info pi; gfarm_mode_t stat_mode; int stat_nsections, nsections; struct gfarm_file_section_info *sections; e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) return (e); e = gfarm_path_info_get(gfarm_file, &pi); if (e != NULL) { free(gfarm_file); return (e); } stat_mode = pi.status.st_mode; stat_nsections = pi.status.st_nsections; e = gfarm_path_info_access(&pi, mode); gfarm_path_info_free(&pi); if (e != NULL) { free(gfarm_file); return (e); } if (GFARM_S_ISDIR(stat_mode)) { free(gfarm_file); return (NULL); } /* * Check all fragments are ready or not. * XXX - is this check necessary? */ e = gfarm_file_section_info_get_all_by_file( gfarm_file, &nsections, §ions); free(gfarm_file); if (e != NULL) return (e); gfarm_file_section_info_free_all(nsections, sections); if (!GFARM_S_IS_PROGRAM(stat_mode) && nsections != stat_nsections) e = GFARM_ERR_FRAGMENT_NUMBER_DOES_NOT_MATCH; return (e); }
char * gfs_access(char *gfarm_url, int mode) { char *e, *gfarm_file; struct gfarm_path_info pi; int nsections; struct gfarm_file_section_info *sections; e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) return (e); e = gfarm_path_info_get(gfarm_file, &pi); if (e != NULL) { free(gfarm_file); return (e); } /* * Check whether the gfarm_url can be accessible by other * processes or not. * * XXX - temporal solution until file locking will be implemented. */ e = gfarm_file_section_info_get_all_by_file(gfarm_file, &nsections, §ions); free(gfarm_file); if (e != NULL) { return (e); } gfarm_file_section_info_free_all(nsections, sections); if (!GFARM_S_IS_PROGRAM(pi.status.st_mode) && nsections != pi.status.st_nsections) return (GFARM_ERR_FRAGMENT_NUMBER_DOES_NOT_MATCH); e = gfarm_path_info_access(&pi, mode); gfarm_path_info_free(&pi); return (e); }
char * gfs_pio_set_view_global(GFS_File gf, int flags) { struct gfs_file_global_context *gc; char *e, *arch; int i, n; struct gfarm_file_section_info *infos; static char gfarm_url_prefix[] = "gfarm:/"; e = gfs_pio_set_view_default(gf); if (e != NULL) return (e); if (GFS_FILE_IS_PROGRAM(gf)) { e = gfarm_host_get_self_architecture(&arch); if (e != NULL) return (gf->error = e); return (gfs_pio_set_view_section(gf, arch, NULL, flags)); } if ((gf->mode & GFS_FILE_MODE_FILE_CREATED) != 0) return (gfs_pio_set_view_index(gf, 1, 0, NULL, flags)); if (gf->open_flags & GFARM_FILE_TRUNC) { int nsections; struct gfarm_file_section_info *sections; /* XXX this may not be OK, if a parallel process does this */ /* remove all sections except section "0" */ e = gfarm_file_section_info_get_all_by_file(gf->pi.pathname, &nsections, §ions); if (e != NULL) return (e); for (i = 0; i < nsections; i++) { if (strcmp(sections[i].section, "0") == 0) continue; (void)gfs_unlink_section_internal(gf->pi.pathname, sections[i].section); } gfarm_file_section_info_free_all(nsections, sections); gf->pi.status.st_nsections = 1; return (gfs_pio_set_view_index(gf, 1, 0, NULL, flags)); } /* XXX - GFARM_FILE_APPEND is not supported */ if (gf->open_flags & GFARM_FILE_APPEND) { gf->error = GFARM_ERR_OPERATION_NOT_SUPPORTED; return (gf->error); } gc = malloc(sizeof(struct gfs_file_global_context)); if (gc == NULL) { gf->error = GFARM_ERR_NO_MEMORY; return (gf->error); } e = gfarm_file_section_info_get_sorted_all_serial_by_file( gf->pi.pathname, &n, &infos); if (e != NULL) { free(gc); gf->error = e; return (e); } if (n != gf->pi.status.st_nsections) { gfarm_file_section_info_free_all(n, infos); free(gc); gf->error = "metainfo inconsitency, fragment number mismatch"; return (gf->error); } gc->offsets = malloc(sizeof(file_offset_t) * (n + 1)); gc->url = malloc(sizeof(gfarm_url_prefix) + strlen(gf->pi.pathname)); if (gc->offsets == NULL || gc->url == NULL) { if (gc->offsets != NULL) free(gc->offsets); if (gc->url != NULL) free(gc->url); gfarm_file_section_info_free_all(n, infos); free(gc); gf->error = GFARM_ERR_NO_MEMORY; return (gf->error); } gc->offsets[0] = 0; for (i = 0; i < n; i++) gc->offsets[i + 1] = gc->offsets[i] + infos[i].filesize; gfarm_file_section_info_free_all(n, infos); sprintf(gc->url, "%s%s", gfarm_url_prefix, gf->pi.pathname); gf->view_context = gc; gf->view_flags = flags; gc->fragment_gf = NULL; e = gfs_pio_view_global_move_to(gf, 0); if (e != NULL) { free(gc->url); free(gc->offsets); free(gc); gf->view_context = NULL; gfs_pio_set_view_default(gf); gf->error = e; return (e); } gf->ops = &gfs_pio_view_global_ops; gf->p = gf->length = 0; gf->io_offset = gf->offset = 0; gf->error = NULL; return (NULL); }
char * gfs_pio_set_view_global(GFS_File gf, int flags) { struct gfs_file_global_context *gc; char *e; int i, n; struct gfarm_file_section_info *infos; static char gfarm_url_prefix[] = "gfarm:/"; e = gfs_pio_set_view_default(gf); if (e != NULL) return (e); if (GFS_FILE_IS_PROGRAM(gf)) { gf->error = GFARM_ERR_OPERATION_NOT_PERMITTED; return (gf->error); } if ((gf->open_flags & GFARM_FILE_CREATE) != 0) return (gfs_pio_set_view_index(gf, 1, 0, NULL, flags)); gc = malloc(sizeof(struct gfs_file_global_context)); if (gc == NULL) { gf->error = GFARM_ERR_NO_MEMORY; return (gf->error); } e = gfarm_file_section_info_get_all_by_file(gf->pi.pathname, &n, &infos); if (e != NULL) { free(gc); gf->error = e; return (e); } if (n != gf->pi.status.st_nsections) { gfarm_file_section_info_free_all(n, infos); free(gc); gf->error = "metainfo inconsitency, fragment number mismatch"; return (gf->error); } gc->offsets = malloc(sizeof(file_offset_t) * (n + 1)); gc->url = malloc(sizeof(gfarm_url_prefix) + strlen(gf->pi.pathname)); if (gc->offsets == NULL || gc->url == NULL) { if (gc->offsets != NULL) free(gc->offsets); if (gc->url != NULL) free(gc->url); gfarm_file_section_info_free_all(n, infos); free(gc); gf->error = GFARM_ERR_NO_MEMORY; return (gf->error); } gc->offsets[0] = 0; for (i = 0; i < n; i++) gc->offsets[i + 1] = gc->offsets[i] + infos[i].filesize; gfarm_file_section_info_free_all(n, infos); sprintf(gc->url, "%s%s", gfarm_url_prefix, gf->pi.pathname); gf->view_context = gc; gf->view_flags = flags; gc->fragment_gf = NULL; e = gfs_pio_view_global_move_to(gf, 0); if (e != NULL) { free(gc->url); free(gc->offsets); free(gc); gf->view_context = NULL; gfs_pio_set_view_default(gf); gf->error = e; return (e); } gf->ops = &gfs_pio_view_global_ops; gf->p = gf->length = 0; gf->io_offset = gf->offset = 0; gf->error = NULL; return (NULL); }
char * gfarm_url_fragment_cleanup(char *gfarm_url, int nhosts, char **hosts) { char *e, *gfarm_file, **canonical_hostnames; int i, j, nfrags, ncopies; struct gfarm_file_section_info *frags; struct gfarm_file_section_copy_info *copies; struct gfs_connection *gfs_server; e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) return (e); e = gfarm_file_section_info_get_all_by_file( gfarm_file, &nfrags, &frags); if (e != NULL) { free(gfarm_file); return (NULL); } gfarm_file_section_info_free_all(nfrags, frags); if (nfrags == nhosts) { free(gfarm_file); return (NULL); /* complete */ } e = gfarm_host_get_canonical_names(nhosts, hosts, &canonical_hostnames); if (e != NULL) { free(gfarm_file); return (e); } /* * do removal */ /* remove gfarm_file_fragment_copy_info and actual copy */ for (i = 0; i < nhosts; i++) { char *path_section; char section_string[GFARM_INT32STRLEN + 1]; struct sockaddr peer_addr; sprintf(section_string, "%d", i); e = gfarm_path_section(gfarm_file, section_string, &path_section); if (e != NULL) continue; e = gfarm_host_address_get(hosts[i], gfarm_spool_server_port, &peer_addr, NULL); if (e != NULL) { free(path_section); continue; } /* remove copy */ if (gfs_client_connection(canonical_hostnames[i], &peer_addr, &gfs_server) == NULL) gfs_client_unlink(gfs_server, path_section); e = gfarm_file_section_copy_info_get_all_by_section( gfarm_file, section_string, &ncopies, &copies); if (e != NULL) { free(path_section); continue; } for (j = 0; j < ncopies; j++) { /* * equivalent to * gfarm_file_section_copy_info_remove_all_by_section() */ gfarm_file_section_copy_info_remove(gfarm_file, section_string, copies[j].hostname); /* remove actual copies */ if (strcasecmp(copies[j].hostname, canonical_hostnames[i]) == 0) continue; if (gfarm_host_address_get(copies[j].hostname, gfarm_spool_server_port, &peer_addr, NULL) != NULL) continue; if (gfs_client_connection(copies[j].hostname, &peer_addr, &gfs_server) == NULL) gfs_client_unlink(gfs_server, path_section); } free(path_section); gfarm_file_section_copy_info_free_all(ncopies, copies); } gfarm_file_section_info_remove_all_by_file(gfarm_file); gfarm_path_info_remove(gfarm_file); gfarm_strings_free_deeply(nhosts, canonical_hostnames); free(gfarm_file); return (NULL); }
char * gfs_unlink_replicas_on_host(const char *gfarm_url, const char *hostname, int force) { char *gfarm_file, *e, *e_save = NULL; int i, j, nsections; struct gfarm_file_section_info *sections; char *c_hname; e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) return (e); e = gfarm_host_get_canonical_name(hostname, &c_hname); if (e != NULL) { free(gfarm_file); return (e); } e = gfarm_file_section_info_get_all_by_file(gfarm_file, &nsections, §ions); if (e != NULL) { e_save = e; nsections = 0; sections = NULL; } for (i = 0; i < nsections; i++) { int ncopies; struct gfarm_file_section_copy_info *copies; e = gfarm_file_section_copy_info_get_all_by_section( gfarm_file, sections[i].section, &ncopies, &copies); if (e != NULL) { if (e == GFARM_ERR_NO_SUCH_OBJECT && force) /* filesystem metadata should be collapsed. */ e = gfarm_file_section_info_remove( gfarm_file, sections[i].section); if (e_save == NULL) e_save = e; continue; } for (j = 0; j < ncopies; j++) { /* skip when a different node. */ if (strcmp(c_hname, copies[j].hostname) != 0) continue; if (ncopies == 1 && force == 0) { if (e_save == NULL) e_save = "gfs_unlink_replica_on_host:" " cannot delete the last file" " replica"; continue; } e = gfs_unlink_replica_internal(gfarm_file, sections[i].section, copies[j].hostname); if (e != NULL) { if (e_save == NULL) e_save = e; continue; } if (ncopies == 1) { int ncps; struct gfarm_file_section_copy_info *cps; e = gfarm_file_section_copy_info_get_all_by_section( gfarm_file, sections[i].section, &ncps, &cps); if (e == GFARM_ERR_NO_SUCH_OBJECT) /* There is no section copy info. */ e = gfarm_file_section_info_remove( gfarm_file, sections[i].section); else if (e == NULL) gfarm_file_section_copy_info_free_all( ncps, cps); if (e != NULL) { if (e_save == NULL) e_save = e; continue; } } } gfarm_file_section_copy_info_free_all(ncopies, copies); } if (sections != NULL) gfarm_file_section_info_free_all(nsections, sections); free(c_hname); free(gfarm_file); return (e_save); }
static char * gfsck_file(char *gfarm_url) { char *gfarm_file, *e, *e_save = NULL; int i, nsections, valid_nsections = 0; struct gfarm_file_section_info *sections; GFS_File gf; e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) return (e); e = gfarm_file_section_info_get_all_by_file( gfarm_file, &nsections, §ions); if (e != NULL) { /* no section info, remove path info */ e = path_info_remove(gfarm_url, gfarm_file); free(gfarm_file); return (e); } e = gfs_pio_open(gfarm_url, GFARM_FILE_RDONLY, &gf); if (e != NULL) { free(gfarm_file); return (e); } for (i = 0; i < nsections; i++) { int j, ncopies, valid_ncopies = 0; struct gfarm_file_section_copy_info *copies; char *section = sections[i].section; e = gfarm_file_section_copy_info_get_all_by_section( gfarm_file, section, &ncopies, &copies); if (e == GFARM_ERR_NO_SUCH_OBJECT) { /* no section copy info, remove section info */ e = section_info_remove(gfarm_url, gfarm_file, section); if (e != NULL && e_save == NULL) e_save = e; continue; } else if (e != NULL) { fprintf(stderr, "%s (%s): %s\n", gfarm_url, section, e); if (e_save == NULL) e_save = e; continue; } for (j = 0; j < ncopies; ++j) { if (option_verbose) printf("%s (%s) on %s\n", gfarm_url, section, copies[j].hostname); e = gfs_pio_set_view_section(gf, section, copies[j].hostname, GFARM_FILE_NOT_REPLICATE | GFARM_FILE_NOT_RETRY); if (e == GFARM_ERR_INCONSISTENT_RECOVERABLE) { /* invalid section copy info removed */ printf("%s (%s) on %s: " "invalid metadata deleted\n", gfarm_url, section, copies[j].hostname); e = NULL; } else { ++valid_ncopies; if (e != NULL) { fprintf(stderr, "%s (%s) on %s: %s\n", gfarm_url, section, copies[j].hostname, e); if (e_save == NULL) e_save = e; } } } gfarm_file_section_copy_info_free_all(ncopies, copies); if (valid_ncopies == 0) { /* no section copy info, remove section info */ e = section_info_remove(gfarm_url, gfarm_file, section); if (e != NULL && e_save == NULL) e_save = e; } else ++valid_nsections; } if (valid_nsections == 0) { /* no section info, remove path info */ e = path_info_remove(gfarm_url, gfarm_file); if (e != NULL && e_save == NULL) e_save = e; } else if (valid_nsections < nsections) { printf("%s: warning: number of file sections reduced\n", gfarm_url); } gfarm_file_section_info_free_all(nsections, sections); free(gfarm_file); e = gfs_pio_close(gf); if (e != NULL) return (e); return (e_save); }
char * gfs_unlink(const char *gfarm_url) { char *gfarm_file, *e, *e_save = NULL; int i, j, nsections; struct gfarm_path_info pi; struct gfarm_file_section_info *sections; gfarm_timerval_t t1, t2; gfs_profile(gfarm_gettimerval(&t1)); e = gfarm_url_make_path_for_creation(gfarm_url, &gfarm_file); if (e != NULL) { e_save = e; goto finish_unlink; } e = gfarm_path_info_get(gfarm_file, &pi); if (e != NULL) { e_save = e; goto finish_free_gfarm_file; } if (GFARM_S_ISDIR(pi.status.st_mode)) { gfarm_path_info_free(&pi); e_save = GFARM_ERR_IS_A_DIRECTORY; goto finish_free_gfarm_file; } gfarm_path_info_free(&pi); e = gfarm_file_section_info_get_all_by_file(gfarm_file, &nsections, §ions); if (e != NULL) { e_save = e; nsections = 0; sections = NULL; } /* XXX - should unlink in parallel. */ for (i = 0; i < nsections; i++) { int ncopies; struct gfarm_file_section_copy_info *copies; e = gfarm_file_section_copy_info_get_all_by_section( gfarm_file, sections[i].section, &ncopies, &copies); if (e != NULL) { if (e_save == NULL) e_save = e; continue; } for (j = 0; j < ncopies; j++) { e = gfs_unlink_replica_internal(gfarm_file, sections[i].section, copies[j].hostname); if (e != NULL) { if (e_save == NULL) e_save = e; continue; } } gfarm_file_section_copy_info_free_all(ncopies, copies); } if (sections != NULL) gfarm_file_section_info_free_all(nsections, sections); e = gfarm_file_section_info_remove_all_by_file(gfarm_file); if (e != NULL) e_save = e; e = gfarm_path_info_remove(gfarm_file); if (e != NULL) e_save = e; finish_free_gfarm_file: free(gfarm_file); finish_unlink: gfs_profile(gfarm_gettimerval(&t2)); gfs_profile(gfs_unlink_time += gfarm_timerval_sub(&t2, &t1)); return (e_save); }