Avoid VLAs with size depending on user input
[ocaml-libvirt.git] / libvirt / libvirt.ml
1 (* OCaml bindings for libvirt.
2    (C) Copyright 2007-2015 Richard W.M. Jones, Red Hat Inc.
3    http://libvirt.org/
4
5    This library is free software; you can redistribute it and/or
6    modify it under the terms of the GNU Lesser General Public
7    License as published by the Free Software Foundation; either
8    version 2 of the License, or (at your option) any later version,
9    with the OCaml linking exception described in ../COPYING.LIB.
10
11    This library is distributed in the hope that it will be useful,
12    but WITHOUT ANY WARRANTY; without even the implied warranty of
13    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
14    Lesser General Public License for more details.
15
16    You should have received a copy of the GNU Lesser General Public
17    License along with this library; if not, write to the Free Software
18    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
19 *)
20
21 type uuid = string
22
23 type xml = string
24
25 type filename = string
26
27 external get_version : ?driver:string -> unit -> int * int = "ocaml_libvirt_get_version"
28
29 let uuid_length = 16
30 let uuid_string_length = 36
31
32 (* http://caml.inria.fr/pub/ml-archives/caml-list/2004/07/80683af867cce6bf8fff273973f70c95.en.html *)
33 type rw = [`R|`W]
34 type ro = [`R]
35
36 module Connect =
37 struct
38   type 'rw t
39
40   type node_info = {
41     model : string;
42     memory : int64;
43     cpus : int;
44     mhz : int;
45     nodes : int;
46     sockets : int;
47     cores : int;
48     threads : int;
49   }
50
51   type credential_type =
52     | CredentialUsername
53     | CredentialAuthname
54     | CredentialLanguage
55     | CredentialCnonce
56     | CredentialPassphrase
57     | CredentialEchoprompt
58     | CredentialNoechoprompt
59     | CredentialRealm
60     | CredentialExternal
61
62   type credential = {
63     typ : credential_type;
64     prompt : string;
65     challenge : string option;
66     defresult : string option;
67   }
68
69   type auth = {
70     credtype : credential_type list;
71     cb : (credential list -> string option list);
72   }
73
74   type list_flag =
75     | ListNoState | ListRunning | ListBlocked
76     | ListPaused | ListShutdown | ListShutoff | ListCrashed
77     | ListActive
78     | ListInactive
79     | ListAll
80
81   external connect : ?name:string -> unit -> rw t = "ocaml_libvirt_connect_open"
82   external connect_readonly : ?name:string -> unit -> ro t = "ocaml_libvirt_connect_open_readonly"
83   external connect_auth : ?name:string -> auth -> rw t = "ocaml_libvirt_connect_open_auth"
84   external connect_auth_readonly : ?name:string -> auth -> ro t = "ocaml_libvirt_connect_open_auth_readonly"
85   external close : [>`R] t -> unit = "ocaml_libvirt_connect_close"
86   external get_type : [>`R] t -> string = "ocaml_libvirt_connect_get_type"
87   external get_version : [>`R] t -> int = "ocaml_libvirt_connect_get_version"
88   external get_hostname : [>`R] t -> string = "ocaml_libvirt_connect_get_hostname"
89   external get_uri : [>`R] t -> string = "ocaml_libvirt_connect_get_uri"
90   external get_max_vcpus : [>`R] t -> ?type_:string -> unit -> int = "ocaml_libvirt_connect_get_max_vcpus"
91   external list_domains : [>`R] t -> int -> int array = "ocaml_libvirt_connect_list_domains"
92   external num_of_domains : [>`R] t -> int = "ocaml_libvirt_connect_num_of_domains"
93   external get_capabilities : [>`R] t -> xml = "ocaml_libvirt_connect_get_capabilities"
94   external num_of_defined_domains : [>`R] t -> int = "ocaml_libvirt_connect_num_of_defined_domains"
95   external list_defined_domains : [>`R] t -> int -> string array = "ocaml_libvirt_connect_list_defined_domains"
96   external num_of_networks : [>`R] t -> int = "ocaml_libvirt_connect_num_of_networks"
97   external list_networks : [>`R] t -> int -> string array = "ocaml_libvirt_connect_list_networks"
98   external num_of_defined_networks : [>`R] t -> int = "ocaml_libvirt_connect_num_of_defined_networks"
99   external list_defined_networks : [>`R] t -> int -> string array = "ocaml_libvirt_connect_list_defined_networks"
100   external num_of_pools : [>`R] t -> int = "ocaml_libvirt_connect_num_of_storage_pools"
101   external list_pools : [>`R] t -> int -> string array = "ocaml_libvirt_connect_list_storage_pools"
102   external num_of_defined_pools : [>`R] t -> int = "ocaml_libvirt_connect_num_of_defined_storage_pools"
103   external list_defined_pools : [>`R] t -> int -> string array = "ocaml_libvirt_connect_list_defined_storage_pools"
104
105   external get_node_info : [>`R] t -> node_info = "ocaml_libvirt_connect_get_node_info"
106   external node_get_free_memory : [> `R] t -> int64 = "ocaml_libvirt_connect_node_get_free_memory"
107   external node_get_cells_free_memory : [> `R] t -> int -> int -> int64 array = "ocaml_libvirt_connect_node_get_cells_free_memory"
108
109   (* See VIR_NODEINFO_MAXCPUS macro defined in <libvirt.h>. *)
110   let maxcpus_of_node_info { nodes = nodes; sockets = sockets;
111                              cores = cores; threads = threads } =
112     nodes * sockets * cores * threads
113
114   (* See VIR_CPU_MAPLEN macro defined in <libvirt.h>. *)
115   let cpumaplen nr_cpus =
116     (nr_cpus + 7) / 8
117
118   (* See VIR_USE_CPU, VIR_UNUSE_CPU, VIR_CPU_USABLE macros defined in <libvirt.h>. *)
119   let use_cpu cpumap cpu =
120     Bytes.set cpumap (cpu/8)
121       (Char.chr (Char.code (Bytes.get cpumap (cpu/8)) lor (1 lsl (cpu mod 8))))
122   let unuse_cpu cpumap cpu =
123     Bytes.set cpumap (cpu/8)
124       (Char.chr (Char.code (Bytes.get cpumap (cpu/8)) land (lnot (1 lsl (cpu mod 8)))))
125   let cpu_usable cpumaps maplen vcpu cpu =
126     Char.code (Bytes.get cpumaps (vcpu*maplen + cpu/8)) land (1 lsl (cpu mod 8)) <> 0
127
128   external set_keep_alive : [>`R] t -> int -> int -> unit = "ocaml_libvirt_connect_set_keep_alive"
129
130   external const : [>`R] t -> ro t = "%identity"
131 end
132
133 module Virterror =
134 struct
135   type code =
136     | VIR_ERR_OK
137     | VIR_ERR_INTERNAL_ERROR
138     | VIR_ERR_NO_MEMORY
139     | VIR_ERR_NO_SUPPORT
140     | VIR_ERR_UNKNOWN_HOST
141     | VIR_ERR_NO_CONNECT
142     | VIR_ERR_INVALID_CONN
143     | VIR_ERR_INVALID_DOMAIN
144     | VIR_ERR_INVALID_ARG
145     | VIR_ERR_OPERATION_FAILED
146     | VIR_ERR_GET_FAILED
147     | VIR_ERR_POST_FAILED
148     | VIR_ERR_HTTP_ERROR
149     | VIR_ERR_SEXPR_SERIAL
150     | VIR_ERR_NO_XEN
151     | VIR_ERR_XEN_CALL
152     | VIR_ERR_OS_TYPE
153     | VIR_ERR_NO_KERNEL
154     | VIR_ERR_NO_ROOT
155     | VIR_ERR_NO_SOURCE
156     | VIR_ERR_NO_TARGET
157     | VIR_ERR_NO_NAME
158     | VIR_ERR_NO_OS
159     | VIR_ERR_NO_DEVICE
160     | VIR_ERR_NO_XENSTORE
161     | VIR_ERR_DRIVER_FULL
162     | VIR_ERR_CALL_FAILED
163     | VIR_ERR_XML_ERROR
164     | VIR_ERR_DOM_EXIST
165     | VIR_ERR_OPERATION_DENIED
166     | VIR_ERR_OPEN_FAILED
167     | VIR_ERR_READ_FAILED
168     | VIR_ERR_PARSE_FAILED
169     | VIR_ERR_CONF_SYNTAX
170     | VIR_ERR_WRITE_FAILED
171     | VIR_ERR_XML_DETAIL
172     | VIR_ERR_INVALID_NETWORK
173     | VIR_ERR_NETWORK_EXIST
174     | VIR_ERR_SYSTEM_ERROR
175     | VIR_ERR_RPC
176     | VIR_ERR_GNUTLS_ERROR
177     | VIR_WAR_NO_NETWORK
178     | VIR_ERR_NO_DOMAIN
179     | VIR_ERR_NO_NETWORK
180     | VIR_ERR_INVALID_MAC
181     | VIR_ERR_AUTH_FAILED
182     | VIR_ERR_INVALID_STORAGE_POOL
183     | VIR_ERR_INVALID_STORAGE_VOL
184     | VIR_WAR_NO_STORAGE
185     | VIR_ERR_NO_STORAGE_POOL
186     | VIR_ERR_NO_STORAGE_VOL
187     | VIR_WAR_NO_NODE
188     | VIR_ERR_INVALID_NODE_DEVICE
189     | VIR_ERR_NO_NODE_DEVICE
190     | VIR_ERR_NO_SECURITY_MODEL
191     | VIR_ERR_OPERATION_INVALID
192     | VIR_WAR_NO_INTERFACE
193     | VIR_ERR_NO_INTERFACE
194     | VIR_ERR_INVALID_INTERFACE
195     | VIR_ERR_MULTIPLE_INTERFACES
196     | VIR_WAR_NO_NWFILTER
197     | VIR_ERR_INVALID_NWFILTER
198     | VIR_ERR_NO_NWFILTER
199     | VIR_ERR_BUILD_FIREWALL
200     | VIR_WAR_NO_SECRET
201     | VIR_ERR_INVALID_SECRET
202     | VIR_ERR_NO_SECRET
203     | VIR_ERR_CONFIG_UNSUPPORTED
204     | VIR_ERR_OPERATION_TIMEOUT
205     | VIR_ERR_MIGRATE_PERSIST_FAILED
206     | VIR_ERR_HOOK_SCRIPT_FAILED
207     | VIR_ERR_INVALID_DOMAIN_SNAPSHOT
208     | VIR_ERR_NO_DOMAIN_SNAPSHOT
209     | VIR_ERR_INVALID_STREAM
210     | VIR_ERR_ARGUMENT_UNSUPPORTED
211     | VIR_ERR_STORAGE_PROBE_FAILED
212     | VIR_ERR_STORAGE_POOL_BUILT
213     | VIR_ERR_SNAPSHOT_REVERT_RISKY
214     | VIR_ERR_OPERATION_ABORTED
215     | VIR_ERR_AUTH_CANCELLED
216     | VIR_ERR_NO_DOMAIN_METADATA
217     | VIR_ERR_MIGRATE_UNSAFE
218     | VIR_ERR_OVERFLOW
219     | VIR_ERR_BLOCK_COPY_ACTIVE
220     | VIR_ERR_OPERATION_UNSUPPORTED
221     | VIR_ERR_SSH
222     | VIR_ERR_AGENT_UNRESPONSIVE
223     | VIR_ERR_RESOURCE_BUSY
224     | VIR_ERR_ACCESS_DENIED
225     | VIR_ERR_DBUS_SERVICE
226     | VIR_ERR_STORAGE_VOL_EXIST
227     | VIR_ERR_CPU_INCOMPATIBLE
228     | VIR_ERR_XML_INVALID_SCHEMA
229     | VIR_ERR_MIGRATE_FINISH_OK
230     | VIR_ERR_AUTH_UNAVAILABLE
231     | VIR_ERR_NO_SERVER
232     | VIR_ERR_NO_CLIENT
233     | VIR_ERR_AGENT_UNSYNCED
234     | VIR_ERR_LIBSSH
235     | VIR_ERR_DEVICE_MISSING
236     | VIR_ERR_INVALID_NWFILTER_BINDING
237     | VIR_ERR_NO_NWFILTER_BINDING
238     | VIR_ERR_UNKNOWN of int
239
240   let string_of_code = function
241     | VIR_ERR_OK -> "VIR_ERR_OK"
242     | VIR_ERR_INTERNAL_ERROR -> "VIR_ERR_INTERNAL_ERROR"
243     | VIR_ERR_NO_MEMORY -> "VIR_ERR_NO_MEMORY"
244     | VIR_ERR_NO_SUPPORT -> "VIR_ERR_NO_SUPPORT"
245     | VIR_ERR_UNKNOWN_HOST -> "VIR_ERR_UNKNOWN_HOST"
246     | VIR_ERR_NO_CONNECT -> "VIR_ERR_NO_CONNECT"
247     | VIR_ERR_INVALID_CONN -> "VIR_ERR_INVALID_CONN"
248     | VIR_ERR_INVALID_DOMAIN -> "VIR_ERR_INVALID_DOMAIN"
249     | VIR_ERR_INVALID_ARG -> "VIR_ERR_INVALID_ARG"
250     | VIR_ERR_OPERATION_FAILED -> "VIR_ERR_OPERATION_FAILED"
251     | VIR_ERR_GET_FAILED -> "VIR_ERR_GET_FAILED"
252     | VIR_ERR_POST_FAILED -> "VIR_ERR_POST_FAILED"
253     | VIR_ERR_HTTP_ERROR -> "VIR_ERR_HTTP_ERROR"
254     | VIR_ERR_SEXPR_SERIAL -> "VIR_ERR_SEXPR_SERIAL"
255     | VIR_ERR_NO_XEN -> "VIR_ERR_NO_XEN"
256     | VIR_ERR_XEN_CALL -> "VIR_ERR_XEN_CALL"
257     | VIR_ERR_OS_TYPE -> "VIR_ERR_OS_TYPE"
258     | VIR_ERR_NO_KERNEL -> "VIR_ERR_NO_KERNEL"
259     | VIR_ERR_NO_ROOT -> "VIR_ERR_NO_ROOT"
260     | VIR_ERR_NO_SOURCE -> "VIR_ERR_NO_SOURCE"
261     | VIR_ERR_NO_TARGET -> "VIR_ERR_NO_TARGET"
262     | VIR_ERR_NO_NAME -> "VIR_ERR_NO_NAME"
263     | VIR_ERR_NO_OS -> "VIR_ERR_NO_OS"
264     | VIR_ERR_NO_DEVICE -> "VIR_ERR_NO_DEVICE"
265     | VIR_ERR_NO_XENSTORE -> "VIR_ERR_NO_XENSTORE"
266     | VIR_ERR_DRIVER_FULL -> "VIR_ERR_DRIVER_FULL"
267     | VIR_ERR_CALL_FAILED -> "VIR_ERR_CALL_FAILED"
268     | VIR_ERR_XML_ERROR -> "VIR_ERR_XML_ERROR"
269     | VIR_ERR_DOM_EXIST -> "VIR_ERR_DOM_EXIST"
270     | VIR_ERR_OPERATION_DENIED -> "VIR_ERR_OPERATION_DENIED"
271     | VIR_ERR_OPEN_FAILED -> "VIR_ERR_OPEN_FAILED"
272     | VIR_ERR_READ_FAILED -> "VIR_ERR_READ_FAILED"
273     | VIR_ERR_PARSE_FAILED -> "VIR_ERR_PARSE_FAILED"
274     | VIR_ERR_CONF_SYNTAX -> "VIR_ERR_CONF_SYNTAX"
275     | VIR_ERR_WRITE_FAILED -> "VIR_ERR_WRITE_FAILED"
276     | VIR_ERR_XML_DETAIL -> "VIR_ERR_XML_DETAIL"
277     | VIR_ERR_INVALID_NETWORK -> "VIR_ERR_INVALID_NETWORK"
278     | VIR_ERR_NETWORK_EXIST -> "VIR_ERR_NETWORK_EXIST"
279     | VIR_ERR_SYSTEM_ERROR -> "VIR_ERR_SYSTEM_ERROR"
280     | VIR_ERR_RPC -> "VIR_ERR_RPC"
281     | VIR_ERR_GNUTLS_ERROR -> "VIR_ERR_GNUTLS_ERROR"
282     | VIR_WAR_NO_NETWORK -> "VIR_WAR_NO_NETWORK"
283     | VIR_ERR_NO_DOMAIN -> "VIR_ERR_NO_DOMAIN"
284     | VIR_ERR_NO_NETWORK -> "VIR_ERR_NO_NETWORK"
285     | VIR_ERR_INVALID_MAC -> "VIR_ERR_INVALID_MAC"
286     | VIR_ERR_AUTH_FAILED -> "VIR_ERR_AUTH_FAILED"
287     | VIR_ERR_INVALID_STORAGE_POOL -> "VIR_ERR_INVALID_STORAGE_POOL"
288     | VIR_ERR_INVALID_STORAGE_VOL -> "VIR_ERR_INVALID_STORAGE_VOL"
289     | VIR_WAR_NO_STORAGE -> "VIR_WAR_NO_STORAGE"
290     | VIR_ERR_NO_STORAGE_POOL -> "VIR_ERR_NO_STORAGE_POOL"
291     | VIR_ERR_NO_STORAGE_VOL -> "VIR_ERR_NO_STORAGE_VOL"
292     | VIR_WAR_NO_NODE -> "VIR_WAR_NO_NODE"
293     | VIR_ERR_INVALID_NODE_DEVICE -> "VIR_ERR_INVALID_NODE_DEVICE"
294     | VIR_ERR_NO_NODE_DEVICE -> "VIR_ERR_NO_NODE_DEVICE"
295     | VIR_ERR_NO_SECURITY_MODEL -> "VIR_ERR_NO_SECURITY_MODEL"
296     | VIR_ERR_OPERATION_INVALID -> "VIR_ERR_OPERATION_INVALID"
297     | VIR_WAR_NO_INTERFACE -> "VIR_WAR_NO_INTERFACE"
298     | VIR_ERR_NO_INTERFACE -> "VIR_ERR_NO_INTERFACE"
299     | VIR_ERR_INVALID_INTERFACE -> "VIR_ERR_INVALID_INTERFACE"
300     | VIR_ERR_MULTIPLE_INTERFACES -> "VIR_ERR_MULTIPLE_INTERFACES"
301     | VIR_WAR_NO_NWFILTER -> "VIR_WAR_NO_NWFILTER"
302     | VIR_ERR_INVALID_NWFILTER -> "VIR_ERR_INVALID_NWFILTER"
303     | VIR_ERR_NO_NWFILTER -> "VIR_ERR_NO_NWFILTER"
304     | VIR_ERR_BUILD_FIREWALL -> "VIR_ERR_BUILD_FIREWALL"
305     | VIR_WAR_NO_SECRET -> "VIR_WAR_NO_SECRET"
306     | VIR_ERR_INVALID_SECRET -> "VIR_ERR_INVALID_SECRET"
307     | VIR_ERR_NO_SECRET -> "VIR_ERR_NO_SECRET"
308     | VIR_ERR_CONFIG_UNSUPPORTED -> "VIR_ERR_CONFIG_UNSUPPORTED"
309     | VIR_ERR_OPERATION_TIMEOUT -> "VIR_ERR_OPERATION_TIMEOUT"
310     | VIR_ERR_MIGRATE_PERSIST_FAILED -> "VIR_ERR_MIGRATE_PERSIST_FAILED"
311     | VIR_ERR_HOOK_SCRIPT_FAILED -> "VIR_ERR_HOOK_SCRIPT_FAILED"
312     | VIR_ERR_INVALID_DOMAIN_SNAPSHOT -> "VIR_ERR_INVALID_DOMAIN_SNAPSHOT"
313     | VIR_ERR_NO_DOMAIN_SNAPSHOT -> "VIR_ERR_NO_DOMAIN_SNAPSHOT"
314     | VIR_ERR_INVALID_STREAM -> "VIR_ERR_INVALID_STREAM"
315     | VIR_ERR_ARGUMENT_UNSUPPORTED -> "VIR_ERR_ARGUMENT_UNSUPPORTED"
316     | VIR_ERR_STORAGE_PROBE_FAILED -> "VIR_ERR_STORAGE_PROBE_FAILED"
317     | VIR_ERR_STORAGE_POOL_BUILT -> "VIR_ERR_STORAGE_POOL_BUILT"
318     | VIR_ERR_SNAPSHOT_REVERT_RISKY -> "VIR_ERR_SNAPSHOT_REVERT_RISKY"
319     | VIR_ERR_OPERATION_ABORTED -> "VIR_ERR_OPERATION_ABORTED"
320     | VIR_ERR_AUTH_CANCELLED -> "VIR_ERR_AUTH_CANCELLED"
321     | VIR_ERR_NO_DOMAIN_METADATA -> "VIR_ERR_NO_DOMAIN_METADATA"
322     | VIR_ERR_MIGRATE_UNSAFE -> "VIR_ERR_MIGRATE_UNSAFE"
323     | VIR_ERR_OVERFLOW -> "VIR_ERR_OVERFLOW"
324     | VIR_ERR_BLOCK_COPY_ACTIVE -> "VIR_ERR_BLOCK_COPY_ACTIVE"
325     | VIR_ERR_OPERATION_UNSUPPORTED -> "VIR_ERR_OPERATION_UNSUPPORTED"
326     | VIR_ERR_SSH -> "VIR_ERR_SSH"
327     | VIR_ERR_AGENT_UNRESPONSIVE -> "VIR_ERR_AGENT_UNRESPONSIVE"
328     | VIR_ERR_RESOURCE_BUSY -> "VIR_ERR_RESOURCE_BUSY"
329     | VIR_ERR_ACCESS_DENIED -> "VIR_ERR_ACCESS_DENIED"
330     | VIR_ERR_DBUS_SERVICE -> "VIR_ERR_DBUS_SERVICE"
331     | VIR_ERR_STORAGE_VOL_EXIST -> "VIR_ERR_STORAGE_VOL_EXIST"
332     | VIR_ERR_CPU_INCOMPATIBLE -> "VIR_ERR_CPU_INCOMPATIBLE"
333     | VIR_ERR_XML_INVALID_SCHEMA -> "VIR_ERR_XML_INVALID_SCHEMA"
334     | VIR_ERR_MIGRATE_FINISH_OK -> "VIR_ERR_MIGRATE_FINISH_OK"
335     | VIR_ERR_AUTH_UNAVAILABLE -> "VIR_ERR_AUTH_UNAVAILABLE"
336     | VIR_ERR_NO_SERVER -> "VIR_ERR_NO_SERVER"
337     | VIR_ERR_NO_CLIENT -> "VIR_ERR_NO_CLIENT"
338     | VIR_ERR_AGENT_UNSYNCED -> "VIR_ERR_AGENT_UNSYNCED"
339     | VIR_ERR_LIBSSH -> "VIR_ERR_LIBSSH"
340     | VIR_ERR_DEVICE_MISSING -> "VIR_ERR_DEVICE_MISSING"
341     | VIR_ERR_INVALID_NWFILTER_BINDING -> "VIR_ERR_INVALID_NWFILTER_BINDING"
342     | VIR_ERR_NO_NWFILTER_BINDING -> "VIR_ERR_NO_NWFILTER_BINDING"
343     | VIR_ERR_UNKNOWN i -> "VIR_ERR_" ^ string_of_int i
344
345   type domain =
346     | VIR_FROM_NONE
347     | VIR_FROM_XEN
348     | VIR_FROM_XEND
349     | VIR_FROM_XENSTORE
350     | VIR_FROM_SEXPR
351     | VIR_FROM_XML
352     | VIR_FROM_DOM
353     | VIR_FROM_RPC
354     | VIR_FROM_PROXY
355     | VIR_FROM_CONF
356     | VIR_FROM_QEMU
357     | VIR_FROM_NET
358     | VIR_FROM_TEST
359     | VIR_FROM_REMOTE
360     | VIR_FROM_OPENVZ
361     | VIR_FROM_XENXM
362     | VIR_FROM_STATS_LINUX
363     | VIR_FROM_LXC
364     | VIR_FROM_STORAGE
365     | VIR_FROM_NETWORK
366     | VIR_FROM_DOMAIN
367     | VIR_FROM_UML
368     | VIR_FROM_NODEDEV
369     | VIR_FROM_XEN_INOTIFY
370     | VIR_FROM_SECURITY
371     | VIR_FROM_VBOX
372     | VIR_FROM_INTERFACE
373     | VIR_FROM_ONE
374     | VIR_FROM_ESX
375     | VIR_FROM_PHYP
376     | VIR_FROM_SECRET
377     | VIR_FROM_CPU
378     | VIR_FROM_XENAPI
379     | VIR_FROM_NWFILTER
380     | VIR_FROM_HOOK
381     | VIR_FROM_DOMAIN_SNAPSHOT
382     | VIR_FROM_AUDIT
383     | VIR_FROM_SYSINFO
384     | VIR_FROM_STREAMS
385     | VIR_FROM_VMWARE
386     | VIR_FROM_EVENT
387     | VIR_FROM_LIBXL
388     | VIR_FROM_LOCKING
389     | VIR_FROM_HYPERV
390     | VIR_FROM_CAPABILITIES
391     | VIR_FROM_URI
392     | VIR_FROM_AUTH
393     | VIR_FROM_DBUS
394     | VIR_FROM_PARALLELS
395     | VIR_FROM_DEVICE
396     | VIR_FROM_SSH
397     | VIR_FROM_LOCKSPACE
398     | VIR_FROM_INITCTL
399     | VIR_FROM_IDENTITY
400     | VIR_FROM_CGROUP
401     | VIR_FROM_ACCESS
402     | VIR_FROM_SYSTEMD
403     | VIR_FROM_BHYVE
404     | VIR_FROM_CRYPTO
405     | VIR_FROM_FIREWALL
406     | VIR_FROM_POLKIT
407     | VIR_FROM_THREAD
408     | VIR_FROM_ADMIN
409     | VIR_FROM_LOGGING
410     | VIR_FROM_XENXL
411     | VIR_FROM_PERF
412     | VIR_FROM_LIBSSH
413     | VIR_FROM_RESCTRL
414     | VIR_FROM_UNKNOWN of int
415
416   let string_of_domain = function
417     | VIR_FROM_NONE -> "VIR_FROM_NONE"
418     | VIR_FROM_XEN -> "VIR_FROM_XEN"
419     | VIR_FROM_XEND -> "VIR_FROM_XEND"
420     | VIR_FROM_XENSTORE -> "VIR_FROM_XENSTORE"
421     | VIR_FROM_SEXPR -> "VIR_FROM_SEXPR"
422     | VIR_FROM_XML -> "VIR_FROM_XML"
423     | VIR_FROM_DOM -> "VIR_FROM_DOM"
424     | VIR_FROM_RPC -> "VIR_FROM_RPC"
425     | VIR_FROM_PROXY -> "VIR_FROM_PROXY"
426     | VIR_FROM_CONF -> "VIR_FROM_CONF"
427     | VIR_FROM_QEMU -> "VIR_FROM_QEMU"
428     | VIR_FROM_NET -> "VIR_FROM_NET"
429     | VIR_FROM_TEST -> "VIR_FROM_TEST"
430     | VIR_FROM_REMOTE -> "VIR_FROM_REMOTE"
431     | VIR_FROM_OPENVZ -> "VIR_FROM_OPENVZ"
432     | VIR_FROM_XENXM -> "VIR_FROM_XENXM"
433     | VIR_FROM_STATS_LINUX -> "VIR_FROM_STATS_LINUX"
434     | VIR_FROM_LXC -> "VIR_FROM_LXC"
435     | VIR_FROM_STORAGE -> "VIR_FROM_STORAGE"
436     | VIR_FROM_NETWORK -> "VIR_FROM_NETWORK"
437     | VIR_FROM_DOMAIN -> "VIR_FROM_DOMAIN"
438     | VIR_FROM_UML -> "VIR_FROM_UML"
439     | VIR_FROM_NODEDEV -> "VIR_FROM_NODEDEV"
440     | VIR_FROM_XEN_INOTIFY -> "VIR_FROM_XEN_INOTIFY"
441     | VIR_FROM_SECURITY -> "VIR_FROM_SECURITY"
442     | VIR_FROM_VBOX -> "VIR_FROM_VBOX"
443     | VIR_FROM_INTERFACE -> "VIR_FROM_INTERFACE"
444     | VIR_FROM_ONE -> "VIR_FROM_ONE"
445     | VIR_FROM_ESX -> "VIR_FROM_ESX"
446     | VIR_FROM_PHYP -> "VIR_FROM_PHYP"
447     | VIR_FROM_SECRET -> "VIR_FROM_SECRET"
448     | VIR_FROM_CPU -> "VIR_FROM_CPU"
449     | VIR_FROM_XENAPI -> "VIR_FROM_XENAPI"
450     | VIR_FROM_NWFILTER -> "VIR_FROM_NWFILTER"
451     | VIR_FROM_HOOK -> "VIR_FROM_HOOK"
452     | VIR_FROM_DOMAIN_SNAPSHOT -> "VIR_FROM_DOMAIN_SNAPSHOT"
453     | VIR_FROM_AUDIT -> "VIR_FROM_AUDIT"
454     | VIR_FROM_SYSINFO -> "VIR_FROM_SYSINFO"
455     | VIR_FROM_STREAMS -> "VIR_FROM_STREAMS"
456     | VIR_FROM_VMWARE -> "VIR_FROM_VMWARE"
457     | VIR_FROM_EVENT -> "VIR_FROM_EVENT"
458     | VIR_FROM_LIBXL -> "VIR_FROM_LIBXL"
459     | VIR_FROM_LOCKING -> "VIR_FROM_LOCKING"
460     | VIR_FROM_HYPERV -> "VIR_FROM_HYPERV"
461     | VIR_FROM_CAPABILITIES -> "VIR_FROM_CAPABILITIES"
462     | VIR_FROM_URI -> "VIR_FROM_URI"
463     | VIR_FROM_AUTH -> "VIR_FROM_AUTH"
464     | VIR_FROM_DBUS -> "VIR_FROM_DBUS"
465     | VIR_FROM_PARALLELS -> "VIR_FROM_PARALLELS"
466     | VIR_FROM_DEVICE -> "VIR_FROM_DEVICE"
467     | VIR_FROM_SSH -> "VIR_FROM_SSH"
468     | VIR_FROM_LOCKSPACE -> "VIR_FROM_LOCKSPACE"
469     | VIR_FROM_INITCTL -> "VIR_FROM_INITCTL"
470     | VIR_FROM_IDENTITY -> "VIR_FROM_IDENTITY"
471     | VIR_FROM_CGROUP -> "VIR_FROM_CGROUP"
472     | VIR_FROM_ACCESS -> "VIR_FROM_ACCESS"
473     | VIR_FROM_SYSTEMD -> "VIR_FROM_SYSTEMD"
474     | VIR_FROM_BHYVE -> "VIR_FROM_BHYVE"
475     | VIR_FROM_CRYPTO -> "VIR_FROM_CRYPTO"
476     | VIR_FROM_FIREWALL -> "VIR_FROM_FIREWALL"
477     | VIR_FROM_POLKIT -> "VIR_FROM_POLKIT"
478     | VIR_FROM_THREAD -> "VIR_FROM_THREAD"
479     | VIR_FROM_ADMIN -> "VIR_FROM_ADMIN"
480     | VIR_FROM_LOGGING -> "VIR_FROM_LOGGING"
481     | VIR_FROM_XENXL -> "VIR_FROM_XENXL"
482     | VIR_FROM_PERF -> "VIR_FROM_PERF"
483     | VIR_FROM_LIBSSH -> "VIR_FROM_LIBSSH"
484     | VIR_FROM_RESCTRL -> "VIR_FROM_RESCTRL"
485     | VIR_FROM_UNKNOWN i -> "VIR_FROM_" ^ string_of_int i
486
487   type level =
488     | VIR_ERR_NONE
489     | VIR_ERR_WARNING
490     | VIR_ERR_ERROR
491     | VIR_ERR_UNKNOWN_LEVEL of int
492
493   let string_of_level = function
494     | VIR_ERR_NONE -> "VIR_ERR_NONE"
495     | VIR_ERR_WARNING -> "VIR_ERR_WARNING"
496     | VIR_ERR_ERROR -> "VIR_ERR_ERROR"
497     | VIR_ERR_UNKNOWN_LEVEL i -> "VIR_ERR_LEVEL_" ^ string_of_int i
498
499   type t = {
500     code : code;
501     domain : domain;
502     message : string option;
503     level : level;
504     str1 : string option;
505     str2 : string option;
506     str3 : string option;
507     int1 : int32;
508     int2 : int32;
509   }
510
511   let to_string { code = code; domain = domain; message = message } =
512     let buf = Buffer.create 128 in
513     Buffer.add_string buf "libvirt: ";
514     Buffer.add_string buf (string_of_code code);
515     Buffer.add_string buf ": ";
516     Buffer.add_string buf (string_of_domain domain);
517     Buffer.add_string buf ": ";
518     (match message with Some msg -> Buffer.add_string buf msg | None -> ());
519     Buffer.contents buf
520
521   external get_last_error : unit -> t option = "ocaml_libvirt_virterror_get_last_error"
522   external get_last_conn_error : [>`R] Connect.t -> t option = "ocaml_libvirt_virterror_get_last_conn_error"
523   external reset_last_error : unit -> unit = "ocaml_libvirt_virterror_reset_last_error"
524   external reset_last_conn_error : [>`R] Connect.t -> unit = "ocaml_libvirt_virterror_reset_last_conn_error"
525
526   let no_error () =
527     { code = VIR_ERR_OK; domain = VIR_FROM_NONE;
528       message = None; level = VIR_ERR_NONE;
529       str1 = None; str2 = None; str3 = None;
530       int1 = 0_l; int2 = 0_l }
531 end
532
533 exception Virterror of Virterror.t
534 exception Not_supported of string
535
536 let rec map_ignore_errors f = function
537   | [] -> []
538   | x :: xs ->
539       try f x :: map_ignore_errors f xs
540       with Virterror _ -> map_ignore_errors f xs
541
542 module Domain =
543 struct
544   type 'rw t
545
546   type state =
547     | InfoNoState | InfoRunning | InfoBlocked | InfoPaused
548     | InfoShutdown | InfoShutoff | InfoCrashed
549
550   type info = {
551     state : state;
552     max_mem : int64;
553     memory : int64;
554     nr_virt_cpu : int;
555     cpu_time : int64;
556   }
557
558   type vcpu_state = VcpuOffline | VcpuRunning | VcpuBlocked
559
560   type vcpu_info = {
561     number : int;
562     vcpu_state : vcpu_state;
563     vcpu_time : int64;
564     cpu : int;
565   }
566
567   type domain_create_flag =
568   | START_PAUSED
569   | START_AUTODESTROY
570   | START_BYPASS_CACHE
571   | START_FORCE_BOOT
572   | START_VALIDATE
573   let rec int_of_domain_create_flags = function
574     | [] -> 0
575     | START_PAUSED :: flags ->       1 lor int_of_domain_create_flags flags
576     | START_AUTODESTROY :: flags ->  2 lor int_of_domain_create_flags flags
577     | START_BYPASS_CACHE :: flags -> 4 lor int_of_domain_create_flags flags
578     | START_FORCE_BOOT :: flags ->   8 lor int_of_domain_create_flags flags
579     | START_VALIDATE :: flags ->    16 lor int_of_domain_create_flags flags
580
581   type sched_param = string * sched_param_value
582   and sched_param_value =
583     | SchedFieldInt32 of int32 | SchedFieldUInt32 of int32
584     | SchedFieldInt64 of int64 | SchedFieldUInt64 of int64
585     | SchedFieldFloat of float | SchedFieldBool of bool
586
587   type typed_param = string * typed_param_value
588   and typed_param_value =
589     | TypedFieldInt32 of int32 | TypedFieldUInt32 of int32
590     | TypedFieldInt64 of int64 | TypedFieldUInt64 of int64
591     | TypedFieldFloat of float | TypedFieldBool of bool
592     | TypedFieldString of string
593
594   type migrate_flag = Live
595
596   type memory_flag = Virtual
597
598   type list_flag =
599     | ListActive
600     | ListInactive
601     | ListAll
602
603   type block_stats = {
604     rd_req : int64;
605     rd_bytes : int64;
606     wr_req : int64;
607     wr_bytes : int64;
608     errs : int64;
609   }
610
611   type interface_stats = {
612     rx_bytes : int64;
613     rx_packets : int64;
614     rx_errs : int64;
615     rx_drop : int64;
616     tx_bytes : int64;
617     tx_packets : int64;
618     tx_errs : int64;
619     tx_drop : int64;
620   }
621
622   type get_all_domain_stats_flag =
623     | GetAllDomainsStatsActive
624     | GetAllDomainsStatsInactive
625     | GetAllDomainsStatsOther
626     | GetAllDomainsStatsPaused
627     | GetAllDomainsStatsPersistent
628     | GetAllDomainsStatsRunning
629     | GetAllDomainsStatsShutoff
630     | GetAllDomainsStatsTransient
631     | GetAllDomainsStatsBacking
632     | GetAllDomainsStatsEnforceStats
633
634   type stats_type =
635     | StatsState | StatsCpuTotal | StatsBalloon | StatsVcpu
636     | StatsInterface | StatsBlock | StatsPerf
637
638   type domain_stats_record = {
639     dom_uuid : uuid;
640     params : typed_param array;
641   }
642
643   type xml_desc_flag =
644     | XmlSecure
645     | XmlInactive
646     | XmlUpdateCPU
647     | XmlMigratable
648
649   (* The maximum size for Domain.memory_peek and Domain.block_peek
650    * supported by libvirt.  This may change with different versions
651    * of libvirt in the future, hence it's a function.
652    *)
653   let max_peek _ = 65536
654
655   external create_linux : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_domain_create_linux"
656   external _create_xml : [>`W] Connect.t -> xml -> int -> rw t = "ocaml_libvirt_domain_create_xml"
657   let create_xml conn xml flags =
658     _create_xml conn xml (int_of_domain_create_flags flags)
659   external lookup_by_id : 'a Connect.t -> int -> 'a t = "ocaml_libvirt_domain_lookup_by_id"
660   external lookup_by_uuid : 'a Connect.t -> uuid -> 'a t = "ocaml_libvirt_domain_lookup_by_uuid"
661   external lookup_by_uuid_string : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_domain_lookup_by_uuid_string"
662   external lookup_by_name : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_domain_lookup_by_name"
663   external destroy : [>`W] t -> unit = "ocaml_libvirt_domain_destroy"
664   external free : [>`R] t -> unit = "ocaml_libvirt_domain_free"
665   external suspend : [>`W] t -> unit = "ocaml_libvirt_domain_suspend"
666   external resume : [>`W] t -> unit = "ocaml_libvirt_domain_resume"
667   external save : [>`W] t -> filename -> unit = "ocaml_libvirt_domain_save"
668   external restore : [>`W] Connect.t -> filename -> unit = "ocaml_libvirt_domain_restore"
669   external core_dump : [>`W] t -> filename -> unit = "ocaml_libvirt_domain_core_dump"
670   external shutdown : [>`W] t -> unit = "ocaml_libvirt_domain_shutdown"
671   external reboot : [>`W] t -> unit = "ocaml_libvirt_domain_reboot"
672   external get_name : [>`R] t -> string = "ocaml_libvirt_domain_get_name"
673   external get_uuid : [>`R] t -> uuid = "ocaml_libvirt_domain_get_uuid"
674   external get_uuid_string : [>`R] t -> string = "ocaml_libvirt_domain_get_uuid_string"
675   external get_id : [>`R] t -> int = "ocaml_libvirt_domain_get_id"
676   external get_os_type : [>`R] t -> string = "ocaml_libvirt_domain_get_os_type"
677   external get_max_memory : [>`R] t -> int64 = "ocaml_libvirt_domain_get_max_memory"
678   external set_max_memory : [>`W] t -> int64 -> unit = "ocaml_libvirt_domain_set_max_memory"
679   external set_memory : [>`W] t -> int64 -> unit = "ocaml_libvirt_domain_set_memory"
680   external get_info : [>`R] t -> info = "ocaml_libvirt_domain_get_info"
681   external get_xml_desc : [>`R] t -> xml = "ocaml_libvirt_domain_get_xml_desc"
682   external get_xml_desc_flags : [>`W] t -> xml_desc_flag list -> xml = "ocaml_libvirt_domain_get_xml_desc_flags"
683   external get_scheduler_type : [>`R] t -> string * int = "ocaml_libvirt_domain_get_scheduler_type"
684   external get_scheduler_parameters : [>`R] t -> int -> sched_param array = "ocaml_libvirt_domain_get_scheduler_parameters"
685   external set_scheduler_parameters : [>`W] t -> sched_param array -> unit = "ocaml_libvirt_domain_set_scheduler_parameters"
686   external define_xml : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_domain_define_xml"
687   external undefine : [>`W] t -> unit = "ocaml_libvirt_domain_undefine"
688   external create : [>`W] t -> unit = "ocaml_libvirt_domain_create"
689   external get_autostart : [>`R] t -> bool = "ocaml_libvirt_domain_get_autostart"
690   external set_autostart : [>`W] t -> bool -> unit = "ocaml_libvirt_domain_set_autostart"
691   external set_vcpus : [>`W] t -> int -> unit = "ocaml_libvirt_domain_set_vcpus"
692   external pin_vcpu : [>`W] t -> int -> string -> unit = "ocaml_libvirt_domain_pin_vcpu"
693   external get_vcpus : [>`R] t -> int -> int -> int * vcpu_info array * string = "ocaml_libvirt_domain_get_vcpus"
694   external get_cpu_stats : [>`R] t -> typed_param list array = "ocaml_libvirt_domain_get_cpu_stats"
695   external get_max_vcpus : [>`R] t -> int = "ocaml_libvirt_domain_get_max_vcpus"
696   external attach_device : [>`W] t -> xml -> unit = "ocaml_libvirt_domain_attach_device"
697   external detach_device : [>`W] t -> xml -> unit = "ocaml_libvirt_domain_detach_device"
698   external migrate : [>`W] t -> [>`W] Connect.t -> migrate_flag list -> ?dname:string -> ?uri:string -> ?bandwidth:int -> unit -> rw t = "ocaml_libvirt_domain_migrate_bytecode" "ocaml_libvirt_domain_migrate_native"
699   external block_stats : [>`R] t -> string -> block_stats = "ocaml_libvirt_domain_block_stats"
700   external interface_stats : [>`R] t -> string -> interface_stats = "ocaml_libvirt_domain_interface_stats"
701   external block_peek : [>`W] t -> string -> int64 -> int -> string -> int -> unit = "ocaml_libvirt_domain_block_peek_bytecode" "ocaml_libvirt_domain_block_peek_native"
702   external memory_peek : [>`W] t -> memory_flag list -> int64 -> int -> string -> int -> unit = "ocaml_libvirt_domain_memory_peek_bytecode" "ocaml_libvirt_domain_memory_peek_native"
703
704   external get_all_domain_stats : [>`R] Connect.t -> stats_type list -> get_all_domain_stats_flag list -> domain_stats_record array = "ocaml_libvirt_domain_get_all_domain_stats"
705
706   external const : [>`R] t -> ro t = "%identity"
707
708   let get_domains conn flags =
709     (* Old/slow/inefficient method. *)
710     let get_active, get_inactive =
711       if List.mem ListAll flags then
712         (true, true)
713       else
714         (List.mem ListActive flags, List.mem ListInactive flags) in
715     let active_doms =
716       if get_active then (
717         let n = Connect.num_of_domains conn in
718         let ids = Connect.list_domains conn n in
719         let ids = Array.to_list ids in
720         map_ignore_errors (lookup_by_id conn) ids
721       ) else [] in
722
723     let inactive_doms =
724       if get_inactive then (
725         let n = Connect.num_of_defined_domains conn in
726         let names = Connect.list_defined_domains conn n in
727         let names = Array.to_list names in
728         map_ignore_errors (lookup_by_name conn) names
729       ) else [] in
730
731     active_doms @ inactive_doms
732
733   let get_domains_and_infos conn flags =
734     (* Old/slow/inefficient method. *)
735     let get_active, get_inactive =
736       if List.mem ListAll flags then
737         (true, true)
738       else (List.mem ListActive flags, List.mem ListInactive flags) in
739     let active_doms =
740       if get_active then (
741         let n = Connect.num_of_domains conn in
742         let ids = Connect.list_domains conn n in
743         let ids = Array.to_list ids in
744         map_ignore_errors (lookup_by_id conn) ids
745       ) else [] in
746
747     let inactive_doms =
748       if get_inactive then (
749         let n = Connect.num_of_defined_domains conn in
750         let names = Connect.list_defined_domains conn n in
751         let names = Array.to_list names in
752         map_ignore_errors (lookup_by_name conn) names
753       ) else [] in
754
755     let doms = active_doms @ inactive_doms in
756
757     map_ignore_errors (fun dom -> (dom, get_info dom)) doms
758 end
759
760 module Event =
761 struct
762
763   module Defined = struct
764     type t = [
765       | `Added
766       | `Updated
767       | `Unknown of int
768     ]
769
770     let to_string = function
771       | `Added -> "Added"
772       | `Updated -> "Updated"
773       | `Unknown x -> Printf.sprintf "Unknown Defined.detail: %d" x
774
775     let make = function
776       | 0 -> `Added
777       | 1 -> `Updated
778       | x -> `Unknown x (* newer libvirt *)
779   end
780
781   module Undefined = struct
782     type t = [
783       | `Removed
784       | `Unknown of int
785     ]
786
787     let to_string = function
788       | `Removed -> "UndefinedRemoved"
789       | `Unknown x -> Printf.sprintf "Unknown Undefined.detail: %d" x
790
791     let make = function
792       | 0 -> `Removed
793       | x -> `Unknown x (* newer libvirt *)
794   end
795
796   module Started = struct
797     type t = [
798       | `Booted
799       | `Migrated
800       | `Restored
801       | `FromSnapshot
802       | `Wakeup
803       | `Unknown of int
804     ]
805
806     let to_string = function
807       | `Booted -> "Booted"
808       | `Migrated -> "Migrated"
809       | `Restored -> "Restored"
810       | `FromSnapshot -> "FromSnapshot"
811       | `Wakeup -> "Wakeup"
812       | `Unknown x -> Printf.sprintf "Unknown Started.detail: %d" x
813  
814     let make = function
815       | 0 -> `Booted
816       | 1 -> `Migrated
817       | 2 -> `Restored
818       | 3 -> `FromSnapshot
819       | 4 -> `Wakeup
820       | x -> `Unknown x (* newer libvirt *)
821   end
822
823   module Suspended = struct
824     type t = [
825       | `Paused
826       | `Migrated
827       | `IOError
828       | `Watchdog
829       | `Restored
830       | `FromSnapshot
831       | `APIError
832       | `Unknown of int (* newer libvirt *)
833     ]
834
835     let to_string = function
836       | `Paused -> "Paused"
837       | `Migrated -> "Migrated"
838       | `IOError -> "IOError"
839       | `Watchdog -> "Watchdog"
840       | `Restored -> "Restored"
841       | `FromSnapshot -> "FromSnapshot"
842       | `APIError -> "APIError"
843       | `Unknown x -> Printf.sprintf "Unknown Suspended.detail: %d" x
844
845      let make = function
846       | 0 -> `Paused
847       | 1 -> `Migrated
848       | 2 -> `IOError
849       | 3 -> `Watchdog
850       | 4 -> `Restored
851       | 5 -> `FromSnapshot
852       | 6 -> `APIError
853       | x -> `Unknown x (* newer libvirt *)
854   end
855
856   module Resumed = struct
857     type t = [
858       | `Unpaused
859       | `Migrated
860       | `FromSnapshot
861       | `Unknown of int (* newer libvirt *)
862     ]
863
864     let to_string = function
865       | `Unpaused -> "Unpaused"
866       | `Migrated -> "Migrated"
867       | `FromSnapshot -> "FromSnapshot"
868       | `Unknown x -> Printf.sprintf "Unknown Resumed.detail: %d" x
869
870     let make = function
871       | 0 -> `Unpaused
872       | 1 -> `Migrated
873       | 2 -> `FromSnapshot
874       | x -> `Unknown x (* newer libvirt *)
875   end
876
877   module Stopped = struct
878     type t = [
879       | `Shutdown
880       | `Destroyed
881       | `Crashed
882       | `Migrated
883       | `Saved
884       | `Failed
885       | `FromSnapshot
886       | `Unknown of int
887     ]
888     let to_string = function
889       | `Shutdown -> "Shutdown"
890       | `Destroyed -> "Destroyed"
891       | `Crashed -> "Crashed"
892       | `Migrated -> "Migrated"
893       | `Saved -> "Saved"
894       | `Failed -> "Failed"
895       | `FromSnapshot -> "FromSnapshot"
896       | `Unknown x -> Printf.sprintf "Unknown Stopped.detail: %d" x
897
898     let make = function
899       | 0 -> `Shutdown
900       | 1 -> `Destroyed
901       | 2 -> `Crashed
902       | 3 -> `Migrated
903       | 4 -> `Saved
904       | 5 -> `Failed
905       | 6 -> `FromSnapshot
906       | x -> `Unknown x (* newer libvirt *)
907   end
908
909   module PM_suspended = struct
910     type t = [
911       | `Memory
912       | `Disk
913       | `Unknown of int (* newer libvirt *)
914     ]
915
916     let to_string = function
917       | `Memory -> "Memory"
918       | `Disk -> "Disk"
919       | `Unknown x -> Printf.sprintf "Unknown PM_suspended.detail: %d" x
920
921     let make = function
922       | 0 -> `Memory
923       | 1 -> `Disk
924       | x -> `Unknown x (* newer libvirt *)
925   end
926
927   let string_option x = match x with
928     | None -> "None"
929     | Some x' -> "Some " ^ x'
930
931   module Lifecycle = struct
932     type t = [
933       | `Defined of Defined.t
934       | `Undefined of Undefined.t
935       | `Started of Started.t
936       | `Suspended of Suspended.t
937       | `Resumed of Resumed.t
938       | `Stopped of Stopped.t
939       | `Shutdown (* no detail defined yet *)
940       | `PMSuspended of PM_suspended.t
941       | `Unknown of int (* newer libvirt *)
942     ]
943
944     let to_string = function
945       | `Defined x -> "Defined " ^ (Defined.to_string x)
946       | `Undefined x -> "Undefined " ^ (Undefined.to_string x)
947       | `Started x -> "Started " ^ (Started.to_string x)
948       | `Suspended x -> "Suspended " ^ (Suspended.to_string x)
949       | `Resumed x -> "Resumed " ^ (Resumed.to_string x)
950       | `Stopped x -> "Stopped " ^ (Stopped.to_string x)
951       | `Shutdown -> "Shutdown"
952       | `PMSuspended x -> "PMSuspended " ^ (PM_suspended.to_string x)
953       | `Unknown x -> Printf.sprintf "Unknown Lifecycle event: %d" x
954
955     let make (ty, detail) = match ty with
956       | 0 -> `Defined (Defined.make detail)
957       | 1 -> `Undefined (Undefined.make detail)
958       | 2 -> `Started (Started.make detail)
959       | 3 -> `Suspended (Suspended.make detail)
960       | 4 -> `Resumed (Resumed.make detail)
961       | 5 -> `Stopped (Stopped.make detail)
962       | 6 -> `Shutdown
963       | 7 -> `PMSuspended (PM_suspended.make detail)
964       | x -> `Unknown x
965   end
966
967   module Reboot = struct
968     type t = unit
969
970     let to_string _ = "()"
971
972     let make () = ()
973   end
974
975   module Rtc_change = struct
976     type t = int64
977
978     let to_string = Int64.to_string
979
980     let make x = x
981   end
982
983   module Watchdog = struct
984     type t = [
985       | `None
986       | `Pause
987       | `Reset
988       | `Poweroff
989       | `Shutdown
990       | `Debug
991       | `Unknown of int
992     ]
993
994     let to_string = function
995       | `None -> "None"
996       | `Pause -> "Pause"
997       | `Reset -> "Reset"
998       | `Poweroff -> "Poweroff"
999       | `Shutdown -> "Shutdown"
1000       | `Debug -> "Debug"
1001       | `Unknown x -> Printf.sprintf "Unknown watchdog_action: %d" x
1002
1003     let make = function
1004       | 0 -> `None
1005       | 1 -> `Pause
1006       | 2 -> `Reset
1007       | 3 -> `Poweroff
1008       | 4 -> `Shutdown
1009       | 5 -> `Debug
1010       | x -> `Unknown x (* newer libvirt *)
1011   end
1012
1013   module Io_error = struct
1014     type action = [
1015       | `None
1016       | `Pause
1017       | `Report
1018       | `Unknown of int (* newer libvirt *)
1019     ]
1020
1021     let string_of_action = function
1022       | `None -> "None"
1023       | `Pause -> "Pause"
1024       | `Report -> "Report"
1025       | `Unknown x -> Printf.sprintf "Unknown Io_error.action: %d" x
1026
1027     let action_of_int = function
1028       | 0 -> `None
1029       | 1 -> `Pause
1030       | 2 -> `Report
1031       | x -> `Unknown x
1032
1033     type t = {
1034       src_path: string option;
1035       dev_alias: string option;
1036       action: action;
1037       reason: string option;
1038     }
1039
1040     let to_string t = Printf.sprintf
1041         "{ Io_error.src_path = %s; dev_alias = %s; action = %s; reason = %s }"
1042         (string_option t.src_path)
1043         (string_option t.dev_alias)
1044         (string_of_action t.action)
1045         (string_option t.reason)
1046
1047     let make (src_path, dev_alias, action, reason) = {
1048         src_path = src_path;
1049         dev_alias = dev_alias;
1050         action = action_of_int action;
1051         reason = reason;
1052     }
1053
1054     let make_noreason (src_path, dev_alias, action) =
1055       make (src_path, dev_alias, action, None)
1056   end
1057
1058   module Graphics_address = struct
1059     type family = [
1060       | `Ipv4
1061       | `Ipv6
1062       | `Unix
1063       | `Unknown of int (* newer libvirt *)
1064     ]
1065
1066     let string_of_family = function
1067       | `Ipv4 -> "IPv4"
1068       | `Ipv6 -> "IPv6"
1069       | `Unix -> "UNIX"
1070       | `Unknown x -> Printf.sprintf "Unknown Graphics_address.family: %d" x
1071
1072     let family_of_int = function
1073       (* no zero *)
1074       | 1 -> `Ipv4
1075       | 2 -> `Ipv6
1076       | 3 -> `Unix
1077       | x -> `Unknown x
1078
1079     type t = {
1080       family: family;         (** Address family *)
1081       node: string option;    (** Address of node (eg IP address, or UNIX path *)
1082       service: string option; (** Service name/number (eg TCP port, or NULL) *)
1083     }
1084
1085     let to_string t = Printf.sprintf
1086       "{ family = %s; node = %s; service = %s }"
1087         (string_of_family t.family)
1088         (string_option t.node)
1089         (string_option t.service)
1090
1091     let make (family, node, service) = {
1092       family = family_of_int family;
1093       node = node;
1094       service = service;
1095     }
1096   end
1097
1098   module Graphics_subject = struct
1099     type identity = {
1100       ty: string option;
1101       name: string option;
1102     }
1103
1104     let string_of_identity t = Printf.sprintf
1105       "{ ty = %s; name = %s }"
1106       (string_option t.ty)
1107       (string_option t.name)
1108
1109     type t = identity list
1110
1111     let to_string ts =
1112       "[ " ^ (String.concat "; " (List.map string_of_identity ts)) ^ " ]"
1113
1114     let make xs =
1115       List.map (fun (ty, name) -> { ty = ty; name = name })
1116         (Array.to_list xs)
1117   end
1118
1119   module Graphics = struct
1120     type phase = [
1121       | `Connect
1122       | `Initialize
1123       | `Disconnect
1124       | `Unknown of int (** newer libvirt *)
1125     ]
1126
1127     let string_of_phase = function
1128       | `Connect -> "Connect"
1129       | `Initialize -> "Initialize"
1130       | `Disconnect -> "Disconnect"
1131       | `Unknown x -> Printf.sprintf "Unknown Graphics.phase: %d" x
1132
1133     let phase_of_int = function
1134       | 0 -> `Connect
1135       | 1 -> `Initialize
1136       | 2 -> `Disconnect
1137       | x -> `Unknown x
1138
1139     type t = {
1140       phase: phase;                (** the phase of the connection *)
1141       local: Graphics_address.t;   (** the local server address *)
1142       remote: Graphics_address.t;  (** the remote client address *)
1143       auth_scheme: string option;  (** the authentication scheme activated *)
1144       subject: Graphics_subject.t; (** the authenticated subject (user) *)
1145     }
1146
1147     let to_string t =
1148       let phase = Printf.sprintf "phase = %s"
1149         (string_of_phase t.phase) in
1150       let local = Printf.sprintf "local = %s"
1151         (Graphics_address.to_string t.local) in
1152       let remote = Printf.sprintf "remote = %s"
1153         (Graphics_address.to_string t.remote) in
1154       let auth_scheme = Printf.sprintf "auth_scheme = %s"
1155         (string_option t.auth_scheme) in
1156       let subject = Printf.sprintf "subject = %s"
1157         (Graphics_subject.to_string t.subject) in
1158       "{ " ^ (String.concat "; " [ phase; local; remote; auth_scheme; subject ]) ^ " }"
1159
1160     let make (phase, local, remote, auth_scheme, subject) = {
1161       phase = phase_of_int phase;
1162       local = Graphics_address.make local;
1163       remote = Graphics_address.make remote;
1164       auth_scheme = auth_scheme;
1165       subject = Graphics_subject.make subject;
1166     }
1167   end
1168
1169   module Control_error = struct
1170     type t = unit
1171
1172     let to_string () = "()"
1173
1174     let make () = ()
1175   end
1176
1177   module Block_job = struct
1178     type ty = [
1179       | `KnownUnknown (* explicitly named UNKNOWN in the spec *)
1180       | `Pull
1181       | `Copy
1182       | `Commit
1183       | `Unknown of int (* newer libvirt *)
1184     ]
1185
1186     let string_of_ty = function
1187       | `KnownUnknown -> "KnownUnknown"
1188       | `Pull -> "Pull"
1189       | `Copy -> "Copy"
1190       | `Commit -> "Commit"
1191       | `Unknown x -> Printf.sprintf "Unknown Block_job.ty: %d" x
1192
1193     let ty_of_int = function
1194       | 0 -> `KnownUnknown
1195       | 1 -> `Pull
1196       | 2 -> `Copy
1197       | 3 -> `Commit
1198       | x -> `Unknown x (* newer libvirt *)
1199
1200     type status = [
1201       | `Completed
1202       | `Failed
1203       | `Cancelled
1204       | `Ready
1205       | `Unknown of int
1206     ]
1207
1208     let string_of_status = function
1209       | `Completed -> "Completed"
1210       | `Failed -> "Failed"
1211       | `Cancelled -> "Cancelled"
1212       | `Ready -> "Ready"
1213       | `Unknown x -> Printf.sprintf "Unknown Block_job.status: %d" x
1214
1215     let status_of_int = function
1216       | 0 -> `Completed
1217       | 1 -> `Failed
1218       | 2 -> `Cancelled
1219       | 3 -> `Ready
1220       | x -> `Unknown x
1221
1222     type t = {
1223       disk: string option;
1224       ty: ty;
1225       status: status;
1226     }
1227
1228     let to_string t = Printf.sprintf "{ disk = %s; ty = %s; status = %s }"
1229       (string_option t.disk)
1230       (string_of_ty t.ty)
1231       (string_of_status t.status)
1232
1233     let make (disk, ty, status) = {
1234       disk = disk;
1235       ty = ty_of_int ty;
1236       status = status_of_int ty;
1237     }
1238   end
1239
1240   module Disk_change = struct
1241     type reason = [
1242       | `MissingOnStart
1243       | `Unknown of int
1244     ]
1245
1246     let string_of_reason = function
1247       | `MissingOnStart -> "MissingOnStart"
1248       | `Unknown x -> Printf.sprintf "Unknown Disk_change.reason: %d" x
1249
1250     let reason_of_int = function
1251       | 0 -> `MissingOnStart
1252       | x -> `Unknown x
1253
1254     type t = {
1255       old_src_path: string option;
1256       new_src_path: string option;
1257       dev_alias: string option;
1258       reason: reason;
1259     }
1260
1261     let to_string t =
1262       let o = Printf.sprintf "old_src_path = %s" (string_option t.old_src_path) in
1263       let n = Printf.sprintf "new_src_path = %s" (string_option t.new_src_path) in
1264       let d = Printf.sprintf "dev_alias = %s" (string_option t.dev_alias) in
1265       let r = string_of_reason t.reason in
1266       "{ " ^ (String.concat "; " [ o; n; d; r ]) ^ " }"
1267
1268     let make (o, n, d, r) = {
1269       old_src_path = o;
1270       new_src_path = n;
1271       dev_alias = d;
1272       reason = reason_of_int r;
1273     }
1274   end
1275
1276   module Tray_change = struct
1277     type reason = [
1278       | `Open
1279       | `Close
1280       | `Unknown of int
1281     ]
1282
1283     let string_of_reason = function
1284       | `Open -> "Open"
1285       | `Close -> "Close"
1286       | `Unknown x -> Printf.sprintf "Unknown Tray_change.reason: %d" x
1287
1288     let reason_of_int = function
1289       | 0 -> `Open
1290       | 1 -> `Close
1291       | x -> `Unknown x
1292
1293     type t = {
1294       dev_alias: string option;
1295       reason: reason;
1296     }
1297
1298     let to_string t = Printf.sprintf
1299       "{ dev_alias = %s; reason = %s }"
1300         (string_option t.dev_alias)
1301         (string_of_reason t.reason)
1302
1303     let make (dev_alias, reason) = {
1304       dev_alias = dev_alias;
1305       reason = reason_of_int reason;
1306     }
1307   end
1308
1309   module PM_wakeup = struct
1310     type reason = [
1311       | `Unknown of int
1312     ]
1313
1314     type t = reason
1315
1316     let to_string = function
1317       | `Unknown x -> Printf.sprintf "Unknown PM_wakeup.reason: %d" x
1318
1319     let make x = `Unknown x
1320   end
1321
1322   module PM_suspend = struct
1323     type reason = [
1324       | `Unknown of int
1325     ]
1326
1327     type t = reason
1328
1329     let to_string = function
1330       | `Unknown x -> Printf.sprintf "Unknown PM_suspend.reason: %d" x
1331
1332     let make x = `Unknown x
1333   end
1334
1335   module Balloon_change = struct
1336     type t = int64
1337
1338     let to_string = Int64.to_string
1339     let make x = x
1340   end
1341
1342   module PM_suspend_disk = struct
1343     type reason = [
1344       | `Unknown of int
1345     ]
1346
1347     type t = reason
1348
1349     let to_string = function
1350       | `Unknown x -> Printf.sprintf "Unknown PM_suspend_disk.reason: %d" x
1351
1352     let make x = `Unknown x
1353   end
1354
1355   type callback =
1356     | Lifecycle     of ([`R] Domain.t -> Lifecycle.t -> unit)
1357     | Reboot        of ([`R] Domain.t -> Reboot.t -> unit)
1358     | RtcChange     of ([`R] Domain.t -> Rtc_change.t -> unit)
1359     | Watchdog      of ([`R] Domain.t -> Watchdog.t -> unit)
1360     | IOError       of ([`R] Domain.t -> Io_error.t -> unit)
1361     | Graphics      of ([`R] Domain.t -> Graphics.t -> unit)
1362     | IOErrorReason of ([`R] Domain.t -> Io_error.t -> unit)
1363     | ControlError  of ([`R] Domain.t -> Control_error.t -> unit)
1364     | BlockJob      of ([`R] Domain.t -> Block_job.t -> unit)
1365     | DiskChange    of ([`R] Domain.t -> Disk_change.t -> unit)
1366     | TrayChange    of ([`R] Domain.t -> Tray_change.t -> unit)
1367     | PMWakeUp      of ([`R] Domain.t -> PM_wakeup.t -> unit)
1368     | PMSuspend     of ([`R] Domain.t -> PM_suspend.t -> unit)
1369     | BalloonChange of ([`R] Domain.t -> Balloon_change.t -> unit)
1370     | PMSuspendDisk of ([`R] Domain.t -> PM_suspend_disk.t -> unit)
1371
1372   type callback_id = int64
1373
1374   let fresh_callback_id =
1375     let next = ref 0L in
1376     fun () ->
1377       let result = !next in
1378       next := Int64.succ !next;
1379       result
1380
1381   let make_table value_name =
1382     let table = Hashtbl.create 16 in
1383     let callback callback_id generic x =
1384       if Hashtbl.mem table callback_id
1385       then Hashtbl.find table callback_id generic x in
1386     let _ = Callback.register value_name callback in
1387     table
1388
1389   let u_table = make_table "Libvirt.u_callback"
1390   let i_table = make_table "Libvirt.i_callback"
1391   let i64_table = make_table "Libvirt.i64_callback"
1392   let i_i_table = make_table "Libvirt.i_i_callback"
1393   let s_i_table = make_table "Libvirt.s_i_callback"
1394   let s_i_i_table = make_table "Libvirt.s_i_i_callback"
1395   let s_s_i_table = make_table "Libvirt.s_s_i_callback"
1396   let s_s_i_s_table = make_table "Libvirt.s_s_i_s_callback"
1397   let s_s_s_i_table = make_table "Libvirt.s_s_s_i_callback"
1398   let i_ga_ga_s_gs_table = make_table "Libvirt.i_ga_ga_s_gs_callback"
1399
1400   external register_default_impl : unit -> unit = "ocaml_libvirt_event_register_default_impl"
1401
1402   external run_default_impl : unit -> unit = "ocaml_libvirt_event_run_default_impl"
1403
1404   external register_any' : 'a Connect.t -> 'a Domain.t option -> callback -> callback_id -> int = "ocaml_libvirt_connect_domain_event_register_any"
1405
1406   external deregister_any' : 'a Connect.t -> int -> unit = "ocaml_libvirt_connect_domain_event_deregister_any"
1407
1408   let our_id_to_libvirt_id = Hashtbl.create 16
1409
1410   let register_any conn ?dom callback =
1411     let id = fresh_callback_id () in
1412     begin match callback with
1413     | Lifecycle f ->
1414         Hashtbl.add i_i_table id (fun dom x ->
1415             f dom (Lifecycle.make x)
1416         )
1417     | Reboot f ->
1418         Hashtbl.add u_table id (fun dom x ->
1419             f dom (Reboot.make x)
1420         )
1421     | RtcChange f ->
1422         Hashtbl.add i64_table id (fun dom x ->
1423             f dom (Rtc_change.make x)
1424         )
1425     | Watchdog f ->
1426         Hashtbl.add i_table id (fun dom x ->
1427             f dom (Watchdog.make x)
1428         ) 
1429     | IOError f ->
1430         Hashtbl.add s_s_i_table id (fun dom x ->
1431             f dom (Io_error.make_noreason x)
1432         )
1433     | Graphics f ->
1434         Hashtbl.add i_ga_ga_s_gs_table id (fun dom x ->
1435             f dom (Graphics.make x)
1436         )
1437     | IOErrorReason f ->
1438         Hashtbl.add s_s_i_s_table id (fun dom x ->
1439             f dom (Io_error.make x)
1440         )
1441     | ControlError f ->
1442         Hashtbl.add u_table id (fun dom x ->
1443             f dom (Control_error.make x)
1444         )
1445     | BlockJob f ->
1446         Hashtbl.add s_i_i_table id (fun dom x ->
1447             f dom (Block_job.make x)
1448         )
1449     | DiskChange f ->
1450         Hashtbl.add s_s_s_i_table id (fun dom x ->
1451             f dom (Disk_change.make x)
1452         )
1453     | TrayChange f ->
1454         Hashtbl.add s_i_table id (fun dom x ->
1455             f dom (Tray_change.make x)
1456         )
1457     | PMWakeUp f ->
1458         Hashtbl.add i_table id (fun dom x ->
1459             f dom (PM_wakeup.make x)
1460         )
1461     | PMSuspend f ->
1462         Hashtbl.add i_table id (fun dom x ->
1463             f dom (PM_suspend.make x)
1464         )
1465     | BalloonChange f ->
1466         Hashtbl.add i64_table id (fun dom x ->
1467             f dom (Balloon_change.make x)
1468         )
1469     | PMSuspendDisk f ->
1470         Hashtbl.add i_table id (fun dom x ->
1471             f dom (PM_suspend_disk.make x)
1472         )
1473     end;
1474     let libvirt_id = register_any' conn dom callback id in
1475     Hashtbl.replace our_id_to_libvirt_id id libvirt_id;
1476     id
1477
1478   let deregister_any conn id =
1479     if Hashtbl.mem our_id_to_libvirt_id id then begin
1480       let libvirt_id = Hashtbl.find our_id_to_libvirt_id id in
1481       deregister_any' conn libvirt_id
1482     end;
1483     Hashtbl.remove our_id_to_libvirt_id id;
1484     Hashtbl.remove u_table id;
1485     Hashtbl.remove i_table id;
1486     Hashtbl.remove i64_table id;
1487     Hashtbl.remove i_i_table id;
1488     Hashtbl.remove s_i_table id;
1489     Hashtbl.remove s_i_i_table id;
1490     Hashtbl.remove s_s_i_table id;
1491     Hashtbl.remove s_s_i_s_table id;
1492     Hashtbl.remove s_s_s_i_table id;
1493     Hashtbl.remove i_ga_ga_s_gs_table id
1494
1495   let timeout_table = Hashtbl.create 16
1496   let _ =
1497     let callback x =
1498       if Hashtbl.mem timeout_table x
1499       then Hashtbl.find timeout_table x () in
1500   Callback.register "Libvirt.timeout_callback" callback
1501
1502   type timer_id = int64
1503
1504   external add_timeout' : 'a Connect.t -> int -> int64 -> int = "ocaml_libvirt_event_add_timeout"
1505
1506   external remove_timeout' : 'a Connect.t -> int -> unit = "ocaml_libvirt_event_remove_timeout"
1507
1508   let our_id_to_timer_id = Hashtbl.create 16
1509   let add_timeout conn ms fn =
1510     let id = fresh_callback_id () in
1511     Hashtbl.add timeout_table id fn;
1512     let timer_id = add_timeout' conn ms id in
1513     Hashtbl.add our_id_to_timer_id id timer_id;
1514     id
1515
1516   let remove_timeout conn id =
1517     if Hashtbl.mem our_id_to_timer_id id then begin
1518       let timer_id = Hashtbl.find our_id_to_timer_id id in
1519       remove_timeout' conn timer_id
1520     end;
1521     Hashtbl.remove our_id_to_timer_id id;
1522     Hashtbl.remove timeout_table id
1523 end
1524
1525 module Network =
1526 struct
1527   type 'rw t
1528
1529   external lookup_by_name : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_network_lookup_by_name"
1530   external lookup_by_uuid : 'a Connect.t -> uuid -> 'a t = "ocaml_libvirt_network_lookup_by_uuid"
1531   external lookup_by_uuid_string : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_network_lookup_by_uuid_string"
1532   external create_xml : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_network_create_xml"
1533   external define_xml : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_network_define_xml"
1534   external undefine : [>`W] t -> unit = "ocaml_libvirt_network_undefine"
1535   external create : [>`W] t -> unit = "ocaml_libvirt_network_create"
1536   external destroy : [>`W] t -> unit = "ocaml_libvirt_network_destroy"
1537   external free : [>`R] t -> unit = "ocaml_libvirt_network_free"
1538   external get_name : [>`R] t -> string = "ocaml_libvirt_network_get_name"
1539   external get_uuid : [>`R] t -> uuid = "ocaml_libvirt_network_get_uuid"
1540   external get_uuid_string : [>`R] t -> string = "ocaml_libvirt_network_get_uuid_string"
1541   external get_xml_desc : [>`R] t -> xml = "ocaml_libvirt_network_get_xml_desc"
1542   external get_bridge_name : [>`R] t -> string = "ocaml_libvirt_network_get_bridge_name"
1543   external get_autostart : [>`R] t -> bool = "ocaml_libvirt_network_get_autostart"
1544   external set_autostart : [>`W] t -> bool -> unit = "ocaml_libvirt_network_set_autostart"
1545
1546   external const : [>`R] t -> ro t = "%identity"
1547 end
1548
1549 module Pool =
1550 struct
1551   type 'rw t
1552   type pool_state = Inactive | Building | Running | Degraded
1553   type pool_build_flags = New | Repair | Resize
1554   type pool_delete_flags = Normal | Zeroed
1555   type pool_info = {
1556     state : pool_state;
1557     capacity : int64;
1558     allocation : int64;
1559     available : int64;
1560   }
1561
1562   external lookup_by_name : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_storage_pool_lookup_by_name"
1563   external lookup_by_uuid : 'a Connect.t -> uuid -> 'a t = "ocaml_libvirt_storage_pool_lookup_by_uuid"
1564   external lookup_by_uuid_string : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_storage_pool_lookup_by_uuid_string"
1565   external create_xml : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_storage_pool_create_xml"
1566   external define_xml : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_storage_pool_define_xml"
1567   external build : [>`W] t -> pool_build_flags -> unit = "ocaml_libvirt_storage_pool_build"
1568   external undefine : [>`W] t -> unit = "ocaml_libvirt_storage_pool_undefine"
1569   external create : [>`W] t -> unit = "ocaml_libvirt_storage_pool_create"
1570   external destroy : [>`W] t -> unit = "ocaml_libvirt_storage_pool_destroy"
1571   external delete : [>`W] t -> unit = "ocaml_libvirt_storage_pool_delete"
1572   external free : [>`R] t -> unit = "ocaml_libvirt_storage_pool_free"
1573   external refresh : [`R] t -> unit = "ocaml_libvirt_storage_pool_refresh"
1574   external get_name : [`R] t -> string = "ocaml_libvirt_storage_pool_get_name"
1575   external get_uuid : [`R] t -> uuid = "ocaml_libvirt_storage_pool_get_uuid"
1576   external get_uuid_string : [`R] t -> string = "ocaml_libvirt_storage_pool_get_uuid_string"
1577   external get_info : [`R] t -> pool_info = "ocaml_libvirt_storage_pool_get_info"
1578   external get_xml_desc : [`R] t -> xml = "ocaml_libvirt_storage_pool_get_xml_desc"
1579   external get_autostart : [`R] t -> bool = "ocaml_libvirt_storage_pool_get_autostart"
1580   external set_autostart : [>`W] t -> bool -> unit = "ocaml_libvirt_storage_pool_set_autostart"
1581   external num_of_volumes : [`R] t -> int = "ocaml_libvirt_storage_pool_num_of_volumes"
1582   external list_volumes : [`R] t -> int -> string array = "ocaml_libvirt_storage_pool_list_volumes"
1583   external const : [>`R] t -> ro t = "%identity"
1584 end
1585
1586 module Volume =
1587 struct
1588   type 'rw t
1589   type vol_type = File | Block
1590   type vol_delete_flags = Normal | Zeroed
1591   type vol_info = {
1592     typ : vol_type;
1593     capacity : int64;
1594     allocation : int64;
1595   }
1596
1597   external lookup_by_name : 'a Pool.t -> string -> 'a t = "ocaml_libvirt_storage_vol_lookup_by_name"
1598   external lookup_by_key : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_storage_vol_lookup_by_key"
1599   external lookup_by_path : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_storage_vol_lookup_by_path"
1600   external pool_of_volume : 'a t -> 'a Pool.t = "ocaml_libvirt_storage_pool_lookup_by_volume"
1601   external get_name : [`R] t -> string = "ocaml_libvirt_storage_vol_get_name"
1602   external get_key : [`R] t -> string = "ocaml_libvirt_storage_vol_get_key"
1603   external get_path : [`R] t -> string = "ocaml_libvirt_storage_vol_get_path"
1604   external get_info : [`R] t -> vol_info = "ocaml_libvirt_storage_vol_get_info"
1605   external get_xml_desc : [`R] t -> xml = "ocaml_libvirt_storage_vol_get_xml_desc"
1606   external create_xml : [>`W] Pool.t -> xml -> unit = "ocaml_libvirt_storage_vol_create_xml"
1607   external delete : [>`W] t -> vol_delete_flags -> unit = "ocaml_libvirt_storage_vol_delete"
1608   external free : [>`R] t -> unit = "ocaml_libvirt_storage_vol_free"
1609   external const : [>`R] t -> ro t = "%identity"
1610 end
1611
1612 (* Initialization. *)
1613 external c_init : unit -> unit = "ocaml_libvirt_init"
1614 let () =
1615   Callback.register_exception
1616     "ocaml_libvirt_virterror" (Virterror (Virterror.no_error ()));
1617   Callback.register_exception
1618     "ocaml_libvirt_not_supported" (Not_supported "");
1619   c_init ()