Version 1.33.10.
[nbdkit.git] / server / plugins.c
blobf1e1c415fa213fc7772a79fb9721df51c61d0ebf
1 /* nbdkit
2 * Copyright (C) 2013-2021 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
6 * met:
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
30 * SUCH DAMAGE.
33 #include <config.h>
35 #include <stdio.h>
36 #include <stdlib.h>
37 #include <stdint.h>
38 #include <string.h>
39 #include <inttypes.h>
40 #include <assert.h>
41 #include <errno.h>
43 #ifdef HAVE_SYS_SOCKET_H
44 #include <sys/socket.h>
45 #endif
47 #include "internal.h"
48 #include "minmax.h"
49 #include "ispowerof2.h"
51 /* We extend the generic backend struct with extra fields relating
52 * to this plugin.
54 struct backend_plugin {
55 struct backend backend;
56 struct nbdkit_plugin plugin;
59 static void
60 plugin_free (struct backend *b)
62 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
64 backend_unload (b, p->plugin.unload);
65 free (p);
68 static int
69 plugin_thread_model (struct backend *b)
71 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
72 int model = p->plugin._thread_model;
73 int r;
75 #if !(defined SOCK_CLOEXEC && defined HAVE_MKOSTEMP && defined HAVE_PIPE2 && \
76 defined HAVE_ACCEPT4)
77 if (model > NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS) {
78 debug ("system lacks atomic CLOEXEC, serializing to avoid fd leaks");
79 model = NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS;
81 #endif
83 if (p->plugin.thread_model) {
84 r = p->plugin.thread_model ();
85 if (r == -1)
86 exit (EXIT_FAILURE);
87 if (r < model)
88 model = r;
91 return model;
94 static const char *
95 plugin_name (struct backend *b)
97 return b->name;
100 static void
101 plugin_usage (struct backend *b)
103 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
104 const char *t;
106 printf ("plugin: %s", b->name);
107 if (p->plugin.longname)
108 printf (" (%s)", p->plugin.longname);
109 printf ("\n");
110 printf ("(%s)\n", b->filename);
111 if (p->plugin.description) {
112 printf ("%s", p->plugin.description);
113 if ((t = strrchr (p->plugin.description, '\n')) == NULL || t[1])
114 printf ("\n");
116 if (p->plugin.config_help) {
117 printf ("%s", p->plugin.config_help);
118 if ((t = strrchr (p->plugin.config_help, '\n')) == NULL || t[1])
119 printf ("\n");
123 static const char *
124 plugin_version (struct backend *b)
126 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
128 return p->plugin.version;
131 /* This implements the --dump-plugin option. */
132 static void
133 plugin_dump_fields (struct backend *b)
135 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
136 char *path;
138 path = nbdkit_realpath (b->filename);
139 printf ("path=%s\n", path);
140 free (path);
142 printf ("name=%s\n", b->name);
143 if (p->plugin.version)
144 printf ("version=%s\n", p->plugin.version);
146 printf ("api_version=%d\n", p->plugin._api_version);
147 printf ("struct_size=%" PRIu64 "\n", p->plugin._struct_size);
148 printf ("max_thread_model=%s\n",
149 name_of_thread_model (p->plugin._thread_model));
150 printf ("thread_model=%s\n",
151 name_of_thread_model (top->thread_model (top)));
152 printf ("errno_is_preserved=%d\n", !!p->plugin.errno_is_preserved);
153 if (p->plugin.magic_config_key)
154 printf ("magic_config_key=%s\n", p->plugin.magic_config_key);
156 #define HAS(field) if (p->plugin.field) printf ("has_%s=1\n", #field)
157 HAS (longname);
158 HAS (description);
159 HAS (load);
160 HAS (unload);
161 HAS (dump_plugin);
162 HAS (config);
163 HAS (config_complete);
164 HAS (config_help);
165 HAS (thread_model);
166 HAS (get_ready);
167 HAS (after_fork);
168 HAS (cleanup);
169 HAS (preconnect);
170 HAS (list_exports);
171 HAS (default_export);
173 HAS (open);
174 HAS (close);
175 HAS (export_description);
176 HAS (get_size);
177 HAS (block_size);
178 HAS (can_write);
179 HAS (can_flush);
180 HAS (is_rotational);
181 HAS (can_trim);
182 HAS (can_zero);
183 HAS (can_fast_zero);
184 HAS (can_extents);
185 HAS (can_fua);
186 HAS (can_multi_conn);
187 HAS (can_cache);
189 HAS (pread);
190 HAS (pwrite);
191 HAS (flush);
192 HAS (trim);
193 HAS (zero);
194 HAS (extents);
195 HAS (cache);
197 HAS (_pread_v1);
198 HAS (_pwrite_v1);
199 HAS (_flush_v1);
200 HAS (_trim_v1);
201 HAS (_zero_v1);
202 #undef HAS
204 /* Custom fields. */
205 if (p->plugin.dump_plugin)
206 p->plugin.dump_plugin ();
209 static void
210 plugin_config (struct backend *b, const char *key, const char *value)
212 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
214 debug ("%s: config key=%s, value=%s", b->name, key, value);
216 if (p->plugin.config == NULL) {
217 fprintf (stderr,
218 "%s: %s: this plugin does not need command line configuration\n"
219 "Try using: %s --help %s\n",
220 program_name, b->filename,
221 program_name, b->filename);
222 exit (EXIT_FAILURE);
225 if (p->plugin.config (key, value) == -1)
226 exit (EXIT_FAILURE);
229 static void
230 plugin_config_complete (struct backend *b)
232 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
234 debug ("%s: config_complete", b->name);
236 if (!p->plugin.config_complete)
237 return;
239 if (p->plugin.config_complete () == -1)
240 exit (EXIT_FAILURE);
243 static const char *
244 plugin_magic_config_key (struct backend *b)
246 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
248 return p->plugin.magic_config_key;
251 static void
252 plugin_get_ready (struct backend *b)
254 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
256 debug ("%s: get_ready", b->name);
258 if (!p->plugin.get_ready)
259 return;
261 if (p->plugin.get_ready () == -1)
262 exit (EXIT_FAILURE);
265 static void
266 plugin_after_fork (struct backend *b)
268 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
270 debug ("%s: after_fork", b->name);
272 if (!p->plugin.after_fork)
273 return;
275 if (p->plugin.after_fork () == -1)
276 exit (EXIT_FAILURE);
279 static void
280 plugin_cleanup (struct backend *b)
282 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
284 debug ("%s: cleanup", b->name);
286 if (p->plugin.cleanup)
287 p->plugin.cleanup ();
290 static int
291 plugin_preconnect (struct backend *b, int readonly)
293 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
295 debug ("%s: preconnect", b->name);
297 if (!p->plugin.preconnect)
298 return 0;
300 return p->plugin.preconnect (readonly);
303 static int
304 plugin_list_exports (struct backend *b, int readonly, int is_tls,
305 struct nbdkit_exports *exports)
307 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
309 if (!p->plugin.list_exports)
310 return nbdkit_use_default_export (exports);
312 return p->plugin.list_exports (readonly, is_tls, exports);
315 static const char *
316 plugin_default_export (struct backend *b, int readonly, int is_tls)
318 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
320 if (!p->plugin.default_export)
321 return "";
323 return p->plugin.default_export (readonly, is_tls);
326 static void *
327 plugin_open (struct context *c, int readonly, const char *exportname,
328 int is_tls)
330 struct backend *b = c->b;
331 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
332 void *r;
334 assert (p->plugin.open != NULL);
336 /* Save the exportname since the lifetime of the string passed in
337 * here is likely to be brief. In addition this provides a place
338 * for nbdkit_export_name to retrieve it if called from the plugin.
339 * While readonly and the export name can be altered in plugins, the
340 * tls mode cannot.
342 * In API V3 we propose to pass the exportname and tls mode as extra
343 * parameters to the (new) plugin.open and deprecate
344 * nbdkit_export_name and nbdkit_is_tls for V3 users. Even then we
345 * will still need to save the export name in the handle because of
346 * the lifetime issue.
348 if (c->conn) {
349 assert (c->conn->exportname == NULL);
350 c->conn->exportname = nbdkit_strdup_intern (exportname);
351 if (c->conn->exportname == NULL)
352 return NULL;
355 r = p->plugin.open (readonly);
356 if (r == NULL && c->conn)
357 c->conn->exportname = NULL;
358 return r;
361 /* We don't expose .prepare and .finalize to plugins since they aren't
362 * necessary. Plugins can easily do the same work in .open and
363 * .close.
365 static int
366 plugin_prepare (struct context *c, int readonly)
368 return 0;
371 static int
372 plugin_finalize (struct context *c)
374 return 0;
377 static void
378 plugin_close (struct context *c)
380 struct backend *b = c->b;
381 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
383 assert (c->handle);
384 if (p->plugin.close)
385 p->plugin.close (c->handle);
386 if (c->conn)
387 c->conn->exportname = NULL;
390 static const char *
391 plugin_export_description (struct context *c)
393 struct backend *b = c->b;
394 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
396 if (p->plugin.export_description)
397 return p->plugin.export_description (c->handle);
398 else
399 return NULL;
402 static int64_t
403 plugin_get_size (struct context *c)
405 struct backend *b = c->b;
406 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
408 assert (p->plugin.get_size != NULL);
410 return p->plugin.get_size (c->handle);
413 static int
414 plugin_block_size (struct context *c,
415 uint32_t *minimum, uint32_t *preferred, uint32_t *maximum)
417 struct backend *b = c->b;
418 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
420 if (p->plugin.block_size) {
421 if (p->plugin.block_size (c->handle, minimum, preferred, maximum) == -1)
422 return -1;
424 /* To make scripting easier, it's permitted to set
425 * minimum = preferred = maximum = 0 and return 0.
426 * That means "no information", and works the same
427 * way as the else clause below.
429 if (*minimum == 0 && *preferred == 0 && *maximum == 0)
430 return 0;
432 if (*minimum < 1 || *minimum > 65536) {
433 nbdkit_error ("plugin must set minimum block size between 1 and 64K");
434 return -1;
436 if (! is_power_of_2 (*minimum)) {
437 nbdkit_error ("plugin must set minimum block size to a power of 2");
438 return -1;
440 if (! is_power_of_2 (*preferred)) {
441 nbdkit_error ("plugin must set preferred block size to a power of 2");
442 return -1;
444 if (*preferred < 512 || *preferred > 32 * 1024 * 1024) {
445 nbdkit_error ("plugin must set preferred block size "
446 "between 512 and 32M");
447 return -1;
449 if (*maximum != (uint32_t)-1 && (*maximum % *minimum) != 0) {
450 nbdkit_error ("plugin must set maximum block size "
451 "to -1 or a multiple of minimum block size");
452 return -1;
454 if (*minimum > *preferred || *preferred > *maximum) {
455 nbdkit_error ("plugin must set minimum block size "
456 "<= preferred <= maximum");
457 return -1;
460 return 0;
462 else {
463 /* If there is no .block_size call then return minimum = preferred
464 * = maximum = 0, which is a sentinel meaning don't send the
465 * NBD_INFO_BLOCK_SIZE message.
467 *minimum = *preferred = *maximum = 0;
468 return 0;
472 static int
473 normalize_bool (int value)
475 if (value == -1 || value == 0)
476 return value;
477 /* Normalize all other non-zero values to true */
478 return 1;
481 static int
482 plugin_can_write (struct context *c)
484 struct backend *b = c->b;
485 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
487 if (p->plugin.can_write)
488 return normalize_bool (p->plugin.can_write (c->handle));
489 else
490 return p->plugin.pwrite || p->plugin._pwrite_v1;
493 static int
494 plugin_can_flush (struct context *c)
496 struct backend *b = c->b;
497 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
499 if (p->plugin.can_flush)
500 return normalize_bool (p->plugin.can_flush (c->handle));
501 else
502 return p->plugin.flush || p->plugin._flush_v1;
505 static int
506 plugin_is_rotational (struct context *c)
508 struct backend *b = c->b;
509 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
511 if (p->plugin.is_rotational)
512 return normalize_bool (p->plugin.is_rotational (c->handle));
513 else
514 return 0; /* assume false */
517 static int
518 plugin_can_trim (struct context *c)
520 struct backend *b = c->b;
521 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
523 if (p->plugin.can_trim)
524 return normalize_bool (p->plugin.can_trim (c->handle));
525 else
526 return p->plugin.trim || p->plugin._trim_v1;
529 static int
530 plugin_can_zero (struct context *c)
532 struct backend *b = c->b;
533 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
534 int r;
536 /* Note the special case here: the plugin's .can_zero returns a bool
537 * which controls only whether we call .zero; while the backend
538 * expects .can_zero to return a tri-state on level of support.
540 if (p->plugin.can_zero) {
541 r = p->plugin.can_zero (c->handle);
542 if (r == -1)
543 return -1;
544 return r ? NBDKIT_ZERO_NATIVE : NBDKIT_ZERO_EMULATE;
546 if (p->plugin.zero || p->plugin._zero_v1)
547 return NBDKIT_ZERO_NATIVE;
548 return NBDKIT_ZERO_EMULATE;
551 static int
552 plugin_can_fast_zero (struct context *c)
554 struct backend *b = c->b;
555 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
556 int r;
558 if (p->plugin.can_fast_zero)
559 return normalize_bool (p->plugin.can_fast_zero (c->handle));
560 /* Advertise support for fast zeroes if no .zero or .can_zero is
561 * false: in those cases, we fail fast instead of using .pwrite.
562 * This also works when v1 plugin has only ._zero_v1.
564 if (p->plugin.zero == NULL)
565 return 1;
566 r = backend_can_zero (c);
567 if (r == -1)
568 return -1;
569 return !r;
572 static int
573 plugin_can_extents (struct context *c)
575 struct backend *b = c->b;
576 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
578 if (p->plugin.can_extents)
579 return normalize_bool (p->plugin.can_extents (c->handle));
580 else
581 return p->plugin.extents != NULL;
584 static int
585 plugin_can_fua (struct context *c)
587 struct backend *b = c->b;
588 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
589 int r;
591 /* The plugin must use API version 2 and have .can_fua return
592 NBDKIT_FUA_NATIVE before we will pass the FUA flag on. */
593 if (p->plugin.can_fua) {
594 r = p->plugin.can_fua (c->handle);
595 if (r > NBDKIT_FUA_EMULATE && p->plugin._api_version == 1)
596 r = NBDKIT_FUA_EMULATE;
597 return r;
599 /* We intend to call .flush even if .can_flush returns false. */
600 if (p->plugin.flush || p->plugin._flush_v1)
601 return NBDKIT_FUA_EMULATE;
602 return NBDKIT_FUA_NONE;
605 static int
606 plugin_can_multi_conn (struct context *c)
608 struct backend *b = c->b;
609 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
611 if (p->plugin.can_multi_conn)
612 return normalize_bool (p->plugin.can_multi_conn (c->handle));
613 else
614 return 0; /* assume false */
617 static int
618 plugin_can_cache (struct context *c)
620 struct backend *b = c->b;
621 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
623 if (p->plugin.can_cache)
624 return p->plugin.can_cache (c->handle);
625 if (p->plugin.cache)
626 return NBDKIT_CACHE_NATIVE;
627 return NBDKIT_CACHE_NONE;
630 /* Plugins and filters can call this to set the true errno, in cases
631 * where !errno_is_preserved.
633 NBDKIT_DLL_PUBLIC void
634 nbdkit_set_error (int err)
636 threadlocal_set_error (err);
639 /* Grab the appropriate error value.
641 static int
642 get_error (struct backend_plugin *p)
644 int ret = threadlocal_get_error ();
646 if (!ret && p->plugin.errno_is_preserved != 0)
647 ret = errno;
648 return ret ? ret : EIO;
651 static int
652 plugin_pread (struct context *c,
653 void *buf, uint32_t count, uint64_t offset, uint32_t flags,
654 int *err)
656 struct backend *b = c->b;
657 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
658 int r;
660 assert (p->plugin.pread || p->plugin._pread_v1);
662 if (p->plugin.pread)
663 r = p->plugin.pread (c->handle, buf, count, offset, 0);
664 else
665 r = p->plugin._pread_v1 (c->handle, buf, count, offset);
666 if (r == -1)
667 *err = get_error (p);
668 return r;
671 static int
672 plugin_flush (struct context *c,
673 uint32_t flags, int *err)
675 struct backend *b = c->b;
676 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
677 int r;
679 if (p->plugin.flush)
680 r = p->plugin.flush (c->handle, 0);
681 else if (p->plugin._flush_v1)
682 r = p->plugin._flush_v1 (c->handle);
683 else {
684 *err = EINVAL;
685 return -1;
687 if (r == -1)
688 *err = get_error (p);
689 return r;
692 static int
693 plugin_pwrite (struct context *c,
694 const void *buf, uint32_t count, uint64_t offset, uint32_t flags,
695 int *err)
697 struct backend *b = c->b;
698 int r;
699 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
700 bool fua = flags & NBDKIT_FLAG_FUA;
701 bool need_flush = false;
703 if (fua && backend_can_fua (c) != NBDKIT_FUA_NATIVE) {
704 flags &= ~NBDKIT_FLAG_FUA;
705 need_flush = true;
707 if (p->plugin.pwrite)
708 r = p->plugin.pwrite (c->handle, buf, count, offset, flags);
709 else if (p->plugin._pwrite_v1)
710 r = p->plugin._pwrite_v1 (c->handle, buf, count, offset);
711 else {
712 *err = EROFS;
713 return -1;
715 if (r != -1 && need_flush)
716 r = plugin_flush (c, 0, err);
717 if (r == -1 && !*err)
718 *err = get_error (p);
719 return r;
722 static int
723 plugin_trim (struct context *c,
724 uint32_t count, uint64_t offset, uint32_t flags, int *err)
726 struct backend *b = c->b;
727 int r;
728 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
729 bool fua = flags & NBDKIT_FLAG_FUA;
730 bool need_flush = false;
732 if (fua && backend_can_fua (c) != NBDKIT_FUA_NATIVE) {
733 flags &= ~NBDKIT_FLAG_FUA;
734 need_flush = true;
736 if (p->plugin.trim)
737 r = p->plugin.trim (c->handle, count, offset, flags);
738 else if (p->plugin._trim_v1)
739 r = p->plugin._trim_v1 (c->handle, count, offset);
740 else {
741 *err = EINVAL;
742 return -1;
744 if (r != -1 && need_flush)
745 r = plugin_flush (c, 0, err);
746 if (r == -1 && !*err)
747 *err = get_error (p);
748 return r;
751 static int
752 plugin_zero (struct context *c,
753 uint32_t count, uint64_t offset, uint32_t flags, int *err)
755 struct backend *b = c->b;
756 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
757 int r = -1;
758 bool may_trim = flags & NBDKIT_FLAG_MAY_TRIM;
759 bool fua = flags & NBDKIT_FLAG_FUA;
760 bool fast_zero = flags & NBDKIT_FLAG_FAST_ZERO;
761 bool emulate = false;
762 bool need_flush = false;
764 if (fua && backend_can_fua (c) != NBDKIT_FUA_NATIVE) {
765 flags &= ~NBDKIT_FLAG_FUA;
766 need_flush = true;
768 if (!count)
769 return 0;
771 if (backend_can_zero (c) == NBDKIT_ZERO_NATIVE) {
772 errno = 0;
773 if (p->plugin.zero)
774 r = p->plugin.zero (c->handle, count, offset, flags);
775 else if (p->plugin._zero_v1) {
776 if (fast_zero) {
777 *err = EOPNOTSUPP;
778 return -1;
780 r = p->plugin._zero_v1 (c->handle, count, offset, may_trim);
782 else
783 emulate = true;
784 if (r == -1)
785 *err = emulate ? EOPNOTSUPP : get_error (p);
786 if (r == 0 || (*err != EOPNOTSUPP && *err != ENOTSUP))
787 goto done;
790 if (fast_zero) {
791 assert (r == -1);
792 *err = EOPNOTSUPP;
793 goto done;
796 flags &= ~NBDKIT_FLAG_MAY_TRIM;
797 threadlocal_set_error (0);
798 *err = 0;
800 while (count) {
801 /* Always contains zeroes, but we can't use const or else gcc 9
802 * will use .rodata instead of .bss and inflate the binary size.
804 static /* const */ char buf[MAX_REQUEST_SIZE];
805 uint32_t limit = MIN (count, sizeof buf);
807 r = plugin_pwrite (c, buf, limit, offset, flags, err);
808 if (r == -1)
809 break;
810 count -= limit;
813 done:
814 if (r != -1 && need_flush)
815 r = plugin_flush (c, 0, err);
816 if (r == -1 && !*err)
817 *err = get_error (p);
818 return r;
821 static int
822 plugin_extents (struct context *c,
823 uint32_t count, uint64_t offset, uint32_t flags,
824 struct nbdkit_extents *extents, int *err)
826 struct backend *b = c->b;
827 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
828 int r;
830 if (p->plugin.extents == NULL) { /* Possible if .can_extents lied */
831 *err = EINVAL;
832 return -1;
835 r = p->plugin.extents (c->handle, count, offset, flags, extents);
836 if (r >= 0 && nbdkit_extents_count (extents) < 1) {
837 nbdkit_error ("extents: plugin must return at least one extent");
838 nbdkit_set_error (EINVAL);
839 r = -1;
841 if (r == -1)
842 *err = get_error (p);
843 return r;
846 static int
847 plugin_cache (struct context *c,
848 uint32_t count, uint64_t offset, uint32_t flags,
849 int *err)
851 struct backend *b = c->b;
852 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
853 int r;
855 /* A plugin may advertise caching but not provide .cache; in that
856 * case, caching is explicitly a no-op. */
857 if (!p->plugin.cache)
858 return 0;
860 r = p->plugin.cache (c->handle, count, offset, flags);
861 if (r == -1)
862 *err = get_error (p);
863 return r;
866 static struct backend plugin_functions = {
867 .free = plugin_free,
868 .thread_model = plugin_thread_model,
869 .plugin_name = plugin_name,
870 .usage = plugin_usage,
871 .version = plugin_version,
872 .dump_fields = plugin_dump_fields,
873 .config = plugin_config,
874 .config_complete = plugin_config_complete,
875 .magic_config_key = plugin_magic_config_key,
876 .get_ready = plugin_get_ready,
877 .after_fork = plugin_after_fork,
878 .cleanup = plugin_cleanup,
879 .preconnect = plugin_preconnect,
880 .list_exports = plugin_list_exports,
881 .default_export = plugin_default_export,
882 .open = plugin_open,
883 .prepare = plugin_prepare,
884 .finalize = plugin_finalize,
885 .close = plugin_close,
886 .export_description = plugin_export_description,
887 .get_size = plugin_get_size,
888 .block_size = plugin_block_size,
889 .can_write = plugin_can_write,
890 .can_flush = plugin_can_flush,
891 .is_rotational = plugin_is_rotational,
892 .can_trim = plugin_can_trim,
893 .can_zero = plugin_can_zero,
894 .can_fast_zero = plugin_can_fast_zero,
895 .can_extents = plugin_can_extents,
896 .can_fua = plugin_can_fua,
897 .can_multi_conn = plugin_can_multi_conn,
898 .can_cache = plugin_can_cache,
899 .pread = plugin_pread,
900 .pwrite = plugin_pwrite,
901 .flush = plugin_flush,
902 .trim = plugin_trim,
903 .zero = plugin_zero,
904 .extents = plugin_extents,
905 .cache = plugin_cache,
908 /* Register and load a plugin. */
909 struct backend *
910 plugin_register (size_t index, const char *filename,
911 void *dl, struct nbdkit_plugin *(*plugin_init) (void))
913 struct backend_plugin *p;
914 const struct nbdkit_plugin *plugin;
915 size_t size;
917 p = malloc (sizeof *p);
918 if (p == NULL) {
919 perror ("strdup");
920 exit (EXIT_FAILURE);
923 p->backend = plugin_functions;
924 backend_init (&p->backend, NULL, index, filename, dl, "plugin");
926 /* Call the initialization function which returns the address of the
927 * plugin's own 'struct nbdkit_plugin'.
929 plugin = plugin_init ();
930 if (!plugin) {
931 fprintf (stderr, "%s: %s: plugin registration function failed\n",
932 program_name, filename);
933 exit (EXIT_FAILURE);
936 /* Check for incompatible future versions. */
937 if (plugin->_api_version < 0 || plugin->_api_version > 2) {
938 fprintf (stderr,
939 "%s: %s: plugin is incompatible with this version of nbdkit "
940 "(_api_version = %d)\n",
941 program_name, filename, plugin->_api_version);
942 exit (EXIT_FAILURE);
945 /* Since the plugin might be much older than the current version of
946 * nbdkit, only copy up to the self-declared _struct_size of the
947 * plugin and zero out the rest. If the plugin is much newer then
948 * we'll only call the "old" fields.
950 size = sizeof p->plugin; /* our struct */
951 memset (&p->plugin, 0, size);
952 if (size > plugin->_struct_size)
953 size = plugin->_struct_size;
954 memcpy (&p->plugin, plugin, size);
956 /* Check for the minimum fields which must exist in the
957 * plugin struct.
959 if (p->plugin.open == NULL) {
960 fprintf (stderr, "%s: %s: plugin must have a .open callback\n",
961 program_name, filename);
962 exit (EXIT_FAILURE);
964 if (p->plugin.get_size == NULL) {
965 fprintf (stderr, "%s: %s: plugin must have a .get_size callback\n",
966 program_name, filename);
967 exit (EXIT_FAILURE);
969 if (p->plugin.pread == NULL && p->plugin._pread_v1 == NULL) {
970 fprintf (stderr, "%s: %s: plugin must have a .pread callback\n",
971 program_name, filename);
972 exit (EXIT_FAILURE);
975 backend_load (&p->backend, p->plugin.name, p->plugin.load);
977 return (struct backend *) p;