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@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