Skip to content

Commit

Permalink
Add fault injection with wrong storage capacity
Browse files Browse the repository at this point in the history
With error injection `errinj_wrong_capacity` filesystem reports a wrong
storage capacity. Problem simulated with `errinj_wrong_capacity` may
happen in real. For instance see a case described in SQLite
documentation: "There are many fraudulent USB sticks in circulation that
report to have a high capacity (ex: 8GB) but are really only capable of
storing a much smaller amount (ex: 1GB). Attempts to write on these
devices will often result in unrelated files being overwritten. Any use
of a fraudulent flash memory device can easily lead to database
corruption, therefore."

1. https://www.sqlite.org/howtocorrupt.html

Closes #62

wrong
  • Loading branch information
ligurio committed Jan 24, 2022
1 parent 785bfb5 commit ad415e0
Show file tree
Hide file tree
Showing 5 changed files with 20 additions and 0 deletions.
3 changes: 3 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,9 @@ Supported fault injections are:
- `errinj_slowdown` - slowdown invoked file operation.
- `errinj_1byte_read` - amount of data returned by `read()` call is always
limited by a single byte.
- `errinj_wrong_capacity` - filesystem reports a wrong storage capacity.
Simulated error can happen in a wild, for instance see '4.2. Fake capacity USB
sticks' in [How To Corrupt An SQLite Database File](https://www.sqlite.org/howtocorrupt.html).

### Building

Expand Down
2 changes: 2 additions & 0 deletions unreliablefs.conf.5
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,8 @@ File operation slowdown for nanoseconds specified by duration parameter.
Return exactly 1 byte on every
.Xr read 2
operation.
.It Cm errinj_wrong_capacity
Report a wrong storage capacity.
.El
.Pp
The options are:
Expand Down
6 changes: 6 additions & 0 deletions unreliablefs_errinj.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ const char *errinj_name[] =
"errinj_noop",
"errinj_slowdown",
"errinj_1byte_read",
"errinj_wrong_capacity",
};

typedef enum {
Expand All @@ -30,6 +31,7 @@ typedef enum {
ERRINJ_NOOP,
ERRINJ_SLOWDOWN,
ERRINJ_1BYTE_READ,
ERRINJ_WRONG_CAPACITY,
} errinj_type;

typedef struct errinj_conf errinj_conf;
Expand Down Expand Up @@ -269,6 +271,10 @@ int error_inject(const char* path, fuse_op operation)
if (strcmp(op_name, "read") == 0)
rc = -ERRINJ_1BYTE_READ;
break;
case ERRINJ_WRONG_CAPACITY:
if (strcmp(op_name, "statfs") == 0)
rc = -ERRNO_WRONG_CAPACITY;
break;
}
}

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

int error_inject(const char* path, fuse_op operation);
Expand Down
8 changes: 8 additions & 0 deletions unreliablefs_ops.c
Original file line number Diff line number Diff line change
Expand Up @@ -386,6 +386,14 @@ int unreliable_statfs(const char *path, struct statvfs *buf)
int ret = error_inject(path, OP_STATFS);
if (ret == -ERRNO_NOOP) {
return 0;
} else if (ret == -ERRNO_WRONG_CAPACITY) {
/* wrong capacity */
ret = statvfs(path, buf);
if (ret == -1) {
return -errno;
}
buf->f_bfree = buf->f_bfree + ( 5 / 100.0 ) * (uint64_t)buf->f_bfree;
return 0;
} else if (ret) {
return ret;
}
Expand Down

0 comments on commit ad415e0

Please sign in to comment.