1nbdkit-ocaml-plugin(3) NBDKIT nbdkit-ocaml-plugin(3)
2
3
4
6 nbdkit-ocaml-plugin - writing nbdkit plugins in OCaml
7
9 nbdkit /path/to/plugin.so [arguments...]
10
11 nbdkit plugin [arguments...]
12
14 This manual page describes how to write nbdkit plugins in natively
15 compiled OCaml code. This requires OCaml ≥ 4.03.
16
18 For an example plugin written in OCaml, see:
19 https://gitlab.com/nbdkit/nbdkit/blob/master/plugins/ocaml/example.ml
20
21 Broadly speaking, OCaml nbdkit plugins work like C ones, so you should
22 read nbdkit-plugin(3) first.
23
24 You should also look at NBDKit(3) which describes the plugin interface
25 for OCaml plugins.
26
27 Your OCaml code should call "NBDKit.register_plugin" like this when the
28 plugin is loaded:
29
30 NBDKit.register_plugin
31 ~name: "myplugin"
32 ~version: "1.0"
33 ~open_connection: myplugin_open
34 ~get_size: myplugin_get_size
35 ~pread: myplugin_pread
36 ~thread_model:
37 (fun () -> NBDKit.THREAD_MODEL_SERIALIZE_ALL_REQUESTS)
38 (* etc *)
39 ()
40
41 "~name", "~open_connection", "~get_size" and "~pread" are required.
42 All other parameters are optional.
43
44 Compiling an OCaml nbdkit plugin
45 OCaml nbdkit plugins are natively compiled into shared object ("*.so")
46 files which nbdkit loads like regular C plugins.
47
48 After writing your OCaml plugin ("myplugin.ml"), compile and link it
49 using this command:
50
51 ocamlopt.opt -output-obj -runtime-variant _pic \
52 -o nbdkit-myplugin-plugin.so \
53 unix.cmxa \
54 NBDKit.cmx myplugin.ml \
55 -cclib -lnbdkitocaml
56
57 You can then use "nbdkit-myplugin-plugin.so" as an nbdkit plugin (see
58 nbdkit(1), nbdkit-plugin(3)):
59
60 nbdkit ./nbdkit-myplugin-plugin.so [args ...]
61
62 or if the ".so" file is installed in the $plugindir directory:
63
64 nbdkit myplugin [args ...]
65
66 Handle
67 Your "open_connection" callback can return an OCaml value of any type.
68 The same value is passed back to the per-connection callbacks like
69 "get_size" and "pread".
70
71 Typically (although this is not a requirement) you define your own
72 handle struct in your plugin:
73
74 type handle = {
75 (* any per-connection data you want to store goes here *)
76 h_id : int; (* this is just an example field *)
77 h_readonly : bool;
78 }
79
80 let id = ref 0
81 let myplugin_open readonly =
82 (* return a newly allocated handle *)
83 incr id;
84 { h_id = !id; h_readonly = readonly }
85
86 let myplugin_get_size handle =
87 printf "handle ID = %d\n" handle.h_id;
88 (* ... *)
89
90 If you don't need to store per-connection data, "open_connection" can
91 return "()".
92
93 Errors
94 Plugins can return errors from methods by raising an exception.
95
96 If you need to control which errno is sent back to the client you have
97 to call "NBDKit.set_error" before raising the exception.
98
99 Note if you call some function in the OCaml "Unix" module or another
100 library which fails, then the errno of the failing system call will not
101 be returned to the client. You have to catch the exception and call
102 "NBDKit.set_error" before re-raising the exception if you need to
103 control this.
104
105 Threads
106 One of the optional parameters of "NBDKit.register_plugin" is
107 "~thread_model", which must return one of the values in the table
108 below:
109
110 "NBDKit.THREAD_MODEL_SERIALIZE_CONNECTIONS"
111 "NBDKit.THREAD_MODEL_SERIALIZE_ALL_REQUESTS"
112 "NBDKit.THREAD_MODEL_SERIALIZE_REQUESTS"
113 "NBDKit.THREAD_MODEL_PARALLEL"
114
115 If this optional parameter is not provided, the thread model defaults
116 to "NBDKit.THREAD_MODEL_PARALLEL". The garbage collector lock is
117 acquired when calling into OCaml code and because of this callbacks are
118 never truly concurrent.
119
120 For more information on thread models, see "THREADS" in
121 nbdkit-plugin(3).
122
123 Debugging
124 You can add debugging messages which are printed only when nbdkit is in
125 verbose mode by calling:
126
127 NBDKit.debug fs [...]
128
129 This function works like "Printf.printf".
130
131 OCaml scripts
132 Using nbdkit-cc-plugin(1) it is possible to write OCaml plugins which
133 are compiled just before use, and so appear to work more like scripts.
134
136 OCaml plugins first appeared in nbdkit 1.2.
137
139 NBDKit(3), nbdkit(1), nbdkit-plugin(3), ocamlopt(1).
140
142 Richard W.M. Jones
143
145 Copyright Red Hat
146
148 Redistribution and use in source and binary forms, with or without
149 modification, are permitted provided that the following conditions are
150 met:
151
152 • Redistributions of source code must retain the above copyright
153 notice, this list of conditions and the following disclaimer.
154
155 • Redistributions in binary form must reproduce the above copyright
156 notice, this list of conditions and the following disclaimer in the
157 documentation and/or other materials provided with the
158 distribution.
159
160 • Neither the name of Red Hat nor the names of its contributors may
161 be used to endorse or promote products derived from this software
162 without specific prior written permission.
163
164 THIS SOFTWARE IS PROVIDED BY RED HAT AND CONTRIBUTORS ''AS IS'' AND ANY
165 EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
166 IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
167 PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL RED HAT OR CONTRIBUTORS BE
168 LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
169 CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
170 SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
171 BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
172 WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
173 OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
174 ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
175
176
177
178nbdkit-1.34.4 2023-09-26 nbdkit-ocaml-plugin(3)