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
);
189 if (p
->plugin
.dump_plugin
)
190 p
->plugin
.dump_plugin ();
194 plugin_config (struct backend
*b
, const char *key
, const char *value
)
196 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
198 debug ("%s: config key=%s, value=%s", b
->name
, key
, value
);
200 if (p
->plugin
.config
== NULL
) {
202 "%s: %s: this plugin does not need command line configuration\n"
203 "Try using: %s --help %s\n",
204 program_name
, b
->filename
,
205 program_name
, b
->filename
);
209 if (p
->plugin
.config (key
, value
) == -1)
214 plugin_config_complete (struct backend
*b
)
216 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
218 debug ("%s: config_complete", b
->name
);
220 if (!p
->plugin
.config_complete
)
223 if (p
->plugin
.config_complete () == -1)
228 plugin_magic_config_key (struct backend
*b
)
230 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
232 return p
->plugin
.magic_config_key
;
236 plugin_open (struct backend
*b
, struct connection
*conn
, int readonly
)
238 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
241 assert (connection_get_handle (conn
, 0) == NULL
);
242 assert (p
->plugin
.open
!= NULL
);
244 handle
= p
->plugin
.open (readonly
);
248 backend_set_handle (b
, conn
, handle
);
252 /* We don't expose .prepare and .finalize to plugins since they aren't
253 * necessary. Plugins can easily do the same work in .open and
257 plugin_prepare (struct backend
*b
, struct connection
*conn
)
263 plugin_finalize (struct backend
*b
, struct connection
*conn
)
269 plugin_close (struct backend
*b
, struct connection
*conn
)
271 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
273 assert (connection_get_handle (conn
, 0));
278 p
->plugin
.close (connection_get_handle (conn
, 0));
280 backend_set_handle (b
, conn
, NULL
);
284 plugin_get_size (struct backend
*b
, struct connection
*conn
)
286 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
288 assert (connection_get_handle (conn
, 0));
289 assert (p
->plugin
.get_size
!= NULL
);
291 return p
->plugin
.get_size (connection_get_handle (conn
, 0));
295 plugin_can_write (struct backend
*b
, struct connection
*conn
)
297 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
299 assert (connection_get_handle (conn
, 0));
301 if (p
->plugin
.can_write
)
302 return p
->plugin
.can_write (connection_get_handle (conn
, 0));
304 return p
->plugin
.pwrite
|| p
->plugin
._pwrite_old
;
308 plugin_can_flush (struct backend
*b
, struct connection
*conn
)
310 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
312 assert (connection_get_handle (conn
, 0));
314 if (p
->plugin
.can_flush
)
315 return p
->plugin
.can_flush (connection_get_handle (conn
, 0));
317 return p
->plugin
.flush
|| p
->plugin
._flush_old
;
321 plugin_is_rotational (struct backend
*b
, struct connection
*conn
)
323 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
325 assert (connection_get_handle (conn
, 0));
327 if (p
->plugin
.is_rotational
)
328 return p
->plugin
.is_rotational (connection_get_handle (conn
, 0));
330 return 0; /* assume false */
334 plugin_can_trim (struct backend
*b
, struct connection
*conn
)
336 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
338 assert (connection_get_handle (conn
, 0));
340 if (p
->plugin
.can_trim
)
341 return p
->plugin
.can_trim (connection_get_handle (conn
, 0));
343 return p
->plugin
.trim
|| p
->plugin
._trim_old
;
347 plugin_can_zero (struct backend
*b
, struct connection
*conn
)
349 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
351 assert (connection_get_handle (conn
, 0));
353 /* Note the special case here: the plugin's .can_zero controls only
354 * whether we call .zero; while the backend expects .can_zero to
355 * return whether to advertise zero support. Since we ALWAYS know
356 * how to fall back to .pwrite in plugin_zero(), we ignore the
357 * difference between the plugin's true or false return, and only
358 * call it to catch a -1 failure during negotiation. */
359 if (p
->plugin
.can_zero
&&
360 p
->plugin
.can_zero (connection_get_handle (conn
, 0)) == -1)
366 plugin_can_extents (struct backend
*b
, struct connection
*conn
)
368 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
370 assert (connection_get_handle (conn
, 0));
372 if (p
->plugin
.can_extents
)
373 return p
->plugin
.can_extents (connection_get_handle (conn
, 0));
375 return p
->plugin
.extents
!= NULL
;
379 plugin_can_fua (struct backend
*b
, struct connection
*conn
)
381 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
384 assert (connection_get_handle (conn
, 0));
386 /* The plugin must use API version 2 and have .can_fua return
387 NBDKIT_FUA_NATIVE before we will pass the FUA flag on. */
388 if (p
->plugin
.can_fua
) {
389 r
= p
->plugin
.can_fua (connection_get_handle (conn
, 0));
390 if (r
> NBDKIT_FUA_EMULATE
&& p
->plugin
._api_version
== 1)
391 r
= NBDKIT_FUA_EMULATE
;
394 /* We intend to call .flush even if .can_flush returns false. */
395 if (p
->plugin
.flush
|| p
->plugin
._flush_old
)
396 return NBDKIT_FUA_EMULATE
;
397 return NBDKIT_FUA_NONE
;
401 plugin_can_multi_conn (struct backend
*b
, struct connection
*conn
)
403 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
405 assert (connection_get_handle (conn
, 0));
407 if (p
->plugin
.can_multi_conn
)
408 return p
->plugin
.can_multi_conn (connection_get_handle (conn
, 0));
410 return 0; /* assume false */
414 plugin_can_cache (struct backend
*b
, struct connection
*conn
)
416 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
418 assert (connection_get_handle (conn
, 0));
420 if (p
->plugin
.can_cache
)
421 return p
->plugin
.can_cache (connection_get_handle (conn
, 0));
423 return NBDKIT_CACHE_NATIVE
;
424 return NBDKIT_CACHE_NONE
;
427 /* Plugins and filters can call this to set the true errno, in cases
428 * where !errno_is_preserved.
431 nbdkit_set_error (int err
)
433 threadlocal_set_error (err
);
436 /* Grab the appropriate error value.
439 get_error (struct backend_plugin
*p
)
441 int ret
= threadlocal_get_error ();
443 if (!ret
&& p
->plugin
.errno_is_preserved
!= 0)
445 return ret
? ret
: EIO
;
449 plugin_pread (struct backend
*b
, struct connection
*conn
,
450 void *buf
, uint32_t count
, uint64_t offset
, uint32_t flags
,
453 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
456 assert (connection_get_handle (conn
, 0));
457 assert (p
->plugin
.pread
|| p
->plugin
._pread_old
);
460 r
= p
->plugin
.pread (connection_get_handle (conn
, 0), buf
, count
, offset
,
463 r
= p
->plugin
._pread_old (connection_get_handle (conn
, 0), buf
, count
,
466 *err
= get_error (p
);
471 plugin_flush (struct backend
*b
, struct connection
*conn
, uint32_t flags
,
474 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
477 assert (connection_get_handle (conn
, 0));
480 r
= p
->plugin
.flush (connection_get_handle (conn
, 0), 0);
481 else if (p
->plugin
._flush_old
)
482 r
= p
->plugin
._flush_old (connection_get_handle (conn
, 0));
488 *err
= get_error (p
);
493 plugin_pwrite (struct backend
*b
, struct connection
*conn
,
494 const void *buf
, uint32_t count
, uint64_t offset
, uint32_t flags
,
498 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
499 bool fua
= flags
& NBDKIT_FLAG_FUA
;
500 bool need_flush
= false;
502 assert (connection_get_handle (conn
, 0));
504 if (fua
&& plugin_can_fua (b
, conn
) != NBDKIT_FUA_NATIVE
) {
505 flags
&= ~NBDKIT_FLAG_FUA
;
508 if (p
->plugin
.pwrite
)
509 r
= p
->plugin
.pwrite (connection_get_handle (conn
, 0), buf
, count
, offset
,
511 else if (p
->plugin
._pwrite_old
)
512 r
= p
->plugin
._pwrite_old (connection_get_handle (conn
, 0),
518 if (r
!= -1 && need_flush
)
519 r
= plugin_flush (b
, conn
, 0, err
);
520 if (r
== -1 && !*err
)
521 *err
= get_error (p
);
526 plugin_trim (struct backend
*b
, struct connection
*conn
,
527 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
530 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
531 bool fua
= flags
& NBDKIT_FLAG_FUA
;
532 bool need_flush
= false;
534 assert (connection_get_handle (conn
, 0));
536 if (fua
&& plugin_can_fua (b
, conn
) != NBDKIT_FUA_NATIVE
) {
537 flags
&= ~NBDKIT_FLAG_FUA
;
541 r
= p
->plugin
.trim (connection_get_handle (conn
, 0), count
, offset
, flags
);
542 else if (p
->plugin
._trim_old
)
543 r
= p
->plugin
._trim_old (connection_get_handle (conn
, 0), count
, offset
);
548 if (r
!= -1 && need_flush
)
549 r
= plugin_flush (b
, conn
, 0, err
);
550 if (r
== -1 && !*err
)
551 *err
= get_error (p
);
556 plugin_zero (struct backend
*b
, struct connection
*conn
,
557 uint32_t count
, uint64_t offset
, uint32_t flags
, int *err
)
559 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
561 bool may_trim
= flags
& NBDKIT_FLAG_MAY_TRIM
;
562 bool fua
= flags
& NBDKIT_FLAG_FUA
;
563 bool emulate
= false;
564 bool need_flush
= false;
565 int can_zero
= 1; /* TODO cache this per-connection? */
567 assert (connection_get_handle (conn
, 0));
569 if (fua
&& plugin_can_fua (b
, conn
) != NBDKIT_FUA_NATIVE
) {
570 flags
&= ~NBDKIT_FLAG_FUA
;
575 if (p
->plugin
.can_zero
) {
576 can_zero
= p
->plugin
.can_zero (connection_get_handle (conn
, 0));
577 assert (can_zero
!= -1);
583 r
= p
->plugin
.zero (connection_get_handle (conn
, 0), count
, offset
,
585 else if (p
->plugin
._zero_old
)
586 r
= p
->plugin
._zero_old (connection_get_handle (conn
, 0), count
, offset
,
591 *err
= emulate
? EOPNOTSUPP
: get_error (p
);
592 if (r
== 0 || (*err
!= EOPNOTSUPP
&& *err
!= ENOTSUP
))
596 assert (p
->plugin
.pwrite
|| p
->plugin
._pwrite_old
);
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
, buf
, limit
, offset
, flags
, err
);
615 if (r
!= -1 && need_flush
)
616 r
= plugin_flush (b
, conn
, 0, err
);
617 if (r
== -1 && !*err
)
618 *err
= get_error (p
);
623 plugin_extents (struct backend
*b
, struct connection
*conn
,
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 assert (connection_get_handle (conn
, 0));
632 /* This should be true because plugin_can_extents checks it. */
633 assert (p
->plugin
.extents
);
635 r
= p
->plugin
.extents (connection_get_handle (conn
, 0), count
, offset
,
637 if (r
>= 0 && nbdkit_extents_count (extents
) < 1) {
638 nbdkit_error ("extents: plugin must return at least one extent");
639 nbdkit_set_error (EINVAL
);
643 *err
= get_error (p
);
648 plugin_cache (struct backend
*b
, struct connection
*conn
,
649 uint32_t count
, uint64_t offset
, uint32_t flags
,
652 struct backend_plugin
*p
= container_of (b
, struct backend_plugin
, backend
);
655 assert (connection_get_handle (conn
, 0));
657 /* A plugin may advertise caching but not provide .cache; in that
658 * case, caching is explicitly a no-op. */
659 if (!p
->plugin
.cache
)
662 r
= p
->plugin
.cache (connection_get_handle (conn
, 0), count
, offset
, flags
);
664 *err
= get_error (p
);
668 static struct backend plugin_functions
= {
670 .thread_model
= plugin_thread_model
,
671 .plugin_name
= plugin_name
,
672 .usage
= plugin_usage
,
673 .version
= plugin_version
,
674 .dump_fields
= plugin_dump_fields
,
675 .config
= plugin_config
,
676 .config_complete
= plugin_config_complete
,
677 .magic_config_key
= plugin_magic_config_key
,
679 .prepare
= plugin_prepare
,
680 .finalize
= plugin_finalize
,
681 .close
= plugin_close
,
682 .get_size
= plugin_get_size
,
683 .can_write
= plugin_can_write
,
684 .can_flush
= plugin_can_flush
,
685 .is_rotational
= plugin_is_rotational
,
686 .can_trim
= plugin_can_trim
,
687 .can_zero
= plugin_can_zero
,
688 .can_extents
= plugin_can_extents
,
689 .can_fua
= plugin_can_fua
,
690 .can_multi_conn
= plugin_can_multi_conn
,
691 .can_cache
= plugin_can_cache
,
692 .pread
= plugin_pread
,
693 .pwrite
= plugin_pwrite
,
694 .flush
= plugin_flush
,
697 .extents
= plugin_extents
,
698 .cache
= plugin_cache
,
701 /* Register and load a plugin. */
703 plugin_register (size_t index
, const char *filename
,
704 void *dl
, struct nbdkit_plugin
*(*plugin_init
) (void))
706 struct backend_plugin
*p
;
707 const struct nbdkit_plugin
*plugin
;
710 p
= malloc (sizeof *p
);
716 p
->backend
= plugin_functions
;
717 backend_init (&p
->backend
, NULL
, index
, filename
, dl
, "plugin");
719 /* Call the initialization function which returns the address of the
720 * plugin's own 'struct nbdkit_plugin'.
722 plugin
= plugin_init ();
724 fprintf (stderr
, "%s: %s: plugin registration function failed\n",
725 program_name
, filename
);
729 /* Check for incompatible future versions. */
730 if (plugin
->_api_version
< 0 || plugin
->_api_version
> 2) {
732 "%s: %s: plugin is incompatible with this version of nbdkit "
733 "(_api_version = %d)\n",
734 program_name
, filename
, plugin
->_api_version
);
738 /* Since the plugin might be much older than the current version of
739 * nbdkit, only copy up to the self-declared _struct_size of the
740 * plugin and zero out the rest. If the plugin is much newer then
741 * we'll only call the "old" fields.
743 size
= sizeof p
->plugin
; /* our struct */
744 memset (&p
->plugin
, 0, size
);
745 if (size
> plugin
->_struct_size
)
746 size
= plugin
->_struct_size
;
747 memcpy (&p
->plugin
, plugin
, size
);
749 /* Check for the minimum fields which must exist in the
752 if (p
->plugin
.open
== NULL
) {
753 fprintf (stderr
, "%s: %s: plugin must have a .open callback\n",
754 program_name
, filename
);
757 if (p
->plugin
.get_size
== NULL
) {
758 fprintf (stderr
, "%s: %s: plugin must have a .get_size callback\n",
759 program_name
, filename
);
762 if (p
->plugin
.pread
== NULL
&& p
->plugin
._pread_old
== NULL
) {
763 fprintf (stderr
, "%s: %s: plugin must have a .pread callback\n",
764 program_name
, filename
);
768 backend_load (&p
->backend
, p
->plugin
.name
, p
->plugin
.load
);
770 return (struct backend
*) p
;