In the error filter, all we need to do is copy-and-paste existing
per-command errors to one more class of commands (well, technically,
this isn't enabled until a later patch flips the default for
.can_cache to pass-through).
Signed-off-by: Eric Blake <eblake(a)redhat.com>
---
filters/error/nbdkit-error-filter.pod | 8 ++++++-
filters/error/error.c | 32 ++++++++++++++++++++++++---
2 files changed, 36 insertions(+), 4 deletions(-)
diff --git a/filters/error/nbdkit-error-filter.pod
b/filters/error/nbdkit-error-filter.pod
index 16ef184..eb738a3 100644
--- a/filters/error/nbdkit-error-filter.pod
+++ b/filters/error/nbdkit-error-filter.pod
@@ -13,6 +13,7 @@ nbdkit-error-filter - inject errors for testing clients
[error-trim=...] [error-trim-rate=...] [error-trim-file=...]
[error-zero=...] [error-zero-rate=...] [error-zero-file=...]
[error-extents=...] [error-extents-rate=...] [error-extents-file=...]
+ [error-cache=...] [error-cache-rate=...] [error-cache-file=...]
=head1 DESCRIPTION
@@ -30,7 +31,7 @@ Inject a low rate of errors randomly into the connection:
nbdkit --filter=error file disk.img error-rate=1%
-Reading, trimming and extents (block status) requests will be
+Reading, trimming, cache and extents (block status) requests will be
successful, but all writes and zeroing will return "No space left on
device":
@@ -112,6 +113,11 @@ settings to NBD zero requests.
Same as C<error>, C<error-rate> and C<error-file> but only apply the
settings to NBD block status requests to read extents.
+=item B<error-cache>, B<error-cache-rate>, B<error-cache-file>.
+
+Same as C<error>, C<error-rate> and C<error-file> but only apply the
+settings to NBD cache requests.
+
=back
=head1 NOTES
diff --git a/filters/error/error.c b/filters/error/error.c
index 8932292..aba6213 100644
--- a/filters/error/error.c
+++ b/filters/error/error.c
@@ -1,5 +1,5 @@
/* nbdkit
- * Copyright (C) 2018 Red Hat Inc.
+ * Copyright (C) 2018-2019 Red Hat Inc.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are
@@ -64,6 +64,7 @@ static struct error_settings pwrite_settings = ERROR_DEFAULT;
static struct error_settings trim_settings = ERROR_DEFAULT;
static struct error_settings zero_settings = ERROR_DEFAULT;
static struct error_settings extents_settings = ERROR_DEFAULT;
+static struct error_settings cache_settings = ERROR_DEFAULT;
/* Random state.
* This must only be accessed when holding the lock (except for load).
@@ -85,6 +86,7 @@ error_unload (void)
free (trim_settings.file);
free (zero_settings.file);
free (extents_settings.file);
+ free (cache_settings.file);
}
static const struct { const char *name; int error; } errors[] = {
@@ -165,7 +167,7 @@ error_config (nbdkit_next_config *next, void *nxdata,
return -1;
pread_settings.error = pwrite_settings.error =
trim_settings.error = zero_settings.error =
- extents_settings.error = i;
+ extents_settings.error = cache_settings.error = i;
return 0;
}
else if (strcmp (key, "error-pread") == 0)
@@ -178,13 +180,15 @@ error_config (nbdkit_next_config *next, void *nxdata,
return parse_error (key, value, &zero_settings.error);
else if (strcmp (key, "error-extents") == 0)
return parse_error (key, value, &extents_settings.error);
+ else if (strcmp (key, "error-cache") == 0)
+ return parse_error (key, value, &cache_settings.error);
else if (strcmp (key, "error-rate") == 0) {
if (parse_error_rate (key, value, &d) == -1)
return -1;
pread_settings.rate = pwrite_settings.rate =
trim_settings.rate = zero_settings.rate =
- extents_settings.rate = d;
+ extents_settings.rate = cache_settings.rate = d;
return 0;
}
else if (strcmp (key, "error-pread-rate") == 0)
@@ -197,6 +201,8 @@ error_config (nbdkit_next_config *next, void *nxdata,
return parse_error_rate (key, value, &zero_settings.rate);
else if (strcmp (key, "error-extents-rate") == 0)
return parse_error_rate (key, value, &extents_settings.rate);
+ else if (strcmp (key, "error-cache-rate") == 0)
+ return parse_error_rate (key, value, &cache_settings.rate);
/* NB: We are using nbdkit_absolute_path here because the trigger
* file probably doesn't exist yet.
@@ -212,6 +218,8 @@ error_config (nbdkit_next_config *next, void *nxdata,
zero_settings.file = nbdkit_absolute_path (value);
free (extents_settings.file);
extents_settings.file = nbdkit_absolute_path (value);
+ free (cache_settings.file);
+ cache_settings.file = nbdkit_absolute_path (value);
return 0;
}
else if (strcmp (key, "error-pread-file") == 0) {
@@ -239,6 +247,11 @@ error_config (nbdkit_next_config *next, void *nxdata,
extents_settings.file = nbdkit_absolute_path (value);
return 0;
}
+ else if (strcmp (key, "error-cache-file") == 0) {
+ free (cache_settings.file);
+ cache_settings.file = nbdkit_absolute_path (value);
+ return 0;
+ }
else
return next (nxdata, key, value);
@@ -349,6 +362,18 @@ error_extents (struct nbdkit_next_ops *next_ops, void *nxdata,
return next_ops->extents (nxdata, count, offset, flags, extents, err);
}
+/* Extents. */
+static int
+error_cache (struct nbdkit_next_ops *next_ops, void *nxdata,
+ void *handle, uint32_t count, uint64_t offset,
+ uint32_t flags, int *err)
+{
+ if (random_error (&cache_settings, "cache", err))
+ return -1;
+
+ return next_ops->cache (nxdata, count, offset, flags, err);
+}
+
static struct nbdkit_filter filter = {
.name = "error",
.longname = "nbdkit error filter",
@@ -362,6 +387,7 @@ static struct nbdkit_filter filter = {
.trim = error_trim,
.zero = error_zero,
.extents = error_extents,
+ .cache = error_cache,
};
NBDKIT_REGISTER_FILTER(filter)
--
2.20.1