(** OCaml bindings for libvirt. *)
-(* (C) Copyright 2007 Richard W.M. Jones, Red Hat Inc.
+(* (C) Copyright 2007-2015 Richard W.M. Jones, Red Hat Inc.
http://libvirt.org/
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
{{: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}
- OCaml-libvirt is backwards and forwards compatible with
- any libvirt >= 0.2.1. One consequence of this is that
- your program can dynamically link to a {i newer} version of
- libvirt than it was compiled with, and it should still
- work.
+ OCaml-libvirt requires libvirt version 1.0.2 or later. Future
+ releases of OCaml-libvirt will use newer features of libvirt
+ and therefore will require later versions of libvirt. It is always
+ possible to dynamically link your application against a newer
+ libvirt than OCaml-libvirt was originally compiled against.
- When we link to an older version of libvirt.so, there may
- be missing functions. If ocaml-libvirt was compiled with
- gcc, then these are turned into OCaml {!Libvirt.Not_supported}
- exceptions.
+ {3 Get list of domains and domain infos}
- We don't support libvirt < 0.2.1, and never will so don't ask us.
+ 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}
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].
+]}
*)
-type ('a, 'b) job_t
-(** Forward definition of {!Job.t} to avoid recursive module dependencies. *)
+(** {3 Forward definitions}
+
+ These definitions are placed here to avoid the need to
+ use recursive module dependencies.
+*)
(** {3 Connections} *)
threads : int; (** number of threads per core *)
}
+ type credential_type =
+ | CredentialUsername (** Identity to act as *)
+ | CredentialAuthname (** Identify to authorize as *)
+ | CredentialLanguage (** RFC 1766 languages, comma separated *)
+ | CredentialCnonce (** client supplies a nonce *)
+ | CredentialPassphrase (** Passphrase secret *)
+ | CredentialEchoprompt (** Challenge response *)
+ | CredentialNoechoprompt (** Challenge response *)
+ | CredentialRealm (** Authentication realm *)
+ | CredentialExternal (** Externally managed credential *)
+
+ type credential = {
+ typ : credential_type; (** The type of credential *)
+ prompt : string; (** Prompt to show to user *)
+ challenge : string option; (** Additional challenge to show *)
+ defresult : string option; (** Optional default result *)
+ }
+
+ type auth = {
+ credtype : credential_type list; (** List of supported credential_type values *)
+ cb : (credential list -> string option list);
+ (** Callback used to collect credentials.
+
+ The input is a list of all the requested credentials.
+
+ The function returns a list of all the results from the
+ requested credentials, so the number of results {e must} match
+ the number of input credentials. Each result is optional,
+ and in case it is [None] it means there was no result.
+ *)
+ }
+
val connect : ?name:string -> unit -> rw t
val connect_readonly : ?name:string -> unit -> ro t
(** [connect ~name ()] connects to the hypervisor with URI [name].
[connect_readonly] is the same but connects in read-only mode.
*)
+ val connect_auth : ?name:string -> auth -> rw t
+ val connect_auth_readonly : ?name:string -> auth -> ro t
+
val close : [>`R] t -> unit
(** [close conn] closes and frees the connection object in memory.
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. *)
CPU map between a single virtual and all physical CPUs of a domain.
*)
- val use_cpu : string -> int -> unit
+ val use_cpu : bytes -> int -> unit
(** [use_cpu cpumap cpu] marks [cpu] as usable in [cpumap]. *)
- val unuse_cpu : string -> int -> unit
+ val unuse_cpu : bytes -> int -> unit
(** [unuse_cpu cpumap cpu] marks [cpu] as not usable in [cpumap]. *)
- val cpu_usable : string -> int -> int -> int -> bool
+ val cpu_usable : bytes -> int -> int -> int -> bool
(** [cpu_usable cpumaps maplen vcpu cpu] checks returns true iff the
[cpu] is usable by [vcpu]. *)
+ val set_keep_alive : [>`R] t -> int -> int -> unit
+ (** [set_keep_alive conn interval count] starts sending keepalive
+ messages after [interval] seconds of inactivity and consider the
+ connection to be broken when no response is received after [count]
+ keepalive messages.
+ Note: the client has to implement and run an event loop to
+ be able to use keep-alive messages. *)
+
external const : [>`R] t -> ro t = "%identity"
(** [const conn] turns a read/write connection into a read-only
connection. Note that the opposite operation is impossible.
| 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 *)
cpu : int; (** real CPU number, -1 if offline *)
}
+ type domain_create_flag =
+ | START_PAUSED (** Launch guest in paused state *)
+ | START_AUTODESTROY (** Automatically kill guest on close *)
+ | START_BYPASS_CACHE (** Avoid filesystem cache pollution *)
+ | START_FORCE_BOOT (** Discard any managed save *)
+ | START_VALIDATE (** Validate XML against schema *)
+
type sched_param = string * sched_param_value
and sched_param_value =
| SchedFieldInt32 of int32 | SchedFieldUInt32 of int32
| SchedFieldInt64 of int64 | SchedFieldUInt64 of int64
| SchedFieldFloat of float | SchedFieldBool of bool
+ type typed_param = string * typed_param_value
+ and typed_param_value =
+ | TypedFieldInt32 of int32 | TypedFieldUInt32 of int32
+ | TypedFieldInt64 of int64 | TypedFieldUInt64 of int64
+ | TypedFieldFloat of float | TypedFieldBool of bool
+ | TypedFieldString of string
+
type migrate_flag = Live
type memory_flag = Virtual
+ type list_flag =
+ | ListActive
+ | ListInactive
+ | ListAll
+
type block_stats = {
rd_req : int64;
rd_bytes : int64;
tx_drop : int64;
}
+ type get_all_domain_stats_flag =
+ | GetAllDomainsStatsActive
+ | GetAllDomainsStatsInactive
+ | GetAllDomainsStatsOther
+ | GetAllDomainsStatsPaused
+ | GetAllDomainsStatsPersistent
+ | GetAllDomainsStatsRunning
+ | GetAllDomainsStatsShutoff
+ | GetAllDomainsStatsTransient
+ | GetAllDomainsStatsBacking
+ | GetAllDomainsStatsEnforceStats
+
+ type stats_type =
+ | StatsState | StatsCpuTotal | StatsBalloon | StatsVcpu
+ | StatsInterface | StatsBlock | StatsPerf
+
+ type domain_stats_record = {
+ dom_uuid : uuid;
+ params : typed_param array;
+ }
+
+ type xml_desc_flag =
+ | XmlSecure (* dump security sensitive information too *)
+ | XmlInactive (* dump inactive domain information *)
+ | XmlUpdateCPU (* update guest CPU requirements according to host CPU *)
+ | XmlMigratable (* dump XML suitable for migration *)
+
+ 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 create_linux : [>`W] Connect.t -> xml -> rw t
(** Create a new guest domain (not necessarily a Linux one)
- from the given XML.
+ from the given XML. Use {!create_xml} instead.
*)
- val create_linux_job : [>`W] Connect.t -> xml -> ([`Domain], rw) job_t
- (** Asynchronous domain creation. *)
+ val create_xml : [>`W] Connect.t -> xml -> domain_create_flag list -> rw t
+ (** Create a new guest domain from the given XML. *)
val lookup_by_id : 'a Connect.t -> int -> 'a t
(** Lookup a domain by ID. *)
val lookup_by_uuid : 'a Connect.t -> uuid -> 'a t
(** Resume a domain. *)
val save : [>`W] t -> filename -> unit
(** Suspend a domain, then save it to the file. *)
- val save_job : [>`W] t -> filename -> ([`Domain_nocreate], rw) job_t
- (** Asynchronous domain suspend. *)
val restore : [>`W] Connect.t -> filename -> unit
(** Restore a domain from a file. *)
- val restore_job : [>`W] Connect.t -> filename -> ([`Domain_nocreate], rw) job_t
- (** Asynchronous domain restore. *)
val core_dump : [>`W] t -> filename -> unit
(** Force a domain to core dump to the named file. *)
- val core_dump_job : [>`W] t -> filename -> ([`Domain_nocreate], rw) job_t
- (** Asynchronous core dump. *)
val shutdown : [>`W] t -> unit
(** Shutdown a domain. *)
val reboot : [>`W] t -> unit
val get_uuid_string : [>`R] t -> string
(** Get the domain UUID (as a printable string). *)
val get_id : [>`R] t -> int
- (** [getid dom] returns the ID of the domain.
-
- Do not call this on a defined but not running domain. Those
- domains don't have IDs, and you'll get an error here.
- *)
-
+ (** [get_id dom] returns the ID of the domain. In most cases
+ this returns [-1] if the domain is not running. *)
val get_os_type : [>`R] t -> string
(** Get the operating system type. *)
val get_max_memory : [>`R] t -> int64
(** Get information about a domain. *)
val get_xml_desc : [>`R] t -> xml
(** Get the XML description of a domain. *)
+ val get_xml_desc_flags : [>`W] t -> xml_desc_flag list -> xml
+ (** Get the XML description of a domain, with the possibility
+ to specify flags. *)
val get_scheduler_type : [>`R] t -> string * int
(** Get the scheduler type. *)
val get_scheduler_parameters : [>`R] t -> int -> sched_param array
(** Undefine a domain - removes its configuration. *)
val create : [>`W] t -> unit
(** Launch a defined (inactive) domain. *)
- val create_job : [>`W] t -> ([`Domain_nocreate], rw) job_t
- (** Asynchronous launch domain. *)
val get_autostart : [>`R] t -> bool
(** Get the autostart flag for a domain. *)
val set_autostart : [>`W] t -> bool -> unit
for a domain. See the libvirt documentation for details
of the array and bitmap returned from this function.
*)
+ val get_cpu_stats : [>`R] t -> typed_param list array
+ (** [get_pcpu_stats dom] returns the physical CPU stats
+ for a domain. See the libvirt documentation for details.
+ *)
val get_max_vcpus : [>`R] t -> int
(** Returns the maximum number of vCPUs supported for this domain. *)
val attach_device : [>`W] t -> xml -> unit
val interface_stats : [>`R] t -> string -> interface_stats
(** Returns network interface stats. *)
- val block_peek : [>`R] t -> string -> int64 -> int -> string -> int -> unit
+ val block_peek : [>`W] t -> string -> int64 -> int -> string -> int -> unit
(** [block_peek dom path offset size buf boff] reads [size] bytes at
[offset] in the domain's [path] block device.
If successful then the data is written into [buf] starting
- at offset [boff], for [size] bytes. *)
- val memory_peek : [>`R] t -> memory_flag -> int64 -> int -> string -> int ->
- unit
+ at offset [boff], for [size] bytes.
+
+ See also {!max_peek}. *)
+ val memory_peek : [>`W] 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 get_all_domain_stats : [>`R] Connect.t -> stats_type list -> get_all_domain_stats_flag list -> domain_stats_record array = "ocaml_libvirt_domain_get_all_domain_stats"
+ (** [get_all_domain_stats conn stats flags] allows you to read
+ all stats across multiple/all domains in a single call.
+
+ See the libvirt documentation for
+ [virConnectGetAllDomainStats]. *)
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},
+ {!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},
+ {!Connect.list_domains},
+ {!Connect.list_defined_domains},
+ {!get_info}.
+ *)
+
end
(** Module dealing with domains. [Domain.t] is the
domain object. *)
+module Event :
+sig
+
+ module Defined : sig
+ type t = [
+ | `Added (** Newly created config file *)
+ | `Updated (** Changed config file *)
+ | `Unknown of int
+ ]
+
+ val to_string: t -> string
+ end
+
+ module Undefined : sig
+ type t = [
+ | `Removed (** Deleted the config file *)
+ | `Unknown of int
+ ]
+
+ val to_string: t -> string
+ end
+
+ module Started : sig
+ type t = [
+ | `Booted (** Normal startup from boot *)
+ | `Migrated (** Incoming migration from another host *)
+ | `Restored (** Restored from a state file *)
+ | `FromSnapshot (** Restored from snapshot *)
+ | `Wakeup (** Started due to wakeup event *)
+ | `Unknown of int
+ ]
+
+ val to_string: t -> string
+ end
+
+ module Suspended : sig
+ type t = [
+ | `Paused (** Normal suspend due to admin pause *)
+ | `Migrated (** Suspended for offline migration *)
+ | `IOError (** Suspended due to a disk I/O error *)
+ | `Watchdog (** Suspended due to a watchdog firing *)
+ | `Restored (** Restored from paused state file *)
+ | `FromSnapshot (** Restored from paused snapshot *)
+ | `APIError (** suspended after failure during libvirt API call *)
+ | `Unknown of int
+ ]
+
+ val to_string: t -> string
+ end
+
+ module Resumed : sig
+ type t = [
+ | `Unpaused (** Normal resume due to admin unpause *)
+ | `Migrated (** Resumed for completion of migration *)
+ | `FromSnapshot (** Resumed from snapshot *)
+ | `Unknown of int
+ ]
+
+ val to_string: t -> string
+ end
+
+ module Stopped : sig
+ type t = [
+ | `Shutdown (** Normal shutdown *)
+ | `Destroyed (** Forced poweroff from host *)
+ | `Crashed (** Guest crashed *)
+ | `Migrated (** Migrated off to another host *)
+ | `Saved (** Saved to a state file *)
+ | `Failed (** Host emulator/mgmt failed *)
+ | `FromSnapshot (** offline snapshot loaded *)
+ | `Unknown of int
+ ]
+
+ val to_string: t -> string
+ end
+
+ module PM_suspended : sig
+ type t = [
+ | `Memory (** Guest was PM suspended to memory *)
+ | `Disk (** Guest was PM suspended to disk *)
+ | `Unknown of int
+ ]
+
+ val to_string: t -> string
+ end
+
+ module Lifecycle : sig
+ type t = [
+ | `Defined of Defined.t
+ | `Undefined of Undefined.t
+ | `Started of Started.t
+ | `Suspended of Suspended.t
+ | `Resumed of Resumed.t
+ | `Stopped of Stopped.t
+ | `Shutdown (* no detail defined yet *)
+ | `PMSuspended of PM_suspended.t
+ | `Unknown of int
+ ]
+
+ val to_string: t -> string
+ end
+
+ module Reboot : sig
+ type t = unit
+
+ val to_string: t -> string
+ end
+
+ module Rtc_change : sig
+ type t = int64
+
+ val to_string: t -> string
+ end
+
+ module Watchdog : sig
+ type t = [
+ | `None (** No action, watchdog ignored *)
+ | `Pause (** Guest CPUs are paused *)
+ | `Reset (** Guest CPUs are reset *)
+ | `Poweroff (** Guest is forcably powered off *)
+ | `Shutdown (** Guest is requested to gracefully shutdown *)
+ | `Debug (** No action, a debug message logged *)
+ | `Unknown of int (** newer libvirt *)
+ ]
+
+ val to_string: t -> string
+ end
+
+ module Io_error : sig
+ (** Represents both IOError and IOErrorReason *)
+ type action = [
+ | `None (** No action, IO error ignored *)
+ | `Pause (** Guest CPUs are paused *)
+ | `Report (** IO error reported to guest OS *)
+ | `Unknown of int (** newer libvirt *)
+ ]
+
+ type t = {
+ src_path: string option; (** The host file on which the I/O error occurred *)
+ dev_alias: string option; (** The guest device alias associated with the path *)
+ action: action; (** The action that is to be taken due to the IO error *)
+ reason: string option; (** The cause of the IO error *)
+ }
+
+ val to_string: t -> string
+ end
+
+ module Graphics_address : sig
+ type family = [
+ | `Ipv4 (** IPv4 address *)
+ | `Ipv6 (** IPv6 address *)
+ | `Unix (** UNIX socket path *)
+ | `Unknown of int (** newer libvirt *)
+ ]
+
+ type t = {
+ family: family; (** Address family *)
+ node: string option; (** Address of node (eg IP address, or UNIX path *)
+ service: string option; (** Service name/number (eg TCP port, or NULL) *)
+ }
+
+ val to_string: t -> string
+ end
+
+ module Graphics_subject : sig
+ type identity = {
+ ty: string option; (** Type of identity *)
+ name: string option; (** Identity value *)
+ }
+
+ type t = identity list
+
+ val to_string: t -> string
+ end
+
+ module Graphics : sig
+ type phase = [
+ | `Connect (** Initial socket connection established *)
+ | `Initialize (** Authentication & setup completed *)
+ | `Disconnect (** Final socket disconnection *)
+ | `Unknown of int (** newer libvirt *)
+ ]
+
+ type t = {
+ phase: phase; (** the phase of the connection *)
+ local: Graphics_address.t; (** the local server address *)
+ remote: Graphics_address.t; (** the remote client address *)
+ auth_scheme: string option; (** the authentication scheme activated *)
+ subject: Graphics_subject.t; (** the authenticated subject (user) *)
+ }
+
+ val to_string: t -> string
+ end
+
+ module Control_error : sig
+ type t = unit
+
+ val to_string: t -> string
+ end
+
+ module Block_job : sig
+ type ty = [
+ | `KnownUnknown (** explicitly named UNKNOWN in the spec *)
+ | `Pull
+ | `Copy
+ | `Commit
+ | `Unknown of int
+ ]
+
+ type status = [
+ | `Completed
+ | `Failed
+ | `Cancelled
+ | `Ready
+ | `Unknown of int
+ ]
+
+ type t = {
+ disk: string option; (** fully-qualified name of the affected disk *)
+ ty: ty; (** type of block job *)
+ status: status; (** final status of the operation *)
+ }
+
+ val to_string: t -> string
+ end
+
+ module Disk_change : sig
+ type reason = [
+ | `MissingOnStart
+ | `Unknown of int
+ ]
+
+ type t = {
+ old_src_path: string option; (** old source path *)
+ new_src_path: string option; (** new source path *)
+ dev_alias: string option; (** device alias name *)
+ reason: reason; (** reason why this callback was called *)
+ }
+
+ val to_string: t -> string
+ end
+
+ module Tray_change : sig
+ type reason = [
+ | `Open
+ | `Close
+ | `Unknown of int
+ ]
+
+ type t = {
+ dev_alias: string option; (** device alias *)
+ reason: reason; (** why the tray status was changed *)
+ }
+
+ val to_string: t -> string
+ end
+
+ module PM_wakeup : sig
+ type reason = [
+ | `Unknown of int
+ ]
+
+ type t = reason
+
+ val to_string: t -> string
+ end
+
+ module PM_suspend : sig
+ type reason = [
+ | `Unknown of int
+ ]
+
+ type t = reason
+
+ val to_string: t -> string
+ end
+
+ module Balloon_change : sig
+ type t = int64
+
+ val to_string: t -> string
+ end
+
+ module PM_suspend_disk : sig
+ type reason = [
+ | `Unknown of int
+ ]
+
+ type t = reason
+
+ val to_string: t -> string
+ end
+
+
+ type callback =
+ | Lifecycle of ([`R] Domain.t -> Lifecycle.t -> unit)
+ | Reboot of ([`R] Domain.t -> Reboot.t -> unit)
+ | RtcChange of ([`R] Domain.t -> Rtc_change.t -> unit)
+ | Watchdog of ([`R] Domain.t -> Watchdog.t -> unit)
+ | IOError of ([`R] Domain.t -> Io_error.t -> unit)
+ | Graphics of ([`R] Domain.t -> Graphics.t -> unit)
+ | IOErrorReason of ([`R] Domain.t -> Io_error.t -> unit)
+ | ControlError of ([`R] Domain.t -> Control_error.t -> unit)
+ | BlockJob of ([`R] Domain.t -> Block_job.t -> unit)
+ | DiskChange of ([`R] Domain.t -> Disk_change.t -> unit)
+ | TrayChange of ([`R] Domain.t -> Tray_change.t -> unit)
+ | PMWakeUp of ([`R] Domain.t -> PM_wakeup.t -> unit)
+ | PMSuspend of ([`R] Domain.t -> PM_suspend.t -> unit)
+ | BalloonChange of ([`R] Domain.t -> Balloon_change.t -> unit)
+ | PMSuspendDisk of ([`R] Domain.t -> PM_suspend_disk.t -> unit)
+
+ (** type of a registered call back function *)
+
+ val register_default_impl : unit -> unit
+ (** Registers the default event loop based on poll(). This
+ must be done before connections are opened.
+
+ Once registered call run_default_impl in a loop. *)
+
+ val run_default_impl : unit -> unit
+ (** Runs one iteration of the event loop. Applications will
+ generally want to have a thread which invokes this in an
+ infinite loop. *)
+
+ type callback_id
+ (** an individual event registration *)
+
+ val register_any : 'a Connect.t -> ?dom:'a Domain.t -> callback -> callback_id
+ (** [register_any con ?dom callback] registers [callback]
+ to receive notification of arbitrary domain events. Return
+ a registration id which can be used in [deregister_any].
+
+ If [?dom] is None then register for this kind of event on
+ all domains. If [dom] is [Some d] then register for this
+ kind of event only on [d].
+ *)
+
+ val deregister_any : 'a Connect.t -> callback_id -> unit
+ (** [deregister_any con id] deregisters the previously registered
+ callback with id [id]. *)
+
+ type timer_id
+ (** an individual timer event *)
+
+ val add_timeout : 'a Connect.t -> int -> (unit -> unit) -> timer_id
+ (** [add_timeout con ms cb] registers [cb] as a timeout callback
+ which will be called every [ms] milliseconds *)
+
+ val remove_timeout : 'a Connect.t -> timer_id -> unit
+ (** [remove_timeout con t] deregisters timeout callback [t]. *)
+
+end
+ (** Module dealing with events generated by domain
+ state changes. *)
+
(** {3 Networks} *)
module Network :
(** Lookup a network by UUID string. *)
val create_xml : [>`W] Connect.t -> xml -> rw t
(** Create a network. *)
- val create_xml_job : [>`W] Connect.t -> xml -> ([`Network], rw) job_t
- (** Asynchronous create network. *)
val define_xml : [>`W] Connect.t -> xml -> rw t
(** Define but don't activate a network. *)
val undefine : [>`W] t -> unit
(** Undefine configuration of a network. *)
val create : [>`W] t -> unit
(** Start up a defined (inactive) network. *)
- val create_job : [>`W] t -> ([`Network_nocreate], rw) job_t
- (** Asynchronous start network. *)
val destroy : [>`W] t -> unit
(** Destroy a network. *)
val free : [>`R] t -> unit
(** Get the XML description. *)
val get_autostart : [`R] t -> bool
(** Get the autostart flag for the storage pool. *)
- val set_autostart : [`W] t -> bool -> unit
+ val set_autostart : [>`W] t -> bool -> unit
(** Set the autostart flag for the storage pool. *)
val num_of_volumes : [`R] t -> int
val get_xml_desc : [`R] t -> xml
(** Get the XML description. *)
- val create_xml : [`W] Pool.t -> xml -> unit
+ val create_xml : [>`W] Pool.t -> xml -> unit
(** Create a storage volume. *)
- val delete : [`W] t -> unit
+ val delete : [>`W] t -> vol_delete_flags -> unit
(** Delete a storage volume. *)
val free : [>`R] t -> unit
(** Free a storage volume object in memory.
end
(** Module dealing with storage volumes. *)
-(** {3 Jobs and asynchronous processing} *)
-
-module Job :
-sig
- type ('jobclass, 'rw) t = ('jobclass, 'rw) job_t
- (** A background asynchronous job.
-
- Jobs represent a pending operation such as domain creation.
- The possible types for a job are:
-
-{v
-(`Domain, `W) Job.t Job creating a new domain
-(`Domain_nocreate, `W) Job.t Job acting on an existing domain
-(`Network, `W) Job.t Job creating a new network
-(`Network_nocreate, `W) Job.t Job acting on an existing network
-v}
- *)
-
- type job_type = Bounded | Unbounded
- (** A Bounded job is one where we can estimate time to completion. *)
-
- type job_state = Running | Complete | Failed | Cancelled
- (** State of the job. *)
-
- type job_info = {
- typ : job_type; (** Job type (Bounded, Unbounded) *)
- state : job_state; (** Job state (Running, etc.) *)
- running_time : int; (** Actual running time (seconds) *)
- (** The following fields are only available in Bounded jobs: *)
- remaining_time : int; (** Estimated time left (seconds) *)
- percent_complete : int (** Estimated percent complete *)
- }
-
- val get_info : ('a,'b) t -> job_info
- (** Get information and status about the job. *)
-
- val get_domain : ([`Domain], 'a) t -> 'a Domain.t
- (** Get the completed domain from a job.
-
- You should only call it on a job in state Complete. *)
-
- val get_network : ([`Network], 'a) t -> 'a Network.t
- (** Get the completed network from a job.
-
- You should only call it on a job in state Complete. *)
-
- val cancel : ('a,'b) t -> unit
- (** Cancel a job. *)
-
- val free : ('a, [>`R]) t -> unit
- (** Free a job object in memory.
-
- The job object is automatically freed if it is garbage
- collected. This function just forces it to be freed right
- away.
- *)
-
- external const : ('a, [>`R]) t -> ('a, ro) t = "%identity"
- (** [const conn] turns a read/write job into a read-only
- job. Note that the opposite operation is impossible.
- *)
-end
- (** Module dealing with asynchronous jobs. *)
-
(** {3 Error handling and exceptions} *)
module Virterror :
| VIR_WAR_NO_STORAGE
| VIR_ERR_NO_STORAGE_POOL
| VIR_ERR_NO_STORAGE_VOL
+ | VIR_WAR_NO_NODE
+ | VIR_ERR_INVALID_NODE_DEVICE
+ | VIR_ERR_NO_NODE_DEVICE
+ | VIR_ERR_NO_SECURITY_MODEL
+ | VIR_ERR_OPERATION_INVALID
+ | VIR_WAR_NO_INTERFACE
+ | VIR_ERR_NO_INTERFACE
+ | VIR_ERR_INVALID_INTERFACE
+ | VIR_ERR_MULTIPLE_INTERFACES
+ | VIR_WAR_NO_NWFILTER
+ | VIR_ERR_INVALID_NWFILTER
+ | VIR_ERR_NO_NWFILTER
+ | VIR_ERR_BUILD_FIREWALL
+ | VIR_WAR_NO_SECRET
+ | VIR_ERR_INVALID_SECRET
+ | VIR_ERR_NO_SECRET
+ | VIR_ERR_CONFIG_UNSUPPORTED
+ | VIR_ERR_OPERATION_TIMEOUT
+ | VIR_ERR_MIGRATE_PERSIST_FAILED
+ | VIR_ERR_HOOK_SCRIPT_FAILED
+ | VIR_ERR_INVALID_DOMAIN_SNAPSHOT
+ | VIR_ERR_NO_DOMAIN_SNAPSHOT
+ | VIR_ERR_INVALID_STREAM
+ | VIR_ERR_ARGUMENT_UNSUPPORTED
+ | VIR_ERR_STORAGE_PROBE_FAILED
+ | VIR_ERR_STORAGE_POOL_BUILT
+ | VIR_ERR_SNAPSHOT_REVERT_RISKY
+ | VIR_ERR_OPERATION_ABORTED
+ | VIR_ERR_AUTH_CANCELLED
+ | VIR_ERR_NO_DOMAIN_METADATA
+ | VIR_ERR_MIGRATE_UNSAFE
+ | VIR_ERR_OVERFLOW
+ | VIR_ERR_BLOCK_COPY_ACTIVE
+ | VIR_ERR_OPERATION_UNSUPPORTED
+ | VIR_ERR_SSH
+ | VIR_ERR_AGENT_UNRESPONSIVE
+ | VIR_ERR_RESOURCE_BUSY
+ | VIR_ERR_ACCESS_DENIED
+ | VIR_ERR_DBUS_SERVICE
+ | VIR_ERR_STORAGE_VOL_EXIST
+ | VIR_ERR_CPU_INCOMPATIBLE
+ | VIR_ERR_XML_INVALID_SCHEMA
+ | VIR_ERR_MIGRATE_FINISH_OK
+ | VIR_ERR_AUTH_UNAVAILABLE
+ | VIR_ERR_NO_SERVER
+ | VIR_ERR_NO_CLIENT
+ | VIR_ERR_AGENT_UNSYNCED
+ | VIR_ERR_LIBSSH
+ | VIR_ERR_DEVICE_MISSING
+ | VIR_ERR_INVALID_NWFILTER_BINDING
+ | VIR_ERR_NO_NWFILTER_BINDING
(* ^^ NB: If you add a variant you MUST edit
libvirt_c_epilogue.c:MAX_VIR_* *)
| VIR_ERR_UNKNOWN of int
| VIR_FROM_OPENVZ
| VIR_FROM_XENXM
| VIR_FROM_STATS_LINUX
+ | VIR_FROM_LXC
| VIR_FROM_STORAGE
+ | VIR_FROM_NETWORK
+ | VIR_FROM_DOMAIN
+ | VIR_FROM_UML
+ | VIR_FROM_NODEDEV
+ | VIR_FROM_XEN_INOTIFY
+ | VIR_FROM_SECURITY
+ | VIR_FROM_VBOX
+ | VIR_FROM_INTERFACE
+ | VIR_FROM_ONE
+ | VIR_FROM_ESX
+ | VIR_FROM_PHYP
+ | VIR_FROM_SECRET
+ | VIR_FROM_CPU
+ | VIR_FROM_XENAPI
+ | VIR_FROM_NWFILTER
+ | VIR_FROM_HOOK
+ | VIR_FROM_DOMAIN_SNAPSHOT
+ | VIR_FROM_AUDIT
+ | VIR_FROM_SYSINFO
+ | VIR_FROM_STREAMS
+ | VIR_FROM_VMWARE
+ | VIR_FROM_EVENT
+ | VIR_FROM_LIBXL
+ | VIR_FROM_LOCKING
+ | VIR_FROM_HYPERV
+ | VIR_FROM_CAPABILITIES
+ | VIR_FROM_URI
+ | VIR_FROM_AUTH
+ | VIR_FROM_DBUS
+ | VIR_FROM_PARALLELS
+ | VIR_FROM_DEVICE
+ | VIR_FROM_SSH
+ | VIR_FROM_LOCKSPACE
+ | VIR_FROM_INITCTL
+ | VIR_FROM_IDENTITY
+ | VIR_FROM_CGROUP
+ | VIR_FROM_ACCESS
+ | VIR_FROM_SYSTEMD
+ | VIR_FROM_BHYVE
+ | VIR_FROM_CRYPTO
+ | VIR_FROM_FIREWALL
+ | VIR_FROM_POLKIT
+ | VIR_FROM_THREAD
+ | VIR_FROM_ADMIN
+ | VIR_FROM_LOGGING
+ | VIR_FROM_XENXL
+ | VIR_FROM_PERF
+ | VIR_FROM_LIBSSH
+ | VIR_FROM_RESCTRL
(* ^^ NB: If you add a variant you MUST edit
libvirt_c_epilogue.c: MAX_VIR_* *)
| VIR_FROM_UNKNOWN of int
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.
+*)