-
Notifications
You must be signed in to change notification settings - Fork 48
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Allow specifying a set of errnos to select from. #24
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -42,19 +42,28 @@ using namespace ::apache::thrift::server; | |
using std::shared_ptr; | ||
|
||
struct fault_descriptor { | ||
bool random; // error code must be randomized | ||
int err_no; // error code to return | ||
int32_t probability; // 0 < probability < 100 | ||
std::string regexp; // regular expression on filename | ||
bool kill_caller; // Must we kill the caller | ||
int32_t delay_us; // operation delay in us | ||
bool auto_delay; // must auto delay like an SSD | ||
bool random; // error code must be randomized | ||
std::vector<int32_t> err_nos; // error code(s) to select from | ||
int32_t probability; // 0 < probability < 100 | ||
std::string regexp; // regular expression on filename | ||
bool kill_caller; // Must we kill the caller | ||
int32_t delay_us; // operation delay in us | ||
bool auto_delay; // must auto delay like an SSD | ||
}; | ||
|
||
std::vector<int32_t> default_errnos; | ||
std::set<std::string> valid_methods; | ||
std::map<std::string, fault_descriptor> fault_map; | ||
std::mutex mutex; | ||
|
||
void init_default_errnos() | ||
{ | ||
int32_t errno; | ||
for (errno = E2BIG; errno < EXFULL; errno++) { | ||
default_errnos.push_back(errno); | ||
} | ||
} | ||
|
||
void init_valid_methods() | ||
{ | ||
valid_methods.insert("getattr"); | ||
|
@@ -104,13 +113,16 @@ static bool is_valid_method(std::string method) | |
} | ||
|
||
// return a random err_no | ||
static int random_err_no() | ||
static int random_err_no(std::vector<int32_t> err_nos) | ||
{ | ||
std::random_device rd; | ||
std::uniform_int_distribution<int> dist(E2BIG, EXFULL); | ||
if (err_nos.empty() == 0) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You mean |
||
err_nos = default_errnos; | ||
} | ||
|
||
return dist(rd); | ||
} | ||
std::random_device rd; | ||
std::uniform_int_distribution<int> dist(0, err_nos.size()); | ||
return int(err_nos[dist(rd)]); | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. As a follow up, we need to use a PRNG ( It would also be nice to add an option to provide a seed to have reproducible runs. |
||
} | ||
|
||
// return true if random number is not in the probability | ||
static bool get_lucky(int probability) | ||
|
@@ -125,7 +137,7 @@ static bool get_lucky(int probability) | |
if (dist(rd) > probability) { | ||
return true; | ||
} | ||
|
||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cosmetic changes should be done in cosmetic-only patches, that contain no functional change. |
||
return false; | ||
} | ||
|
||
|
@@ -139,16 +151,13 @@ int error_inject(volatile int in_flight, std::string path, std::string method) | |
return 0; | ||
} | ||
|
||
// get the fault injection descritor | ||
// get the fault injection descriptor | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto, move to a patch with cosmetic changes only |
||
auto descr = fault_map[method]; | ||
|
||
int err_no = 0; | ||
|
||
// get the err_no to inject | ||
if (descr.err_no) { | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Let's instead special case the Although drawing a random number in |
||
err_no = descr.err_no; | ||
} else if (descr.random) { | ||
err_no = random_err_no(); | ||
int err_no = 0; | ||
if (descr.random || !descr.err_nos.empty()) { | ||
err_no = random_err_no(descr.err_nos); | ||
} | ||
|
||
if (descr.regexp.size()) { | ||
|
@@ -208,14 +217,14 @@ class server_handler: public serverIf { | |
} | ||
|
||
void set_fault(const std::vector<std::string>& methods, const bool random, | ||
const int32_t err_no, const int32_t probability, | ||
const std::vector<int32_t> & err_nos, const int32_t probability, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nit: There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Why not provide it by value and move it below rather than copying? |
||
const std::string& regexp, const bool kill_caller, | ||
int32_t delay_us, const bool auto_delay) | ||
{ | ||
struct fault_descriptor descr; | ||
|
||
descr.random = random; | ||
descr.err_no = err_no; | ||
descr.err_nos = err_nos; | ||
descr.probability = probability; | ||
descr.regexp = regexp; | ||
descr.kill_caller = kill_caller; | ||
|
@@ -230,7 +239,7 @@ class server_handler: public serverIf { | |
} | ||
} | ||
|
||
void set_all_fault(const bool random, const int32_t err_no, | ||
void set_all_fault(const bool random, const std::vector<int32_t> & err_nos, | ||
const int32_t probability, const std::string& regexp, | ||
const bool kill_caller, const int32_t delay_us, | ||
const bool auto_delay) | ||
|
@@ -240,8 +249,8 @@ class server_handler: public serverIf { | |
for (auto method: valid_methods) { | ||
methods.push_back(method); | ||
} | ||
set_fault(methods, random, err_no, probability, | ||
|
||
set_fault(methods, random, err_nos, probability, | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto, |
||
regexp, kill_caller, delay_us, | ||
auto_delay); | ||
} | ||
|
@@ -253,6 +262,7 @@ void server_thread() | |
int port = 9090; | ||
|
||
init_valid_methods(); | ||
init_default_errnos(); | ||
|
||
std::cout << "Server Thread started" << std::endl; | ||
try { | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,7 +7,7 @@ | |
service server { | ||
|
||
// Used to get the list of availables systems calls | ||
list<string> get_methods(), | ||
list<string> get_methods(), | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. cosmetic |
||
|
||
// Used to clear all faults sources | ||
void clear_all_faults(), | ||
|
@@ -18,7 +18,7 @@ service server { | |
// Set fault on a specific list of methods | ||
void set_fault(list<string> methods, // the list of methods to operate on | ||
bool random, // Must we return random errno | ||
i32 err_no, // A specific errno to return | ||
list<i32> err_nos, // A list of specific errnos to select from | ||
i32 probability, // Fault probability over 100 000 | ||
string regexp, // A regexp matching a victim file | ||
bool kill_caller, // Kill -9 the caller process | ||
|
@@ -27,7 +27,7 @@ service server { | |
|
||
// Works like set_fault but applies the fault to all methods | ||
void set_all_fault(bool random, | ||
i32 err_no, | ||
list<i32> err_nos, | ||
i32 probability, | ||
string regexp, | ||
bool kill_caller, | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I see where this range comes from, but it doesn't make a lot of sense to be honest.
As a follow up we should be more specific about the random errors and drop those that don't make sense, like
ENOSYS
orEL2NSYNC
and OTOH add some that do make sense likeEIO
.