Loading include/client/preload_context.hpp +2 −4 Original line number Diff line number Diff line Loading @@ -56,8 +56,6 @@ struct FsConfig { enum class RelativizeStatus { ok, internal, external, fd_unknown, fd_not_a_dir }; Loading Loading @@ -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, Loading include/config.hpp +9 −0 Original line number Diff line number Diff line Loading @@ -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 Loading src/client/hooks.cpp +145 −143 Original line number Diff line number Diff line Loading @@ -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; } // Loading @@ -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; // } } Loading Loading @@ -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 Loading @@ -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 Loading @@ -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) { Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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) { Loading @@ -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; } } Loading Loading @@ -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) { Loading Loading @@ -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; } } Loading @@ -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; } } Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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; } } Loading Loading @@ -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__); Loading @@ -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__); Loading @@ -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) { Loading Loading
include/client/preload_context.hpp +2 −4 Original line number Diff line number Diff line Loading @@ -56,8 +56,6 @@ struct FsConfig { enum class RelativizeStatus { ok, internal, external, fd_unknown, fd_not_a_dir }; Loading Loading @@ -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, Loading
include/config.hpp +9 −0 Original line number Diff line number Diff line Loading @@ -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 Loading
src/client/hooks.cpp +145 −143 Original line number Diff line number Diff line Loading @@ -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; } // Loading @@ -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; // } } Loading Loading @@ -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 Loading @@ -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 Loading @@ -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) { Loading @@ -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) { Loading Loading @@ -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; Loading @@ -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) { Loading @@ -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; } } Loading Loading @@ -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) { Loading Loading @@ -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; } } Loading @@ -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; } } Loading @@ -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; Loading @@ -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) { Loading Loading @@ -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; } } Loading Loading @@ -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__); Loading @@ -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__); Loading @@ -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) { Loading