2 * Copyright (C) 2013-2018 Red Hat Inc.
4 * Redistribution and use in source and binary forms, with or without
5 * modification, are permitted provided that the following conditions are
8 * * Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
11 * * Redistributions in binary form must reproduce the above copyright
12 * notice, this list of conditions and the following disclaimer in the
13 * documentation and/or other materials provided with the distribution.
15 * * Neither the name of Red Hat nor the names of its contributors may be
16 * used to endorse or promote products derived from this software without
17 * specific prior written permission.
19 * THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND
20 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO,
21 * THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A
22 * PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR
23 * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
24 * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
25 * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF
26 * USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
27 * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
28 * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
29 * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
46 /* We extend the generic backend struct with extra fields relating
49 struct backend_filter
{
50 struct backend backend
;
51 char *name
; /* copy of filter.name */
54 struct nbdkit_filter filter
;
57 /* Literally a backend + a connection pointer. This is the
58 * implementation of ‘void *nxdata’ in the filter API.
62 struct connection
*conn
;
65 /* Note this frees the whole chain. */
67 filter_free (struct backend
*b
)
69 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
71 f
->backend
.next
->free (f
->backend
.next
);
73 /* Acquiring this lock prevents any filter callbacks from running
78 debug ("%s: unload", f
->name
);
93 filter_thread_model (struct backend
*b
)
95 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
96 int filter_thread_model
= f
->filter
._thread_model
;
97 int thread_model
= f
->backend
.next
->thread_model (f
->backend
.next
);
99 if (filter_thread_model
< thread_model
) /* more serialized */
100 thread_model
= filter_thread_model
;
105 /* This is actually passing the request through to the final plugin,
106 * hence the function name.
109 plugin_name (struct backend
*b
)
111 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
113 return f
->backend
.next
->plugin_name (f
->backend
.next
);
117 filter_name (struct backend
*b
)
119 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
125 filter_version (struct backend
*b
)
127 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
129 return f
->filter
.version
;
133 filter_usage (struct backend
*b
)
135 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
138 printf ("filter: %s", f
->name
);
139 if (f
->filter
.longname
)
140 printf (" (%s)", f
->filter
.longname
);
142 printf ("(%s)\n", f
->filename
);
143 if (f
->filter
.description
) {
144 printf ("%s", f
->filter
.description
);
145 if ((p
= strrchr (f
->filter
.description
, '\n')) == NULL
|| p
[1])
148 if (f
->filter
.config_help
) {
149 printf ("%s", f
->filter
.config_help
);
150 if ((p
= strrchr (f
->filter
.config_help
, '\n')) == NULL
|| p
[1])
156 filter_dump_fields (struct backend
*b
)
158 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
160 f
->backend
.next
->dump_fields (f
->backend
.next
);
164 next_config (void *nxdata
, const char *key
, const char *value
)
166 struct backend
*b
= nxdata
;
167 b
->config (b
, key
, value
);
172 filter_config (struct backend
*b
, const char *key
, const char *value
)
174 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
176 debug ("%s: config key=%s, value=%s",
177 f
->name
, key
, value
);
179 if (f
->filter
.config
) {
180 if (f
->filter
.config (next_config
, f
->backend
.next
, key
, value
) == -1)
184 f
->backend
.next
->config (f
->backend
.next
, key
, value
);
188 next_config_complete (void *nxdata
)
190 struct backend
*b
= nxdata
;
191 b
->config_complete (b
);
196 filter_config_complete (struct backend
*b
)
198 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
200 debug ("%s: config_complete", f
->name
);
202 if (f
->filter
.config_complete
) {
203 if (f
->filter
.config_complete (next_config_complete
, f
->backend
.next
) == -1)
207 f
->backend
.next
->config_complete (f
->backend
.next
);
210 /* magic_config_key only applies to plugins, so this passes the
211 * request through to the plugin (hence the name).
214 plugin_magic_config_key (struct backend
*b
)
216 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
218 return f
->backend
.next
->magic_config_key (f
->backend
.next
);
222 next_open (void *nxdata
, int readonly
)
224 struct b_conn
*b_conn
= nxdata
;
226 return b_conn
->b
->open (b_conn
->b
, b_conn
->conn
, readonly
);
230 filter_open (struct backend
*b
, struct connection
*conn
, int readonly
)
232 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
233 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
236 debug ("%s: open readonly=%d", f
->name
, readonly
);
238 if (f
->filter
.open
) {
239 handle
= f
->filter
.open (next_open
, &nxdata
, readonly
);
242 connection_set_handle (conn
, f
->backend
.i
, handle
);
246 return f
->backend
.next
->open (f
->backend
.next
, conn
, readonly
);
250 filter_close (struct backend
*b
, struct connection
*conn
)
252 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
253 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
255 debug ("%s: close", f
->name
);
258 f
->filter
.close (handle
);
259 f
->backend
.next
->close (f
->backend
.next
, conn
);
262 /* The next_functions structure contains pointers to backend
263 * functions. However because these functions are all expecting a
264 * backend and a connection, we cannot call them directly, but must
265 * write some next_* functions that unpack the two parameters from a
266 * single ‘void *nxdata’ struct pointer (‘b_conn’).
270 next_get_size (void *nxdata
)
272 struct b_conn
*b_conn
= nxdata
;
273 return b_conn
->b
->get_size (b_conn
->b
, b_conn
->conn
);
277 next_can_write (void *nxdata
)
279 struct b_conn
*b_conn
= nxdata
;
280 return b_conn
->b
->can_write (b_conn
->b
, b_conn
->conn
);
284 next_can_flush (void *nxdata
)
286 struct b_conn
*b_conn
= nxdata
;
287 return b_conn
->b
->can_flush (b_conn
->b
, b_conn
->conn
);
291 next_is_rotational (void *nxdata
)
293 struct b_conn
*b_conn
= nxdata
;
294 return b_conn
->b
->is_rotational (b_conn
->b
, b_conn
->conn
);
298 next_can_trim (void *nxdata
)
300 struct b_conn
*b_conn
= nxdata
;
301 return b_conn
->b
->can_trim (b_conn
->b
, b_conn
->conn
);
305 next_can_zero (void *nxdata
)
307 struct b_conn
*b_conn
= nxdata
;
308 return b_conn
->b
->can_zero (b_conn
->b
, b_conn
->conn
);
312 next_can_extents (void *nxdata
)
314 struct b_conn
*b_conn
= nxdata
;
315 return b_conn
->b
->can_extents (b_conn
->b
, b_conn
->conn
);
319 next_can_fua (void *nxdata
)
321 struct b_conn
*b_conn
= nxdata
;
322 return b_conn
->b
->can_fua (b_conn
->b
, b_conn
->conn
);
326 next_can_multi_conn (void *nxdata
)
328 struct b_conn
*b_conn
= nxdata
;
329 return b_conn
->b
->can_multi_conn (b_conn
->b
, b_conn
->conn
);
333 next_pread (void *nxdata
, void *buf
, uint32_t count
, uint64_t offset
,
334 uint32_t flags
, int *err
)
336 struct b_conn
*b_conn
= nxdata
;
337 return b_conn
->b
->pread (b_conn
->b
, b_conn
->conn
, buf
, count
, offset
, flags
,
342 next_pwrite (void *nxdata
, const void *buf
, uint32_t count
, uint64_t offset
,
343 uint32_t flags
, int *err
)
345 struct b_conn
*b_conn
= nxdata
;
346 return b_conn
->b
->pwrite (b_conn
->b
, b_conn
->conn
, buf
, count
, offset
, flags
,
351 next_flush (void *nxdata
, uint32_t flags
, int *err
)
353 struct b_conn
*b_conn
= nxdata
;
354 return b_conn
->b
->flush (b_conn
->b
, b_conn
->conn
, flags
, err
);
358 next_trim (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
361 struct b_conn
*b_conn
= nxdata
;
362 return b_conn
->b
->trim (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
366 next_zero (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
369 struct b_conn
*b_conn
= nxdata
;
370 return b_conn
->b
->zero (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
, err
);
374 next_extents (void *nxdata
, uint32_t count
, uint64_t offset
, uint32_t flags
,
375 struct nbdkit_extents
*extents
, int *err
)
377 struct b_conn
*b_conn
= nxdata
;
378 return b_conn
->b
->extents (b_conn
->b
, b_conn
->conn
, count
, offset
, flags
,
382 static struct nbdkit_next_ops next_ops
= {
383 .get_size
= next_get_size
,
384 .can_write
= next_can_write
,
385 .can_flush
= next_can_flush
,
386 .is_rotational
= next_is_rotational
,
387 .can_trim
= next_can_trim
,
388 .can_zero
= next_can_zero
,
389 .can_extents
= next_can_extents
,
390 .can_fua
= next_can_fua
,
391 .can_multi_conn
= next_can_multi_conn
,
393 .pwrite
= next_pwrite
,
397 .extents
= next_extents
,
401 filter_prepare (struct backend
*b
, struct connection
*conn
)
403 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
404 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
405 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
407 debug ("%s: prepare", f
->name
);
409 /* Call these in order starting from the filter closest to the
412 if (f
->backend
.next
->prepare (f
->backend
.next
, conn
) == -1)
415 if (f
->filter
.prepare
&&
416 f
->filter
.prepare (&next_ops
, &nxdata
, handle
) == -1)
423 filter_finalize (struct backend
*b
, struct connection
*conn
)
425 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
426 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
427 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
429 debug ("%s: finalize", f
->name
);
431 /* Call these in reverse order to .prepare above, starting from the
432 * filter furthest away from the plugin.
434 if (f
->filter
.finalize
&&
435 f
->filter
.finalize (&next_ops
, &nxdata
, handle
) == -1)
438 return f
->backend
.next
->finalize (f
->backend
.next
, conn
);
442 filter_get_size (struct backend
*b
, struct connection
*conn
)
444 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
445 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
446 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
448 debug ("%s: get_size", f
->name
);
450 if (f
->filter
.get_size
)
451 return f
->filter
.get_size (&next_ops
, &nxdata
, handle
);
453 return f
->backend
.next
->get_size (f
->backend
.next
, conn
);
457 filter_can_write (struct backend
*b
, struct connection
*conn
)
459 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
460 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
461 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
463 debug ("%s: can_write", f
->name
);
465 if (f
->filter
.can_write
)
466 return f
->filter
.can_write (&next_ops
, &nxdata
, handle
);
468 return f
->backend
.next
->can_write (f
->backend
.next
, conn
);
472 filter_can_flush (struct backend
*b
, struct connection
*conn
)
474 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
475 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
476 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
478 debug ("%s: can_flush", f
->name
);
480 if (f
->filter
.can_flush
)
481 return f
->filter
.can_flush (&next_ops
, &nxdata
, handle
);
483 return f
->backend
.next
->can_flush (f
->backend
.next
, conn
);
487 filter_is_rotational (struct backend
*b
, struct connection
*conn
)
489 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
490 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
491 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
493 debug ("%s: is_rotational", f
->name
);
495 if (f
->filter
.is_rotational
)
496 return f
->filter
.is_rotational (&next_ops
, &nxdata
, handle
);
498 return f
->backend
.next
->is_rotational (f
->backend
.next
, conn
);
502 filter_can_trim (struct backend
*b
, struct connection
*conn
)
504 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
505 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
506 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
508 debug ("%s: can_trim", f
->name
);
510 if (f
->filter
.can_trim
)
511 return f
->filter
.can_trim (&next_ops
, &nxdata
, handle
);
513 return f
->backend
.next
->can_trim (f
->backend
.next
, conn
);
517 filter_can_zero (struct backend
*b
, struct connection
*conn
)
519 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
520 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
521 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
523 debug ("%s: can_zero", f
->name
);
525 if (f
->filter
.can_zero
)
526 return f
->filter
.can_zero (&next_ops
, &nxdata
, handle
);
528 return f
->backend
.next
->can_zero (f
->backend
.next
, conn
);
532 filter_can_extents (struct backend
*b
, struct connection
*conn
)
534 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
535 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
536 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
538 debug ("%s: can_extents", f
->name
);
540 if (f
->filter
.can_extents
)
541 return f
->filter
.can_extents (&next_ops
, &nxdata
, handle
);
543 return f
->backend
.next
->can_extents (f
->backend
.next
, conn
);
547 filter_can_fua (struct backend
*b
, struct connection
*conn
)
549 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
550 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
551 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
553 debug ("%s: can_fua", f
->name
);
555 if (f
->filter
.can_fua
)
556 return f
->filter
.can_fua (&next_ops
, &nxdata
, handle
);
558 return f
->backend
.next
->can_fua (f
->backend
.next
, conn
);
562 filter_can_multi_conn (struct backend
*b
, struct connection
*conn
)
564 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
565 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
566 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
568 debug ("%s: can_multi_conn", f
->name
);
570 if (f
->filter
.can_multi_conn
)
571 return f
->filter
.can_multi_conn (&next_ops
, &nxdata
, handle
);
573 return f
->backend
.next
->can_multi_conn (f
->backend
.next
, conn
);
577 filter_pread (struct backend
*b
, struct connection
*conn
,
578 void *buf
, uint32_t count
, uint64_t offset
,
579 uint32_t flags
, int *err
)
581 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
582 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
583 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
587 debug ("%s: pread count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
588 f
->name
, count
, offset
, flags
);
591 return f
->filter
.pread (&next_ops
, &nxdata
, handle
,
592 buf
, count
, offset
, flags
, err
);
594 return f
->backend
.next
->pread (f
->backend
.next
, conn
,
595 buf
, count
, offset
, flags
, err
);
599 filter_pwrite (struct backend
*b
, struct connection
*conn
,
600 const void *buf
, uint32_t count
, uint64_t offset
,
601 uint32_t flags
, int *err
)
603 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
604 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
605 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
607 assert (!(flags
& ~NBDKIT_FLAG_FUA
));
609 debug ("%s: pwrite count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
610 f
->name
, count
, offset
, flags
);
612 if (f
->filter
.pwrite
)
613 return f
->filter
.pwrite (&next_ops
, &nxdata
, handle
,
614 buf
, count
, offset
, flags
, err
);
616 return f
->backend
.next
->pwrite (f
->backend
.next
, conn
,
617 buf
, count
, offset
, flags
, err
);
621 filter_flush (struct backend
*b
, struct connection
*conn
, uint32_t flags
,
624 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
625 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
626 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
630 debug ("%s: flush flags=0x%" PRIx32
, f
->name
, flags
);
633 return f
->filter
.flush (&next_ops
, &nxdata
, handle
, flags
, err
);
635 return f
->backend
.next
->flush (f
->backend
.next
, conn
, flags
, err
);
639 filter_trim (struct backend
*b
, struct connection
*conn
,
640 uint32_t count
, uint64_t offset
,
641 uint32_t flags
, int *err
)
643 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
644 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
645 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
649 debug ("%s: trim count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
650 f
->name
, count
, offset
, flags
);
653 return f
->filter
.trim (&next_ops
, &nxdata
, handle
, count
, offset
, flags
,
656 return f
->backend
.next
->trim (f
->backend
.next
, conn
, count
, offset
, flags
,
661 filter_zero (struct backend
*b
, struct connection
*conn
,
662 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
664 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
665 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
666 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
668 assert (!(flags
& ~(NBDKIT_FLAG_MAY_TRIM
| NBDKIT_FLAG_FUA
)));
670 debug ("%s: zero count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
671 f
->name
, count
, offset
, flags
);
674 return f
->filter
.zero (&next_ops
, &nxdata
, handle
,
675 count
, offset
, flags
, err
);
677 return f
->backend
.next
->zero (f
->backend
.next
, conn
,
678 count
, offset
, flags
, err
);
682 filter_extents (struct backend
*b
, struct connection
*conn
,
683 uint32_t count
, uint64_t offset
, uint32_t flags
,
684 struct nbdkit_extents
*extents
, int *err
)
686 struct backend_filter
*f
= container_of (b
, struct backend_filter
, backend
);
687 void *handle
= connection_get_handle (conn
, f
->backend
.i
);
688 struct b_conn nxdata
= { .b
= f
->backend
.next
, .conn
= conn
};
690 assert (!(flags
& ~NBDKIT_FLAG_REQ_ONE
));
692 debug ("%s: extents count=%" PRIu32
" offset=%" PRIu64
" flags=0x%" PRIx32
,
693 f
->name
, count
, offset
, flags
);
695 if (f
->filter
.extents
)
696 return f
->filter
.extents (&next_ops
, &nxdata
, handle
,
697 count
, offset
, flags
,
700 return f
->backend
.next
->extents (f
->backend
.next
, conn
,
701 count
, offset
, flags
,
705 static struct backend filter_functions
= {
707 .thread_model
= filter_thread_model
,
709 .plugin_name
= plugin_name
,
710 .usage
= filter_usage
,
711 .version
= filter_version
,
712 .dump_fields
= filter_dump_fields
,
713 .config
= filter_config
,
714 .config_complete
= filter_config_complete
,
715 .magic_config_key
= plugin_magic_config_key
,
717 .prepare
= filter_prepare
,
718 .finalize
= filter_finalize
,
719 .close
= filter_close
,
720 .get_size
= filter_get_size
,
721 .can_write
= filter_can_write
,
722 .can_flush
= filter_can_flush
,
723 .is_rotational
= filter_is_rotational
,
724 .can_trim
= filter_can_trim
,
725 .can_zero
= filter_can_zero
,
726 .can_extents
= filter_can_extents
,
727 .can_fua
= filter_can_fua
,
728 .can_multi_conn
= filter_can_multi_conn
,
729 .pread
= filter_pread
,
730 .pwrite
= filter_pwrite
,
731 .flush
= filter_flush
,
734 .extents
= filter_extents
,
737 /* Register and load a filter. */
739 filter_register (struct backend
*next
, size_t index
, const char *filename
,
740 void *dl
, struct nbdkit_filter
*(*filter_init
) (void))
742 struct backend_filter
*f
;
743 const struct nbdkit_filter
*filter
;
746 f
= calloc (1, sizeof *f
);
753 f
->backend
= filter_functions
;
754 f
->backend
.next
= next
;
755 f
->backend
.i
= index
;
756 f
->filename
= strdup (filename
);
757 if (f
->filename
== NULL
) goto out_of_memory
;
760 debug ("registering filter %s", f
->filename
);
762 /* Call the initialization function which returns the address of the
763 * filter's own 'struct nbdkit_filter'.
765 filter
= filter_init ();
767 fprintf (stderr
, "%s: %s: filter registration function failed\n",
768 program_name
, f
->filename
);
772 /* We do not provide API or ABI guarantees for filters, other than
773 * the ABI position of _api_version that will let us diagnose
774 * mismatch when the API changes.
776 if (filter
->_api_version
!= NBDKIT_FILTER_API_VERSION
) {
778 "%s: %s: filter is incompatible with this version of nbdkit "
779 "(_api_version = %d)\n",
780 program_name
, f
->filename
, filter
->_api_version
);
786 /* Only filter.name is required. */
787 if (f
->filter
.name
== NULL
) {
788 fprintf (stderr
, "%s: %s: filter must have a .name field\n",
789 program_name
, f
->filename
);
793 len
= strlen (f
->filter
.name
);
795 fprintf (stderr
, "%s: %s: filter.name field must not be empty\n",
796 program_name
, f
->filename
);
799 for (i
= 0; i
< len
; ++i
) {
800 if (!((f
->filter
.name
[i
] >= '0' && f
->filter
.name
[i
] <= '9') ||
801 (f
->filter
.name
[i
] >= 'a' && f
->filter
.name
[i
] <= 'z') ||
802 (f
->filter
.name
[i
] >= 'A' && f
->filter
.name
[i
] <= 'Z'))) {
804 "%s: %s: filter.name ('%s') field "
805 "must contain only ASCII alphanumeric characters\n",
806 program_name
, f
->filename
, f
->filter
.name
);
811 /* Copy the module's name into local storage, so that filter.name
812 * survives past unload.
814 f
->name
= strdup (f
->filter
.name
);
815 if (f
->name
== NULL
) {
820 debug ("registered filter %s (name %s)", f
->filename
, f
->name
);
822 /* Set debug flags before calling load. */
823 set_debug_flags (dl
, f
->name
);
825 /* Call the on-load callback if it exists. */
826 debug ("%s: load", f
->name
);
830 return (struct backend
*) f
;