1nbdkit-filter(3) NBDKIT nbdkit-filter(3)
2
3
4
6 nbdkit-filter - how to write nbdkit filters
7
9 #include <nbdkit-filter.h>
10
11 #define THREAD_MODEL NBDKIT_THREAD_MODEL_PARALLEL
12
13 static int
14 myfilter_config (nbdkit_next_config *next, void *nxdata,
15 const char *key, const char *value)
16 {
17 if (strcmp (key, "myparameter") == 0) {
18 // ...
19 return 0;
20 }
21 else {
22 // pass through to next filter or plugin
23 return next (nxdata, key, value);
24 }
25 }
26
27 static struct nbdkit_filter filter = {
28 .name = "filter",
29 .config = myfilter_config,
30 /* etc */
31 };
32
33 NBDKIT_REGISTER_FILTER(filter)
34
35 When this has been compiled to a shared library, do:
36
37 nbdkit [--args ...] --filter=./myfilter.so plugin [key=value ...]
38
39 When debugging, use the -fv options:
40
41 nbdkit -fv --filter=./myfilter.so plugin [key=value ...]
42
44 One or more nbdkit filters can be placed in front of an nbdkit plugin
45 to modify the behaviour of the plugin. This manual page describes how
46 to create an nbdkit filter.
47
48 Filters can be used for example to limit requests to an offset/limit,
49 add copy-on-write support, or inject delays or errors (for testing).
50
51 Different filters can be stacked:
52
53 NBD ┌─────────┐ ┌─────────┐ ┌────────┐
54 client ───▶│ filter1 │───▶│ filter2 │── ─ ─ ──▶│ plugin │
55 request └─────────┘ └─────────┘ └────────┘
56
57 Each filter intercepts plugin functions (see nbdkit-plugin(3)) and can
58 call the next filter or plugin in the chain, modifying parameters,
59 calling before the filter function, in the middle or after. Filters
60 may even short-cut the chain. As an example, to process its own
61 parameters the filter can intercept the ".config" method:
62
63 static int
64 myfilter_config (nbdkit_next_config *next, void *nxdata,
65 const char *key, const char *value)
66 {
67 if (strcmp (key, "myparameter") == 0) {
68 // ...
69 // here you would handle this key, value
70 // ...
71 return 0;
72 }
73 else {
74 // pass through to next filter or plugin
75 return next (nxdata, key, value);
76 }
77 }
78
79 static struct nbdkit_filter filter = {
80 // ...
81 .config = myfilter_config,
82 // ...
83 };
84
85 The call to "next (nxdata, ...)" calls the ".config" method of the next
86 filter or plugin in the chain. In the example above any instances of
87 "myparameter=..." on the command line would not be seen by the plugin.
88
89 To see example filters:
90 https://github.com/libguestfs/nbdkit/tree/master/filters
91
92 Filters must be written in C.
93
94 Unlike plugins, where we provide a stable ABI guarantee that permits
95 operation across version differences, filters can only be run with the
96 same version of nbdkit that they were compiled with. The reason for
97 this is two-fold: the filter API includes access to struct
98 nbdkit_next_ops that is likely to change if new callbacks are added
99 (old nbdkit cannot safely run new filters that access new methods); and
100 if we added new methods then an old filter would not see them and so
101 they would be passed unmodified through the filter, and in some cases
102 that leads to data corruption (new nbdkit cannot safely run old filters
103 unaware of new methods). Therefore, unlike plugins, you should not
104 expect to distribute filters separately from nbdkit.
105
107 All filters should start by including this header file.
108
110 All filters must define a thread model. See "THREADS" in
111 nbdkit-plugin(3) for a discussion of thread models.
112
113 The final thread model is the smallest (ie. most serialized) out of all
114 the filters and the plugin. Filters cannot alter the thread model to
115 make it larger (more parallel).
116
117 If possible filters should be be written to handle fully parallel
118 requests ("NBDKIT_THREAD_MODEL_PARALLEL", even multiple requests issued
119 in parallel on the same connection). This ensures that they don't slow
120 down other filters or plugins.
121
123 All filters must define and register one "struct nbdkit_filter", which
124 contains the name of the filter and pointers to plugin methods that the
125 filter wants to intercept.
126
127 static struct nbdkit_filter filter = {
128 .name = "filter",
129 .longname = "My Filter",
130 .description = "This is my great filter for nbdkit",
131 .config = myfilter_config,
132 /* etc */
133 };
134
135 NBDKIT_REGISTER_FILTER(filter)
136
137 The ".name" field is the name of the filter. This is the only field
138 which is required.
139
141 nbdkit-filter.h defines three function types ("nbdkit_next_config",
142 "nbdkit_next_config_complete", "nbdkit_next_open") and a structure
143 called "struct nbdkit_next_ops". These abstract the next plugin or
144 filter in the chain. There is also an opaque pointer "nxdata" which
145 must be passed along when calling these functions.
146
147 The filter’s ".config", ".config_complete" and ".open" methods may only
148 call the next ".config", ".config_complete" and ".open" method in the
149 chain (optionally for ".config").
150
151 The filter’s ".close" method is called when an old connection closed,
152 and this has no "next" parameter because it cannot be short-circuited.
153
154 The filter’s other methods like ".prepare", ".get_size", ".pread" etc ―
155 always called in the context of a connection ― are passed a pointer to
156 "struct nbdkit_next_ops" which contains a comparable set of accessors
157 to plugin methods that can be called during a connection. It is
158 possible for a filter to issue (for example) extra read calls in
159 response to a single ".pwrite" call. Note that the semantics of the
160 functions in "struct nbdkit_next_ops" are slightly different from what
161 a plugin implements: for example, when a plugin's ".pread" returns -1
162 on error, the error value to advertise to the client is implicit (via
163 the plugin calling "nbdkit_set_error" or setting "errno"), whereas
164 "next_ops->pread" exposes this via an explicit parameter, allowing a
165 filter to learn or modify this error if desired.
166
167 You can modify parameters when you call the "next" function. However
168 be careful when modifying strings because for some methods (eg.
169 ".config") the plugin may save the string pointer that you pass along.
170 So you may have to ensure that the string is not freed for the lifetime
171 of the server.
172
173 Note that if your filter registers a callback but in that callback it
174 doesn't call the "next" function then the corresponding method in the
175 plugin will never be called. In particular, your ".open" method, if
176 you have one, must call the ".next" method.
177
179 "struct nbdkit_filter" has some static fields describing the filter and
180 optional callback functions which can be used to intercept plugin
181 methods.
182
183 ".name"
184 const char *name;
185
186 This field (a string) is required, and must contain only ASCII
187 alphanumeric characters and be unique amongst all filters.
188
189 ".version"
190 const char *version;
191
192 Filters may optionally set a version string which is displayed in help
193 and debugging output.
194
195 ".longname"
196 const char *longname;
197
198 An optional free text name of the filter. This field is used in error
199 messages.
200
201 ".description"
202 const char *description;
203
204 An optional multi-line description of the filter.
205
206 ".load"
207 void load (void);
208
209 This is called once just after the filter is loaded into memory. You
210 can use this to perform any global initialization needed by the filter.
211
212 ".unload"
213 void unload (void);
214
215 This may be called once just before the filter is unloaded from memory.
216 Note that it's not guaranteed that ".unload" will always be called (eg.
217 the server might be killed or segfault), so you should try to make the
218 filter as robust as possible by not requiring cleanup. See also
219 "SHUTDOWN" in nbdkit-plugin(3).
220
221 ".config"
222 int (*config) (nbdkit_next_config *next, void *nxdata,
223 const char *key, const char *value);
224
225 This intercepts the plugin ".config" method and can be used by the
226 filter to parse its own command line parameters. You should try to
227 make sure that command line parameter keys that the filter uses do not
228 conflict with ones that could be used by a plugin.
229
230 If there is an error, ".config" should call "nbdkit_error" with an
231 error message and return "-1".
232
233 ".config_complete"
234 int (*config_complete) (nbdkit_next_config_complete *next, void *nxdata);
235
236 This intercepts the plugin ".config_complete" method and can be used to
237 ensure that all parameters needed by the filter were supplied on the
238 command line.
239
240 If there is an error, ".config_complete" should call "nbdkit_error"
241 with an error message and return "-1".
242
243 ".config_help"
244 const char *config_help;
245
246 This optional multi-line help message should summarize any "key=value"
247 parameters that it takes. It does not need to repeat what already
248 appears in ".description".
249
250 If the filter doesn't take any config parameters you should probably
251 omit this.
252
253 ".open"
254 void * (*open) (nbdkit_next_open *next, void *nxdata,
255 int readonly);
256
257 This is called when a new client connection is opened and can be used
258 to allocate any per-connection data structures needed by the filter.
259 The handle (which is not the same as the plugin handle) is passed back
260 to other filter callbacks and could be freed in the ".close" callback.
261
262 Note that the handle is completely opaque to nbdkit, but it must not be
263 NULL. If you don't need to use a handle, return
264 "NBDKIT_HANDLE_NOT_NEEDED" which is a static non-NULL pointer.
265
266 If there is an error, ".open" should call "nbdkit_error" with an error
267 message and return "NULL".
268
269 ".close"
270 void (*close) (void *handle);
271
272 This is called when the client closes the connection. It should clean
273 up any per-connection resources used by the filter.
274
275 ".prepare"
276 ".finalize"
277 int (*prepare) (struct nbdkit_next_ops *next_ops, void *nxdata,
278 void *handle);
279 int (*finalize) (struct nbdkit_next_ops *next_ops, void *nxdata,
280 void *handle);
281
282 These two methods can be used to perform any necessary operations just
283 after opening the connection (".prepare") or just before closing the
284 connection (".finalize").
285
286 For example if you need to scan the underlying disk to check for a
287 partition table, you could do it in your ".prepare" method (calling the
288 plugin's ".pread" method via "next_ops"). Or if you need to cleanly
289 update superblock data in the image on close you can do it in your
290 ".finalize" method (calling the plugin's ".pwrite" method). Doing
291 these things in the filter's ".open" or ".close" method is not
292 possible.
293
294 There is no "next_ops->prepare" or "next_ops->finalize". Unlike other
295 filter methods, prepare and finalize are not chained through the
296 "next_ops" structure. Instead the core nbdkit server calls the prepare
297 and finalize methods of all filters. Prepare methods are called
298 starting with the filter closest to the plugin and proceeding outwards.
299 Finalize methods are called in the reverse order of prepare methods.
300
301 If there is an error, both callbacks should call "nbdkit_error" with an
302 error message and return "-1".
303
304 ".get_size"
305 int64_t (*get_size) (struct nbdkit_next_ops *next_ops, void *nxdata,
306 void *handle);
307
308 This intercepts the plugin ".get_size" method and can be used to read
309 or modify the apparent size of the block device that the NBD client
310 will see.
311
312 The returned size must be ≥ 0. If there is an error, ".get_size"
313 should call "nbdkit_error" with an error message and return "-1". If
314 this function is called more than once for the same connection, it
315 should return the same value; similarly, the filter may cache
316 "next_ops->get_size" for a given connection rather than repeating
317 calls.
318
319 ".can_write"
320 ".can_flush"
321 ".is_rotational"
322 ".can_trim"
323 ".can_zero"
324 ".can_extents"
325 ".can_fua"
326 ".can_multi_conn"
327 int (*can_write) (struct nbdkit_next_ops *next_ops, void *nxdata,
328 void *handle);
329 int (*can_flush) (struct nbdkit_next_ops *next_ops, void *nxdata,
330 void *handle);
331 int (*is_rotational) (struct nbdkit_next_ops *next_ops,
332 void *nxdata,
333 void *handle);
334 int (*can_trim) (struct nbdkit_next_ops *next_ops, void *nxdata,
335 void *handle);
336 int (*can_zero) (struct nbdkit_next_ops *next_ops, void *nxdata,
337 void *handle);
338 int (*can_extents) (struct nbdkit_next_ops *next_ops, void *nxdata,
339 void *handle);
340 int (*can_fua) (struct nbdkit_next_ops *next_ops, void *nxdata,
341 void *handle);
342 int (*can_multi_conn) (struct nbdkit_next_ops *next_ops, void *nxdata,
343 void *handle);
344
345 These intercept the corresponding plugin methods, and control feature
346 bits advertised to the client.
347
348 Of note, the ".can_zero" callback in the filter controls whether the
349 server advertises zero support to the client, which is slightly
350 different semantics than the plugin; that is, "next_ops->can_zero"
351 always returns true for a plugin, even when the plugin's own
352 ".can_zero" callback returned false, because nbdkit implements a
353 fallback to ".pwrite" at the plugin layer.
354
355 Remember that most of the feature check functions return merely a
356 boolean success value, while ".can_fua" has three success values. The
357 difference between values may affect choices made in the filter: when
358 splitting a write request that requested FUA from the client, if
359 "next_ops->can_fua" returns "NBDKIT_FUA_NATIVE", then the filter should
360 pass the FUA flag on to each sub-request; while if it is known that FUA
361 is emulated by a flush because of a return of "NBDKIT_FUA_EMULATE", it
362 is more efficient to only flush once after all sub-requests have
363 completed (often by passing "NBDKIT_FLAG_FUA" on to only the final sub-
364 request, or by dropping the flag and ending with a direct call to
365 "next_ops->flush").
366
367 If there is an error, the callback should call "nbdkit_error" with an
368 error message and return "-1". If these functions are called more than
369 once for the same connection, they should return the same value;
370 similarly, the filter may cache the results of each counterpart in
371 "next_ops" for a given connection rather than repeating calls.
372
373 ".pread"
374 int (*pread) (struct nbdkit_next_ops *next_ops, void *nxdata,
375 void *handle, void *buf, uint32_t count, uint64_t offset,
376 uint32_t flags, int *err);
377
378 This intercepts the plugin ".pread" method and can be used to read or
379 modify data read by the plugin.
380
381 The parameter "flags" exists in case of future NBD protocol extensions;
382 at this time, it will be 0 on input, and the filter should not pass any
383 flags to "next_ops->pread".
384
385 If there is an error (including a short read which couldn't be
386 recovered from), ".pread" should call "nbdkit_error" with an error
387 message and return -1 with "err" set to the positive errno value to
388 return to the client.
389
390 ".pwrite"
391 int (*pwrite) (struct nbdkit_next_ops *next_ops, void *nxdata,
392 void *handle,
393 const void *buf, uint32_t count, uint64_t offset,
394 uint32_t flags, int *err);
395
396 This intercepts the plugin ".pwrite" method and can be used to modify
397 data written by the plugin.
398
399 This function will not be called if ".can_write" returned false; in
400 turn, the filter should not call "next_ops->pwrite" if
401 "next_ops->can_write" did not return true.
402
403 The parameter "flags" may include "NBDKIT_FLAG_FUA" on input based on
404 the result of ".can_fua". In turn, the filter should only pass
405 "NBDKIT_FLAG_FUA" on to "next_ops->pwrite" if "next_ops->can_fua"
406 returned a positive value.
407
408 If there is an error (including a short write which couldn't be
409 recovered from), ".pwrite" should call "nbdkit_error" with an error
410 message and return -1 with "err" set to the positive errno value to
411 return to the client.
412
413 ".flush"
414 int (*flush) (struct nbdkit_next_ops *next_ops, void *nxdata,
415 void *handle, uint32_t flags, int *err);
416
417 This intercepts the plugin ".flush" method and can be used to modify
418 flush requests.
419
420 This function will not be called if ".can_flush" returned false; in
421 turn, the filter should not call "next_ops->flush" if
422 "next_ops->can_flush" did not return true.
423
424 The parameter "flags" exists in case of future NBD protocol extensions;
425 at this time, it will be 0 on input, and the filter should not pass any
426 flags to "next_ops->flush".
427
428 If there is an error, ".flush" should call "nbdkit_error" with an error
429 message and return -1 with "err" set to the positive errno value to
430 return to the client.
431
432 ".trim"
433 int (*trim) (struct nbdkit_next_ops *next_ops, void *nxdata,
434 void *handle, uint32_t count, uint64_t offset,
435 uint32_t flags, int *err);
436
437 This intercepts the plugin ".trim" method and can be used to modify
438 trim requests.
439
440 This function will not be called if ".can_trim" returned false; in
441 turn, the filter should not call "next_ops->trim" if
442 "next_ops->can_trim" did not return true.
443
444 The parameter "flags" may include "NBDKIT_FLAG_FUA" on input based on
445 the result of ".can_fua". In turn, the filter should only pass
446 "NBDKIT_FLAG_FUA" on to "next_ops->trim" if "next_ops->can_fua"
447 returned a positive value.
448
449 If there is an error, ".trim" should call "nbdkit_error" with an error
450 message and return -1 with "err" set to the positive errno value to
451 return to the client.
452
453 ".zero"
454 int (*zero) (struct nbdkit_next_ops *next_ops, void *nxdata,
455 void *handle, uint32_t count, uint64_t offset, uint32_t flags,
456 int *err);
457
458 This intercepts the plugin ".zero" method and can be used to modify
459 zero requests.
460
461 This function will not be called if ".can_zero" returned false; in
462 turn, the filter should not call "next_ops->zero" if
463 "next_ops->can_zero" did not return true.
464
465 On input, the parameter "flags" may include "NBDKIT_FLAG_MAY_TRIM"
466 unconditionally, and "NBDKIT_FLAG_FUA" based on the result of
467 ".can_fua". In turn, the filter may pass "NBDKIT_FLAG_MAY_TRIM"
468 unconditionally, but should only pass "NBDKIT_FLAG_FUA" on to
469 "next_ops->zero" if "next_ops->can_fua" returned a positive value.
470
471 Note that unlike the plugin ".zero" which is permitted to fail with
472 "EOPNOTSUPP" to force a fallback to ".pwrite", the function
473 "next_ops->zero" will never fail with "err" set to "EOPNOTSUPP" because
474 the fallback has already taken place.
475
476 If there is an error, ".zero" should call "nbdkit_error" with an error
477 message and return -1 with "err" set to the positive errno value to
478 return to the client. The filter should never fail with "EOPNOTSUPP"
479 (while plugins have automatic fallback to ".pwrite", filters do not).
480
481 ".extents"
482 int (*extents) (struct nbdkit_next_ops *next_ops, void *nxdata,
483 void *handle, uint32_t count, uint64_t offset, uint32_t flags,
484 struct nbdkit_extents *extents,
485 int *err);
486
487 This intercepts the plugin ".extents" method and can be used to modify
488 extent requests.
489
490 This function will not be called if ".can_extents" returned false; in
491 turn, the filter should not call "next_ops->extents" if
492 "next_ops->can_extents" did not return true.
493
494 It is possible for filters to transform the extents list received back
495 from the layer below. Without error checking it would look like this:
496
497 myfilter_extents (..., uint32_t count, uint64_t offset, ...)
498 {
499 size_t i;
500 struct nbdkit_extents *extents2;
501 struct nbdkit_extent e;
502 int64_t size;
503
504 size = next_ops->get_size (nxdata);
505 extents2 = nbdkit_extents_new (offset + shift, size - shift);
506 next_ops->extents (nxdata, count, offset + shift, flags, extents2, err);
507 for (i = 0; i < nbdkit_extents_count (extents2); ++i) {
508 e = nbdkit_get_extent (extents2, i);
509 e.offset -= shift;
510 nbdkit_add_extent (extents, e.offset, e.length, e.type);
511 }
512 nbdkit_extents_free (extents2);
513 }
514
515 If there is an error, ".extents" should call "nbdkit_error" with an
516 error message and return -1 with "err" set to the positive errno value
517 to return to the client.
518
519 Allocating and freeing nbdkit_extents list
520
521 Two functions are provided to filters only for allocating and freeing
522 the map:
523
524 struct nbdkit_extents *nbdkit_extents_new (uint64_t start, uint64_t end);
525
526 Allocates and returns a new, empty extents list. The "start" parameter
527 is the start of the range described in the list, and the "end"
528 parameter is the offset of the byte beyond the end. Normally you would
529 pass in "offset" as the start and the size of the plugin as the end,
530 but for filters which adjust offsets, they should pass in the adjusted
531 offset.
532
533 On error this function can return "NULL". In this case it calls
534 "nbdkit_error" and/or "nbdkit_set_error" as required. "errno" will be
535 set to a suitable value.
536
537 void nbdkit_extents_free (struct nbdkit_extents *);
538
539 Frees an existing extents list.
540
541 Iterating over nbdkit_extents list
542
543 Two functions are provided to filters only to iterate over the extents
544 in order:
545
546 size_t nbdkit_extents_count (const struct nbdkit_extents *);
547
548 Returns the number of extents in the list.
549
550 struct nbdkit_extent {
551 uint64_t offset;
552 uint64_t length;
553 uint32_t type;
554 };
555 struct nbdkit_extent nbdkit_get_extent (const struct nbdkit_extents *,
556 size_t i);
557
558 Returns a copy of the "i"'th extent.
559
561 If there is an error in the filter itself, the filter should call
562 "nbdkit_error" to report an error message. If the callback is involved
563 in serving data, the explicit "err" parameter determines the error code
564 that will be sent to the client; other callbacks should return the
565 appropriate error indication, eg. "NULL" or "-1".
566
567 "nbdkit_error" has the following prototype and works like printf(3):
568
569 void nbdkit_error (const char *fs, ...);
570 void nbdkit_verror (const char *fs, va_list args);
571
572 For convenience, "nbdkit_error" preserves the value of "errno", and
573 also supports the glibc extension of a single %m in a format string
574 expanding to "strerror(errno)", even on platforms that don't support
575 that natively.
576
578 Run the server with -f and -v options so it doesn't fork and you can
579 see debugging information:
580
581 nbdkit -fv --filter=./myfilter.so plugin [key=value [key=value [...]]]
582
583 To print debugging information from within the filter, call
584 "nbdkit_debug", which has the following prototype and works like
585 printf(3):
586
587 void nbdkit_debug (const char *fs, ...);
588 void nbdkit_vdebug (const char *fs, va_list args);
589
590 For convenience, "nbdkit_debug" preserves the value of "errno", and
591 also supports the glibc extension of a single %m in a format string
592 expanding to "strerror(errno)", even on platforms that don't support
593 that natively. Note that "nbdkit_debug" only prints things when the
594 server is in verbose mode (-v option).
595
596 Debug Flags
597 Debug Flags in filters work exactly the same way as plugins. See
598 "Debug Flags" in nbdkit-plugin(3).
599
601 The filter is a "*.so" file and possibly a manual page. You can of
602 course install the filter "*.so" file wherever you want, and users will
603 be able to use it by running:
604
605 nbdkit --filter=/path/to/filter.so plugin [args]
606
607 However if the shared library has a name of the form
608 "nbdkit-name-filter.so" and if the library is installed in the
609 $filterdir directory, then users can be run it by only typing:
610
611 nbdkit --filter=name plugin [args]
612
613 The location of the $filterdir directory is set when nbdkit is compiled
614 and can be found by doing:
615
616 nbdkit --dump-config
617
618 If using the pkg-config/pkgconf system then you can also find the
619 filter directory at compile time by doing:
620
621 pkgconf nbdkit --variable=filterdir
622
624 nbdkit provides a pkg-config/pkgconf file called "nbdkit.pc" which
625 should be installed on the correct path when the nbdkit development
626 environment is installed. You can use this in autoconf configure.ac
627 scripts to test for the development environment:
628
629 PKG_CHECK_MODULES([NBDKIT], [nbdkit >= 1.2.3])
630
631 The above will fail unless nbdkit ≥ 1.2.3 and the header file is
632 installed, and will set "NBDKIT_CFLAGS" and "NBDKIT_LIBS" appropriately
633 for compiling filters.
634
635 You can also run pkg-config/pkgconf directly, for example:
636
637 if ! pkgconf nbdkit --exists; then
638 echo "you must install the nbdkit development environment"
639 exit 1
640 fi
641
642 You can also substitute the filterdir variable by doing:
643
644 PKG_CHECK_VAR([NBDKIT_FILTERDIR], [nbdkit], [filterdir])
645
646 which defines "$(NBDKIT_FILTERDIR)" in automake-generated Makefiles.
647
649 nbdkit(1), nbdkit-plugin(3).
650
651 Standard filters provided by nbdkit:
652
653 nbdkit-blocksize-filter(1), nbdkit-cache-filter(1),
654 nbdkit-cow-filter(1), nbdkit-delay-filter(1), nbdkit-error-filter(1),
655 nbdkit-fua-filter(1), nbdkit-log-filter(1), nbdkit-noextents-filter(1),
656 nbdkit-nozero-filter(1), nbdkit-offset-filter(1),
657 nbdkit-partition-filter(1), nbdkit-rate-filter(1),
658 nbdkit-readahead-filter(1), nbdkit-truncate-filter(1),
659 nbdkit-xz-filter(1) .
660
662 Eric Blake
663
664 Richard W.M. Jones
665
667 Copyright (C) 2013-2018 Red Hat Inc.
668
670 Redistribution and use in source and binary forms, with or without
671 modification, are permitted provided that the following conditions are
672 met:
673
674 · Redistributions of source code must retain the above copyright
675 notice, this list of conditions and the following disclaimer.
676
677 · Redistributions in binary form must reproduce the above copyright
678 notice, this list of conditions and the following disclaimer in the
679 documentation and/or other materials provided with the
680 distribution.
681
682 · Neither the name of Red Hat nor the names of its contributors may
683 be used to endorse or promote products derived from this software
684 without specific prior written permission.
685
686 THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND ANY
687 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
688 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
689 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR CONTRIBUTORS BE
690 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
691 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
692 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
693 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
694 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
695 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
696 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
697
698
699
700nbdkit-1.12.3 2019-05-22 nbdkit-filter(3)