Beispiel #1
0
/*
 * lgetxattr
 */
int
lgetxattr(const char *path, const char *name, void *value, size_t size)
{
	char *e, *gfarm_file;
	char *url;

	_gfs_hook_debug_v(fprintf(stderr,
				  "Hooking lgetxattr(%s, %s, %p, %lu)\n",
				  path, name, value, (unsigned long)size));

	if (!gfs_hook_is_url(path, &url))
#ifdef SYS_lgetxattr
		return syscall(SYS_lgetxattr, path, name, value, size);
#else
	{
		errno = ENODATA;
		return (-1);
	}
#endif

	_gfs_hook_debug(fprintf(stderr,
				"GFS: Hooking lgetxattr(%s, %s, %p, %lu)\n",
				path, name, value, (unsigned long)size));

	e = gfarm_url_make_path(url, &gfarm_file);
	free(url);
	if (e == NULL) {
		e = GFARM_ERR_OPERATION_NOT_SUPPORTED;
		free(gfarm_file);
	}

	_gfs_hook_debug(fprintf(stderr, "GFS: lgetxattr: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
Beispiel #2
0
int
__chdir(const char *path)
{
	const char *e;
	char *url, *sec;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __chdir(%s)\n", path));

	gfs_hook_cwd_is_gfarm = gfs_hook_is_url(path, &url, &sec);
	if (!gfs_hook_cwd_is_gfarm)
		return syscall(SYS_chdir, path);

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __chdir(%s)\n", path));

	e = gfs_chdir(url);
	free(url);
	if (sec != NULL)
		free(sec);
	if (e == NULL)
		return (0);

	_gfs_hook_debug(fprintf(stderr, "GFS: __chdir: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
Beispiel #3
0
int
__chdir(const char *path)
{
	const char *e;
	char *url;
	int r;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __chdir(%s)\n", path));

	if (!gfs_hook_is_url(path, &url)) {
		if ((r = syscall(SYS_chdir, path)) == 0)
			gfs_hook_set_cwd_is_gfarm(0);
		return (r);
	}

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __chdir(%s)\n", path));

	e = gfs_chdir(url);
	free(url);
	if (e == NULL) {
		gfs_hook_set_cwd_is_gfarm(1);
		return (0);
	}
	_gfs_hook_debug(fprintf(stderr, "GFS: __chdir: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
Beispiel #4
0
int
__link(const char *oldpath, const char *newpath)
{
	const char *e;
	char *url;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __link(%s, %s)\n",
				  oldpath, newpath));

	if (!gfs_hook_is_url(newpath, &url))
		return (syscall(SYS_link, oldpath, newpath));

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __link(%s, %s)\n",
				oldpath, newpath));

	/*
	 * Gfarm file system does not support the creation of
	 * hard link yet.
	 */
	e = GFARM_ERR_OPERATION_NOT_PERMITTED; /* EPERM */
	free(url);

	_gfs_hook_debug(fprintf(stderr, "GFS: __link: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
Beispiel #5
0
int
__utime(const char *path, const struct utimbuf *buf)
{
	char *e, *url;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __utime(%s, %p)\n",
	    path, buf));

	if (!gfs_hook_is_url(path, &url))
		return syscall(SYS_utime, path, buf);

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __utime(%s)\n", url));
	if (buf == NULL)
		e = gfs_utimes(url, NULL);
	else {
		struct gfarm_timespec gt[2];
		
		gt[0].tv_sec = buf->actime;
		gt[0].tv_nsec= 0;
		gt[1].tv_sec = buf->modtime;
		gt[1].tv_nsec= 0;
		e = gfs_utimes(url, gt);
	}
	free(url);
	if (e == NULL)
		return (0);

	_gfs_hook_debug(fprintf(stderr, "GFS: __utime: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
Beispiel #6
0
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);
}
Beispiel #7
0
int
__rename(const char *oldpath, const char *newpath)
{
	const char *e;
	char *oldurl, *newurl;
	int old_is_url, new_is_url;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __rename(%s, %s)\n",
				  oldpath, newpath));

	old_is_url = gfs_hook_is_url(oldpath, &oldurl);
	new_is_url = gfs_hook_is_url(newpath, &newurl);
	if (!old_is_url || !new_is_url) {
		if (old_is_url)
			free(oldurl);
		if (new_is_url)	
			free(newurl);
		if (old_is_url != new_is_url) {
			errno = EXDEV;
			return (-1);
		}
		return (syscall(SYS_rename, oldpath, newpath));
	}

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __rename(%s, %s)\n",
				oldpath, newpath));

	e = gfs_rename(oldurl, newurl);
	free(oldurl);
	free(newurl);
	if (e == NULL)
		return (0);

	_gfs_hook_debug(fprintf(stderr, "GFS: __rename: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
Beispiel #8
0
int
__utimes(const char *path, const struct timeval *tvp)
{
	char *e, *url, *sec;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __utimes(%s, %p)\n",
	    path, tvp));

	if (!gfs_hook_is_url(path, &url, &sec)) {
#ifdef __linux__
		if (tvp == NULL) {
			return syscall(SYS_utime, path, NULL);
		} else {
			struct utimbuf ut;

			ut.actime = tvp[0].tv_sec;
			ut.modtime = tvp[1].tv_sec;
			return syscall(SYS_utime, path, &ut);
		}
#else
		return syscall(SYS_utimes, path, tvp);
#endif
	}

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __utimes(%s)\n", url));
	if (tvp == NULL)
		e = gfs_utimes(url, NULL);
	else {
		struct gfarm_timespec gt[2];
		
		gt[0].tv_sec = tvp[0].tv_sec;
		gt[0].tv_nsec= tvp[0].tv_usec * 1000;
		gt[1].tv_sec = tvp[1].tv_sec;
		gt[1].tv_nsec= tvp[1].tv_usec * 1000;
		e = gfs_utimes(url, gt);
	}
	free(url);
	if (sec != NULL)
		free(sec);
	if (e == NULL)
		return (0);

	_gfs_hook_debug(fprintf(stderr, "GFS: __utimes: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
Beispiel #9
0
int
__execve(const char *filename, char *const argv [], char *const envp[])
{
	char *url, *e;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __execve(%s)\n", filename));

	if (!gfs_hook_is_url(filename, &url))
		return syscall(SYS_execve, filename, argv, envp);

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __execve(%s)\n", url));
	e = gfs_execve(url, argv, envp);
	free(url);
	_gfs_hook_debug(fprintf(stderr, "GFS: __execve: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
Beispiel #10
0
int
__unlink(const char *path)
{
	const char *e;
	char *url;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __unlink(%s)\n", path));

	if (!gfs_hook_is_url(path, &url))
		return syscall(SYS_unlink, path);

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __unlink(%s)\n", path));
	e = gfs_unlink(url);
	free(url);
	if (e == NULL)
		return (0);

	_gfs_hook_debug(fprintf(stderr, "GFS: __unlink: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
Beispiel #11
0
int
__access(const char *path, int type)
{
	char *e, *url;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __access(%s, %d)\n",
	    path, type));

	if (!gfs_hook_is_url(path, &url))
		return syscall(SYS_access, path, type);

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __access(%s, %d)\n",
				path, type));
	e = gfs_access(url, type);
	free(url);
	if (e == NULL)
		return (0);

	_gfs_hook_debug(fprintf(stderr, "GFS: __access: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
Beispiel #12
0
int
__chmod(const char *path, mode_t mode)
{
	const char *e;
	char *url;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __chmod(%s, 0%o)\n",
				path, mode));

	if (!gfs_hook_is_url(path, &url))
		return syscall(SYS_chmod, path, mode);

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __chmod(%s, 0%o)\n",
				path, mode));
	e = gfs_chmod(url, mode);
	free(url);
	if (e == NULL)
		return (0);

	_gfs_hook_debug(fprintf(stderr, "GFS: __chmod: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
Beispiel #13
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));
		}
	);
Beispiel #14
0
int
__execve(const char *filename, char *const argv [], char *const envp[])
{
	char *url, *e;
	int status, r;
	pid_t pid;

	_gfs_hook_debug(fprintf(stderr, "Hooking __execve(%s)\n", filename));

	if (!gfs_hook_is_url(filename, &url)) {
		if (gfs_hook_num_gfs_files() > 0) {
			_gfs_hook_debug(
			    fprintf(stderr, "GFS: __execve(%s) - fork : %d\n",
				    filename, gfs_hook_num_gfs_files()));
			/* flush all of buffer */
			gfs_hook_flush_all();
			/* all files may be accessed by the child process */
			gfs_hook_mode_calc_digest_all();
			pid = fork();
		}
		else
			pid = 0;

		switch (pid) {
		case -1:
			_gfs_hook_debug(perror("GFS: fork"));
			status = 255;
			break;
		case 0:
			r = syscall(SYS_execve, filename, argv, envp);
			if (gfs_hook_num_gfs_files() == 0)
				return (r);
			_gfs_hook_debug(perror(filename));
			exit(255);
		default:
			while ((r = waitpid(pid, &status, 0)) == -1 &&
			       errno == EINTR);
			if (r == -1) {
				_gfs_hook_debug(perror("GFS: waitpid"));
				status = 255;
			}
			else if (WIFEXITED(status)) {
				switch (WEXITSTATUS(status)) {
				case 255:
					/* child process fails in execve */
					_gfs_hook_debug(
					 fprintf(stderr, "%s(%d): %s\n",
					 "GFS: waitpid", pid, "status 255"));
					/* XXX - need to obtain from child */
					errno = ENOENT;
					return (-1);
				default:
					status = WEXITSTATUS(status);
					break;
				}
			}
			else if (WIFSIGNALED(status)) {
				_gfs_hook_debug(
				 fprintf(stderr,
				  "%s(%d): signal %d received%s.\n",
				  "GFS: waitpid", pid, WTERMSIG(status),
				  WCOREDUMP(status) ? " (core dumped)" : ""));
				/* propagate the signal */
				raise(WTERMSIG(status));
				status = 255;
			}
			break;
		}
		e = gfs_hook_close_all();
		if (e != NULL)
			_gfs_hook_debug(fprintf(stderr, "close_all: %s\n", e));
		exit(status);
	}
	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __execve(%s)\n", url));
	e = gfs_execve(url, argv, envp);
	free(url);
	_gfs_hook_debug(fprintf(stderr, "GFS: __execve: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
Beispiel #15
0
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);
}
Beispiel #16
0
int
FUNC___OPEN(const char *path, int oflag, ...)
{
	GFS_File gf;
	const char *e;
	char *url;
	va_list ap;
	mode_t mode;
	int filedes;
	struct gfs_stat gs;
	int file_exist, file_size = 0, is_directory = 0;
	int nf = -1, np;

	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))
		return (SYSCALL_OPEN(path, oflag, mode));

	if (gfs_hook_get_current_view() == section_view)
		e = gfs_stat_section(url, gfs_hook_get_current_section(), &gs);
	else
		e = gfs_stat(url, &gs);
	if (e == GFARM_ERR_NO_SUCH_OBJECT)
		file_exist = 0;
	else if (e == NULL) {
		file_exist = 1;
		file_size = gs.st_size;
		is_directory = GFARM_S_ISDIR(gs.st_mode);
		gfs_stat_free(&gs);
	}
	else {
		_gfs_hook_debug(fprintf(stderr,
		    "GFS: Hooking " S(FUNC___OPEN) ": gfs_stat: %s\n", e));
		/* XXX - metadata may be incomplete. anyway, continue. */
		file_exist = 1;
		file_size = 0;
		/* XXX - metadata of a directory should not be imcomplete */
		is_directory = 0; 
	}

	/*
	 * XXX - stopgap implementation of O_WRONLY/O_RDWR, O_CREAT,
	 * O_TRUNC flags
	 */
	if (!file_exist && (oflag & O_CREAT) != 0) {

		_gfs_hook_debug(fprintf(stderr,
		    "GFS: Hooking " S(FUNC___OPEN) "(%s, 0x%x, 0%o)\n",
		    url, oflag, mode));

		e = gfs_pio_create(url, oflag, mode, &gf);
		if (e == NULL)
			gfs_hook_add_creating_file(gf);
	}
	else if ((oflag & O_ACCMODE) == O_WRONLY
		 || (oflag & O_ACCMODE) == O_RDWR) {

		_gfs_hook_debug(fprintf(stderr,
		    "GFS: Hooking " S(FUNC___OPEN) "(%s, 0x%x, 0%o)\n",
		    url, oflag, mode));

		if (file_exist && (file_size == 0 || (oflag & O_TRUNC) != 0)) {
			/*
			 * XXX - O_TRUNC is basically supported in
			 * Gfarm v1 except in global file view.
			 * This case needs to be implemented in
			 * gfs_pio_set_view_global() in gfs_pio_global.c.
			 */
			if (gfs_hook_get_current_view() == global_view)
				gfs_unlink(url); /* XXX - FIXME */
			/*
			 * gfs_pio_create assumes GFARM_FILE_TRUNC.
			 * It is not necessary to set O_TRUNC explicitly.
			 */
			e = gfs_pio_create(url, oflag, mode, &gf);
			if (e == NULL)
				gfs_hook_add_creating_file(gf);
		}
		else if (file_exist) { /* read-write mode: not supported yet */
			_gfs_hook_debug(fprintf(stderr,
				"GFS: Hooking " S(FUNC___OPEN)
				": unsupported flags 0%o\n", oflag));
			free(url);
			errno = ENOSYS;
			return (-1);
		}
		else { /* no such file or directory */
			_gfs_hook_debug(fprintf(stderr,
				"GFS: Hooking " S(FUNC___OPEN)
				": no such file or directory\n"));
			free(url);
			errno = ENOENT;
			return (-1);
		}
	}
	/* XXX - end of stopgap implementation */
	else {
		_gfs_hook_debug(fprintf(stderr,
		    "GFS: Hooking " S(FUNC___OPEN) "(%s, 0x%x)\n", url, oflag));

		if (file_exist && is_directory) {
			GFS_Dir dir;

			e = gfs_opendir(url, &dir);
                        if (e == NULL) {
                                filedes = gfs_hook_insert_gfs_dir(dir, url);
                                _gfs_hook_debug(
                                        if (filedes != -1) {
                                                fprintf(stderr,
                                                    "GFS: Hooking "
                                                    S(FUNC___OPEN)
                                                    " --> %d\n", filedes);
                                        }
                                );
                                free(url);
                                return (filedes);
			}
Beispiel #17
0
int
FUNC___OPEN(const char *path, int oflag, ...)
{
	GFS_File gf;
	const char *e;
	char *url;
	va_list ap;
	mode_t mode;
	int filedes;
	struct gfs_stat gs;
	int is_directory, save_errno;
	int nf = -1, np;

	va_start(ap, oflag);
	/*
	 * We need `int' instead of `mode_t' in va_arg() below, because
	 * sizeof(mode_t) < sizeof(int) on some platforms (e.g. FreeBSD),
	 * and gcc-3.4/gcc-4's builtin va_arg() warns the integer promotion.
	 * XXX	this doesn't work, if sizeof(mode_t) > sizeof(int),
	 *	but currently there isn't any such platform as far as we know.
	 */
	mode = va_arg(ap, int);
	va_end(ap);

	_gfs_hook_debug_v(gflog_info(
	    "Hooking " S(FUNC___OPEN) "(%s, 0%o)", path, oflag));

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

	if (gfs_hook_get_current_view() == section_view)
		e = gfs_stat_section(url, gfs_hook_get_current_section(), &gs);
	else
		e = gfs_stat(url, &gs);
	if (e == NULL) {
		is_directory = GFARM_S_ISDIR(gs.st_mode);
		gfs_stat_free(&gs);
	} else {
		/* XXX - metadata may be incomplete. anyway, continue. */
		/* XXX - metadata of a directory should not be imcomplete */
		is_directory = 0;
		if (e != GFARM_ERR_NO_SUCH_OBJECT)
			_gfs_hook_debug(gflog_info(
			    "GFS: Hooking " S(FUNC___OPEN) ": gfs_stat: %s",
			    e));
	}

	if (is_directory) {
		GFS_Dir dir;

		_gfs_hook_debug(gflog_info(
		   "GFS: Hooking " S(FUNC___OPEN) "(%s, 0%o): dir",
		    url, oflag));

		if ((oflag & (O_CREAT|O_TRUNC)) != 0 ||
		    (oflag & O_ACCMODE) != O_RDONLY) {
			free(url);
			errno = EISDIR;
			return (-1);
		}
		e = gfs_opendir(url, &dir);
		if (e == NULL) {
			filedes = gfs_hook_insert_gfs_dir(dir, url);
			save_errno = errno;
			_gfs_hook_debug(
				gflog_info("GFS: Hooking "
				    S(FUNC___OPEN) " --> %d", filedes);
			);
			free(url);
			if (filedes == -1)
				errno = save_errno;
			return (filedes);
		}