Update Red Hat Copyright Notices
[nbdkit.git] / plugins / ruby / nbdkit-ruby-plugin.pod
blobd33f97cfd90f8c4820c0ce9c7b0ef779c7f22707
1 =head1 NAME
3 nbdkit-ruby-plugin - nbdkit ruby plugin
5 =head1 SYNOPSIS
7  nbdkit ruby /path/to/plugin.rb [arguments...]
9 =head1 WARNING
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
14 not others.
16 For the whole sorry saga, see:
17 L<https://redmine.ruby-lang.org/issues/2294>
19 =head1 DESCRIPTION
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
27 like this:
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:
45  def open(readonly)
46    # see below
47  end
48  def get_size(h)
49    # see below
50  end
51  def pread(h, count, offset)
52    # see below
53  end
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"
64 at the top:
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>.
73 =head2 Methods
75 Your script has access to the C<Nbdkit> module, with the following
76 singleton methods:
78  Nbdkit.set_error(err)
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
86 values.
88 =head2 Exceptions
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>.
94 =head2 Ruby callbacks
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
99 L<nbdkit-plugin(3)>.
101 =over 4
103 =item C<dump_plugin>
105 (Optional)
107 There are no arguments or return value.
109 =item C<config>
111 (Optional)
113  def config(key, value)
114    # no return value
115  end
117 =item C<config_complete>
119 (Optional)
121 There are no arguments or return value.
123 =item C<open>
125 (Required)
127  def open(readonly)
128    # return handle
129  end
131 You can return any non-nil Ruby value as the handle.  It is passed
132 back in subsequent calls.
134 =item C<close>
136 (Optional)
138  def close(h)
139    # no return value
140  end
142 =item C<get_size>
144 (Required)
146  def get_size(h)
147    # return the size of the disk
148  end
150 =item C<can_write>
152 (Optional)
154  def can_write(h)
155    # return a boolean
156  end
158 =item C<can_flush>
160 (Optional)
162  def can_flush(h)
163    # return a boolean
164  end
166 =item C<is_rotational>
168 (Optional)
170  def is_rotational(h)
171    # return a boolean
172  end
174 =item C<can_trim>
176 (Optional)
178  def can_trim(h)
179    # return a boolean
180  end
182 =item C<pread>
184 (Required)
186  def pread(h, count, offset)
187    # construct a string of length count bytes and return it
188  end
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.
199 =item C<pwrite>
201 (Optional)
203  def pwrite(h, buf, offset)
204    length = buf.length
205    # no return value
206  end
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
210 C<offset>.
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.
217 =item C<flush>
219 (Optional)
221  def flush(h)
222    # no return value
223  end
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.
231 =item C<trim>
233 (Optional)
235  def trim(h, count, offset)
236    # no return value
237  end
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.
243 =item C<zero>
245 (Optional)
247  def zero(h, count, offset, may_trim)
248    # no return value
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)>.
263 =back
265 =head2 Missing callbacks
267 =over 4
269 =item Missing: C<load> and C<unload>
271 These are not needed because you can just use ordinary Ruby
272 constructs.
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.
279 =back
281 =head2 Threads
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
286 settable in future.
288 =head1 FILES
290 =over 4
292 =item F<$plugindir/nbdkit-ruby-plugin.so>
294 The plugin.
296 Use C<nbdkit --dump-config> to find the location of C<$plugindir>.
298 =back
300 =head1 VERSION
302 C<nbdkit-ruby-plugin> first appeared in nbdkit 1.2.
304 =head1 SEE ALSO
306 L<nbdkit(1)>,
307 L<nbdkit-plugin(3)>,
308 L<ruby(1)>.
310 =head1 AUTHORS
312 Eric Blake
314 Richard W.M. Jones
316 =head1 COPYRIGHT
318 Copyright Red Hat