예제 #1
0
static int
gfs_pio_view_global_fd(GFS_File gf)
{
	struct gfs_file_global_context *gc = gf->view_context;

	return (gfs_pio_fileno(gc->fragment_gf));
}
예제 #2
0
int
gfs_hook_insert_gfs_file(GFS_File gf)
{
	int fd, save_errno;

	_gfs_hook_debug(fprintf(stderr, "gfs_hook_insert_gfs_file: %p\n", gf));

	fd = dup(gfs_pio_fileno(gf));
	if (fd == -1) {
		save_errno = errno;
		gfs_pio_close(gf);
		errno = save_errno;
		return (-1);
	}
	if (fd >= MAX_GFS_FILE_BUF) {
		__syscall_close(fd);
		gfs_pio_close(gf);
		errno = EMFILE;
		return (-1);
	}
	if (_gfs_file_buf[fd] != NULL) {
		__syscall_close(fd);
		gfs_pio_close(gf);
		errno = EBADF; /* XXX - something broken */
		return (-1);
	}
	_gfs_file_buf[fd] = gf;
	return (fd);
}
예제 #3
0
int
gfs_hook_insert_gfs_file(GFS_File gf)
{
	int fd, save_errno;
	struct stat st;

	_gfs_hook_debug(fprintf(stderr, "GFS: insert_gfs_file: %p\n", gf));

	/*
	 * A new file descriptor is needed to identify a hooked file
	 * descriptor.
	 */
	fd = gfs_pio_fileno(gf);
	if (fstat(fd, &st) == -1) {
		save_errno = errno;
		gfs_hook_delete_creating_file(gf);
		gfs_pio_close(gf);
		errno = save_errno;
		return (-1);
	}
	if (S_ISREG(st.st_mode))
		fd = dup(fd);
	else /* don't return a socket, to make select(2) work with this fd */
		fd = open("/dev/null", O_RDWR);
	if (fd == -1) {
		save_errno = errno;
		gfs_hook_delete_creating_file(gf);
		gfs_pio_close(gf);
		errno = save_errno;
		return (-1);
	}
	if (fd >= MAX_GFS_FILE_BUF) {
		__syscall_close(fd);
		gfs_hook_delete_creating_file(gf);
		gfs_pio_close(gf);
		errno = EMFILE;
		return (-1);
	}
	if (_gfs_file_buf[fd] != NULL) {
		__syscall_close(fd);
		gfs_hook_delete_creating_file(gf);
		gfs_pio_close(gf);
		errno = EBADF; /* XXX - something broken */
		return (-1);
	}
	_gfs_file_buf[fd] = malloc(sizeof(*_gfs_file_buf[fd]));
	if (_gfs_file_buf[fd] == NULL) {
		__syscall_close(fd);
		gfs_hook_delete_creating_file(gf);
		gfs_pio_close(gf);
		errno = ENOMEM;
		return (-1);
	}
	_gfs_file_buf[fd]->refcount = 1;
	_gfs_file_buf[fd]->d_type = GFS_DT_REG;
	_gfs_file_buf[fd]->u.f = gf;
	return (fd);
}
예제 #4
0
파일: hooks.c 프로젝트: krichter722/gfarm
/* fprintf and fputs should not be put into the following function. */
ssize_t
__write(int filedes, const void *buf, size_t nbyte)
{
	GFS_File gf;
	char *e;
	int n;

	/* 
	 * DO NOT put the following line here. This causes infinite loop!
	 *
	 * _gfs_hook_debug_v(fprintf(stderr, "Hooking __write(%d, , %lu)\n",
	 *     filedes, (unsigned long)nbyte));
	 */

	if ((gf = gfs_hook_is_open(filedes)) == NULL)
		return (syscall(SYS_write, filedes, buf, nbyte));

	if (gfs_hook_gfs_file_type(filedes) == GFS_DT_DIR) {
		/*
		 * DO NOT put the following line here, which results
		 * in infinite loop.
		 * 
		 * _gfs_hook_debug(fprintf(stderr,
		 *			"GFS: Hooking __write(%d, , %d)\n",
		 *			filedes, nbyte));
		 */
		e = GFARM_ERR_IS_A_DIRECTORY;
		goto error;
	}

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __write(%d(%d), , %lu)\n",
	    filedes, gfs_pio_fileno(gf), (unsigned long)nbyte));

	e = gfs_pio_write(gf, buf, nbyte, &n);
	if (e == NULL) {
		_gfs_hook_debug_v(fprintf(stderr,
		    "GFS: Hooking __write --> %d\n", n));
		return (n);
	}
error:
	/*
	 * DO NOT put the following line here.
	 *
	 * _gfs_hook_debug(fprintf(stderr, "GFS: __write: %s\n", e));
	 */
	errno = gfarm_error_to_errno(e);
	return (-1);
}
예제 #5
0
파일: hooks.c 프로젝트: krichter722/gfarm
/*
 * mmap
 *
 * XXX - just print out the information.
 */

#if 0 /* XXX - Linux causes a segfault while loading a shared library.
	       Should we call old_map() instead of syscall(SYS_mmap)??? */
void *
__mmap(void *addr, size_t len, int prot, int flags, int fildes, off_t off)
{
	GFS_File gf;
	int gfs_fd;

	_gfs_hook_debug_v(fprintf(stderr,
		"Hooking __mmap(%p, %d, %d, %d, %d, %d)\n",
		addr, len, prot, flags, fildes, (int)off));

	if ((gf = gfs_hook_is_open(fildes)) == NULL)
		return (void *)syscall(
			SYS_mmap, addr, len, prot, flags, fildes, off);

	_gfs_hook_debug(fprintf(stderr,
		"GFS: Hooking __mmap(%p, %d, %d, %d, %d, %d)\n",
		addr, len, prot, flags, fildes, (int)off));

	gfs_fd = gfs_pio_fileno(gf);
	return (void *)syscall(SYS_mmap, addr, len, prot, flags, gfs_fd, off);
}
예제 #6
0
파일: hooks.c 프로젝트: krichter722/gfarm
ssize_t
__read(int filedes, void *buf, size_t nbyte)
{
	GFS_File gf;
	char *e;
	int n;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __read(%d, , %d)\n",
	    filedes, nbyte));

	if ((gf = gfs_hook_is_open(filedes)) == NULL)
		return syscall(SYS_read, filedes, buf, nbyte);

	if (gfs_hook_gfs_file_type(filedes) == GFS_DT_DIR) {
		_gfs_hook_debug(fprintf(stderr,
					"GFS: Hooking __read(%d, , %d)\n",
	    				filedes, nbyte));

		e = GFARM_ERR_IS_A_DIRECTORY;
		goto error;
	}

	_gfs_hook_debug(fprintf(stderr, "GFS: Hooking __read(%d(%d), , %d)\n",
	    filedes, gfs_pio_fileno(gf), nbyte));

	e = gfs_pio_read(gf, buf, nbyte, &n);
	if (e == NULL) {
		_gfs_hook_debug_v(fprintf(stderr,
		    "GFS: Hooking __read --> %d\n", n));
		return (n);
	}
error:

	_gfs_hook_debug(fprintf(stderr, "GFS: __read: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
예제 #7
0
파일: hooks.c 프로젝트: krichter722/gfarm
int
__close(int filedes)
{
	GFS_File gf;
	char *e;

	_gfs_hook_debug_v(fprintf(stderr, "Hooking __close(%d)\n", filedes));

	if ((gf = gfs_hook_is_open(filedes)) == NULL)
		return (__syscall_close(filedes));

	switch (gfs_hook_gfs_file_type(filedes)) {
	case GFS_DT_REG:
		_gfs_hook_debug(fprintf(stderr,
					"GFS: Hooking __close(%d(%d))\n",
					filedes, gfs_pio_fileno(gf)));
		break;
	case GFS_DT_DIR:
		_gfs_hook_debug(fprintf(stderr,
					"GFS: Hooking __close(%d)\n",
					filedes));
		break;
	default:
		_gfs_hook_debug(fprintf(stderr,
			"GFS: Hooking __close: couldn't get gf or dir\n"));
		errno = EBADF; /* XXX - something broken */
		return (-1);			
	}

	e = gfs_hook_clear_gfs_file(filedes);
	if (e == NULL)
		return (0);
	_gfs_hook_debug(fprintf(stderr, "GFS: __close: %s\n", e));
	errno = gfarm_error_to_errno(e);
	return (-1);
}
예제 #8
0
static gfarm_error_t
gfarm_redirect_file(int fd, char *file, GFS_File *gf)
{
	gfarm_error_t e;
	int nfd;

	if (file == NULL)
		return (GFARM_ERR_NO_ERROR);

	e = gfs_pio_create(file, GFARM_FILE_WRONLY, 0644, gf);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);

	e = gfs_pio_set_view_local(*gf, 0);
	if (e != GFARM_ERR_NO_ERROR)
		return (e);

	nfd = gfs_pio_fileno(*gf);
	if (nfd == -1)
		return (gfarm_errno_to_error(errno));

	/*
	 * This assumes the file fragment is created in the local
	 * spool.
	 */
	if (dup2(nfd, fd) == -1)
		e = gfarm_errno_to_error(errno);

	/* XXX - apparently violate the layer */
	((struct gfs_file_section_context *)(*gf)->view_context)->fd = fd;
	(*gf)->mode &= ~GFS_FILE_MODE_CALC_DIGEST;

	close(nfd);

	return (e);
}
예제 #9
0
/* XXX FIXME */
static gfarm_error_t
gfs_replicate_from_to_internal(GFS_File gf, char *srchost, int srcport,
	char *dsthost, int dstport)
{
	gfarm_error_t e;
	struct gfm_connection *gfm_server = gfs_pio_metadb(gf);
	struct gfs_connection *gfs_server;
	int nretry = 1, gfsd_retried = 0, failover_retried = 0;

retry:
	gfm_server = gfs_pio_metadb(gf);
	if ((e = gfs_client_connection_and_process_acquire(
	    &gfm_server, dsthost, dstport, &gfs_server, NULL))
		!= GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1001388,
			"acquirement of client connection failed: %s",
			gfarm_error_string(e));
		return (e);
	}

	e = gfs_client_replica_add_from(gfs_server, srchost, srcport,
	    gfs_pio_fileno(gf));
	gfs_client_connection_free(gfs_server);
	if (e != GFARM_ERR_NO_ERROR) {
		gflog_debug(GFARM_MSG_1003878,
		    "gfs_client_replica_add_from: %s",
		    gfarm_error_string(e));
		if (nretry-- > 0) {
			if (gfs_client_is_connection_error(e)) {
				gfsd_retried = 1;
				goto retry;
			}
			if (gfs_pio_should_failover(gf, e)) {
				if ((e = gfs_pio_failover(gf))
				    != GFARM_ERR_NO_ERROR) {
					gflog_debug(GFARM_MSG_1003879,
					    "gfs_pio_failover: %s",
					    gfarm_error_string(e));
				} else {
					failover_retried = 1;
					goto retry;
				}
			}
		}
	}
	if ((e == GFARM_ERR_ALREADY_EXISTS || e == GFARM_ERR_FILE_BUSY) &&
	    (gfsd_retried || failover_retried)) {
		gflog_warning(GFARM_MSG_1003453,
		    "error ocurred at retry for the operation after "
		    "connection to %s, "
		    "so the operation possibly succeeded in the server."
		    " error='%s'",
		    gfsd_retried && failover_retried ?
		    "gfsd was disconnected and connection to "
		    "gfmd was failed over" :
		    gfsd_retried ?
		    "gfsd was disconnected" :
		    "gfmd was failed over" ,
		    gfarm_error_string(e));
	}
	return (e);
}
예제 #10
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));
		}
	);