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)); }
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); }
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); }
/* 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); }
/* * 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); }
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); }
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); }
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); }
/* 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); }
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)); } );