Commit 9688d48f authored by Ramon Nou's avatar Ramon Nou
Browse files

fix(client,test): support virtual fds in close_range and improve error handling

parent a3b64fba
Loading
Loading
Loading
Loading
Loading
+20 −5
Changes for src/client/gkfs_libc.cpp: 20 added lines, 5 removed lines.
Original line number Diff line number Diff line
@@ -969,18 +969,33 @@ close_range(unsigned int low, unsigned int high, int flags) {
    gkfs_init_routine_placeholder();
    DEBUG_INFO("close_range({}, {}, {})", low, high, flags);

    if(low > high) {
        errno = EINVAL;
        return -1;
    }

#ifdef CLOSE_RANGE_UNSHARE
    if(flags & CLOSE_RANGE_UNSHARE) {
        DEBUG_INFO("close_range with non-standard CLOSE_RANGE_UNSHARE");
    }
#endif

    if(GKFS_INTERCEPTION_ENABLED()) {
        std::vector<int> fds_to_check = get_open_fds();
#ifndef CLOSE_RANGE_CLOEXEC
#define CLOSE_RANGE_CLOEXEC (1U << 2)
#endif

        for(int fd_val : fds_to_check) {
            if(fd_val >= static_cast<int>(low) &&
               fd_val <= static_cast<int>(high) && is_gkfs_fd(fd_val)) {
    if(GKFS_INTERCEPTION_ENABLED() && CTX && CTX->file_map()) {
        auto gkfs_fds = CTX->file_map()->get_range(low, high);
        if(flags & CLOSE_RANGE_CLOEXEC) {
            for(int fd_val : gkfs_fds) {
                auto open_file = CTX->file_map()->get(fd_val);
                if(open_file) {
                    open_file->set_flag(gkfs::filemap::OpenFile_flags::cloexec,
                                        true);
                }
            }
        } else {
            for(int fd_val : gkfs_fds) {
                DEBUG_INFO("[GKFS] Closing fd {} via close_range", fd_val);
                gkfs::syscall::gkfs_close(fd_val);
            }
+1 −3
Changes for src/client/hooks.cpp: 1 added line, 3 removed lines.
Original line number Diff line number Diff line
@@ -1126,9 +1126,7 @@ hook_fchdir(unsigned int fd) {
    } else {
        long ret = syscall_no_intercept_wrapper(SYS_fchdir, fd);
        if(ret < 0) {
            throw std::system_error(
                    syscall_error_code(ret), std::system_category(),
                    "Failed to change directory (fchdir syscall)");
            return -syscall_error_code(ret);
        }
        gkfs::path::unset_env_cwd();
        try {
+33 −2
Changes for src/client/intercept.cpp: 33 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -795,16 +795,47 @@ hook(long syscall_number, long arg0, long arg1, long arg2, long arg3, long arg4,
            // preloaded client runtime is still active. Forwarding the range
            // closes native runtime descriptors (Mercury/Margo sockets, event
            // fds, etc.) and breaks the client before exec or shutdown.
            const unsigned int first = static_cast<unsigned int>(arg0);
            const unsigned int last = static_cast<unsigned int>(arg1);
            const unsigned int flags = static_cast<unsigned int>(arg2);
            if(first > last) {
                *result = -EINVAL;
                break;
            }
#ifndef CLOSE_RANGE_CLOEXEC
#define CLOSE_RANGE_CLOEXEC (1U << 2)
#endif
            if(CTX && CTX->file_map()) {
                auto gkfs_fds = CTX->file_map()->get_range(first, last);
                if(flags & CLOSE_RANGE_CLOEXEC) {
                    for(auto fd : gkfs_fds) {
                        auto open_file = CTX->file_map()->get(fd);
                        if(open_file) {
                            open_file->set_flag(
                                    gkfs::filemap::OpenFile_flags::cloexec,
                                    true);
                        }
                    }
                } else {
                    for(auto fd : gkfs_fds) {
                        gkfs::syscall::gkfs_close(fd);
                    }
                }
            }
            auto fds = get_open_fds();
            for(auto fd : fds) {
                if(fd < static_cast<int>(arg0) || fd > static_cast<int>(arg1)) {
                if(fd < static_cast<int>(first) ||
                   fd > static_cast<int>(last)) {
                    continue;
                }
                if(CTX->is_internal_fd(fd)) {
                    continue;
                }
                if(CTX->file_map()->exist(fd)) {
                    gkfs::syscall::gkfs_close(fd);
                    continue;
                }
                if(flags & CLOSE_RANGE_CLOEXEC) {
                    syscall_no_intercept(SYS_fcntl, fd, F_SETFD, FD_CLOEXEC);
                } else {
                    close(fd);
                }
+8 −2
Changes for tests/integration/harness/gkfs.py: 8 added lines, 2 removed lines.
Original line number Diff line number Diff line
@@ -783,9 +783,12 @@ class Client:

        logger.debug(f"command output: {output}")
        if out_returncode != 0:
            err_msg = out_stderr.decode('utf-8') if isinstance(out_stderr, bytes) else str(out_stderr)
            logger.error(f"Command failed with return code {out_returncode}")
            if out_stderr:
                 logger.error(f"stderr: {out_stderr.decode('utf-8') if isinstance(out_stderr, bytes) else out_stderr}")
                 logger.error(f"stderr: {err_msg}")
            if not output or not output.strip() or output == "b''":
                raise RuntimeError(f"Command '{cmd}' failed with return code {out_returncode}: {err_msg}")

        json_start = output.find('{')
        if json_start != -1:
@@ -888,9 +891,12 @@ class ClientLibc:


        if out_returncode != 0:
            err_msg = out_stderr.decode('utf-8') if isinstance(out_stderr, bytes) else str(out_stderr)
            logger.error(f"Command failed with return code {out_returncode}")
            if out_stderr:
                 logger.error(f"stderr: {out_stderr.decode('utf-8') if isinstance(out_stderr, bytes) else out_stderr}")
                 logger.error(f"stderr: {err_msg}")
            if not output or not output.strip() or output == "b''":
                raise RuntimeError(f"Command '{cmd}' failed with return code {out_returncode}: {err_msg}")

        return self._parser.parse(cmd, output)