This library is free software; you can redistribute it and/or
modify it under the terms of the GNU Lesser General Public
License as published by the Free Software Foundation; either
- version 2 of the License, or (at your option) any later version.
+ version 2 of the License, or (at your option) any later version,
+ with the OCaml linking exception described in ../COPYING.LIB.
This library is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
Lesser General Public License for more details.
- Please see the file ../COPYING.LIB.
+ You should have received a copy of the GNU Lesser General Public
+ License along with this library; if not, write to the Free Software
+ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
*)
(**
{{:http://libvirt.org/html/libvirt-libvirt.html}virConnect*, virDomain* and virNetwork* functions from libvirt}.
For brevity I usually rename these modules like this:
-{v
+{[
module C = Libvirt.Connect
module D = Libvirt.Domain
module N = Libvirt.Network
-v}
+]}
To get a connection handle, assuming a Xen hypervisor:
-{v
+{[
let name = "xen:///"
let conn = C.connect_readonly ~name ()
-v}
+]}
{3 Example: List running domains}
-{v
+{[
open Printf
-let n = C.num_of_domains conn in
-let ids = C.list_domains conn n in
-let domains = Array.map (D.lookup_by_id conn) ids in
-Array.iter (
+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)
) domains;
-v}
+]}
{3 Example: List inactive domains}
-{v
-let n = C.num_of_defined_domains conn in
-let names = C.list_defined_domains conn n in
-Array.iter (
- fun name ->
- printf "inactive %s\n%!" name
-) names;
-v}
+{[
+let domains = D.get_domains conn [D.ListInactive] in
+List.iter (
+ fun dom ->
+ printf "inactive %s\n%!" (D.get_name dom)
+) domains;
+]}
{3 Example: Print node info}
-{v
+{[
let node_info = C.get_node_info conn in
printf "model = %s\n" node_info.C.model;
printf "memory = %Ld K\n" node_info.C.memory;
let uri = C.get_uri conn in
printf "uri = %s\n%!" uri
-v}
+]}
*)
Note that even though you hold open (eg) a domain object, that
doesn't mean that the domain (virtual machine) actually exists.
The domain could have been shut down or deleted by another user.
- Thus domain objects can through odd exceptions at any time.
+ Thus domain objects can raise odd exceptions at any time.
This is just the nature of virtualisation.
{3 Backwards and forwards compatibility}
We don't support libvirt < 0.2.1, and never will so don't ask us.
+ {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.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.
+
{3 Threads}
You can issue multiple concurrent libvirt requests in
If you want to handle both read-write and read-only
connections at runtime, use a variant similar to this:
-{v
+{[
type conn_t =
| No_connection
| Read_only of Libvirt.ro Libvirt.Connect.t
| Read_write of Libvirt.rw Libvirt.Connect.t
-v}
+]}
See also the source of [mlvirsh].
*)
+(** {3 Forward definitions}
+
+ These definitions are placed here to avoid the need to
+ use recursive module dependencies.
+*)
+
type ('a, 'b) job_t
-(** Forward definition of {!Job.t} to avoid recursive module dependencies. *)
+(** Forward definition of {!Job.t}. *)
(** {3 Connections} *)
val list_domains : [>`R] t -> int -> int array
(** [list_domains conn max] returns the running domain IDs,
up to a maximum of [max] entries.
+
Call {!num_of_domains} first to get a value for [max].
+
+ 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. *)
(** [list_defined_domains conn max]
returns the names of the inactive domains, up to
a maximum of [max] entries.
+
Call {!num_of_defined_domains} first to get a value for [max].
+
+ See also:
+ {!Libvirt.Domain.get_domains},
+ {!Libvirt.Domain.get_domains_and_infos}.
*)
val num_of_networks : [>`R] t -> int
(** Returns the number of networks. *)
| InfoShutdown | InfoShutoff | InfoCrashed
type info = {
- state : state; (** running state *)
+ state : state; (** running state *)
max_mem : int64; (** maximum memory in kilobytes *)
memory : int64; (** memory used in kilobytes *)
nr_virt_cpu : int; (** number of virtual CPUs *)
type memory_flag = Virtual
+ type list_flag =
+ | ListActive
+ | ListInactive
+ | ListAll
+
type block_stats = {
rd_req : int64;
rd_bytes : int64;
tx_drop : int64;
}
+ val max_peek : [>`R] t -> int
+ (** Maximum size supported by the {!block_peek} and {!memory_peek}
+ functions. If you want to peek more than this then you must
+ break your request into chunks. *)
+
+ val list_all_domains : 'a Connect.t -> ?want_info:bool -> list_flag list -> 'a t array * info array
+ (** [list_all_domains conn flags] returns all domains which
+ match [flags].
+
+ This can return both active and inactive domains. The
+ list of flags controls what domains are returned. See
+ {!list_flag}.
+
+ The two arrays returned will have the same length, unless
+ [~want_info] is [false] in which case the info array
+ 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.
+
+ 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 {!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)
from the given XML.
[offset] in the domain's [path] block device.
If successful then the data is written into [buf] starting
- at offset [boff], for [size] bytes. *)
+ at offset [boff], for [size] bytes.
+
+ See also {!max_peek}. *)
val memory_peek : [>`R] t -> memory_flag list -> int64 -> int ->
string -> int -> unit
(** [memory_peek dom Virtual offset size] reads [size] bytes
at [offset] in the domain's virtual memory.
If successful then the data is written into [buf] starting
- at offset [boff], for [size] bytes. *)
+ at offset [boff], for [size] bytes.
+
+ See also {!max_peek}. *)
external const : [>`R] t -> ro t = "%identity"
(** [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. *)
See also {{:http://libvirt.org/hvsupport.html}http://libvirt.org/hvsupport.html}
*)
+(** {3 Utility functions} *)
+
+val map_ignore_errors : ('a -> 'b) -> 'a list -> 'b list
+(** [map_ignore_errors f xs] calls function [f] for each element of [xs].
+
+ This is just like [List.map] except that if [f x] throws a
+ {!Virterror.t} exception, the error is ignored and [f x]
+ is not returned in the final list.
+
+ This function is primarily useful when dealing with domains which
+ might 'disappear' asynchronously from the currently running
+ program.
+*)