3 nbdkit-ruby-plugin - nbdkit ruby plugin
7 nbdkit ruby /path/to/plugin.rb [arguments...]
11 The Ruby language is fundamentally broken when it comes to embedding
12 in a program which uses pthreads. This means you may see random
13 "stack overflows" when using this plugin on some versions of Ruby but
16 For the whole sorry saga, see:
17 L<https://redmine.ruby-lang.org/issues/2294>
21 C<nbdkit-ruby-plugin> is an embedded Ruby interpreter for
22 L<nbdkit(1)>, allowing you to write nbdkit plugins in Ruby.
24 =head2 If you have been given an nbdkit Ruby plugin
26 Assuming you have a Ruby script which is an nbdkit plugin, you run it
29 nbdkit ruby /path/to/ruby.rb
31 You may have to add further C<key=value> arguments to the command
32 line. Read the Ruby script to see if it requires any.
34 =head1 WRITING A RUBY NBDKIT PLUGIN
36 For an example plugin written in Ruby, see:
37 L<https://gitlab.com/nbdkit/nbdkit/blob/master/plugins/ruby/example.rb>
39 Broadly speaking, Ruby nbdkit plugins work like C ones, so you should
40 read L<nbdkit-plugin(3)> first.
42 To write a Ruby nbdkit plugin, you create a Ruby file which
43 contains at least the following required functions:
51 def pread(h, count, offset)
55 Note that the subroutines must have those literal names (like C<open>),
56 because the C part looks up and calls those functions directly. You
57 may want to include documentation and globals (eg. for storing global
58 state). Any other top level statements are run when the script is
59 loaded, just like ordinary Ruby.
61 =head2 Executable script
63 If you want you can make the script executable and include a "shebang"
66 #!/usr/sbin/nbdkit ruby
68 See also L<nbdkit(1)/Shebang scripts>.
70 These scripts can also be installed in the C<$plugindir>. See
71 L<nbdkit-plugin(3)/WRITING PLUGINS IN OTHER PROGRAMMING LANGUAGES>.
75 Your script has access to the C<Nbdkit> module, with the following
80 Record C<err> as the reason you are about to raise an
81 exception. C<err> should either be a class that defines an C<Errno>
82 constant (all of the subclasses of C<SystemCallError> in module
83 C<Errno> have this property), an object that defines an C<errno>
84 method with no arguments (all instances of C<SystemCallError> have
85 this property), or an integer value corresponding to the usual errno
90 Ruby callbacks should throw exceptions to indicate errors. Remember
91 to use C<Nbdkit.set_error> if you need to control which error is sent
92 back to the client; if omitted, the client will see an error of C<EIO>.
96 This just documents the arguments to the callbacks in Ruby, and any
97 way that they differ from the C callbacks. In all other respects they
98 work the same way as the C callbacks, so you should go and read
107 There are no arguments or return value.
113 def config(key, value)
117 =item C<config_complete>
121 There are no arguments or return value.
131 You can return any non-nil Ruby value as the handle. It is passed
132 back in subsequent calls.
147 # return the size of the disk
166 =item C<is_rotational>
186 def pread(h, count, offset)
187 # construct a string of length count bytes and return it
190 The body of your C<pread> function should construct a string of length
191 (at least) C<count> bytes. You should read C<count> bytes from the
192 disk starting at C<offset>.
194 NBD only supports whole reads, so your function should try to read
195 the whole region (perhaps requiring a loop). If the read fails or
196 is partial, your function should throw an exception, optionally using
197 C<Nbdkit.set_error> first.
203 def pwrite(h, buf, offset)
208 The body of your C<pwrite> function should write the C<buf> string to
209 the disk. You should write C<count> bytes to the disk starting at
212 NBD only supports whole writes, so your function should try to
213 write the whole region (perhaps requiring a loop). If the write
214 fails or is partial, your function should throw an exception, optionally
215 using C<Nbdkit.set_error> first.
225 The body of your C<flush> function should do a L<sync(2)> or
226 L<fdatasync(2)> or equivalent on the backing store.
228 If the flush fails, your function should throw an exception, optionally
229 using C<Nbdkit.set_error> first.
235 def trim(h, count, offset)
239 The body of your C<trim> function should "punch a hole" in the
240 backing store. If the trim fails, your function should throw an
241 exception, optionally using C<Nbdkit.set_error> first.
247 def zero(h, count, offset, may_trim)
250 The body of your C<zero> function should ensure that C<count> bytes
251 of the disk, starting at C<offset>, will read back as zero. If
252 C<may_trim> is true, the operation may be optimized as a trim as long
253 as subsequent reads see zeroes.
255 NBD only supports whole writes, so your function should try to
256 write the whole region (perhaps requiring a loop). If the write
257 fails or is partial, your function should throw an exception,
258 optionally using C<Nbdkit.set_error> first. In particular, if
259 you would like to automatically fall back to C<pwrite> (perhaps
260 because there is nothing to optimize if C<may_trim> is false),
261 use C<Nbdkit.set_error(Errno::EOPNOTSUPP)>.
265 =head2 Missing callbacks
269 =item Missing: C<load> and C<unload>
271 These are not needed because you can just use ordinary Ruby
274 =item Missing: C<name>, C<version>, C<longname>, C<description>,
275 C<config_help>, C<can_fua>, C<can_cache>, C<cache>
277 These are not yet supported.
283 The thread model for Ruby callbacks currently cannot be set from Ruby.
284 It is hard-coded in the C part to
285 C<NBDKIT_THREAD_MODEL_SERIALIZE_ALL_REQUESTS>. This may change or be
292 =item F<$plugindir/nbdkit-ruby-plugin.so>
296 Use C<nbdkit --dump-config> to find the location of C<$plugindir>.
302 C<nbdkit-ruby-plugin> first appeared in nbdkit 1.2.