1 /* nbdkit
2  * Copyright (C) 2013-2020 Red Hat Inc.
3  *
4  * Redistribution and use in source and binary forms, with or without
5  * modification, are permitted provided that the following conditions are
6  * met:
7  *
8  * * Redistributions of source code must retain the above copyright
9  * notice, this list of conditions and the following disclaimer.
10  *
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.
14  *
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.
18  *
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.
31  */
32 
33 #include <config.h>
34 
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>
43 
44 #include "internal.h"
45 #include "minmax.h"
46 
47 /* We extend the generic backend struct with extra fields relating
48  * to this plugin.
49  */
50 struct backend_plugin {
51   struct backend backend;
52   struct nbdkit_plugin plugin;
53 };
54 
55 static void
plugin_free(struct backend * b)56 plugin_free (struct backend *b)
57 {
58   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
59 
60   backend_unload (b, p->plugin.unload);
61   free (p);
62 }
63 
64 static int
plugin_thread_model(struct backend * b)65 plugin_thread_model (struct backend *b)
66 {
67   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
68   int model = p->plugin._thread_model;
69   int r;
70 
71 #if !(defined SOCK_CLOEXEC && defined HAVE_MKOSTEMP && defined HAVE_PIPE2 && \
72       defined HAVE_ACCEPT4)
73   if (model > NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS) {
74     debug ("system lacks atomic CLOEXEC, serializing to avoid fd leaks");
75     model = NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS;
76   }
77 #endif
78 
79   if (p->plugin.thread_model) {
80     r = p->plugin.thread_model ();
81     if (r == -1)
82       exit (EXIT_FAILURE);
83     if (r < model)
84       model = r;
85   }
86 
87   return model;
88 }
89 
90 static const char *
plugin_name(struct backend * b)91 plugin_name (struct backend *b)
92 {
93   return b->name;
94 }
95 
96 static void
plugin_usage(struct backend * b)97 plugin_usage (struct backend *b)
98 {
99   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
100   const char *t;
101 
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");
111   }
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");
116   }
117 }
118 
119 static const char *
plugin_version(struct backend * b)120 plugin_version (struct backend *b)
121 {
122   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
123 
124   return p->plugin.version;
125 }
126 
127 /* This implements the --dump-plugin option. */
128 static void
plugin_dump_fields(struct backend * b)129 plugin_dump_fields (struct backend *b)
130 {
131   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
132   char *path;
133 
134   path = nbdkit_realpath (b->filename);
135   printf ("path=%s\n", path);
136   free (path);
137 
138   printf ("name=%s\n", b->name);
139   if (p->plugin.version)
140     printf ("version=%s\n", p->plugin.version);
141 
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 (top->thread_model (top)));
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);
151 
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 (get_ready);
162   HAS (preconnect);
163   HAS (open);
164   HAS (close);
165   HAS (get_size);
166   HAS (can_write);
167   HAS (can_flush);
168   HAS (is_rotational);
169   HAS (can_trim);
170   HAS (_pread_v1);
171   HAS (_pwrite_v1);
172   HAS (_flush_v1);
173   HAS (_trim_v1);
174   HAS (_zero_v1);
175   HAS (can_zero);
176   HAS (can_fua);
177   HAS (pread);
178   HAS (pwrite);
179   HAS (flush);
180   HAS (trim);
181   HAS (zero);
182   HAS (can_multi_conn);
183   HAS (can_extents);
184   HAS (extents);
185   HAS (can_cache);
186   HAS (cache);
187   HAS (thread_model);
188   HAS (can_fast_zero);
189 #undef HAS
190 
191   /* Custom fields. */
192   if (p->plugin.dump_plugin)
193     p->plugin.dump_plugin ();
194 }
195 
196 static void
plugin_config(struct backend * b,const char * key,const char * value)197 plugin_config (struct backend *b, const char *key, const char *value)
198 {
199   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
200 
201   debug ("%s: config key=%s, value=%s", b->name, key, value);
202 
203   if (p->plugin.config == NULL) {
204     fprintf (stderr,
205              "%s: %s: this plugin does not need command line configuration\n"
206              "Try using: %s --help %s\n",
207              program_name, b->filename,
208              program_name, b->filename);
209     exit (EXIT_FAILURE);
210   }
211 
212   if (p->plugin.config (key, value) == -1)
213     exit (EXIT_FAILURE);
214 }
215 
216 static void
plugin_config_complete(struct backend * b)217 plugin_config_complete (struct backend *b)
218 {
219   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
220 
221   debug ("%s: config_complete", b->name);
222 
223   if (!p->plugin.config_complete)
224     return;
225 
226   if (p->plugin.config_complete () == -1)
227     exit (EXIT_FAILURE);
228 }
229 
230 static const char *
plugin_magic_config_key(struct backend * b)231 plugin_magic_config_key (struct backend *b)
232 {
233   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
234 
235   return p->plugin.magic_config_key;
236 }
237 
238 static void
plugin_get_ready(struct backend * b)239 plugin_get_ready (struct backend *b)
240 {
241   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
242 
243   debug ("%s: get_ready", b->name);
244 
245   if (!p->plugin.get_ready)
246     return;
247 
248   if (p->plugin.get_ready () == -1)
249     exit (EXIT_FAILURE);
250 }
251 
252 static int
plugin_preconnect(struct backend * b,int readonly)253 plugin_preconnect (struct backend *b, int readonly)
254 {
255   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
256 
257   debug ("%s: preconnect", b->name);
258 
259   if (!p->plugin.preconnect)
260     return 0;
261 
262   return p->plugin.preconnect (readonly);
263 }
264 
265 static void *
plugin_open(struct backend * b,int readonly)266 plugin_open (struct backend *b, int readonly)
267 {
268   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
269 
270   assert (p->plugin.open != NULL);
271 
272   return p->plugin.open (readonly);
273 }
274 
275 /* We don't expose .prepare and .finalize to plugins since they aren't
276  * necessary.  Plugins can easily do the same work in .open and
277  * .close.
278  */
279 static int
plugin_prepare(struct backend * b,void * handle,int readonly)280 plugin_prepare (struct backend *b, void *handle,
281                 int readonly)
282 {
283   return 0;
284 }
285 
286 static int
plugin_finalize(struct backend * b,void * handle)287 plugin_finalize (struct backend *b, void *handle)
288 {
289   return 0;
290 }
291 
292 static void
plugin_close(struct backend * b,void * handle)293 plugin_close (struct backend *b, void *handle)
294 {
295   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
296 
297   if (handle && p->plugin.close)
298     p->plugin.close (handle);
299 }
300 
301 static int64_t
plugin_get_size(struct backend * b,void * handle)302 plugin_get_size (struct backend *b, void *handle)
303 {
304   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
305 
306   assert (p->plugin.get_size != NULL);
307 
308   return p->plugin.get_size (handle);
309 }
310 
311 static int
normalize_bool(int value)312 normalize_bool (int value)
313 {
314   if (value == -1 || value == 0)
315     return value;
316   /* Normalize all other non-zero values to true */
317   return 1;
318 }
319 
320 static int
plugin_can_write(struct backend * b,void * handle)321 plugin_can_write (struct backend *b, void *handle)
322 {
323   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
324 
325   if (p->plugin.can_write)
326     return normalize_bool (p->plugin.can_write (handle));
327   else
328     return p->plugin.pwrite || p->plugin._pwrite_v1;
329 }
330 
331 static int
plugin_can_flush(struct backend * b,void * handle)332 plugin_can_flush (struct backend *b, void *handle)
333 {
334   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
335 
336   if (p->plugin.can_flush)
337     return normalize_bool (p->plugin.can_flush (handle));
338   else
339     return p->plugin.flush || p->plugin._flush_v1;
340 }
341 
342 static int
plugin_is_rotational(struct backend * b,void * handle)343 plugin_is_rotational (struct backend *b, void *handle)
344 {
345   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
346 
347   if (p->plugin.is_rotational)
348     return normalize_bool (p->plugin.is_rotational (handle));
349   else
350     return 0; /* assume false */
351 }
352 
353 static int
plugin_can_trim(struct backend * b,void * handle)354 plugin_can_trim (struct backend *b, void *handle)
355 {
356   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
357 
358   if (p->plugin.can_trim)
359     return normalize_bool (p->plugin.can_trim (handle));
360   else
361     return p->plugin.trim || p->plugin._trim_v1;
362 }
363 
364 static int
plugin_can_zero(struct backend * b,void * handle)365 plugin_can_zero (struct backend *b, void *handle)
366 {
367   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
368   int r;
369 
370   /* Note the special case here: the plugin's .can_zero returns a bool
371    * which controls only whether we call .zero; while the backend
372    * expects .can_zero to return a tri-state on level of support.
373    */
374   if (p->plugin.can_zero) {
375     r = p->plugin.can_zero (handle);
376     if (r == -1)
377       return -1;
378     return r ? NBDKIT_ZERO_NATIVE : NBDKIT_ZERO_EMULATE;
379   }
380   if (p->plugin.zero || p->plugin._zero_v1)
381     return NBDKIT_ZERO_NATIVE;
382   return NBDKIT_ZERO_EMULATE;
383 }
384 
385 static int
plugin_can_fast_zero(struct backend * b,void * handle)386 plugin_can_fast_zero (struct backend *b, void *handle)
387 {
388   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
389   int r;
390 
391   if (p->plugin.can_fast_zero)
392     return normalize_bool (p->plugin.can_fast_zero (handle));
393   /* Advertise support for fast zeroes if no .zero or .can_zero is
394    * false: in those cases, we fail fast instead of using .pwrite.
395    * This also works when v1 plugin has only ._zero_v1.
396    */
397   if (p->plugin.zero == NULL)
398     return 1;
399   r = backend_can_zero (b);
400   if (r == -1)
401     return -1;
402   return !r;
403 }
404 
405 static int
plugin_can_extents(struct backend * b,void * handle)406 plugin_can_extents (struct backend *b, void *handle)
407 {
408   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
409 
410   if (p->plugin.can_extents)
411     return normalize_bool (p->plugin.can_extents (handle));
412   else
413     return p->plugin.extents != NULL;
414 }
415 
416 static int
plugin_can_fua(struct backend * b,void * handle)417 plugin_can_fua (struct backend *b, void *handle)
418 {
419   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
420   int r;
421 
422   /* The plugin must use API version 2 and have .can_fua return
423      NBDKIT_FUA_NATIVE before we will pass the FUA flag on. */
424   if (p->plugin.can_fua) {
425     r = p->plugin.can_fua (handle);
426     if (r > NBDKIT_FUA_EMULATE && p->plugin._api_version == 1)
427       r = NBDKIT_FUA_EMULATE;
428     return r;
429   }
430   /* We intend to call .flush even if .can_flush returns false. */
431   if (p->plugin.flush || p->plugin._flush_v1)
432     return NBDKIT_FUA_EMULATE;
433   return NBDKIT_FUA_NONE;
434 }
435 
436 static int
plugin_can_multi_conn(struct backend * b,void * handle)437 plugin_can_multi_conn (struct backend *b, void *handle)
438 {
439   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
440 
441   if (p->plugin.can_multi_conn)
442     return normalize_bool (p->plugin.can_multi_conn (handle));
443   else
444     return 0; /* assume false */
445 }
446 
447 static int
plugin_can_cache(struct backend * b,void * handle)448 plugin_can_cache (struct backend *b, void *handle)
449 {
450   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
451 
452   if (p->plugin.can_cache)
453     return p->plugin.can_cache (handle);
454   if (p->plugin.cache)
455     return NBDKIT_CACHE_NATIVE;
456   return NBDKIT_CACHE_NONE;
457 }
458 
459 /* Plugins and filters can call this to set the true errno, in cases
460  * where !errno_is_preserved.
461  */
462 void
nbdkit_set_error(int err)463 nbdkit_set_error (int err)
464 {
465   threadlocal_set_error (err);
466 }
467 
468 /* Grab the appropriate error value.
469  */
470 static int
get_error(struct backend_plugin * p)471 get_error (struct backend_plugin *p)
472 {
473   int ret = threadlocal_get_error ();
474 
475   if (!ret && p->plugin.errno_is_preserved != 0)
476     ret = errno;
477   return ret ? ret : EIO;
478 }
479 
480 static int
plugin_pread(struct backend * b,void * handle,void * buf,uint32_t count,uint64_t offset,uint32_t flags,int * err)481 plugin_pread (struct backend *b, void *handle,
482               void *buf, uint32_t count, uint64_t offset, uint32_t flags,
483               int *err)
484 {
485   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
486   int r;
487 
488   assert (p->plugin.pread || p->plugin._pread_v1);
489 
490   if (p->plugin.pread)
491     r = p->plugin.pread (handle, buf, count, offset, 0);
492   else
493     r = p->plugin._pread_v1 (handle, buf, count, offset);
494   if (r == -1)
495     *err = get_error (p);
496   return r;
497 }
498 
499 static int
plugin_flush(struct backend * b,void * handle,uint32_t flags,int * err)500 plugin_flush (struct backend *b, void *handle,
501               uint32_t flags, int *err)
502 {
503   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
504   int r;
505 
506   if (p->plugin.flush)
507     r = p->plugin.flush (handle, 0);
508   else if (p->plugin._flush_v1)
509     r = p->plugin._flush_v1 (handle);
510   else {
511     *err = EINVAL;
512     return -1;
513   }
514   if (r == -1)
515     *err = get_error (p);
516   return r;
517 }
518 
519 static int
plugin_pwrite(struct backend * b,void * handle,const void * buf,uint32_t count,uint64_t offset,uint32_t flags,int * err)520 plugin_pwrite (struct backend *b, void *handle,
521                const void *buf, uint32_t count, uint64_t offset, uint32_t flags,
522                int *err)
523 {
524   int r;
525   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
526   bool fua = flags & NBDKIT_FLAG_FUA;
527   bool need_flush = false;
528 
529   if (fua && backend_can_fua (b) != NBDKIT_FUA_NATIVE) {
530     flags &= ~NBDKIT_FLAG_FUA;
531     need_flush = true;
532   }
533   if (p->plugin.pwrite)
534     r = p->plugin.pwrite (handle, buf, count, offset, flags);
535   else if (p->plugin._pwrite_v1)
536     r = p->plugin._pwrite_v1 (handle, buf, count, offset);
537   else {
538     *err = EROFS;
539     return -1;
540   }
541   if (r != -1 && need_flush)
542     r = plugin_flush (b, handle, 0, err);
543   if (r == -1 && !*err)
544     *err = get_error (p);
545   return r;
546 }
547 
548 static int
plugin_trim(struct backend * b,void * handle,uint32_t count,uint64_t offset,uint32_t flags,int * err)549 plugin_trim (struct backend *b, void *handle,
550              uint32_t count, uint64_t offset, uint32_t flags, int *err)
551 {
552   int r;
553   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
554   bool fua = flags & NBDKIT_FLAG_FUA;
555   bool need_flush = false;
556 
557   if (fua && backend_can_fua (b) != NBDKIT_FUA_NATIVE) {
558     flags &= ~NBDKIT_FLAG_FUA;
559     need_flush = true;
560   }
561   if (p->plugin.trim)
562     r = p->plugin.trim (handle, count, offset, flags);
563   else if (p->plugin._trim_v1)
564     r = p->plugin._trim_v1 (handle, count, offset);
565   else {
566     *err = EINVAL;
567     return -1;
568   }
569   if (r != -1 && need_flush)
570     r = plugin_flush (b, handle, 0, err);
571   if (r == -1 && !*err)
572     *err = get_error (p);
573   return r;
574 }
575 
576 static int
plugin_zero(struct backend * b,void * handle,uint32_t count,uint64_t offset,uint32_t flags,int * err)577 plugin_zero (struct backend *b, void *handle,
578              uint32_t count, uint64_t offset, uint32_t flags, int *err)
579 {
580   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
581   int r = -1;
582   bool may_trim = flags & NBDKIT_FLAG_MAY_TRIM;
583   bool fua = flags & NBDKIT_FLAG_FUA;
584   bool fast_zero = flags & NBDKIT_FLAG_FAST_ZERO;
585   bool emulate = false;
586   bool need_flush = false;
587 
588   if (fua && backend_can_fua (b) != NBDKIT_FUA_NATIVE) {
589     flags &= ~NBDKIT_FLAG_FUA;
590     need_flush = true;
591   }
592   if (!count)
593     return 0;
594 
595   if (backend_can_zero (b) == NBDKIT_ZERO_NATIVE) {
596     errno = 0;
597     if (p->plugin.zero)
598       r = p->plugin.zero (handle, count, offset, flags);
599     else if (p->plugin._zero_v1) {
600       if (fast_zero) {
601         *err = EOPNOTSUPP;
602         return -1;
603       }
604       r = p->plugin._zero_v1 (handle, count, offset, may_trim);
605     }
606     else
607       emulate = true;
608     if (r == -1)
609       *err = emulate ? EOPNOTSUPP : get_error (p);
610     if (r == 0 || (*err != EOPNOTSUPP && *err != ENOTSUP))
611       goto done;
612   }
613 
614   if (fast_zero) {
615     assert (r == -1);
616     *err = EOPNOTSUPP;
617     goto done;
618   }
619 
620   assert (p->plugin.pwrite || p->plugin._pwrite_v1);
621   flags &= ~NBDKIT_FLAG_MAY_TRIM;
622   threadlocal_set_error (0);
623   *err = 0;
624 
625   while (count) {
626     /* Always contains zeroes, but we can't use const or else gcc 9
627      * will use .rodata instead of .bss and inflate the binary size.
628      */
629     static /* const */ char buf[MAX_REQUEST_SIZE];
630     uint32_t limit = MIN (count, sizeof buf);
631 
632     r = plugin_pwrite (b, handle, buf, limit, offset, flags, err);
633     if (r == -1)
634       break;
635     count -= limit;
636   }
637 
638  done:
639   if (r != -1 && need_flush)
640     r = plugin_flush (b, handle, 0, err);
641   if (r == -1 && !*err)
642     *err = get_error (p);
643   return r;
644 }
645 
646 static int
plugin_extents(struct backend * b,void * handle,uint32_t count,uint64_t offset,uint32_t flags,struct nbdkit_extents * extents,int * err)647 plugin_extents (struct backend *b, void *handle,
648                 uint32_t count, uint64_t offset, uint32_t flags,
649                 struct nbdkit_extents *extents, int *err)
650 {
651   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
652   int r;
653 
654   /* This should be true because plugin_can_extents checks it. */
655   assert (p->plugin.extents);
656 
657   r = p->plugin.extents (handle, count, offset, flags, extents);
658   if (r >= 0 && nbdkit_extents_count (extents) < 1) {
659     nbdkit_error ("extents: plugin must return at least one extent");
660     nbdkit_set_error (EINVAL);
661     r = -1;
662   }
663   if (r == -1)
664     *err = get_error (p);
665   return r;
666 }
667 
668 static int
plugin_cache(struct backend * b,void * handle,uint32_t count,uint64_t offset,uint32_t flags,int * err)669 plugin_cache (struct backend *b, void *handle,
670               uint32_t count, uint64_t offset, uint32_t flags,
671               int *err)
672 {
673   struct backend_plugin *p = container_of (b, struct backend_plugin, backend);
674   int r;
675 
676   /* A plugin may advertise caching but not provide .cache; in that
677    * case, caching is explicitly a no-op. */
678   if (!p->plugin.cache)
679     return 0;
680 
681   r = p->plugin.cache (handle, count, offset, flags);
682   if (r == -1)
683     *err = get_error (p);
684   return r;
685 }
686 
687 static struct backend plugin_functions = {
688   .free = plugin_free,
689   .thread_model = plugin_thread_model,
690   .plugin_name = plugin_name,
691   .usage = plugin_usage,
692   .version = plugin_version,
693   .dump_fields = plugin_dump_fields,
694   .config = plugin_config,
695   .config_complete = plugin_config_complete,
696   .magic_config_key = plugin_magic_config_key,
697   .get_ready = plugin_get_ready,
698   .preconnect = plugin_preconnect,
699   .open = plugin_open,
700   .prepare = plugin_prepare,
701   .finalize = plugin_finalize,
702   .close = plugin_close,
703   .get_size = plugin_get_size,
704   .can_write = plugin_can_write,
705   .can_flush = plugin_can_flush,
706   .is_rotational = plugin_is_rotational,
707   .can_trim = plugin_can_trim,
708   .can_zero = plugin_can_zero,
709   .can_fast_zero = plugin_can_fast_zero,
710   .can_extents = plugin_can_extents,
711   .can_fua = plugin_can_fua,
712   .can_multi_conn = plugin_can_multi_conn,
713   .can_cache = plugin_can_cache,
714   .pread = plugin_pread,
715   .pwrite = plugin_pwrite,
716   .flush = plugin_flush,
717   .trim = plugin_trim,
718   .zero = plugin_zero,
719   .extents = plugin_extents,
720   .cache = plugin_cache,
721 };
722 
723 /* Register and load a plugin. */
724 struct backend *
plugin_register(size_t index,const char * filename,void * dl,struct nbdkit_plugin * (* plugin_init)(void))725 plugin_register (size_t index, const char *filename,
726                  void *dl, struct nbdkit_plugin *(*plugin_init) (void))
727 {
728   struct backend_plugin *p;
729   const struct nbdkit_plugin *plugin;
730   size_t size;
731 
732   p = malloc (sizeof *p);
733   if (p == NULL) {
734     perror ("strdup");
735     exit (EXIT_FAILURE);
736   }
737 
738   p->backend = plugin_functions;
739   backend_init (&p->backend, NULL, index, filename, dl, "plugin");
740 
741   /* Call the initialization function which returns the address of the
742    * plugin's own 'struct nbdkit_plugin'.
743    */
744   plugin = plugin_init ();
745   if (!plugin) {
746     fprintf (stderr, "%s: %s: plugin registration function failed\n",
747              program_name, filename);
748     exit (EXIT_FAILURE);
749   }
750 
751   /* Check for incompatible future versions. */
752   if (plugin->_api_version < 0 || plugin->_api_version > 2) {
753     fprintf (stderr,
754              "%s: %s: plugin is incompatible with this version of nbdkit "
755              "(_api_version = %d)\n",
756              program_name, filename, plugin->_api_version);
757     exit (EXIT_FAILURE);
758   }
759 
760   /* Since the plugin might be much older than the current version of
761    * nbdkit, only copy up to the self-declared _struct_size of the
762    * plugin and zero out the rest.  If the plugin is much newer then
763    * we'll only call the "old" fields.
764    */
765   size = sizeof p->plugin;      /* our struct */
766   memset (&p->plugin, 0, size);
767   if (size > plugin->_struct_size)
768     size = plugin->_struct_size;
769   memcpy (&p->plugin, plugin, size);
770 
771   /* Check for the minimum fields which must exist in the
772    * plugin struct.
773    */
774   if (p->plugin.open == NULL) {
775     fprintf (stderr, "%s: %s: plugin must have a .open callback\n",
776              program_name, filename);
777     exit (EXIT_FAILURE);
778   }
779   if (p->plugin.get_size == NULL) {
780     fprintf (stderr, "%s: %s: plugin must have a .get_size callback\n",
781              program_name, filename);
782     exit (EXIT_FAILURE);
783   }
784   if (p->plugin.pread == NULL && p->plugin._pread_v1 == NULL) {
785     fprintf (stderr, "%s: %s: plugin must have a .pread callback\n",
786              program_name, filename);
787     exit (EXIT_FAILURE);
788   }
789 
790   backend_load (&p->backend, p->plugin.name, p->plugin.load);
791 
792   return (struct backend *) p;
793 }
794