示例#1
0
文件: gfrep.c 项目: ddk50/gfarm_v2
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);
}
示例#2
0
文件: gfrep.c 项目: ddk50/gfarm_v2
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);
}
示例#3
0
文件: gfrep.c 项目: ddk50/gfarm_v2
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);
}
示例#4
0
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);
}
示例#5
0
文件: gfrep.c 项目: ddk50/gfarm_v2
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);
}
示例#6
0
文件: gfreg.c 项目: krichter722/gfarm
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(&section) != 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);
}
示例#7
0
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);
}
示例#8
0
文件: gfrep.c 项目: ddk50/gfarm_v2
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);
}
示例#9
0
文件: gfrep.c 项目: ddk50/gfarm_v2
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, &copy);
	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);
}
示例#10
0
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);	
}
示例#11
0
文件: gfreg.c 项目: krichter722/gfarm
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);
}
示例#12
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);
}
示例#13
0
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);
}
示例#14
0
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);
}
示例#15
0
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,
	    &parallel_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);
}