Skip to content
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

Add fault injection with 1-byte reads #92

Closed
wants to merge 3 commits into from
Closed
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
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ Supported fault injections are:
(similar to [libeatmydata](https://github.com/stewartsmith/libeatmydata),
but applicable to any file operation).
- `errinj_slowdown` - slowdown invoked file operation.
- `errinj_1byte_read` - amount of data returned by `read()` call is always
limited by a single byte.

### Building

Expand Down
2 changes: 2 additions & 0 deletions unreliablefs-scm-1.rockspec
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,8 @@ description = {
- `errinj_kill_caller` - send SIGKILL to a process that invoked file operation;
- `errinj_noop` - replace file operation with no operation;
- `errinj_slowdown` - slowdown invoked file operation;
- `errinj_1byte_read` - amount of data returned by `read()` call is always
limited by a single byte.
]],
homepage = "https://github.com/ligurio/unreliablefs",
maintainer = "Sergey Bronnikov <[email protected]>",
Expand Down
8 changes: 8 additions & 0 deletions unreliablefs.conf.5
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,10 @@ Set random errno.
limited by supported errno's.
.It Cm errinj_slowdown
File operation slowdown for nanoseconds specified by duration parameter.
.It Cm errinj_1byte_read
Return exactly 1 byte on every
.Xr read 2
operation.
.El
.Pp
The options are:
Expand Down Expand Up @@ -69,6 +73,10 @@ probability = 70
path_regexp = *.xlog
probability = 4

[errinj_1byte_read]
path_regexp = *.xlog
probability = 100

.Ed
.Sh SEE ALSO
.Xr unreliablefs 1 ,
Expand Down
38 changes: 38 additions & 0 deletions unreliablefs_errinj.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,39 @@
#include "unreliablefs.h"
#include "unreliablefs_errinj.h"

const char *errinj_name[] =
{
"errinj_errno",
"errinj_kill_caller",
"errinj_noop",
"errinj_slowdown",
"errinj_1byte_read",
};

typedef enum {
ERRINJ_ERRNO,
ERRINJ_KILL_CALLER,
ERRINJ_NOOP,
ERRINJ_SLOWDOWN,
ERRINJ_1BYTE_READ,
} errinj_type;

typedef struct errinj_conf errinj_conf;

struct errinj_conf {
char *err_injection_name;
char *op_regexp;
char *path_regexp;
char *errno_regexp;
unsigned int probability;
unsigned int duration;
errinj_type type;

TAILQ_ENTRY(errinj_conf) entries;
};

TAILQ_HEAD(err_inj_q, errinj_conf);

static int rand_range(int, int);
int error_inject(const char* path, fuse_op operation);

Expand Down Expand Up @@ -231,6 +264,11 @@ int error_inject(const char* path, fuse_op operation)
fprintf(stdout, "end of '%s' slowdown with '%d' ns\n", op_name, err->duration);
}
break;
case ERRINJ_1BYTE_READ:
fprintf(stdout, "start of 1-byte read\n");
if (strcmp(op_name, "read") == 0)
rc = -ERRINJ_1BYTE_READ;
break;
}
}

Expand Down
32 changes: 1 addition & 31 deletions unreliablefs_errinj.h
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#define MIN_PROBABLITY 0
#define MAX_PROBABLITY 100
#define ERRNO_NOOP -999
#define ERRNO_1BYTE_READ -998
#define DEFAULT_SIGNAL_NAME SIGKILL

int error_inject(const char* path, fuse_op operation);
Expand All @@ -31,35 +32,4 @@ int conf_option_handler(void* cfg, const char* section,
const char* name, const char* value);
int is_regex_matched(const char *regex, const char *string);

const char *errinj_name[] =
{
"errinj_errno",
"errinj_kill_caller",
"errinj_noop",
"errinj_slowdown",
};

typedef enum {
ERRINJ_ERRNO,
ERRINJ_KILL_CALLER,
ERRINJ_NOOP,
ERRINJ_SLOWDOWN,
} errinj_type;

typedef struct errinj_conf errinj_conf;

struct errinj_conf {
char *err_injection_name;
char *op_regexp;
char *path_regexp;
char *errno_regexp;
unsigned int probability;
unsigned int duration;
errinj_type type;

TAILQ_ENTRY(errinj_conf) entries;
};

TAILQ_HEAD(err_inj_q, errinj_conf);

#endif /* ERRINJ_HH */
5 changes: 3 additions & 2 deletions unreliablefs_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -16,9 +16,8 @@
#define _XOPEN_SOURCE 700
#endif

#define ERRNO_NOOP -999

#include "unreliablefs_ops.h"
#include "unreliablefs_errinj.h"

const char *fuse_op_name[] = {
"getattr",
Expand Down Expand Up @@ -318,6 +317,8 @@ int unreliable_read(const char *path, char *buf, size_t size, off_t offset,
int ret = error_inject(path, OP_READ);
if (ret == -ERRNO_NOOP) {
return 0;
} else if (ret == -ERRNO_1BYTE_READ) {
size = 1;
} else if (ret) {
return ret;
}
Expand Down