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