static gfarm_error_t create_hosthash_from_file(char *hostfile, int hashsize, struct gfarm_hash_table **hashp) { int error_line = -1, nhosts; gfarm_error_t e; char **hosts; if (hostfile == NULL) { *hashp = NULL; return (GFARM_ERR_NO_ERROR); } e = gfarm_hostlist_read(hostfile, &nhosts, &hosts, &error_line); if (e != GFARM_ERR_NO_ERROR) { if (error_line != -1) fprintf(stderr, "%s: line %d: %s\n", hostfile, error_line, gfarm_error_string(e)); else fprintf(stderr, "%s: %s\n", hostfile, gfarm_error_string(e)); exit(EXIT_FAILURE); } e = create_hash_table_from_string_list(nhosts, hosts, HOSTHASH_SIZE, hashp); gfarm_strings_free_deeply(nhosts, hosts); return (e); }
static void file_info_free(struct file_info *info) { free(info->pathname); if (info->copy != NULL) gfarm_strings_free_deeply(info->ncopy, info->copy); free(info); }
static gfarm_error_t create_hostlist_by_domain_and_hash(struct file_info *finfo, char *domain, struct gfarm_hash_table *hosthash, int *nhostsp, char ***hostsp, int **portsp) { int ninfo, i, j, *ports, nhosts; struct gfarm_host_sched_info *infos; char **hosts; gfarm_error_t e; e = schedule_host_domain(finfo->pathname, domain, &ninfo, &infos); if (e != GFARM_ERR_NO_ERROR) return (e); /* sort 'infos' in descending order wrt available capacity */ qsort(infos, ninfo, sizeof(*infos), compare_available_capacity_r); /* eliminate file system nodes that do not have enough space */ for (i = 0; i < ninfo; ++i) /* note that disk_avail is the number of 1K blocks */ if (infos[i].disk_avail * 1024 < gfarm_get_minimum_free_disk_space()) break; nhosts = i; /* XXX - abandon CPU load and available capacity */ GFARM_MALLOC_ARRAY(hosts, nhosts); if (hosts == NULL) { gfarm_host_sched_info_free(ninfo, infos); return (GFARM_ERR_NO_MEMORY); } GFARM_MALLOC_ARRAY(ports, nhosts); if (ports == NULL) { free(hosts); gfarm_host_sched_info_free(ninfo, infos); return (GFARM_ERR_NO_MEMORY); } for (i = 0, j = 0; i < nhosts; ++i) { char *host = infos[i].host; if (hosthash == NULL || gfarm_hash_lookup(hosthash, host, strlen(host) + 1)) { hosts[j] = strdup(host); ports[j] = infos[i].port; if (hosts[j] == NULL) { gfarm_strings_free_deeply(j, hosts); return (GFARM_ERR_NO_MEMORY); } ++j; } } gfarm_host_sched_info_free(ninfo, infos); *hostsp = hosts; *portsp = ports; *nhostsp = j; return (e); }
char * gfarm_url_hosts_schedule(const char *gfarm_url, char *option, int *nhostsp, char ***hostsp) { char *e, *gfarm_file, **hosts; int i, nfrags, n_all_hosts; struct gfarm_host_info *all_hosts; struct gfarm_hash_table *hosts_state; char section[GFARM_INT32STRLEN + 1]; e = gfarm_url_fragment_number(gfarm_url, &nfrags); if (e != NULL) return (e); e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) return (e); hosts = malloc(sizeof(char *) * nfrags); if (hosts == NULL) { free(gfarm_file); return (GFARM_ERR_NO_MEMORY); } e = alloc_hosts_state(&n_all_hosts, &all_hosts, &hosts_state); if (e != NULL) { free(hosts); free(gfarm_file); return (e); } for (i = 0; i < nfrags; i++) { sprintf(section, "%d", i); e = schedule_by_file_section(hosts_state, gfarm_file, section, &null_filter, 1, &hosts[i]); if (e != NULL) { free_hosts_state(n_all_hosts, all_hosts, hosts_state); gfarm_strings_free_deeply(i, hosts); free(gfarm_file); return (e); } } free_hosts_state(n_all_hosts, all_hosts, hosts_state); free(gfarm_file); *nhostsp = nfrags; *hostsp = hosts; return (NULL); }
static gfarm_error_t gfarm_list_add_file_info(char *pathname, gfarm_off_t filesize, int ncopy, char **copy, int surplus, gfarm_list *list) { struct file_info *info; gfarm_error_t e; int i; info = file_info_alloc(); if (info == NULL) return (GFARM_ERR_NO_MEMORY); info->pathname = strdup(pathname); if (info->pathname == NULL) { file_info_free(info); return (GFARM_ERR_NO_MEMORY); } GFARM_MALLOC_ARRAY(info->copy, ncopy); if (info->copy == NULL) { file_info_free(info); return (GFARM_ERR_NO_MEMORY); } for (i = 0; i < ncopy; ++i) { info->copy[i] = strdup(copy[i]); if (info->copy[i] == NULL) { gfarm_strings_free_deeply(i, info->copy); info->copy = NULL; file_info_free(info); return (GFARM_ERR_NO_ERROR); } } info->ncopy = ncopy; info->filesize = filesize; info->surplus_ncopy = surplus; e = gfarm_list_add(list, info); if (e != GFARM_ERR_NO_ERROR) file_info_free(info); return (e); }
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); }
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); }
int main(int argc, char *argv[]) { char *src_hostfile = NULL, *dst_hostfile = NULL; gfarm_stringlist paths; gfs_glob_t types; int mode_src_ch = 0, mode_dst_ch = 0, parallel = -1; int i, ch; gfarm_error_t e; const char *errmsg, *errmsg2 = NULL; struct gfrep_arg gfrep_arg; struct flist flist; if (argc >= 1) program_name = basename(argv[0]); memset(&gfrep_arg, 0, sizeof(gfrep_arg)); memset(&flist, 0, sizeof(flist)); flist.src_domain = ""; flist.dst_domain = ""; e = gfarm_initialize(&argc, &argv); error_check(e); #ifdef _OPENMP while ((ch = getopt(argc, argv, "h:j:mnqvxS:D:H:N:?")) != -1) { #else while ((ch = getopt(argc, argv, "h:mnqvxS:D:H:N:?")) != -1) { #endif switch (ch) { case 'h': src_hostfile = optarg; conflict_check(&mode_src_ch, ch); break; #ifdef _OPENMP case 'j': parallel = strtol(optarg, NULL, 0); break; #endif case 'm': act = &migrate_mode; break; case 'n': opt_noexec = 1; break; case 'q': opt_quiet = 1; break; case 'v': opt_verbose = 1; break; case 'x': opt_remove = 1; break; case 'S': flist.src_domain = optarg; conflict_check(&mode_src_ch, ch); break; case 'D': flist.dst_domain = optarg; conflict_check(&mode_dst_ch, ch); break; case 'H': dst_hostfile = optarg; conflict_check(&mode_dst_ch, ch); break; case 'N': opt_nrep = strtol(optarg, NULL, 0); break; case '?': default: usage(); } } argc -= optind; argv += optind; /* make writing-to-stderr atomic, for GfarmFS-FUSE log output */ setvbuf(stderr, NULL, _IOLBF, 0); if (!opt_quiet) { printf("constructing file list..."); fflush(stdout); } e = gfarm_stringlist_init(&paths); if (e == GFARM_ERR_NO_ERROR) { e = gfs_glob_init(&types); if (e == GFARM_ERR_NO_ERROR) { for (i = 0; i < argc; i++) gfs_glob(argv[i], &paths, &types); gfs_glob_free(&types); } } error_check(e); e = gfarm_list_init(&flist.slist); error_check(e); e = gfarm_list_init(&flist.dlist); error_check(e); flist.srchash = gfarm_hash_table_alloc(HOSTHASH_SIZE, gfarm_hash_casefold, gfarm_hash_key_equal_casefold); if (flist.srchash == NULL) error_check(GFARM_ERR_NO_MEMORY); e = create_hosthash_from_file(src_hostfile, HOSTHASH_SIZE, &flist.src_hosthash); error_check(e); e = create_hosthash_from_file(dst_hostfile, HOSTHASH_SIZE, &flist.dst_hosthash); error_check(e); for (i = 0; i < gfarm_stringlist_length(&paths); i++) { char *file = gfarm_stringlist_elem(&paths, i), *realpath = NULL; e = gfarm_realpath_by_gfarm2fs(file, &realpath); if (e == GFARM_ERR_NO_ERROR) file = realpath; e = gfarm_foreach_directory_hierarchy( create_filelist, NULL, NULL, file, &flist); free(realpath); if (e != GFARM_ERR_NO_ERROR) break; } gfarm_stringlist_free_deeply(&paths); error_check(e); if (!opt_quiet) printf(" done\n"); if (opt_verbose) { printf("files to be replicated\n"); print_file_list(&flist.slist); } if (opt_verbose && opt_remove) { printf("files having too many replicas\n"); print_file_list(&flist.dlist); } if (gfarm_list_length(&flist.slist) <= 0 && (!opt_remove || gfarm_list_length(&flist.dlist) <= 0)) exit(0); /* no file */ /* replicate files */ e = gfarm_hash_to_string_array( flist.srchash, &gfrep_arg.nsrc, &gfrep_arg.src); error_check(e); gfarm_hash_table_free(flist.srchash); if (!opt_quiet) { printf("investigating hosts..."); fflush(stdout); } e = create_hostlist_by_domain_and_hash( gfarm_list_length(&flist.slist) > 0 ? gfarm_list_elem(&flist.slist, 0) : gfarm_list_elem(&flist.dlist, 0), flist.dst_domain, flist.dst_hosthash, &gfrep_arg.ndst, &gfrep_arg.dst, &gfrep_arg.dst_port); error_check(e); if (!opt_quiet) printf(" done\n"); errmsg = pfor_list(act, &flist.slist, parallel, &gfrep_arg); gfarm_list_free(&flist.slist); /* remove file replicas */ if (opt_remove) errmsg2 = pfor_list( &remove_mode, &flist.dlist, parallel, &gfrep_arg); gfarm_list_free(&flist.dlist); if (errmsg == NULL) errmsg = errmsg2; if (errmsg != NULL) fprintf(stderr, "%s\n", errmsg), exit(EXIT_FAILURE); gfarm_strings_free_deeply(gfrep_arg.nsrc, gfrep_arg.src); gfarm_strings_free_deeply(gfrep_arg.ndst, gfrep_arg.dst); free(gfrep_arg.dst_port); e = gfarm_terminate(); error_check(e); return (0); }
static gfarm_error_t create_filelist(char *file, struct gfs_stat *st, void *arg) { struct flist *a = arg; int i, j, ncopy, src_ncopy = 0, dst_ncopy = 0; char **copy; gfarm_error_t e; if (!GFARM_S_ISREG(st->st_mode)) { if (opt_verbose) printf("%s: not a regular file, skipped\n", file); return (GFARM_ERR_NO_ERROR); } e = gfs_replica_list_by_name(file, &ncopy, ©); if (e != GFARM_ERR_NO_ERROR) return (e); /* if there is no available file replica, display error message */ if (ncopy == 0 && st->st_size > 0) { fprintf(stderr, "%s: no available file repilca\n", file); e = GFARM_ERR_NO_ERROR; goto free_copy; } for (i = 0; i < ncopy; ++i) { if ((a->src_hosthash == NULL || gfarm_hash_lookup( a->src_hosthash, copy[i], strlen(copy[i]) + 1)) && gfarm_host_is_in_domain(copy[i], a->src_domain)) { ++src_ncopy; } if ((a->dst_hosthash == NULL || gfarm_hash_lookup( a->dst_hosthash, copy[i], strlen(copy[i]) + 1)) && gfarm_host_is_in_domain(copy[i], a->dst_domain)) { ++dst_ncopy; } } /* * if there is no replica in a set of source nodes or there * are already specified number of replicas in a set of * destination nodes, do not add. */ if (src_ncopy == 0 || dst_ncopy == opt_nrep) { e = GFARM_ERR_NO_ERROR; goto free_copy; } /* add source nodes to srchash to count the number of source nodes */ for (i = 0; i < ncopy; ++i) { char *s = copy[i]; if ((a->src_hosthash == NULL || gfarm_hash_lookup( a->src_hosthash, s, strlen(s) + 1)) && gfarm_host_is_in_domain(s, a->src_domain)) gfarm_hash_enter(a->srchash, s, strlen(s)+1, 0, NULL); } /* add a file info to slist */ for (j = 0; j < opt_nrep - dst_ncopy; ++j) { e = gfarm_list_add_file_info(file, st->st_size, ncopy, copy, 0, &a->slist); if (e != GFARM_ERR_NO_ERROR) goto free_copy; } /* add a file info to dlist if too many file replicas exist */ if (dst_ncopy > opt_nrep) { e = gfarm_list_add_file_info(file, st->st_size, ncopy, copy, dst_ncopy - opt_nrep, &a->dlist); } free_copy: gfarm_strings_free_deeply(ncopy, copy); return (e); }
char * gfs_unlink_section_replica(const char *gfarm_url, const char *section, int nreplicas, char **replica_hosts, int force) { char *e, *e_save = NULL; char *gfarm_file, **replica_canonical_hostnames; int i, j, ncopies, ndeletes; struct gfarm_file_section_copy_info *copies; char *do_delete; int remove_section_info = 0; e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) goto finish; e = gfarm_file_section_copy_info_get_all_by_section( gfarm_file, section, &ncopies, &copies); if (e != NULL) { if (e == GFARM_ERR_NO_SUCH_OBJECT && force) /* * filesystem metadata should be collapsed. * Ignore the previous error and delete the * section information. */ e = gfarm_file_section_info_remove( gfarm_file, section); goto finish_gfarm_file; } if (ncopies == 0) { /* assert(0); */ e = "gfs_unlink_section_replica: no file replica"; goto finish_copies; } do_delete = malloc(ncopies); if (do_delete == NULL) { e = GFARM_ERR_NO_MEMORY; goto finish_copies; } memset(do_delete, 0, ncopies); e = gfarm_host_get_canonical_names(nreplicas, replica_hosts, &replica_canonical_hostnames); if (e != NULL) goto finish_do_delete; ndeletes = 0; for (i = 0; i < nreplicas; i++) { for (j = 0; j < ncopies; j++) { if (strcasecmp(replica_canonical_hostnames[i], copies[j].hostname) == 0) { if (do_delete[j]) { e = "gfs_unlink_section_replica: " "duplicate hostname"; if (e_save == NULL) e_save = e; /* do not finish, but continue */ continue; } do_delete[j] = 1; ndeletes++; break; } } if (j >= ncopies && e_save == NULL) { e_save = "gfs_unlink_section_replica: " "no file replica on the host"; /* do not finish, but continue */ } } if (ndeletes == ncopies) { if (force == 0) { e_save = "gfs_unlink_section_replica: cannot remove all replicas"; goto finish_replica_canonical_hostnames; } else remove_section_info = 1; } for (j = 0; j < ncopies; j++) { if (!do_delete[j]) continue; e = gfs_unlink_replica_internal(gfarm_file, section, copies[j].hostname); if (e != NULL) { if (e_save == NULL) e_save = e; continue; } } if (remove_section_info) { int ncps; struct gfarm_file_section_copy_info *cps; e = gfarm_file_section_copy_info_get_all_by_section( gfarm_file, section, &ncps, &cps); if (e == GFARM_ERR_NO_SUCH_OBJECT) /* Oh, there is no section copy info. */ /* Some filesystem nodes might be down. */ e = gfarm_file_section_info_remove( gfarm_file, section); else if (e == NULL) gfarm_file_section_copy_info_free_all(ncps, cps); if (e != NULL) { if (e_save == NULL) e_save = e; } } finish_replica_canonical_hostnames: gfarm_strings_free_deeply(nreplicas, replica_canonical_hostnames); finish_do_delete: free(do_delete); finish_copies: gfarm_file_section_copy_info_free_all(ncopies, copies); finish_gfarm_file: free(gfarm_file); finish: return (e_save != NULL ? e_save : e); }
int main(int argc, char *argv[]) { char *gfarm_url, *node_index = NULL; char *hostname = NULL, **auto_hosts = NULL, *domainname = NULL, *e; int total_nodes = -1, c, auto_index = 0; extern char *optarg; extern int optind; e = gfarm_initialize(&argc, &argv); if (e != NULL) { fprintf(stderr, "%s: %s\n", program_name, e); exit(1); } /* Command options */ while ((c = getopt(argc, argv, "a:fh:D:I:N:")) != -1) { switch (c) { case 'I': case 'a': node_index = optarg; break; case 'N': total_nodes = 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(); } if ((argc > 2 || hostname == NULL) && (argc > 1 && total_nodes < 0 && node_index == NULL)) { total_nodes = argc - 1; auto_index = 1; if (hostname != NULL) fprintf(stderr, "%s: warning: -h option is ignored\n", program_name); auto_hosts = malloc(total_nodes * sizeof(char *)); if (auto_hosts != NULL) { if (domainname != NULL) e = gfarm_schedule_search_idle_by_domainname( domainname, total_nodes, auto_hosts); else e = gfarm_schedule_search_idle_by_all( total_nodes, auto_hosts); if (e != NULL) { free(auto_hosts); auto_hosts = NULL; } } } gfarm_url = argv[argc - 1]; while (--argc) { char index_str[GFARM_INT32STRLEN + 1]; /* XXX - need to register in parallel? */ if (auto_index) { sprintf(index_str, "%d", total_nodes - argc); node_index = index_str; if (auto_hosts != NULL) hostname = auto_hosts[total_nodes - argc]; } if (gfarm_register_file(gfarm_url, node_index, hostname, total_nodes, *argv++, auto_index)) break; } if (auto_hosts != NULL) gfarm_strings_free_deeply(total_nodes, auto_hosts); e = gfarm_terminate(); if (e != NULL) { fprintf(stderr, "%s: %s\n", program_name, e); exit(1); } exit(0); }
static char * url_hosts_schedule_filtered(struct gfarm_hash_table *hosts_state, char *gfarm_url, char *option, int nihosts, struct string_filter *ihost_filter, struct get_next_iterator *ihost_iterator, int *nhostsp, char ***hostsp) { char *e, *gfarm_file, **hosts, **residual; int i, nfrags, shortage; char section[GFARM_INT32STRLEN + 1]; e = gfarm_url_fragment_number(gfarm_url, &nfrags); if (e != NULL) return (e); e = gfarm_url_make_path(gfarm_url, &gfarm_file); if (e != NULL) return (e); hosts = malloc(sizeof(char *) * nfrags); if (hosts == NULL) { free(gfarm_file); return (GFARM_ERR_NO_MEMORY); } shortage = 0; for (i = 0; i < nfrags; i++) { sprintf(section, "%d", i); e = schedule_by_file_section(hosts_state, gfarm_file, section, ihost_filter, 1, &hosts[i]); if (e == GFARM_ERR_NO_HOST) { hosts[i] = NULL; shortage++; continue; } if (e != NULL) { gfarm_strings_free_deeply(i, hosts); free(gfarm_file); return (e); } } if (shortage > 0) { residual = malloc(shortage * sizeof(*residual)); if (residual == NULL) { gfarm_strings_free_deeply(nfrags, hosts); free(gfarm_file); return (GFARM_ERR_NO_MEMORY); } e = search_idle_cyclic(hosts_state, nihosts, ihost_filter, ihost_iterator, shortage, residual); if (e == NULL) e = gfarm_fixedstrings_dup(shortage,residual,residual); if (e != NULL) { free(residual); gfarm_strings_free_deeply(nfrags, hosts); free(gfarm_file); return (e); } for (i = 0; i < nfrags; i++) { if (hosts[i] == NULL) { hosts[i] = residual[--shortage]; if (shortage == 0) break; } } free(residual); } *nhostsp = nfrags; *hostsp = hosts; free(gfarm_file); return (e); }
char * gfarm_url_fragments_replicate(char *gfarm_url, int ndsthosts, char **dsthosts) { char *e, *gfarm_file, **srchosts, **edsthosts; int nsrchosts; gfarm_mode_t mode; int i, pid, *pids; struct gfarm_path_info pi; 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) goto finish_gfarm_file; mode = pi.status.st_mode; gfarm_path_info_free(&pi); if (!GFARM_S_IS_FRAGMENTED_FILE(mode)) { e = GFARM_ERR_OPERATION_NOT_PERMITTED; goto finish_gfarm_file; } /* * XXX - if the owner of a file is not the same, permit a * group/other write access - This should be fixed in the next * major release. */ if (strcmp(pi.status.st_user, gfarm_get_global_username()) != 0) { e = gfarm_path_info_access(&pi, GFS_R_OK); if (e != NULL) { gfarm_path_info_free(&pi); free(gfarm_file); return (e); } mode |= 022; } e = gfarm_url_hosts_schedule(gfarm_url, "", &nsrchosts, &srchosts); if (e != NULL) goto finish_gfarm_file; edsthosts = malloc(sizeof(*edsthosts) * nsrchosts); if (edsthosts == NULL) { e = GFARM_ERR_NO_MEMORY; goto finish_srchosts; } gfarm_strings_expand_cyclic(ndsthosts, dsthosts, nsrchosts, edsthosts); pids = malloc(sizeof(int) * nsrchosts); if (pids == NULL) { e = GFARM_ERR_NO_MEMORY; goto finish_edsthosts; } /* * To use different connection for each metadb access. * * XXX: FIXME layering violation */ e = gfarm_metadb_terminate(); if (e != NULL) goto finish_pids; for (i = 0; i < nsrchosts; i++) { struct sockaddr peer_addr; char *if_hostname; char section_string[GFARM_INT32STRLEN + 1]; struct gfarm_file_section_info si; pid = fork(); if (pid < 0) break; if (pid) { /* parent */ pids[i] = pid; continue; } /* child */ /* * use different connection for each metadb access. * * XXX: FIXME layering violation */ e = gfarm_metadb_initialize(); if (e != NULL) _exit(1); /* reflect "address_use" directive in the `srchosts[i]' */ e = gfarm_host_address_get(srchosts[i], gfarm_spool_server_port, &peer_addr, &if_hostname); if (e != NULL) _exit(2); sprintf(section_string, "%d", i); e = gfarm_file_section_info_get(gfarm_file, section_string, &si); if (e != NULL) _exit(3); e = gfarm_file_section_replicate_from_to_internal( gfarm_file, section_string, mode & GFARM_S_ALLPERM, si.filesize, srchosts[i], if_hostname, edsthosts[i]); if (e != NULL) _exit(1); _exit(0); } while (--i >= 0) { int rv, s; while ((rv = waitpid(pids[i], &s, 0)) == -1 && errno == EINTR) ; if (rv == -1) { if (e == NULL) e = gfarm_errno_to_error(errno); } else if (WIFEXITED(s) && WEXITSTATUS(s) != 0) { e = "error happens on replication"; } } /* * recover temporary closed metadb connection * * XXX: FIXME layering violation */ if (e != NULL) { gfarm_metadb_initialize(); } else { e = gfarm_metadb_initialize(); } finish_pids: free(pids); finish_edsthosts: free(edsthosts); finish_srchosts: gfarm_strings_free_deeply(nsrchosts, srchosts); finish_gfarm_file: free(gfarm_file); return (e); }
char * gfarm_url_program_deliver(const char *gfarm_url, int nhosts, char **hosts, char ***delivered_paths) { char *e, **dp, *gfarm_file, *root, *arch, **canonical_hostnames; gfarm_mode_t mode; int i; struct gfarm_path_info pi; 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); } mode = pi.status.st_mode; if (!GFARM_S_IS_PROGRAM(mode)) { gfarm_path_info_free(&pi); free(gfarm_file); return ("gfarm_url_program_deliver(): not a program"); } /* * XXX - if the owner of a file is not the same, permit a * group/other write access - This should be fixed in the next * major release. */ if (strcmp(pi.status.st_user, gfarm_get_global_username()) != 0) { e = gfarm_path_info_access(&pi, GFS_X_OK); if (e != NULL) { gfarm_path_info_free(&pi); free(gfarm_file); return (e); } mode |= 022; } gfarm_path_info_free(&pi); dp = malloc(sizeof(char *) * (nhosts + 1)); if (dp == NULL) { free(gfarm_file); return (GFARM_ERR_NO_MEMORY); } dp[nhosts] = NULL; e = gfarm_host_get_canonical_names(nhosts, hosts, &canonical_hostnames); if (e != NULL) { free(dp); free(gfarm_file); return (e); } /* XXX - this is too slow */ for (i = 0; i < nhosts; i++) { struct sockaddr peer_addr; struct gfs_connection *gfs_server; struct gfarm_file_section_info si; dp[i] = NULL; /* for error handling */ arch = gfarm_host_info_get_architecture_by_host( canonical_hostnames[i]); if (arch == NULL) { /* architecture of the hosts[i] is not registered */ e = "cannot deliver program to an unregistered host"; goto error; } /* XXX - which to use? `hosts[i]' vs `copies[j].hostname' */ e = gfarm_host_address_get(hosts[i], gfarm_spool_server_port, &peer_addr, NULL); if (e != NULL) { free(arch); goto error; } e = gfs_client_connection(canonical_hostnames[i], &peer_addr, &gfs_server); if (e != NULL) { free(arch); goto error; } e = gfs_client_get_spool_root(gfs_server, &root); if (e != NULL) { free(arch); goto error; } e = gfarm_full_path_file_section(root, gfarm_file, arch, &dp[i]); free(root); if (e != NULL) { free(arch); goto error; } e = gfarm_file_section_info_get(gfarm_file, arch, &si); if (e != NULL) { free(arch); goto error; } /* * replicate the program */ e = gfarm_file_section_replicate_to_internal(gfarm_file, arch, mode & GFARM_S_ALLPERM, si.filesize, hosts[i]); gfarm_file_section_info_free(&si); free(arch); if (e != NULL) goto error; } gfarm_strings_free_deeply(nhosts, canonical_hostnames); free(gfarm_file); *delivered_paths = dp; return (NULL); error: gfarm_strings_free_deeply(nhosts, canonical_hostnames); free(gfarm_file); gfarm_strings_free_deeply(i + 1, dp); *delivered_paths = NULL; return (e); }
char * gfarm_file_section_replicate_multiple_request( gfarm_stringlist *gfarm_file_list, gfarm_stringlist *section_list, char *src_canonical, char *dst_canonical, struct gfs_client_rep_backend_state **statep) { char *e, **gfrep_backend_client_paths; struct sockaddr peer_addr; long parallel_streams, stripe_unit_size; long file_sync_stripe, send_stripe_sync, recv_stripe_sync; struct gfs_client_rep_backend_state *state; struct xxx_connection *from_server, *to_server; int replication_method_save; if (gfarm_stringlist_length(gfarm_file_list) != gfarm_stringlist_length(section_list)) return ("number of files isn't equal to number of sections"); /* * netparam is evaluated here rather than in gfsd, * so, settings in user's .gfarmrc can be reflected. * * XXX - but this also means that settings in frontend host * is used, rather than settings in the host which does * actual transfer. */ e = gfarm_host_address_get(src_canonical, gfarm_spool_server_port, &peer_addr, NULL); if (e != NULL) return (e); e = gfarm_netparam_config_get_long( &gfarm_netparam_parallel_streams, src_canonical, (struct sockaddr *)&peer_addr, ¶llel_streams); if (e != NULL) /* shouldn't happen */ return (e); e = gfarm_netparam_config_get_long( &gfarm_netparam_stripe_unit_size, src_canonical, (struct sockaddr *)&peer_addr, &stripe_unit_size); if (e != NULL) /* shouldn't happen */ return (e); e = gfarm_netparam_config_get_long( &gfarm_netparam_file_sync_stripe, src_canonical, (struct sockaddr *)&peer_addr, &file_sync_stripe); if (e != NULL) /* shouldn't happen */ return (e); e = gfarm_netparam_config_get_long( &gfarm_netparam_send_stripe_sync, src_canonical, (struct sockaddr *)&peer_addr, &send_stripe_sync); if (e != NULL) /* shouldn't happen */ return (e); e = gfarm_netparam_config_get_long( &gfarm_netparam_recv_stripe_sync, src_canonical, (struct sockaddr *)&peer_addr, &recv_stripe_sync); if (e != NULL) /* shouldn't happen */ return (e); replication_method_save = gfarm_replication_get_method(); gfarm_replication_set_method(GFARM_REPLICATION_BOOTSTRAP_METHOD); e = gfarm_url_program_deliver(gfrep_backend_client, 1, &dst_canonical, &gfrep_backend_client_paths); gfarm_replication_set_method(GFARM_REPLICATION_BOOTSTRAP_METHOD); if (e != NULL) return (e); e = gfs_client_rep_backend_invoke(dst_canonical, gfrcmd_local_path, gfrep_backend_client_paths[0], src_canonical, -1, parallel_streams, stripe_unit_size, file_sync_stripe, send_stripe_sync, recv_stripe_sync, "gfarm_file_section_replicate_multiple_request()", &from_server, &to_server, &state); gfarm_strings_free_deeply(1, gfrep_backend_client_paths); if (e != NULL) return (e); state->n = gfarm_stringlist_length(gfarm_file_list); e = gfs_client_rep_filelist_send(src_canonical, state->out, "gfarm_file_section_replicate_multiple_request()", state->n, gfarm_file_list, section_list); if (e != NULL) { gfs_client_rep_backend_kill(state); return (e); } *statep = state; return (NULL); }