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