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