Verified Commit 06ee81b5 authored by Marc Vef's avatar Marc Vef
Browse files

Changed all hooks to new method. Squash

parent a745b58d
Loading
Loading
Loading
Loading
+2 −4
Original line number Diff line number Diff line
@@ -56,8 +56,6 @@ struct FsConfig {

enum class RelativizeStatus {
    ok,
    internal,
    external,
    fd_unknown,
    fd_not_a_dir
};
@@ -126,9 +124,9 @@ public:

    bool is_gkfs_path(std::string& path);

    RelativizeStatus normalize_path(int dirfd, const char* raw_path, std::string& normalized_path);
    RelativizeStatus normalize_path(int dirfd, const char* raw_path, std::string& normalized_path, bool resolve_last_link = true);

    RelativizeStatus normalize_path(const char* raw_path, std::string& normalized_path);
    std::string normalize_path(const char* raw_path, bool resolve_last_link = true);

    RelativizeStatus relativize_fd_path(int dirfd,
                                        const char* raw_path,
+9 −0
Original line number Diff line number Diff line
@@ -68,6 +68,15 @@ namespace rocksdb {
constexpr auto use_write_ahead_log = false;
} // namespace rocksdb

namespace preload {
/*
 * This option allows a symlink outside of the GekkoFS namespace into the GekkoFS namespace.
 * This is by default disabled as it incurs a significant overhead during GekkoFS' path resolution.
 * Therefore, it is recommended to keep it disabled
 */
constexpr auto allow_symlinks_into_gkfs = false;
}

} // namespace gkfs
} // namespace config

+145 −143
Original line number Diff line number Diff line
@@ -62,7 +62,7 @@ int hook_openat(int dirfd, const char* cpath, int flags, mode_t mode) {
            else
                return syscall_no_intercept(SYS_openat, dirfd, normalized_path.c_str(), flags, mode);
        default:
            LOG(ERROR, "{}() relativize status unknown: {}", __func__);
            LOG(ERROR, "{}() relativize status unknown", __func__);
            return -EINVAL;
    }
//
@@ -84,7 +84,7 @@ int hook_openat(int dirfd, const char* cpath, int flags, mode_t mode) {
//            return with_errno(gkfs::syscall::gkfs_open(resolved, mode, flags));
//
//        default:
//            LOG(ERROR, "{}() relativize status unknown: {}", __func__);
//            LOG(ERROR, "{}() relativize status unknown", __func__);
//            return -EINVAL;
//    }
}
@@ -113,11 +113,11 @@ int hook_stat(const char* path, struct stat* buf) {
    LOG(DEBUG, "{}() called with path: \"{}\", buf: {}",
        __func__, path, fmt::ptr(buf));

    std::string rel_path;
    if (CTX->relativize_path(path, rel_path, false)) {
        return with_errno(gkfs::syscall::gkfs_stat(rel_path, buf));
    }
    return syscall_no_intercept(SYS_stat, rel_path.c_str(), buf);
    auto normalized_path = CTX->normalize_path(path, false);
    if (CTX->is_gkfs_path(normalized_path))
        return with_errno(gkfs::syscall::gkfs_stat(normalized_path, buf));
    else
        return syscall_no_intercept(SYS_stat, normalized_path.c_str(), buf);
}

#ifdef STATX_TYPE
@@ -126,28 +126,25 @@ int hook_statx(int dirfd, const char* path, int flags, unsigned int mask, struct
    LOG(DEBUG, "{}() called with dirfd: '{}', path: \"{}\", flags: '{}', mask: '{}', buf: '{}'",
        __func__, dirfd, path, flags, mask, fmt::ptr(buf));

    std::string resolved;
    auto rstatus = CTX->relativize_fd_path(dirfd, path, resolved);
    switch (rstatus) {
    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, path, normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_statx, dirfd, path, flags, mask,  buf);

        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_statx, dirfd, resolved.c_str(), flags, mask,  buf);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::internal:
            return with_errno(gkfs::syscall::gkfs_statx(dirfd, resolved.c_str() , flags, mask, buf));

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path))
                return with_errno(gkfs::syscall::gkfs_statx(dirfd, normalized_path.c_str() , flags, mask, buf));
            else
                return syscall_no_intercept(SYS_statx, dirfd, normalized_path.c_str(), flags, mask,  buf);
        default:
            LOG(ERROR, "{}() relativize status unknown: {}", __func__);
            LOG(ERROR, "{}() relativize status unknown", __func__);
            return -EINVAL;

    }
   
    return syscall_no_intercept(SYS_statx, dirfd, path, flags, mask,  buf);
}
#endif

@@ -156,11 +153,11 @@ int hook_lstat(const char* path, struct stat* buf) {
    LOG(DEBUG, "{}() called with path: \"{}\", buf: {}",
        __func__, path, fmt::ptr(buf));

    std::string rel_path;
    if (CTX->relativize_path(path, rel_path)) {
        return with_errno(gkfs::syscall::gkfs_stat(rel_path, buf));
    }
    return syscall_no_intercept(SYS_lstat, rel_path.c_str(), buf);
    auto normalized_path = CTX->normalize_path(path);
    if (CTX->is_gkfs_path(normalized_path))
        return with_errno(gkfs::syscall::gkfs_stat(normalized_path, buf));
    else
        return syscall_no_intercept(SYS_lstat, normalized_path.c_str(), buf);
}

int hook_fstat(unsigned int fd, struct stat* buf) {
@@ -185,25 +182,26 @@ int hook_fstatat(int dirfd, const char* cpath, struct stat* buf, int flags) {
        return -ENOTSUP;
    }

    std::string resolved;
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved);
    switch (rstatus) {
    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, cpath, normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_newfstatat, dirfd, cpath, buf, flags);

        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_newfstatat, dirfd, resolved.c_str(), buf, flags);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::internal:
            return with_errno(gkfs::syscall::gkfs_stat(resolved, buf));

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path))
                return with_errno(gkfs::syscall::gkfs_stat(normalized_path, buf));
            else
                return syscall_no_intercept(SYS_newfstatat, dirfd, normalized_path.c_str(), buf, flags);
        default:
            LOG(ERROR, "{}() relativize status unknown: {}", __func__);
            LOG(ERROR, "{}() relativize status unknown", __func__);
            return -EINVAL;
    }

}

int hook_read(unsigned int fd, void* buf, size_t count) {
@@ -310,58 +308,57 @@ int hook_unlinkat(int dirfd, const char* cpath, int flags) {
        return -EINVAL;
    }

    std::string resolved;
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false);
    switch (rstatus) {
    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, cpath, normalized_path, false);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_unlinkat, dirfd, cpath, flags);

        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_unlinkat, dirfd, resolved.c_str(), flags);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::internal:
        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path)) {
                if (flags & AT_REMOVEDIR) {
                return with_errno(gkfs::syscall::gkfs_rmdir(resolved));
                    return with_errno(gkfs::syscall::gkfs_rmdir(normalized_path));
                } else {
                return with_errno(gkfs::syscall::gkfs_remove(resolved));
                    return with_errno(gkfs::syscall::gkfs_remove(normalized_path));
                }

            } else
                return syscall_no_intercept(SYS_unlinkat, dirfd, normalized_path.c_str(), flags);
        default:
            LOG(ERROR, "{}() relativize status unknown: {}", __func__);
            LOG(ERROR, "{}() relativize status unknown", __func__);
            return -EINVAL;
    }
}

int hook_symlinkat(const char* oldname, int newdfd, const char* newname) {

    LOG(DEBUG, "{}() called with oldname: \"{}\", newfd: {}, newname: \"{}\"",
        __func__, oldname, newdfd, newname);

    std::string oldname_resolved;
    if (CTX->relativize_path(oldname, oldname_resolved)) {
    auto old_normalized_path = CTX->normalize_path(oldname);
    if (CTX->is_gkfs_path(old_normalized_path)) {
        LOG(WARNING, "{}() operation not supported", __func__);
        return -ENOTSUP;
    }

    std::string newname_resolved;
    auto rstatus = CTX->relativize_fd_path(newdfd, newname, newname_resolved, false);
    switch (rstatus) {
    std::string new_normalized_path{};
    auto status = CTX->normalize_path(newdfd, newname, new_normalized_path, false);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_symlinkat, oldname, newdfd, newname);

        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_symlinkat, oldname, newdfd, newname_resolved.c_str());

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::internal:
        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(new_normalized_path)) {
                LOG(WARNING, "{}() operation not supported", __func__);
                return -ENOTSUP;

            } else
                return syscall_no_intercept(SYS_symlinkat, oldname, newdfd, new_normalized_path.c_str());
        default:
            LOG(ERROR, "{}() relativize status unknown", __func__);
            return -EINVAL;
@@ -374,15 +371,15 @@ int hook_access(const char* path, int mask) {
    LOG(DEBUG, "{}() called path: \"{}\", mask: {}",
        __func__, path, mask);

    std::string rel_path;
    if (CTX->relativize_path(path, rel_path)) {
        auto ret = gkfs::syscall::gkfs_access(rel_path, mask);
    auto normalized_path = CTX->normalize_path(path);
    if (CTX->is_gkfs_path(normalized_path)) {
        auto ret = gkfs::syscall::gkfs_access(normalized_path, mask);
        if (ret < 0) {
            return -errno;
        }
        return ret;
    }
    return syscall_no_intercept(SYS_access, rel_path.c_str(), mask);
    return syscall_no_intercept(SYS_access, normalized_path.c_str(), mask);
}

int hook_faccessat(int dirfd, const char* cpath, int mode) {
@@ -390,23 +387,23 @@ int hook_faccessat(int dirfd, const char* cpath, int mode) {
    LOG(DEBUG, "{}() called with dirfd: {}, path: \"{}\", mode: {}",
        __func__, dirfd, cpath, mode);

    std::string resolved;
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved);
    switch (rstatus) {
    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, cpath, normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_faccessat, dirfd, cpath, mode);

        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_faccessat, dirfd, resolved.c_str(), mode);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::internal:
            return with_errno(gkfs::syscall::gkfs_access(resolved, mode));

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path))
                return with_errno(gkfs::syscall::gkfs_access(normalized_path, mode));
            else
                return syscall_no_intercept(SYS_faccessat, dirfd, normalized_path.c_str(), mode);
        default:
            LOG(ERROR, "{}() relativize status unknown: {}", __func__);
            LOG(ERROR, "{}() relativize status unknown", __func__);
            return -EINVAL;
    }
}
@@ -434,11 +431,11 @@ int hook_truncate(const char* path, long length) {
    LOG(DEBUG, "{}() called with path: {}, offset: {}",
        __func__, path, length);

    std::string rel_path;
    if (CTX->relativize_path(path, rel_path)) {
        return with_errno(gkfs::syscall::gkfs_truncate(rel_path, length));
    }
    return syscall_no_intercept(SYS_truncate, rel_path.c_str(), length);
    auto normalized_path = CTX->normalize_path(path);
    if (CTX->is_gkfs_path(normalized_path))
        return with_errno(gkfs::syscall::gkfs_truncate(normalized_path, length));
    else
        return syscall_no_intercept(SYS_truncate, normalized_path.c_str(), length);
}

int hook_ftruncate(unsigned int fd, unsigned long length) {
@@ -518,23 +515,23 @@ int hook_mkdirat(int dirfd, const char* cpath, mode_t mode) {
    LOG(DEBUG, "{}() called with dirfd: {}, path: \"{}\", mode: {}",
        __func__, dirfd, cpath, mode);

    std::string resolved;
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved);
    switch (rstatus) {
        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_mkdirat, dirfd, resolved.c_str(), mode);
    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, cpath, normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_mkdirat, dirfd, cpath, mode);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::internal:
            return with_errno(gkfs::syscall::gkfs_create(resolved, mode | S_IFDIR));

        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path))
                return with_errno(gkfs::syscall::gkfs_create(normalized_path, mode | S_IFDIR));
            else
                return syscall_no_intercept(SYS_mkdirat, dirfd, normalized_path.c_str(), mode);
        default:
            LOG(ERROR, "{}() relativize status unknown: {}", __func__);
            LOG(ERROR, "{}() relativize status unknown", __func__);
            return -EINVAL;
    }
}
@@ -544,24 +541,24 @@ int hook_fchmodat(int dirfd, const char* cpath, mode_t mode) {
    LOG(DEBUG, "{}() called dirfd: {}, path: \"{}\", mode: {}",
        __func__, dirfd, cpath, mode);

    std::string resolved;
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved);
    switch (rstatus) {
    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, cpath, normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_fchmodat, dirfd, cpath, mode);

        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_fchmodat, dirfd, resolved.c_str(), mode);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::internal:
        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path)) {
                LOG(WARNING, "{}() operation not supported", __func__);
                return -ENOTSUP;

            } else
                return syscall_no_intercept(SYS_fchmodat, dirfd, normalized_path.c_str(), mode);
        default:
            LOG(ERROR, "{}() relativize status unknown: {}", __func__);
            LOG(ERROR, "{}() relativize status unknown", __func__);
            return -EINVAL;
    }
}
@@ -583,11 +580,11 @@ int hook_chdir(const char* path) {
    LOG(DEBUG, "{}() called with path: \"{}\"",
        __func__, path);

    std::string rel_path;
    bool internal = CTX->relativize_path(path, rel_path);
    auto normalized_path = CTX->normalize_path(path);
    auto internal = CTX->is_gkfs_path(normalized_path);
    if (internal) {
        //path falls in our namespace
        auto md = gkfs::util::get_metadata(rel_path);
        auto md = gkfs::util::get_metadata(normalized_path);
        if (md == nullptr) {
            LOG(ERROR, "{}() path does not exists", __func__);
            return -ENOENT;
@@ -598,18 +595,19 @@ int hook_chdir(const char* path) {
        }
        //TODO get complete path from relativize_path instead of
        // removing mountdir and then adding again here
        rel_path.insert(0, CTX->mountdir());
        if (gkfs::path::has_trailing_slash(rel_path)) {
        normalized_path.insert(0, CTX->mountdir());
        if (gkfs::path::has_trailing_slash(normalized_path)) {
            // open_dir is '/'
            rel_path.pop_back();
            normalized_path.pop_back();
        }
    }
    try {
        gkfs::path::set_cwd(rel_path, internal);
        gkfs::path::set_cwd(normalized_path, internal);
    } catch (const std::system_error& se) {
        return -(se.code().value());
    }
    return 0;

}

int hook_fchdir(unsigned int fd) {
@@ -668,24 +666,24 @@ int hook_readlinkat(int dirfd, const char* cpath, char* buf, int bufsiz) {
    LOG(DEBUG, "{}() called with dirfd: {}, path \"{}\", buf: {}, bufsize: {}",
        __func__, dirfd, cpath, fmt::ptr(buf), bufsiz);

    std::string resolved;
    auto rstatus = CTX->relativize_fd_path(dirfd, cpath, resolved, false);
    switch (rstatus) {
    std::string normalized_path{};
    auto status = CTX->normalize_path(dirfd, cpath, normalized_path, false);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
            return syscall_no_intercept(SYS_readlinkat, dirfd, cpath, buf, bufsiz);

        case gkfs::preload::RelativizeStatus::external:
            return syscall_no_intercept(SYS_readlinkat, dirfd, resolved.c_str(), buf, bufsiz);

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::internal:
        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(normalized_path)) {
                LOG(WARNING, "{}() not supported", __func__);
                return -ENOTSUP;

            } else
                return syscall_no_intercept(SYS_readlinkat, dirfd, normalized_path.c_str(), buf, bufsiz);
        default:
            LOG(ERROR, "{}() relativize status unknown: {}", __func__);
            LOG(ERROR, "{}() relativize status unknown", __func__);
            return -EINVAL;
    }
}
@@ -763,23 +761,25 @@ int hook_renameat(int olddfd, const char* oldname,
        __func__, olddfd, oldname, newdfd, newname, flags);

    const char* oldpath_pass;
    std::string oldpath_resolved;
    auto oldpath_status = CTX->relativize_fd_path(olddfd, oldname, oldpath_resolved);
    switch (oldpath_status) {
    std::string oldpath_normalized_path{};
    auto status = CTX->normalize_path(olddfd, oldname, oldpath_normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
            oldpath_pass = oldname;
            break;

        case gkfs::preload::RelativizeStatus::external:
            oldpath_pass = oldpath_resolved.c_str();
            break;

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::internal:
        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(oldpath_normalized_path)) {
                LOG(WARNING, "{}() not supported", __func__);
                return -ENOTSUP;
            } else {
                oldpath_pass = oldpath_normalized_path.c_str();
                break;
            }

        default:
            LOG(ERROR, "{}() relativize status unknown", __func__);
@@ -787,23 +787,25 @@ int hook_renameat(int olddfd, const char* oldname,
    }

    const char* newpath_pass;
    std::string newpath_resolved;
    auto newpath_status = CTX->relativize_fd_path(newdfd, newname, newpath_resolved);
    switch (newpath_status) {
    std::string newpath_normalized_path{};
    status = CTX->normalize_path(newdfd, newname, newpath_normalized_path);

    switch (status) {
        case gkfs::preload::RelativizeStatus::fd_unknown:
            newpath_pass = newname;
            break;

        case gkfs::preload::RelativizeStatus::external:
            newpath_pass = newpath_resolved.c_str();
            break;

        case gkfs::preload::RelativizeStatus::fd_not_a_dir:
            return -ENOTDIR;

        case gkfs::preload::RelativizeStatus::internal:
        case gkfs::preload::RelativizeStatus::ok:
            if (CTX->is_gkfs_path(newpath_normalized_path)) {
                LOG(WARNING, "{}() not supported", __func__);
                return -ENOTSUP;
            } else {
                newpath_pass = newpath_normalized_path.c_str();
                break;
            }

        default:
            LOG(ERROR, "{}() relativize status unknown", __func__);
@@ -818,11 +820,11 @@ int hook_statfs(const char* path, struct statfs* buf) {
    LOG(DEBUG, "{}() called with path: \"{}\", buf: {}",
        __func__, path, fmt::ptr(buf));

    std::string rel_path;
    if (CTX->relativize_path(path, rel_path)) {
    auto normalized_path = CTX->normalize_path(path);
    if (CTX->is_gkfs_path(normalized_path))
        return with_errno(gkfs::syscall::gkfs_statfs(buf));
    }
    return syscall_no_intercept(SYS_statfs, rel_path.c_str(), buf);
    else
        return syscall_no_intercept(SYS_statfs, normalized_path.c_str(), buf);
}

int hook_fstatfs(unsigned int fd, struct statfs* buf) {