044d4a200a8a8c2a352d7e89968d945604878e9a
[ocaml-libvirt.git] / libvirt / libvirt.ml
1 (* OCaml bindings for libvirt.
2    (C) Copyright 2007 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
10    This library is distributed in the hope that it will be useful,
11    but WITHOUT ANY WARRANTY; without even the implied warranty of
12    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13    Lesser General Public License for more details.
14
15    You should have received a copy of the GNU Lesser General Public
16    License along with this library; if not, write to the Free Software
17    Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA
18 *)
19
20 type uuid = string
21
22 type xml = string
23
24 type filename = string
25
26 external get_version : ?driver:string -> unit -> int * int = "ocaml_libvirt_get_version"
27
28 let uuid_length = 16
29 let uuid_string_length = 36
30
31 (* http://caml.inria.fr/pub/ml-archives/caml-list/2004/07/80683af867cce6bf8fff273973f70c95.en.html *)
32 type rw = [`R|`W]
33 type ro = [`R]
34
35 type ('a, 'b) job_t
36
37 module Connect =
38 struct
39   type 'rw t
40
41   type node_info = {
42     model : string;
43     memory : int64;
44     cpus : int;
45     mhz : int;
46     nodes : int;
47     sockets : int;
48     cores : int;
49     threads : int;
50   }
51
52   external connect : ?name:string -> unit -> rw t = "ocaml_libvirt_connect_open"
53   external connect_readonly : ?name:string -> unit -> ro t = "ocaml_libvirt_connect_open_readonly"
54   external close : [>`R] t -> unit = "ocaml_libvirt_connect_close"
55   external get_type : [>`R] t -> string = "ocaml_libvirt_connect_get_type"
56   external get_version : [>`R] t -> int = "ocaml_libvirt_connect_get_version"
57   external get_hostname : [>`R] t -> string = "ocaml_libvirt_connect_get_hostname"
58   external get_uri : [>`R] t -> string = "ocaml_libvirt_connect_get_uri"
59   external get_max_vcpus : [>`R] t -> ?type_:string -> unit -> int = "ocaml_libvirt_connect_get_max_vcpus"
60   external list_domains : [>`R] t -> int -> int array = "ocaml_libvirt_connect_list_domains"
61   external num_of_domains : [>`R] t -> int = "ocaml_libvirt_connect_num_of_domains"
62   external get_capabilities : [>`R] t -> xml = "ocaml_libvirt_connect_get_capabilities"
63   external num_of_defined_domains : [>`R] t -> int = "ocaml_libvirt_connect_num_of_defined_domains"
64   external list_defined_domains : [>`R] t -> int -> string array = "ocaml_libvirt_connect_list_defined_domains"
65   external num_of_networks : [>`R] t -> int = "ocaml_libvirt_connect_num_of_networks"
66   external list_networks : [>`R] t -> int -> string array = "ocaml_libvirt_connect_list_networks"
67   external num_of_defined_networks : [>`R] t -> int = "ocaml_libvirt_connect_num_of_defined_networks"
68   external list_defined_networks : [>`R] t -> int -> string array = "ocaml_libvirt_connect_list_defined_networks"
69   external num_of_pools : [>`R] t -> int = "ocaml_libvirt_connect_num_of_storage_pools"
70   external list_pools : [>`R] t -> int -> string array = "ocaml_libvirt_connect_list_storage_pools"
71   external num_of_defined_pools : [>`R] t -> int = "ocaml_libvirt_connect_num_of_defined_storage_pools"
72   external list_defined_pools : [>`R] t -> int -> string array = "ocaml_libvirt_connect_list_defined_storage_pools"
73
74   external get_node_info : [>`R] t -> node_info = "ocaml_libvirt_connect_get_node_info"
75   external node_get_free_memory : [> `R] t -> int64 = "ocaml_libvirt_connect_node_get_free_memory"
76   external node_get_cells_free_memory : [> `R] t -> int -> int -> int64 array = "ocaml_libvirt_connect_node_get_cells_free_memory"
77
78   (* See VIR_NODEINFO_MAXCPUS macro defined in <libvirt.h>. *)
79   let maxcpus_of_node_info { nodes = nodes; sockets = sockets;
80                              cores = cores; threads = threads } =
81     nodes * sockets * cores * threads
82
83   (* See VIR_CPU_MAPLEN macro defined in <libvirt.h>. *)
84   let cpumaplen nr_cpus =
85     (nr_cpus + 7) / 8
86
87   (* See VIR_USE_CPU, VIR_UNUSE_CPU, VIR_CPU_USABLE macros defined in <libvirt.h>. *)
88   let use_cpu cpumap cpu =
89     cpumap.[cpu/8] <-
90       Char.chr (Char.code cpumap.[cpu/8] lor (1 lsl (cpu mod 8)))
91   let unuse_cpu cpumap cpu =
92     cpumap.[cpu/8] <-
93       Char.chr (Char.code cpumap.[cpu/8] land (lnot (1 lsl (cpu mod 8))))
94   let cpu_usable cpumaps maplen vcpu cpu =
95     Char.code cpumaps.[vcpu*maplen + cpu/8] land (1 lsl (cpu mod 8)) <> 0
96
97   external const : [>`R] t -> ro t = "%identity"
98 end
99
100 module Domain =
101 struct
102   type 'rw t
103
104   type state =
105     | InfoNoState | InfoRunning | InfoBlocked | InfoPaused
106     | InfoShutdown | InfoShutoff | InfoCrashed
107
108   type info = {
109     state : state;
110     max_mem : int64;
111     memory : int64;
112     nr_virt_cpu : int;
113     cpu_time : int64;
114   }
115
116   type vcpu_state = VcpuOffline | VcpuRunning | VcpuBlocked
117
118   type vcpu_info = {
119     number : int;
120     vcpu_state : vcpu_state;
121     vcpu_time : int64;
122     cpu : int;
123   }
124
125   type sched_param = string * sched_param_value
126   and sched_param_value =
127     | SchedFieldInt32 of int32 | SchedFieldUInt32 of int32
128     | SchedFieldInt64 of int64 | SchedFieldUInt64 of int64
129     | SchedFieldFloat of float | SchedFieldBool of bool
130
131   type migrate_flag = Live
132
133   type memory_flag = Virtual
134
135   type block_stats = {
136     rd_req : int64;
137     rd_bytes : int64;
138     wr_req : int64;
139     wr_bytes : int64;
140     errs : int64;
141   }
142
143   type interface_stats = {
144     rx_bytes : int64;
145     rx_packets : int64;
146     rx_errs : int64;
147     rx_drop : int64;
148     tx_bytes : int64;
149     tx_packets : int64;
150     tx_errs : int64;
151     tx_drop : int64;
152   }
153
154   external create_linux : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_domain_create_linux"
155   external create_linux_job : [>`W] Connect.t -> xml -> ([`Domain], rw) job_t = "ocaml_libvirt_domain_create_linux_job"
156   external lookup_by_id : 'a Connect.t -> int -> 'a t = "ocaml_libvirt_domain_lookup_by_id"
157   external lookup_by_uuid : 'a Connect.t -> uuid -> 'a t = "ocaml_libvirt_domain_lookup_by_uuid"
158   external lookup_by_uuid_string : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_domain_lookup_by_uuid_string"
159   external lookup_by_name : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_domain_lookup_by_name"
160   external destroy : [>`W] t -> unit = "ocaml_libvirt_domain_destroy"
161   external free : [>`R] t -> unit = "ocaml_libvirt_domain_free"
162   external suspend : [>`W] t -> unit = "ocaml_libvirt_domain_suspend"
163   external resume : [>`W] t -> unit = "ocaml_libvirt_domain_resume"
164   external save : [>`W] t -> filename -> unit = "ocaml_libvirt_domain_save"
165   external save_job : [>`W] t -> filename -> ([`Domain_nocreate], rw) job_t = "ocaml_libvirt_domain_save_job"
166   external restore : [>`W] Connect.t -> filename -> unit = "ocaml_libvirt_domain_restore"
167   external restore_job : [>`W] Connect.t -> filename -> ([`Domain_nocreate], rw) job_t = "ocaml_libvirt_domain_restore_job"
168   external core_dump : [>`W] t -> filename -> unit = "ocaml_libvirt_domain_core_dump"
169   external core_dump_job : [>`W] t -> filename -> ([`Domain_nocreate], rw) job_t = "ocaml_libvirt_domain_core_dump_job"
170   external shutdown : [>`W] t -> unit = "ocaml_libvirt_domain_shutdown"
171   external reboot : [>`W] t -> unit = "ocaml_libvirt_domain_reboot"
172   external get_name : [>`R] t -> string = "ocaml_libvirt_domain_get_name"
173   external get_uuid : [>`R] t -> uuid = "ocaml_libvirt_domain_get_uuid"
174   external get_uuid_string : [>`R] t -> string = "ocaml_libvirt_domain_get_uuid_string"
175   external get_id : [>`R] t -> int = "ocaml_libvirt_domain_get_id"
176   external get_os_type : [>`R] t -> string = "ocaml_libvirt_domain_get_os_type"
177   external get_max_memory : [>`R] t -> int64 = "ocaml_libvirt_domain_get_max_memory"
178   external set_max_memory : [>`W] t -> int64 -> unit = "ocaml_libvirt_domain_set_max_memory"
179   external set_memory : [>`W] t -> int64 -> unit = "ocaml_libvirt_domain_set_memory"
180   external get_info : [>`R] t -> info = "ocaml_libvirt_domain_get_info"
181   external get_xml_desc : [>`R] t -> xml = "ocaml_libvirt_domain_get_xml_desc"
182   external get_scheduler_type : [>`R] t -> string * int = "ocaml_libvirt_domain_get_scheduler_type"
183   external get_scheduler_parameters : [>`R] t -> int -> sched_param array = "ocaml_libvirt_domain_get_scheduler_parameters"
184   external set_scheduler_parameters : [>`W] t -> sched_param array -> unit = "ocaml_libvirt_domain_set_scheduler_parameters"
185   external define_xml : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_domain_define_xml"
186   external undefine : [>`W] t -> unit = "ocaml_libvirt_domain_undefine"
187   external create : [>`W] t -> unit = "ocaml_libvirt_domain_create"
188   external create_job : [>`W] t -> ([`Domain_nocreate], rw) job_t = "ocaml_libvirt_domain_create_job"
189   external get_autostart : [>`R] t -> bool = "ocaml_libvirt_domain_get_autostart"
190   external set_autostart : [>`W] t -> bool -> unit = "ocaml_libvirt_domain_set_autostart"
191   external set_vcpus : [>`W] t -> int -> unit = "ocaml_libvirt_domain_set_vcpus"
192   external pin_vcpu : [>`W] t -> int -> string -> unit = "ocaml_libvirt_domain_pin_vcpu"
193   external get_vcpus : [>`R] t -> int -> int -> int * vcpu_info array * string = "ocaml_libvirt_domain_get_vcpus"
194   external get_max_vcpus : [>`R] t -> int = "ocaml_libvirt_domain_get_max_vcpus"
195   external attach_device : [>`W] t -> xml -> unit = "ocaml_libvirt_domain_attach_device"
196   external detach_device : [>`W] t -> xml -> unit = "ocaml_libvirt_domain_detach_device"
197   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"
198   external block_stats : [>`R] t -> string -> block_stats = "ocaml_libvirt_domain_block_stats"
199   external interface_stats : [>`R] t -> string -> interface_stats = "ocaml_libvirt_domain_interface_stats"
200   external block_peek : [>`R] t -> string -> int64 -> int -> string -> int -> unit = "ocaml_libvirt_domain_block_peek_bytecode" "ocaml_libvirt_domain_block_peek_native"
201   external memory_peek : [>`R] t -> memory_flag -> int64 -> int -> string -> int -> unit = "ocaml_libvirt_domain_memory_peek_bytecode" "ocaml_libvirt_domain_memory_peek_native"
202
203   external const : [>`R] t -> ro t = "%identity"
204 end
205
206 module Network =
207 struct
208   type 'rw t
209
210   external lookup_by_name : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_network_lookup_by_name"
211   external lookup_by_uuid : 'a Connect.t -> uuid -> 'a t = "ocaml_libvirt_network_lookup_by_uuid"
212   external lookup_by_uuid_string : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_network_lookup_by_uuid_string"
213   external create_xml : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_network_create_xml"
214   external create_xml_job : [>`W] Connect.t -> xml -> ([`Network], rw) job_t = "ocaml_libvirt_network_create_xml_job"
215   external define_xml : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_network_define_xml"
216   external undefine : [>`W] t -> unit = "ocaml_libvirt_network_undefine"
217   external create : [>`W] t -> unit = "ocaml_libvirt_network_create"
218   external create_job : [>`W] t -> ([`Network_nocreate], rw) job_t = "ocaml_libvirt_network_create_job"
219   external destroy : [>`W] t -> unit = "ocaml_libvirt_network_destroy"
220   external free : [>`R] t -> unit = "ocaml_libvirt_network_free"
221   external get_name : [>`R] t -> string = "ocaml_libvirt_network_get_name"
222   external get_uuid : [>`R] t -> uuid = "ocaml_libvirt_network_get_uuid"
223   external get_uuid_string : [>`R] t -> string = "ocaml_libvirt_network_get_uuid_string"
224   external get_xml_desc : [>`R] t -> xml = "ocaml_libvirt_network_get_xml_desc"
225   external get_bridge_name : [>`R] t -> string = "ocaml_libvirt_network_get_bridge_name"
226   external get_autostart : [>`R] t -> bool = "ocaml_libvirt_network_get_autostart"
227   external set_autostart : [>`W] t -> bool -> unit = "ocaml_libvirt_network_set_autostart"
228
229   external const : [>`R] t -> ro t = "%identity"
230 end
231
232 module Pool =
233 struct
234   type 'rw t
235   type pool_state = Inactive | Building | Running | Degraded
236   type pool_build_flags = New | Repair | Resize
237   type pool_delete_flags = Normal | Zeroed
238   type pool_info = {
239     state : pool_state;
240     capacity : int64;
241     allocation : int64;
242     available : int64;
243   }
244
245   external lookup_by_name : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_storage_pool_lookup_by_name"
246   external lookup_by_uuid : 'a Connect.t -> uuid -> 'a t = "ocaml_libvirt_storage_pool_lookup_by_uuid"
247   external lookup_by_uuid_string : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_storage_pool_lookup_by_uuid_string"
248   external create_xml : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_storage_pool_create_xml"
249   external define_xml : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_storage_pool_define_xml"
250   external build : [>`W] t -> pool_build_flags -> unit = "ocaml_libvirt_storage_pool_build"
251   external undefine : [>`W] t -> unit = "ocaml_libvirt_storage_pool_undefine"
252   external create : [>`W] t -> unit = "ocaml_libvirt_storage_pool_create"
253   external destroy : [>`W] t -> unit = "ocaml_libvirt_storage_pool_destroy"
254   external delete : [>`W] t -> unit = "ocaml_libvirt_storage_pool_delete"
255   external free : [>`R] t -> unit = "ocaml_libvirt_storage_pool_free"
256   external refresh : [`R] t -> unit = "ocaml_libvirt_storage_pool_refresh"
257   external get_name : [`R] t -> string = "ocaml_libvirt_storage_pool_get_name"
258   external get_uuid : [`R] t -> uuid = "ocaml_libvirt_storage_pool_get_uuid"
259   external get_uuid_string : [`R] t -> string = "ocaml_libvirt_storage_pool_get_uuid_string"
260   external get_info : [`R] t -> pool_info = "ocaml_libvirt_storage_pool_get_info"
261   external get_xml_desc : [`R] t -> xml = "ocaml_libvirt_storage_pool_get_xml_desc"
262   external get_autostart : [`R] t -> bool = "ocaml_libvirt_storage_pool_get_autostart"
263   external set_autostart : [`W] t -> bool -> unit = "ocaml_libvirt_storage_pool_set_autostart"
264   external num_of_volumes : [`R] t -> int = "ocaml_libvirt_storage_pool_num_of_volumes"
265   external list_volumes : [`R] t -> int -> string array = "ocaml_libvirt_storage_pool_list_volumes"
266   external const : [>`R] t -> ro t = "%identity"
267 end
268
269 module Volume =
270 struct
271   type 'rw t
272   type vol_type = File | Block
273   type vol_delete_flags = Normal | Zeroed
274   type vol_info = {
275     typ : vol_type;
276     capacity : int64;
277     allocation : int64;
278   }
279
280   external lookup_by_name : 'a Pool.t -> string -> 'a t = "ocaml_libvirt_storage_vol_lookup_by_name"
281   external lookup_by_key : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_storage_vol_lookup_by_key"
282   external lookup_by_path : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_storage_vol_lookup_by_path"
283   external pool_of_volume : 'a t -> 'a Pool.t = "ocaml_libvirt_storage_pool_lookup_by_volume"
284   external get_name : [`R] t -> string = "ocaml_libvirt_storage_vol_get_name"
285   external get_key : [`R] t -> string = "ocaml_libvirt_storage_vol_get_key"
286   external get_path : [`R] t -> string = "ocaml_libvirt_storage_vol_get_path"
287   external get_info : [`R] t -> vol_info = "ocaml_libvirt_storage_vol_get_info"
288   external get_xml_desc : [`R] t -> xml = "ocaml_libvirt_storage_vol_get_xml_desc"
289   external create_xml : [`W] Pool.t -> xml -> unit = "ocaml_libvirt_storage_vol_create_xml"
290   external delete : [`W] t -> unit = "ocaml_libvirt_storage_vol_delete"
291   external free : [>`R] t -> unit = "ocaml_libvirt_storage_vol_free"
292   external const : [>`R] t -> ro t = "%identity"
293 end
294
295 module Job =
296 struct
297   type ('jobclass, 'rw) t = ('jobclass, 'rw) job_t
298   type job_type = Bounded | Unbounded
299   type job_state = Running | Complete | Failed | Cancelled
300   type job_info = {
301     typ : job_type;
302     state : job_state;
303     running_time : int;
304     remaining_time : int;
305     percent_complete : int
306   }
307   external get_info : ('a,'b) t -> job_info = "ocaml_libvirt_job_get_info"
308   external get_domain : ([`Domain], 'a) t -> 'a Domain.t = "ocaml_libvirt_job_get_domain"
309   external get_network : ([`Network], 'a) t -> 'a Network.t = "ocaml_libvirt_job_get_network"
310   external cancel : ('a,'b) t -> unit = "ocaml_libvirt_job_cancel"
311   external free : ('a, [>`R]) t -> unit = "ocaml_libvirt_job_free"
312   external const : ('a, [>`R]) t -> ('a, ro) t = "%identity"
313 end
314
315 module Virterror =
316 struct
317   type code =
318     | VIR_ERR_OK
319     | VIR_ERR_INTERNAL_ERROR
320     | VIR_ERR_NO_MEMORY
321     | VIR_ERR_NO_SUPPORT
322     | VIR_ERR_UNKNOWN_HOST
323     | VIR_ERR_NO_CONNECT
324     | VIR_ERR_INVALID_CONN
325     | VIR_ERR_INVALID_DOMAIN
326     | VIR_ERR_INVALID_ARG
327     | VIR_ERR_OPERATION_FAILED
328     | VIR_ERR_GET_FAILED
329     | VIR_ERR_POST_FAILED
330     | VIR_ERR_HTTP_ERROR
331     | VIR_ERR_SEXPR_SERIAL
332     | VIR_ERR_NO_XEN
333     | VIR_ERR_XEN_CALL
334     | VIR_ERR_OS_TYPE
335     | VIR_ERR_NO_KERNEL
336     | VIR_ERR_NO_ROOT
337     | VIR_ERR_NO_SOURCE
338     | VIR_ERR_NO_TARGET
339     | VIR_ERR_NO_NAME
340     | VIR_ERR_NO_OS
341     | VIR_ERR_NO_DEVICE
342     | VIR_ERR_NO_XENSTORE
343     | VIR_ERR_DRIVER_FULL
344     | VIR_ERR_CALL_FAILED
345     | VIR_ERR_XML_ERROR
346     | VIR_ERR_DOM_EXIST
347     | VIR_ERR_OPERATION_DENIED
348     | VIR_ERR_OPEN_FAILED
349     | VIR_ERR_READ_FAILED
350     | VIR_ERR_PARSE_FAILED
351     | VIR_ERR_CONF_SYNTAX
352     | VIR_ERR_WRITE_FAILED
353     | VIR_ERR_XML_DETAIL
354     | VIR_ERR_INVALID_NETWORK
355     | VIR_ERR_NETWORK_EXIST
356     | VIR_ERR_SYSTEM_ERROR
357     | VIR_ERR_RPC
358     | VIR_ERR_GNUTLS_ERROR
359     | VIR_WAR_NO_NETWORK
360     | VIR_ERR_NO_DOMAIN
361     | VIR_ERR_NO_NETWORK
362     | VIR_ERR_INVALID_MAC
363     | VIR_ERR_AUTH_FAILED
364     | VIR_ERR_INVALID_STORAGE_POOL
365     | VIR_ERR_INVALID_STORAGE_VOL
366     | VIR_WAR_NO_STORAGE
367     | VIR_ERR_NO_STORAGE_POOL
368     | VIR_ERR_NO_STORAGE_VOL
369     | VIR_ERR_UNKNOWN of int
370
371   let string_of_code = function
372     | VIR_ERR_OK -> "VIR_ERR_OK"
373     | VIR_ERR_INTERNAL_ERROR -> "VIR_ERR_INTERNAL_ERROR"
374     | VIR_ERR_NO_MEMORY -> "VIR_ERR_NO_MEMORY"
375     | VIR_ERR_NO_SUPPORT -> "VIR_ERR_NO_SUPPORT"
376     | VIR_ERR_UNKNOWN_HOST -> "VIR_ERR_UNKNOWN_HOST"
377     | VIR_ERR_NO_CONNECT -> "VIR_ERR_NO_CONNECT"
378     | VIR_ERR_INVALID_CONN -> "VIR_ERR_INVALID_CONN"
379     | VIR_ERR_INVALID_DOMAIN -> "VIR_ERR_INVALID_DOMAIN"
380     | VIR_ERR_INVALID_ARG -> "VIR_ERR_INVALID_ARG"
381     | VIR_ERR_OPERATION_FAILED -> "VIR_ERR_OPERATION_FAILED"
382     | VIR_ERR_GET_FAILED -> "VIR_ERR_GET_FAILED"
383     | VIR_ERR_POST_FAILED -> "VIR_ERR_POST_FAILED"
384     | VIR_ERR_HTTP_ERROR -> "VIR_ERR_HTTP_ERROR"
385     | VIR_ERR_SEXPR_SERIAL -> "VIR_ERR_SEXPR_SERIAL"
386     | VIR_ERR_NO_XEN -> "VIR_ERR_NO_XEN"
387     | VIR_ERR_XEN_CALL -> "VIR_ERR_XEN_CALL"
388     | VIR_ERR_OS_TYPE -> "VIR_ERR_OS_TYPE"
389     | VIR_ERR_NO_KERNEL -> "VIR_ERR_NO_KERNEL"
390     | VIR_ERR_NO_ROOT -> "VIR_ERR_NO_ROOT"
391     | VIR_ERR_NO_SOURCE -> "VIR_ERR_NO_SOURCE"
392     | VIR_ERR_NO_TARGET -> "VIR_ERR_NO_TARGET"
393     | VIR_ERR_NO_NAME -> "VIR_ERR_NO_NAME"
394     | VIR_ERR_NO_OS -> "VIR_ERR_NO_OS"
395     | VIR_ERR_NO_DEVICE -> "VIR_ERR_NO_DEVICE"
396     | VIR_ERR_NO_XENSTORE -> "VIR_ERR_NO_XENSTORE"
397     | VIR_ERR_DRIVER_FULL -> "VIR_ERR_DRIVER_FULL"
398     | VIR_ERR_CALL_FAILED -> "VIR_ERR_CALL_FAILED"
399     | VIR_ERR_XML_ERROR -> "VIR_ERR_XML_ERROR"
400     | VIR_ERR_DOM_EXIST -> "VIR_ERR_DOM_EXIST"
401     | VIR_ERR_OPERATION_DENIED -> "VIR_ERR_OPERATION_DENIED"
402     | VIR_ERR_OPEN_FAILED -> "VIR_ERR_OPEN_FAILED"
403     | VIR_ERR_READ_FAILED -> "VIR_ERR_READ_FAILED"
404     | VIR_ERR_PARSE_FAILED -> "VIR_ERR_PARSE_FAILED"
405     | VIR_ERR_CONF_SYNTAX -> "VIR_ERR_CONF_SYNTAX"
406     | VIR_ERR_WRITE_FAILED -> "VIR_ERR_WRITE_FAILED"
407     | VIR_ERR_XML_DETAIL -> "VIR_ERR_XML_DETAIL"
408     | VIR_ERR_INVALID_NETWORK -> "VIR_ERR_INVALID_NETWORK"
409     | VIR_ERR_NETWORK_EXIST -> "VIR_ERR_NETWORK_EXIST"
410     | VIR_ERR_SYSTEM_ERROR -> "VIR_ERR_SYSTEM_ERROR"
411     | VIR_ERR_RPC -> "VIR_ERR_RPC"
412     | VIR_ERR_GNUTLS_ERROR -> "VIR_ERR_GNUTLS_ERROR"
413     | VIR_WAR_NO_NETWORK -> "VIR_WAR_NO_NETWORK"
414     | VIR_ERR_NO_DOMAIN -> "VIR_ERR_NO_DOMAIN"
415     | VIR_ERR_NO_NETWORK -> "VIR_ERR_NO_NETWORK"
416     | VIR_ERR_INVALID_MAC -> "VIR_ERR_INVALID_MAC"
417     | VIR_ERR_AUTH_FAILED -> "VIR_ERR_AUTH_FAILED"
418     | VIR_ERR_INVALID_STORAGE_POOL -> "VIR_ERR_INVALID_STORAGE_POOL"
419     | VIR_ERR_INVALID_STORAGE_VOL -> "VIR_ERR_INVALID_STORAGE_VOL"
420     | VIR_WAR_NO_STORAGE -> "VIR_WAR_NO_STORAGE"
421     | VIR_ERR_NO_STORAGE_POOL -> "VIR_ERR_NO_STORAGE_POOL"
422     | VIR_ERR_NO_STORAGE_VOL -> "VIR_ERR_NO_STORAGE_VOL"
423     | VIR_ERR_UNKNOWN i -> "VIR_ERR_" ^ string_of_int i
424
425   type domain =
426     | VIR_FROM_NONE
427     | VIR_FROM_XEN
428     | VIR_FROM_XEND
429     | VIR_FROM_XENSTORE
430     | VIR_FROM_SEXPR
431     | VIR_FROM_XML
432     | VIR_FROM_DOM
433     | VIR_FROM_RPC
434     | VIR_FROM_PROXY
435     | VIR_FROM_CONF
436     | VIR_FROM_QEMU
437     | VIR_FROM_NET
438     | VIR_FROM_TEST
439     | VIR_FROM_REMOTE
440     | VIR_FROM_OPENVZ
441     | VIR_FROM_XENXM
442     | VIR_FROM_STATS_LINUX
443     | VIR_FROM_STORAGE
444     | VIR_FROM_UNKNOWN of int
445
446   let string_of_domain = function
447     | VIR_FROM_NONE -> "VIR_FROM_NONE"
448     | VIR_FROM_XEN -> "VIR_FROM_XEN"
449     | VIR_FROM_XEND -> "VIR_FROM_XEND"
450     | VIR_FROM_XENSTORE -> "VIR_FROM_XENSTORE"
451     | VIR_FROM_SEXPR -> "VIR_FROM_SEXPR"
452     | VIR_FROM_XML -> "VIR_FROM_XML"
453     | VIR_FROM_DOM -> "VIR_FROM_DOM"
454     | VIR_FROM_RPC -> "VIR_FROM_RPC"
455     | VIR_FROM_PROXY -> "VIR_FROM_PROXY"
456     | VIR_FROM_CONF -> "VIR_FROM_CONF"
457     | VIR_FROM_QEMU -> "VIR_FROM_QEMU"
458     | VIR_FROM_NET -> "VIR_FROM_NET"
459     | VIR_FROM_TEST -> "VIR_FROM_TEST"
460     | VIR_FROM_REMOTE -> "VIR_FROM_REMOTE"
461     | VIR_FROM_OPENVZ -> "VIR_FROM_OPENVZ"
462     | VIR_FROM_XENXM -> "VIR_FROM_XENXM"
463     | VIR_FROM_STATS_LINUX -> "VIR_FROM_STATS_LINUX"
464     | VIR_FROM_STORAGE -> "VIR_FROM_STORAGE"
465     | VIR_FROM_UNKNOWN i -> "VIR_FROM_" ^ string_of_int i
466
467   type level =
468     | VIR_ERR_NONE
469     | VIR_ERR_WARNING
470     | VIR_ERR_ERROR
471     | VIR_ERR_UNKNOWN_LEVEL of int
472
473   let string_of_level = function
474     | VIR_ERR_NONE -> "VIR_ERR_NONE"
475     | VIR_ERR_WARNING -> "VIR_ERR_WARNING"
476     | VIR_ERR_ERROR -> "VIR_ERR_ERROR"
477     | VIR_ERR_UNKNOWN_LEVEL i -> "VIR_ERR_LEVEL_" ^ string_of_int i
478
479   type t = {
480     code : code;
481     domain : domain;
482     message : string option;
483     level : level;
484     str1 : string option;
485     str2 : string option;
486     str3 : string option;
487     int1 : int32;
488     int2 : int32;
489   }
490
491   let to_string { code = code; domain = domain; message = message } =
492     let buf = Buffer.create 128 in
493     Buffer.add_string buf "libvirt: ";
494     Buffer.add_string buf (string_of_code code);
495     Buffer.add_string buf ": ";
496     Buffer.add_string buf (string_of_domain domain);
497     Buffer.add_string buf ": ";
498     (match message with Some msg -> Buffer.add_string buf msg | None -> ());
499     Buffer.contents buf
500
501   external get_last_error : unit -> t option = "ocaml_libvirt_virterror_get_last_error"
502   external get_last_conn_error : [>`R] Connect.t -> t option = "ocaml_libvirt_virterror_get_last_conn_error"
503   external reset_last_error : unit -> unit = "ocaml_libvirt_virterror_reset_last_error"
504   external reset_last_conn_error : [>`R] Connect.t -> unit = "ocaml_libvirt_virterror_reset_last_conn_error"
505
506   let no_error () =
507     { code = VIR_ERR_OK; domain = VIR_FROM_NONE;
508       message = None; level = VIR_ERR_NONE;
509       str1 = None; str2 = None; str3 = None;
510       int1 = 0_l; int2 = 0_l }
511 end
512
513 exception Virterror of Virterror.t
514 exception Not_supported of string
515
516 (* Initialization. *)
517 external c_init : unit -> unit = "ocaml_libvirt_init"
518 let () =
519   Callback.register_exception
520     "ocaml_libvirt_virterror" (Virterror (Virterror.no_error ()));
521   Callback.register_exception
522     "ocaml_libvirt_not_supported" (Not_supported "");
523   c_init ()