1nbdkit-python-plugin(3) nbdkit nbdkit-python-plugin(3)
2
3
4
6 nbdkit-python-plugin - nbdkit python plugin
7
9 nbdkit python /path/to/plugin.py [arguments...]
10
12 "nbdkit-python-plugin" is an embedded Python interpreter for nbdkit(1),
13 allowing you to write nbdkit plugins in Python.
14
15 Broadly speaking, Python nbdkit plugins work like C ones, so you should
16 read nbdkit-plugin(3) first.
17
18 PYTHON 2 AND PYTHON 3
19 The Python plugin has to be compiled for either Python 2 or Python 3
20 when building nbdkit. You can set the "PYTHON" environment variable to
21 the desired interpreter, otherwise nbdkit will use the interpreter
22 called "python" on the current $PATH. For example:
23
24 PYTHON=/usr/bin/python3 ./configure
25
26 USING A PYTHON NBDKIT PLUGIN
27 Assuming you have a Python script which is an nbdkit plugin, you run it
28 like this:
29
30 nbdkit python /path/to/plugin.py
31
32 You may have to add further "key=value" arguments to the command line.
33 Read the Python script to see if it requires any.
34
36 There is an example Python nbdkit plugin called "example.py" which
37 ships with the nbdkit source.
38
39 To write a Python nbdkit plugin, you create a Python file which
40 contains at least the following required functions (in the top level
41 "__main__" module):
42
43 def open(readonly):
44 # see below
45 def get_size(h):
46 # see below
47 def pread(h, count, offset):
48 # see below
49
50 Note that the subroutines must have those literal names (like "open"),
51 because the C part looks up and calls those functions directly. You
52 may want to include documentation and globals (eg. for storing global
53 state). Any other top level statements are run when the script is
54 loaded, just like ordinary Python.
55
56 EXECUTABLE SCRIPT
57 If you want you can make the script executable and include a "shebang"
58 at the top:
59
60 #!/usr/sbin/nbdkit python
61
62 See also "Shebang scripts" in nbdkit(1).
63
64 These scripts can also be installed in the $plugindir. See "WRITING
65 PLUGINS IN OTHER PROGRAMMING LANGUAGES" in nbdkit-plugin(3).
66
67 METHODS
68 Your script may use "import nbdkit" to have access to the following
69 methods in the "nbdkit" module:
70
71 nbdkit.set_error(I<err>)
72
73 Record "err" as the reason you are about to throw an exception. "err"
74 should correspond to usual errno values, where it may help to "import
75 errno".
76
77 EXCEPTIONS
78 Python callbacks should throw exceptions to indicate errors. Remember
79 to use "nbdkit.set_error" if you need to control which error is sent
80 back to the client; if omitted, the client will see an error of "EIO".
81
82 PYTHON CALLBACKS
83 This just documents the arguments to the callbacks in Python, and any
84 way that they differ from the C callbacks. In all other respects they
85 work the same way as the C callbacks, so you should go and read
86 nbdkit-plugin(3).
87
88 "dump_plugin"
89 (Optional)
90
91 There are no arguments or return value.
92
93 "config"
94 (Optional)
95
96 def config(key, value):
97 # no return value
98
99 "config_complete"
100 (Optional)
101
102 There are no arguments or return value.
103
104 "open"
105 (Required)
106
107 def open(readonly):
108 # return handle
109
110 You can return any non-NULL Python value as the handle. It is
111 passed back in subsequent calls.
112
113 "close"
114 (Optional)
115
116 def close(h):
117 # no return value
118
119 After "close" returns, the reference count of the handle is
120 decremented in the C part, which usually means that the handle and
121 its contents will be garbage collected.
122
123 "get_size"
124 (Required)
125
126 def get_size(h):
127 # return the size of the disk
128
129 "can_write"
130 (Optional)
131
132 def can_write(h):
133 # return a boolean
134
135 "can_flush"
136 (Optional)
137
138 def can_flush(h):
139 # return a boolean
140
141 "is_rotational"
142 (Optional)
143
144 def is_rotational(h):
145 # return a boolean
146
147 "can_trim"
148 (Optional)
149
150 def can_trim(h):
151 # return a boolean
152
153 "pread"
154 (Required)
155
156 def pread(h, count, offset):
157 # construct a bytearray of length count bytes and return it
158
159 The body of your "pread" function should construct a buffer of
160 length (at least) "count" bytes. You should read "count" bytes
161 from the disk starting at "offset".
162
163 NBD only supports whole reads, so your function should try to read
164 the whole region (perhaps requiring a loop). If the read fails or
165 is partial, your function should throw an exception, optionally
166 using "nbdkit.set_error" first.
167
168 "pwrite"
169 (Optional)
170
171 def pwrite(h, buf, offset):
172 length = len (buf)
173 # no return value
174
175 The body of your "pwrite" function should write the "buf" string to
176 the disk. You should write "count" bytes to the disk starting at
177 "offset".
178
179 NBD only supports whole writes, so your function should try to
180 write the whole region (perhaps requiring a loop). If the write
181 fails or is partial, your function should throw an exception,
182 optionally using "nbdkit.set_error" first.
183
184 "flush"
185 (Optional)
186
187 def flush(h):
188 # no return value
189
190 The body of your "flush" function should do a sync(2) or
191 fdatasync(2) or equivalent on the backing store.
192
193 If the flush fails, your function should throw an exception,
194 optionally using "nbdkit.set_error" first.
195
196 "trim"
197 (Optional)
198
199 def trim(h, count, offset):
200 # no return value
201
202 The body of your "trim" function should "punch a hole" in the
203 backing store. If the trim fails, your function should throw an
204 exception, optionally using "nbdkit.set_error" first.
205
206 "zero"
207 (Optional)
208
209 def zero(h, count, offset, may_trim):
210 # no return value
211
212 The body of your "zero" function should ensure that "count" bytes
213 of the disk, starting at "offset", will read back as zero. If
214 "may_trim" is true, the operation may be optimized as a trim as
215 long as subsequent reads see zeroes.
216
217 NBD only supports whole writes, so your function should try to
218 write the whole region (perhaps requiring a loop). If the write
219 fails or is partial, your function should throw an exception,
220 optionally using "nbdkit.set_error" first. In particular, if you
221 would like to automatically fall back to "pwrite" (perhaps because
222 there is nothing to optimize if "may_trim" is false), use
223 "nbdkit.set_error(errno.EOPNOTSUPP)".
224
225 MISSING CALLBACKS
226 Missing: "load" and "unload"
227 These are not needed because you can just use ordinary Python
228 constructs.
229
230 Missing: "name", "version", "longname", "description", "config_help"
231 These are not yet supported.
232
233 THREADS
234 The thread model for Python callbacks currently cannot be set from
235 Python. It is hard-coded in the C part to
236 "NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS". This may change or be
237 settable in future.
238
240 nbdkit(1), nbdkit-plugin(3), python(1).
241
243 Richard W.M. Jones
244
246 Copyright (C) 2013-2014 Red Hat Inc.
247
249 Redistribution and use in source and binary forms, with or without
250 modification, are permitted provided that the following conditions are
251 met:
252
253 · Redistributions of source code must retain the above copyright
254 notice, this list of conditions and the following disclaimer.
255
256 · Redistributions in binary form must reproduce the above copyright
257 notice, this list of conditions and the following disclaimer in the
258 documentation and/or other materials provided with the
259 distribution.
260
261 · Neither the name of Red Hat nor the names of its contributors may
262 be used to endorse or promote products derived from this software
263 without specific prior written permission.
264
265 THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND ANY
266 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
267 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
268 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR CONTRIBUTORS BE
269 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
270 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
271 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
272 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
273 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
274 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
275 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
276
277
278
279nbdkit 2017-12-06 nbdkit-python-plugin(3)