Verified Commit 8683281c authored by Tommaso Tocci's avatar Tommaso Tocci
Browse files

Move fd managment into open_file_map

parent 74fed6a6
Loading
Loading
Loading
Loading
+15 −0
Original line number Diff line number Diff line
@@ -5,6 +5,7 @@
#include <map>
#include <mutex>
#include <memory>
#include <atomic>

enum class OpenFile_flags {
    append = 0,
@@ -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();

@@ -75,6 +88,8 @@ public:

    int dup2(int oldfd, int newfd);

    int generate_fd_idx();
    int get_fd_idx();
};


+0 −6
Original line number Diff line number Diff line
@@ -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
+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;

@@ -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() {

@@ -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;
}


+0 −37
Original line number Diff line number Diff line
@@ -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;
}