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
18 changes: 16 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,14 @@ set(CMAKE_EXPORT_COMPILE_COMMANDS TRUE)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -pedantic -O0")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} -O3")

# Silence warning from G++
if (CMAKE_CXX_COMPILER_ID STREQUAL "GNU")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wno-terminate")
endif ()

# Silence warning from clang
if (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -pedantic -O0 -Wno-gnu-zero-variadic-macro-arguments")
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} -Wall -pedantic -O0 -Wno-gnu-zero-variadic-macro-arguments -Wno-exceptions")
endif (CMAKE_CXX_COMPILER_ID STREQUAL "Clang")

#####################################
Expand All @@ -49,6 +54,14 @@ find_package(Threads REQUIRED)
#####################################
add_compile_definitions(CAPIO_VERSION="${CMAKE_PROJECT_VERSION}")

# We check here and define only here the CAPIO_BUILD_TESTS macro
# as it is required by both src/posix and src/server targets
# Later on we check again to add the tests subproject, which cannot
# be added here for issues with include directories
IF (CAPIO_BUILD_TESTS)
add_compile_definitions(CAPIO_BUILD_TESTS)
ENDIF (CAPIO_BUILD_TESTS)

IF (CAPIO_LOG)
IF (CMAKE_BUILD_TYPE STREQUAL "Debug")
message(STATUS "Enabling CAPIO logger")
Expand Down Expand Up @@ -97,5 +110,6 @@ install(

IF (CAPIO_BUILD_TESTS)
message(STATUS "Building CAPIO test suite")
add_compile_definitions(CAPIO_BUILD_TESTS)
add_subdirectory(tests)
ENDIF (CAPIO_BUILD_TESTS)
ENDIF (CAPIO_BUILD_TESTS)
6 changes: 3 additions & 3 deletions src/common/capio/constants.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,9 @@
typedef unsigned long long int capio_off64_t;

// CAPIO files constants
constexpr size_t CAPIO_DEFAULT_DIR_INITIAL_SIZE = 1024L * 1024 * 1024;
constexpr off64_t CAPIO_DEFAULT_FILE_INITIAL_SIZE = 1024L * 1024 * 1024 * 4;
constexpr std::array CAPIO_DIR_FORBIDDEN_PATHS = {
constexpr size_t CAPIO_DEFAULT_DIR_INITIAL_SIZE = 1024L * 1024 * 1024;
constexpr off64_t CAPIO_DEFAULT_FILE_INITIAL_SIZE = 1024L * 1024 * 1024 * 4;
[[maybe_unused]] constexpr std::array CAPIO_DIR_FORBIDDEN_PATHS = {
std::string_view{"/proc/"}, std::string_view{"/sys/"}, std::string_view{"/boot/"},
std::string_view{"/dev/"}, std::string_view{"/var/"}, std::string_view{"/run/"},
std::string_view("/spack/")};
Expand Down
50 changes: 1 addition & 49 deletions src/common/capio/filesystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -105,7 +105,7 @@ inline bool is_capio_path(const std::filesystem::path &path_to_check) {
* @param capio_path String to convert
* @return std::regex compiled with the corresponding c++ regex
*/
[[nodiscard]] static std::regex generateCapioRegex(const std::string &capio_path) {
[[maybe_unused]] [[nodiscard]] static std::regex generateCapioRegex(const std::string &capio_path) {
START_LOG(gettid(), "call(capio_path=%s)", capio_path.c_str());
auto computed = replaceSymbol(capio_path, '.', "\\.");
computed = replaceSymbol(computed, '/', "\\/");
Expand All @@ -115,52 +115,4 @@ inline bool is_capio_path(const std::filesystem::path &path_to_check) {
return std::regex(computed);
}

/**
* Resolve a possible symbolic link to the absolute path that it points to
* @param input_path
* @return
*/
[[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());

#ifdef __CAPIO_POSIX
syscall_no_intercept_flag = true;
#endif

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

for (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};
if (capio_syscall(SYS_readlink, resolved.c_str(), buf, sizeof(buf) - 1) == -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;
#endif

return resolved;
}

#endif // CAPIO_COMMON_FILESYSTEM_HPP
2 changes: 1 addition & 1 deletion src/common/capio/logger.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,7 @@ class Logger {
gethostname(node_name, HOST_NAME_MAX); \
printf("%s [ %s ] %s\n", CAPIO_LOG_SERVER_CLI_LEVEL_ERROR, node_name, tmp_buf); \
fflush(stdout); \
exit(EXIT_FAILURE); \
throw std::runtime_error(std::string(tmp_buf)); \
}
#define LOG(message, ...) log.log(message, ##__VA_ARGS__)
#define START_LOG(tid, message, ...) \
Expand Down
2 changes: 1 addition & 1 deletion src/common/capio/semaphore.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -94,7 +94,7 @@ class NamedSemaphore {
START_LOG(capio_syscall(SYS_gettid), "call(name=%s)", _name.c_str());

if (sem_wait(_sem) == -1) {
ERR_EXIT(" unable to acquire %s", _name.c_str());
ERR_EXIT("Unable to acquire %s", _name.c_str());
}
}

Expand Down
12 changes: 7 additions & 5 deletions src/posix/handlers/copy_file_range.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,11 +2,13 @@
#define CAPIO_COPY_FILE_RANGE_HPP
int copy_file_range_handler(long arg0, long arg1, long arg2, long arg3, long arg4, long arg5,
long *result) {
auto tid = static_cast<pid_t>(syscall_no_intercept(SYS_gettid));
auto fd_in = static_cast<int>(arg0);
auto fd_out = static_cast<int>(arg2);
auto off_in = static_cast<capio_off64_t>(arg1);
auto off_out = static_cast<capio_off64_t>(arg3);
auto tid = static_cast<pid_t>(syscall_no_intercept(SYS_gettid));
auto fd_in = static_cast<int>(arg0);
auto off_in = static_cast<capio_off64_t>(arg1);

// auto fd_out = static_cast<int>(arg2);
// auto off_out = static_cast<capio_off64_t>(arg3);

START_LOG(tid, "call()");

// TODO: support in memory read / write
Expand Down
15 changes: 8 additions & 7 deletions src/posix/handlers/posix_readdir.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,8 @@
#include <utils/requests.hpp>

// Map &DIR -> <dir_path, files already served>
inline std::unordered_map<unsigned long int, std::pair<std::string, int>> *opened_directory =
nullptr;
inline std::unordered_map<unsigned long int, std::pair<std::string, long unsigned int>>
*opened_directory = nullptr;

inline std::unordered_map<std::string, std::vector<dirent64 *> *> *directory_items;

Expand Down Expand Up @@ -50,8 +50,9 @@ inline void init_posix_dirent() {
real_readdir = (dirent * (*) (DIR *) ) dlsym(RTLD_NEXT, "readdir");
}

directory_items = new std::unordered_map<std::string, std::vector<dirent64 *> *>();
opened_directory = new std::unordered_map<unsigned long, std::pair<std::string, int>>();
directory_items = new std::unordered_map<std::string, std::vector<dirent64 *> *>();
opened_directory =
new std::unordered_map<unsigned long, std::pair<std::string, unsigned long int>>();

dirent_curr_dir = new dirent64();
dirent_parent_dir = new dirent64();
Expand All @@ -65,14 +66,14 @@ inline void init_posix_dirent() {
syscall_no_intercept_flag = false;
}

inline int load_files_from_directory(const char *path) {
inline unsigned long int load_files_from_directory(const char *path) {

START_LOG(capio_syscall(SYS_gettid), "call(path=%s)", path);

syscall_no_intercept_flag = true;
dirent64 *entry;
DIR *dir = real_opendir(path);
int count = 0;
DIR *dir = real_opendir(path);
unsigned long int count = 0;

if (directory_items->find(path) == directory_items->end()) {
LOG("Directory vector not present. Adding it at path %s", path);
Expand Down
2 changes: 1 addition & 1 deletion src/posix/utils/cache/read_request_cache_fs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,7 @@ class ReadRequestCacheFS {
return;
}

if (end_of_read > max_read) {
if (static_cast<capio_off64_t>(end_of_read) > max_read) {
LOG("[cache] end_of_read > max_read. Performing server request");
max_read = _read_request(current_path, end_of_read, tid, fd);
LOG("[cache] Obtained value from server is %llu", max_read);
Expand Down
2 changes: 1 addition & 1 deletion src/posix/utils/cache/read_request_cache_mem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -85,7 +85,7 @@ class ReadRequestCacheMEM {
_real_file_size_commmitted = -1;
}

long read(const int fd, void *buffer, off64_t count) {
long read(const int fd, void *buffer, capio_off64_t count) {
START_LOG(capio_syscall(SYS_gettid), "call(fd=%d, count=%ld)", fd, count);

long actual_read_size = 0;
Expand Down
4 changes: 2 additions & 2 deletions src/posix/utils/cache/write_request_cache_fs.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
#define WRITE_REQUEST_CACHE_FS_HPP
class WriteRequestCacheFS {

int current_fd = -1;
long long current_size = 0;
int current_fd = -1;
capio_off64_t current_size = 0;

const capio_off64_t _max_size;

Expand Down
49 changes: 49 additions & 0 deletions src/posix/utils/filesystem.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -300,4 +300,53 @@ inline void set_current_dir(const std::filesystem::path &cwd) {
current_dir = std::make_unique<std::filesystem::path>(cwd);
}

/**
* Resolve a possible symbolic link to the absolute path that it points to
* @param input_path
* @return
*/
[[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());

#ifdef __CAPIO_POSIX
syscall_no_intercept_flag = true;
#endif

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

for (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};
if (capio_syscall(SYS_readlink, resolved.c_str(), buf, sizeof(buf) - 1) == -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;
#endif

return resolved;
}

#endif // CAPIO_POSIX_UTILS_FILESYSTEM_HPP
25 changes: 22 additions & 3 deletions src/posix/utils/requests.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,8 +32,7 @@ inline void init_client() {
}

/**
* Perform handshake. server returns the amount of paths that needs to be obtained from the server
* to know which files are going to be treated during write and read operations inside memory
* Perform handshake.
* @param tid
* @param pid
* @param app_name
Expand All @@ -51,9 +50,29 @@ inline void handshake_request(const long tid, const long pid, const std::string
char req[CAPIO_REQ_MAX_SIZE];
sprintf(req, "%04d %ld %ld %s", CAPIO_REQUEST_HANDSHAKE, tid, pid, app_name.c_str());
buf_requests->write(req, CAPIO_REQ_MAX_SIZE);

#ifndef CAPIO_BUILD_TESTS
LOG("Waiting for response from capio_server");
/*
* The handshake request must be blocking ONLY when not building tests. This is because when
* starting unit tests, the binary is loaded with libcapio_posix.so underneath thus performing
* a handshake request. If the handshake is blocking, then the capio_server binary cannot be
* started as the whole process is waiting for a handshake.
*/
if (bufs_response->at(pid)->read() == 0) {
ERR_EXIT("Error: handshake request sent while capio_server is shutting down!");
}
#endif

LOG("Sent handshake request");
}

/**
* File in memory requests: server returns the amount of paths that needs to be obtained from the
* server to know which files are going to be treated during write and read operations inside memory
* @param pid
* @return
*/
inline std::vector<std::regex> *file_in_memory_request(const long pid) {
START_LOG(capio_syscall(SYS_gettid), "call(pid=%ld)", pid);
char req[CAPIO_REQ_MAX_SIZE];
Expand All @@ -64,7 +83,7 @@ inline std::vector<std::regex> *file_in_memory_request(const long pid) {
capio_off64_t files_to_read_from_queue = bufs_response->at(pid)->read();
LOG("Need to read %llu files from data queues", files_to_read_from_queue);
const auto regex_vector = new std::vector<std::regex>;
for (int i = 0; i < files_to_read_from_queue; i++) {
for (capio_off64_t i = 0; i < files_to_read_from_queue; i++) {
LOG("Reading file number %d", i);
auto file = new char[PATH_MAX]{};
stc_queue->read(file, PATH_MAX);
Expand Down
3 changes: 3 additions & 0 deletions src/server/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ FetchContent_Declare(
GIT_REPOSITORY https://github.com/Taywee/args.git
GIT_TAG 6.4.7
)
set(ARGS_BUILD_EXAMPLE OFF CACHE INTERNAL "")
set(ARGS_BUILD_UNITTESTS OFF CACHE INTERNAL "")

FetchContent_Declare(
simdjson
GIT_REPOSITORY https://github.com/simdjson/simdjson.git
Expand Down
17 changes: 9 additions & 8 deletions src/server/capio-cl-engine/capio_cl_engine.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ class CapioCLEngine {
bool>> // Store File on FS. true = memory [11]
_locations;

static std::string truncateLastN(const std::string &str, const int n) {
static std::string truncateLastN(const std::string &str, const std::size_t n) {
return str.length() > n ? "[..] " + str.substr(str.length() - n) : str;
}

Expand All @@ -41,13 +41,13 @@ class CapioCLEngine {
"==========================================================|"
<< std::endl
<< "|" << std::setw(135) << "|" << std::endl
<< "| Parsed configuration file for workflow: \e[1;36m" << workflow_name
<< std::setw(94 - workflow_name.length()) << "\e[0m |" << std::endl
<< "| Parsed configuration file for workflow: \033[1;36m" << workflow_name
<< std::setw(94 - workflow_name.length()) << "\033[0m |" << std::endl
<< "|" << std::setw(135) << "|" << std::endl
<< "| File color legend: \e[48;5;034m \e[0m File stored in memory"
<< "| File color legend: \033[48;5;034m \033[0m File stored in memory"
<< std::setw(83) << "|" << std::endl
<< "| "
<< "\e[48;5;172m \e[0m File stored on file system" << std::setw(78) << "|"
<< "\033[48;5;172m \033[0m File stored on file system" << std::setw(78) << "|"
<< std::endl
<< "|============================================================================"
"==========================================================|"
Expand All @@ -63,8 +63,9 @@ class CapioCLEngine {
<< std::endl;

for (auto itm : _locations) {
std::string color_preamble = std::get<11>(itm.second) ? "\e[38;5;034m" : "\e[38;5;172m";
std::string color_post = "\e[0m";
std::string color_preamble =
std::get<11>(itm.second) ? "\033[38;5;034m" : "\033[38;5;172m";
std::string color_post = "\033[0m";

std::string name_trunc = truncateLastN(itm.first, 12);
auto kind = std::get<6>(itm.second) ? "F" : "D";
Expand All @@ -83,7 +84,7 @@ class CapioCLEngine {
n_files = "N.A.";
}

for (int i = 0; i <= rowCount; i++) {
for (std::size_t i = 0; i <= rowCount; i++) {
std::string prod, cons;
if (i > 0) {
std::cout << "| | | ";
Expand Down
Loading