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 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
);
181 HAS (can_multi_conn
);
191 if (p
->plugin
.dump_plugin
)
192 p
->plugin
.dump_plugin ();
196 plugin_config (struct backend
*b
, const char *key
, const char *value
)
198 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
200 debug ("%s: config key=%s, value=%s", b
->name
, key
, value
);
202 if (p
->plugin
.config
== NULL
) {
204 "%s: %s: this plugin does not need command line configuration\n"
205 "Try using: %s --help %s\n",
206 program_name
, b
->filename
,
207 program_name
, b
->filename
);
211 if (p
->plugin
.config (key
, value
) == -1)
216 plugin_config_complete (struct backend
*b
)
218 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
220 debug ("%s: config_complete", b
->name
);
222 if (!p
->plugin
.config_complete
)
225 if (p
->plugin
.config_complete () == -1)
230 plugin_magic_config_key (struct backend
*b
)
232 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
234 return p
->plugin
.magic_config_key
;
238 plugin_preconnect (struct backend
*b
, struct connection
*conn
, int readonly
)
240 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
242 debug ("%s: preconnect", b
->name
);
244 if (!p
->plugin
.preconnect
)
247 return p
->plugin
.preconnect (readonly
);
251 plugin_open (struct backend
*b
, struct connection
*conn
, int readonly
)
253 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
255 assert (p
->plugin
.open
!= NULL
);
257 return p
->plugin
.open (readonly
);
260 /* We don't expose .prepare and .finalize to plugins since they aren't
261 * necessary. Plugins can easily do the same work in .open and
265 plugin_prepare (struct backend
*b
, struct connection
*conn
, void *handle
,
272 plugin_finalize (struct backend
*b
, struct connection
*conn
, void *handle
)
278 plugin_close (struct backend
*b
, struct connection
*conn
, void *handle
)
280 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
282 if (handle
&& p
->plugin
.close
)
283 p
->plugin
.close (handle
);
287 plugin_get_size (struct backend
*b
, struct connection
*conn
, void *handle
)
289 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
291 assert (p
->plugin
.get_size
!= NULL
);
293 return p
->plugin
.get_size (handle
);
297 plugin_can_write (struct backend
*b
, struct connection
*conn
, void *handle
)
299 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
301 if (p
->plugin
.can_write
)
302 return p
->plugin
.can_write (handle
);
304 return p
->plugin
.pwrite
|| p
->plugin
._pwrite_v1
;
308 plugin_can_flush (struct backend
*b
, struct connection
*conn
, void *handle
)
310 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
312 if (p
->plugin
.can_flush
)
313 return p
->plugin
.can_flush (handle
);
315 return p
->plugin
.flush
|| p
->plugin
._flush_v1
;
319 plugin_is_rotational (struct backend
*b
, struct connection
*conn
, void *handle
)
321 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
323 if (p
->plugin
.is_rotational
)
324 return p
->plugin
.is_rotational (handle
);
326 return 0; /* assume false */
330 plugin_can_trim (struct backend
*b
, struct connection
*conn
, void *handle
)
332 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
334 if (p
->plugin
.can_trim
)
335 return p
->plugin
.can_trim (handle
);
337 return p
->plugin
.trim
|| p
->plugin
._trim_v1
;
341 plugin_can_zero (struct backend
*b
, struct connection
*conn
, void *handle
)
343 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
346 /* Note the special case here: the plugin's .can_zero returns a bool
347 * which controls only whether we call .zero; while the backend
348 * expects .can_zero to return a tri-state on level of support.
350 if (p
->plugin
.can_zero
) {
351 r
= p
->plugin
.can_zero (handle
);
354 return r
? NBDKIT_ZERO_NATIVE
: NBDKIT_ZERO_EMULATE
;
356 if (p
->plugin
.zero
|| p
->plugin
._zero_v1
)
357 return NBDKIT_ZERO_NATIVE
;
358 return NBDKIT_ZERO_EMULATE
;
362 plugin_can_fast_zero (struct backend
*b
, struct connection
*conn
, void *handle
)
364 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
367 if (p
->plugin
.can_fast_zero
)
368 return p
->plugin
.can_fast_zero (handle
);
369 /* Advertise support for fast zeroes if no .zero or .can_zero is
370 * false: in those cases, we fail fast instead of using .pwrite.
371 * This also works when v1 plugin has only ._zero_v1.
373 if (p
->plugin
.zero
== NULL
)
375 r
= backend_can_zero (b
, conn
);
382 plugin_can_extents (struct backend
*b
, struct connection
*conn
, void *handle
)
384 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
386 if (p
->plugin
.can_extents
)
387 return p
->plugin
.can_extents (handle
);
389 return p
->plugin
.extents
!= NULL
;
393 plugin_can_fua (struct backend
*b
, struct connection
*conn
, void *handle
)
395 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
398 /* The plugin must use API version 2 and have .can_fua return
399 NBDKIT_FUA_NATIVE before we will pass the FUA flag on. */
400 if (p
->plugin
.can_fua
) {
401 r
= p
->plugin
.can_fua (handle
);
402 if (r
> NBDKIT_FUA_EMULATE
&& p
->plugin
._api_version
== 1)
403 r
= NBDKIT_FUA_EMULATE
;
406 /* We intend to call .flush even if .can_flush returns false. */
407 if (p
->plugin
.flush
|| p
->plugin
._flush_v1
)
408 return NBDKIT_FUA_EMULATE
;
409 return NBDKIT_FUA_NONE
;
413 plugin_can_multi_conn (struct backend
*b
, struct connection
*conn
, void *handle
)
415 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
417 if (p
->plugin
.can_multi_conn
)
418 return p
->plugin
.can_multi_conn (handle
);
420 return 0; /* assume false */
424 plugin_can_cache (struct backend
*b
, struct connection
*conn
, void *handle
)
426 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
428 if (p
->plugin
.can_cache
)
429 return p
->plugin
.can_cache (handle
);
431 return NBDKIT_CACHE_NATIVE
;
432 return NBDKIT_CACHE_NONE
;
435 /* Plugins and filters can call this to set the true errno, in cases
436 * where !errno_is_preserved.
439 nbdkit_set_error (int err
)
441 threadlocal_set_error (err
);
444 /* Grab the appropriate error value.
447 get_error (struct backend_plugin
*p
)
449 int ret
= threadlocal_get_error ();
451 if (!ret
&& p
->plugin
.errno_is_preserved
!= 0)
453 return ret
? ret
: EIO
;
457 plugin_pread (struct backend
*b
, struct connection
*conn
, void *handle
,
458 void *buf
, uint32_t count
, uint64_t offset
, uint32_t flags
,
461 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
464 assert (p
->plugin
.pread
|| p
->plugin
._pread_v1
);
467 r
= p
->plugin
.pread (handle
, buf
, count
, offset
, 0);
469 r
= p
->plugin
._pread_v1 (handle
, buf
, count
, offset
);
471 *err
= get_error (p
);
476 plugin_flush (struct backend
*b
, struct connection
*conn
, void *handle
,
477 uint32_t flags
, int *err
)
479 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
483 r
= p
->plugin
.flush (handle
, 0);
484 else if (p
->plugin
._flush_v1
)
485 r
= p
->plugin
._flush_v1 (handle
);
491 *err
= get_error (p
);
496 plugin_pwrite (struct backend
*b
, struct connection
*conn
, void *handle
,
497 const void *buf
, uint32_t count
, uint64_t offset
, uint32_t flags
,
501 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
502 bool fua
= flags
& NBDKIT_FLAG_FUA
;
503 bool need_flush
= false;
505 if (fua
&& backend_can_fua (b
, conn
) != NBDKIT_FUA_NATIVE
) {
506 flags
&= ~NBDKIT_FLAG_FUA
;
509 if (p
->plugin
.pwrite
)
510 r
= p
->plugin
.pwrite (handle
, buf
, count
, offset
, flags
);
511 else if (p
->plugin
._pwrite_v1
)
512 r
= p
->plugin
._pwrite_v1 (handle
, buf
, count
, offset
);
517 if (r
!= -1 && need_flush
)
518 r
= plugin_flush (b
, conn
, handle
, 0, err
);
519 if (r
== -1 && !*err
)
520 *err
= get_error (p
);
525 plugin_trim (struct backend
*b
, struct connection
*conn
, void *handle
,
526 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
529 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
530 bool fua
= flags
& NBDKIT_FLAG_FUA
;
531 bool need_flush
= false;
533 if (fua
&& backend_can_fua (b
, conn
) != NBDKIT_FUA_NATIVE
) {
534 flags
&= ~NBDKIT_FLAG_FUA
;
538 r
= p
->plugin
.trim (handle
, count
, offset
, flags
);
539 else if (p
->plugin
._trim_v1
)
540 r
= p
->plugin
._trim_v1 (handle
, count
, offset
);
545 if (r
!= -1 && need_flush
)
546 r
= plugin_flush (b
, conn
, handle
, 0, err
);
547 if (r
== -1 && !*err
)
548 *err
= get_error (p
);
553 plugin_zero (struct backend
*b
, struct connection
*conn
, void *handle
,
554 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
556 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
558 bool may_trim
= flags
& NBDKIT_FLAG_MAY_TRIM
;
559 bool fua
= flags
& NBDKIT_FLAG_FUA
;
560 bool fast_zero
= flags
& NBDKIT_FLAG_FAST_ZERO
;
561 bool emulate
= false;
562 bool need_flush
= false;
564 if (fua
&& backend_can_fua (b
, conn
) != NBDKIT_FUA_NATIVE
) {
565 flags
&= ~NBDKIT_FLAG_FUA
;
571 if (backend_can_zero (b
, conn
) == NBDKIT_ZERO_NATIVE
) {
574 r
= p
->plugin
.zero (handle
, count
, offset
, flags
);
575 else if (p
->plugin
._zero_v1
) {
580 r
= p
->plugin
._zero_v1 (handle
, count
, offset
, may_trim
);
585 *err
= emulate
? EOPNOTSUPP
: get_error (p
);
586 if (r
== 0 || (*err
!= EOPNOTSUPP
&& *err
!= ENOTSUP
))
596 assert (p
->plugin
.pwrite
|| p
->plugin
._pwrite_v1
);
597 flags
&= ~NBDKIT_FLAG_MAY_TRIM
;
598 threadlocal_set_error (0);
602 /* Always contains zeroes, but we can't use const or else gcc 9
603 * will use .rodata instead of .bss and inflate the binary size.
605 static /* const */ char buf
[MAX_REQUEST_SIZE
];
606 uint32_t limit
= MIN (count
, sizeof buf
);
608 r
= plugin_pwrite (b
, conn
, handle
, buf
, limit
, offset
, flags
, err
);
615 if (r
!= -1 && need_flush
)
616 r
= plugin_flush (b
, conn
, handle
, 0, err
);
617 if (r
== -1 && !*err
)
618 *err
= get_error (p
);
623 plugin_extents (struct backend
*b
, struct connection
*conn
, void *handle
,
624 uint32_t count
, uint64_t offset
, uint32_t flags
,
625 struct nbdkit_extents
*extents
, int *err
)
627 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
630 /* This should be true because plugin_can_extents checks it. */
631 assert (p
->plugin
.extents
);
633 r
= p
->plugin
.extents (handle
, count
, offset
, flags
, extents
);
634 if (r
>= 0 && nbdkit_extents_count (extents
) < 1) {
635 nbdkit_error ("extents: plugin must return at least one extent");
636 nbdkit_set_error (EINVAL
);
640 *err
= get_error (p
);
645 plugin_cache (struct backend
*b
, struct connection
*conn
, void *handle
,
646 uint32_t count
, uint64_t offset
, uint32_t flags
,
649 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
652 /* A plugin may advertise caching but not provide .cache; in that
653 * case, caching is explicitly a no-op. */
654 if (!p
->plugin
.cache
)
657 r
= p
->plugin
.cache (handle
, count
, offset
, flags
);
659 *err
= get_error (p
);
663 static struct backend plugin_functions
= {
665 .thread_model
= plugin_thread_model
,
666 .plugin_name
= plugin_name
,
667 .usage
= plugin_usage
,
668 .version
= plugin_version
,
669 .dump_fields
= plugin_dump_fields
,
670 .config
= plugin_config
,
671 .config_complete
= plugin_config_complete
,
672 .magic_config_key
= plugin_magic_config_key
,
673 .preconnect
= plugin_preconnect
,
675 .prepare
= plugin_prepare
,
676 .finalize
= plugin_finalize
,
677 .close
= plugin_close
,
678 .get_size
= plugin_get_size
,
679 .can_write
= plugin_can_write
,
680 .can_flush
= plugin_can_flush
,
681 .is_rotational
= plugin_is_rotational
,
682 .can_trim
= plugin_can_trim
,
683 .can_zero
= plugin_can_zero
,
684 .can_fast_zero
= plugin_can_fast_zero
,
685 .can_extents
= plugin_can_extents
,
686 .can_fua
= plugin_can_fua
,
687 .can_multi_conn
= plugin_can_multi_conn
,
688 .can_cache
= plugin_can_cache
,
689 .pread
= plugin_pread
,
690 .pwrite
= plugin_pwrite
,
691 .flush
= plugin_flush
,
694 .extents
= plugin_extents
,
695 .cache
= plugin_cache
,
698 /* Register and load a plugin. */
700 plugin_register (size_t index
, const char *filename
,
701 void *dl
, struct nbdkit_plugin
*(*plugin_init
) (void))
703 struct backend_plugin
*p
;
704 const struct nbdkit_plugin
*plugin
;
707 p
= malloc (sizeof *p
);
713 p
->backend
= plugin_functions
;
714 backend_init (&p
->backend
, NULL
, index
, filename
, dl
, "plugin");
716 /* Call the initialization function which returns the address of the
717 * plugin's own 'struct nbdkit_plugin'.
719 plugin
= plugin_init ();
721 fprintf (stderr
, "%s: %s: plugin registration function failed\n",
722 program_name
, filename
);
726 /* Check for incompatible future versions. */
727 if (plugin
->_api_version
< 0 || plugin
->_api_version
> 2) {
729 "%s: %s: plugin is incompatible with this version of nbdkit "
730 "(_api_version = %d)\n",
731 program_name
, filename
, plugin
->_api_version
);
735 /* Since the plugin might be much older than the current version of
736 * nbdkit, only copy up to the self-declared _struct_size of the
737 * plugin and zero out the rest. If the plugin is much newer then
738 * we'll only call the "old" fields.
740 size
= sizeof p
->plugin
; /* our struct */
741 memset (&p
->plugin
, 0, size
);
742 if (size
> plugin
->_struct_size
)
743 size
= plugin
->_struct_size
;
744 memcpy (&p
->plugin
, plugin
, size
);
746 /* Check for the minimum fields which must exist in the
749 if (p
->plugin
.open
== NULL
) {
750 fprintf (stderr
, "%s: %s: plugin must have a .open callback\n",
751 program_name
, filename
);
754 if (p
->plugin
.get_size
== NULL
) {
755 fprintf (stderr
, "%s: %s: plugin must have a .get_size callback\n",
756 program_name
, filename
);
759 if (p
->plugin
.pread
== NULL
&& p
->plugin
._pread_v1
== NULL
) {
760 fprintf (stderr
, "%s: %s: plugin must have a .pread callback\n",
761 program_name
, filename
);
765 backend_load (&p
->backend
, p
->plugin
.name
, p
->plugin
.load
);
767 return (struct backend
*) p
;