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
);
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
);
241 assert (p
->plugin
.open
!= NULL
);
243 return p
->plugin
.open (readonly
);
246 /* We don't expose .prepare and .finalize to plugins since they aren't
247 * necessary. Plugins can easily do the same work in .open and
251 plugin_prepare (struct backend
*b
, struct connection
*conn
, void *handle
,
258 plugin_finalize (struct backend
*b
, struct connection
*conn
, void *handle
)
264 plugin_close (struct backend
*b
, struct connection
*conn
, void *handle
)
266 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
268 if (handle
&& p
->plugin
.close
)
269 p
->plugin
.close (handle
);
273 plugin_get_size (struct backend
*b
, struct connection
*conn
, void *handle
)
275 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
277 assert (p
->plugin
.get_size
!= NULL
);
279 return p
->plugin
.get_size (handle
);
283 plugin_can_write (struct backend
*b
, struct connection
*conn
, void *handle
)
285 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
287 if (p
->plugin
.can_write
)
288 return p
->plugin
.can_write (handle
);
290 return p
->plugin
.pwrite
|| p
->plugin
._pwrite_old
;
294 plugin_can_flush (struct backend
*b
, struct connection
*conn
, void *handle
)
296 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
298 if (p
->plugin
.can_flush
)
299 return p
->plugin
.can_flush (handle
);
301 return p
->plugin
.flush
|| p
->plugin
._flush_old
;
305 plugin_is_rotational (struct backend
*b
, struct connection
*conn
, void *handle
)
307 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
309 if (p
->plugin
.is_rotational
)
310 return p
->plugin
.is_rotational (handle
);
312 return 0; /* assume false */
316 plugin_can_trim (struct backend
*b
, struct connection
*conn
, void *handle
)
318 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
320 if (p
->plugin
.can_trim
)
321 return p
->plugin
.can_trim (handle
);
323 return p
->plugin
.trim
|| p
->plugin
._trim_old
;
327 plugin_can_zero (struct backend
*b
, struct connection
*conn
, void *handle
)
329 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
332 /* Note the special case here: the plugin's .can_zero returns a bool
333 * which controls only whether we call .zero; while the backend
334 * expects .can_zero to return a tri-state on level of support.
336 if (p
->plugin
.can_zero
) {
337 r
= p
->plugin
.can_zero (handle
);
340 return r
? NBDKIT_ZERO_NATIVE
: NBDKIT_ZERO_EMULATE
;
342 if (p
->plugin
.zero
|| p
->plugin
._zero_old
)
343 return NBDKIT_ZERO_NATIVE
;
344 return NBDKIT_ZERO_EMULATE
;
348 plugin_can_fast_zero (struct backend
*b
, struct connection
*conn
, void *handle
)
350 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
353 if (p
->plugin
.can_fast_zero
)
354 return p
->plugin
.can_fast_zero (handle
);
355 /* Advertise support for fast zeroes if no .zero or .can_zero is
356 * false: in those cases, we fail fast instead of using .pwrite.
357 * This also works when v1 plugin has only ._zero_old.
359 if (p
->plugin
.zero
== NULL
)
361 r
= backend_can_zero (b
, conn
);
368 plugin_can_extents (struct backend
*b
, struct connection
*conn
, void *handle
)
370 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
372 if (p
->plugin
.can_extents
)
373 return p
->plugin
.can_extents (handle
);
375 return p
->plugin
.extents
!= NULL
;
379 plugin_can_fua (struct backend
*b
, struct connection
*conn
, void *handle
)
381 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
384 /* The plugin must use API version 2 and have .can_fua return
385 NBDKIT_FUA_NATIVE before we will pass the FUA flag on. */
386 if (p
->plugin
.can_fua
) {
387 r
= p
->plugin
.can_fua (handle
);
388 if (r
> NBDKIT_FUA_EMULATE
&& p
->plugin
._api_version
== 1)
389 r
= NBDKIT_FUA_EMULATE
;
392 /* We intend to call .flush even if .can_flush returns false. */
393 if (p
->plugin
.flush
|| p
->plugin
._flush_old
)
394 return NBDKIT_FUA_EMULATE
;
395 return NBDKIT_FUA_NONE
;
399 plugin_can_multi_conn (struct backend
*b
, struct connection
*conn
, void *handle
)
401 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
403 if (p
->plugin
.can_multi_conn
)
404 return p
->plugin
.can_multi_conn (handle
);
406 return 0; /* assume false */
410 plugin_can_cache (struct backend
*b
, struct connection
*conn
, void *handle
)
412 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
414 if (p
->plugin
.can_cache
)
415 return p
->plugin
.can_cache (handle
);
417 return NBDKIT_CACHE_NATIVE
;
418 return NBDKIT_CACHE_NONE
;
421 /* Plugins and filters can call this to set the true errno, in cases
422 * where !errno_is_preserved.
425 nbdkit_set_error (int err
)
427 threadlocal_set_error (err
);
430 /* Grab the appropriate error value.
433 get_error (struct backend_plugin
*p
)
435 int ret
= threadlocal_get_error ();
437 if (!ret
&& p
->plugin
.errno_is_preserved
!= 0)
439 return ret
? ret
: EIO
;
443 plugin_pread (struct backend
*b
, struct connection
*conn
, void *handle
,
444 void *buf
, uint32_t count
, uint64_t offset
, uint32_t flags
,
447 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
450 assert (p
->plugin
.pread
|| p
->plugin
._pread_old
);
453 r
= p
->plugin
.pread (handle
, buf
, count
, offset
, 0);
455 r
= p
->plugin
._pread_old (handle
, buf
, count
, offset
);
457 *err
= get_error (p
);
462 plugin_flush (struct backend
*b
, struct connection
*conn
, void *handle
,
463 uint32_t flags
, int *err
)
465 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
469 r
= p
->plugin
.flush (handle
, 0);
470 else if (p
->plugin
._flush_old
)
471 r
= p
->plugin
._flush_old (handle
);
477 *err
= get_error (p
);
482 plugin_pwrite (struct backend
*b
, struct connection
*conn
, void *handle
,
483 const void *buf
, uint32_t count
, uint64_t offset
, uint32_t flags
,
487 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
488 bool fua
= flags
& NBDKIT_FLAG_FUA
;
489 bool need_flush
= false;
491 if (fua
&& backend_can_fua (b
, conn
) != NBDKIT_FUA_NATIVE
) {
492 flags
&= ~NBDKIT_FLAG_FUA
;
495 if (p
->plugin
.pwrite
)
496 r
= p
->plugin
.pwrite (handle
, buf
, count
, offset
, flags
);
497 else if (p
->plugin
._pwrite_old
)
498 r
= p
->plugin
._pwrite_old (handle
, buf
, count
, offset
);
503 if (r
!= -1 && need_flush
)
504 r
= plugin_flush (b
, conn
, handle
, 0, err
);
505 if (r
== -1 && !*err
)
506 *err
= get_error (p
);
511 plugin_trim (struct backend
*b
, struct connection
*conn
, void *handle
,
512 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
515 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
516 bool fua
= flags
& NBDKIT_FLAG_FUA
;
517 bool need_flush
= false;
519 if (fua
&& backend_can_fua (b
, conn
) != NBDKIT_FUA_NATIVE
) {
520 flags
&= ~NBDKIT_FLAG_FUA
;
524 r
= p
->plugin
.trim (handle
, count
, offset
, flags
);
525 else if (p
->plugin
._trim_old
)
526 r
= p
->plugin
._trim_old (handle
, count
, offset
);
531 if (r
!= -1 && need_flush
)
532 r
= plugin_flush (b
, conn
, handle
, 0, err
);
533 if (r
== -1 && !*err
)
534 *err
= get_error (p
);
539 plugin_zero (struct backend
*b
, struct connection
*conn
, void *handle
,
540 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
542 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
544 bool may_trim
= flags
& NBDKIT_FLAG_MAY_TRIM
;
545 bool fua
= flags
& NBDKIT_FLAG_FUA
;
546 bool fast_zero
= flags
& NBDKIT_FLAG_FAST_ZERO
;
547 bool emulate
= false;
548 bool need_flush
= false;
550 if (fua
&& backend_can_fua (b
, conn
) != NBDKIT_FUA_NATIVE
) {
551 flags
&= ~NBDKIT_FLAG_FUA
;
557 if (backend_can_zero (b
, conn
) == NBDKIT_ZERO_NATIVE
) {
560 r
= p
->plugin
.zero (handle
, count
, offset
, flags
);
561 else if (p
->plugin
._zero_old
) {
566 r
= p
->plugin
._zero_old (handle
, count
, offset
, may_trim
);
571 *err
= emulate
? EOPNOTSUPP
: get_error (p
);
572 if (r
== 0 || (*err
!= EOPNOTSUPP
&& *err
!= ENOTSUP
))
582 assert (p
->plugin
.pwrite
|| p
->plugin
._pwrite_old
);
583 flags
&= ~NBDKIT_FLAG_MAY_TRIM
;
584 threadlocal_set_error (0);
588 /* Always contains zeroes, but we can't use const or else gcc 9
589 * will use .rodata instead of .bss and inflate the binary size.
591 static /* const */ char buf
[MAX_REQUEST_SIZE
];
592 uint32_t limit
= MIN (count
, sizeof buf
);
594 r
= plugin_pwrite (b
, conn
, handle
, buf
, limit
, offset
, flags
, err
);
601 if (r
!= -1 && need_flush
)
602 r
= plugin_flush (b
, conn
, handle
, 0, err
);
603 if (r
== -1 && !*err
)
604 *err
= get_error (p
);
609 plugin_extents (struct backend
*b
, struct connection
*conn
, void *handle
,
610 uint32_t count
, uint64_t offset
, uint32_t flags
,
611 struct nbdkit_extents
*extents
, int *err
)
613 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
616 /* This should be true because plugin_can_extents checks it. */
617 assert (p
->plugin
.extents
);
619 r
= p
->plugin
.extents (handle
, count
, offset
, flags
, extents
);
620 if (r
>= 0 && nbdkit_extents_count (extents
) < 1) {
621 nbdkit_error ("extents: plugin must return at least one extent");
622 nbdkit_set_error (EINVAL
);
626 *err
= get_error (p
);
631 plugin_cache (struct backend
*b
, struct connection
*conn
, void *handle
,
632 uint32_t count
, uint64_t offset
, uint32_t flags
,
635 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
638 /* A plugin may advertise caching but not provide .cache; in that
639 * case, caching is explicitly a no-op. */
640 if (!p
->plugin
.cache
)
643 r
= p
->plugin
.cache (handle
, count
, offset
, flags
);
645 *err
= get_error (p
);
649 static struct backend plugin_functions
= {
651 .thread_model
= plugin_thread_model
,
652 .plugin_name
= plugin_name
,
653 .usage
= plugin_usage
,
654 .version
= plugin_version
,
655 .dump_fields
= plugin_dump_fields
,
656 .config
= plugin_config
,
657 .config_complete
= plugin_config_complete
,
658 .magic_config_key
= plugin_magic_config_key
,
660 .prepare
= plugin_prepare
,
661 .finalize
= plugin_finalize
,
662 .close
= plugin_close
,
663 .get_size
= plugin_get_size
,
664 .can_write
= plugin_can_write
,
665 .can_flush
= plugin_can_flush
,
666 .is_rotational
= plugin_is_rotational
,
667 .can_trim
= plugin_can_trim
,
668 .can_zero
= plugin_can_zero
,
669 .can_fast_zero
= plugin_can_fast_zero
,
670 .can_extents
= plugin_can_extents
,
671 .can_fua
= plugin_can_fua
,
672 .can_multi_conn
= plugin_can_multi_conn
,
673 .can_cache
= plugin_can_cache
,
674 .pread
= plugin_pread
,
675 .pwrite
= plugin_pwrite
,
676 .flush
= plugin_flush
,
679 .extents
= plugin_extents
,
680 .cache
= plugin_cache
,
683 /* Register and load a plugin. */
685 plugin_register (size_t index
, const char *filename
,
686 void *dl
, struct nbdkit_plugin
*(*plugin_init
) (void))
688 struct backend_plugin
*p
;
689 const struct nbdkit_plugin
*plugin
;
692 p
= malloc (sizeof *p
);
698 p
->backend
= plugin_functions
;
699 backend_init (&p
->backend
, NULL
, index
, filename
, dl
, "plugin");
701 /* Call the initialization function which returns the address of the
702 * plugin's own 'struct nbdkit_plugin'.
704 plugin
= plugin_init ();
706 fprintf (stderr
, "%s: %s: plugin registration function failed\n",
707 program_name
, filename
);
711 /* Check for incompatible future versions. */
712 if (plugin
->_api_version
< 0 || plugin
->_api_version
> 2) {
714 "%s: %s: plugin is incompatible with this version of nbdkit "
715 "(_api_version = %d)\n",
716 program_name
, filename
, plugin
->_api_version
);
720 /* Since the plugin might be much older than the current version of
721 * nbdkit, only copy up to the self-declared _struct_size of the
722 * plugin and zero out the rest. If the plugin is much newer then
723 * we'll only call the "old" fields.
725 size
= sizeof p
->plugin
; /* our struct */
726 memset (&p
->plugin
, 0, size
);
727 if (size
> plugin
->_struct_size
)
728 size
= plugin
->_struct_size
;
729 memcpy (&p
->plugin
, plugin
, size
);
731 /* Check for the minimum fields which must exist in the
734 if (p
->plugin
.open
== NULL
) {
735 fprintf (stderr
, "%s: %s: plugin must have a .open callback\n",
736 program_name
, filename
);
739 if (p
->plugin
.get_size
== NULL
) {
740 fprintf (stderr
, "%s: %s: plugin must have a .get_size callback\n",
741 program_name
, filename
);
744 if (p
->plugin
.pread
== NULL
&& p
->plugin
._pread_old
== NULL
) {
745 fprintf (stderr
, "%s: %s: plugin must have a .pread callback\n",
746 program_name
, filename
);
750 backend_load (&p
->backend
, p
->plugin
.name
, p
->plugin
.load
);
752 return (struct backend
*) p
;