File: example.ml

package info (click to toggle)
nbdkit 1.42.9-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 14,696 kB
  • sloc: ansic: 59,224; sh: 16,793; makefile: 6,463; python: 1,837; cpp: 1,116; ml: 504; perl: 502; tcl: 62
file content (136 lines) | stat: -rw-r--r-- 3,856 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
(* Example OCaml plugin.

   This example can be freely copied and used for any purpose.

   When building nbdkit this example is compiled as:

     plugins/ocaml/nbdkit-ocamlexample-plugin.so

   You can run it from the build directory like this:

     ./nbdkit -f -v plugins/ocaml/nbdkit-ocamlexample-plugin.so

   or specify the size of the disk:

     ./nbdkit -f -v plugins/ocaml/nbdkit-ocamlexample-plugin.so 100M

   and connect to it with guestfish like this:

     guestfish --format=raw -a nbd://localhost
     ><fs> run
     ><fs> part-disk /dev/sda mbr
     ><fs> mkfs ext2 /dev/sda1
     ><fs> list-filesystems
     ><fs> mount /dev/sda1 /
     ><fs> [etc]
*)

(* Disk image with default size. *)
let disk = ref (Bytes.make (1024*1024) '\000')

(* This is called when the plugin is loaded. *)
let load () =
  (* Debugging output is only printed when the server is in
   * verbose mode (nbdkit -v option).
   *)
  NBDKit.debug "example OCaml plugin loaded"

(* This is called when the plugin is unloaded. *)
let unload () =
  NBDKit.debug "example OCaml plugin unloaded"

(* Add some extra fields to --dump-plugin output.
 * To test this from the build directory:
 *   ./nbdkit --dump-plugin plugins/ocaml/nbdkit-ocamlexample-plugin.so
 *)
let dump_plugin () =
  Printf.printf "ocamlexample_data=42\n";
  flush stdout

(* This is called for every [key=value] parameter passed to the plugin
 * on the command line.
 *)
let config key value =
  match key with
  | "size" ->
     let size = Int64.to_int (NBDKit.parse_size value) in
     disk := Bytes.make size '\000' (* Reallocate the disk. *)
  | _ ->
     failwith (Printf.sprintf "unknown parameter: %s" key)

(* A debug flag (see example-debug-flag.c) *)
external ocamlexample_debug_foo : unit -> int =
  "get_ocamlexample_debug_foo" [@@noalloc]

(* Any type (even unit) can be used as a per-connection handle.
 * This is just an example.  The same value that you return from
 * your [open_connection] function is passed back as the first
 * parameter to connected functions like get_size and pread.
 *)
type handle = {
  h_id : int; (* just a useless example field *)
}

let id = ref 0

(* An NBD client has opened a connection. *)
let open_connection readonly =
  let export_name = NBDKit.export_name () in
  NBDKit.debug "example OCaml plugin handle opened readonly=%b export=%S"
    readonly export_name;
  NBDKit.debug "debug flag: -D ocamlexample.foo=%d" (ocamlexample_debug_foo ());
  incr id;
  { h_id = !id }

(* Return the size of the disk. *)
let get_size h =
  NBDKit.debug "example OCaml plugin get_size id=%d" h.h_id;
  Int64.of_int (Bytes.length !disk)

(* Read part of the disk.  This should modify the buf parameter
 * directly as shown below.
 *)
let pread h buf offset _ =
  let len = NBDKit.buf_len buf in
  let offset = Int64.to_int offset in
  NBDKit.blit_bytes_to_buf !disk offset buf 0 len

(* Write part of the disk. *)
let pwrite h buf offset _ =
  let len = NBDKit.buf_len buf in
  let offset = Int64.to_int offset in
  NBDKit.blit_buf_to_bytes buf 0 !disk offset len

(* Set the plugin thread model.  [SERIALIZE_ALL_REQUESTS] is a
 * safe default.
 *)
let thread_model () =
  NBDKit.THREAD_MODEL_SERIALIZE_ALL_REQUESTS

(* Version is optional.  If used, it can be any string. *)
let version =
  (* You can return a normal version string such as "1.0"
   * or call this function which returns the version of
   * nbdkit at compile time:
   *)
  NBDKit.version ()

(* The plugin must be registered once by calling [register_plugin].
 * name, open_connection, get_size and pread are required,
 * everything else is optional.
 *)
let () =
  NBDKit.register_plugin
    ~name: "ocamlexample"
    ~version
    ~load
    ~unload
    ~dump_plugin
    ~config
    ~magic_config_key: "size"
    ~open_connection
    ~get_size
    ~pread
    ~pwrite
    ~thread_model
    ()