Workaround lack of constness in custom_operations::identifier
[ocaml-libvirt.git] / libvirt / libvirt.mli
index 988f0a0..ff8d4ca 100644 (file)
@@ -1,11 +1,12 @@
 (** OCaml bindings for libvirt. *)
 (** 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
    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
 
    This library is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
@@ -60,47 +61,44 @@ v}
    {{:http://libvirt.org/html/libvirt-libvirt.html}virConnect*, virDomain* and virNetwork* functions from libvirt}.
    For brevity I usually rename these modules like this:
 
    {{: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
 module C = Libvirt.Connect
 module D = Libvirt.Domain
 module N = Libvirt.Network
-v}
+]}
 
    To get a connection handle, assuming a Xen hypervisor:
 
 
    To get a connection handle, assuming a Xen hypervisor:
 
-{v
+{[
 let name = "xen:///"
 let conn = C.connect_readonly ~name ()
 let name = "xen:///"
 let conn = C.connect_readonly ~name ()
-v}
+]}
 
    {3 Example: List running domains}
 
 
    {3 Example: List running domains}
 
-{v
+{[
 open Printf
 
 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;
   fun dom ->
     printf "%8d %s\n%!" (D.get_id dom) (D.get_name dom)
 ) domains;
-v}
+]}
 
    {3 Example: List inactive domains}
 
 
    {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}
 
 
    {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 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;
@@ -116,7 +114,7 @@ printf "hostname = %s\n%!" hostname;
 
 let uri = C.get_uri conn in
 printf "uri = %s\n%!" uri
 
 let uri = C.get_uri conn in
 printf "uri = %s\n%!" uri
-v}
+]}
 
 *)
 
 
 *)
 
@@ -139,23 +137,25 @@ 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.
     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}
 
     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}
 
 
     {3 Threads}
 
@@ -226,17 +226,19 @@ type ro = [`R]
 
        If you want to handle both read-write and read-only
        connections at runtime, use a variant similar to this:
 
        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
 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} *)
 
 
 (** {3 Connections} *)
 
@@ -258,6 +260,38 @@ sig
     threads : int;                     (** number of threads per core *)
   }
 
     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].
   val connect : ?name:string -> unit -> rw t
   val connect_readonly : ?name:string -> unit -> ro t
     (** [connect ~name ()] connects to the hypervisor with URI [name].
@@ -267,6 +301,9 @@ sig
        [connect_readonly] is the same but connects in read-only mode.
     *)
 
        [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 close : [>`R] t -> unit
     (** [close conn] closes and frees the connection object in memory.
 
@@ -292,7 +329,12 @@ sig
   val list_domains : [>`R] t -> int -> int array
     (** [list_domains conn max] returns the running domain IDs,
        up to a maximum of [max] entries.
   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].
        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. *)
     *)
   val num_of_domains : [>`R] t -> int
     (** Returns the number of running domains. *)
@@ -304,7 +346,12 @@ sig
     (** [list_defined_domains conn max]
        returns the names of the inactive domains, up to
        a maximum of [max] entries.
     (** [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].
        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. *)
     *)
   val num_of_networks : [>`R] t -> int
     (** Returns the number of networks. *)
@@ -364,14 +411,22 @@ sig
        CPU map between a single virtual and all physical CPUs of a domain.
     *)
 
        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]. *)
     (** [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]. *)
     (** [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]. *)
 
     (** [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.
   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.
@@ -394,7 +449,7 @@ sig
     | InfoShutdown | InfoShutoff | InfoCrashed
 
   type info = {
     | 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 *)
     max_mem : int64;                   (** maximum memory in kilobytes *)
     memory : int64;                    (** memory used in kilobytes *)
     nr_virt_cpu : int;                 (** number of virtual CPUs *)
@@ -410,16 +465,35 @@ sig
     cpu : int;                         (** real CPU number, -1 if offline *)
   }
 
     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 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 migrate_flag = Live
 
   type memory_flag = Virtual
 
+  type list_flag =
+    | ListActive
+    | ListInactive
+    | ListAll
+
   type block_stats = {
     rd_req : int64;
     rd_bytes : int64;
   type block_stats = {
     rd_req : int64;
     rd_bytes : int64;
@@ -439,12 +513,44 @@ sig
     tx_drop : 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)
   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
   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
@@ -469,16 +575,10 @@ sig
     (** Resume a domain. *)
   val save : [>`W] t -> filename -> unit
     (** Suspend a domain, then save it to the file. *)
     (** 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 : [>`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 : [>`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 shutdown : [>`W] t -> unit
     (** Shutdown a domain. *)
   val reboot : [>`W] t -> unit
@@ -490,12 +590,8 @@ sig
   val get_uuid_string : [>`R] t -> string
     (** Get the domain UUID (as a printable string). *)
   val get_id : [>`R] t -> int
   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
   val get_os_type : [>`R] t -> string
     (** Get the operating system type. *)
   val get_max_memory : [>`R] t -> int64
@@ -508,6 +604,9 @@ sig
     (** Get information about a domain. *)
   val get_xml_desc : [>`R] t -> xml
     (** Get the XML description of a domain. *)
     (** 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
   val get_scheduler_type : [>`R] t -> string * int
     (** Get the scheduler type. *)
   val get_scheduler_parameters : [>`R] t -> int -> sched_param array
@@ -520,8 +619,6 @@ sig
     (** Undefine a domain - removes its configuration. *)
   val create : [>`W] t -> unit
     (** Launch a defined (inactive) domain. *)
     (** 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
   val get_autostart : [>`R] t -> bool
     (** Get the autostart flag for a domain. *)
   val set_autostart : [>`W] t -> bool -> unit
@@ -537,6 +634,10 @@ sig
        for a domain.  See the libvirt documentation for details
        of the array and bitmap returned from this function.
     *)
        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 get_max_vcpus : [>`R] t -> int
     (** Returns the maximum number of vCPUs supported for this domain. *)
   val attach_device : [>`W] t -> xml -> unit
@@ -561,28 +662,418 @@ sig
   val interface_stats : [>`R] t -> string -> interface_stats
     (** Returns network interface stats. *)
 
   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
     (** [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 list -> int64 -> int ->
+       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
     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.
       *)
 
   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. *)
 
 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 : 
 (** {3 Networks} *)
 
 module Network : 
@@ -600,16 +1091,12 @@ sig
     (** Lookup a network by UUID string. *)
   val create_xml : [>`W] Connect.t -> xml -> rw t
     (** Create a 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 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
   val destroy : [>`W] t -> unit
     (** Destroy a network. *)
   val free : [>`R] t -> unit
@@ -707,7 +1194,7 @@ sig
     (** Get the XML description. *)
   val get_autostart : [`R] t -> bool
     (** Get the autostart flag for the storage pool. *)
     (** 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
     (** Set the autostart flag for the storage pool. *)
 
   val num_of_volumes : [`R] t -> int
@@ -760,9 +1247,9 @@ sig
   val get_xml_desc : [`R] t -> xml
     (** Get the XML description. *)
 
   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. *)
     (** 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.
     (** Delete a storage volume. *)
   val free : [>`R] t -> unit
     (** Free a storage volume object in memory.
@@ -779,70 +1266,6 @@ sig
 end
   (** Module dealing with storage volumes. *)
 
 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 :
 (** {3 Error handling and exceptions} *)
 
 module Virterror :
@@ -899,6 +1322,57 @@ sig
     | VIR_WAR_NO_STORAGE
     | VIR_ERR_NO_STORAGE_POOL
     | VIR_ERR_NO_STORAGE_VOL
     | 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
        (* ^^ NB: If you add a variant you MUST edit
           libvirt_c_epilogue.c:MAX_VIR_* *)
     | VIR_ERR_UNKNOWN of int
@@ -924,7 +1398,57 @@ sig
     | VIR_FROM_OPENVZ
     | VIR_FROM_XENXM
     | VIR_FROM_STATS_LINUX
     | VIR_FROM_OPENVZ
     | VIR_FROM_XENXM
     | VIR_FROM_STATS_LINUX
+    | VIR_FROM_LXC
     | VIR_FROM_STORAGE
     | 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
        (* ^^ NB: If you add a variant you MUST edit
           libvirt_c_epilogue.c: MAX_VIR_* *)
     | VIR_FROM_UNKNOWN of int
@@ -998,3 +1522,16 @@ exception Not_supported of string
     See also {{:http://libvirt.org/hvsupport.html}http://libvirt.org/hvsupport.html}
 *)
 
     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.
+*)