Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 5 additions & 10 deletions capio-common/capio/filesystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -72,17 +72,12 @@ inline bool is_capio_dir(const std::filesystem::path &path_to_check) {
inline bool is_capio_path(const std::filesystem::path &path_to_check) {
START_LOG(capio_syscall(SYS_gettid), "call(path_to_check=%s)", path_to_check.c_str());

// check if path_to_check begins with CAPIO_DIR
const auto is_prefix_res = is_prefix(get_capio_dir(), path_to_check);
// check if path_to_check begins with CAPIO_DIR and is not within the forbidden paths
const auto is_capio_path =
is_prefix(get_capio_dir(), path_to_check) && !is_forbidden_path(path_to_check.string());

LOG("IS PREFIX=%s", is_prefix_res ? "TRUE" : "FALSE");

const auto is_forbidden_res = is_forbidden_path(path_to_check.string());

LOG("IS FORBIDDEN=%s", is_forbidden_res ? "TRUE" : "FALSE");

LOG("is_capio_path:%s", is_prefix_res && !is_forbidden_res ? "yes" : "no");
return is_prefix_res && !is_forbidden_res;
LOG("is_capio_path:%s", is_capio_path ? "yes" : "no");
return is_capio_path;
}

/**
Expand Down
6 changes: 3 additions & 3 deletions capio-posix/handlers/exit.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -21,15 +21,15 @@ int exit_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg
syscall_no_intercept_flag = true;
LOG("syscall_no_intercept_flag = true");

delete_caches();
LOG("Removed caches");

if (is_capio_tid(tid)) {
LOG("Thread %d is a CAPIO thread: clean up", tid);
exit_group_request(tid);
remove_capio_tid(tid);
}

delete_caches();
LOG("Removed caches");

if (const auto itm = bufs_response->find(tid); itm != bufs_response->end()) {
delete itm->second;
bufs_response->erase(tid);
Expand Down
5 changes: 4 additions & 1 deletion capio-posix/utils/cache/read_request_cache_fs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,7 +48,7 @@
} else {
LOG("[cache] Entry not found, initializing new entry to offset 0");
max_read = 0;
available_read_cache->emplace(current_path, max_read);
available_read_cache->emplace(current_path, 0);
}
LOG("[cache] Max read value is %llu %s", max_read,
max_read == ULLONG_MAX ? "(ULLONG_MAX)" : "");
Expand All @@ -65,9 +65,12 @@
max_read = _read_request(current_path, end_of_read, tid, fd);
LOG("[cache] Obtained value from server is %llu", max_read);
if (available_read_cache->find(path) == available_read_cache->end()) {
LOG("[cache] Cound not find entry in cache. Adding new entry to cache");

Check failure on line 68 in capio-posix/utils/cache/read_request_cache_fs.hpp

View workflow job for this annotation

GitHub Actions / Check codespell conformance

Cound ==> Could, Count, Found
available_read_cache->emplace(path, max_read);
} else {
available_read_cache->at(path) = max_read;
LOG("[cache] Updating max read value in cache. new value: %llu",
available_read_cache->at(path));
}
LOG("[cache] completed update from server of max read for file. returning control to "
"application");
Expand Down
43 changes: 21 additions & 22 deletions capio-posix/utils/cache/write_request_cache_fs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,19 +2,18 @@
#define WRITE_REQUEST_CACHE_FS_HPP

class WriteRequestCacheFS {
int current_fd = -1;
capio_off64_t current_size = 0;
std::unordered_map<std::string, capio_off64_t> capio_internal_write_offsets;

const capio_off64_t _max_size;

std::filesystem::path current_path;

// non-blocking as write is not in the pre port of CAPIO semantics
inline void _write_request(const off64_t count, const long tid, const long fd) const {
inline void _write_request(capio_off64_t count, const long tid, const long fd) const {
START_LOG(capio_syscall(SYS_gettid), "call(path=%s, count=%ld, tid=%ld)",
current_path.c_str(), count, tid);
char req[CAPIO_REQ_MAX_SIZE];
sprintf(req, "%04d %ld %ld %s %ld", CAPIO_REQUEST_WRITE, tid, fd, current_path.c_str(),
sprintf(req, "%04d %ld %ld %s %llu", CAPIO_REQUEST_WRITE, tid, fd, current_path.c_str(),
count);
buf_requests->write(req, CAPIO_REQ_MAX_SIZE);
}
Expand All @@ -24,34 +23,34 @@ class WriteRequestCacheFS {

~WriteRequestCacheFS() {
START_LOG(capio_syscall(SYS_gettid), "call()");
this->flush(capio_syscall(SYS_gettid));
const int tid = capio_syscall(SYS_gettid);
for (auto &[path, size] : capio_internal_write_offsets) {
this->flush(path, tid, -1);
}
}

void write_request(std::filesystem::path path, int tid, int fd, long count) {
void write_request(const std::filesystem::path &path, int tid, int fd, long count) {
START_LOG(capio_syscall(SYS_gettid), "call(path=%s, tid=%ld, fd=%ld, count=%ld)",
path.c_str(), tid, fd, count);
if (fd != current_fd || path.compare(current_path) != 0) {
LOG("File descriptor changed from previous state. updating");
this->flush(tid);
current_path = std::move(path);
current_fd = fd;

if (!capio_internal_write_offsets.contains(path.c_str())) {
capio_internal_write_offsets[path.c_str()] = 0;
}
current_size += count;

if (current_size > _max_size) {
capio_internal_write_offsets[path.c_str()] += count;

if (capio_internal_write_offsets[path.c_str()] >= _max_size) {
LOG("exceeded maximum cache size. flushing...");
this->flush(tid);
this->flush(path, tid, fd);
capio_internal_write_offsets[path.c_str()] = 0;
}
};

void flush(int tid) {
START_LOG(capio_syscall(SYS_gettid), "call(tid=%ld)", tid);
if (current_fd != -1 && current_size > 0) {
LOG("Performing write to SHM");
_write_request(tid, current_fd, current_size);
}
current_fd = -1;
current_size = 0;
void flush(const std::filesystem::path &path, long tid, int fd) {
START_LOG(capio_syscall(SYS_gettid), "call(tid=%ld, path=%s)", tid, path.c_str());

LOG("Performing write to SHM");
_write_request(capio_internal_write_offsets[path.c_str()], tid, fd);
}
};

Expand Down
64 changes: 36 additions & 28 deletions capio-posix/utils/filesystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -307,48 +307,56 @@ inline void set_current_dir(const std::filesystem::path &cwd) {
*/
[[maybe_unused]] [[nodiscard]] static std::string
resolve_possible_symlink(const std::filesystem::path &input_path) {
START_LOG(capio_syscall(SYS_gettid), "call(path=%s)", input_path.c_str());

LOG("Absolute path = %s", input_path.c_str());
// Cache for resolved symbolic links: link -> realpath
static std::unordered_map<std::string, std::string> resolved_symlinks_cache;

if (!resolved_symlinks_cache.contains(input_path)) {
START_LOG(capio_syscall(SYS_gettid), "call(path=%s)", input_path.c_str());

LOG("Absolute path = %s", input_path.c_str());

#ifdef __CAPIO_POSIX
syscall_no_intercept_flag = true;
syscall_no_intercept_flag = true;
#endif

std::filesystem::path resolved, input_abs_path = std::filesystem::absolute(input_path);
std::filesystem::path resolved;

for (const auto &part : input_abs_path) {
resolved /= part;
for (std::filesystem::path input_abs_path = std::filesystem::absolute(input_path);
const auto &part : input_abs_path) {
resolved /= part;

if (part == "." || part.empty()) {
continue;
}
if (part == "..") {
resolved = resolved.parent_path();
continue;
}
if (std::filesystem::is_symlink(resolved)) {
char buf[PATH_MAX]{0};
auto result =
capio_syscall(SYS_readlinkat, AT_FDCWD, resolved.c_str(), buf, sizeof(buf) - 1);
if (result == -1) {
LOG("File might not exist. path was %s and Error is %s", resolved.c_str(),
strerror(errno));
if (part == "." || part.empty()) {
continue;
}

if (std::filesystem::path target(buf); target.is_relative()) {
resolved = resolved.parent_path() / target;
} else {
resolved = target;
if (part == "..") {
resolved = resolved.parent_path();
continue;
}
if (std::filesystem::is_symlink(resolved)) {
char buf[PATH_MAX]{0};
auto result =
capio_syscall(SYS_readlinkat, AT_FDCWD, resolved.c_str(), buf, sizeof(buf) - 1);
if (result == -1) {
LOG("File might not exist. path was %s and Error is %s", resolved.c_str(),
strerror(errno));
continue;
}

if (std::filesystem::path target(buf); target.is_relative()) {
resolved = resolved.parent_path() / target;
} else {
resolved = target;
}
}
}
}
#ifdef __CAPIO_POSIX
syscall_no_intercept_flag = false;
syscall_no_intercept_flag = false;
#endif

return resolved;
resolved_symlinks_cache[input_path] = resolved;
}
return resolved_symlinks_cache[input_path];
}

#endif // CAPIO_POSIX_UTILS_FILESYSTEM_HPP
5 changes: 1 addition & 4 deletions capio-posix/utils/requests.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ inline capio_off64_t posix_directory_committed_request(const long pid,
// non blocking
inline void close_request(const std::filesystem::path &path, const long tid) {
START_LOG(capio_syscall(SYS_gettid), "call(path=%s, tid=%ld)", path.c_str(), tid);
write_request_cache_fs->flush(tid);
write_request_cache_fs->flush(path, tid, -1);
char req[CAPIO_REQ_MAX_SIZE];
sprintf(req, "%04d %ld %s", CAPIO_REQUEST_CLOSE, tid, path.c_str());
buf_requests->write(req, CAPIO_REQ_MAX_SIZE);
Expand All @@ -130,7 +130,6 @@ inline void create_request(const int fd, const std::filesystem::path &path, cons
// non blocking
inline void exit_group_request(const long tid) {
START_LOG(capio_syscall(SYS_gettid), "call(tid=%ld)", tid);
write_request_cache_fs->flush(tid);
char req[CAPIO_REQ_MAX_SIZE];
sprintf(req, "%04d %ld", CAPIO_REQUEST_EXIT_GROUP, tid);
buf_requests->write(req, CAPIO_REQ_MAX_SIZE);
Expand All @@ -140,8 +139,6 @@ inline void exit_group_request(const long tid) {
[[nodiscard]] inline capio_off64_t open_request(const int fd, const std::filesystem::path &path,
const long tid) {
START_LOG(capio_syscall(SYS_gettid), "call(fd=%ld, path=%s, tid=%ld)", fd, path.c_str(), tid);
write_request_cache_fs->flush(tid);

char req[CAPIO_REQ_MAX_SIZE];
sprintf(req, "%04d %ld %d %s", CAPIO_REQUEST_OPEN, tid, fd, path.c_str());
buf_requests->write(req, CAPIO_REQ_MAX_SIZE);
Expand Down
20 changes: 16 additions & 4 deletions capio-server/src/capio-cl-engine/capio_cl_engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -233,15 +233,27 @@ bool CapioCLEngine::isFirable(const std::string &path) {
LOG("Fire rule for file %s is %s", path.c_str(), std::get<3>(itm->second).c_str());
return std::get<3>(itm->second) == CAPIO_FILE_MODE_NO_UPDATE;
}

LOG("No entry found on map. checking globs...");
const auto is_firable = std::any_of(_locations.begin(), _locations.end(), [&](auto &itm) {
LOG("Checking against %s", itm.first.c_str());
if (std::regex_match(path.c_str(), std::get<10>(itm.second))) {
LOG("Found match. Is Firable: %s",
std::get<3>(itm.second) == CAPIO_FILE_MODE_NO_UPDATE ? "YES" : "NO");
return std::get<3>(itm.second) == CAPIO_FILE_MODE_NO_UPDATE;
}
return false;
});

/*
* For caching purpose, each new file is then added to the map if not found,
* with its data being instantiated from the metadata of the most likely matched glob
* TODO: check overhead of this
*/
LOG("No entry found on map. checking globs. Creating new file from globs");
this->newFile((path));
LOG("Creating new file for caching purpose...");
this->newFile(path);
this->setFireRule(path, is_firable ? CAPIO_FILE_MODE_NO_UPDATE : CAPIO_FILE_MODE_UPDATE);
LOG("Fire rule for file %s is %s", path.c_str(), std::get<3>(_locations.at((path))).c_str());
return std::get<3>(_locations.at((path))) == CAPIO_FILE_MODE_NO_UPDATE;
return is_firable;
}

void CapioCLEngine::setPermanent(const std::string &path, bool value) {
Expand Down