예제 #1
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);
}
예제 #2
0
파일: gfexec.c 프로젝트: krichter722/gfarm
int
main(int argc, char *argv[], char *envp[])
{
	char *e, *gfarm_url, *local_path, **new_env, *cwd_env, *pwd_env;
	int i, j, status, envc, rank = -1, nodes = -1;
	pid_t pid;
	static const char env_node_rank[] = "GFARM_NODE_RANK=";
	static const char env_node_size[] = "GFARM_NODE_SIZE=";
	static const char env_flags[] = "GFARM_FLAGS=";
	static const char env_gfs_pwd[] = "GFS_PWD=";
	static const char env_pwd[] = "PWD=";
	char rankbuf[sizeof(env_node_rank) + GFARM_INT64STRLEN];
	char nodesbuf[sizeof(env_node_size) + GFARM_INT64STRLEN];
	char flagsbuf[sizeof(env_flags) + 3];
	char cwdbuf[PATH_MAX * 2], pwdbuf[PATH_MAX * 2];

	e = gfarm_initialize(&argc, &argv);
	if (e != NULL) {
		errmsg("gfarm_initialize", e);
		exit(1);
	}

	/*
	 * don't use getopt(3) here, because getopt(3) in glibc refers
	 * argv[] passed to main(), instead of argv[] passed to getopt(3).
	 */
	for (i = 1; i < argc; i++) {
		if (argv[i][0] != '-')
			break;
		for (j = 1; argv[i][j] != '\0'; j++) {
			switch (argv[i][j]) {
			case 'I':
				if (argv[i][j + 1] != '\0') {
					rank = strtol(&argv[i][j+1], NULL, 0);
					j += strlen(&argv[i][j + 1]);
				} else if (i + 1 < argc) {
					rank = strtol(argv[++i], NULL, 0);
					j = strlen(argv[i]) - 1;
				} else {
					errmsg("-I", "missing argument");
					print_usage();
				}
				break;
			case 'N':
				if (argv[i][j + 1] != '\0') {
					nodes = strtol(&argv[i][j+1], NULL, 0);
					j += strlen(&argv[i][j + 1]);
				} else if (i + 1 < argc) {
					nodes = strtol(argv[++i], NULL, 0);
					j = strlen(argv[i]) - 1;
				} else {
					errmsg("-N", "missing argument");
					print_usage();
				}
				break;
			case 's':
				rank = 0;
				nodes = 1;
				break;
			case 'h':
			case '?':
				print_usage();
			default:
				fprintf(stderr, "%s: invalid option -- %c\n",
				    progname, argv[i][j]);
				print_usage();
			}
		}
	}
	argc -= i;
	argv += i;
	if (argc == 0)
		print_usage();

	e = gfs_realpath(argv[0], &gfarm_url);
	if (e != NULL) {
		/* XXX check `e' */
		local_path = search_path(argv[0]);
	} else {
		e = gfarm_url_program_get_local_path(gfarm_url, &local_path);
		if (e != NULL) {
			errmsg(gfarm_url, e);
			exit(1);
		}
	}

	e = modify_ld_library_path();
	if (e != NULL) {
		errmsg("modify_ld_library_path", e);
		/* continue */
	}

	/*
	 * the followings are only needed for pid==0 case.
	 * but isn't it better to check errors before fork(2)?
	 *
	 * If gfs_pio_get_node_{rank,size}() fails, continue to
	 * execute as a single process (not parallel processes).
	 */
	if (rank == -1) {
		e = gfs_pio_get_node_rank(&rank);
		if (e != NULL)
			rank = 0;
	}
	if (nodes == -1) {
		e = gfs_pio_get_node_size(&nodes);
		if (e != NULL)
			nodes = 1;
	}
	for (envc = 0; envp[envc] != NULL; envc++)
		;
	new_env = malloc(sizeof(*new_env) * (envc + 5 + 1));
	memcpy(cwdbuf, GFARM_URL_PREFIX, GFARM_URL_PREFIX_LENGTH);
	e = gfs_getcwd(cwdbuf + GFARM_URL_PREFIX_LENGTH,
		sizeof(cwdbuf) - GFARM_URL_PREFIX_LENGTH);
	if (e != NULL) {
		errmsg("cannot get current directory", e);
		exit(1);
	}
	if ((cwd_env = malloc(strlen(cwdbuf) + sizeof(env_gfs_pwd))) == NULL) {
		fprintf(stderr, "%s: no memory for %s%s\n",
		    progname, env_gfs_pwd, cwdbuf);
		exit(1);
	}
	(void)chdir(cwdbuf); /* rely on syscall hook. it is ok if it fails */
	getcwd(pwdbuf, sizeof pwdbuf);
	pwd_env = malloc(strlen(pwdbuf) + sizeof(env_pwd));
	if (pwd_env == NULL) {
		fprintf(stderr, "%s: no memory for %s%s\n",
		    progname, env_pwd, pwdbuf);
		exit(1);
	}
	envc = 0;
	for (i = 0; (e = envp[i]) != NULL; i++) {
		if (memcmp(e, env_node_rank, sizeof(env_node_rank) -1 ) != 0 &&
		    memcmp(e, env_node_size, sizeof(env_node_size) -1 ) != 0 &&
		    memcmp(e, env_flags, sizeof(env_flags) - 1 ) != 0 &&
		    memcmp(e, env_gfs_pwd, sizeof(env_gfs_pwd) - 1) != 0 &&
		    memcmp(e, env_pwd, sizeof(env_pwd) - 1 ) != 0)
			new_env[envc++] = e;
	}
	sprintf(rankbuf, "%s%d", env_node_rank, rank);
	new_env[envc++] = rankbuf;
	sprintf(nodesbuf, "%s%d", env_node_size, nodes);
	new_env[envc++] = nodesbuf;
	sprintf(flagsbuf, "%s%s%s%s", env_flags,
	    gf_profile ? "p" : "",
	    gf_on_demand_replication ? "r" : "",
	    gf_hook_default_global ? "g" : "");
	new_env[envc++] = flagsbuf;
	sprintf(cwd_env, "%s%s", env_gfs_pwd, cwdbuf);
	new_env[envc++] = cwd_env;
	sprintf(pwd_env, "%s%s", env_pwd, pwdbuf);
	new_env[envc++] = pwd_env;
	new_env[envc++] = NULL;

	if (gf_stdout == NULL && gf_stderr == NULL) {
		/* what we need is to call exec(2) */
		pid = 0;
	} else {
		/*
		 * we have to call fork(2) and exec(2), to close
		 * gf_stdout and gf_stderr by calling gfarm_terminate()
		 * after the child program finished.
		 */
		pid = fork();
	}

	switch (pid) {
	case -1:
		perror(PROGRAM_NAME ": fork");
		status = 255;
		break;
	case 0:
		if (gf_stdout == NULL && gf_stderr == NULL) {
			/*
			 * not to display profile statistics
			 * on gfarm_terminate()
			 */
			gfs_profile(gf_profile = 0);

			e = gfarm_terminate();
			if (e != NULL)
				errmsg("(child) gfarm_terminate", e);
		} else {
			/*
			 * otherwise don't call gfarm_terminate(), because:
			 * - it closes gf_stdout and gf_stderr.
			 * - it causes:
			 *   "gfarm_terminate: Can't contact LDAP server"
			 *   on the parent process.
			 */
		}
		execve(local_path, argv, new_env);
		if (errno != ENOEXEC) {
			perror(local_path);
		} else {
			/*
			 * argv[-1] must be available,
			 * because there should be "gfexec" at least.
			 */
			argv[-1] = BOURNE_SHELL;
			argv[0] = local_path;
			execve(BOURNE_SHELL, argv - 1, new_env);
		}
		_exit(255);
	default:
		if (waitpid(pid, &status, 0) == -1) {
			perror(PROGRAM_NAME ": waitpid");
			status = 255;
		} else if (WIFSIGNALED(status)) {
			fprintf(stderr, "%s: signal %d received%s.\n",
			    gfarm_host_get_self_name(), WTERMSIG(status),
			    WCOREDUMP(status) ? " (core dumped)" : "");
			status = 255;
		} else {
			status = WEXITSTATUS(status);
		}
		break;
	}

	/* not to display profile statistics on gfarm_terminate() */
	gfs_profile(gf_profile = 0);

	e = gfarm_terminate();
	if (e != NULL) {
		errmsg("gfarm_terminate", e);
		exit(1);
	}
	exit(status);
}
예제 #3
0
파일: hooks_stat.c 프로젝트: ddk50/gfarm_v2
int
FUNC___XSTAT(int ver, const char *path, STRUCT_STAT *buf)
{
	const char *e;
	char *url;
	struct gfs_stat gs;
	int nf = -1, np, errno_save = errno;

	_gfs_hook_debug_v(gflog_info(GFARM_MSG_UNFIXED,
	    "Hooking " S(FUNC___XSTAT) "(%s)",
	    path));

	if (!gfs_hook_is_url(path, &url))
		return (SYSCALL_XSTAT(ver, path, buf));

	_gfs_hook_debug(gflog_info(GFARM_MSG_UNFIXED,
	    "GFS: Hooking " S(FUNC___XSTAT) "(%s)", path));

	switch (gfs_hook_get_current_view()) {
	case section_view:
		_gfs_hook_debug(gflog_info(GFARM_MSG_UNFIXED,
			"GFS: " S(GFS_STAT_SECTION) "(%s, %s)",
			url, gfs_hook_get_current_section()));
		e = GFS_STAT_SECTION(url, gfs_hook_get_current_section(), &gs);
		break;
	case index_view:
		_gfs_hook_debug(gflog_info(GFARM_MSG_UNFIXED,
			"GFS: " S(GFS_STAT_INDEX) "(%s, %d)",
			url, gfs_hook_get_current_index()));
		e = GFS_STAT_INDEX(url, gfs_hook_get_current_index(), &gs);
		break;
	case local_view:
		/*
		 * If the number of fragments is not the same as the
		 * number of parallel processes, or the file is not
		 * fragmented, do not change to the local file view.
		 */
		if (gfarm_url_fragment_number(url, &nf) == NULL) {
			if (gfs_pio_get_node_size(&np) == NULL && nf == np) {
				_gfs_hook_debug(gflog_info(GFARM_MSG_UNFIXED,
					"GFS: " S(GFS_STAT_INDEX) "(%s, %d)",
					url, gfarm_node));
				e = GFS_STAT_INDEX(url, gfarm_node, &gs);
			}
			else {
				_gfs_hook_debug(gflog_info(GFARM_MSG_UNFIXED,
					"GFS: " S(GFS_STAT) "(%s)", url));
				e = GFS_STAT(url, &gs);
			}
		}
		else {
			_gfs_hook_debug(gflog_info(GFARM_MSG_UNFIXED,
				"GFS: " S(GFS_STAT) "(%s)", url));
			e = GFS_STAT(url, &gs);
		}
		break;
	default:
		_gfs_hook_debug(gflog_info(GFARM_MSG_UNFIXED,
			"GFS: " S(GFS_STAT) "(%s)", url));
		e = GFS_STAT(url, &gs);
	}
	free(url);
	if (e == NULL) {
		struct passwd *p;

		memset(buf, 0, sizeof(*buf));
		buf->st_dev = GFS_DEV;	  
		buf->st_ino = gs.st_ino;
		buf->st_mode = gs.st_mode;
		buf->st_nlink = S_ISDIR(buf->st_mode) ? GFS_NLINK_DIR : 1;

		/* XXX FIXME: need to convert gfarm global user to UNIX uid */
		p = getpwnam(gfarm_get_local_username());
		if (p != NULL) {
			buf->st_uid = p->pw_uid;
			buf->st_gid = p->pw_gid;
		} else {
			buf->st_uid = getuid(); /* XXX */
			buf->st_gid = getgid(); /* XXX */
		}
		buf->st_size = gs.st_size;
		buf->st_blksize = GFS_BLKSIZE;
		buf->st_blocks = (gs.st_size + STAT_BLKSIZ - 1) / STAT_BLKSIZ;
		buf->st_atime = gs.st_atimespec.tv_sec;
		buf->st_mtime = gs.st_mtimespec.tv_sec;
		buf->st_ctime = gs.st_ctimespec.tv_sec;
		gfs_stat_free(&gs);

		errno = errno_save;
		return (0);
	}

	_gfs_hook_debug(gflog_info(GFARM_MSG_UNFIXED,
	    "GFS: " S(FUNC___XSTAT) ": %s", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
예제 #4
0
파일: gfreg.c 프로젝트: krichter722/gfarm
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);
}
예제 #5
0
int
FUNC___OPEN(const char *path, int oflag, ...)
{
	GFS_File gf;
	const char *e;
	char *url, *sec;
	va_list ap;
	mode_t mode;
	int filedes;

	va_start(ap, oflag);
	mode = va_arg(ap, mode_t);
	va_end(ap);

	_gfs_hook_debug_v(fprintf(stderr,
	    "Hooking " S(FUNC___OPEN) "(%s, 0x%x)\n", path, oflag));

	if (!gfs_hook_is_url(path, &url, &sec))
		return (SYSCALL_OPEN(path, oflag, mode));

	/* XXX - ROOT I/O creates a new file with O_CREAT|O_RDWR mode. */
	/* XXX - FIXME */
	if ((oflag & O_CREAT) != 0 || (oflag & O_TRUNC) != 0) {
		_gfs_hook_debug(fprintf(stderr,
		    "GFS: Hooking " S(FUNC___OPEN) "(%s:%s, 0x%x, 0%o)\n",
		    url, sec != NULL ? sec : "(null)", oflag, mode));
		if (oflag & O_TRUNC) {
			/*
			 * Hooking open syscall does not mean to open
			 * an entire file but a file fragment in local and
			 * index file views.  gfs_unlink() should not be
			 * called in both views.
			 */
			if (_gfs_hook_default_view == global_view)
				gfs_unlink(url); /* XXX - FIXME */
			e = gfs_pio_create(url, oflag, mode, &gf);
		} else {
			e = gfs_pio_open(url, oflag, &gf);
			if (e == GFARM_ERR_NO_SUCH_OBJECT) /* XXX - FIXME */
				e = gfs_pio_create(url, oflag, mode, &gf);
		}
	} else {
		_gfs_hook_debug(fprintf(stderr,
		    "GFS: Hooking " S(FUNC___OPEN) "(%s:%s, 0x%x)\n",
		    url, sec != NULL ? sec : "(null)", oflag));
		e = gfs_pio_open(url, oflag, &gf);
	}
	free(url);
	if (e != NULL) {
		_gfs_hook_debug(fprintf(stderr,
		    "GFS: Hooking " S(FUNC___OPEN) ": %s\n", e));
		errno = gfarm_error_to_errno(e);
		return (-1);
	}

	if (sec != NULL || _gfs_hook_default_view == index_view) {
		if (sec != NULL) {
			_gfs_hook_debug(fprintf(stderr,
				"GFS: set_view_section(%s, %s)\n", url, sec));
			e = gfs_pio_set_view_section(gf, sec, NULL, 0);
			free(sec);
		} else {
			_gfs_hook_debug(fprintf(stderr,
				"GFS: set_view_index(%s, %d, %d)\n", url,
				_gfs_hook_num_fragments, _gfs_hook_index));
			e = gfs_pio_set_view_index(gf, _gfs_hook_num_fragments,
				_gfs_hook_index, NULL, 0);
		}
		if (e != NULL) {
			_gfs_hook_debug(fprintf(stderr,
			    "GFS: set_view_section: %s\n", e));
			gfs_pio_close(gf);
			errno = gfarm_error_to_errno(e);
			return (-1);
		}
	} else if (_gfs_hook_default_view == local_view) {
		int nf = -1, np;
		/*
		 * If the number of fragments is not the same as the
		 * number of parallel processes, or the file is not
		 * fragmented, do not change to the local file view.
		 */
		if (gfs_pio_get_nfragment(gf, &nf) ==
			GFARM_ERR_FRAGMENT_INDEX_NOT_AVAILABLE ||
		    (gfs_pio_get_node_size(&np) == NULL && nf == np)) {
			_gfs_hook_debug(fprintf(stderr,
				"GFS: set_view_local(%s (%d, %d))\n",
					url, gfarm_node, gfarm_nnode));
			if ((e = gfs_pio_set_view_local(gf, 0)) != NULL) {
				_gfs_hook_debug(fprintf(stderr,
					"GFS: set_view_local: %s\n", e));
				gfs_pio_close(gf);
				errno = gfarm_error_to_errno(e);
				return (-1);
			}
		}
	}
	filedes = gfs_hook_insert_gfs_file(gf);
	_gfs_hook_debug(
		if (filedes != -1) {
			fprintf(stderr,
			    "GFS: Hooking " S(FUNC___OPEN) " --> %d(%d)\n",
			    filedes, gfs_pio_fileno(gf));
		}
	);