1nbdkit-sh-plugin(3)                 NBDKIT                 nbdkit-sh-plugin(3)
2
3
4

NAME

6       nbdkit-sh-plugin - nbdkit shell, script or executable plugin
7

SYNOPSIS

9        nbdkit sh /path/to/script [arguments...]
10
11        nbdkit sh - <<'EOF'
12        ... shell script ...
13        EOF
14

DESCRIPTION

16       "nbdkit-sh-plugin" allows you to write plugins for nbdkit(1) using
17       arbitrary scripting languages, including shells like bash(1), dash(1),
18       csh(1), zsh(1) etc., other scripting environments, or any executable.
19       Note if you want to use an established scripting language like Perl or
20       Python, then nbdkit has specific plugins to handle those languages and
21       those will be more efficient (see nbdkit(1) for a complete list).
22
23   If you have been given an nbdkit sh plugin
24       Assuming you have a shell script which is an nbdkit plugin, you run it
25       like this:
26
27        nbdkit sh /path/to/script
28
29       You may have to add further "key=value" arguments to the command line.
30       The script must be executable ("chmod +x").
31
32   Inline shell scripts
33       It is also possible to write a shell script plugin "inline" using "-"
34       as the name of the script, like this:
35
36        nbdkit sh - <<'EOF'
37          case "$1" in
38            get_size) echo 1M ;;
39            pread) dd if=/dev/zero count=$3 iflag=count_bytes ;;
40            *) exit 2 ;;
41          esac
42        EOF
43
44       By default the inline script runs under /bin/sh.  You can add a shebang
45       ("#!") to use other scripting languages.
46

WRITING AN NBDKIT SH PLUGIN

48       For an example plugin written in Bash, see:
49       https://github.com/libguestfs/nbdkit/blob/master/plugins/sh/example.sh
50
51       Broadly speaking, nbdkit shell plugins work like C ones, so you should
52       read nbdkit-plugin(3) first.
53
54   Programming model
55       This plugin has a simple programming model: For every plugin method
56       that needs to be called, the external script is invoked with parameters
57       describing the method and its arguments.  The first parameter is always
58       the method name.  For example:
59
60        /path/to/script config file disk.img
61                          │      │   │
62                          │      │   └─ value ($3)
63                          │      └── key ($2)
64                      method ($1)
65
66        /path/to/script pread <handle> <count> <offset>
67                          │       │       │       │
68                          │       │       │       └─ offset in bytes ($4)
69                          │       │       └── request size in bytes ($3)
70                      method ($1) └── handle ($2) ─ see "Handles" below
71
72   Exit codes
73       The script should exit with specific exit codes:
74
75       0   The method was executed successfully.
76
77       1 and 8-127
78           There was an error.  The script may print on stderr an errno and a
79           message, for example:
80
81            ENOSPC Out of space
82
83           If the script doesn't print anything or the output cannot be parsed
84           then nbdkit assumes error "EIO".
85
86       2   The requested method is not supported by the script.
87
88       3   For methods which return booleans, this code indicates false.
89
90       4, 5, 6, 7
91           These exit codes are reserved for future use.
92
93   Temporary directory
94       A fresh script is invoked for each method call (ie. scripts are
95       stateless), so if the script needs to store state it has to store it
96       somewhere in the filesystem in a format and location which is left up
97       to the author of the script.
98
99       However nbdkit helps by creating a randomly named, empty directory for
100       the script.  This directory persists for the lifetime of nbdkit and is
101       deleted when nbdkit exits.  The name of the directory is passed to each
102       script invocation in the $tmpdir environment variable.
103
104   Handles
105       Handles are arbitrary strings, but it is best to limit them to short
106       alphanumeric strings.
107
108       Per-connection state
109
110       The temporary directory described above can be used for state for the
111       lifetime of the nbdkit instance (across multiple connections).  If you
112       want to store state per connection then one way to do it is to create a
113       randomly named subdirectory under the temporary directory:
114
115        case "$1" in
116          ...
117          open)
118            mktemp -d $tmpdir/handle-XXXXXX ;;
119
120       The handle will be the subdirectory name, returned to the script as $2
121       in all connected calls (eg. "pread", "get_size").  You can delete the
122       subdirectory explicitly in "close":
123
124        case "$1" in
125          ...
126          close)
127            rm -rf "$2" ;;
128
129       or rely on nbdkit deleting the whole temporary directory including all
130       per-handle subdirectories when it exits.
131
132   Methods
133       This just documents the arguments to the script corresponding to each
134       plugin method, and any way that they differ from the C callbacks.  In
135       all other respects they work the same way as the C callbacks, so you
136       should go and read nbdkit-plugin(3).
137
138       "load"
139            /path/to/script load
140
141       "unload"
142            /path/to/script unload
143
144           This is called just before nbdkit exits.  Errors from this method
145           are ignored.
146
147       "dump_plugin"
148            /path/to/script dump_plugin
149
150       "config"
151            /path/to/script config <key> <value>
152
153       "config_complete"
154            /path/to/script config_complete
155
156       "open"
157            /path/to/script open <readonly>
158
159           The "readonly" parameter will be "true" or "false".
160
161           On success this should print the handle (any string) on stdout and
162           exit with code 0.  If the handle ends with a newline character then
163           the newline is removed.
164
165           Unlike C plugins, this method is not required.  If omitted then the
166           handle will be "" (empty string).
167
168       "close"
169            /path/to/script close <handle>
170
171       "get_size"
172            /path/to/script get_size <handle>
173
174           The script should print the size of the disk image on stdout.  You
175           can print the size in bytes, or use any format understood by
176           "nbdkit_parse_size" such as "1M" (see "PARSING SIZE PARAMETERS" in
177           nbdkit-plugin(3)).
178
179           This method is required.
180
181       "can_write"
182       "can_flush"
183       "can_trim"
184       "can_zero"
185       "can_extents"
186           Unlike in other languages, you must provide the "can_*" methods
187           otherwise they are assumed to all return false and your "pwrite",
188           "flush", "trim", "zero" and "extents" methods will never be called.
189           The reason for this is obscure: In other languages we can detect if
190           (eg) a "pwrite" method is defined and synthesize an appropriate
191           response if no actual "can_write" method is defined.  However
192           detecting if methods are present without running them is not
193           possible with this plugin.
194
195            /path/to/script can_write <handle>
196            /path/to/script can_flush <handle>
197            /path/to/script can_trim <handle>
198            /path/to/script can_zero <handle>
199            /path/to/script can_extents <handle>
200
201           The script should exit with code 0 for true or code 3 for false.
202
203       "is_rotational"
204            /path/to/script is_rotational <handle>
205
206           The script should exit with code 0 for true or code 3 for false.
207
208       "can_fua"
209            /path/to/script can_fua <handle>
210
211           This controls Forced Unit Access (FUA) behaviour of the core
212           server.
213
214           Unlike the other "can_*" callbacks, this one is not a boolean.  It
215           must print either "none", "emulate" or "native" to stdout.  The
216           meaning of these is described in nbdkit-plugin(3).
217
218       "can_multi_conn"
219            /path/to/script can_multi_conn <handle>
220
221           The script should exit with code 0 for true or code 3 for false.
222
223       "pread"
224            /path/to/script pread <handle> <count> <offset>
225
226           The script should print the requested binary data on stdout.
227           Exactly "count" bytes must be printed.
228
229           This method is required.
230
231       "pwrite"
232            /path/to/script pwrite <handle> <count> <offset> <flags>
233
234           The script should read the binary data to be written from stdin.
235
236           The "flags" parameter can be an empty string or "fua".  In the
237           future, a comma-separated list of flags may be present.
238
239           Unlike in other languages, if you provide a "pwrite" method you
240           must also provide a "can_write" method which exits with code 0
241           (true).
242
243       "flush"
244            /path/to/script flush <handle>
245
246           Unlike in other languages, if you provide a "flush" method you must
247           also provide a "can_flush" method which exits with code 0 (true).
248
249       "trim"
250            /path/to/script trim <handle> <count> <offset> <flags>
251
252           The "flags" parameter can be an empty string or "fua".  In the
253           future, a comma-separated list of flags may be present.
254
255           Unlike in other languages, if you provide a "trim" method you must
256           also provide a "can_trim" method which exits with code 0 (true).
257
258       "zero"
259            /path/to/script zero <handle> <count> <offset> <flags>
260
261           The "flags" parameter can be an empty string or a comma-separated
262           list of the flags: "fua" and "may_trim" (eg. "", "fua",
263           "fua,may_trim" are all possible values).
264
265           Unlike in other languages, if you provide a "zero" method you must
266           also provide a "can_zero" method which exits with code 0 (true).
267
268       "extents"
269            /path/to/script extents <handle> <count> <offset> <flags>
270
271           The "flags" parameter can be an empty string or "req_one".
272
273           This must print, one per line on stdout, a list of one or more
274           extents in the format:
275
276            offset length type
277
278           which correspond to the inputs of the C "nbdkit_add_extent"
279           function (see nbdkit-plugin(3)).  The "offset" and "length" fields
280           may use any format understood by "nbdkit_parse_size".  The optional
281           "type" field may be an integer, missing (same as 0), or a comma-
282           separated list of the words "hole" and "zero".  An example of a
283           valid set of extents covering a "10M" disk where the first megabyte
284           only is allocated data:
285
286            0  1M
287            1M 9M  hole,zero
288
289           Unlike in other languages, if you provide an "extents" method you
290           must also provide a "can_extents" method which exits with code 0
291           (true).
292
293   Missing callbacks
294       Missing: "name", "version", "longname", "description", "config_help"
295           These are not yet supported.
296
297   Threads
298       The thread model for scripts currently cannot be set from this plugin.
299       It is hard-coded in the C part to
300       "NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS".  This may change or be
301       settable in future.
302

SEE ALSO

304       nbdkit(1), nbdkit-plugin(3).
305

AUTHORS

307       Richard W.M. Jones
308
310       Copyright (C) 2018 Red Hat Inc.
311

LICENSE

313       Redistribution and use in source and binary forms, with or without
314       modification, are permitted provided that the following conditions are
315       met:
316
317       ·   Redistributions of source code must retain the above copyright
318           notice, this list of conditions and the following disclaimer.
319
320       ·   Redistributions in binary form must reproduce the above copyright
321           notice, this list of conditions and the following disclaimer in the
322           documentation and/or other materials provided with the
323           distribution.
324
325       ·   Neither the name of Red Hat nor the names of its contributors may
326           be used to endorse or promote products derived from this software
327           without specific prior written permission.
328
329       THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND ANY
330       EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
331       IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
332       PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR CONTRIBUTORS BE
333       LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
334       CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
335       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
336       BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
337       WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
338       OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
339       ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
340
341
342
343nbdkit-1.12.3                     2019-05-21               nbdkit-sh-plugin(3)
Impressum