Skip to content

Commit b45603b

Browse files
authored
Improved performances on cache. Fixed bug on CapioClEngine::isFirable (#174)
Co-authored-by: Marco Edoardo Santimaria <marcoedoardo.santimaria@unito.it>
1 parent 2997b26 commit b45603b

7 files changed

Lines changed: 86 additions & 72 deletions

File tree

capio-common/capio/filesystem.hpp

Lines changed: 5 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -72,17 +72,12 @@ inline bool is_capio_dir(const std::filesystem::path &path_to_check) {
7272
inline bool is_capio_path(const std::filesystem::path &path_to_check) {
7373
START_LOG(capio_syscall(SYS_gettid), "call(path_to_check=%s)", path_to_check.c_str());
7474

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

78-
LOG("IS PREFIX=%s", is_prefix_res ? "TRUE" : "FALSE");
79-
80-
const auto is_forbidden_res = is_forbidden_path(path_to_check.string());
81-
82-
LOG("IS FORBIDDEN=%s", is_forbidden_res ? "TRUE" : "FALSE");
83-
84-
LOG("is_capio_path:%s", is_prefix_res && !is_forbidden_res ? "yes" : "no");
85-
return is_prefix_res && !is_forbidden_res;
79+
LOG("is_capio_path:%s", is_capio_path ? "yes" : "no");
80+
return is_capio_path;
8681
}
8782

8883
/**

capio-posix/handlers/exit.hpp

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -21,15 +21,15 @@ int exit_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg
2121
syscall_no_intercept_flag = true;
2222
LOG("syscall_no_intercept_flag = true");
2323

24+
delete_caches();
25+
LOG("Removed caches");
26+
2427
if (is_capio_tid(tid)) {
2528
LOG("Thread %d is a CAPIO thread: clean up", tid);
2629
exit_group_request(tid);
2730
remove_capio_tid(tid);
2831
}
2932

30-
delete_caches();
31-
LOG("Removed caches");
32-
3333
if (const auto itm = bufs_response->find(tid); itm != bufs_response->end()) {
3434
delete itm->second;
3535
bufs_response->erase(tid);

capio-posix/utils/cache/read_request_cache_fs.hpp

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@ class ReadRequestCacheFS {
4848
} else {
4949
LOG("[cache] Entry not found, initializing new entry to offset 0");
5050
max_read = 0;
51-
available_read_cache->emplace(current_path, max_read);
51+
available_read_cache->emplace(current_path, 0);
5252
}
5353
LOG("[cache] Max read value is %llu %s", max_read,
5454
max_read == ULLONG_MAX ? "(ULLONG_MAX)" : "");
@@ -65,9 +65,12 @@ class ReadRequestCacheFS {
6565
max_read = _read_request(current_path, end_of_read, tid, fd);
6666
LOG("[cache] Obtained value from server is %llu", max_read);
6767
if (available_read_cache->find(path) == available_read_cache->end()) {
68+
LOG("[cache] Cound not find entry in cache. Adding new entry to cache");
6869
available_read_cache->emplace(path, max_read);
6970
} else {
7071
available_read_cache->at(path) = max_read;
72+
LOG("[cache] Updating max read value in cache. new value: %llu",
73+
available_read_cache->at(path));
7174
}
7275
LOG("[cache] completed update from server of max read for file. returning control to "
7376
"application");

capio-posix/utils/cache/write_request_cache_fs.hpp

Lines changed: 21 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -2,19 +2,18 @@
22
#define WRITE_REQUEST_CACHE_FS_HPP
33

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

87
const capio_off64_t _max_size;
98

109
std::filesystem::path current_path;
1110

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

2524
~WriteRequestCacheFS() {
2625
START_LOG(capio_syscall(SYS_gettid), "call()");
27-
this->flush(capio_syscall(SYS_gettid));
26+
const int tid = capio_syscall(SYS_gettid);
27+
for (auto &[path, size] : capio_internal_write_offsets) {
28+
this->flush(path, tid, -1);
29+
}
2830
}
2931

30-
void write_request(std::filesystem::path path, int tid, int fd, long count) {
32+
void write_request(const std::filesystem::path &path, int tid, int fd, long count) {
3133
START_LOG(capio_syscall(SYS_gettid), "call(path=%s, tid=%ld, fd=%ld, count=%ld)",
3234
path.c_str(), tid, fd, count);
33-
if (fd != current_fd || path.compare(current_path) != 0) {
34-
LOG("File descriptor changed from previous state. updating");
35-
this->flush(tid);
36-
current_path = std::move(path);
37-
current_fd = fd;
35+
36+
if (!capio_internal_write_offsets.contains(path.c_str())) {
37+
capio_internal_write_offsets[path.c_str()] = 0;
3838
}
39-
current_size += count;
4039

41-
if (current_size > _max_size) {
40+
capio_internal_write_offsets[path.c_str()] += count;
41+
42+
if (capio_internal_write_offsets[path.c_str()] >= _max_size) {
4243
LOG("exceeded maximum cache size. flushing...");
43-
this->flush(tid);
44+
this->flush(path, tid, fd);
45+
capio_internal_write_offsets[path.c_str()] = 0;
4446
}
4547
};
4648

47-
void flush(int tid) {
48-
START_LOG(capio_syscall(SYS_gettid), "call(tid=%ld)", tid);
49-
if (current_fd != -1 && current_size > 0) {
50-
LOG("Performing write to SHM");
51-
_write_request(tid, current_fd, current_size);
52-
}
53-
current_fd = -1;
54-
current_size = 0;
49+
void flush(const std::filesystem::path &path, long tid, int fd) {
50+
START_LOG(capio_syscall(SYS_gettid), "call(tid=%ld, path=%s)", tid, path.c_str());
51+
52+
LOG("Performing write to SHM");
53+
_write_request(capio_internal_write_offsets[path.c_str()], tid, fd);
5554
}
5655
};
5756

capio-posix/utils/filesystem.hpp

Lines changed: 36 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -307,48 +307,56 @@ inline void set_current_dir(const std::filesystem::path &cwd) {
307307
*/
308308
[[maybe_unused]] [[nodiscard]] static std::string
309309
resolve_possible_symlink(const std::filesystem::path &input_path) {
310-
START_LOG(capio_syscall(SYS_gettid), "call(path=%s)", input_path.c_str());
311310

312-
LOG("Absolute path = %s", input_path.c_str());
311+
// Cache for resolved symbolic links: link -> realpath
312+
static std::unordered_map<std::string, std::string> resolved_symlinks_cache;
313+
314+
if (!resolved_symlinks_cache.contains(input_path)) {
315+
START_LOG(capio_syscall(SYS_gettid), "call(path=%s)", input_path.c_str());
316+
317+
LOG("Absolute path = %s", input_path.c_str());
313318

314319
#ifdef __CAPIO_POSIX
315-
syscall_no_intercept_flag = true;
320+
syscall_no_intercept_flag = true;
316321
#endif
317322

318-
std::filesystem::path resolved, input_abs_path = std::filesystem::absolute(input_path);
323+
std::filesystem::path resolved;
319324

320-
for (const auto &part : input_abs_path) {
321-
resolved /= part;
325+
for (std::filesystem::path input_abs_path = std::filesystem::absolute(input_path);
326+
const auto &part : input_abs_path) {
327+
resolved /= part;
322328

323-
if (part == "." || part.empty()) {
324-
continue;
325-
}
326-
if (part == "..") {
327-
resolved = resolved.parent_path();
328-
continue;
329-
}
330-
if (std::filesystem::is_symlink(resolved)) {
331-
char buf[PATH_MAX]{0};
332-
auto result =
333-
capio_syscall(SYS_readlinkat, AT_FDCWD, resolved.c_str(), buf, sizeof(buf) - 1);
334-
if (result == -1) {
335-
LOG("File might not exist. path was %s and Error is %s", resolved.c_str(),
336-
strerror(errno));
329+
if (part == "." || part.empty()) {
337330
continue;
338331
}
339-
340-
if (std::filesystem::path target(buf); target.is_relative()) {
341-
resolved = resolved.parent_path() / target;
342-
} else {
343-
resolved = target;
332+
if (part == "..") {
333+
resolved = resolved.parent_path();
334+
continue;
335+
}
336+
if (std::filesystem::is_symlink(resolved)) {
337+
char buf[PATH_MAX]{0};
338+
auto result =
339+
capio_syscall(SYS_readlinkat, AT_FDCWD, resolved.c_str(), buf, sizeof(buf) - 1);
340+
if (result == -1) {
341+
LOG("File might not exist. path was %s and Error is %s", resolved.c_str(),
342+
strerror(errno));
343+
continue;
344+
}
345+
346+
if (std::filesystem::path target(buf); target.is_relative()) {
347+
resolved = resolved.parent_path() / target;
348+
} else {
349+
resolved = target;
350+
}
344351
}
345352
}
346-
}
347353
#ifdef __CAPIO_POSIX
348-
syscall_no_intercept_flag = false;
354+
syscall_no_intercept_flag = false;
349355
#endif
350356

351-
return resolved;
357+
resolved_symlinks_cache[input_path] = resolved;
358+
}
359+
return resolved_symlinks_cache[input_path];
352360
}
353361

354362
#endif // CAPIO_POSIX_UTILS_FILESYSTEM_HPP

capio-posix/utils/requests.hpp

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -113,7 +113,7 @@ inline capio_off64_t posix_directory_committed_request(const long pid,
113113
// non blocking
114114
inline void close_request(const std::filesystem::path &path, const long tid) {
115115
START_LOG(capio_syscall(SYS_gettid), "call(path=%s, tid=%ld)", path.c_str(), tid);
116-
write_request_cache_fs->flush(tid);
116+
write_request_cache_fs->flush(path, tid, -1);
117117
char req[CAPIO_REQ_MAX_SIZE];
118118
sprintf(req, "%04d %ld %s", CAPIO_REQUEST_CLOSE, tid, path.c_str());
119119
buf_requests->write(req, CAPIO_REQ_MAX_SIZE);
@@ -130,7 +130,6 @@ inline void create_request(const int fd, const std::filesystem::path &path, cons
130130
// non blocking
131131
inline void exit_group_request(const long tid) {
132132
START_LOG(capio_syscall(SYS_gettid), "call(tid=%ld)", tid);
133-
write_request_cache_fs->flush(tid);
134133
char req[CAPIO_REQ_MAX_SIZE];
135134
sprintf(req, "%04d %ld", CAPIO_REQUEST_EXIT_GROUP, tid);
136135
buf_requests->write(req, CAPIO_REQ_MAX_SIZE);
@@ -140,8 +139,6 @@ inline void exit_group_request(const long tid) {
140139
[[nodiscard]] inline capio_off64_t open_request(const int fd, const std::filesystem::path &path,
141140
const long tid) {
142141
START_LOG(capio_syscall(SYS_gettid), "call(fd=%ld, path=%s, tid=%ld)", fd, path.c_str(), tid);
143-
write_request_cache_fs->flush(tid);
144-
145142
char req[CAPIO_REQ_MAX_SIZE];
146143
sprintf(req, "%04d %ld %d %s", CAPIO_REQUEST_OPEN, tid, fd, path.c_str());
147144
buf_requests->write(req, CAPIO_REQ_MAX_SIZE);

capio-server/src/capio-cl-engine/capio_cl_engine.cpp

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -233,15 +233,27 @@ bool CapioCLEngine::isFirable(const std::string &path) {
233233
LOG("Fire rule for file %s is %s", path.c_str(), std::get<3>(itm->second).c_str());
234234
return std::get<3>(itm->second) == CAPIO_FILE_MODE_NO_UPDATE;
235235
}
236+
237+
LOG("No entry found on map. checking globs...");
238+
const auto is_firable = std::any_of(_locations.begin(), _locations.end(), [&](auto &itm) {
239+
LOG("Checking against %s", itm.first.c_str());
240+
if (std::regex_match(path.c_str(), std::get<10>(itm.second))) {
241+
LOG("Found match. Is Firable: %s",
242+
std::get<3>(itm.second) == CAPIO_FILE_MODE_NO_UPDATE ? "YES" : "NO");
243+
return std::get<3>(itm.second) == CAPIO_FILE_MODE_NO_UPDATE;
244+
}
245+
return false;
246+
});
247+
236248
/*
237249
* For caching purpose, each new file is then added to the map if not found,
238250
* with its data being instantiated from the metadata of the most likely matched glob
239-
* TODO: check overhead of this
240251
*/
241-
LOG("No entry found on map. checking globs. Creating new file from globs");
242-
this->newFile((path));
252+
LOG("Creating new file for caching purpose...");
253+
this->newFile(path);
254+
this->setFireRule(path, is_firable ? CAPIO_FILE_MODE_NO_UPDATE : CAPIO_FILE_MODE_UPDATE);
243255
LOG("Fire rule for file %s is %s", path.c_str(), std::get<3>(_locations.at((path))).c_str());
244-
return std::get<3>(_locations.at((path))) == CAPIO_FILE_MODE_NO_UPDATE;
256+
return is_firable;
245257
}
246258

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

0 commit comments

Comments
 (0)