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