commit d5103c8c5ca25276e66527f5c9b8a838c37c341c from: Sergey Bronnikov date: Wed Jun 30 08:55:04 2021 UTC Add error injection with operation slowdown Closes #29 commit - ecfa26454887e7709a7fb8c882ee2c071c4cdf8c commit + d5103c8c5ca25276e66527f5c9b8a838c37c341c blob - 9b353ed7d52f651edcf8809b8626319c2bd5751c blob + 1ee7d1221407f9b79c6471595121f4faa3cd3a62 --- README.md +++ README.md @@ -12,6 +12,7 @@ Supported fault injections are: - `errinj_noop` - replace file operation with no operation (similar to [libeatmydata](https://github.com/stewartsmith/libeatmydata), but applicable to any file operation). +- `errinj_slowdown` - slowdown invoked file operation. ### Building blob - 3254755254a6b5735b89837b3a96b5fc667d3169 blob + 624bc25cbc29c1d549c4793cb4762e4fffb54cb9 --- unreliablefs.conf.5 +++ unreliablefs.conf.5 @@ -34,6 +34,8 @@ Send SIGKILL signal to a process that invoked file ope Set random errno. .Xr errno 2 limited by supported errno's. +.It Cm errinj_slowdown +File operation slowdown for nanoseconds specified by duration parameter. .El .Pp The options are: @@ -52,6 +54,8 @@ POSIX Extended Regular Expression syntax is supported Sets the probability in percents. Probability equal to 0 means that error injection will never happen. Probability equal to 100 means that error injection will happen on each file operation. +.It Cm duration +Sets the duration of file operation slowdown. Applicable to errinj_slowdown only. .El .Sh EXAMPLES .Bd -literal blob - 017326ff3ea0cdfc2457dbc81fd69a69a954e8ae blob + 2d9fc1a878d6025b0239b9260042e2a5a75ec857 --- unreliablefs_errinj.c +++ unreliablefs_errinj.c @@ -219,6 +219,16 @@ int error_inject(const char* path, fuse_op operation) fprintf(stdout, "errno '%s'\n", strerror(rc)); rc = -rc; break; + case ERRINJ_SLOWDOWN: ; + struct timespec ts = {}; + ts.tv_nsec = err->duration; + fprintf(stdout, "start of '%s' slowdown for '%d' ns\n", op_name, err->duration); + if (nanosleep(&ts, NULL) != 0) { + perror("nanosleep"); + } else { + fprintf(stdout, "end of '%s' slowdown with '%d' ns\n", op_name, err->duration); + } + break; } } @@ -315,6 +325,8 @@ int conf_option_handler(void* cfg, const char* section err->op_regexp = strdup(value); } else if (strcmp(key, "probability") == 0) { err->probability = atoi(value); + } else if (strcmp(key, "duration") == 0) { + err->duration = atoi(value); } else { fprintf(stderr, "unknown option '%s' in configuration file\n", key); return 0; blob - d703591e7d7ad3f918af60d8e1d795dd014f90a5 blob + 2dcc775ca5c9a010de8149d51d0bc8a92deee037 --- unreliablefs_errinj.h +++ unreliablefs_errinj.h @@ -36,12 +36,14 @@ 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; @@ -52,6 +54,7 @@ struct errinj_conf { char *path_regexp; char *errno_regexp; unsigned int probability; + unsigned int duration; errinj_type type; TAILQ_ENTRY(errinj_conf) entries;