external const : [>`R] t -> ro t = "%identity"
end
+module Virterror =
+struct
+ type code =
+ | VIR_ERR_OK
+ | VIR_ERR_INTERNAL_ERROR
+ | VIR_ERR_NO_MEMORY
+ | VIR_ERR_NO_SUPPORT
+ | VIR_ERR_UNKNOWN_HOST
+ | VIR_ERR_NO_CONNECT
+ | VIR_ERR_INVALID_CONN
+ | VIR_ERR_INVALID_DOMAIN
+ | VIR_ERR_INVALID_ARG
+ | VIR_ERR_OPERATION_FAILED
+ | VIR_ERR_GET_FAILED
+ | VIR_ERR_POST_FAILED
+ | VIR_ERR_HTTP_ERROR
+ | VIR_ERR_SEXPR_SERIAL
+ | VIR_ERR_NO_XEN
+ | VIR_ERR_XEN_CALL
+ | VIR_ERR_OS_TYPE
+ | VIR_ERR_NO_KERNEL
+ | VIR_ERR_NO_ROOT
+ | VIR_ERR_NO_SOURCE
+ | VIR_ERR_NO_TARGET
+ | VIR_ERR_NO_NAME
+ | VIR_ERR_NO_OS
+ | VIR_ERR_NO_DEVICE
+ | VIR_ERR_NO_XENSTORE
+ | VIR_ERR_DRIVER_FULL
+ | VIR_ERR_CALL_FAILED
+ | VIR_ERR_XML_ERROR
+ | VIR_ERR_DOM_EXIST
+ | VIR_ERR_OPERATION_DENIED
+ | VIR_ERR_OPEN_FAILED
+ | VIR_ERR_READ_FAILED
+ | VIR_ERR_PARSE_FAILED
+ | VIR_ERR_CONF_SYNTAX
+ | VIR_ERR_WRITE_FAILED
+ | VIR_ERR_XML_DETAIL
+ | VIR_ERR_INVALID_NETWORK
+ | VIR_ERR_NETWORK_EXIST
+ | VIR_ERR_SYSTEM_ERROR
+ | VIR_ERR_RPC
+ | VIR_ERR_GNUTLS_ERROR
+ | VIR_WAR_NO_NETWORK
+ | VIR_ERR_NO_DOMAIN
+ | VIR_ERR_NO_NETWORK
+ | VIR_ERR_INVALID_MAC
+ | VIR_ERR_AUTH_FAILED
+ | VIR_ERR_INVALID_STORAGE_POOL
+ | VIR_ERR_INVALID_STORAGE_VOL
+ | VIR_WAR_NO_STORAGE
+ | VIR_ERR_NO_STORAGE_POOL
+ | VIR_ERR_NO_STORAGE_VOL
+ | VIR_ERR_UNKNOWN of int
+
+ let string_of_code = function
+ | VIR_ERR_OK -> "VIR_ERR_OK"
+ | VIR_ERR_INTERNAL_ERROR -> "VIR_ERR_INTERNAL_ERROR"
+ | VIR_ERR_NO_MEMORY -> "VIR_ERR_NO_MEMORY"
+ | VIR_ERR_NO_SUPPORT -> "VIR_ERR_NO_SUPPORT"
+ | VIR_ERR_UNKNOWN_HOST -> "VIR_ERR_UNKNOWN_HOST"
+ | VIR_ERR_NO_CONNECT -> "VIR_ERR_NO_CONNECT"
+ | VIR_ERR_INVALID_CONN -> "VIR_ERR_INVALID_CONN"
+ | VIR_ERR_INVALID_DOMAIN -> "VIR_ERR_INVALID_DOMAIN"
+ | VIR_ERR_INVALID_ARG -> "VIR_ERR_INVALID_ARG"
+ | VIR_ERR_OPERATION_FAILED -> "VIR_ERR_OPERATION_FAILED"
+ | VIR_ERR_GET_FAILED -> "VIR_ERR_GET_FAILED"
+ | VIR_ERR_POST_FAILED -> "VIR_ERR_POST_FAILED"
+ | VIR_ERR_HTTP_ERROR -> "VIR_ERR_HTTP_ERROR"
+ | VIR_ERR_SEXPR_SERIAL -> "VIR_ERR_SEXPR_SERIAL"
+ | VIR_ERR_NO_XEN -> "VIR_ERR_NO_XEN"
+ | VIR_ERR_XEN_CALL -> "VIR_ERR_XEN_CALL"
+ | VIR_ERR_OS_TYPE -> "VIR_ERR_OS_TYPE"
+ | VIR_ERR_NO_KERNEL -> "VIR_ERR_NO_KERNEL"
+ | VIR_ERR_NO_ROOT -> "VIR_ERR_NO_ROOT"
+ | VIR_ERR_NO_SOURCE -> "VIR_ERR_NO_SOURCE"
+ | VIR_ERR_NO_TARGET -> "VIR_ERR_NO_TARGET"
+ | VIR_ERR_NO_NAME -> "VIR_ERR_NO_NAME"
+ | VIR_ERR_NO_OS -> "VIR_ERR_NO_OS"
+ | VIR_ERR_NO_DEVICE -> "VIR_ERR_NO_DEVICE"
+ | VIR_ERR_NO_XENSTORE -> "VIR_ERR_NO_XENSTORE"
+ | VIR_ERR_DRIVER_FULL -> "VIR_ERR_DRIVER_FULL"
+ | VIR_ERR_CALL_FAILED -> "VIR_ERR_CALL_FAILED"
+ | VIR_ERR_XML_ERROR -> "VIR_ERR_XML_ERROR"
+ | VIR_ERR_DOM_EXIST -> "VIR_ERR_DOM_EXIST"
+ | VIR_ERR_OPERATION_DENIED -> "VIR_ERR_OPERATION_DENIED"
+ | VIR_ERR_OPEN_FAILED -> "VIR_ERR_OPEN_FAILED"
+ | VIR_ERR_READ_FAILED -> "VIR_ERR_READ_FAILED"
+ | VIR_ERR_PARSE_FAILED -> "VIR_ERR_PARSE_FAILED"
+ | VIR_ERR_CONF_SYNTAX -> "VIR_ERR_CONF_SYNTAX"
+ | VIR_ERR_WRITE_FAILED -> "VIR_ERR_WRITE_FAILED"
+ | VIR_ERR_XML_DETAIL -> "VIR_ERR_XML_DETAIL"
+ | VIR_ERR_INVALID_NETWORK -> "VIR_ERR_INVALID_NETWORK"
+ | VIR_ERR_NETWORK_EXIST -> "VIR_ERR_NETWORK_EXIST"
+ | VIR_ERR_SYSTEM_ERROR -> "VIR_ERR_SYSTEM_ERROR"
+ | VIR_ERR_RPC -> "VIR_ERR_RPC"
+ | VIR_ERR_GNUTLS_ERROR -> "VIR_ERR_GNUTLS_ERROR"
+ | VIR_WAR_NO_NETWORK -> "VIR_WAR_NO_NETWORK"
+ | VIR_ERR_NO_DOMAIN -> "VIR_ERR_NO_DOMAIN"
+ | VIR_ERR_NO_NETWORK -> "VIR_ERR_NO_NETWORK"
+ | VIR_ERR_INVALID_MAC -> "VIR_ERR_INVALID_MAC"
+ | VIR_ERR_AUTH_FAILED -> "VIR_ERR_AUTH_FAILED"
+ | VIR_ERR_INVALID_STORAGE_POOL -> "VIR_ERR_INVALID_STORAGE_POOL"
+ | VIR_ERR_INVALID_STORAGE_VOL -> "VIR_ERR_INVALID_STORAGE_VOL"
+ | VIR_WAR_NO_STORAGE -> "VIR_WAR_NO_STORAGE"
+ | VIR_ERR_NO_STORAGE_POOL -> "VIR_ERR_NO_STORAGE_POOL"
+ | VIR_ERR_NO_STORAGE_VOL -> "VIR_ERR_NO_STORAGE_VOL"
+ | VIR_ERR_UNKNOWN i -> "VIR_ERR_" ^ string_of_int i
+
+ type domain =
+ | VIR_FROM_NONE
+ | VIR_FROM_XEN
+ | VIR_FROM_XEND
+ | VIR_FROM_XENSTORE
+ | VIR_FROM_SEXPR
+ | VIR_FROM_XML
+ | VIR_FROM_DOM
+ | VIR_FROM_RPC
+ | VIR_FROM_PROXY
+ | VIR_FROM_CONF
+ | VIR_FROM_QEMU
+ | VIR_FROM_NET
+ | VIR_FROM_TEST
+ | VIR_FROM_REMOTE
+ | VIR_FROM_OPENVZ
+ | VIR_FROM_XENXM
+ | VIR_FROM_STATS_LINUX
+ | VIR_FROM_STORAGE
+ | VIR_FROM_UNKNOWN of int
+
+ let string_of_domain = function
+ | VIR_FROM_NONE -> "VIR_FROM_NONE"
+ | VIR_FROM_XEN -> "VIR_FROM_XEN"
+ | VIR_FROM_XEND -> "VIR_FROM_XEND"
+ | VIR_FROM_XENSTORE -> "VIR_FROM_XENSTORE"
+ | VIR_FROM_SEXPR -> "VIR_FROM_SEXPR"
+ | VIR_FROM_XML -> "VIR_FROM_XML"
+ | VIR_FROM_DOM -> "VIR_FROM_DOM"
+ | VIR_FROM_RPC -> "VIR_FROM_RPC"
+ | VIR_FROM_PROXY -> "VIR_FROM_PROXY"
+ | VIR_FROM_CONF -> "VIR_FROM_CONF"
+ | VIR_FROM_QEMU -> "VIR_FROM_QEMU"
+ | VIR_FROM_NET -> "VIR_FROM_NET"
+ | VIR_FROM_TEST -> "VIR_FROM_TEST"
+ | VIR_FROM_REMOTE -> "VIR_FROM_REMOTE"
+ | VIR_FROM_OPENVZ -> "VIR_FROM_OPENVZ"
+ | VIR_FROM_XENXM -> "VIR_FROM_XENXM"
+ | VIR_FROM_STATS_LINUX -> "VIR_FROM_STATS_LINUX"
+ | VIR_FROM_STORAGE -> "VIR_FROM_STORAGE"
+ | VIR_FROM_UNKNOWN i -> "VIR_FROM_" ^ string_of_int i
+
+ type level =
+ | VIR_ERR_NONE
+ | VIR_ERR_WARNING
+ | VIR_ERR_ERROR
+ | VIR_ERR_UNKNOWN_LEVEL of int
+
+ let string_of_level = function
+ | VIR_ERR_NONE -> "VIR_ERR_NONE"
+ | VIR_ERR_WARNING -> "VIR_ERR_WARNING"
+ | VIR_ERR_ERROR -> "VIR_ERR_ERROR"
+ | VIR_ERR_UNKNOWN_LEVEL i -> "VIR_ERR_LEVEL_" ^ string_of_int i
+
+ type t = {
+ code : code;
+ domain : domain;
+ message : string option;
+ level : level;
+ str1 : string option;
+ str2 : string option;
+ str3 : string option;
+ int1 : int32;
+ int2 : int32;
+ }
+
+ let to_string { code = code; domain = domain; message = message } =
+ let buf = Buffer.create 128 in
+ Buffer.add_string buf "libvirt: ";
+ Buffer.add_string buf (string_of_code code);
+ Buffer.add_string buf ": ";
+ Buffer.add_string buf (string_of_domain domain);
+ Buffer.add_string buf ": ";
+ (match message with Some msg -> Buffer.add_string buf msg | None -> ());
+ Buffer.contents buf
+
+ external get_last_error : unit -> t option = "ocaml_libvirt_virterror_get_last_error"
+ external get_last_conn_error : [>`R] Connect.t -> t option = "ocaml_libvirt_virterror_get_last_conn_error"
+ external reset_last_error : unit -> unit = "ocaml_libvirt_virterror_reset_last_error"
+ external reset_last_conn_error : [>`R] Connect.t -> unit = "ocaml_libvirt_virterror_reset_last_conn_error"
+
+ let no_error () =
+ { code = VIR_ERR_OK; domain = VIR_FROM_NONE;
+ message = None; level = VIR_ERR_NONE;
+ str1 = None; str2 = None; str3 = None;
+ int1 = 0_l; int2 = 0_l }
+end
+
+exception Virterror of Virterror.t
+exception Not_supported of string
+
+let rec map_ignore_errors f = function
+ | [] -> []
+ | x :: xs ->
+ try f x :: map_ignore_errors f xs
+ with Virterror _ -> map_ignore_errors f xs
+
module Domain =
struct
type 'rw t
type memory_flag = Virtual
type list_flag =
- | ListNoState | ListRunning | ListBlocked
- | ListPaused | ListShutdown | ListShutoff | ListCrashed
| ListActive
| ListInactive
| ListAll
external memory_peek : [>`R] t -> memory_flag list -> int64 -> int -> string -> int -> unit = "ocaml_libvirt_domain_memory_peek_bytecode" "ocaml_libvirt_domain_memory_peek_native"
external const : [>`R] t -> ro t = "%identity"
+
+ (* First time we are called, we will check if
+ * virConnectListAllDomains is supported.
+ *)
+ let have_list_all_domains = ref None
+
+ let check_have_list_all_domains conn =
+ match !have_list_all_domains with
+ | Some v -> v
+ | None ->
+ (* Check if virConnectListAllDomains is supported
+ * by this version of libvirt.
+ *)
+ let v =
+ (* libvirt has a short-cut which makes this very quick ... *)
+ try ignore (list_all_domains conn []); true
+ with Not_supported "virConnectListAllDomains" -> false in
+ have_list_all_domains := Some v;
+ v
+
+ let get_domains conn flags =
+ let have_list_all_domains = check_have_list_all_domains conn in
+
+ if have_list_all_domains then (
+ (* Good, we can use the shiny new method. *)
+ let doms, _ = list_all_domains conn ~want_info:false flags in
+ Array.to_list doms
+ )
+ else (
+ (* Old/slow/inefficient method. *)
+ let get_active, get_inactive =
+ if List.mem ListAll flags then
+ (true, true)
+ else
+ (List.mem ListActive flags, List.mem ListInactive flags) in
+ let active_doms =
+ if get_active then (
+ let n = Connect.num_of_domains conn in
+ let ids = Connect.list_domains conn n in
+ let ids = Array.to_list ids in
+ map_ignore_errors (lookup_by_id conn) ids
+ ) else [] in
+
+ let inactive_doms =
+ if get_inactive then (
+ let n = Connect.num_of_defined_domains conn in
+ let names = Connect.list_defined_domains conn n in
+ let names = Array.to_list names in
+ map_ignore_errors (lookup_by_name conn) names
+ ) else [] in
+
+ active_doms @ inactive_doms
+ )
+
+ let get_domains_and_infos conn flags =
+ let have_list_all_domains = check_have_list_all_domains conn in
+
+ if have_list_all_domains then (
+ (* Good, we can use the shiny new method. *)
+ let doms, infos = list_all_domains conn ~want_info:true flags in
+ let doms = Array.to_list doms and infos = Array.to_list infos in
+ List.combine doms infos
+ )
+ else (
+ (* Old/slow/inefficient method. *)
+ let get_active, get_inactive =
+ if List.mem ListAll flags then
+ (true, true)
+ else (List.mem ListActive flags, List.mem ListInactive flags) in
+ let active_doms =
+ if get_active then (
+ let n = Connect.num_of_domains conn in
+ let ids = Connect.list_domains conn n in
+ let ids = Array.to_list ids in
+ map_ignore_errors (lookup_by_id conn) ids
+ ) else [] in
+
+ let inactive_doms =
+ if get_inactive then (
+ let n = Connect.num_of_defined_domains conn in
+ let names = Connect.list_defined_domains conn n in
+ let names = Array.to_list names in
+ map_ignore_errors (lookup_by_name conn) names
+ ) else [] in
+
+ let doms = active_doms @ inactive_doms in
+
+ map_ignore_errors (fun dom -> (dom, get_info dom)) doms
+ )
end
module Network =
external const : ('a, [>`R]) t -> ('a, ro) t = "%identity"
end
-module Virterror =
-struct
- type code =
- | VIR_ERR_OK
- | VIR_ERR_INTERNAL_ERROR
- | VIR_ERR_NO_MEMORY
- | VIR_ERR_NO_SUPPORT
- | VIR_ERR_UNKNOWN_HOST
- | VIR_ERR_NO_CONNECT
- | VIR_ERR_INVALID_CONN
- | VIR_ERR_INVALID_DOMAIN
- | VIR_ERR_INVALID_ARG
- | VIR_ERR_OPERATION_FAILED
- | VIR_ERR_GET_FAILED
- | VIR_ERR_POST_FAILED
- | VIR_ERR_HTTP_ERROR
- | VIR_ERR_SEXPR_SERIAL
- | VIR_ERR_NO_XEN
- | VIR_ERR_XEN_CALL
- | VIR_ERR_OS_TYPE
- | VIR_ERR_NO_KERNEL
- | VIR_ERR_NO_ROOT
- | VIR_ERR_NO_SOURCE
- | VIR_ERR_NO_TARGET
- | VIR_ERR_NO_NAME
- | VIR_ERR_NO_OS
- | VIR_ERR_NO_DEVICE
- | VIR_ERR_NO_XENSTORE
- | VIR_ERR_DRIVER_FULL
- | VIR_ERR_CALL_FAILED
- | VIR_ERR_XML_ERROR
- | VIR_ERR_DOM_EXIST
- | VIR_ERR_OPERATION_DENIED
- | VIR_ERR_OPEN_FAILED
- | VIR_ERR_READ_FAILED
- | VIR_ERR_PARSE_FAILED
- | VIR_ERR_CONF_SYNTAX
- | VIR_ERR_WRITE_FAILED
- | VIR_ERR_XML_DETAIL
- | VIR_ERR_INVALID_NETWORK
- | VIR_ERR_NETWORK_EXIST
- | VIR_ERR_SYSTEM_ERROR
- | VIR_ERR_RPC
- | VIR_ERR_GNUTLS_ERROR
- | VIR_WAR_NO_NETWORK
- | VIR_ERR_NO_DOMAIN
- | VIR_ERR_NO_NETWORK
- | VIR_ERR_INVALID_MAC
- | VIR_ERR_AUTH_FAILED
- | VIR_ERR_INVALID_STORAGE_POOL
- | VIR_ERR_INVALID_STORAGE_VOL
- | VIR_WAR_NO_STORAGE
- | VIR_ERR_NO_STORAGE_POOL
- | VIR_ERR_NO_STORAGE_VOL
- | VIR_ERR_UNKNOWN of int
-
- let string_of_code = function
- | VIR_ERR_OK -> "VIR_ERR_OK"
- | VIR_ERR_INTERNAL_ERROR -> "VIR_ERR_INTERNAL_ERROR"
- | VIR_ERR_NO_MEMORY -> "VIR_ERR_NO_MEMORY"
- | VIR_ERR_NO_SUPPORT -> "VIR_ERR_NO_SUPPORT"
- | VIR_ERR_UNKNOWN_HOST -> "VIR_ERR_UNKNOWN_HOST"
- | VIR_ERR_NO_CONNECT -> "VIR_ERR_NO_CONNECT"
- | VIR_ERR_INVALID_CONN -> "VIR_ERR_INVALID_CONN"
- | VIR_ERR_INVALID_DOMAIN -> "VIR_ERR_INVALID_DOMAIN"
- | VIR_ERR_INVALID_ARG -> "VIR_ERR_INVALID_ARG"
- | VIR_ERR_OPERATION_FAILED -> "VIR_ERR_OPERATION_FAILED"
- | VIR_ERR_GET_FAILED -> "VIR_ERR_GET_FAILED"
- | VIR_ERR_POST_FAILED -> "VIR_ERR_POST_FAILED"
- | VIR_ERR_HTTP_ERROR -> "VIR_ERR_HTTP_ERROR"
- | VIR_ERR_SEXPR_SERIAL -> "VIR_ERR_SEXPR_SERIAL"
- | VIR_ERR_NO_XEN -> "VIR_ERR_NO_XEN"
- | VIR_ERR_XEN_CALL -> "VIR_ERR_XEN_CALL"
- | VIR_ERR_OS_TYPE -> "VIR_ERR_OS_TYPE"
- | VIR_ERR_NO_KERNEL -> "VIR_ERR_NO_KERNEL"
- | VIR_ERR_NO_ROOT -> "VIR_ERR_NO_ROOT"
- | VIR_ERR_NO_SOURCE -> "VIR_ERR_NO_SOURCE"
- | VIR_ERR_NO_TARGET -> "VIR_ERR_NO_TARGET"
- | VIR_ERR_NO_NAME -> "VIR_ERR_NO_NAME"
- | VIR_ERR_NO_OS -> "VIR_ERR_NO_OS"
- | VIR_ERR_NO_DEVICE -> "VIR_ERR_NO_DEVICE"
- | VIR_ERR_NO_XENSTORE -> "VIR_ERR_NO_XENSTORE"
- | VIR_ERR_DRIVER_FULL -> "VIR_ERR_DRIVER_FULL"
- | VIR_ERR_CALL_FAILED -> "VIR_ERR_CALL_FAILED"
- | VIR_ERR_XML_ERROR -> "VIR_ERR_XML_ERROR"
- | VIR_ERR_DOM_EXIST -> "VIR_ERR_DOM_EXIST"
- | VIR_ERR_OPERATION_DENIED -> "VIR_ERR_OPERATION_DENIED"
- | VIR_ERR_OPEN_FAILED -> "VIR_ERR_OPEN_FAILED"
- | VIR_ERR_READ_FAILED -> "VIR_ERR_READ_FAILED"
- | VIR_ERR_PARSE_FAILED -> "VIR_ERR_PARSE_FAILED"
- | VIR_ERR_CONF_SYNTAX -> "VIR_ERR_CONF_SYNTAX"
- | VIR_ERR_WRITE_FAILED -> "VIR_ERR_WRITE_FAILED"
- | VIR_ERR_XML_DETAIL -> "VIR_ERR_XML_DETAIL"
- | VIR_ERR_INVALID_NETWORK -> "VIR_ERR_INVALID_NETWORK"
- | VIR_ERR_NETWORK_EXIST -> "VIR_ERR_NETWORK_EXIST"
- | VIR_ERR_SYSTEM_ERROR -> "VIR_ERR_SYSTEM_ERROR"
- | VIR_ERR_RPC -> "VIR_ERR_RPC"
- | VIR_ERR_GNUTLS_ERROR -> "VIR_ERR_GNUTLS_ERROR"
- | VIR_WAR_NO_NETWORK -> "VIR_WAR_NO_NETWORK"
- | VIR_ERR_NO_DOMAIN -> "VIR_ERR_NO_DOMAIN"
- | VIR_ERR_NO_NETWORK -> "VIR_ERR_NO_NETWORK"
- | VIR_ERR_INVALID_MAC -> "VIR_ERR_INVALID_MAC"
- | VIR_ERR_AUTH_FAILED -> "VIR_ERR_AUTH_FAILED"
- | VIR_ERR_INVALID_STORAGE_POOL -> "VIR_ERR_INVALID_STORAGE_POOL"
- | VIR_ERR_INVALID_STORAGE_VOL -> "VIR_ERR_INVALID_STORAGE_VOL"
- | VIR_WAR_NO_STORAGE -> "VIR_WAR_NO_STORAGE"
- | VIR_ERR_NO_STORAGE_POOL -> "VIR_ERR_NO_STORAGE_POOL"
- | VIR_ERR_NO_STORAGE_VOL -> "VIR_ERR_NO_STORAGE_VOL"
- | VIR_ERR_UNKNOWN i -> "VIR_ERR_" ^ string_of_int i
-
- type domain =
- | VIR_FROM_NONE
- | VIR_FROM_XEN
- | VIR_FROM_XEND
- | VIR_FROM_XENSTORE
- | VIR_FROM_SEXPR
- | VIR_FROM_XML
- | VIR_FROM_DOM
- | VIR_FROM_RPC
- | VIR_FROM_PROXY
- | VIR_FROM_CONF
- | VIR_FROM_QEMU
- | VIR_FROM_NET
- | VIR_FROM_TEST
- | VIR_FROM_REMOTE
- | VIR_FROM_OPENVZ
- | VIR_FROM_XENXM
- | VIR_FROM_STATS_LINUX
- | VIR_FROM_STORAGE
- | VIR_FROM_UNKNOWN of int
-
- let string_of_domain = function
- | VIR_FROM_NONE -> "VIR_FROM_NONE"
- | VIR_FROM_XEN -> "VIR_FROM_XEN"
- | VIR_FROM_XEND -> "VIR_FROM_XEND"
- | VIR_FROM_XENSTORE -> "VIR_FROM_XENSTORE"
- | VIR_FROM_SEXPR -> "VIR_FROM_SEXPR"
- | VIR_FROM_XML -> "VIR_FROM_XML"
- | VIR_FROM_DOM -> "VIR_FROM_DOM"
- | VIR_FROM_RPC -> "VIR_FROM_RPC"
- | VIR_FROM_PROXY -> "VIR_FROM_PROXY"
- | VIR_FROM_CONF -> "VIR_FROM_CONF"
- | VIR_FROM_QEMU -> "VIR_FROM_QEMU"
- | VIR_FROM_NET -> "VIR_FROM_NET"
- | VIR_FROM_TEST -> "VIR_FROM_TEST"
- | VIR_FROM_REMOTE -> "VIR_FROM_REMOTE"
- | VIR_FROM_OPENVZ -> "VIR_FROM_OPENVZ"
- | VIR_FROM_XENXM -> "VIR_FROM_XENXM"
- | VIR_FROM_STATS_LINUX -> "VIR_FROM_STATS_LINUX"
- | VIR_FROM_STORAGE -> "VIR_FROM_STORAGE"
- | VIR_FROM_UNKNOWN i -> "VIR_FROM_" ^ string_of_int i
-
- type level =
- | VIR_ERR_NONE
- | VIR_ERR_WARNING
- | VIR_ERR_ERROR
- | VIR_ERR_UNKNOWN_LEVEL of int
-
- let string_of_level = function
- | VIR_ERR_NONE -> "VIR_ERR_NONE"
- | VIR_ERR_WARNING -> "VIR_ERR_WARNING"
- | VIR_ERR_ERROR -> "VIR_ERR_ERROR"
- | VIR_ERR_UNKNOWN_LEVEL i -> "VIR_ERR_LEVEL_" ^ string_of_int i
-
- type t = {
- code : code;
- domain : domain;
- message : string option;
- level : level;
- str1 : string option;
- str2 : string option;
- str3 : string option;
- int1 : int32;
- int2 : int32;
- }
-
- let to_string { code = code; domain = domain; message = message } =
- let buf = Buffer.create 128 in
- Buffer.add_string buf "libvirt: ";
- Buffer.add_string buf (string_of_code code);
- Buffer.add_string buf ": ";
- Buffer.add_string buf (string_of_domain domain);
- Buffer.add_string buf ": ";
- (match message with Some msg -> Buffer.add_string buf msg | None -> ());
- Buffer.contents buf
-
- external get_last_error : unit -> t option = "ocaml_libvirt_virterror_get_last_error"
- external get_last_conn_error : [>`R] Connect.t -> t option = "ocaml_libvirt_virterror_get_last_conn_error"
- external reset_last_error : unit -> unit = "ocaml_libvirt_virterror_reset_last_error"
- external reset_last_conn_error : [>`R] Connect.t -> unit = "ocaml_libvirt_virterror_reset_last_conn_error"
-
- let no_error () =
- { code = VIR_ERR_OK; domain = VIR_FROM_NONE;
- message = None; level = VIR_ERR_NONE;
- str1 = None; str2 = None; str3 = None;
- int1 = 0_l; int2 = 0_l }
-end
-
-exception Virterror of Virterror.t
-exception Not_supported of string
-
-let rec map_ignore_errors f = function
- | [] -> []
- | x :: xs ->
- try f x :: map_ignore_errors f xs
- with Virterror _ -> map_ignore_errors f xs
-
-(* First time we are called, we will check if
- * virConnectListAllDomains is supported.
- *)
-let have_list_all_domains = ref None
-
-let get_domains conn ?(want_info = true) flags =
- let have_list_all_domains =
- match !have_list_all_domains with
- | Some v -> v
- | None ->
- (* Check if virConnectListAllDomains is supported
- * by this version of libvirt.
- *)
- let v =
- (* libvirt has a short-cut which makes this very quick ... *)
- try ignore (Domain.list_all_domains conn []); true
- with Not_supported "virConnectListAllDomains" -> false in
- have_list_all_domains := Some v;
- v in
-
- if have_list_all_domains then (
- (* Good, we can use the shiny new method. *)
- let doms, infos = Domain.list_all_domains conn ~want_info flags in
- Array.to_list doms, Array.to_list infos
- )
- else (
- (* Old/slow/inefficient method. *)
- let get_all, get_active, get_inactive, another_flag =
- let rec loop ((all, active, inactive, another) as xs) = function
- | [] -> xs
- | Domain.ListAll :: _ -> (true, true, true, false)
- | Domain.ListActive :: fs -> loop (all, true, inactive, another) fs
- | Domain.ListInactive :: fs -> loop (all, active, true, another) fs
- | _ -> (true, true, true, true)
- in
- loop (false, false, false, false) flags in
-
- let active_doms =
- if get_active then (
- let n = Connect.num_of_domains conn in
- let ids = Connect.list_domains conn n in
- let ids = Array.to_list ids in
- map_ignore_errors (Domain.lookup_by_id conn) ids
- ) else [] in
-
- let inactive_doms =
- if get_inactive then (
- let n = Connect.num_of_defined_domains conn in
- let names = Connect.list_defined_domains conn n in
- let names = Array.to_list names in
- map_ignore_errors (Domain.lookup_by_name conn) names
- ) else [] in
-
- let doms = active_doms @ inactive_doms in
-
- if not another_flag then (
- if want_info then
- List.split (
- map_ignore_errors (fun dom -> (dom, Domain.get_info dom)) doms
- )
- else
- doms, []
- ) else (
- (* Slow method: We have to get the infos and filter on state. *)
- let flag_is_set =
- let h = Hashtbl.create 13 in
- List.iter (fun flag -> Hashtbl.add h flag ()) flags;
- Hashtbl.mem h
- in
-
- let doms =
- map_ignore_errors (fun dom -> (dom, Domain.get_info dom)) doms in
- let doms = List.filter (
- fun (dom, { Domain.state = state }) ->
- match state with
- | Domain.InfoNoState -> flag_is_set Domain.ListNoState
- | Domain.InfoRunning ->
- flag_is_set Domain.ListActive || flag_is_set Domain.ListRunning
- | Domain.InfoBlocked ->
- flag_is_set Domain.ListActive || flag_is_set Domain.ListBlocked
- | Domain.InfoPaused ->
- flag_is_set Domain.ListActive || flag_is_set Domain.ListPaused
- | Domain.InfoShutdown ->
- flag_is_set Domain.ListActive || flag_is_set Domain.ListShutdown
- | Domain.InfoShutoff ->
- flag_is_set Domain.ListInactive
- || flag_is_set Domain.ListShutoff
- | Domain.InfoCrashed -> flag_is_set Domain.ListCrashed
- ) doms in
- List.split doms
- )
- )
-
(* Initialization. *)
external c_init : unit -> unit = "ocaml_libvirt_init"
let () =
{[
open Printf
-let domains =
- fst (Libvirt.get_domains conn ~want_info:false [D.ListActive]) in
+let domains = D.get_domains conn [D.ListActive] in
List.iter (
fun dom ->
printf "%8d %s\n%!" (D.get_id dom) (D.get_name dom)
{3 Example: List inactive domains}
{[
-let domains =
- fst (Libvirt.get_domains conn ~want_info:false [D.ListInactive]) in
+let domains = D.get_domains conn [D.ListInactive] in
List.iter (
fun dom ->
printf "inactive %s\n%!" (D.get_name dom)
We don't support libvirt < 0.2.1, and never will so don't ask us.
- {3 Get list of domains}
+ {3 Get list of domains and domain infos}
This is a very common operation, and libvirt supports various
different methods to do it. We have hidden the complexity in a
- flexible {!Libvirt.get_domains} call which is easy to use and
+ flexible {!Libvirt.Domain.get_domains} and
+ {!Libvirt.Domain.get_domains_and_infos} calls which is easy to use and
automatically chooses the most efficient method depending on the
version of libvirt in use.
Call {!num_of_domains} first to get a value for [max].
- See also: {!Libvirt.get_domains}.
+ See also:
+ {!Libvirt.Domain.get_domains},
+ {!Libvirt.Domain.get_domains_and_infos}.
*)
val num_of_domains : [>`R] t -> int
(** Returns the number of running domains. *)
Call {!num_of_defined_domains} first to get a value for [max].
- See also: {!Libvirt.get_domains}.
+ See also:
+ {!Libvirt.Domain.get_domains},
+ {!Libvirt.Domain.get_domains_and_infos}.
*)
val num_of_networks : [>`R] t -> int
(** Returns the number of networks. *)
type memory_flag = Virtual
type list_flag =
- | ListNoState | ListRunning | ListBlocked
- | ListPaused | ListShutdown | ListShutoff | ListCrashed
| ListActive
| ListInactive
| ListAll
This call was introduced in libvirt 0.4.5. Because you
might dynamically link to an older version of libvirt which
- doesn't have this call, you should use {!Libvirt.get_domains}
- which uses the most efficient way to get domains for the
- available version of libvirt.
+ doesn't have this call, you should use {!get_domains}
+ or {!get_domains_and_infos} which use the most efficient
+ way to get domains for the available version of libvirt.
*)
val create_linux : [>`W] Connect.t -> xml -> rw t
(** Create a new guest domain (not necessarily a Linux one)
(** [const dom] turns a read/write domain handle into a read-only
domain handle. Note that the opposite operation is impossible.
*)
+
+ val get_domains : ([>`R] as 'a) Connect.t -> list_flag list -> 'a t list
+ (** Get the active and/or inactive domains using the most
+ efficient method available.
+
+ See also:
+ {!get_domains_and_infos},
+ {!list_all_domains},
+ {!Connect.list_domains},
+ {!Connect.list_defined_domains}.
+ *)
+
+ val get_domains_and_infos : ([>`R] as 'a) Connect.t -> list_flag list ->
+ ('a t * info) list
+ (** This gets the active and/or inactive domains and the
+ domain info for each one using the most efficient
+ method available.
+
+ See also:
+ {!get_domains},
+ {!list_all_domains},
+ {!Connect.list_domains},
+ {!Connect.list_defined_domains},
+ {!get_info}.
+ *)
+
end
(** Module dealing with domains. [Domain.t] is the
domain object. *)
might 'disappear' asynchronously from the currently running
program.
*)
-
-val get_domains : ([>`R] as 'a) Connect.t -> ?want_info:bool -> Domain.list_flag list -> 'a Domain.t list * Domain.info list
- (** Get the active and/or inactive domains using the most
- efficient method available.
-
- The two lists returned will have the same length, unless
- [~want_info] is [false] in which case the info list will be
- zero-length. The default for [~want_info] is [true]. In most
- cases there is no extra penalty for getting the info fields, or
- the penalty is insignificant.
-
- See also:
- {!Domain.list_all_domains},
- {!Connect.list_domains},
- {!Connect.list_defined_domains}.
- *)