server: Remember .open(readonly) status
[nbdkit/ericb.git] / server / plugins.c
blob1c4b5f503a09b46945b5e914f29584e706b82983
1 /* nbdkit
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
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>
42 #include <sys/socket.h>
44 #include "internal.h"
45 #include "minmax.h"
47 /* We extend the generic backend struct with extra fields relating
48 * to this plugin.
50 struct backend_plugin {
51 struct backend backend;
52 struct nbdkit_plugin plugin;
55 static void
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);
61 free (p);
64 static int
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;
69 int r;
71 #if !(defined SOCK_CLOEXEC && defined HAVE_MKOSTEMP && defined HAVE_PIPE2 && \
72 defined HAVE_ACCEPT4)
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;
77 #endif
79 if (p->plugin.thread_model) {
80 r = p->plugin.thread_model ();
81 if (r == -1)
82 exit (EXIT_FAILURE);
83 if (r < thread_model)
84 thread_model = r;
87 return thread_model;
90 static const char *
91 plugin_name (struct backend *b)
93 return b->name;
96 static void
97 plugin_usage (struct backend *b)
99 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
100 const char *t;
102 printf ("plugin: %s", b->name);
103 if (p->plugin.longname)
104 printf (" (%s)", p->plugin.longname);
105 printf ("\n");
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])
110 printf ("\n");
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])
115 printf ("\n");
119 static const char *
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. */
128 static void
129 plugin_dump_fields (struct backend *b)
131 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
132 char *path;
134 path = nbdkit_realpath (b->filename);
135 printf ("path=%s\n", path);
136 free (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)
153 HAS (longname);
154 HAS (description);
155 HAS (load);
156 HAS (unload);
157 HAS (dump_plugin);
158 HAS (config);
159 HAS (config_complete);
160 HAS (config_help);
161 HAS (open);
162 HAS (close);
163 HAS (get_size);
164 HAS (can_write);
165 HAS (can_flush);
166 HAS (is_rotational);
167 HAS (can_trim);
168 HAS (_pread_old);
169 HAS (_pwrite_old);
170 HAS (_flush_old);
171 HAS (_trim_old);
172 HAS (_zero_old);
173 HAS (can_zero);
174 HAS (can_fua);
175 HAS (pread);
176 HAS (pwrite);
177 HAS (flush);
178 HAS (trim);
179 HAS (zero);
180 HAS (can_multi_conn);
181 HAS (can_extents);
182 HAS (extents);
183 HAS (can_cache);
184 HAS (cache);
185 HAS (thread_model);
186 #undef HAS
188 /* Custom fields. */
189 if (p->plugin.dump_plugin)
190 p->plugin.dump_plugin ();
193 static void
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) {
201 fprintf (stderr,
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);
206 exit (EXIT_FAILURE);
209 if (p->plugin.config (key, value) == -1)
210 exit (EXIT_FAILURE);
213 static void
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)
221 return;
223 if (p->plugin.config_complete () == -1)
224 exit (EXIT_FAILURE);
227 static const char *
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;
235 static int
236 plugin_open (struct backend *b, struct connection *conn, int readonly)
238 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
239 void *handle;
241 assert (connection_get_handle (conn, 0) == NULL);
242 assert (p->plugin.open != NULL);
244 handle = p->plugin.open (readonly);
245 if (!handle)
246 return -1;
248 backend_set_handle (b, conn, handle);
249 return 0;
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
254 * .close.
256 static int
257 plugin_prepare (struct backend *b, struct connection *conn)
259 return 0;
262 static int
263 plugin_finalize (struct backend *b, struct connection *conn)
265 return 0;
268 static void
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));
275 debug ("close");
277 if (p->plugin.close)
278 p->plugin.close (connection_get_handle (conn, 0));
280 backend_set_handle (b, conn, NULL);
283 static int64_t
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));
294 static int
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));
303 else
304 return p->plugin.pwrite || p->plugin._pwrite_old;
307 static int
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));
316 else
317 return p->plugin.flush || p->plugin._flush_old;
320 static int
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));
329 else
330 return 0; /* assume false */
333 static int
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));
342 else
343 return p->plugin.trim || p->plugin._trim_old;
346 static int
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)
361 return -1;
362 return 1;
365 static int
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));
374 else
375 return p->plugin.extents != NULL;
378 static int
379 plugin_can_fua (struct backend *b, struct connection *conn)
381 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
382 int r;
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;
392 return r;
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;
400 static int
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));
409 else
410 return 0; /* assume false */
413 static int
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));
422 if (p->plugin.cache)
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.
430 void
431 nbdkit_set_error (int err)
433 threadlocal_set_error (err);
436 /* Grab the appropriate error value.
438 static int
439 get_error (struct backend_plugin *p)
441 int ret = threadlocal_get_error ();
443 if (!ret && p->plugin.errno_is_preserved != 0)
444 ret = errno;
445 return ret ? ret : EIO;
448 static int
449 plugin_pread (struct backend *b, struct connection *conn,
450 void *buf, uint32_t count, uint64_t offset, uint32_t flags,
451 int *err)
453 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
454 int r;
456 assert (connection_get_handle (conn, 0));
457 assert (p->plugin.pread || p->plugin._pread_old);
459 if (p->plugin.pread)
460 r = p->plugin.pread (connection_get_handle (conn, 0), buf, count, offset,
462 else
463 r = p->plugin._pread_old (connection_get_handle (conn, 0), buf, count,
464 offset);
465 if (r == -1)
466 *err = get_error (p);
467 return r;
470 static int
471 plugin_flush (struct backend *b, struct connection *conn, uint32_t flags,
472 int *err)
474 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
475 int r;
477 assert (connection_get_handle (conn, 0));
479 if (p->plugin.flush)
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));
483 else {
484 *err = EINVAL;
485 return -1;
487 if (r == -1)
488 *err = get_error (p);
489 return r;
492 static int
493 plugin_pwrite (struct backend *b, struct connection *conn,
494 const void *buf, uint32_t count, uint64_t offset, uint32_t flags,
495 int *err)
497 int r;
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;
506 need_flush = true;
508 if (p->plugin.pwrite)
509 r = p->plugin.pwrite (connection_get_handle (conn, 0), buf, count, offset,
510 flags);
511 else if (p->plugin._pwrite_old)
512 r = p->plugin._pwrite_old (connection_get_handle (conn, 0),
513 buf, count, offset);
514 else {
515 *err = EROFS;
516 return -1;
518 if (r != -1 && need_flush)
519 r = plugin_flush (b, conn, 0, err);
520 if (r == -1 && !*err)
521 *err = get_error (p);
522 return r;
525 static int
526 plugin_trim (struct backend *b, struct connection *conn,
527 uint32_t count, uint64_t offset, uint32_t flags, int *err)
529 int r;
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;
538 need_flush = true;
540 if (p->plugin.trim)
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);
544 else {
545 *err = EINVAL;
546 return -1;
548 if (r != -1 && need_flush)
549 r = plugin_flush (b, conn, 0, err);
550 if (r == -1 && !*err)
551 *err = get_error (p);
552 return r;
555 static int
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);
560 int r = -1;
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;
571 need_flush = true;
573 if (!count)
574 return 0;
575 if (p->plugin.can_zero) {
576 can_zero = p->plugin.can_zero (connection_get_handle (conn, 0));
577 assert (can_zero != -1);
580 if (can_zero) {
581 errno = 0;
582 if (p->plugin.zero)
583 r = p->plugin.zero (connection_get_handle (conn, 0), count, offset,
584 flags);
585 else if (p->plugin._zero_old)
586 r = p->plugin._zero_old (connection_get_handle (conn, 0), count, offset,
587 may_trim);
588 else
589 emulate = true;
590 if (r == -1)
591 *err = emulate ? EOPNOTSUPP : get_error (p);
592 if (r == 0 || (*err != EOPNOTSUPP && *err != ENOTSUP))
593 goto done;
596 assert (p->plugin.pwrite || p->plugin._pwrite_old);
597 flags &= ~NBDKIT_FLAG_MAY_TRIM;
598 threadlocal_set_error (0);
599 *err = 0;
601 while (count) {
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);
609 if (r == -1)
610 break;
611 count -= limit;
614 done:
615 if (r != -1 && need_flush)
616 r = plugin_flush (b, conn, 0, err);
617 if (r == -1 && !*err)
618 *err = get_error (p);
619 return r;
622 static int
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);
628 int r;
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,
636 flags, extents);
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);
640 r = -1;
642 if (r == -1)
643 *err = get_error (p);
644 return r;
647 static int
648 plugin_cache (struct backend *b, struct connection *conn,
649 uint32_t count, uint64_t offset, uint32_t flags,
650 int *err)
652 struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
653 int r;
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)
660 return 0;
662 r = p->plugin.cache (connection_get_handle (conn, 0), count, offset, flags);
663 if (r == -1)
664 *err = get_error (p);
665 return r;
668 static struct backend plugin_functions = {
669 .free = plugin_free,
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,
678 .open = plugin_open,
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,
695 .trim = plugin_trim,
696 .zero = plugin_zero,
697 .extents = plugin_extents,
698 .cache = plugin_cache,
701 /* Register and load a plugin. */
702 struct backend *
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;
708 size_t size;
710 p = malloc (sizeof *p);
711 if (p == NULL) {
712 perror ("strdup");
713 exit (EXIT_FAILURE);
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 ();
723 if (!plugin) {
724 fprintf (stderr, "%s: %s: plugin registration function failed\n",
725 program_name, filename);
726 exit (EXIT_FAILURE);
729 /* Check for incompatible future versions. */
730 if (plugin->_api_version < 0 || plugin->_api_version > 2) {
731 fprintf (stderr,
732 "%s: %s: plugin is incompatible with this version of nbdkit "
733 "(_api_version = %d)\n",
734 program_name, filename, plugin->_api_version);
735 exit (EXIT_FAILURE);
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
750 * plugin struct.
752 if (p->plugin.open == NULL) {
753 fprintf (stderr, "%s: %s: plugin must have a .open callback\n",
754 program_name, filename);
755 exit (EXIT_FAILURE);
757 if (p->plugin.get_size == NULL) {
758 fprintf (stderr, "%s: %s: plugin must have a .get_size callback\n",
759 program_name, filename);
760 exit (EXIT_FAILURE);
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);
765 exit (EXIT_FAILURE);
768 backend_load (&p->backend, p->plugin.name, p->plugin.load);
770 return (struct backend *) p;