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

NAME

6       nbdkit-tcl-plugin - nbdkit Tcl plugin
7

SYNOPSIS

9        nbdkit tcl /path/to/plugin.tcl [arguments...]
10

DESCRIPTION

12       "nbdkit-tcl-plugin" is an embedded Tcl interpreter for nbdkit(1),
13       allowing you to write nbdkit plugins in Tcl.
14
15   If you have been given an nbdkit Tcl plugin
16       Assuming you have a Tcl script which is an nbdkit plugin, you run it
17       like this:
18
19        nbdkit tcl /path/to/plugin.tcl
20
21       You may have to add further "key=value" arguments to the command line.
22       Read the Tcl script to see if it requires any.
23

WRITING A TCL NBDKIT PLUGIN

25       For an example plugin written in Tcl, see:
26       https://gitlab.com/nbdkit/nbdkit/blob/master/plugins/tcl/example.tcl
27
28       Broadly speaking, Tcl nbdkit plugins work like C ones, so you should
29       read nbdkit-plugin(3) first.
30
31       To write a Tcl nbdkit plugin, you create a Tcl file which contains at
32       least the following required subroutines:
33
34        proc plugin_open {readonly} {
35            # see below
36            return $h
37        }
38        proc get_size {h} {
39            # see below
40            return $size
41        }
42        proc pread {h count offset} {
43            # see below
44            return $buf
45        }
46
47       Note that the subroutines must have those literal names (like
48       "plugin_open"), because the C part looks up and calls those functions
49       directly.  You may want to include documentation and globals (eg. for
50       storing global state).  Also any top-level statements are run when
51       nbdkit starts up.
52
53   Executable script
54       If you want you can make the script executable and include a "shebang"
55       at the top:
56
57        #!/usr/sbin/nbdkit tcl
58
59       See also "Shebang scripts" in nbdkit(1).
60
61       These scripts can also be installed in the $plugindir.  See "WRITING
62       PLUGINS IN OTHER PROGRAMMING LANGUAGES" in nbdkit-plugin(3).
63
64   Exceptions
65       Tcl plugin methods can indicate an error by calling "error".
66
67   Binary data
68       When writing your Tcl script, be careful to ensure that it is
69       processing binary data (not Unicode).  If reading and writing from
70       local disk files, you should use:
71
72        fconfigure $fp -translation binary
73
74       Note also that the value returned from "pread" should convertible to a
75       byte array, and the buffer passed to "pwrite" is also a byte array.
76
77       See also: https://wiki.tcl.tk/1180
78
79   Tcl callbacks
80       This just documents the arguments to the callbacks in Tcl, and any way
81       that they differ from the C callbacks.  In all other respects they work
82       the same way as the C callbacks, so you should go and read
83       nbdkit-plugin(3).
84
85       "dump_plugin"
86           (Optional)
87
88           There are no arguments or return value.
89
90       "config"
91           (Optional)
92
93            proc config {key value} {
94                # No return value.
95            }
96
97       "config_complete"
98           (Optional)
99
100           There are no arguments or return value.
101
102       "plugin_open"
103           (Required)
104
105            proc plugin_open {readonly} {
106                set handle ...
107                return $handle
108            }
109
110           The "readonly" flag is a boolean.
111
112           You can return any Tcl string or object as the handle.  It is
113           passed back to subsequent calls.
114
115       "plugin_close"
116           (Optional)
117
118            proc plugin_close {h} {
119                # No return value
120            }
121
122           After "plugin_close" returns, the reference count of the handle is
123           decremented in the C part, which usually means that the handle and
124           its contents will be garbage collected.
125
126       "get_size"
127           (Required)
128
129            proc get_size {h} {
130                set size .. the size of the disk ..
131                return $size
132            }
133
134           This returns the size of the disk.
135
136       "can_write"
137           (Optional)
138
139            proc can_write {h} {
140                return $bool
141            }
142
143           Return a boolean indicating whether the disk is writable.
144
145       "can_flush"
146           (Optional)
147
148            proc can_flush {h} {
149                return $bool
150            }
151
152           Return a boolean indicating whether flush can be performed.
153
154       "is_rotational"
155           (Optional)
156
157            proc is_rotational {h} {
158                return $bool
159            }
160
161           Return a boolean indicating whether the disk is rotational.
162
163       "can_trim"
164           (Optional)
165
166            proc can_trim {h} {
167                return $bool
168            }
169
170           Return a boolean indicating whether trim/discard can be performed.
171
172       "pread"
173           (Required)
174
175            proc pread {h count offset} {
176               # Construct a buffer of length $count bytes and return it.
177               return $buf
178            }
179
180           The body of your "pread" function should construct a buffer of
181           length (at least) $count bytes.  You should read $count bytes from
182           the disk starting at $offset.
183
184           NBD only supports whole reads, so your function should try to read
185           the whole region (perhaps requiring a loop).  If the read fails or
186           is partial, your function should call "error".
187
188       "pwrite"
189           (Optional)
190
191            proc pwrite {h buf offset} {
192               # No return value
193            }
194
195           The body of your "pwrite" function should write the $buf string to
196           the disk.  You should write $count bytes to the disk starting at
197           $offset.
198
199           NBD only supports whole writes, so your function should try to
200           write the whole region (perhaps requiring a loop).  If the write
201           fails or is partial, your function should call "error".
202
203       "plugin_flush"
204           (Optional)
205
206            proc plugin_flush {h} {
207                # No return value
208            }
209
210           The body of your "plugin_flush" function should do a sync(2) or
211           fdatasync(2) or equivalent on the backing store.
212
213       "trim"
214           (Optional)
215
216            proc trim {h count offset} {
217                # No return value
218            }
219
220           The body of your "trim" function should "punch a hole" in the
221           backing store.
222
223       "zero"
224           (Optional)
225
226            proc zero {h count offset may_trim} {
227               # No return value
228            }
229
230           The body of your "zero" function should ensure that $count bytes of
231           the disk, starting at $offset, will read back as zero.  If
232           $may_trim is true, the operation may be optimized as a trim as long
233           as subsequent reads see zeroes.
234
235           NBD only supports whole writes, so your function should try to
236           write the whole region (perhaps requiring a loop).  If the write
237           fails or is partial, your function should call "error".
238
239   Missing callbacks
240       Missing: "load", "unload", "name", "version", "longname",
241       "description", "config_help", "can_zero", "can_fua", "can_cache",
242       "cache"
243           These are not yet supported.
244
245   Threads
246       The thread model for Tcl callbacks currently cannot be set from Tcl.
247       It is hard-coded in the C part to
248       "NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS".  This may change or be
249       settable in future.
250

FILES

252       $plugindir/nbdkit-tcl-plugin.so
253           The plugin.
254
255           Use "nbdkit --dump-config" to find the location of $plugindir.
256

VERSION

258       "nbdkit-tcl-plugin" first appeared in nbdkit 1.4.
259

SEE ALSO

261       nbdkit(1), nbdkit-plugin(3).
262

AUTHORS

264       Richard W.M. Jones
265
267       Copyright (C) 2018 Red Hat Inc.
268

LICENSE

270       Redistribution and use in source and binary forms, with or without
271       modification, are permitted provided that the following conditions are
272       met:
273
274       •   Redistributions of source code must retain the above copyright
275           notice, this list of conditions and the following disclaimer.
276
277       •   Redistributions in binary form must reproduce the above copyright
278           notice, this list of conditions and the following disclaimer in the
279           documentation and/or other materials provided with the
280           distribution.
281
282       •   Neither the name of Red Hat nor the names of its contributors may
283           be used to endorse or promote products derived from this software
284           without specific prior written permission.
285
286       THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND ANY
287       EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
288       IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
289       PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR CONTRIBUTORS BE
290       LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
291       CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
292       SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
293       BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
294       WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
295       OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
296       ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
297
298
299
300nbdkit-1.32.5                     2023-01-03              nbdkit-tcl-plugin(3)
Impressum