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