2 * Copyright (C) 2013-2019 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
42 #include <sys/socket.h>
47 /* We extend the generic backend struct with extra fields relating
50 struct backend_plugin
{
51 struct backend backend
;
52 struct nbdkit_plugin plugin
;
56 plugin_free (struct backend
*b
)
58 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
60 backend_unload (b
, p
->plugin
.unload
);
65 plugin_thread_model (struct backend
*b
)
67 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
68 int thread_model
= p
->plugin
._thread_model
;
71 #if !(defined SOCK_CLOEXEC && defined HAVE_MKOSTEMP && defined HAVE_PIPE2 && \
73 if (thread_model
> NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS
) {
74 nbdkit_debug ("system lacks atomic CLOEXEC, serializing to avoid fd leaks");
75 thread_model
= NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS
;
79 if (p
->plugin
.thread_model
) {
80 r
= p
->plugin
.thread_model ();
91 plugin_name (struct backend
*b
)
97 plugin_usage (struct backend
*b
)
99 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
102 printf ("plugin: %s", b
->name
);
103 if (p
->plugin
.longname
)
104 printf (" (%s)", p
->plugin
.longname
);
106 printf ("(%s)\n", b
->filename
);
107 if (p
->plugin
.description
) {
108 printf ("%s", p
->plugin
.description
);
109 if ((t
= strrchr (p
->plugin
.description
, '\n')) == NULL
|| t
[1])
112 if (p
->plugin
.config_help
) {
113 printf ("%s", p
->plugin
.config_help
);
114 if ((t
= strrchr (p
->plugin
.config_help
, '\n')) == NULL
|| t
[1])
120 plugin_version (struct backend
*b
)
122 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
124 return p
->plugin
.version
;
127 /* This implements the --dump-plugin option. */
129 plugin_dump_fields (struct backend
*b
)
131 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
134 path
= nbdkit_realpath (b
->filename
);
135 printf ("path=%s\n", path
);
138 printf ("name=%s\n", b
->name
);
139 if (p
->plugin
.version
)
140 printf ("version=%s\n", p
->plugin
.version
);
142 printf ("api_version=%d\n", p
->plugin
._api_version
);
143 printf ("struct_size=%" PRIu64
"\n", p
->plugin
._struct_size
);
144 printf ("max_thread_model=%s\n",
145 name_of_thread_model (p
->plugin
._thread_model
));
146 printf ("thread_model=%s\n",
147 name_of_thread_model (backend
->thread_model (backend
)));
148 printf ("errno_is_preserved=%d\n", !!p
->plugin
.errno_is_preserved
);
149 if (p
->plugin
.magic_config_key
)
150 printf ("magic_config_key=%s\n", p
->plugin
.magic_config_key
);
152 #define HAS(field) if (p->plugin.field) printf ("has_%s=1\n", #field)
159 HAS (config_complete
);
180 HAS (can_multi_conn
);
190 if (p
->plugin
.dump_plugin
)
191 p
->plugin
.dump_plugin ();
195 plugin_config (struct backend
*b
, const char *key
, const char *value
)
197 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
199 debug ("%s: config key=%s, value=%s", b
->name
, key
, value
);
201 if (p
->plugin
.config
== NULL
) {
203 "%s: %s: this plugin does not need command line configuration\n"
204 "Try using: %s --help %s\n",
205 program_name
, b
->filename
,
206 program_name
, b
->filename
);
210 if (p
->plugin
.config (key
, value
) == -1)
215 plugin_config_complete (struct backend
*b
)
217 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
219 debug ("%s: config_complete", b
->name
);
221 if (!p
->plugin
.config_complete
)
224 if (p
->plugin
.config_complete () == -1)
229 plugin_magic_config_key (struct backend
*b
)
231 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
233 return p
->plugin
.magic_config_key
;
237 plugin_open (struct backend
*b
, struct connection
*conn
, int readonly
)
239 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
242 assert (connection_get_handle (conn
, 0) == NULL
);
243 assert (p
->plugin
.open
!= NULL
);
245 handle
= p
->plugin
.open (readonly
);
249 backend_set_handle (b
, conn
, handle
);
253 /* We don't expose .prepare and .finalize to plugins since they aren't
254 * necessary. Plugins can easily do the same work in .open and
258 plugin_prepare (struct backend
*b
, struct connection
*conn
, int readonly
)
264 plugin_finalize (struct backend
*b
, struct connection
*conn
)
270 plugin_close (struct backend
*b
, struct connection
*conn
)
272 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
274 assert (connection_get_handle (conn
, 0));
277 p
->plugin
.close (connection_get_handle (conn
, 0));
281 plugin_get_size (struct backend
*b
, struct connection
*conn
)
283 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
285 assert (connection_get_handle (conn
, 0));
286 assert (p
->plugin
.get_size
!= NULL
);
288 return p
->plugin
.get_size (connection_get_handle (conn
, 0));
292 plugin_can_write (struct backend
*b
, struct connection
*conn
)
294 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
296 assert (connection_get_handle (conn
, 0));
298 if (p
->plugin
.can_write
)
299 return p
->plugin
.can_write (connection_get_handle (conn
, 0));
301 return p
->plugin
.pwrite
|| p
->plugin
._pwrite_old
;
305 plugin_can_flush (struct backend
*b
, struct connection
*conn
)
307 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
309 assert (connection_get_handle (conn
, 0));
311 if (p
->plugin
.can_flush
)
312 return p
->plugin
.can_flush (connection_get_handle (conn
, 0));
314 return p
->plugin
.flush
|| p
->plugin
._flush_old
;
318 plugin_is_rotational (struct backend
*b
, struct connection
*conn
)
320 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
322 assert (connection_get_handle (conn
, 0));
324 if (p
->plugin
.is_rotational
)
325 return p
->plugin
.is_rotational (connection_get_handle (conn
, 0));
327 return 0; /* assume false */
331 plugin_can_trim (struct backend
*b
, struct connection
*conn
)
333 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
335 assert (connection_get_handle (conn
, 0));
337 if (p
->plugin
.can_trim
)
338 return p
->plugin
.can_trim (connection_get_handle (conn
, 0));
340 return p
->plugin
.trim
|| p
->plugin
._trim_old
;
344 plugin_can_zero (struct backend
*b
, struct connection
*conn
)
346 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
349 assert (connection_get_handle (conn
, 0));
351 /* Note the special case here: the plugin's .can_zero returns a bool
352 * which controls only whether we call .zero; while the backend
353 * expects .can_zero to return a tri-state on level of support.
355 if (p
->plugin
.can_zero
) {
356 r
= p
->plugin
.can_zero (connection_get_handle (conn
, 0));
359 return r
? NBDKIT_ZERO_NATIVE
: NBDKIT_ZERO_EMULATE
;
361 if (p
->plugin
.zero
|| p
->plugin
._zero_old
)
362 return NBDKIT_ZERO_NATIVE
;
363 return NBDKIT_ZERO_EMULATE
;
367 plugin_can_fast_zero (struct backend
*b
, struct connection
*conn
)
369 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
372 assert (connection_get_handle (conn
, 0));
374 if (p
->plugin
.can_fast_zero
)
375 return p
->plugin
.can_fast_zero (connection_get_handle (conn
, 0));
376 /* Advertise support for fast zeroes if no .zero or .can_zero is
377 * false: in those cases, we fail fast instead of using .pwrite.
378 * This also works when v1 plugin has only ._zero_old.
380 if (p
->plugin
.zero
== NULL
)
382 r
= backend_can_zero (b
, conn
);
389 plugin_can_extents (struct backend
*b
, struct connection
*conn
)
391 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
393 assert (connection_get_handle (conn
, 0));
395 if (p
->plugin
.can_extents
)
396 return p
->plugin
.can_extents (connection_get_handle (conn
, 0));
398 return p
->plugin
.extents
!= NULL
;
402 plugin_can_fua (struct backend
*b
, struct connection
*conn
)
404 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
407 assert (connection_get_handle (conn
, 0));
409 /* The plugin must use API version 2 and have .can_fua return
410 NBDKIT_FUA_NATIVE before we will pass the FUA flag on. */
411 if (p
->plugin
.can_fua
) {
412 r
= p
->plugin
.can_fua (connection_get_handle (conn
, 0));
413 if (r
> NBDKIT_FUA_EMULATE
&& p
->plugin
._api_version
== 1)
414 r
= NBDKIT_FUA_EMULATE
;
417 /* We intend to call .flush even if .can_flush returns false. */
418 if (p
->plugin
.flush
|| p
->plugin
._flush_old
)
419 return NBDKIT_FUA_EMULATE
;
420 return NBDKIT_FUA_NONE
;
424 plugin_can_multi_conn (struct backend
*b
, struct connection
*conn
)
426 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
428 assert (connection_get_handle (conn
, 0));
430 if (p
->plugin
.can_multi_conn
)
431 return p
->plugin
.can_multi_conn (connection_get_handle (conn
, 0));
433 return 0; /* assume false */
437 plugin_can_cache (struct backend
*b
, struct connection
*conn
)
439 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
441 assert (connection_get_handle (conn
, 0));
443 if (p
->plugin
.can_cache
)
444 return p
->plugin
.can_cache (connection_get_handle (conn
, 0));
446 return NBDKIT_CACHE_NATIVE
;
447 return NBDKIT_CACHE_NONE
;
450 /* Plugins and filters can call this to set the true errno, in cases
451 * where !errno_is_preserved.
454 nbdkit_set_error (int err
)
456 threadlocal_set_error (err
);
459 /* Grab the appropriate error value.
462 get_error (struct backend_plugin
*p
)
464 int ret
= threadlocal_get_error ();
466 if (!ret
&& p
->plugin
.errno_is_preserved
!= 0)
468 return ret
? ret
: EIO
;
472 plugin_pread (struct backend
*b
, struct connection
*conn
,
473 void *buf
, uint32_t count
, uint64_t offset
, uint32_t flags
,
476 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
479 assert (connection_get_handle (conn
, 0));
480 assert (p
->plugin
.pread
|| p
->plugin
._pread_old
);
483 r
= p
->plugin
.pread (connection_get_handle (conn
, 0), buf
, count
, offset
,
486 r
= p
->plugin
._pread_old (connection_get_handle (conn
, 0), buf
, count
,
489 *err
= get_error (p
);
494 plugin_flush (struct backend
*b
, struct connection
*conn
, uint32_t flags
,
497 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
500 assert (connection_get_handle (conn
, 0));
503 r
= p
->plugin
.flush (connection_get_handle (conn
, 0), 0);
504 else if (p
->plugin
._flush_old
)
505 r
= p
->plugin
._flush_old (connection_get_handle (conn
, 0));
511 *err
= get_error (p
);
516 plugin_pwrite (struct backend
*b
, struct connection
*conn
,
517 const void *buf
, uint32_t count
, uint64_t offset
, uint32_t flags
,
521 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
522 bool fua
= flags
& NBDKIT_FLAG_FUA
;
523 bool need_flush
= false;
525 assert (connection_get_handle (conn
, 0));
527 if (fua
&& backend_can_fua (b
, conn
) != NBDKIT_FUA_NATIVE
) {
528 flags
&= ~NBDKIT_FLAG_FUA
;
531 if (p
->plugin
.pwrite
)
532 r
= p
->plugin
.pwrite (connection_get_handle (conn
, 0), buf
, count
, offset
,
534 else if (p
->plugin
._pwrite_old
)
535 r
= p
->plugin
._pwrite_old (connection_get_handle (conn
, 0),
541 if (r
!= -1 && need_flush
)
542 r
= plugin_flush (b
, conn
, 0, err
);
543 if (r
== -1 && !*err
)
544 *err
= get_error (p
);
549 plugin_trim (struct backend
*b
, struct connection
*conn
,
550 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
553 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
554 bool fua
= flags
& NBDKIT_FLAG_FUA
;
555 bool need_flush
= false;
557 assert (connection_get_handle (conn
, 0));
559 if (fua
&& backend_can_fua (b
, conn
) != NBDKIT_FUA_NATIVE
) {
560 flags
&= ~NBDKIT_FLAG_FUA
;
564 r
= p
->plugin
.trim (connection_get_handle (conn
, 0), count
, offset
, flags
);
565 else if (p
->plugin
._trim_old
)
566 r
= p
->plugin
._trim_old (connection_get_handle (conn
, 0), count
, offset
);
571 if (r
!= -1 && need_flush
)
572 r
= plugin_flush (b
, conn
, 0, err
);
573 if (r
== -1 && !*err
)
574 *err
= get_error (p
);
579 plugin_zero (struct backend
*b
, struct connection
*conn
,
580 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
582 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
584 bool may_trim
= flags
& NBDKIT_FLAG_MAY_TRIM
;
585 bool fua
= flags
& NBDKIT_FLAG_FUA
;
586 bool fast_zero
= flags
& NBDKIT_FLAG_FAST_ZERO
;
587 bool emulate
= false;
588 bool need_flush
= false;
590 assert (connection_get_handle (conn
, 0));
592 if (fua
&& backend_can_fua (b
, conn
) != NBDKIT_FUA_NATIVE
) {
593 flags
&= ~NBDKIT_FLAG_FUA
;
599 if (backend_can_zero (b
, conn
) == NBDKIT_ZERO_NATIVE
) {
602 r
= p
->plugin
.zero (connection_get_handle (conn
, 0), count
, offset
,
604 else if (p
->plugin
._zero_old
) {
609 r
= p
->plugin
._zero_old (connection_get_handle (conn
, 0), count
, offset
,
615 *err
= emulate
? EOPNOTSUPP
: get_error (p
);
616 if (r
== 0 || (*err
!= EOPNOTSUPP
&& *err
!= ENOTSUP
))
626 assert (p
->plugin
.pwrite
|| p
->plugin
._pwrite_old
);
627 flags
&= ~NBDKIT_FLAG_MAY_TRIM
;
628 threadlocal_set_error (0);
632 /* Always contains zeroes, but we can't use const or else gcc 9
633 * will use .rodata instead of .bss and inflate the binary size.
635 static /* const */ char buf
[MAX_REQUEST_SIZE
];
636 uint32_t limit
= MIN (count
, sizeof buf
);
638 r
= plugin_pwrite (b
, conn
, buf
, limit
, offset
, flags
, err
);
645 if (r
!= -1 && need_flush
)
646 r
= plugin_flush (b
, conn
, 0, err
);
647 if (r
== -1 && !*err
)
648 *err
= get_error (p
);
653 plugin_extents (struct backend
*b
, struct connection
*conn
,
654 uint32_t count
, uint64_t offset
, uint32_t flags
,
655 struct nbdkit_extents
*extents
, int *err
)
657 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
660 assert (connection_get_handle (conn
, 0));
662 /* This should be true because plugin_can_extents checks it. */
663 assert (p
->plugin
.extents
);
665 r
= p
->plugin
.extents (connection_get_handle (conn
, 0), count
, offset
,
667 if (r
>= 0 && nbdkit_extents_count (extents
) < 1) {
668 nbdkit_error ("extents: plugin must return at least one extent");
669 nbdkit_set_error (EINVAL
);
673 *err
= get_error (p
);
678 plugin_cache (struct backend
*b
, struct connection
*conn
,
679 uint32_t count
, uint64_t offset
, uint32_t flags
,
682 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
685 assert (connection_get_handle (conn
, 0));
687 /* A plugin may advertise caching but not provide .cache; in that
688 * case, caching is explicitly a no-op. */
689 if (!p
->plugin
.cache
)
692 r
= p
->plugin
.cache (connection_get_handle (conn
, 0), count
, offset
, flags
);
694 *err
= get_error (p
);
698 static struct backend plugin_functions
= {
700 .thread_model
= plugin_thread_model
,
701 .plugin_name
= plugin_name
,
702 .usage
= plugin_usage
,
703 .version
= plugin_version
,
704 .dump_fields
= plugin_dump_fields
,
705 .config
= plugin_config
,
706 .config_complete
= plugin_config_complete
,
707 .magic_config_key
= plugin_magic_config_key
,
709 .prepare
= plugin_prepare
,
710 .finalize
= plugin_finalize
,
711 .close
= plugin_close
,
712 .get_size
= plugin_get_size
,
713 .can_write
= plugin_can_write
,
714 .can_flush
= plugin_can_flush
,
715 .is_rotational
= plugin_is_rotational
,
716 .can_trim
= plugin_can_trim
,
717 .can_zero
= plugin_can_zero
,
718 .can_fast_zero
= plugin_can_fast_zero
,
719 .can_extents
= plugin_can_extents
,
720 .can_fua
= plugin_can_fua
,
721 .can_multi_conn
= plugin_can_multi_conn
,
722 .can_cache
= plugin_can_cache
,
723 .pread
= plugin_pread
,
724 .pwrite
= plugin_pwrite
,
725 .flush
= plugin_flush
,
728 .extents
= plugin_extents
,
729 .cache
= plugin_cache
,
732 /* Register and load a plugin. */
734 plugin_register (size_t index
, const char *filename
,
735 void *dl
, struct nbdkit_plugin
*(*plugin_init
) (void))
737 struct backend_plugin
*p
;
738 const struct nbdkit_plugin
*plugin
;
741 p
= malloc (sizeof *p
);
747 p
->backend
= plugin_functions
;
748 backend_init (&p
->backend
, NULL
, index
, filename
, dl
, "plugin");
750 /* Call the initialization function which returns the address of the
751 * plugin's own 'struct nbdkit_plugin'.
753 plugin
= plugin_init ();
755 fprintf (stderr
, "%s: %s: plugin registration function failed\n",
756 program_name
, filename
);
760 /* Check for incompatible future versions. */
761 if (plugin
->_api_version
< 0 || plugin
->_api_version
> 2) {
763 "%s: %s: plugin is incompatible with this version of nbdkit "
764 "(_api_version = %d)\n",
765 program_name
, filename
, plugin
->_api_version
);
769 /* Since the plugin might be much older than the current version of
770 * nbdkit, only copy up to the self-declared _struct_size of the
771 * plugin and zero out the rest. If the plugin is much newer then
772 * we'll only call the "old" fields.
774 size
= sizeof p
->plugin
; /* our struct */
775 memset (&p
->plugin
, 0, size
);
776 if (size
> plugin
->_struct_size
)
777 size
= plugin
->_struct_size
;
778 memcpy (&p
->plugin
, plugin
, size
);
780 /* Check for the minimum fields which must exist in the
783 if (p
->plugin
.open
== NULL
) {
784 fprintf (stderr
, "%s: %s: plugin must have a .open callback\n",
785 program_name
, filename
);
788 if (p
->plugin
.get_size
== NULL
) {
789 fprintf (stderr
, "%s: %s: plugin must have a .get_size callback\n",
790 program_name
, filename
);
793 if (p
->plugin
.pread
== NULL
&& p
->plugin
._pread_old
== NULL
) {
794 fprintf (stderr
, "%s: %s: plugin must have a .pread callback\n",
795 program_name
, filename
);
799 backend_load (&p
->backend
, p
->plugin
.name
, p
->plugin
.load
);
801 return (struct backend
*) p
;