Commit Diff


commit - d91fa75962d8d81722b3abbf298f41ec663e9726
commit + 581f6809d6169477638240aaa1e7c70bf1484476
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;