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); }
static gfarm_error_t gfs_stat_cache_enter_internal(const char *path, const struct gfs_stat *st, const struct timeval *nowp) { gfarm_error_t e; struct gfarm_hash_entry *entry; struct stat_cache_data *data; int created; if (stat_cache == NULL) { if ((e = gfs_stat_cache_init()) != GFARM_ERR_NO_ERROR) return (e); } gfs_stat_cache_expire_internal(nowp); if (stat_cache_count >= gfarm_attr_cache_limit) { /* remove the head of the list (i.e. oldest entry) */ data = stat_cache_list_head.next; data->prev->next = data->next; data->next->prev = data->prev; gfs_stat_free(&data->st); entry = data->entry; gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry), gfarm_hash_entry_key_length(entry)); --stat_cache_count; } entry = gfarm_hash_enter(stat_cache, path, strlen(path) + 1, sizeof(*data), &created); if (entry == NULL) return (GFARM_ERR_NO_MEMORY); data = gfarm_hash_entry_data(entry); if (created) { ++stat_cache_count; data->entry = entry; } else { /* remove from the list, to move this to the end of the list */ data->prev->next = data->next; data->next->prev = data->prev; gfs_stat_free(&data->st); } e = gfs_stat_copy(&data->st, st); if (e != GFARM_ERR_NO_ERROR) { gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry), gfarm_hash_entry_key_length(entry)); --stat_cache_count; return (e); } data->expiration = *nowp; gfarm_timeval_add(&data->expiration, &stat_cache_lifespan); /* add to the end of the cache list, i.e. assumes monotonic time */ data->next = &stat_cache_list_head; data->prev = stat_cache_list_head.prev; stat_cache_list_head.prev->next = data; stat_cache_list_head.prev = data; return (GFARM_ERR_NO_ERROR); }
static int fixfrag(char *pathname, const char *gfarm_prefix) { char *gfarm_url, *sec, *gfarm_file, *e; struct gfs_stat gst; int r = 1; gfarm_url = append_prefix_pathname(gfarm_prefix, pathname); if (gfarm_url == NULL) { print_errmsg(pathname, NULL, "not enough memory"); return (r); } /* divide into file and section parts. */ e = split_file_and_section(gfarm_url, &sec); if (e != NULL) { print_errmsg(pathname, NULL, e); delete_invalid_file_or_directory(pathname); goto error_gfarm_url; } e = gfs_stat(gfarm_url, &gst); if (e == NULL) { if (!GFARM_S_ISREG(gst.st_mode)) { gfs_stat_free(&gst); print_errmsg(gfarm_url, NULL, "not a regular file"); delete_invalid_file_or_directory(pathname); goto error_gfarm_url; } gfs_stat_free(&gst); } else /* permit no fragment case */; e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) { print_errmsg(gfarm_url, sec, e); delete_invalid_file_or_directory(pathname); goto error_gfarm_url; } /* check whether the fragment is already registered. */ e = fixfrag_i(gfarm_url, pathname, gfarm_file, sec); if (e != NULL && e != GFARM_ERR_ALREADY_EXISTS) goto error_gfarm_file; r = 0; error_gfarm_file: free(gfarm_file); error_gfarm_url: free(gfarm_url); return (r); }
static char * gfsck_dir(char *gfarm_dir, char *file) { char *e, *e_save = NULL, *gfarm_url; struct gfs_stat gsb; GFS_Dir gdir; struct gfs_dirent *gdent; gfarm_url = malloc(strlen(gfarm_dir) + strlen(file) + 2); if (gfarm_url == NULL) return (GFARM_ERR_NO_MEMORY); if (gfarm_dir[0] == '\0') sprintf(gfarm_url, "%s", file); else sprintf(gfarm_url, "%s/%s", gfarm_dir, file); e = gfs_stat(gfarm_url, &gsb); if (e != NULL) { free(gfarm_url); return (e); } if (GFARM_S_ISREG(gsb.st_mode)) { gfs_stat_free(&gsb); e = gfsck_file(gfarm_url); free(gfarm_url); return (e); } if (!GFARM_S_ISDIR(gsb.st_mode)) { gfs_stat_free(&gsb); free(gfarm_url); return ("unknown file type"); } gfs_stat_free(&gsb); e = gfs_opendir(gfarm_url, &gdir); if (e != NULL) { free(gfarm_url); return (e); } while ((e = gfs_readdir(gdir, &gdent)) == NULL && gdent != NULL) { e = gfsck_dir(gfarm_url, gdent->d_name); if (e != NULL) { fprintf(stderr, "%s/%s: %s\n", gfarm_url, gdent->d_name, e); if (e_save == NULL) e_save = e; } } (void)gfs_closedir(gdir); free(gfarm_url); 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 * remove_whole_file_or_dir(char *path, int is_recursive) { char *e, *e2; struct gfs_stat gs; char cwdbuf[PATH_MAX * 2]; e = gfs_stat(path, &gs); if (e == GFARM_ERR_NO_FRAGMENT_INFORMATION) e2 = gfs_unlink(path); if (e != NULL) return (e); if (GFARM_S_ISREG(gs.st_mode)) { e = gfs_unlink(path); } else if (GFARM_S_ISDIR(gs.st_mode)) { if (!is_recursive) return (GFARM_ERR_IS_A_DIRECTORY); e = gfs_getcwd(cwdbuf, sizeof(cwdbuf)); if (e != NULL) return (e); e = gfs_chdir(path); if (e != NULL) return (e); remove_cwd_entries(); e = gfs_chdir_canonical(cwdbuf); if (e != NULL) return (e); e = gfs_rmdir(path); } gfs_stat_free(&gs); return (e); }
int __fchown(int fd, uid_t owner, gid_t group) { GFS_File gf; const char *e; struct gfs_stat s; _gfs_hook_debug_v(fprintf(stderr, "Hooking __fchown(%d, %d, %d)\n", fd, uid, group)); if ((gf = gfs_hook_is_open(fd)) == NULL) return (__syscall_fchown(fd, owner, group)); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __fchown(%d, %d, %d)\n", fd, owner, group)); e = gfs_fstat(gf, &s); if (e == NULL) { if (strcmp(s.st_user, gfarm_get_global_username()) != 0) e = GFARM_ERR_OPERATION_NOT_PERMITTED; /* EPERM */ /* XXX - do nothing */ gfs_stat_free(&s); } if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __fchown: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
int __lchown(const char *path, uid_t owner, gid_t group) { const char *e; char *url; struct gfs_stat s; _gfs_hook_debug_v(fprintf(stderr, "Hooking __lchown(%s, %d, %d)\n", path, uid, group)); if (!gfs_hook_is_url(path, &url)) return (__syscall_lchown(path, owner, group)); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __lchown(%s, %d, %d)\n", path, owner, group)); /* XXX - gfs_lstat is not supported */ e = gfs_stat(url, &s); free(url); if (e == NULL) { if (strcmp(s.st_user, gfarm_get_global_username()) != 0) e = GFARM_ERR_OPERATION_NOT_PERMITTED; /* EPERM */ /* XXX - do nothing */ gfs_stat_free(&s); } if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __lchown: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
static char * gfs_pio_local_mkdir_p(char *canonic_dir) { struct gfs_stat stata; struct stat statb; gfarm_mode_t mode; char *e, *local_path, *user; /* dirname(3) may return '.'. This means the spool root directory. */ if (strcmp(canonic_dir, "/") == 0 || strcmp(canonic_dir, ".") == 0) return (NULL); /* should exist */ e = gfs_stat_canonical_path(canonic_dir, &stata); if (e != NULL) return (e); mode = stata.st_mode; /* * XXX - if the owner of a directory is not the same, create a * directory with permission 0777 - This should be fixed in * the next major release. */ user = gfarm_get_global_username(); if (strcmp(stata.st_user, user) != 0) mode |= 0777; gfs_stat_free(&stata); if (!GFARM_S_ISDIR(mode)) return (GFARM_ERR_NOT_A_DIRECTORY); e = gfarm_path_localize(canonic_dir, &local_path); if (e != NULL) return (e); if (stat(local_path, &statb)) { char *par_dir, *saved_par_dir; mode_t saved_umask; int r; par_dir = saved_par_dir = strdup(canonic_dir); if (par_dir == NULL) { free(local_path); return (GFARM_ERR_NO_MEMORY); } par_dir = dirname(par_dir); e = gfs_pio_local_mkdir_p(par_dir); free(saved_par_dir); if (e != NULL) { free(local_path); return (e); } saved_umask = umask(0); r = mkdir(local_path, mode); umask(saved_umask); if (r == -1) { free(local_path); return (gfarm_errno_to_error(errno)); } } free(local_path); return (NULL); }
static void gfs_dirplus_clear(GFS_DirPlus dir) { int i, n = dir->n; for (i = 0; i < n; i++) gfs_stat_free(&dir->stbuf[i]); dir->n = dir->index = 0; }
char * gfs_chdir(const char *dir) { char *e, *canonic_path; struct gfs_stat st; if ((e = gfs_stat(dir, &st)) != NULL) return (e); if (!GFARM_S_ISDIR(st.st_mode)) { gfs_stat_free(&st); return (GFARM_ERR_NOT_A_DIRECTORY); } gfs_stat_free(&st); e = gfarm_canonical_path(gfarm_url_prefix_skip(dir), &canonic_path); if (e != NULL) return (e); e = gfs_chdir_canonical(canonic_path); free (canonic_path); return (e); }
static int section_does_not_exists(char *gfarm_url, char *section) { struct gfs_stat s; if (gfs_stat_section(gfarm_url, section, &s) == NULL) { gfs_stat_free(&s); fprintf(stderr, "%s: %s:%s already exists\n", program_name, gfarm_url, section); return (0); } return (1); }
char * gfs_opendir(const char *path, GFS_Dir *dirp) { char *e, *canonic_path; struct node *n; struct gfs_dir *dir; struct gfs_stat st; /* gfs_stat() -> gfarm_path_info_get() makes the dircache consistent */ if ((e = gfs_stat(path, &st)) != NULL) return (e); if (!GFARM_S_ISDIR(st.st_mode)) { gfs_stat_free(&st); return (GFARM_ERR_NOT_A_DIRECTORY); } gfs_stat_free(&st); e = gfarm_canonical_path(gfarm_url_prefix_skip(path), &canonic_path); if (e != NULL) return (e); e = lookup_relative(root, canonic_path, NODE_FLAG_IS_DIR, GFARM_INODE_LOOKUP, &n); free(canonic_path); if (e != NULL) return (e); dir = malloc(sizeof(struct gfs_dir)); if (dir == NULL) return (GFARM_ERR_NO_MEMORY); dir->dir = n; gfarm_hash_iterator_begin(n->u.d.children, &dir->iterator); dir->index = 0; *dirp = dir; ++opendir_count; /* XXX if someone removed a path, while opening a directory... */ return (NULL); }
static char * gfs_pio_remote_mkdir_p( struct gfs_connection *gfs_server, char *canonic_dir) { struct gfs_stat stata; gfarm_mode_t mode; char *e, *user; /* dirname(3) may return '.'. This means the spool root directory. */ if (strcmp(canonic_dir, "/") == 0 || strcmp(canonic_dir, ".") == 0) return (NULL); /* should exist */ user = gfarm_get_global_username(); if (user == NULL) return ("gfs_pio_remote_mkdir_p(): programming error, " "gfarm library isn't properly initialized"); e = gfs_stat_canonical_path(canonic_dir, &stata); if (e != NULL) return (e); mode = stata.st_mode; /* * XXX - if the owner of a directory is not the same, create a * directory with permission 0777 - This should be fixed in * the next major release. */ if (strcmp(stata.st_user, user) != 0) mode |= 0777; gfs_stat_free(&stata); if (!GFARM_S_ISDIR(mode)) return (GFARM_ERR_NOT_A_DIRECTORY); if (gfs_client_exist(gfs_server, canonic_dir) == GFARM_ERR_NO_SUCH_OBJECT) { char *par_dir, *saved_par_dir; par_dir = saved_par_dir = strdup(canonic_dir); if (par_dir == NULL) return (GFARM_ERR_NO_MEMORY); par_dir = dirname(par_dir); e = gfs_pio_remote_mkdir_p(gfs_server, par_dir); free(saved_par_dir); if (e != NULL) return (e); e = gfs_client_mkdir(gfs_server, canonic_dir, mode); } return (e); }
static char * gfarm_path_info_dup(struct gfarm_path_info *src, struct gfarm_path_info *dest) { char *e; e = gfs_stat_dup(&src->status, &dest->status); if (e != NULL) return (e); if (src->pathname != NULL) { dest->pathname = strdup(src->pathname); if (dest->pathname == NULL) { gfs_stat_free(&dest->status); return (GFARM_ERR_NO_MEMORY); } } return (NULL); }
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); }
void gfs_stat_cache_clear(void) { struct stat_cache_data *p, *q; struct gfarm_hash_entry *entry; for (p = stat_cache_list_head.next; p != &stat_cache_list_head; p = q) { q = p->next; gfs_stat_free(&p->st); entry = p->entry; gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry), gfarm_hash_entry_key_length(entry)); } stat_cache_list_head.next = stat_cache_list_head.prev = &stat_cache_list_head; stat_cache_count = 0; }
static char * remove_whole_file_or_dir(char *path, Unlink_Ops ops, void *closure, int is_recursive) { struct gfs_stat gs; char *e, cwdbuf[PATH_MAX * 2]; const char *b; gfarm_mode_t mode; b = gfarm_path_dir_skip(gfarm_url_prefix_skip(path)); if (b[0] == '.' && (b[1] == '\0' || (b[1] == '.' && b[2] == '\0'))) return ("cannot remove \'.\' or \'..\'"); e = gfs_stat(path, &gs); if (e == GFARM_ERR_NO_FRAGMENT_INFORMATION) return (ops->unlink(path, closure)); if (e != NULL) return (e); mode = gs.st_mode; gfs_stat_free(&gs); if (GFARM_S_ISREG(mode)) { e = ops->unlink(path, closure); } else if (GFARM_S_ISDIR(mode)) { if (!is_recursive) return (GFARM_ERR_IS_A_DIRECTORY); e = gfs_getcwd(cwdbuf, sizeof(cwdbuf)); if (e != NULL) return (e); e = gfs_chdir(path); if (e != NULL) return (e); remove_cwd_entries(ops, closure); e = gfs_chdir_canonical(cwdbuf); if (e != NULL) return (e); e = ops->rmdir(path, closure); } return (e); }
static char * display_replica_catalog_section(char *gfarm_url, char *section) { char *gfarm_file, *e; int j, ncopies; struct gfarm_file_section_copy_info *copies; struct gfs_stat st; if (section == NULL) return (display_replica_catalog(gfarm_url)); e = gfs_stat(gfarm_url, &st); if (e != NULL) { fprintf(stderr, "%s: %s\n", gfarm_url, e); return (e); } gfs_stat_free(&st); e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) { fprintf(stderr, "%s: %s\n", gfarm_url, e); return (e); } e = gfarm_file_section_copy_info_get_all_by_section( gfarm_file, section, &ncopies, &copies); if (e != NULL) { fprintf(stderr, "%s\n", e); free(gfarm_file); return (e); } j = 0; printf("%s", copies[j].hostname); for (++j; j < ncopies; ++j) printf(" %s", copies[j].hostname); printf("\n"); gfarm_file_section_copy_info_free_all(ncopies, copies); free(gfarm_file); return (NULL); }
static void gfs_stat_cache_expire_internal(const struct timeval *nowp) { struct stat_cache_data *p, *q; struct gfarm_hash_entry *entry; for (p = stat_cache_list_head.next; p != &stat_cache_list_head; p = q) { /* assumes monotonic time */ if (gfarm_timeval_cmp(&p->expiration, nowp) > 0) break; q = p->next; gfs_stat_free(&p->st); entry = p->entry; gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry), gfarm_hash_entry_key_length(entry)); --stat_cache_count; } stat_cache_list_head.next = p; p->prev = &stat_cache_list_head; }
gfarm_error_t gfs_stat_cache_purge(const char *path) { struct gfarm_hash_iterator it; struct gfarm_hash_entry *entry; struct stat_cache_data *data; if (stat_cache == NULL) /* there is nothing to purge */ return (GFARM_ERR_NO_ERROR); gfs_stat_cache_expire(); if (!gfarm_hash_iterator_lookup(stat_cache, path, strlen(path)+1, &it)) return (GFARM_ERR_NO_SUCH_FILE_OR_DIRECTORY); entry = gfarm_hash_iterator_access(&it); assert(entry != NULL); data = gfarm_hash_entry_data(entry); data->prev->next = data->next; data->next->prev = data->prev; gfs_stat_free(&data->st); gfarm_hash_iterator_purge(&it); --stat_cache_count; return (GFARM_ERR_NO_ERROR); }
char * gfs_hook_clear_gfs_file(int fd) { GFS_File gf; char *e = NULL; _gfs_hook_debug(fprintf(stderr, "GFS: clear_gfs_file: %d\n", fd)); gf = gfs_hook_is_open(fd); if (gf == NULL) { _gfs_hook_debug(fprintf(stderr, "GFS: ERROR: not a Gfarm file: %d\n", fd)); return ("not a Gfarm file"); } if (--_gfs_file_buf[fd]->refcount > 0) { /* fd is duplicated, skip closing the file. */ _gfs_hook_debug(fprintf(stderr, "GFS: clear_gfs_file: skipped\n")); } else { if (gfs_hook_gfs_file_type(fd) == GFS_DT_REG) { gfs_hook_delete_creating_file(gf); e = gfs_pio_close(gf); } else if (gfs_hook_gfs_file_type(fd) == GFS_DT_DIR) { _gfs_file_buf[fd]->u.d->dir = NULL; _gfs_file_buf[fd]->u.d->suspended = NULL; gfs_stat_free(&_gfs_file_buf[fd]->u.d->gst); free(_gfs_file_buf[fd]->u.d->canonical_path); free(_gfs_file_buf[fd]->u.d); e = gfs_closedir((GFS_Dir)gf); } free(_gfs_file_buf[fd]); } __syscall_close(fd); _gfs_file_buf[fd] = NULL; return (e); }
int main(int argc, char **argv) { int argc_save = argc; char **argv_save = argv; gfarm_error_t e, e_save = GFARM_ERR_NO_ERROR; int i, n, ch, opt_recursive = 0; gfarm_stringlist paths; gfs_glob_t types; if (argc >= 1) program_name = basename(argv[0]); while ((ch = getopt(argc, argv, "rR?")) != -1) { switch (ch) { case 'r': case 'R': opt_recursive = 1; break; case '?': default: usage(); } } argc -= optind; argv += optind; e = gfarm_initialize(&argc_save, &argv_save); if (e != GFARM_ERR_NO_ERROR) { fprintf(stderr, "%s: %s\n", program_name, gfarm_error_string(e)); exit(1); } if (argc == 0) { usage(); } e = gfarm_stringlist_init(&paths); if (e != GFARM_ERR_NO_ERROR) { fprintf(stderr, "%s: %s\n", program_name, gfarm_error_string(e)); exit(EXIT_FAILURE); } e = gfs_glob_init(&types); if (e != GFARM_ERR_NO_ERROR) { fprintf(stderr, "%s: %s\n", program_name, gfarm_error_string(e)); exit(EXIT_FAILURE); } for (i = 0; i < argc; i++) gfs_glob(argv[i], &paths, &types); gfs_glob_free(&types); n = gfarm_stringlist_length(&paths); for (i = 0; i < n; i++) { char *p = gfarm_stringlist_elem(&paths, i); struct gfs_stat st; if ((e = gfs_stat(p, &st)) != GFARM_ERR_NO_ERROR) { fprintf(stderr, "%s: %s\n", p, gfarm_error_string(e)); } else { if (GFARM_S_ISREG(st.st_mode)) e = display_replica_catalog(p, &st, NULL); else if (opt_recursive) e = gfarm_foreach_directory_hierarchy( display_replica_catalog, display_name, NULL, p, NULL); else fprintf(stderr, "%s: not a file\n", p); gfs_stat_free(&st); if (e_save == GFARM_ERR_NO_ERROR) e_save = e; } } gfarm_stringlist_free_deeply(&paths); e = gfarm_terminate(); if (e != GFARM_ERR_NO_ERROR) { fprintf(stderr, "%s: %s\n", program_name, gfarm_error_string(e)); exit(1); } return (e_save == GFARM_ERR_NO_ERROR ? 0 : 1); }
static int fixdir(char *dir, const char *gfarm_prefix) { DIR* dirp; struct dirent *dp; struct stat sb; char *dir1; char *gfarm_url, *e; int is_directory; struct gfs_stat gs; if (lstat(dir, &sb)) { perror(dir); return (1); } if (S_ISREG(sb.st_mode)) return (fixfrag(dir, gfarm_prefix)); if (!S_ISDIR(sb.st_mode)) { print_errmsg(dir, NULL, "neither a regular file nor a directory"); delete_invalid_file_or_directory(dir); return (1); } /* 'dir' is a directory */ gfarm_url = append_prefix_pathname(gfarm_prefix, dir); if (gfarm_url == NULL) { print_errmsg(dir, NULL, "not enough memory"); return (1); } e = gfs_stat(gfarm_url, &gs); if (e != NULL) { print_errmsg(gfarm_url, NULL, e); delete_invalid_file_or_directory(dir); free(gfarm_url); return (1); } is_directory = GFARM_S_ISDIR(gs.st_mode); gfs_stat_free(&gs); if (!is_directory) { print_errmsg(gfarm_url, NULL, "invalid directory"); delete_invalid_file_or_directory(dir); free(gfarm_url); return (1); } free(gfarm_url); dirp = opendir(dir); if (dirp == NULL) { perror(dir); return (1); } if (strcmp(dir, ".") == 0) dir = ""; /* just a trick */ while ((dp = readdir(dirp)) != NULL) { if (strcmp(dp->d_name, ".") == 0 || strcmp(dp->d_name, "..") == 0) continue; GFARM_MALLOC_ARRAY(dir1, strlen(dir) + strlen(dp->d_name) + 2); if (dir1 == NULL) { print_errmsg(dp->d_name, NULL, "not enough memory"); closedir(dirp); return (1); } strcpy(dir1, dir); if (strcmp(dir, "")) strcat(dir1, "/"); strcat(dir1, dp->d_name); fixdir(dir1, gfarm_prefix); free(dir1); } return (closedir(dirp)); }
static void fixurl(const char *gfarm_url) { char *gfarm_file, *local_path, *e; struct stat sb; int len_path, is_invalid = 0, is_directory = 0; glob_t pglob; char **pathp, *pat; struct gfs_stat gs; e = gfarm_canonical_path(gfarm_url_prefix_skip(gfarm_url), &gfarm_file); if (e != NULL) { /* * no path info, try to delete invalid physical files * or directories */ e = gfarm_canonical_path_for_creation( gfarm_url_prefix_skip(gfarm_url), &gfarm_file); if (e != NULL) { /* in this case, give up searching invalid files */ print_errmsg(gfarm_url, NULL, e); return; } is_invalid = 1; } else { /* check it is a directory or not */ e = gfs_stat(gfarm_url, &gs); if (e != NULL) { if (e != GFARM_ERR_NO_FRAGMENT_INFORMATION) { /* maybe permission denied */ print_errmsg(gfarm_url, NULL, e); goto error_gfarm_file; } /* no fragment information case */ } else { is_directory = GFARM_S_ISDIR(gs.st_mode); gfs_stat_free(&gs); } } /* * Check local_path; if it is invalid or not a directory, * delete it. Otherwise, check it recursively. */ e = gfarm_path_localize(gfarm_file, &local_path); if (e == NULL && stat(local_path, &sb) == 0) { if (is_invalid || !is_directory || !S_ISDIR(sb.st_mode)) { print_errmsg(local_path, NULL, "invalid file or directory"); delete_invalid_file_or_directory(local_path); } else if (chdir(local_path) == 0) (void)fixdir(".", gfarm_url); /* continue */ } if (e != NULL) { print_errmsg(gfarm_url, NULL, e); goto error_gfarm_file; } /* investigate file sections */ len_path = strlen(local_path); GFARM_MALLOC_ARRAY(pat, len_path + 3); if (pat == NULL) { print_errmsg(gfarm_url, NULL, "not enough memory"); free(local_path); goto error_gfarm_file; } strcpy(pat, local_path); strcat(pat, ":*"); free(local_path); pglob.gl_offs = 0; glob(pat, GLOB_DOOFFS, NULL, &pglob); free(pat); pathp = pglob.gl_pathv; while (*pathp) { char *sec = &((*pathp)[len_path + 1]); if (is_invalid || is_directory) { print_errmsg(gfarm_url, sec, "invalid file"); delete_invalid_file_or_directory(*pathp); ++pathp; continue; } (void)fixfrag_i(gfarm_url, *pathp, gfarm_file, sec); ++pathp; } globfree(&pglob); error_gfarm_file: free(gfarm_file); return; }
static int gfarm_register_file(char *gfarm_url, char *node_index, char *hostname, int total_nodes, char *filename, int auto_index) { struct stat s; struct gfs_stat gs; char *e, *target_url = NULL; int executable_file = 0; if (stat(filename, &s) == 0) { if (!S_ISREG(s.st_mode)) { fprintf(stderr, "%s: not a regular file", filename); return (-1); } if ((s.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) != 0) executable_file = 1; } else if (strcmp(filename, "-")) { perror(filename); return (-1); } e = gfs_stat(gfarm_url, &gs); if (e == NULL && GFARM_S_ISDIR(gs.st_mode)) { char *bname; /* gfarm_url is a directory */ gfs_stat_free(&gs); if (auto_index && total_nodes > 1 && !executable_file) { /* * In the auto index mode, the target Gfarm URL * should be a regular file when two or more local * non-executable files will be registered for * preventing unexpected results. */ fprintf(stderr, "%s: not a regular file. " "The target Gfarm URL should be a " "regular file when registering two or " "more local files.\n", gfarm_url); return (-1); } bname = basename(filename); target_url = malloc(strlen(gfarm_url) + strlen(bname) + 2); if (target_url == NULL) { fprintf(stderr, "not enough memory\n"); return (-1); } strcpy(target_url, gfarm_url); if (*gfarm_path_dir_skip(gfarm_url_prefix_skip(target_url)) != '\0') strcat(target_url, "/"); strcat(target_url, bname); } else if (e == NULL) gfs_stat_free(&gs); if (target_url == NULL) { target_url = strdup(gfarm_url); if (target_url == NULL) { fprintf(stderr, "not enough memory\n"); return (-1); } } if (executable_file) { /* register a binary executable. */ /* * In auto index case, node_index does not stand for * architecture. */ if (auto_index) node_index = NULL; if (node_index == NULL) { if (hostname == NULL) { char *self_name; e = gfarm_host_get_canonical_self_name( &self_name); if (e != NULL) { fprintf(stderr, "%s: %s\n", gfarm_host_get_self_name(), e); return (-1); } node_index = gfarm_host_info_get_architecture_by_host( self_name); } else { char *c_name; e = gfarm_host_get_canonical_name( hostname, &c_name); if (e != NULL) { fprintf(stderr, "%s: %s\n", hostname, e); return (-1); } node_index = gfarm_host_info_get_architecture_by_host( c_name); free(c_name); } } if (node_index == NULL) { fprintf(stderr, "%s: cannot determine the architecture " "of %s.\n", program_name, gfarm_host_get_self_name()); return (-1); } if (total_nodes <= 0) { if (gfs_pio_get_node_size(&total_nodes) != NULL) total_nodes = 1; } if (!opt_force) { struct gfs_stat s; if (gfs_stat_section(target_url, node_index, &s) == NULL) { gfs_stat_free(&s); e = "already exist"; goto finish; } } e = gfarm_url_fragment_register(target_url, node_index, GFARM_FILE_DONTCARE, hostname, filename); /* * XXX - gfarm_url_replicate() to replicate * 'total_nodes' copies of target_url. */ } else { char index_str[GFARM_INT32STRLEN + 1]; /* register a file fragment. */ if (node_index == NULL) { int index; e = gfs_pio_get_node_rank(&index); if (e != NULL) { fprintf(stderr, "%s: missing -I <Gfarm index>\n", program_name); return (-1); } sprintf(index_str, "%d", index); node_index = index_str; } if (total_nodes <= 0) { e = gfs_pio_get_node_size(&total_nodes); if (e != NULL) { fprintf(stderr, "%s: missing -N " "<total num of fragments>\n", program_name); return (-1); } } if (!opt_force) { struct gfs_stat s; if (gfs_stat_section(target_url, node_index, &s) == NULL) { gfs_stat_free(&s); e = "already exist"; goto finish; } } e = gfarm_url_fragment_register(target_url, node_index, total_nodes, hostname, filename); } finish: if (e != NULL) { fprintf(stderr, "%s: %s\n", target_url, e); return (-1); } free(target_url); return (0); }
static char * gfsck_dir(char *gfarm_dir, char *file) { char *e, *gfarm_url; struct gfs_stat gsb; GFS_Dir gdir; struct gfs_dirent *gdent; gfarm_url = malloc(strlen(gfarm_dir) + strlen(file) + 2); if (gfarm_url == NULL) return (GFARM_ERR_NO_MEMORY); if (gfarm_dir[0] == '\0') sprintf(gfarm_url, "%s", file); else if (strcmp(gfarm_dir, GFARM_URL_PREFIX) == 0) sprintf(gfarm_url, "%s%s", gfarm_dir, file); else sprintf(gfarm_url, "%s/%s", gfarm_dir, file); e = gfs_stat(gfarm_url, &gsb); if (e != NULL) { if (e == GFARM_ERR_NO_FRAGMENT_INFORMATION) { /* no fragment information, remove path info */ e = path_info_remove(gfarm_url, NULL); } free(gfarm_url); return (e); } if (GFARM_S_ISREG(gsb.st_mode)) { gfs_stat_free(&gsb); e = gfsck_file(gfarm_url); free(gfarm_url); return (e); } if (!GFARM_S_ISDIR(gsb.st_mode)) { gfs_stat_free(&gsb); free(gfarm_url); return ("unknown file type"); } gfs_stat_free(&gsb); e = gfs_opendir(gfarm_url, &gdir); if (e != NULL) { free(gfarm_url); return (e); } while ((e = gfs_readdir(gdir, &gdent)) == NULL && gdent != NULL) { if (gdent->d_name[0] == '.' && (gdent->d_name[1] == '\0' || (gdent->d_name[1] == '.' && gdent->d_name[2] == '\0'))) continue; /* "." or ".." */ e = gfsck_dir(gfarm_url, gdent->d_name); if (e != NULL) { fprintf(stderr, "%s%s%s: %s\n", gfarm_url, strcmp(gfarm_url, GFARM_URL_PREFIX) == 0 ? "" : "/", gdent->d_name, e); /* it is not necessary to save error */ } } (void)gfs_closedir(gdir); free(gfarm_url); return (NULL); }
int main(int argc, char *argv[]) { /* options */ char *section = NULL; int nfragments = GFARM_FILE_DONTCARE; /* -1, actually */ char *hostname = NULL; char *hostfile = NULL; char *domainname = NULL; char *e, *gfarm_url, *file_mode_arg; gfarm_mode_t file_mode = DEFAULT_FILE_MODE; int c, i, is_dir, index; struct gfs_stat gs; e = gfarm_initialize(&argc, &argv); if (e != NULL) { fprintf(stderr, "%s: %s\n", program_name, e); exit(EXIT_FAILURE); } /* Command options */ while ((c = getopt(argc, argv, "a:fh:D:I:N:?")) != -1) { switch (c) { case 'I': case 'a': section = optarg; break; case 'N': nfragments = strtol(optarg, NULL, 0); break; case 'h': hostname = optarg; break; case 'D': domainname = optarg; break; case 'f': opt_force = 1; break; case '?': default: usage(); } } argc -= optind; argv += optind; if (argc == 0) { fprintf(stderr, "%s: missing a local filename\n", program_name); usage(); } if (argc == 1) { fprintf(stderr, "%s: missing a Gfarm URL\n", program_name); usage(); } gfarm_url = argv[argc - 1]; --argc; if (!gfarm_is_url(gfarm_url)) { fprintf(stderr, "%s: %s: %s\n", program_name, gfarm_url, GFARM_ERR_GFARM_URL_PREFIX_IS_MISSING); exit(EXIT_FAILURE); } c = 0; if (hostname != NULL) c++; if (hostfile != NULL) c++; if (domainname != NULL) c++; if (c > 1) { fprintf(stderr, "%s: more than one options are specified " "from -h, -H and -D\n", program_name); usage(); } /* * distinguish which mode is specified: * 1. program mode: * gfreg [-h <hostname>] [-a <architecture>] \ * <local-program>... <gfarm-URL> * 2. auto index mode: * gfreg [-h <hostname>] [-H <hostfile>] [-D <domainname>] \ * <local-file>... <gfarm-URL> * 3. fragment mode: * gfreg [-h <hostname>] [-N <nfragments>] -I <index> \ * <local-file>... <gfarm-URL> */ e = gfs_stat(gfarm_url, &gs); if (e == GFARM_ERR_NO_SUCH_OBJECT) { is_dir = 0; file_mode_arg = NULL; } else if (e != NULL) { fprintf(stderr, "%s: %s: %s\n", program_name, gfarm_url, e); exit(EXIT_FAILURE); } else { if (GFARM_S_ISREG(gs.st_mode)) { is_dir = 0; file_mode_arg = gfarm_url; file_mode = gs.st_mode; } else if (GFARM_S_ISDIR(gs.st_mode)) { is_dir = 1; file_mode_arg = NULL; } else { /* defensive programming. this shouldn't happen. */ fprintf(stderr, "%s: %s: unknown file type\n", program_name, gfarm_url); exit(EXIT_FAILURE); } gfs_stat_free(&gs); } c = 0; /* count of "-" in the arguments */ if (hostfile != NULL && strcmp(hostfile, STDIN_FILENAME) == 0) ++c; for (i = 0; i < argc; i++) { int fd, fd_needs_close; gfarm_mode_t m; if (!open_file(argv[i], &fd, &fd_needs_close)) exit(EXIT_FAILURE); if (!get_mode(fd, argv[i], &m)) exit(EXIT_FAILURE); if (S_ISREG(m)) { if (file_mode_arg == NULL) { /* * NOTE: this mode may be used for the mode * to create the gfarm file. */ file_mode_arg = argv[i]; file_mode = m & FILE_MODE_MASK; } if (((m & 0111) != 0) != ((file_mode & 0111) != 0)) { fprintf(stderr, "%s: program and non-program are mixed in " "%s and %s\n", program_name, file_mode_arg, argv[i]); exit(EXIT_FAILURE); } } else if (fd_needs_close) { /* if it's "-", allow non-file (e.g. pipe) */ fprintf(stderr, "%s: %s: not a regular file\n", program_name, argv[i]); exit(EXIT_FAILURE); } if (fd_needs_close) { close(fd); } else if (++c > 1) { fprintf(stderr, "%s: `-' (stdin) is specified " "multiple times\n", program_name); exit(EXIT_FAILURE); } } if ((file_mode & 0111) != 0) { /* * program mode */ int section_alloced = 0; if (!is_dir && argc != 1) { fprintf(stderr, "%s: only one file can be specified to" " register the gfarm program `%s'\n", program_name, gfarm_url); exit(EXIT_FAILURE); } if (hostfile != NULL || domainname != NULL) { fprintf(stderr, "%s: cannot use -%c to register programs\n", program_name, hostfile != NULL ? 'H' : 'D'); exit(EXIT_FAILURE); } if (nfragments != GFARM_FILE_DONTCARE) { /* * XXX - call gfarm_url_replicate() to replicate * `nfragments' copies of gfarm_url:section? */ fprintf(stderr, "%s: warning: option -N is currently ignored\n", program_name); } if (section != NULL) { ; } else if (hostname != NULL) { char *canonical; e = gfarm_host_get_canonical_name(hostname, &canonical); if (e != NULL) { if (e == GFARM_ERR_NO_SUCH_OBJECT) e = "not a filesystem node"; fprintf(stderr, "%s: host %s: %s\n", program_name, hostname, e); exit(EXIT_FAILURE); } section_alloced = 1; section = gfarm_host_info_get_architecture_by_host( canonical); free(canonical); if (section == NULL) { fprintf(stderr, "%s: %s\n", program_name, GFARM_ERR_NO_MEMORY); exit(EXIT_FAILURE); } } else if (gfarm_host_get_self_architecture(§ion) != NULL){ fprintf(stderr, "%s: missing -a option\n", program_name); exit(EXIT_FAILURE); } for (i = 0; i < argc; i++) { register_program(is_dir, gfarm_url, section, hostname, argv[i], file_mode_arg == gfarm_url || file_mode_arg == argv[i], file_mode); } if (section_alloced) free(section); } else if (section != NULL || gfs_pio_get_node_rank(&index) == NULL) { /* * fragment mode */ if (section != NULL) index = strtol(section, NULL, 0); else if (nfragments == GFARM_FILE_DONTCARE) gfs_pio_get_node_size(&nfragments); if (!is_dir && argc != 1) { fprintf(stderr, "%s: only one file can be specified to" " register a fragment %s of the gfarm file `%s'\n", program_name, section, gfarm_url); exit(EXIT_FAILURE); } if (hostfile != NULL || domainname != NULL) { fprintf(stderr, "%s: cannot use -%c with -I\n", program_name, hostfile != NULL ? 'H' : 'D'); exit(EXIT_FAILURE); } for (i = 0; i < argc; i++) { register_fragment(is_dir, gfarm_url, index, nfragments, hostname, argv[i], file_mode_arg == gfarm_url || file_mode_arg == argv[i], file_mode); } } else { /* * auto index mode */ char **hosts = NULL; if (nfragments == GFARM_FILE_DONTCARE) nfragments = argc; if (nfragments != argc) { fprintf(stderr, "%s: local file number %d " "doesn't match with -N %d\n", program_name, argc, nfragments); exit(EXIT_FAILURE); } if (is_dir && nfragments > 1) { fprintf(stderr, "%s: cannot determine the file name " "under the directory %s, " "because multiple local file names are specifed\n", program_name, gfarm_url); exit(EXIT_FAILURE); } if (hostname != NULL) { ; } else if (hostfile != NULL) { int nhosts, error_line; e = gfarm_hostlist_read(hostfile, &nhosts, &hosts, &error_line); if (e != NULL) { if (error_line != -1) fprintf(stderr, "%s: %s line %d: %s\n", program_name, hostfile, error_line, e); else fprintf(stderr, "%s: %s: %s\n", program_name, hostfile, e); exit(EXIT_FAILURE); } } else { hosts = malloc(sizeof(*hosts) * nfragments); if (hosts == NULL) { fprintf(stderr, "%s: %s\n", program_name, GFARM_ERR_NO_MEMORY); exit(EXIT_FAILURE); } if (domainname != NULL) e = gfarm_schedule_search_idle_by_domainname( domainname, nfragments, hosts); else e = gfarm_schedule_search_idle_by_all( nfragments, hosts); if (e != NULL) { fprintf(stderr, "%s: selecting filesystem nodes: %s\n", program_name, e); exit(EXIT_FAILURE); } } /* XXX - need to register in parallel? */ for (i = 0; i < argc; i++) { register_fragment(is_dir, gfarm_url, i, nfragments, hostname != NULL ? hostname : hosts[i], argv[i], 1, file_mode); } if (hostname == NULL) gfarm_strings_free_deeply(nfragments, hosts); } e = gfarm_terminate(); if (e != NULL) { fprintf(stderr, "%s: %s\n", program_name, e); exit(EXIT_FAILURE); } exit(error_happened); }
static void remove_cwd_entries() { char *e; char cwdbf[PATH_MAX * 2]; int i; GFS_Dir dir; struct gfs_dirent *entry; gfarm_stringlist entry_list; e = gfs_getcwd(cwdbf, sizeof(cwdbf)); if (e != NULL) { fprintf(stderr, "%s\n", e); return; } e = gfs_opendir(".", &dir); if (e != NULL) { fprintf(stderr, "%s: %s\n", cwdbf, e); return; } e = gfarm_stringlist_init(&entry_list); if (e != NULL) { fprintf(stderr, "%s: %s\n", cwdbf, e); return; } while ((e = gfs_readdir(dir, &entry)) == NULL && entry != NULL) { char *p; if (entry->d_name[0] == '.' && (entry->d_name[1] == '\0' || (entry->d_name[1] == '.' && entry->d_name[2] == '\0'))) continue; /* "." or ".." */ p = strdup(entry->d_name); if (p == NULL) { fprintf(stderr, "%s\n", GFARM_ERR_NO_MEMORY); exit (1); } e = gfarm_stringlist_add(&entry_list, p); if (e != NULL) { fprintf(stderr, "%s/%s: %s\n", cwdbf, entry->d_name, e); } } if (e != NULL) fprintf(stderr, "%s: %s\n", cwdbf, e); gfs_closedir(dir); for (i = 0; i < gfarm_stringlist_length(&entry_list); i++) { struct gfs_stat gs; char *path = gfarm_stringlist_elem(&entry_list, i); e = gfs_stat(path, &gs); if (e != NULL) { fprintf(stderr, "%s/%s: %s\n", cwdbf, path, e); continue; } if (GFARM_S_ISREG(gs.st_mode)) { char *url; url = gfarm_url_prefix_add(path); if (url == NULL) { fprintf(stderr, "%s\n", GFARM_ERR_NO_MEMORY); exit (1); } e = gfs_unlink(url); if (e != NULL) fprintf(stderr, "%s/%s: %s\n", cwdbf, path, e); free(url); } else if (GFARM_S_ISDIR(gs.st_mode)) { e = gfs_chdir(path); if (e != NULL) { fprintf(stderr, "%s/%s: %s\n", cwdbf, path, e); continue; } remove_cwd_entries(); e = gfs_chdir(".."); if (e != NULL) { fprintf(stderr, "%s: %s\n", cwdbf, e); exit (1); } e = gfs_rmdir(path); if (e != NULL) fprintf(stderr, "%s/%s: %s\n", cwdbf, path, e); } gfs_stat_free(&gs); } gfarm_stringlist_free_deeply(&entry_list); }
static int fixfrag(char *pathname, const char *gfarm_prefix) { char *gfarm_url, *sec, *pname, *gfarm_file, *e; struct gfs_stat gst; int r = 1; gfarm_url = append_prefix_pathname(gfarm_prefix, pathname); if (gfarm_url == NULL) { print_errmsg(pathname, "not enough memory"); return (r); } /* divide into file and section parts. */ sec = &gfarm_url[strlen(gfarm_url) - 1]; pname = sec - strlen(pathname) + 1; while (sec > pname && *sec != '/') { if (*sec == ':') { *sec = '\0'; ++sec; break; } --sec; } if (sec == pname || *sec == '/') { print_errmsg(pathname, "invalid filename"); delete_invalid_file_or_directory(pathname); goto error_gfarm_url; } e = gfs_stat(gfarm_url, &gst); if (e == NULL) { if (!GFARM_S_ISREG(gst.st_mode)) { gfs_stat_free(&gst); print_errmsg(gfarm_url, "not a regular file"); delete_invalid_file_or_directory(pathname); goto error_gfarm_url; } gfs_stat_free(&gst); } else /* permit no fragment case */; e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) { print_errmsg_with_section(gfarm_url, sec, e); delete_invalid_file_or_directory(pathname); goto error_gfarm_url; } /* check whether the fragment is already registered. */ e = fixfrag_i(pathname, gfarm_file, sec); if (e != NULL) { if (e != GFARM_ERR_ALREADY_EXISTS) { print_errmsg_with_section(pathname, sec, e); delete_invalid_file_or_directory(pathname); goto error_gfarm_file; } else /* no message */; } else printf("%s (%s) on %s: fixed\n", gfarm_url, sec, gfarm_host_get_self_name()); r = 0; error_gfarm_file: free(gfarm_file); error_gfarm_url: free(gfarm_url); return (r); }