New exception Libvirt.Not_supported "function"
[virt-top.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 module Connect =
36 struct
37   type 'rw t
38
39   type node_info = {
40     model : string;
41     memory : int64;
42     cpus : int;
43     mhz : int;
44     nodes : int;
45     sockets : int;
46     cores : int;
47     threads : int;
48   }
49
50   external connect : ?name:string -> unit -> rw t = "ocaml_libvirt_connect_open"
51   external connect_readonly : ?name:string -> unit -> ro t = "ocaml_libvirt_connect_open_readonly"
52   external close : [>`R] t -> unit = "ocaml_libvirt_connect_close"
53   external get_type : [>`R] t -> string = "ocaml_libvirt_connect_get_type"
54   external get_version : [>`R] t -> int = "ocaml_libvirt_connect_get_version"
55   external get_hostname : [>`R] t -> string = "ocaml_libvirt_connect_get_hostname"
56   external get_uri : [>`R] t -> string = "ocaml_libvirt_connect_get_uri"
57   external get_max_vcpus : [>`R] t -> ?type_:string -> unit -> int = "ocaml_libvirt_connect_get_max_vcpus"
58   external list_domains : [>`R] t -> int -> int array = "ocaml_libvirt_connect_list_domains"
59   external num_of_domains : [>`R] t -> int = "ocaml_libvirt_connect_num_of_domains"
60   external get_capabilities : [>`R] t -> xml = "ocaml_libvirt_connect_get_capabilities"
61   external num_of_defined_domains : [>`R] t -> int = "ocaml_libvirt_connect_num_of_defined_domains"
62   external list_defined_domains : [>`R] t -> int -> string array = "ocaml_libvirt_connect_list_defined_domains"
63   external num_of_networks : [>`R] t -> int = "ocaml_libvirt_connect_num_of_networks"
64   external list_networks : [>`R] t -> int -> string array = "ocaml_libvirt_connect_list_networks"
65   external num_of_defined_networks : [>`R] t -> int = "ocaml_libvirt_connect_num_of_defined_networks"
66   external list_defined_networks : [>`R] t -> int -> string array = "ocaml_libvirt_connect_list_defined_networks"
67   external get_node_info : [>`R] t -> node_info = "ocaml_libvirt_connect_get_node_info"
68   external node_get_free_memory : [> `R] t -> int64 = "ocaml_libvirt_connect_node_get_free_memory"
69   external node_get_cells_free_memory : [> `R] t -> int -> int -> int64 array = "ocaml_libvirt_connect_node_get_cells_free_memory"
70
71   (* See VIR_NODEINFO_MAXCPUS macro defined in <libvirt.h>. *)
72   let maxcpus_of_node_info { nodes = nodes; sockets = sockets;
73                              cores = cores; threads = threads } =
74     nodes * sockets * cores * threads
75
76   (* See VIR_CPU_MAPLEN macro defined in <libvirt.h>. *)
77   let cpumaplen nr_cpus =
78     (nr_cpus + 7) / 8
79
80   (* See VIR_USE_CPU, VIR_UNUSE_CPU, VIR_CPU_USABLE macros defined in <libvirt.h>. *)
81   let use_cpu cpumap cpu =
82     cpumap.[cpu/8] <-
83       Char.chr (Char.code cpumap.[cpu/8] lor (1 lsl (cpu mod 8)))
84   let unuse_cpu cpumap cpu =
85     cpumap.[cpu/8] <-
86       Char.chr (Char.code cpumap.[cpu/8] land (lnot (1 lsl (cpu mod 8))))
87   let cpu_usable cpumaps maplen vcpu cpu =
88     Char.code cpumaps.[vcpu*maplen + cpu/8] land (1 lsl (cpu mod 8)) <> 0
89
90   external const : [>`R] t -> ro t = "%identity"
91 end
92
93 module Domain =
94 struct
95   type 'rw dom
96   type 'rw t = 'rw dom * 'rw Connect.t
97
98   type state =
99     | InfoNoState | InfoRunning | InfoBlocked | InfoPaused
100     | InfoShutdown | InfoShutoff | InfoCrashed
101
102   type info = {
103     state : state;
104     max_mem : int64;
105     memory : int64;
106     nr_virt_cpu : int;
107     cpu_time : int64;
108   }
109
110   type vcpu_state = VcpuOffline | VcpuRunning | VcpuBlocked
111
112   type vcpu_info = {
113     number : int;
114     vcpu_state : vcpu_state;
115     vcpu_time : int64;
116     cpu : int;
117   }
118
119   type sched_param = string * sched_param_value
120   and sched_param_value =
121     | SchedFieldInt32 of int32 | SchedFieldUInt32 of int32
122     | SchedFieldInt64 of int64 | SchedFieldUInt64 of int64
123     | SchedFieldFloat of float | SchedFieldBool of bool
124
125   type migrate_flag = Live
126
127   type block_stats = {
128     rd_req : int64;
129     rd_bytes : int64;
130     wr_req : int64;
131     wr_bytes : int64;
132     errs : int64;
133   }
134
135   type interface_stats = {
136     rx_bytes : int64;
137     rx_packets : int64;
138     rx_errs : int64;
139     rx_drop : int64;
140     tx_bytes : int64;
141     tx_packets : int64;
142     tx_errs : int64;
143     tx_drop : int64;
144   }
145
146   external create_linux : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_domain_create_linux"
147   external lookup_by_id : 'a Connect.t -> int -> 'a t = "ocaml_libvirt_domain_lookup_by_id"
148   external lookup_by_uuid : 'a Connect.t -> uuid -> 'a t = "ocaml_libvirt_domain_lookup_by_uuid"
149   external lookup_by_uuid_string : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_domain_lookup_by_uuid_string"
150   external lookup_by_name : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_domain_lookup_by_name"
151   external destroy : [>`W] t -> unit = "ocaml_libvirt_domain_destroy"
152   external free : [>`R] t -> unit = "ocaml_libvirt_domain_free"
153   external suspend : [>`W] t -> unit = "ocaml_libvirt_domain_suspend"
154   external resume : [>`W] t -> unit = "ocaml_libvirt_domain_resume"
155   external save : [>`W] t -> filename -> unit = "ocaml_libvirt_domain_save"
156   external restore : [>`W] Connect.t -> filename -> unit = "ocaml_libvirt_domain_restore"
157   external core_dump : [>`W] t -> filename -> unit = "ocaml_libvirt_domain_core_dump"
158   external shutdown : [>`W] t -> unit = "ocaml_libvirt_domain_shutdown"
159   external reboot : [>`W] t -> unit = "ocaml_libvirt_domain_reboot"
160   external get_name : [>`R] t -> string = "ocaml_libvirt_domain_get_name"
161   external get_uuid : [>`R] t -> uuid = "ocaml_libvirt_domain_get_uuid"
162   external get_uuid_string : [>`R] t -> string = "ocaml_libvirt_domain_get_uuid_string"
163   external get_id : [>`R] t -> int = "ocaml_libvirt_domain_get_id"
164   external get_os_type : [>`R] t -> string = "ocaml_libvirt_domain_get_os_type"
165   external get_max_memory : [>`R] t -> int64 = "ocaml_libvirt_domain_get_max_memory"
166   external set_max_memory : [>`W] t -> int64 -> unit = "ocaml_libvirt_domain_set_max_memory"
167   external set_memory : [>`W] t -> int64 -> unit = "ocaml_libvirt_domain_set_memory"
168   external get_info : [>`R] t -> info = "ocaml_libvirt_domain_get_info"
169   external get_xml_desc : [>`R] t -> xml = "ocaml_libvirt_domain_get_xml_desc"
170   external get_scheduler_type : [>`R] t -> string * int = "ocaml_libvirt_domain_get_scheduler_type"
171   external get_scheduler_parameters : [>`R] t -> int -> sched_param array = "ocaml_libvirt_domain_get_scheduler_parameters"
172   external set_scheduler_parameters : [>`W] t -> sched_param array -> unit = "ocaml_libvirt_domain_set_scheduler_parameters"
173   external define_xml : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_domain_define_xml"
174   external undefine : [>`W] t -> unit = "ocaml_libvirt_domain_undefine"
175   external create : [>`W] t -> unit = "ocaml_libvirt_domain_create"
176   external get_autostart : [>`R] t -> bool = "ocaml_libvirt_domain_get_autostart"
177   external set_autostart : [>`W] t -> bool -> unit = "ocaml_libvirt_domain_set_autostart"
178   external set_vcpus : [>`W] t -> int -> unit = "ocaml_libvirt_domain_set_vcpus"
179   external pin_vcpu : [>`W] t -> int -> string -> unit = "ocaml_libvirt_domain_pin_vcpu"
180   external get_vcpus : [>`R] t -> int -> int -> int * vcpu_info array * string = "ocaml_libvirt_domain_get_vcpus"
181   external get_max_vcpus : [>`R] t -> int = "ocaml_libvirt_domain_get_max_vcpus"
182   external attach_device : [>`W] t -> xml -> unit = "ocaml_libvirt_domain_attach_device"
183   external detach_device : [>`W] t -> xml -> unit = "ocaml_libvirt_domain_detach_device"
184   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"
185   external block_stats : [>`R] t -> string -> block_stats = "ocaml_libvirt_domain_block_stats"
186   external interface_stats : [>`R] t -> string -> interface_stats = "ocaml_libvirt_domain_interface_stats"
187
188   external const : [>`R] t -> ro t = "%identity"
189 end
190
191 module Network =
192 struct
193   type 'rw net
194   type 'rw t = 'rw net * 'rw Connect.t
195
196   external lookup_by_name : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_network_lookup_by_name"
197   external lookup_by_uuid : 'a Connect.t -> uuid -> 'a t = "ocaml_libvirt_network_lookup_by_uuid"
198   external lookup_by_uuid_string : 'a Connect.t -> string -> 'a t = "ocaml_libvirt_network_lookup_by_uuid_string"
199   external create_xml : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_network_create_xml"
200   external define_xml : [>`W] Connect.t -> xml -> rw t = "ocaml_libvirt_network_define_xml"
201   external undefine : [>`W] t -> unit = "ocaml_libvirt_network_undefine"
202   external create : [>`W] t -> unit = "ocaml_libvirt_network_create"
203   external destroy : [>`W] t -> unit = "ocaml_libvirt_network_destroy"
204   external free : [>`R] t -> unit = "ocaml_libvirt_network_free"
205   external get_name : [>`R] t -> string = "ocaml_libvirt_network_get_name"
206   external get_uuid : [>`R] t -> uuid = "ocaml_libvirt_network_get_uuid"
207   external get_uuid_string : [>`R] t -> string = "ocaml_libvirt_network_get_uuid_string"
208   external get_xml_desc : [>`R] t -> xml = "ocaml_libvirt_network_get_xml_desc"
209   external get_bridge_name : [>`R] t -> string = "ocaml_libvirt_network_get_bridge_name"
210   external get_autostart : [>`R] t -> bool = "ocaml_libvirt_network_get_autostart"
211   external set_autostart : [>`W] t -> bool -> unit = "ocaml_libvirt_network_set_autostart"
212
213   external const : [>`R] t -> ro t = "%identity"
214 end
215
216 module Virterror =
217 struct
218   type code =
219     | VIR_ERR_OK
220     | VIR_ERR_INTERNAL_ERROR
221     | VIR_ERR_NO_MEMORY
222     | VIR_ERR_NO_SUPPORT
223     | VIR_ERR_UNKNOWN_HOST
224     | VIR_ERR_NO_CONNECT
225     | VIR_ERR_INVALID_CONN
226     | VIR_ERR_INVALID_DOMAIN
227     | VIR_ERR_INVALID_ARG
228     | VIR_ERR_OPERATION_FAILED
229     | VIR_ERR_GET_FAILED
230     | VIR_ERR_POST_FAILED
231     | VIR_ERR_HTTP_ERROR
232     | VIR_ERR_SEXPR_SERIAL
233     | VIR_ERR_NO_XEN
234     | VIR_ERR_XEN_CALL
235     | VIR_ERR_OS_TYPE
236     | VIR_ERR_NO_KERNEL
237     | VIR_ERR_NO_ROOT
238     | VIR_ERR_NO_SOURCE
239     | VIR_ERR_NO_TARGET
240     | VIR_ERR_NO_NAME
241     | VIR_ERR_NO_OS
242     | VIR_ERR_NO_DEVICE
243     | VIR_ERR_NO_XENSTORE
244     | VIR_ERR_DRIVER_FULL
245     | VIR_ERR_CALL_FAILED
246     | VIR_ERR_XML_ERROR
247     | VIR_ERR_DOM_EXIST
248     | VIR_ERR_OPERATION_DENIED
249     | VIR_ERR_OPEN_FAILED
250     | VIR_ERR_READ_FAILED
251     | VIR_ERR_PARSE_FAILED
252     | VIR_ERR_CONF_SYNTAX
253     | VIR_ERR_WRITE_FAILED
254     | VIR_ERR_XML_DETAIL
255     | VIR_ERR_INVALID_NETWORK
256     | VIR_ERR_NETWORK_EXIST
257     | VIR_ERR_SYSTEM_ERROR
258     | VIR_ERR_RPC
259     | VIR_ERR_GNUTLS_ERROR
260     | VIR_WAR_NO_NETWORK
261     | VIR_ERR_NO_DOMAIN
262     | VIR_ERR_NO_NETWORK
263     | VIR_ERR_INVALID_MAC
264     | VIR_ERR_UNKNOWN of int
265
266   let string_of_code = function
267     | VIR_ERR_OK -> "VIR_ERR_OK"
268     | VIR_ERR_INTERNAL_ERROR -> "VIR_ERR_INTERNAL_ERROR"
269     | VIR_ERR_NO_MEMORY -> "VIR_ERR_NO_MEMORY"
270     | VIR_ERR_NO_SUPPORT -> "VIR_ERR_NO_SUPPORT"
271     | VIR_ERR_UNKNOWN_HOST -> "VIR_ERR_UNKNOWN_HOST"
272     | VIR_ERR_NO_CONNECT -> "VIR_ERR_NO_CONNECT"
273     | VIR_ERR_INVALID_CONN -> "VIR_ERR_INVALID_CONN"
274     | VIR_ERR_INVALID_DOMAIN -> "VIR_ERR_INVALID_DOMAIN"
275     | VIR_ERR_INVALID_ARG -> "VIR_ERR_INVALID_ARG"
276     | VIR_ERR_OPERATION_FAILED -> "VIR_ERR_OPERATION_FAILED"
277     | VIR_ERR_GET_FAILED -> "VIR_ERR_GET_FAILED"
278     | VIR_ERR_POST_FAILED -> "VIR_ERR_POST_FAILED"
279     | VIR_ERR_HTTP_ERROR -> "VIR_ERR_HTTP_ERROR"
280     | VIR_ERR_SEXPR_SERIAL -> "VIR_ERR_SEXPR_SERIAL"
281     | VIR_ERR_NO_XEN -> "VIR_ERR_NO_XEN"
282     | VIR_ERR_XEN_CALL -> "VIR_ERR_XEN_CALL"
283     | VIR_ERR_OS_TYPE -> "VIR_ERR_OS_TYPE"
284     | VIR_ERR_NO_KERNEL -> "VIR_ERR_NO_KERNEL"
285     | VIR_ERR_NO_ROOT -> "VIR_ERR_NO_ROOT"
286     | VIR_ERR_NO_SOURCE -> "VIR_ERR_NO_SOURCE"
287     | VIR_ERR_NO_TARGET -> "VIR_ERR_NO_TARGET"
288     | VIR_ERR_NO_NAME -> "VIR_ERR_NO_NAME"
289     | VIR_ERR_NO_OS -> "VIR_ERR_NO_OS"
290     | VIR_ERR_NO_DEVICE -> "VIR_ERR_NO_DEVICE"
291     | VIR_ERR_NO_XENSTORE -> "VIR_ERR_NO_XENSTORE"
292     | VIR_ERR_DRIVER_FULL -> "VIR_ERR_DRIVER_FULL"
293     | VIR_ERR_CALL_FAILED -> "VIR_ERR_CALL_FAILED"
294     | VIR_ERR_XML_ERROR -> "VIR_ERR_XML_ERROR"
295     | VIR_ERR_DOM_EXIST -> "VIR_ERR_DOM_EXIST"
296     | VIR_ERR_OPERATION_DENIED -> "VIR_ERR_OPERATION_DENIED"
297     | VIR_ERR_OPEN_FAILED -> "VIR_ERR_OPEN_FAILED"
298     | VIR_ERR_READ_FAILED -> "VIR_ERR_READ_FAILED"
299     | VIR_ERR_PARSE_FAILED -> "VIR_ERR_PARSE_FAILED"
300     | VIR_ERR_CONF_SYNTAX -> "VIR_ERR_CONF_SYNTAX"
301     | VIR_ERR_WRITE_FAILED -> "VIR_ERR_WRITE_FAILED"
302     | VIR_ERR_XML_DETAIL -> "VIR_ERR_XML_DETAIL"
303     | VIR_ERR_INVALID_NETWORK -> "VIR_ERR_INVALID_NETWORK"
304     | VIR_ERR_NETWORK_EXIST -> "VIR_ERR_NETWORK_EXIST"
305     | VIR_ERR_SYSTEM_ERROR -> "VIR_ERR_SYSTEM_ERROR"
306     | VIR_ERR_RPC -> "VIR_ERR_RPC"
307     | VIR_ERR_GNUTLS_ERROR -> "VIR_ERR_GNUTLS_ERROR"
308     | VIR_WAR_NO_NETWORK -> "VIR_WAR_NO_NETWORK"
309     | VIR_ERR_NO_DOMAIN -> "VIR_ERR_NO_DOMAIN"
310     | VIR_ERR_NO_NETWORK -> "VIR_ERR_NO_NETWORK"
311     | VIR_ERR_INVALID_MAC -> "VIR_ERR_INVALID_MAC"
312     | VIR_ERR_UNKNOWN i -> "VIR_ERR_" ^ string_of_int i
313
314   type domain =
315     | VIR_FROM_NONE
316     | VIR_FROM_XEN
317     | VIR_FROM_XEND
318     | VIR_FROM_XENSTORE
319     | VIR_FROM_SEXPR
320     | VIR_FROM_XML
321     | VIR_FROM_DOM
322     | VIR_FROM_RPC
323     | VIR_FROM_PROXY
324     | VIR_FROM_CONF
325     | VIR_FROM_QEMU
326     | VIR_FROM_NET
327     | VIR_FROM_TEST
328     | VIR_FROM_REMOTE
329     | VIR_FROM_OPENVZ
330     | VIR_FROM_XENXM
331     | VIR_FROM_STATS_LINUX
332     | VIR_FROM_UNKNOWN of int
333
334   let string_of_domain = function
335     | VIR_FROM_NONE -> "VIR_FROM_NONE"
336     | VIR_FROM_XEN -> "VIR_FROM_XEN"
337     | VIR_FROM_XEND -> "VIR_FROM_XEND"
338     | VIR_FROM_XENSTORE -> "VIR_FROM_XENSTORE"
339     | VIR_FROM_SEXPR -> "VIR_FROM_SEXPR"
340     | VIR_FROM_XML -> "VIR_FROM_XML"
341     | VIR_FROM_DOM -> "VIR_FROM_DOM"
342     | VIR_FROM_RPC -> "VIR_FROM_RPC"
343     | VIR_FROM_PROXY -> "VIR_FROM_PROXY"
344     | VIR_FROM_CONF -> "VIR_FROM_CONF"
345     | VIR_FROM_QEMU -> "VIR_FROM_QEMU"
346     | VIR_FROM_NET -> "VIR_FROM_NET"
347     | VIR_FROM_TEST -> "VIR_FROM_TEST"
348     | VIR_FROM_REMOTE -> "VIR_FROM_REMOTE"
349     | VIR_FROM_OPENVZ -> "VIR_FROM_OPENVZ"
350     | VIR_FROM_XENXM -> "VIR_FROM_XENXM"
351     | VIR_FROM_STATS_LINUX -> "VIR_FROM_STATS_LINUX"
352     | VIR_FROM_UNKNOWN i -> "VIR_FROM_" ^ string_of_int i
353
354   type level =
355     | VIR_ERR_NONE
356     | VIR_ERR_WARNING
357     | VIR_ERR_ERROR
358     | VIR_ERR_UNKNOWN_LEVEL of int
359
360   let string_of_level = function
361     | VIR_ERR_NONE -> "VIR_ERR_NONE"
362     | VIR_ERR_WARNING -> "VIR_ERR_WARNING"
363     | VIR_ERR_ERROR -> "VIR_ERR_ERROR"
364     | VIR_ERR_UNKNOWN_LEVEL i -> "VIR_ERR_LEVEL_" ^ string_of_int i
365
366   type t = {
367     code : code;
368     domain : domain;
369     message : string option;
370     level : level;
371     conn : ro Connect.t option;
372     dom : ro Domain.t option;
373     str1 : string option;
374     str2 : string option;
375     str3 : string option;
376     int1 : int32;
377     int2 : int32;
378     net : ro Network.t option;
379   }
380
381   let to_string { code = code; domain = domain; message = message } =
382     let buf = Buffer.create 128 in
383     Buffer.add_string buf "libvirt: ";
384     Buffer.add_string buf (string_of_code code);
385     Buffer.add_string buf ": ";
386     Buffer.add_string buf (string_of_domain domain);
387     Buffer.add_string buf ": ";
388     (match message with Some msg -> Buffer.add_string buf msg | None -> ());
389     Buffer.contents buf
390
391   external get_last_error : unit -> t option = "ocaml_libvirt_virterror_get_last_error"
392   external get_last_conn_error : [>`R] Connect.t -> t option = "ocaml_libvirt_virterror_get_last_conn_error"
393   external reset_last_error : unit -> unit = "ocaml_libvirt_virterror_reset_last_error"
394   external reset_last_conn_error : [>`R] Connect.t -> unit = "ocaml_libvirt_virterror_reset_last_conn_error"
395
396   let no_error () =
397     { code = VIR_ERR_OK; domain = VIR_FROM_NONE; message = None;
398       level = VIR_ERR_NONE; conn = None; dom = None;
399       str1 = None; str2 = None; str3 = None;
400       int1 = 0_l; int2 = 0_l; net = None }
401 end
402
403 exception Virterror of Virterror.t
404 exception Not_supported of string
405
406 (* Initialization. *)
407 external c_init : unit -> unit = "ocaml_libvirt_init"
408 let () =
409   Callback.register_exception
410     "ocaml_libvirt_virterror" (Virterror (Virterror.no_error ()));
411   Callback.register_exception
412     "ocaml_libvirt_not_supported" (Not_supported "");
413   c_init ()