Skip to content

Commit

Permalink
clear-page fault config fixed
Browse files Browse the repository at this point in the history
  • Loading branch information
kianda17 committed Jul 31, 2024
1 parent eb3c94c commit fd202d5
Show file tree
Hide file tree
Showing 3 changed files with 245 additions and 5 deletions.
91 changes: 91 additions & 0 deletions libs/libpcache/include/faults/faults.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
#define TORN_OP "torn-op"
#define TORN_SEQ "torn-seq"
#define CLEAR "clear-cache"
#define CLEAR_PAGE "clear-page"

using namespace std;

Expand Down Expand Up @@ -271,5 +272,95 @@ class ClearF : public Fault {
vector<string> validate();

};

/*********************************************************************************************/

/**
* @brief Fault for clearing certain pages in LazyFS's cache in a specific point of execution, persist the others and, optionally, crash the process.
*/
class ClearP : public Fault {
public:
/**
* @brief Timing of the fault ("before","after").
*/
string timing;

/**
* @brief System call (i.e. "write", ...).
*/
string op;

/**
* @brief Path of the system call.
*/
string from;

/**
* @brief Path when op requires two paths (e.g., rename system call).
*/
string to;

/**
* @brief Occurrence of the op.
*/
int occurrence;

/**
* @brief Counter of the op.
*/
std::atomic_int counter;

/**
* @brief If the fault is a crash fault.
*/
bool crash;

/**
* @brief Pages that will be cleared.
*/
string pages;

/**
* @brief True if LazyFS crashes only after completing the current system call. False if otherwise.
*/
bool ret;

/**
* @brief Map of allowed operations to have a crash fault
*
*/
static const unordered_set<string> allow_crash_fs_operations;

/**
* @brief Map of operations that have two paths
*
*/
static const unordered_set<string> fs_op_multi_path;

/**
* @brief Constructor for Fault.
*
* @param timing Timing of the fault ("before","after").
* @param op System call (i.e. "write", ...).
* @param from Path of the system call.
* @param to Path when op requires two paths (e.g., rename system call).
* @param occurrence Occurrence of the op.
* @param crash If the fault is a crash fault.
* @param pages Pages to clear.
* @param ret If the current system call is finished before crashing.
*/
ClearP(string timing, string op, string from, string to, int occurrence, bool crash, string pages, bool ret);

~ClearP ();

/**
* @brief Check if the parameters have correct values for the fault.
*
* @return Vector with errors.
*/
vector<string> validate();

};

// namespace faults
}
94 changes: 91 additions & 3 deletions libs/libpcache/src/config/config.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -202,7 +202,7 @@ unordered_map<string,vector<faults::Fault*>> Config::load_config (string filenam
if (injection.contains("return")) {
ret = toml::find<bool>(injection,"return");
} else {
ret = false;
ret = true;
}

faults::ReorderF * fault = NULL;
Expand Down Expand Up @@ -283,7 +283,7 @@ unordered_map<string,vector<faults::Fault*>> Config::load_config (string filenam
if (injection.contains("return")) {
ret = toml::find<bool>(injection,"return");
} else {
ret = false;
ret = true;
}

faults::SplitWriteF * fault = nullptr;
Expand Down Expand Up @@ -383,7 +383,7 @@ unordered_map<string,vector<faults::Fault*>> Config::load_config (string filenam
if (injection.contains("return")) {
ret = toml::find<bool>(injection,"return");
} else {
ret = false;
ret = true;
}

faults::ClearF * fault = NULL;
Expand Down Expand Up @@ -420,6 +420,94 @@ unordered_map<string,vector<faults::Fault*>> Config::load_config (string filenam
}
}

} else if (type == CLEAR_PAGE) {
valid_fault = true;
error_msg = "The following errors were found in the configuration file for a fault of type \"clear-cache\": \n";

int occurrence = 0;
if (!injection.contains("occurrence")) {
valid_fault = false;
error_msg += "\tKey 'occurrence' for some injection of type \"clear\" is not defined in the configuration file.\n";
} else
occurrence = toml::find<int>(injection,"occurrence");

string timing{};
if (!injection.contains("timing")) {
valid_fault = false;
error_msg += "\tKey 'timing' for some injection of type \"clear\" is not defined in the configuration file.\n";
} else
timing = toml::find<string>(injection,"timing");

string op{};
if (!injection.contains("op")) {
valid_fault = false;
error_msg += "\tKey 'op' for some injection of type \"clear\" is not defined in the configuration file.\n";
} else
op = toml::find<string>(injection,"op");

string from = "none";
if (injection.contains("from"))
from = toml::find<string>(injection,"from");

string to = "none";
if (injection.contains("to"))
to = toml::find<string>(injection,"to");

string pages{};
if (!injection.contains("pages")) {
valid_fault = false;
error_msg += "\tKey 'pages' for some injection of type \"clear-page\" is not defined in the configuration file.\n";
} else
pages = toml::find<string>(injection,"pages");

bool crash = false;
if (!injection.contains("crash")) {
valid_fault = false;
error_msg += "\tKey 'crash' for some injection of type \"clear\" is not defined in the configuration file.\n";
} else
crash = toml::find<bool>(injection,"crash");

bool ret;
if (injection.contains("return")) {
ret = toml::find<bool>(injection,"return");
} else {
ret = true;
}

faults::ClearP * fault = NULL;
vector<string> errors;
if (valid_fault) {
fault = new faults::ClearP(timing,op,from,to,occurrence,crash,pages,ret);
errors = fault->validate();
}

if (!valid_fault || errors.size() > 0) {
for (string error : errors) {
error_msg += "\t" + error + "\n";
}
spdlog::error(error_msg);
delete fault;

} else {

auto it = faults.find(from);
if (it == faults.end()) {
vector<faults::Fault*> v_faults;
v_faults.push_back(fault);
faults[from] = v_faults;
} else {
//At the moment, only one clear fault per file is acceptable.
for (faults::Fault* f : it->second) {
faults::ClearP* clear_fault = dynamic_cast<faults::ClearP*>(f);
if (clear_fault) {
valid_fault = false;
spdlog::error("It is only acceptable one clear-page fault per file.");
}
}
if (valid_fault) (it->second).push_back(fault);
}
}

} else {
spdlog::error("Key 'type' for some injection has an unknown value in the configuration file.");
}
Expand Down
65 changes: 63 additions & 2 deletions libs/libpcache/src/faults.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -29,7 +29,7 @@ ReorderF::ReorderF() : Fault(TORN_SEQ) {
this->op = "";
this->persist = v;
this->occurrence = 0;
this->ret = false;
this->ret = true;
}

ReorderF::~ReorderF(){}
Expand Down Expand Up @@ -79,7 +79,7 @@ SplitWriteF::SplitWriteF() : Fault(TORN_OP) {
this->persist = p;
this->parts_bytes = v;
this->parts = 0;
this->ret = false;
this->ret = true;
}

SplitWriteF::~SplitWriteF() {}
Expand Down Expand Up @@ -173,5 +173,66 @@ vector<string> ClearF::validate() {
return errors;
}

// clear page fault

const unordered_set<string> ClearP::allow_crash_fs_operations = {"unlink",
"truncate",
"fsync",
"write",
"create",
"access",
"open",
"read",
"rename",
"link",
"symlink"};

const unordered_set<string> ClearP::fs_op_multi_path = {"rename", "link", "symlink"};

ClearP::ClearP (string timing, string op, string from, string to, int occurrence, bool crash, string pages, bool ret) : Fault(CLEAR) {
this->timing = timing;
this->op = op;
this->from = from;
this->to = to;
this->occurrence = occurrence;
this->crash = crash;
this->pages = pages;
(this->counter).store(0);
this->ret = ret;
}

ClearP::~ClearP(){}

vector<string> ClearP::validate() {
vector<string> errors;
if (this->occurrence <= 0) {
errors.push_back("Occurrence must be greater than 0.");
}

if (ClearP::allow_crash_fs_operations.find(this->op) == ClearP::allow_crash_fs_operations.end()) {
errors.push_back("Operation not available.");
}

if (this->timing != "before" && this->timing != "after") {
errors.push_back("Timing must be \"before\" or \"after\".");
}

if (this->pages != "first" && this->pages != "last" && this->pages != "first-half" && this->pages != "last-half" && this->pages != "random") {
errors.push_back("Pages must be \"first\", \"last\", \"first-half\", \"last-half\" or \"random\".");
}

if (ClearP::fs_op_multi_path.find (this->op) != ClearP::fs_op_multi_path.end ()) {
if (this->from == "none" || this->to == "none") {
errors.push_back("\"from\" and \"to\" must be set defined operations with two paths.");
}
} else {
if (this->from == "none" || this->to != "none") {
errors.push_back ("Should specify \"from\" (and not \"to\")");
}
}

return errors;
}

// namespace faults
};

0 comments on commit fd202d5

Please sign in to comment.