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 /* See nbdkit-plugin(3) for documentation and how to write a plugin. */
34 
35 #ifndef NBDKIT_PLUGIN_H
36 #define NBDKIT_PLUGIN_H
37 
38 #include <nbdkit-common.h>
39 
40 #ifdef __cplusplus
41 extern "C" {
42 #endif
43 
44 /* By default, a plugin gets API version 1; but you may request
45  * version 2 prior to including this header */
46 #ifndef NBDKIT_API_VERSION
47 #define NBDKIT_API_VERSION                            1
48 #elif (NBDKIT_API_VERSION - 0) < 1 || NBDKIT_API_VERSION > 2
49 #error Unsupported API version
50 #endif
51 
52 struct nbdkit_plugin {
53   /* Do not set these fields directly; use NBDKIT_REGISTER_PLUGIN.
54    * They exist so that we can support plugins compiled against
55    * one version of the header with a runtime compiled against a
56    * different version with more (or fewer) fields.
57    */
58   uint64_t _struct_size;
59   int _api_version;
60   int _thread_model;
61 
62   /* Plugins are responsible for these fields; see the documentation
63    * for semantics, and which fields are optional. New fields will
64    * only be added at the end of the struct.
65    */
66   const char *name;
67   const char *longname;
68   const char *version;
69   const char *description;
70 
71   void (*load) (void);
72   void (*unload) (void);
73 
74   int (*config) (const char *key, const char *value);
75   int (*config_complete) (void);
76   const char *config_help;
77 
78   void * (*open) (int readonly);
79   void (*close) (void *handle);
80 
81   int64_t (*get_size) (void *handle);
82 
83   int (*can_write) (void *handle);
84   int (*can_flush) (void *handle);
85   int (*is_rotational) (void *handle);
86   int (*can_trim) (void *handle);
87 
88 #if NBDKIT_API_VERSION == 1
89   int (*pread) (void *handle, void *buf, uint32_t count, uint64_t offset);
90   int (*pwrite) (void *handle, const void *buf, uint32_t count, uint64_t offset);
91   int (*flush) (void *handle);
92   int (*trim) (void *handle, uint32_t count, uint64_t offset);
93   int (*zero) (void *handle, uint32_t count, uint64_t offset, int may_trim);
94 #else
95   int (*_pread_v1) (void *, void *, uint32_t, uint64_t);
96   int (*_pwrite_v1) (void *, const void *, uint32_t, uint64_t);
97   int (*_flush_v1) (void *);
98   int (*_trim_v1) (void *, uint32_t, uint64_t);
99   int (*_zero_v1) (void *, uint32_t, uint64_t, int);
100 #endif
101 
102   int errno_is_preserved;
103 
104   void (*dump_plugin) (void);
105 
106   int (*can_zero) (void *handle);
107   int (*can_fua) (void *handle);
108 #if NBDKIT_API_VERSION == 1
109   int (*_unused1) (void *, void *, uint32_t, uint64_t, uint32_t);
110   int (*_unused2) (void *, const void *, uint32_t, uint64_t, uint32_t);
111   int (*_unused3) (void *, uint32_t);
112   int (*_unused4) (void *, uint32_t, uint64_t, uint32_t);
113   int (*_unused5) (void *, uint32_t, uint64_t, uint32_t);
114 #else
115   int (*pread) (void *handle, void *buf, uint32_t count, uint64_t offset,
116                 uint32_t flags);
117   int (*pwrite) (void *handle, const void *buf, uint32_t count,
118                  uint64_t offset, uint32_t flags);
119   int (*flush) (void *handle, uint32_t flags);
120   int (*trim) (void *handle, uint32_t count, uint64_t offset, uint32_t flags);
121   int (*zero) (void *handle, uint32_t count, uint64_t offset, uint32_t flags);
122 #endif
123 
124   const char *magic_config_key;
125 
126   int (*can_multi_conn) (void *handle);
127 
128   int (*can_extents) (void *handle);
129   int (*extents) (void *handle, uint32_t count, uint64_t offset, uint32_t flags,
130                   struct nbdkit_extents *extents);
131   int (*can_cache) (void *handle);
132   int (*cache) (void *handle, uint32_t count, uint64_t offset, uint32_t flags);
133 
134   int (*thread_model) (void);
135 
136   int (*can_fast_zero) (void *handle);
137 
138   int (*preconnect) (int readonly);
139 
140   int (*get_ready) (void);
141 };
142 
143 extern void nbdkit_set_error (int err);
144 
145 #define NBDKIT_REGISTER_PLUGIN(plugin)                                  \
146   NBDKIT_CXX_LANG_C                                                     \
147   struct nbdkit_plugin *                                                \
148   plugin_init (void)                                                    \
149   {                                                                     \
150     (plugin)._struct_size = sizeof (plugin);                            \
151     (plugin)._api_version = NBDKIT_API_VERSION;                         \
152     (plugin)._thread_model = THREAD_MODEL;                              \
153     return &(plugin);                                                   \
154   }
155 
156 #ifdef __cplusplus
157 }
158 #endif
159 
160 #endif /* NBDKIT_PLUGIN_H */
161