예제 #1
0
파일: gfwhere.c 프로젝트: krichter722/gfarm
static char *
display_replica_catalog(char *gfarm_url)
{
	char *gfarm_file, *e, *e_save = NULL;
	int i, j, nsections;
	struct gfarm_file_section_info *sections;
	struct gfs_stat st;

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL) {
		fprintf(stderr, "%s: %s\n", gfarm_url, e);
		return (e);
	}
	e = gfs_stat(gfarm_url, &st);
	if (e != NULL) {
		free(gfarm_file);
		fprintf(stderr, "%s: %s\n", gfarm_url, e);
		return (e);
	}
	if (!GFARM_S_ISREG(st.st_mode)) {
		free(gfarm_file);
		gfs_stat_free(&st);
		fprintf(stderr, "%s: not a file\n", gfarm_url);
		return (e);
	}
	if ((st.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) != 0) { /* program? */
		e = gfarm_file_section_info_get_all_by_file(
		    gfarm_file, &nsections, &sections);
	} else {
		e = gfarm_file_section_info_get_sorted_all_serial_by_file(
		    gfarm_file, &nsections, &sections);
	}
	gfs_stat_free(&st);
	if (e != NULL) {
		free(gfarm_file);
		fprintf(stderr, "%s: %s\n", gfarm_url, e);
		return (e);
	}
	for (i = 0; i < nsections; i++) {
		int ncopies;
		struct gfarm_file_section_copy_info *copies;

		e = gfarm_file_section_copy_info_get_all_by_section(
		    gfarm_file, sections[i].section, &ncopies, &copies);
		if (e != NULL) {
			fprintf(stderr, "%d: %s\n", i, e);
			if (e_save == NULL)
				e_save = e;
			continue;
		}
		printf("%s:", sections[i].section);
		for (j = 0; j < ncopies; j++)
			printf(" %s", copies[j].hostname);
		gfarm_file_section_copy_info_free_all(ncopies, copies);
		printf("\n");
	}
	gfarm_file_section_info_free_all(nsections, sections);
	free(gfarm_file);
	return (e_save);	
}
예제 #2
0
static gfarm_error_t
gfs_stat_cache_enter_internal(const char *path, const struct gfs_stat *st,
	const struct timeval *nowp)
{
	gfarm_error_t e;
	struct gfarm_hash_entry *entry;
	struct stat_cache_data *data;
	int created;

	if (stat_cache == NULL) {
		if ((e = gfs_stat_cache_init()) != GFARM_ERR_NO_ERROR)
			return (e);
	}
	gfs_stat_cache_expire_internal(nowp);

	if (stat_cache_count >= gfarm_attr_cache_limit) {
		/* remove the head of the list (i.e. oldest entry) */
		data = stat_cache_list_head.next;
		data->prev->next = data->next;
		data->next->prev = data->prev;
		gfs_stat_free(&data->st);
		entry = data->entry;
		gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry),
		    gfarm_hash_entry_key_length(entry));
		--stat_cache_count;
	}

	entry = gfarm_hash_enter(stat_cache, path, strlen(path) + 1,
	    sizeof(*data), &created);
	if (entry == NULL)
		return (GFARM_ERR_NO_MEMORY);

	data = gfarm_hash_entry_data(entry);
	if (created) {
		++stat_cache_count;
		data->entry = entry;
	} else {
		/* remove from the list, to move this to the end of the list */
		data->prev->next = data->next;
		data->next->prev = data->prev;

		gfs_stat_free(&data->st);
	}
	e = gfs_stat_copy(&data->st, st);
	if (e != GFARM_ERR_NO_ERROR) {
		gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry),
		    gfarm_hash_entry_key_length(entry));
		--stat_cache_count;
		return (e);
	}
	data->expiration = *nowp;
	gfarm_timeval_add(&data->expiration, &stat_cache_lifespan);
	/* add to the end of the cache list, i.e. assumes monotonic time */
	data->next = &stat_cache_list_head;
	data->prev = stat_cache_list_head.prev;
	stat_cache_list_head.prev->next = data;
	stat_cache_list_head.prev = data;
	return (GFARM_ERR_NO_ERROR);
		
}
예제 #3
0
파일: gfsplck.c 프로젝트: krichter722/gfarm
static int
fixfrag(char *pathname, const char *gfarm_prefix)
{
	char *gfarm_url, *sec, *gfarm_file, *e;
	struct gfs_stat gst;
	int r = 1;

	gfarm_url = append_prefix_pathname(gfarm_prefix, pathname);
	if (gfarm_url == NULL) {
		print_errmsg(pathname, NULL, "not enough memory");
		return (r);
	}

	/* divide into file and section parts. */
	e = split_file_and_section(gfarm_url, &sec);
	if (e != NULL) {
		print_errmsg(pathname, NULL, e);
		delete_invalid_file_or_directory(pathname);
		goto error_gfarm_url;
	}

	e = gfs_stat(gfarm_url, &gst);
	if (e == NULL) {
		if (!GFARM_S_ISREG(gst.st_mode)) {
			gfs_stat_free(&gst);
			print_errmsg(gfarm_url, NULL, "not a regular file");
			delete_invalid_file_or_directory(pathname);
			goto error_gfarm_url;
		}
		gfs_stat_free(&gst);
	}
	else
		/* permit no fragment case */;

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL) {
		print_errmsg(gfarm_url, sec, e);
		delete_invalid_file_or_directory(pathname);
		goto error_gfarm_url;
	}

	/* check whether the fragment is already registered. */
	e = fixfrag_i(gfarm_url, pathname, gfarm_file, sec);
	if (e != NULL && e != GFARM_ERR_ALREADY_EXISTS)
		goto error_gfarm_file;

	r = 0;

error_gfarm_file:
	free(gfarm_file);
error_gfarm_url:	
	free(gfarm_url);
	return (r);
}
예제 #4
0
파일: gfsck.c 프로젝트: krichter722/gfarm
static char *
gfsck_dir(char *gfarm_dir, char *file)
{
	char *e, *e_save = NULL, *gfarm_url;
	struct gfs_stat gsb;
	GFS_Dir gdir;
	struct gfs_dirent *gdent;

	gfarm_url = malloc(strlen(gfarm_dir) + strlen(file) + 2);
	if (gfarm_url == NULL)
		return (GFARM_ERR_NO_MEMORY);
	if (gfarm_dir[0] == '\0')
		sprintf(gfarm_url, "%s", file);
	else
		sprintf(gfarm_url, "%s/%s", gfarm_dir, file);

	e = gfs_stat(gfarm_url, &gsb);
	if (e != NULL) {
		free(gfarm_url);
		return (e);
	}
	if (GFARM_S_ISREG(gsb.st_mode)) {
		gfs_stat_free(&gsb);
		e = gfsck_file(gfarm_url);
		free(gfarm_url);
		return (e);
	}
	if (!GFARM_S_ISDIR(gsb.st_mode)) {
		gfs_stat_free(&gsb);
		free(gfarm_url);
		return ("unknown file type");
	}
	gfs_stat_free(&gsb);

	e = gfs_opendir(gfarm_url, &gdir);
	if (e != NULL) {
		free(gfarm_url);
		return (e);
	}
	while ((e = gfs_readdir(gdir, &gdent)) == NULL && gdent != NULL) {
		e = gfsck_dir(gfarm_url, gdent->d_name);
		if (e != NULL) {
			fprintf(stderr, "%s/%s: %s\n",
				gfarm_url, gdent->d_name, e);
			if (e_save == NULL)
				e_save = e;
		}
	}
	(void)gfs_closedir(gdir);
	free(gfarm_url);

	return (e_save);
}
예제 #5
0
char *
gfs_stat_canonical_path(char *gfarm_file, struct gfs_stat *s)
{
	char *e;
	int i, nsections;
	struct gfarm_file_section_info *sections;
	struct gfarm_path_info pi;
	long ino;

	e = gfs_get_ino(gfarm_file, &ino);
	if (e != NULL)
		return (e);

	e = gfarm_path_info_get(gfarm_file, &pi);
	if (e != NULL)
		return (e);

	*s = pi.status;
	s->st_ino = ino;
	s->st_user = strdup(s->st_user);
	s->st_group = strdup(s->st_group);
	gfarm_path_info_free(&pi);
	if (s->st_user == NULL || s->st_group == NULL) {
		gfs_stat_free(s);
		return (GFARM_ERR_NO_MEMORY);
	}

	if (!GFARM_S_ISREG(s->st_mode))
		return (NULL);

	/* regular file */
	e = gfarm_file_section_info_get_all_by_file(gfarm_file,
	    &nsections, &sections);
	if (e != NULL) {
		gfs_stat_free(s);
		/*
		 * If GFARM_ERR_NO_SUCH_OBJECT is returned here,
		 * gfs_stat() incorrectly assumes that this is a directory,
		 * and reports GFARM_ERR_NOT_A_DIRECTORY.
		 */
		return (GFARM_ERR_NO_FRAGMENT_INFORMATION);
	}

	s->st_size = 0;
	for (i = 0; i < nsections; i++)
		s->st_size += sections[i].filesize;
	s->st_nsections = nsections;

	gfarm_file_section_info_free_all(nsections, sections);

	return (NULL);
}
예제 #6
0
파일: gfrm.c 프로젝트: krichter722/gfarm
static char *
remove_whole_file_or_dir(char *path, int is_recursive)
{
	char *e, *e2;
	struct gfs_stat gs;
	char cwdbuf[PATH_MAX * 2];

	e = gfs_stat(path, &gs);
	if (e == GFARM_ERR_NO_FRAGMENT_INFORMATION)
		e2 = gfs_unlink(path);	
	if (e != NULL)
		return (e);

	if (GFARM_S_ISREG(gs.st_mode)) {
		e = gfs_unlink(path);
	} else if (GFARM_S_ISDIR(gs.st_mode)) {
		if (!is_recursive)
	        	return (GFARM_ERR_IS_A_DIRECTORY);
		e = gfs_getcwd(cwdbuf, sizeof(cwdbuf));
		if (e != NULL)
			return (e);
		e = gfs_chdir(path);
		if (e != NULL)
			return (e);
		remove_cwd_entries();
		e = gfs_chdir_canonical(cwdbuf);
		if (e != NULL)
			return (e);
		e = gfs_rmdir(path);
	}
	gfs_stat_free(&gs);
	return (e);
}
예제 #7
0
파일: hooks.c 프로젝트: krichter722/gfarm
int
__fchown(int fd, uid_t owner, gid_t group)
{
	GFS_File gf;
	const char *e;
	struct gfs_stat s;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __fchown(%d, %d, %d)\n",
				  fd, uid, group));

	if ((gf = gfs_hook_is_open(fd)) == NULL)
		return (__syscall_fchown(fd, owner, group));

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __fchown(%d, %d, %d)\n",
				fd, owner, group));
	e = gfs_fstat(gf, &s);
	if (e == NULL) {
		if (strcmp(s.st_user, gfarm_get_global_username()) != 0)
			e = GFARM_ERR_OPERATION_NOT_PERMITTED; /* EPERM */
		/* XXX - do nothing */
		gfs_stat_free(&s);
	}	
	if (e == NULL)
		return (0);

	_gfs_hook_debug(fprintf(stderr, "GFS: __fchown: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
예제 #8
0
파일: hooks.c 프로젝트: krichter722/gfarm
int
__lchown(const char *path, uid_t owner, gid_t group)
{
	const char *e;
	char *url;
	struct gfs_stat s;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __lchown(%s, %d, %d)\n",
				  path, uid, group));

	if (!gfs_hook_is_url(path, &url))
		return (__syscall_lchown(path, owner, group));

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __lchown(%s, %d, %d)\n",
				path, owner, group));
	/* XXX - gfs_lstat is not supported */
	e = gfs_stat(url, &s);
	free(url);
	if (e == NULL) {
		if (strcmp(s.st_user, gfarm_get_global_username()) != 0)
			e = GFARM_ERR_OPERATION_NOT_PERMITTED; /* EPERM */
		/* XXX - do nothing */
		gfs_stat_free(&s);
	}	
	if (e == NULL)
		return (0);

	_gfs_hook_debug(fprintf(stderr, "GFS: __lchown: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
예제 #9
0
static char *
gfs_pio_local_mkdir_p(char *canonic_dir)
{
	struct gfs_stat stata;
	struct stat statb;
	gfarm_mode_t mode;
	char *e, *local_path, *user;

	/* dirname(3) may return '.'.  This means the spool root directory. */
	if (strcmp(canonic_dir, "/") == 0 || strcmp(canonic_dir, ".") == 0)
		return (NULL); /* should exist */

	e = gfs_stat_canonical_path(canonic_dir, &stata);
	if (e != NULL)
		return (e);
	mode = stata.st_mode;
	/*
	 * XXX - if the owner of a directory is not the same, create a
	 * directory with permission 0777 - This should be fixed in
	 * the next major release.
	 */
	user = gfarm_get_global_username();
	if (strcmp(stata.st_user, user) != 0)
		mode |= 0777;
	gfs_stat_free(&stata);
	if (!GFARM_S_ISDIR(mode))
		return (GFARM_ERR_NOT_A_DIRECTORY);

	e = gfarm_path_localize(canonic_dir, &local_path);
	if (e != NULL)
		return (e);
	if (stat(local_path, &statb)) {
		char *par_dir, *saved_par_dir;
		mode_t saved_umask;
		int r;

		par_dir = saved_par_dir = strdup(canonic_dir);
		if (par_dir == NULL) {
			free(local_path);
			return (GFARM_ERR_NO_MEMORY);
		}
		par_dir = dirname(par_dir);
		e = gfs_pio_local_mkdir_p(par_dir);
		free(saved_par_dir);
		if (e != NULL) {
			free(local_path);
			return (e);
		}
		saved_umask = umask(0);
		r = mkdir(local_path, mode);
		umask(saved_umask);
		if (r == -1) {
			free(local_path);
			return (gfarm_errno_to_error(errno));
		}
	}
	free(local_path);
	return (NULL);
}
예제 #10
0
파일: gfs_dirplus.c 프로젝트: eterps/pwrake
static void
gfs_dirplus_clear(GFS_DirPlus dir)
{
	int i, n = dir->n;

	for (i = 0; i < n; i++)
		gfs_stat_free(&dir->stbuf[i]);
	dir->n = dir->index = 0;
}
예제 #11
0
파일: gfs_dir.c 프로젝트: krichter722/gfarm
char *
gfs_chdir(const char *dir)
{
	char *e, *canonic_path;
	struct gfs_stat st;

	if ((e = gfs_stat(dir, &st)) != NULL)
		return (e);
	if (!GFARM_S_ISDIR(st.st_mode)) {
		gfs_stat_free(&st);
		return (GFARM_ERR_NOT_A_DIRECTORY);
	}
	gfs_stat_free(&st);

	e = gfarm_canonical_path(gfarm_url_prefix_skip(dir), &canonic_path);
	if (e != NULL)
		return (e);
	e = gfs_chdir_canonical(canonic_path);
	free (canonic_path);
	return (e);
}
예제 #12
0
파일: gfreg.c 프로젝트: krichter722/gfarm
static int
section_does_not_exists(char *gfarm_url, char *section)
{
	struct gfs_stat s;

	if (gfs_stat_section(gfarm_url, section, &s) == NULL) {
		gfs_stat_free(&s);
		fprintf(stderr, "%s: %s:%s already exists\n",
		    program_name, gfarm_url, section);
		return (0);
	}
	return (1);
}
예제 #13
0
파일: gfs_dir.c 프로젝트: krichter722/gfarm
char *
gfs_opendir(const char *path, GFS_Dir *dirp)
{
	char *e, *canonic_path;
	struct node *n;
	struct gfs_dir *dir;
	struct gfs_stat st;

	/* gfs_stat() -> gfarm_path_info_get() makes the dircache consistent */
	if ((e = gfs_stat(path, &st)) != NULL)
		return (e);
	if (!GFARM_S_ISDIR(st.st_mode)) {
		gfs_stat_free(&st);
		return (GFARM_ERR_NOT_A_DIRECTORY);
	}
	gfs_stat_free(&st);

	e = gfarm_canonical_path(gfarm_url_prefix_skip(path), &canonic_path);
	if (e != NULL)
		return (e);

	e = lookup_relative(root, canonic_path, NODE_FLAG_IS_DIR,
	    GFARM_INODE_LOOKUP, &n);
	free(canonic_path);
	if (e != NULL)
		return (e);

	dir = malloc(sizeof(struct gfs_dir));
	if (dir == NULL)
		return (GFARM_ERR_NO_MEMORY);
	dir->dir = n;
	gfarm_hash_iterator_begin(n->u.d.children, &dir->iterator);
	dir->index = 0;
	*dirp = dir;

	++opendir_count;
	/* XXX if someone removed a path, while opening a directory... */
	return (NULL);
}
예제 #14
0
static char *
gfs_pio_remote_mkdir_p(
	struct gfs_connection *gfs_server, char *canonic_dir)
{
	struct gfs_stat stata;
	gfarm_mode_t mode;
	char *e, *user;

	/* dirname(3) may return '.'.  This means the spool root directory. */
	if (strcmp(canonic_dir, "/") == 0 || strcmp(canonic_dir, ".") == 0)
		return (NULL); /* should exist */

	user = gfarm_get_global_username();
	if (user == NULL)
		return ("gfs_pio_remote_mkdir_p(): programming error, "
			"gfarm library isn't properly initialized");

	e = gfs_stat_canonical_path(canonic_dir, &stata);
	if (e != NULL)
		return (e);
	mode = stata.st_mode;
	/*
	 * XXX - if the owner of a directory is not the same, create a
	 * directory with permission 0777 - This should be fixed in
	 * the next major release.
	 */
	if (strcmp(stata.st_user, user) != 0)
		mode |= 0777;
	gfs_stat_free(&stata);
	if (!GFARM_S_ISDIR(mode))
		return (GFARM_ERR_NOT_A_DIRECTORY);

	if (gfs_client_exist(gfs_server, canonic_dir)
	    == GFARM_ERR_NO_SUCH_OBJECT) {
		char *par_dir, *saved_par_dir;

		par_dir = saved_par_dir = strdup(canonic_dir);
		if (par_dir == NULL)
			return (GFARM_ERR_NO_MEMORY);
		par_dir = dirname(par_dir);
		e = gfs_pio_remote_mkdir_p(gfs_server, par_dir);
		free(saved_par_dir);
		if (e != NULL)
			return (e);
		
		e = gfs_client_mkdir(gfs_server, canonic_dir, mode);
	}
	return (e);
}
예제 #15
0
static char *
gfarm_path_info_dup(struct gfarm_path_info *src, struct gfarm_path_info *dest)
{
	char *e;

	e = gfs_stat_dup(&src->status, &dest->status);
	if (e != NULL)
		return (e);
	if (src->pathname != NULL) {
		dest->pathname = strdup(src->pathname);
		if (dest->pathname == NULL) {
			gfs_stat_free(&dest->status);
			return (GFARM_ERR_NO_MEMORY);
		}
	}
	return (NULL);
}
예제 #16
0
파일: gfwhere.c 프로젝트: krichter722/gfarm
static char *
display_replica_catalog(char *gfarm_url)
{
	char *gfarm_file, *e, *e_save;
	int i, nsections;
	struct gfarm_file_section_info *sections;
	struct gfs_stat st;
	gfarm_mode_t mode;

	e = gfs_stat(gfarm_url, &st);
	if (e != NULL)
		return (e);
	mode = st.st_mode;
	gfs_stat_free(&st);

	if (!GFARM_S_ISREG(mode))
		return ("not a regular file");

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL)
		return (e);

	if ((mode & (S_IXUSR|S_IXGRP|S_IXOTH)) != 0) { /* program? */
		e_save = gfarm_file_section_info_get_all_by_file(
		    gfarm_file, &nsections, &sections);
	} else {
		e_save = gfarm_file_section_info_get_sorted_all_serial_by_file(
		    gfarm_file, &nsections, &sections);
	}
	if (e_save != NULL)
		goto free_gfarm_file;

	for (i = 0; i < nsections; i++) {
		e = display_section_copies(gfarm_file, sections[i].section);
		if (e != NULL) {
			if (e_save == NULL)
				e_save = e;
			fprintf(stderr, "%s: %s\n", sections[i].section, e);
		}
	}
	gfarm_file_section_info_free_all(nsections, sections);
free_gfarm_file:
	free(gfarm_file);
	return (e_save);
}
예제 #17
0
void
gfs_stat_cache_clear(void)
{
	struct stat_cache_data *p, *q;
	struct gfarm_hash_entry *entry;

	for (p = stat_cache_list_head.next; p != &stat_cache_list_head; p = q) {
		q = p->next;
		gfs_stat_free(&p->st);

		entry = p->entry;
		gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry),
		    gfarm_hash_entry_key_length(entry));
	}
	stat_cache_list_head.next = stat_cache_list_head.prev =
	    &stat_cache_list_head;
	stat_cache_count = 0;
}
예제 #18
0
파일: gfrm.c 프로젝트: krichter722/gfarm
static char *
remove_whole_file_or_dir(char *path,
	Unlink_Ops ops, void *closure, int is_recursive)
{
	struct gfs_stat gs;
	char *e, cwdbuf[PATH_MAX * 2];
	const char *b;
	gfarm_mode_t mode;

	b = gfarm_path_dir_skip(gfarm_url_prefix_skip(path));
	if (b[0] == '.' && (b[1] == '\0' || (b[1] == '.' && b[2] == '\0')))
		return ("cannot remove \'.\' or \'..\'");

	e = gfs_stat(path, &gs);
	if (e == GFARM_ERR_NO_FRAGMENT_INFORMATION)
		return (ops->unlink(path, closure));
	if (e != NULL)
		return (e);

	mode = gs.st_mode;
	gfs_stat_free(&gs);

	if (GFARM_S_ISREG(mode)) {
		e = ops->unlink(path, closure);
	} else if (GFARM_S_ISDIR(mode)) {
		if (!is_recursive)
			return (GFARM_ERR_IS_A_DIRECTORY);
		e = gfs_getcwd(cwdbuf, sizeof(cwdbuf));
		if (e != NULL)
			return (e);
		e = gfs_chdir(path);
		if (e != NULL)
			return (e);
		remove_cwd_entries(ops, closure);
		e = gfs_chdir_canonical(cwdbuf);
		if (e != NULL)
			return (e);
		e = ops->rmdir(path, closure);
	}
	return (e);
}
예제 #19
0
파일: gfwhere.c 프로젝트: krichter722/gfarm
static char *
display_replica_catalog_section(char *gfarm_url, char *section)
{
	char *gfarm_file, *e;
	int j, ncopies;
	struct gfarm_file_section_copy_info *copies;
	struct gfs_stat st;

	if (section == NULL)
		return (display_replica_catalog(gfarm_url));

	e = gfs_stat(gfarm_url, &st);
	if (e != NULL) {
		fprintf(stderr, "%s: %s\n", gfarm_url, e);
		return (e);
	}
	gfs_stat_free(&st);

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL) {
		fprintf(stderr, "%s: %s\n", gfarm_url, e);
		return (e);
	}
	e = gfarm_file_section_copy_info_get_all_by_section(
		gfarm_file, section, &ncopies, &copies);
	if (e != NULL) {
		fprintf(stderr, "%s\n", e);
		free(gfarm_file);
		return (e);
	}
	j = 0;
	printf("%s", copies[j].hostname);
	for (++j; j < ncopies; ++j)
		printf(" %s", copies[j].hostname);
	printf("\n");
	gfarm_file_section_copy_info_free_all(ncopies, copies);
	free(gfarm_file);

	return (NULL);
}
예제 #20
0
static void
gfs_stat_cache_expire_internal(const struct timeval *nowp)
{
	struct stat_cache_data *p, *q;
	struct gfarm_hash_entry *entry;

	for (p = stat_cache_list_head.next; p != &stat_cache_list_head; p = q) {
		/* assumes monotonic time */
		if (gfarm_timeval_cmp(&p->expiration, nowp) > 0)
			break;

		q = p->next;
		gfs_stat_free(&p->st);

		entry = p->entry;
		gfarm_hash_purge(stat_cache, gfarm_hash_entry_key(entry),
		    gfarm_hash_entry_key_length(entry));
		--stat_cache_count;
	}
	stat_cache_list_head.next = p;
	p->prev = &stat_cache_list_head;
}
예제 #21
0
gfarm_error_t
gfs_stat_cache_purge(const char *path)
{
	struct gfarm_hash_iterator it;
	struct gfarm_hash_entry *entry;
	struct stat_cache_data *data;

	if (stat_cache == NULL) /* there is nothing to purge */
		return (GFARM_ERR_NO_ERROR);

	gfs_stat_cache_expire();
	if (!gfarm_hash_iterator_lookup(stat_cache, path, strlen(path)+1, &it))
		return (GFARM_ERR_NO_SUCH_FILE_OR_DIRECTORY);
	entry = gfarm_hash_iterator_access(&it);
	assert(entry != NULL);
	data = gfarm_hash_entry_data(entry);
	data->prev->next = data->next;
	data->next->prev = data->prev;
	gfs_stat_free(&data->st);
	gfarm_hash_iterator_purge(&it);
	--stat_cache_count;
	return (GFARM_ERR_NO_ERROR);
}
예제 #22
0
char *
gfs_hook_clear_gfs_file(int fd)
{
	GFS_File gf;
	char *e = NULL;

	_gfs_hook_debug(fprintf(stderr, "GFS: clear_gfs_file: %d\n", fd));

	gf = gfs_hook_is_open(fd);
	if (gf == NULL) {
		_gfs_hook_debug(fprintf(stderr,
			"GFS: ERROR: not a Gfarm file: %d\n", fd));
		return ("not a Gfarm file");
	}

	if (--_gfs_file_buf[fd]->refcount > 0) {
	  	/* fd is duplicated, skip closing the file. */
		_gfs_hook_debug(fprintf(stderr,
					"GFS: clear_gfs_file: skipped\n"));
	} else {
		if (gfs_hook_gfs_file_type(fd) == GFS_DT_REG) {
			gfs_hook_delete_creating_file(gf);
			e = gfs_pio_close(gf);
		} else if (gfs_hook_gfs_file_type(fd) == GFS_DT_DIR) {
			_gfs_file_buf[fd]->u.d->dir = NULL;
			_gfs_file_buf[fd]->u.d->suspended = NULL;
			gfs_stat_free(&_gfs_file_buf[fd]->u.d->gst);
			free(_gfs_file_buf[fd]->u.d->canonical_path); 
			free(_gfs_file_buf[fd]->u.d);
			e = gfs_closedir((GFS_Dir)gf);
		}
		free(_gfs_file_buf[fd]);
	}
	__syscall_close(fd);
	_gfs_file_buf[fd] = NULL;
	return (e);
}
예제 #23
0
파일: gfwhere.c 프로젝트: krichter722/gfarm
int
main(int argc, char **argv)
{
	int argc_save = argc;
	char **argv_save = argv;
	gfarm_error_t e, e_save = GFARM_ERR_NO_ERROR;
	int i, n, ch, opt_recursive = 0;
	gfarm_stringlist paths;
	gfs_glob_t types;

	if (argc >= 1)
		program_name = basename(argv[0]);

	while ((ch = getopt(argc, argv, "rR?")) != -1) {
		switch (ch) {
		case 'r':
		case 'R':
			opt_recursive = 1;
			break;
		case '?':
		default:
			usage();
		}
	}
	argc -= optind;
	argv += optind;

	e = gfarm_initialize(&argc_save, &argv_save);
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: %s\n", program_name,
		    gfarm_error_string(e));
		exit(1);
	}
	if (argc == 0) {
		usage();
	}

	e = gfarm_stringlist_init(&paths);
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: %s\n", program_name,
		    gfarm_error_string(e));
		exit(EXIT_FAILURE);
	}
	e = gfs_glob_init(&types);
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: %s\n", program_name,
		    gfarm_error_string(e));
		exit(EXIT_FAILURE);
	}
	for (i = 0; i < argc; i++)
		gfs_glob(argv[i], &paths, &types);
	gfs_glob_free(&types);

	n = gfarm_stringlist_length(&paths);
	for (i = 0; i < n; i++) {
		char *p = gfarm_stringlist_elem(&paths, i);
		struct gfs_stat st;

		if ((e = gfs_stat(p, &st)) != GFARM_ERR_NO_ERROR) {
			fprintf(stderr, "%s: %s\n", p, gfarm_error_string(e));
		} else {
			if (GFARM_S_ISREG(st.st_mode)) 
				e = display_replica_catalog(p, &st, NULL);
			else if (opt_recursive)
				e = gfarm_foreach_directory_hierarchy(
					display_replica_catalog, display_name,
					NULL, p, NULL);
			else
				fprintf(stderr, "%s: not a file\n", p);
			gfs_stat_free(&st);
			if (e_save == GFARM_ERR_NO_ERROR)
				e_save = e;
		}
	}

	gfarm_stringlist_free_deeply(&paths);
	e = gfarm_terminate();
	if (e != GFARM_ERR_NO_ERROR) {
		fprintf(stderr, "%s: %s\n", program_name,
		    gfarm_error_string(e));
		exit(1);
	}
	return (e_save == GFARM_ERR_NO_ERROR ? 0 : 1);
}
예제 #24
0
파일: gfsplck.c 프로젝트: krichter722/gfarm
static int
fixdir(char *dir, const char *gfarm_prefix)
{
	DIR* dirp;
	struct dirent *dp;
	struct stat sb;
	char *dir1;
	char *gfarm_url, *e;
	int is_directory;
	struct gfs_stat gs;

	if (lstat(dir, &sb)) {
		perror(dir);
		return (1);
	}
	if (S_ISREG(sb.st_mode))
		return (fixfrag(dir, gfarm_prefix));

	if (!S_ISDIR(sb.st_mode)) {
		print_errmsg(dir, NULL,
			"neither a regular file nor a directory");
		delete_invalid_file_or_directory(dir);
		return (1);
	}

	/* 'dir' is a directory */
	gfarm_url = append_prefix_pathname(gfarm_prefix, dir);
	if (gfarm_url == NULL) {
		print_errmsg(dir, NULL, "not enough memory");
		return (1);
	}

	e = gfs_stat(gfarm_url, &gs);
	if (e != NULL) {
		print_errmsg(gfarm_url, NULL, e);
		delete_invalid_file_or_directory(dir);
		free(gfarm_url);
		return (1);
	}
	is_directory = GFARM_S_ISDIR(gs.st_mode);
	gfs_stat_free(&gs);
	if (!is_directory) {
		print_errmsg(gfarm_url, NULL, "invalid directory");
		delete_invalid_file_or_directory(dir);
		free(gfarm_url);
		return (1);
	}
	free(gfarm_url);

	dirp = opendir(dir);
	if (dirp == NULL) {
		perror(dir);
		return (1);
	}

	if (strcmp(dir, ".") == 0)
		dir = ""; /* just a trick */

	while ((dp = readdir(dirp)) != NULL) {
		if (strcmp(dp->d_name, ".") == 0
		    || strcmp(dp->d_name, "..") == 0)
			continue;

		GFARM_MALLOC_ARRAY(dir1, strlen(dir) + strlen(dp->d_name) + 2);
		if (dir1 == NULL) {
			print_errmsg(dp->d_name, NULL, "not enough memory");
			closedir(dirp);
			return (1);
		}
		strcpy(dir1, dir);
		if (strcmp(dir, ""))
			strcat(dir1, "/");
		strcat(dir1, dp->d_name);

		fixdir(dir1, gfarm_prefix);

		free(dir1);
	}
	return (closedir(dirp));
}
예제 #25
0
파일: gfsplck.c 프로젝트: krichter722/gfarm
static void
fixurl(const char *gfarm_url)
{
	char *gfarm_file, *local_path, *e;
	struct stat sb;
	int len_path, is_invalid = 0, is_directory = 0;
	glob_t pglob;
	char **pathp, *pat;
	struct gfs_stat gs;

	e = gfarm_canonical_path(gfarm_url_prefix_skip(gfarm_url), &gfarm_file);
	if (e != NULL) {
		/*
		 * no path info, try to delete invalid physical files
		 * or directories
		 */
		e = gfarm_canonical_path_for_creation(
			gfarm_url_prefix_skip(gfarm_url), &gfarm_file);
		if (e != NULL) {
			/* in this case, give up searching invalid files */
			print_errmsg(gfarm_url, NULL, e);
			return;
		}
		is_invalid = 1;
	}
	else {
		/* check it is a directory or not */
		e = gfs_stat(gfarm_url, &gs);
		if (e != NULL) {
			if (e != GFARM_ERR_NO_FRAGMENT_INFORMATION) {
				/* maybe permission denied */
				print_errmsg(gfarm_url, NULL, e);
				goto error_gfarm_file;
			}
			/* no fragment information case */
		}
		else {
			is_directory = GFARM_S_ISDIR(gs.st_mode);
			gfs_stat_free(&gs);
		}
	}
	/*
	 * Check local_path; if it is invalid or not a directory,
	 * delete it.  Otherwise, check it recursively.
	 */
	e = gfarm_path_localize(gfarm_file, &local_path);
	if (e == NULL && stat(local_path, &sb) == 0) {
		if (is_invalid || !is_directory || !S_ISDIR(sb.st_mode)) {
			print_errmsg(local_path, NULL,
				"invalid file or directory");
			delete_invalid_file_or_directory(local_path);
		}
		else if (chdir(local_path) == 0)
			(void)fixdir(".", gfarm_url);
		/* continue */
	}
	if (e != NULL) {
		print_errmsg(gfarm_url, NULL, e);
		goto error_gfarm_file;
	}

	/* investigate file sections */
	len_path = strlen(local_path);
	GFARM_MALLOC_ARRAY(pat, len_path + 3);
	if (pat == NULL) {
		print_errmsg(gfarm_url, NULL, "not enough memory");
		free(local_path);
		goto error_gfarm_file;
	}
	strcpy(pat, local_path);
	strcat(pat, ":*");
	free(local_path);

	pglob.gl_offs = 0;
	glob(pat, GLOB_DOOFFS, NULL, &pglob);
	free(pat);
	
	pathp = pglob.gl_pathv;
	while (*pathp) {
		char *sec = &((*pathp)[len_path + 1]);

		if (is_invalid || is_directory) {
			print_errmsg(gfarm_url, sec, "invalid file");
			delete_invalid_file_or_directory(*pathp);
			++pathp;
			continue;
		}
		(void)fixfrag_i(gfarm_url, *pathp, gfarm_file, sec);

		++pathp;
	}
	globfree(&pglob);

 error_gfarm_file:
	free(gfarm_file);
	return;
}
예제 #26
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);
}
예제 #27
0
파일: gfsck.c 프로젝트: krichter722/gfarm
static char *
gfsck_dir(char *gfarm_dir, char *file)
{
	char *e, *gfarm_url;
	struct gfs_stat gsb;
	GFS_Dir gdir;
	struct gfs_dirent *gdent;

	gfarm_url = malloc(strlen(gfarm_dir) + strlen(file) + 2);
	if (gfarm_url == NULL)
		return (GFARM_ERR_NO_MEMORY);
	if (gfarm_dir[0] == '\0')
		sprintf(gfarm_url, "%s", file);
	else if (strcmp(gfarm_dir, GFARM_URL_PREFIX) == 0)
		sprintf(gfarm_url, "%s%s", gfarm_dir, file);
	else
		sprintf(gfarm_url, "%s/%s", gfarm_dir, file);

	e = gfs_stat(gfarm_url, &gsb);
	if (e != NULL) {
		if (e == GFARM_ERR_NO_FRAGMENT_INFORMATION) {
			/* no fragment information, remove path info */
			e = path_info_remove(gfarm_url, NULL);
		}
		free(gfarm_url);
		return (e);
	}
	if (GFARM_S_ISREG(gsb.st_mode)) {
		gfs_stat_free(&gsb);
		e = gfsck_file(gfarm_url);
		free(gfarm_url);
		return (e);
	}
	if (!GFARM_S_ISDIR(gsb.st_mode)) {
		gfs_stat_free(&gsb);
		free(gfarm_url);
		return ("unknown file type");
	}
	gfs_stat_free(&gsb);

	e = gfs_opendir(gfarm_url, &gdir);
	if (e != NULL) {
		free(gfarm_url);
		return (e);
	}
	while ((e = gfs_readdir(gdir, &gdent)) == NULL && gdent != NULL) {
		if (gdent->d_name[0] == '.' && (gdent->d_name[1] == '\0' ||
		    (gdent->d_name[1] == '.' && gdent->d_name[2] == '\0')))
			continue; /* "." or ".." */
		e = gfsck_dir(gfarm_url, gdent->d_name);
		if (e != NULL) {
			fprintf(stderr, "%s%s%s: %s\n",
				gfarm_url, 
				strcmp(gfarm_url, GFARM_URL_PREFIX) == 0
				? "" : "/", gdent->d_name, e);
			/* it is not necessary to save error */
		}
	}
	(void)gfs_closedir(gdir);
	free(gfarm_url);

	return (NULL);
}
예제 #28
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);
}
예제 #29
0
파일: gfrm.c 프로젝트: krichter722/gfarm
static void
remove_cwd_entries()
{
	char *e;
	char cwdbf[PATH_MAX * 2];
	int i;
	GFS_Dir dir;
	struct gfs_dirent *entry;
	gfarm_stringlist entry_list;

	e = gfs_getcwd(cwdbf, sizeof(cwdbf));
	if (e != NULL) {
		fprintf(stderr, "%s\n", e);
		return;
	}
	e = gfs_opendir(".", &dir);
	if (e != NULL) {
		fprintf(stderr, "%s: %s\n", cwdbf, e);
		return;
	}
	e = gfarm_stringlist_init(&entry_list);
	if (e != NULL) {
		fprintf(stderr, "%s: %s\n", cwdbf, e);
		return;
	}
	while ((e = gfs_readdir(dir, &entry)) == NULL && entry != NULL) {
		char *p;

		if (entry->d_name[0] == '.' && (entry->d_name[1] == '\0' ||
		    (entry->d_name[1] == '.' && entry->d_name[2] == '\0')))
			continue; /* "." or ".." */
	 	p = strdup(entry->d_name);
		if (p == NULL) {
			fprintf(stderr, "%s\n", GFARM_ERR_NO_MEMORY);
			exit (1);
		}
		e = gfarm_stringlist_add(&entry_list, p);
		if (e != NULL) {
			fprintf(stderr, "%s/%s: %s\n",
					cwdbf, entry->d_name, e);
		}
	}
	if (e != NULL)
		fprintf(stderr, "%s: %s\n", cwdbf, e);
	gfs_closedir(dir);
	for (i = 0; i < gfarm_stringlist_length(&entry_list); i++) {
		struct gfs_stat gs;
		char *path = gfarm_stringlist_elem(&entry_list, i);

		e = gfs_stat(path, &gs);
		if (e != NULL) {
			fprintf(stderr, "%s/%s: %s\n", cwdbf, path, e);
			continue;
		}
		if (GFARM_S_ISREG(gs.st_mode)) {
			char *url;

			url = gfarm_url_prefix_add(path);
			if (url == NULL) {
				fprintf(stderr, "%s\n", GFARM_ERR_NO_MEMORY);
				exit (1);
			}
			e = gfs_unlink(url);
			if (e != NULL)
				fprintf(stderr, "%s/%s: %s\n", cwdbf, path, e);
			free(url);
		} else if (GFARM_S_ISDIR(gs.st_mode)) {
			e = gfs_chdir(path);
			if (e != NULL) {
				fprintf(stderr, "%s/%s: %s\n", cwdbf, path, e);
				continue;
			}
			remove_cwd_entries();
			e = gfs_chdir("..");
			if (e != NULL) {
				fprintf(stderr, "%s: %s\n", cwdbf, e);
				exit (1);
			}
			e = gfs_rmdir(path);
			if (e != NULL)
				fprintf(stderr, "%s/%s: %s\n", cwdbf, path, e);
		}
		gfs_stat_free(&gs);
	}
	gfarm_stringlist_free_deeply(&entry_list);
}
예제 #30
0
파일: gfsplck.c 프로젝트: krichter722/gfarm
static int
fixfrag(char *pathname, const char *gfarm_prefix)
{
	char *gfarm_url, *sec, *pname, *gfarm_file, *e;
	struct gfs_stat gst;
	int r = 1;

	gfarm_url = append_prefix_pathname(gfarm_prefix, pathname);
	if (gfarm_url == NULL) {
		print_errmsg(pathname, "not enough memory");
		return (r);
	}

	/* divide into file and section parts. */
	sec = &gfarm_url[strlen(gfarm_url) - 1];
	pname = sec - strlen(pathname) + 1;
	while (sec > pname && *sec != '/') {
		if (*sec == ':') {
			*sec = '\0';
			++sec;
			break;
		}
		--sec;
	}
	if (sec == pname || *sec == '/') {
		print_errmsg(pathname, "invalid filename");
		delete_invalid_file_or_directory(pathname);
		goto error_gfarm_url;
	}

	e = gfs_stat(gfarm_url, &gst);
	if (e == NULL) {
		if (!GFARM_S_ISREG(gst.st_mode)) {
			gfs_stat_free(&gst);
			print_errmsg(gfarm_url, "not a regular file");
			delete_invalid_file_or_directory(pathname);
			goto error_gfarm_url;
		}
		gfs_stat_free(&gst);
	}
	else
		/* permit no fragment case */;

	e = gfarm_url_make_path(gfarm_url, &gfarm_file);
	if (e != NULL) {
		print_errmsg_with_section(gfarm_url, sec, e);
		delete_invalid_file_or_directory(pathname);
		goto error_gfarm_url;
	}

	/* check whether the fragment is already registered. */
	e = fixfrag_i(pathname, gfarm_file, sec);
	if (e != NULL) {
		if (e != GFARM_ERR_ALREADY_EXISTS) {
			print_errmsg_with_section(pathname, sec, e);
			delete_invalid_file_or_directory(pathname);
			goto error_gfarm_file;
		}
		else
			/* no message */;
	}
	else
		printf("%s (%s) on %s: fixed\n", gfarm_url, sec,
		       gfarm_host_get_self_name());
	r = 0;

error_gfarm_file:
	free(gfarm_file);
error_gfarm_url:	
	free(gfarm_url);
	return (r);
}