Loading ifs/include/preload/open_file_map.hpp +15 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ #include <map> #include <mutex> #include <memory> #include <atomic> enum class OpenFile_flags { append = 0, Loading Loading @@ -60,6 +61,18 @@ private: int safe_generate_fd_idx_(); /* * TODO: Setting our file descriptor index to a specific value is dangerous because we might clash with the kernel. * E.g., if we would passthrough and not intercept and the kernel assigns a file descriptor but we will later use * the same fd value, we will intercept calls that were supposed to be going to the kernel. This works the other way around too. * To mitigate this issue, we set the initial fd number to a high value. We "hope" that we do not clash but this is no permanent solution. * Note: This solution will probably work well already for many cases because kernel fd values are reused, unlike to ours. * The only case where we will clash with the kernel is, if one process has more than 100000 files open at the same time. */ int fd_idx; std::mutex fd_idx_mutex; std::atomic<bool> fd_validation_needed; public: OpenFileMap(); Loading @@ -75,6 +88,8 @@ public: int dup2(int oldfd, int newfd); int generate_fd_idx(); int get_fd_idx(); }; Loading ifs/include/preload/preload_util.hpp +0 −6 Original line number Diff line number Diff line Loading @@ -72,15 +72,9 @@ extern hg_id_t rpc_read_data_id; extern hg_id_t rpc_get_dirents_id; // rpc addresses. Populated when environment is initialized. After that it is read-only accessed extern std::map<uint64_t, hg_addr_t> rpc_addresses; // file descriptor index validation flag extern std::atomic<bool> fd_validation_needed; // function definitions int generate_fd_idx(); int get_fd_idx(); bool is_fs_path(const char* path); // TODO template these two suckers Loading ifs/src/preload/open_file_map.cpp +34 −2 Original line number Diff line number Diff line #include <fcntl.h> #include <global/global_defs.hpp> #include <preload/open_file_map.hpp> #include <preload/preload.hpp> #include <preload/preload_util.hpp> using namespace std; Loading @@ -23,7 +24,10 @@ OpenFile::OpenFile(const string& path, const int flags) : path_(path) { pos_ = 0; // If O_APPEND flag is used, it will be used before each write. } OpenFileMap::OpenFileMap() {} OpenFileMap::OpenFileMap(): fd_idx(10000), fd_validation_needed(false) {} OpenFile::~OpenFile() { Loading Loading @@ -147,3 +151,31 @@ int OpenFileMap::dup2(const int oldfd, const int newfd) { files_.insert(make_pair(newfd, open_file)); return newfd; } /** * Generate new file descriptor index to be used as an fd within one process in ADA-FS * @return fd_idx */ int OpenFileMap::generate_fd_idx() { // We need a mutex here for thread safety std::lock_guard<std::mutex> inode_lock(fd_idx_mutex); if (fd_idx == std::numeric_limits<int>::max()) { CTX->log()->info("{}() File descriptor index exceeded ints max value. Setting it back to 100000", __func__); /* * Setting fd_idx back to 3 could have the effect that fd are given twice for different path. * This must not happen. Instead a flag is set which tells can tell the OpenFileMap that it should check * if this fd is really safe to use. */ fd_idx = 100000; fd_validation_needed = true; } return fd_idx++; } int OpenFileMap::get_fd_idx() { std::lock_guard<std::mutex> inode_lock(fd_idx_mutex); return fd_idx; } ifs/src/preload/preload_util.cpp +0 −37 Original line number Diff line number Diff line Loading @@ -14,43 +14,6 @@ using namespace std; static const std::string dentry_val_delim = ","s; /* * TODO: Setting our file descriptor index to a specific value is dangerous because we might clash with the kernel. * E.g., if we would passthrough and not intercept and the kernel assigns a file descriptor but we will later use * the same fd value, we will intercept calls that were supposed to be going to the kernel. This works the other way around too. * To mitigate this issue, we set the initial fd number to a high value. We "hope" that we do not clash but this is no permanent solution. * Note: This solution will probably work well already for many cases because kernel fd values are reused, unlike to ours. * The only case where we will clash with the kernel is, if one process has more than 100000 files open at the same time. */ static int fd_idx = 100000; static mutex fd_idx_mutex; std::atomic<bool> fd_validation_needed(false); /** * Generate new file descriptor index to be used as an fd within one process in ADA-FS * @return fd_idx */ int generate_fd_idx() { // We need a mutex here for thread safety std::lock_guard<std::mutex> inode_lock(fd_idx_mutex); if (fd_idx == std::numeric_limits<int>::max()) { CTX->log()->info("{}() File descriptor index exceeded ints max value. Setting it back to 100000", __func__); /* * Setting fd_idx back to 3 could have the effect that fd are given twice for different path. * This must not happen. Instead a flag is set which tells can tell the OpenFileMap that it should check * if this fd is really safe to use. */ fd_idx = 100000; fd_validation_needed = true; } return fd_idx++; } int get_fd_idx() { std::lock_guard<std::mutex> inode_lock(fd_idx_mutex); return fd_idx; } bool is_fs_path(const char* path) { return strstr(path, CTX->mountdir().c_str()) == path; } Loading Loading
ifs/include/preload/open_file_map.hpp +15 −0 Original line number Diff line number Diff line Loading @@ -5,6 +5,7 @@ #include <map> #include <mutex> #include <memory> #include <atomic> enum class OpenFile_flags { append = 0, Loading Loading @@ -60,6 +61,18 @@ private: int safe_generate_fd_idx_(); /* * TODO: Setting our file descriptor index to a specific value is dangerous because we might clash with the kernel. * E.g., if we would passthrough and not intercept and the kernel assigns a file descriptor but we will later use * the same fd value, we will intercept calls that were supposed to be going to the kernel. This works the other way around too. * To mitigate this issue, we set the initial fd number to a high value. We "hope" that we do not clash but this is no permanent solution. * Note: This solution will probably work well already for many cases because kernel fd values are reused, unlike to ours. * The only case where we will clash with the kernel is, if one process has more than 100000 files open at the same time. */ int fd_idx; std::mutex fd_idx_mutex; std::atomic<bool> fd_validation_needed; public: OpenFileMap(); Loading @@ -75,6 +88,8 @@ public: int dup2(int oldfd, int newfd); int generate_fd_idx(); int get_fd_idx(); }; Loading
ifs/include/preload/preload_util.hpp +0 −6 Original line number Diff line number Diff line Loading @@ -72,15 +72,9 @@ extern hg_id_t rpc_read_data_id; extern hg_id_t rpc_get_dirents_id; // rpc addresses. Populated when environment is initialized. After that it is read-only accessed extern std::map<uint64_t, hg_addr_t> rpc_addresses; // file descriptor index validation flag extern std::atomic<bool> fd_validation_needed; // function definitions int generate_fd_idx(); int get_fd_idx(); bool is_fs_path(const char* path); // TODO template these two suckers Loading
ifs/src/preload/open_file_map.cpp +34 −2 Original line number Diff line number Diff line #include <fcntl.h> #include <global/global_defs.hpp> #include <preload/open_file_map.hpp> #include <preload/preload.hpp> #include <preload/preload_util.hpp> using namespace std; Loading @@ -23,7 +24,10 @@ OpenFile::OpenFile(const string& path, const int flags) : path_(path) { pos_ = 0; // If O_APPEND flag is used, it will be used before each write. } OpenFileMap::OpenFileMap() {} OpenFileMap::OpenFileMap(): fd_idx(10000), fd_validation_needed(false) {} OpenFile::~OpenFile() { Loading Loading @@ -147,3 +151,31 @@ int OpenFileMap::dup2(const int oldfd, const int newfd) { files_.insert(make_pair(newfd, open_file)); return newfd; } /** * Generate new file descriptor index to be used as an fd within one process in ADA-FS * @return fd_idx */ int OpenFileMap::generate_fd_idx() { // We need a mutex here for thread safety std::lock_guard<std::mutex> inode_lock(fd_idx_mutex); if (fd_idx == std::numeric_limits<int>::max()) { CTX->log()->info("{}() File descriptor index exceeded ints max value. Setting it back to 100000", __func__); /* * Setting fd_idx back to 3 could have the effect that fd are given twice for different path. * This must not happen. Instead a flag is set which tells can tell the OpenFileMap that it should check * if this fd is really safe to use. */ fd_idx = 100000; fd_validation_needed = true; } return fd_idx++; } int OpenFileMap::get_fd_idx() { std::lock_guard<std::mutex> inode_lock(fd_idx_mutex); return fd_idx; }
ifs/src/preload/preload_util.cpp +0 −37 Original line number Diff line number Diff line Loading @@ -14,43 +14,6 @@ using namespace std; static const std::string dentry_val_delim = ","s; /* * TODO: Setting our file descriptor index to a specific value is dangerous because we might clash with the kernel. * E.g., if we would passthrough and not intercept and the kernel assigns a file descriptor but we will later use * the same fd value, we will intercept calls that were supposed to be going to the kernel. This works the other way around too. * To mitigate this issue, we set the initial fd number to a high value. We "hope" that we do not clash but this is no permanent solution. * Note: This solution will probably work well already for many cases because kernel fd values are reused, unlike to ours. * The only case where we will clash with the kernel is, if one process has more than 100000 files open at the same time. */ static int fd_idx = 100000; static mutex fd_idx_mutex; std::atomic<bool> fd_validation_needed(false); /** * Generate new file descriptor index to be used as an fd within one process in ADA-FS * @return fd_idx */ int generate_fd_idx() { // We need a mutex here for thread safety std::lock_guard<std::mutex> inode_lock(fd_idx_mutex); if (fd_idx == std::numeric_limits<int>::max()) { CTX->log()->info("{}() File descriptor index exceeded ints max value. Setting it back to 100000", __func__); /* * Setting fd_idx back to 3 could have the effect that fd are given twice for different path. * This must not happen. Instead a flag is set which tells can tell the OpenFileMap that it should check * if this fd is really safe to use. */ fd_idx = 100000; fd_validation_needed = true; } return fd_idx++; } int get_fd_idx() { std::lock_guard<std::mutex> inode_lock(fd_idx_mutex); return fd_idx; } bool is_fs_path(const char* path) { return strstr(path, CTX->mountdir().c_str()) == path; } Loading