char * __getcwd(char *buf, size_t size) { const char *e; _gfs_hook_debug_v(fprintf(stderr, "Hooking __getcwd(%p, %d)\n", buf, size)); if (!gfs_hook_cwd_is_gfarm) return (gfs_hook_syscall_getcwd(buf, size)); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __getcwd(%p, %d)\n" ,buf, size)); e = gfs_hook_get_prefix(buf, size); if (e != NULL) goto error; e = gfs_getcwd(buf + strlen(buf), size - strlen(buf)); if (e == NULL) return (buf); error: _gfs_hook_debug(fprintf(stderr, "GFS: __getcwd: %s\n", e)); errno = gfarm_error_to_errno(e); return (NULL); }
int gfsk_gfarm_init(uid_t uid) { gfarm_error_t e; e = gfarm_context_init(); if (e != GFARM_ERR_NO_ERROR) { gflog_error(GFARM_MSG_UNFIXED, "gfarm_context_init failed: %s", gfarm_error_string(e)); goto out; } e = gfarm_set_local_user_for_this_uid(uid); if (e != GFARM_ERR_NO_ERROR) { gflog_error(GFARM_MSG_UNFIXED, "gfarm_set_local_user_for_this_uid failed: %s", gfarm_error_string(e)); goto out; } gflog_initialize(); e = gfarm_config_read(); if (e != GFARM_ERR_NO_ERROR) { gflog_error(GFARM_MSG_UNFIXED, "gfarm_config_read() failed: %s", gfarm_error_string(e)); goto out; } out: return (-gfarm_error_to_errno(e)); }
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); }
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); }
/* * 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); }
/* * fsetxattr */ int fsetxattr(int filedes, const char *name, void *value, size_t size, int flags) { char *e; _gfs_hook_debug_v(fprintf(stderr, "Hooking fsetxattr(%d, %s, %p, %lu, %d)\n", filedes, name, value, (unsigned long)size, flags)); if (!gfs_hook_is_open(filedes)) #ifdef SYS_fsetxattr return syscall(SYS_fsetxattr, filedes, name, value, size, flags); #else { errno = ENOTSUP; return (-1); } #endif _gfs_hook_debug(fprintf(stderr, "GFS: Hooking fsetxattr(%d, %s, %p, %lu, %d)\n", filedes, name, value, (unsigned long)size, flags)); e = GFARM_ERR_OPERATION_NOT_SUPPORTED; _gfs_hook_debug(fprintf(stderr, "GFS: fsetxattr: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
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); }
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); }
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); }
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); }
int __fchdir(int filedes) { GFS_File gf; const char *e; char *url; _gfs_hook_debug_v(fprintf(stderr, "Hooking __fchdir(%d)\n", filedes)); if ((gf = gfs_hook_is_open(filedes)) == NULL) return syscall(SYS_fchdir, filedes); if (gfs_hook_gfs_file_type(filedes) != GFS_DT_DIR) { e = GFARM_ERR_NOT_A_DIRECTORY; goto error; } _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __fchdir(%d)\n", filedes)); e = gfarm_path_canonical_to_url( gfs_hook_get_gfs_canonical_path(filedes), &url); if (e != NULL) goto error; e = gfs_chdir(url); free(url); if (e == NULL) return (0); error: _gfs_hook_debug(fprintf(stderr, "GFS: __fchdir: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
char * __getcwd(char *buf, size_t size) { const char *e; char *p; int alloced = 0; int prefix_size; _gfs_hook_debug_v(fprintf(stderr, "Hooking __getcwd(%p, %lu)\n", buf, (unsigned long)size)); if (!gfs_hook_get_cwd_is_gfarm()) return (gfs_hook_syscall_getcwd(buf, size)); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __getcwd(%p, %lu)\n" ,buf, (unsigned long)size)); if (buf == NULL) { size = 2048; buf = malloc(size); if (buf == NULL) { e = GFARM_ERR_NO_MEMORY; goto error; } alloced = 1; } e = gfs_hook_get_prefix(buf, size); if (e != NULL) goto error; prefix_size = strlen(buf); e = gfs_getcwd(buf + prefix_size, size - prefix_size); if (e == NULL) { /* root in Gfarm FS is a special case. '/gfarm/' -> '/gfarm' */ if (buf[0] == '/' && buf[prefix_size] == '/' && buf[prefix_size + 1] == '\0') buf[prefix_size] = '\0'; if (alloced) { p = realloc(buf, strlen(buf) + 1); if (p != NULL) return (p); } return (buf); } error: if (alloced) free(buf); _gfs_hook_debug(fprintf(stderr, "GFS: __getcwd: %s\n", e)); errno = gfarm_error_to_errno(e); return (NULL); }
/* 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); }
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); }
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); }
/* * convert error string to machine independent error number. * (errno may be different between platforms) * * See also gfarm_errno_error_map[] in error.c. */ enum gfs_proto_error gfs_string_to_proto_error(char *e) { /* * The reason we treat somes errors as special cases * is that those errors may not have corresponding errno on some * platforms. * (So gfs_errno_to_proto_error() cannot convert such errors). */ return (e == GFARM_ERR_AUTHENTICATION ? GFS_ERROR_AUTH : e == GFARM_ERR_EXPIRED ? GFS_ERROR_EXPIRED : e == GFARM_ERR_PROTOCOL ? GFS_ERROR_PROTO : e == GFARM_ERR_PROTOCOL_NOT_SUPPORTED ? GFS_ERROR_PROTONOSUPPORT : e == GFARM_ERR_UNKNOWN ? GFS_ERROR_UNKNOWN : gfs_errno_to_proto_error(gfarm_error_to_errno(e))); }
char * __getcwd(char *buf, size_t size) { const char *e; char *p; int alloced = 0; _gfs_hook_debug_v(fprintf(stderr, "Hooking __getcwd(%p, %lu)\n", buf, (unsigned long)size)); if (!gfs_hook_get_cwd_is_gfarm()) return (gfs_hook_syscall_getcwd(buf, size)); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __getcwd(%p, %lu)\n" ,buf, (unsigned long)size)); if (buf == NULL) { size = 2048; buf = malloc(size); if (buf == NULL) { e = GFARM_ERR_NO_MEMORY; goto error; } alloced = 1; } e = gfs_hook_get_prefix(buf, size); if (e != NULL) goto error; e = gfs_getcwd(buf + strlen(buf), size - strlen(buf)); if (e == NULL) { if (alloced) { p = realloc(buf, strlen(buf) + 1); if (p != NULL) return (p); } return (buf); } error: if (alloced) free(buf); _gfs_hook_debug(fprintf(stderr, "GFS: __getcwd: %s\n", e)); errno = gfarm_error_to_errno(e); return (NULL); }
int __fchmod(int filedes, mode_t mode) { GFS_File gf; char *e, *url; _gfs_hook_debug_v(fprintf(stderr, "Hooking __fchmod(%d, 0%o)\n", filedes, mode)); if ((gf = gfs_hook_is_open(filedes)) == NULL) return syscall(SYS_fchmod, filedes, mode); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __fchmod(%d, 0%o)\n", filedes, mode)); switch (gfs_hook_gfs_file_type(filedes)) { case GFS_DT_REG: e = gfs_fchmod(gf, mode); break; case GFS_DT_DIR: url = gfarm_url_prefix_add(gfs_dirname((GFS_Dir)gf)); if (url == NULL) { e = GFARM_ERR_NO_MEMORY; break; } e = gfs_chmod(url, mode); free(url); break; default: _gfs_hook_debug(fprintf(stderr, "GFS: Hooking __fchmod: couldn't get gf or dir\n")); errno = EBADF; /* XXX - something broken */ return (-1); } if (e == NULL) return (0); _gfs_hook_debug(fprintf(stderr, "GFS: __fchmod: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
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); }
int fgetxattr(int filedes, const char *name, void *value, size_t size) { char *e; _gfs_hook_debug_v(fprintf(stderr, "Hooking fgetxattr(%d, %s, %p, %lu)\n", filedes, name, value, (unsigned long)size)); if (!gfs_hook_is_open(filedes)) return syscall(SYS_fgetxattr, filedes, name, value, size); _gfs_hook_debug(fprintf(stderr, "GFS: Hooking fgetxattr(%d, %s, %p, %lu)\n", filedes, name, value, (unsigned long)size)); e = GFARM_ERR_OPERATION_NOT_SUPPORTED; _gfs_hook_debug(fprintf(stderr, "GFS: fgetxattr: %s\n", e)); errno = gfarm_error_to_errno(e); return (-1); }
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); }
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); }
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 __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); }
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); }
} 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); } free(url); errno = gfarm_error_to_errno(e); return (-1); } if ((oflag & O_CREAT) != 0) { _gfs_hook_debug(gflog_info( "GFS: Hooking " S(FUNC___OPEN) "(%s, 0%o, 0%o)", url, oflag, mode)); oflag = gfs_hook_open_flags_gfarmize(oflag); e = gfs_pio_create(url, oflag, mode, &gf); } else { _gfs_hook_debug(gflog_info( "GFS: Hooking " S(FUNC___OPEN) "(%s, 0%o)", url, oflag)); oflag = gfs_hook_open_flags_gfarmize(oflag);
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); }
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)); } );
int gfs_hook_insert_gfs_dir(GFS_Dir dir, char *url) { int fd, save_errno; char *e, *canonical_path; _gfs_hook_debug(fprintf(stderr, "GFS: insert_gfs_dir: %p\n", dir)); /* * A new file descriptor is needed to identify a hooked file * descriptor. */ fd = open("/dev/null", O_RDONLY); if (fd == -1) { save_errno = errno; gfs_closedir(dir); errno = save_errno; return (-1); } if (fd >= MAX_GFS_FILE_BUF) { __syscall_close(fd); gfs_closedir(dir); errno = EMFILE; return (-1); } if (_gfs_file_buf[fd] != NULL) { __syscall_close(fd); gfs_closedir(dir); errno = EBADF; /* XXX - something broken */ return (-1); } e = gfarm_canonical_path(gfarm_url_prefix_skip(url), &canonical_path); if (e != NULL) { __syscall_close(fd); gfs_closedir(dir); errno = gfarm_error_to_errno(e); return (-1); } _gfs_file_buf[fd] = malloc(sizeof(*_gfs_file_buf[fd])); if (_gfs_file_buf[fd] == NULL) { free(canonical_path); __syscall_close(fd); gfs_closedir(dir); errno = ENOMEM; return (-1); } _gfs_file_buf[fd]->u.d = malloc(sizeof(*_gfs_file_buf[fd]->u.d)); if (_gfs_file_buf[fd]->u.d == NULL) { free(_gfs_file_buf[fd]); _gfs_file_buf[fd] = NULL; free(canonical_path); __syscall_close(fd); gfs_closedir(dir); errno = ENOMEM; return (-1); } e = gfs_stat(url, &_gfs_file_buf[fd]->u.d->gst); if (e != NULL) { free(_gfs_file_buf[fd]->u.d); free(_gfs_file_buf[fd]); _gfs_file_buf[fd] = NULL; free(canonical_path); __syscall_close(fd); gfs_closedir(dir); errno = gfarm_error_to_errno(e); return (-1); } _gfs_file_buf[fd]->refcount = 1; _gfs_file_buf[fd]->d_type = GFS_DT_DIR; _gfs_file_buf[fd]->u.d->dir = dir; _gfs_file_buf[fd]->u.d->suspended = NULL; _gfs_file_buf[fd]->u.d->canonical_path = canonical_path; return (fd); }
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); }