1 (** OCaml bindings for libvirt. *)
2 (* (C) Copyright 2007-2015 Richard W.M. Jones, Red Hat Inc.
5 This library is free software; you can redistribute it and/or
6 modify it under the terms of the GNU Lesser General Public
7 License as published by the Free Software Foundation; either
8 version 2 of the License, or (at your option) any later version,
9 with the OCaml linking exception described in ../COPYING.LIB.
11 This library is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
14 Lesser General Public License for more details.
16 You should have received a copy of the GNU Lesser General Public
17 License along with this library; if not, write to the Free Software
18 Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
22 {2 Introduction and examples}
24 This is a set of bindings for writing OCaml programs to
25 manage virtual machines through {{:http://libvirt.org/}libvirt}.
27 {3 Using libvirt interactively}
29 Using the interactive toplevel:
33 Objective Caml version 3.10.0
36 # #load "mllibvirt.cma";;
37 # let name = "test:///default";;
38 val name : string = "test:///default"
39 # let conn = Libvirt.Connect.connect_readonly ~name () ;;
40 val conn : Libvirt.ro Libvirt.Connect.t = <abstr>
41 # Libvirt.Connect.get_node_info conn;;
42 : Libvirt.Connect.node_info =
43 {Libvirt.Connect.model = "i686"; Libvirt.Connect.memory = 3145728L;
44 Libvirt.Connect.cpus = 16; Libvirt.Connect.mhz = 1400;
45 Libvirt.Connect.nodes = 2; Libvirt.Connect.sockets = 2;
46 Libvirt.Connect.cores = 2; Libvirt.Connect.threads = 2}
49 {3 Compiling libvirt programs}
51 This command compiles a program to native code:
54 ocamlopt -I +libvirt mllibvirt.cmxa list_domains.ml -o list_domains
57 {3 Example: Connect to the hypervisor}
59 The main modules are {!Libvirt.Connect}, {!Libvirt.Domain} and
60 {!Libvirt.Network} corresponding respectively to the
61 {{:http://libvirt.org/html/libvirt-libvirt.html}virConnect*, virDomain* and virNetwork* functions from libvirt}.
62 For brevity I usually rename these modules like this:
65 module C = Libvirt.Connect
66 module D = Libvirt.Domain
67 module N = Libvirt.Network
70 To get a connection handle, assuming a Xen hypervisor:
74 let conn = C.connect_readonly ~name ()
77 {3 Example: List running domains}
82 let domains = D.get_domains conn [D.ListActive] in
85 printf "%8d %s\n%!" (D.get_id dom) (D.get_name dom)
89 {3 Example: List inactive domains}
92 let domains = D.get_domains conn [D.ListInactive] in
95 printf "inactive %s\n%!" (D.get_name dom)
99 {3 Example: Print node info}
102 let node_info = C.get_node_info conn in
103 printf "model = %s\n" node_info.C.model;
104 printf "memory = %Ld K\n" node_info.C.memory;
105 printf "cpus = %d\n" node_info.C.cpus;
106 printf "mhz = %d\n" node_info.C.mhz;
107 printf "nodes = %d\n" node_info.C.nodes;
108 printf "sockets = %d\n" node_info.C.sockets;
109 printf "cores = %d\n" node_info.C.cores;
110 printf "threads = %d\n%!" node_info.C.threads;
112 let hostname = C.get_hostname conn in
113 printf "hostname = %s\n%!" hostname;
115 let uri = C.get_uri conn in
116 printf "uri = %s\n%!" uri
122 (** {2 Programming issues}
124 {3 General safety issues}
126 Memory allocation / automatic garbage collection of all libvirt
127 objects should be completely safe. If you find any safety issues
128 or if your pure OCaml program ever segfaults, please contact the author.
130 You can force a libvirt object to be freed early by calling
131 the [close] function on the object. This shouldn't affect
132 the safety of garbage collection and should only be used when
133 you want to explicitly free memory. Note that explicitly
134 closing a connection object does nothing if there are still
135 unclosed domain or network objects referencing it.
137 Note that even though you hold open (eg) a domain object, that
138 doesn't mean that the domain (virtual machine) actually exists.
139 The domain could have been shut down or deleted by another user.
140 Thus domain objects can raise odd exceptions at any time.
141 This is just the nature of virtualisation.
143 {3 Backwards and forwards compatibility}
145 OCaml-libvirt requires libvirt version 1.0.2 or later. Future
146 releases of OCaml-libvirt will use newer features of libvirt
147 and therefore will require later versions of libvirt. It is always
148 possible to dynamically link your application against a newer
149 libvirt than OCaml-libvirt was originally compiled against.
151 {3 Get list of domains and domain infos}
153 This is a very common operation, and libvirt supports various
154 different methods to do it. We have hidden the complexity in a
155 flexible {!Libvirt.Domain.get_domains} and
156 {!Libvirt.Domain.get_domains_and_infos} calls which is easy to use and
157 automatically chooses the most efficient method depending on the
158 version of libvirt in use.
162 You can issue multiple concurrent libvirt requests in
163 different threads. However you must follow this rule:
164 Each thread must have its own separate libvirt connection, {i or}
165 you must implement your own mutex scheme to ensure that no
166 two threads can ever make concurrent calls using the same
169 (Note that multithreaded code is not well tested. If you find
170 bugs please report them.)
174 Libvirt requires all callers to call virInitialize before
175 using the library. This is done automatically for you by
176 these bindings when the program starts up, and we believe
177 that the way this is done is safe.
183 (** This is a "raw" UUID, ie. a packed string of bytes. *)
186 (** Type of XML (an uninterpreted string of bytes). Use PXP, expat,
187 xml-light, etc. if you want to do anything useful with the XML.
190 type filename = string
193 val get_version : ?driver:string -> unit -> int * int
194 (** [get_version ()] returns the library version in the first part
195 of the tuple, and [0] in the second part.
197 [get_version ~driver ()] returns the library version in the first
198 part of the tuple, and the version of the driver called [driver]
201 The version numbers are encoded as
202 1,000,000 * major + 1,000 * minor + release.
205 val uuid_length : int
206 (** Length of packed UUIDs. *)
208 val uuid_string_length : int
209 (** Length of UUID strings. *)
214 {{:http://caml.inria.fr/pub/ml-archives/caml-list/2004/07/80683af867cce6bf8fff273973f70c95.en.html}phantom types}
215 are used to ensure the type-safety of read-only
216 versus read-write connections.
218 All connection/domain/etc. objects are marked with
219 a phantom read-write or read-only type, and trying to
220 pass a read-only object into a function which could
221 mutate the object will cause a compile time error.
223 Each module provides a function like {!Libvirt.Connect.const}
224 to demote a read-write object into a read-only object. The
225 opposite operation is, of course, not allowed.
227 If you want to handle both read-write and read-only
228 connections at runtime, use a variant similar to this:
232 | Read_only of Libvirt.ro Libvirt.Connect.t
233 | Read_write of Libvirt.rw Libvirt.Connect.t
237 (** {3 Forward definitions}
239 These definitions are placed here to avoid the need to
240 use recursive module dependencies.
243 (** {3 Connections} *)
248 (** Connection. Read-only connections have type [ro Connect.t] and
249 read-write connections have type [rw Connect.t].
253 model : string; (** CPU model *)
254 memory : int64; (** memory size in kilobytes *)
255 cpus : int; (** number of active CPUs *)
256 mhz : int; (** expected CPU frequency *)
257 nodes : int; (** number of NUMA nodes (1 = UMA) *)
258 sockets : int; (** number of CPU sockets per node *)
259 cores : int; (** number of cores per socket *)
260 threads : int; (** number of threads per core *)
263 type credential_type =
264 | CredentialUsername (** Identity to act as *)
265 | CredentialAuthname (** Identify to authorize as *)
266 | CredentialLanguage (** RFC 1766 languages, comma separated *)
267 | CredentialCnonce (** client supplies a nonce *)
268 | CredentialPassphrase (** Passphrase secret *)
269 | CredentialEchoprompt (** Challenge response *)
270 | CredentialNoechoprompt (** Challenge response *)
271 | CredentialRealm (** Authentication realm *)
272 | CredentialExternal (** Externally managed credential *)
275 typ : credential_type; (** The type of credential *)
276 prompt : string; (** Prompt to show to user *)
277 challenge : string option; (** Additional challenge to show *)
278 defresult : string option; (** Optional default result *)
282 credtype : credential_type list; (** List of supported credential_type values *)
283 cb : (credential list -> string option list);
284 (** Callback used to collect credentials.
286 The input is a list of all the requested credentials.
288 The function returns a list of all the results from the
289 requested credentials, so the number of results {e must} match
290 the number of input credentials. Each result is optional,
291 and in case it is [None] it means there was no result.
295 val connect : ?name:string -> unit -> rw t
296 val connect_readonly : ?name:string -> unit -> ro t
297 (** [connect ~name ()] connects to the hypervisor with URI [name].
299 [connect ()] connects to the default hypervisor.
301 [connect_readonly] is the same but connects in read-only mode.
304 val connect_auth : ?name:string -> auth -> rw t
305 val connect_auth_readonly : ?name:string -> auth -> ro t
307 val close : [>`R] t -> unit
308 (** [close conn] closes and frees the connection object in memory.
310 The connection is automatically closed if it is garbage
311 collected. This function just forces it to be closed
312 and freed right away.
315 val get_type : [>`R] t -> string
316 (** Returns the name of the driver (hypervisor). *)
318 val get_version : [>`R] t -> int
319 (** Returns the driver version
320 [major * 1_000_000 + minor * 1000 + release]
322 val get_hostname : [>`R] t -> string
323 (** Returns the hostname of the physical server. *)
324 val get_uri : [>`R] t -> string
325 (** Returns the canonical connection URI. *)
326 val get_max_vcpus : [>`R] t -> ?type_:string -> unit -> int
327 (** Returns the maximum number of virtual CPUs
328 supported by a guest VM of a particular type. *)
329 val list_domains : [>`R] t -> int -> int array
330 (** [list_domains conn max] returns the running domain IDs,
331 up to a maximum of [max] entries.
333 Call {!num_of_domains} first to get a value for [max].
336 {!Libvirt.Domain.get_domains},
337 {!Libvirt.Domain.get_domains_and_infos}.
339 val num_of_domains : [>`R] t -> int
340 (** Returns the number of running domains. *)
341 val get_capabilities : [>`R] t -> xml
342 (** Returns the hypervisor capabilities (as XML). *)
343 val num_of_defined_domains : [>`R] t -> int
344 (** Returns the number of inactive (shutdown) domains. *)
345 val list_defined_domains : [>`R] t -> int -> string array
346 (** [list_defined_domains conn max]
347 returns the names of the inactive domains, up to
348 a maximum of [max] entries.
350 Call {!num_of_defined_domains} first to get a value for [max].
353 {!Libvirt.Domain.get_domains},
354 {!Libvirt.Domain.get_domains_and_infos}.
356 val num_of_networks : [>`R] t -> int
357 (** Returns the number of networks. *)
358 val list_networks : [>`R] t -> int -> string array
359 (** [list_networks conn max]
360 returns the names of the networks, up to a maximum
362 Call {!num_of_networks} first to get a value for [max].
364 val num_of_defined_networks : [>`R] t -> int
365 (** Returns the number of inactive networks. *)
366 val list_defined_networks : [>`R] t -> int -> string array
367 (** [list_defined_networks conn max]
368 returns the names of the inactive networks, up to a maximum
370 Call {!num_of_defined_networks} first to get a value for [max].
373 val num_of_pools : [>`R] t -> int
374 (** Returns the number of storage pools. *)
375 val list_pools : [>`R] t -> int -> string array
376 (** Return list of storage pools. *)
377 val num_of_defined_pools : [>`R] t -> int
378 (** Returns the number of storage pools. *)
379 val list_defined_pools : [>`R] t -> int -> string array
380 (** Return list of storage pools. *)
382 (* The name of this function is inconsistent, but the inconsistency
383 * is really in libvirt itself.
385 val num_of_secrets : [>`R] t -> int
386 (** Returns the number of secrets. *)
387 val list_secrets : [>`R] t -> int -> string array
388 (** Returns the list of secrets. *)
389 val get_node_info : [>`R] t -> node_info
390 (** Return information about the physical server. *)
392 val node_get_free_memory : [> `R] t -> int64
394 [node_get_free_memory conn]
395 returns the amount of free memory (not allocated to any guest)
399 val node_get_cells_free_memory : [> `R] t -> int -> int -> int64 array
401 [node_get_cells_free_memory conn start max]
402 returns the amount of free memory on each NUMA cell in kilobytes.
403 [start] is the first cell for which we return free memory.
404 [max] is the maximum number of cells for which we return free memory.
405 Returns an array of up to [max] entries in length.
408 val maxcpus_of_node_info : node_info -> int
409 (** Calculate the total number of CPUs supported (but not necessarily
413 val cpumaplen : int -> int
414 (** Calculate the length (in bytes) required to store the complete
415 CPU map between a single virtual and all physical CPUs of a domain.
418 val use_cpu : bytes -> int -> unit
419 (** [use_cpu cpumap cpu] marks [cpu] as usable in [cpumap]. *)
420 val unuse_cpu : bytes -> int -> unit
421 (** [unuse_cpu cpumap cpu] marks [cpu] as not usable in [cpumap]. *)
422 val cpu_usable : bytes -> int -> int -> int -> bool
423 (** [cpu_usable cpumaps maplen vcpu cpu] checks returns true iff the
424 [cpu] is usable by [vcpu]. *)
426 val set_keep_alive : [>`R] t -> int -> int -> unit
427 (** [set_keep_alive conn interval count] starts sending keepalive
428 messages after [interval] seconds of inactivity and consider the
429 connection to be broken when no response is received after [count]
431 Note: the client has to implement and run an event loop to
432 be able to use keep-alive messages. *)
434 val get_auth_default : unit -> auth
435 (** [get_auth_default ()] returns the default authentication handler
439 external const : [>`R] t -> ro t = "%identity"
440 (** [const conn] turns a read/write connection into a read-only
441 connection. Note that the opposite operation is impossible.
444 (** Module dealing with connections. [Connect.t] is the
445 connection object. *)
452 (** Domain handle. Read-only handles have type [ro Domain.t] and
453 read-write handles have type [rw Domain.t].
457 | InfoNoState | InfoRunning | InfoBlocked | InfoPaused
458 | InfoShutdown | InfoShutoff | InfoCrashed
461 state : state; (** running state *)
462 max_mem : int64; (** maximum memory in kilobytes *)
463 memory : int64; (** memory used in kilobytes *)
464 nr_virt_cpu : int; (** number of virtual CPUs *)
465 cpu_time : int64; (** CPU time used in nanoseconds *)
468 type vcpu_state = VcpuOffline | VcpuRunning | VcpuBlocked
471 number : int; (** virtual CPU number *)
472 vcpu_state : vcpu_state; (** state *)
473 vcpu_time : int64; (** CPU time used in nanoseconds *)
474 cpu : int; (** real CPU number, -1 if offline *)
477 type domain_create_flag =
478 | START_PAUSED (** Launch guest in paused state *)
479 | START_AUTODESTROY (** Automatically kill guest on close *)
480 | START_BYPASS_CACHE (** Avoid filesystem cache pollution *)
481 | START_FORCE_BOOT (** Discard any managed save *)
482 | START_VALIDATE (** Validate XML against schema *)
484 type sched_param = string * sched_param_value
485 and sched_param_value =
486 | SchedFieldInt32 of int32 | SchedFieldUInt32 of int32
487 | SchedFieldInt64 of int64 | SchedFieldUInt64 of int64
488 | SchedFieldFloat of float | SchedFieldBool of bool
490 type typed_param = string * typed_param_value
491 and typed_param_value =
492 | TypedFieldInt32 of int32 | TypedFieldUInt32 of int32
493 | TypedFieldInt64 of int64 | TypedFieldUInt64 of int64
494 | TypedFieldFloat of float | TypedFieldBool of bool
495 | TypedFieldString of string
497 type migrate_flag = Live
499 type memory_flag = Virtual
514 type interface_stats = {
525 type get_all_domain_stats_flag =
526 | GetAllDomainsStatsActive
527 | GetAllDomainsStatsInactive
528 | GetAllDomainsStatsOther
529 | GetAllDomainsStatsPaused
530 | GetAllDomainsStatsPersistent
531 | GetAllDomainsStatsRunning
532 | GetAllDomainsStatsShutoff
533 | GetAllDomainsStatsTransient
534 | GetAllDomainsStatsBacking
535 | GetAllDomainsStatsEnforceStats
538 | StatsState | StatsCpuTotal | StatsBalloon | StatsVcpu
539 | StatsInterface | StatsBlock | StatsPerf
541 type domain_stats_record = {
543 params : typed_param array;
547 | XmlSecure (* dump security sensitive information too *)
548 | XmlInactive (* dump inactive domain information *)
549 | XmlUpdateCPU (* update guest CPU requirements according to host CPU *)
550 | XmlMigratable (* dump XML suitable for migration *)
552 val max_peek : [>`R] t -> int
553 (** Maximum size supported by the {!block_peek} and {!memory_peek}
554 functions. If you want to peek more than this then you must
555 break your request into chunks. *)
557 val create_linux : [>`W] Connect.t -> xml -> rw t
558 (** Create a new guest domain (not necessarily a Linux one)
559 from the given XML. Use {!create_xml} instead.
561 val create_xml : [>`W] Connect.t -> xml -> domain_create_flag list -> rw t
562 (** Create a new guest domain from the given XML. *)
563 val lookup_by_id : 'a Connect.t -> int -> 'a t
564 (** Lookup a domain by ID. *)
565 val lookup_by_uuid : 'a Connect.t -> uuid -> 'a t
566 (** Lookup a domain by UUID. This uses the packed byte array UUID. *)
567 val lookup_by_uuid_string : 'a Connect.t -> string -> 'a t
568 (** Lookup a domain by (string) UUID. *)
569 val lookup_by_name : 'a Connect.t -> string -> 'a t
570 (** Lookup a domain by name. *)
571 val destroy : [>`W] t -> unit
572 (** Abruptly destroy a domain. *)
573 val free : [>`R] t -> unit
574 (** [free domain] frees the domain object in memory.
576 The domain object is automatically freed if it is garbage
577 collected. This function just forces it to be freed right
581 val suspend : [>`W] t -> unit
582 (** Suspend a domain. *)
583 val resume : [>`W] t -> unit
584 (** Resume a domain. *)
585 val save : [>`W] t -> filename -> unit
586 (** Suspend a domain, then save it to the file. *)
587 val restore : [>`W] Connect.t -> filename -> unit
588 (** Restore a domain from a file. *)
589 val core_dump : [>`W] t -> filename -> unit
590 (** Force a domain to core dump to the named file. *)
591 val shutdown : [>`W] t -> unit
592 (** Shutdown a domain. *)
593 val reboot : [>`W] t -> unit
594 (** Reboot a domain. *)
595 val get_name : [>`R] t -> string
596 (** Get the domain name. *)
597 val get_uuid : [>`R] t -> uuid
598 (** Get the domain UUID (as a packed byte array). *)
599 val get_uuid_string : [>`R] t -> string
600 (** Get the domain UUID (as a printable string). *)
601 val get_id : [>`R] t -> int
602 (** [get_id dom] returns the ID of the domain. In most cases
603 this returns [-1] if the domain is not running. *)
604 val get_os_type : [>`R] t -> string
605 (** Get the operating system type. *)
606 val get_max_memory : [>`R] t -> int64
607 (** Get the maximum memory allocation. *)
608 val set_max_memory : [>`W] t -> int64 -> unit
609 (** Set the maximum memory allocation. *)
610 val set_memory : [>`W] t -> int64 -> unit
611 (** Set the normal memory allocation. *)
612 val get_info : [>`R] t -> info
613 (** Get information about a domain. *)
614 val get_xml_desc : [>`R] t -> xml
615 (** Get the XML description of a domain. *)
616 val get_xml_desc_flags : [>`W] t -> xml_desc_flag list -> xml
617 (** Get the XML description of a domain, with the possibility
619 val get_scheduler_type : [>`R] t -> string * int
620 (** Get the scheduler type. *)
621 val get_scheduler_parameters : [>`R] t -> int -> sched_param array
622 (** Get the array of scheduler parameters. *)
623 val set_scheduler_parameters : [>`W] t -> sched_param array -> unit
624 (** Set the array of scheduler parameters. *)
625 val define_xml : [>`W] Connect.t -> xml -> rw t
626 (** Define a new domain (but don't start it up) from the XML. *)
627 val undefine : [>`W] t -> unit
628 (** Undefine a domain - removes its configuration. *)
629 val create : [>`W] t -> unit
630 (** Launch a defined (inactive) domain. *)
631 val get_autostart : [>`R] t -> bool
632 (** Get the autostart flag for a domain. *)
633 val set_autostart : [>`W] t -> bool -> unit
634 (** Set the autostart flag for a domain. *)
635 val set_vcpus : [>`W] t -> int -> unit
636 (** Change the number of vCPUs available to a domain. *)
637 val pin_vcpu : [>`W] t -> int -> string -> unit
638 (** [pin_vcpu dom vcpu bitmap] pins a domain vCPU to a bitmap of physical
639 CPUs. See the libvirt documentation for details of the
640 layout of the bitmap. *)
641 val get_vcpus : [>`R] t -> int -> int -> int * vcpu_info array * string
642 (** [get_vcpus dom maxinfo maplen] returns the pinning information
643 for a domain. See the libvirt documentation for details
644 of the array and bitmap returned from this function.
646 val get_cpu_stats : [>`R] t -> typed_param list array
647 (** [get_pcpu_stats dom] returns the physical CPU stats
648 for a domain. See the libvirt documentation for details.
650 val get_max_vcpus : [>`R] t -> int
651 (** Returns the maximum number of vCPUs supported for this domain. *)
652 val attach_device : [>`W] t -> xml -> unit
653 (** Attach a device (described by the device XML) to a domain. *)
654 val detach_device : [>`W] t -> xml -> unit
655 (** Detach a device (described by the device XML) from a domain. *)
657 val migrate : [>`W] t -> [>`W] Connect.t -> migrate_flag list ->
658 ?dname:string -> ?uri:string -> ?bandwidth:int -> unit -> rw t
659 (** [migrate dom dconn flags ()] migrates a domain to a
660 destination host described by [dconn].
662 The optional flag [?dname] is used to rename the domain.
664 The optional flag [?uri] is used to route the migration.
666 The optional flag [?bandwidth] is used to limit the bandwidth
667 used for migration (in Mbps). *)
669 val block_stats : [>`R] t -> string -> block_stats
670 (** Returns block device stats. *)
671 val interface_stats : [>`R] t -> string -> interface_stats
672 (** Returns network interface stats. *)
674 val block_peek : [>`W] t -> string -> int64 -> int -> string -> int -> unit
675 (** [block_peek dom path offset size buf boff] reads [size] bytes at
676 [offset] in the domain's [path] block device.
678 If successful then the data is written into [buf] starting
679 at offset [boff], for [size] bytes.
681 See also {!max_peek}. *)
682 val memory_peek : [>`W] t -> memory_flag list -> int64 -> int ->
683 string -> int -> unit
684 (** [memory_peek dom Virtual offset size] reads [size] bytes
685 at [offset] in the domain's virtual memory.
687 If successful then the data is written into [buf] starting
688 at offset [boff], for [size] bytes.
690 See also {!max_peek}. *)
692 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"
693 (** [get_all_domain_stats conn stats flags] allows you to read
694 all stats across multiple/all domains in a single call.
696 See the libvirt documentation for
697 [virConnectGetAllDomainStats]. *)
699 external const : [>`R] t -> ro t = "%identity"
700 (** [const dom] turns a read/write domain handle into a read-only
701 domain handle. Note that the opposite operation is impossible.
704 val get_domains : ([>`R] as 'a) Connect.t -> list_flag list -> 'a t list
705 (** Get the active and/or inactive domains using the most
706 efficient method available.
709 {!get_domains_and_infos},
710 {!Connect.list_domains},
711 {!Connect.list_defined_domains}.
714 val get_domains_and_infos : ([>`R] as 'a) Connect.t -> list_flag list ->
716 (** This gets the active and/or inactive domains and the
717 domain info for each one using the most efficient
722 {!Connect.list_domains},
723 {!Connect.list_defined_domains},
728 (** Module dealing with domains. [Domain.t] is the
736 | `Added (** Newly created config file *)
737 | `Updated (** Changed config file *)
741 val to_string: t -> string
744 module Undefined : sig
746 | `Removed (** Deleted the config file *)
750 val to_string: t -> string
755 | `Booted (** Normal startup from boot *)
756 | `Migrated (** Incoming migration from another host *)
757 | `Restored (** Restored from a state file *)
758 | `FromSnapshot (** Restored from snapshot *)
759 | `Wakeup (** Started due to wakeup event *)
763 val to_string: t -> string
766 module Suspended : sig
768 | `Paused (** Normal suspend due to admin pause *)
769 | `Migrated (** Suspended for offline migration *)
770 | `IOError (** Suspended due to a disk I/O error *)
771 | `Watchdog (** Suspended due to a watchdog firing *)
772 | `Restored (** Restored from paused state file *)
773 | `FromSnapshot (** Restored from paused snapshot *)
774 | `APIError (** suspended after failure during libvirt API call *)
778 val to_string: t -> string
783 | `Unpaused (** Normal resume due to admin unpause *)
784 | `Migrated (** Resumed for completion of migration *)
785 | `FromSnapshot (** Resumed from snapshot *)
789 val to_string: t -> string
794 | `Shutdown (** Normal shutdown *)
795 | `Destroyed (** Forced poweroff from host *)
796 | `Crashed (** Guest crashed *)
797 | `Migrated (** Migrated off to another host *)
798 | `Saved (** Saved to a state file *)
799 | `Failed (** Host emulator/mgmt failed *)
800 | `FromSnapshot (** offline snapshot loaded *)
804 val to_string: t -> string
807 module PM_suspended : sig
809 | `Memory (** Guest was PM suspended to memory *)
810 | `Disk (** Guest was PM suspended to disk *)
814 val to_string: t -> string
817 module Lifecycle : sig
819 | `Defined of Defined.t
820 | `Undefined of Undefined.t
821 | `Started of Started.t
822 | `Suspended of Suspended.t
823 | `Resumed of Resumed.t
824 | `Stopped of Stopped.t
825 | `Shutdown (* no detail defined yet *)
826 | `PMSuspended of PM_suspended.t
830 val to_string: t -> string
836 val to_string: t -> string
839 module Rtc_change : sig
842 val to_string: t -> string
845 module Watchdog : sig
847 | `None (** No action, watchdog ignored *)
848 | `Pause (** Guest CPUs are paused *)
849 | `Reset (** Guest CPUs are reset *)
850 | `Poweroff (** Guest is forcably powered off *)
851 | `Shutdown (** Guest is requested to gracefully shutdown *)
852 | `Debug (** No action, a debug message logged *)
853 | `Unknown of int (** newer libvirt *)
856 val to_string: t -> string
859 module Io_error : sig
860 (** Represents both IOError and IOErrorReason *)
862 | `None (** No action, IO error ignored *)
863 | `Pause (** Guest CPUs are paused *)
864 | `Report (** IO error reported to guest OS *)
865 | `Unknown of int (** newer libvirt *)
869 src_path: string option; (** The host file on which the I/O error occurred *)
870 dev_alias: string option; (** The guest device alias associated with the path *)
871 action: action; (** The action that is to be taken due to the IO error *)
872 reason: string option; (** The cause of the IO error *)
875 val to_string: t -> string
878 module Graphics_address : sig
880 | `Ipv4 (** IPv4 address *)
881 | `Ipv6 (** IPv6 address *)
882 | `Unix (** UNIX socket path *)
883 | `Unknown of int (** newer libvirt *)
887 family: family; (** Address family *)
888 node: string option; (** Address of node (eg IP address, or UNIX path *)
889 service: string option; (** Service name/number (eg TCP port, or NULL) *)
892 val to_string: t -> string
895 module Graphics_subject : sig
897 ty: string option; (** Type of identity *)
898 name: string option; (** Identity value *)
901 type t = identity list
903 val to_string: t -> string
906 module Graphics : sig
908 | `Connect (** Initial socket connection established *)
909 | `Initialize (** Authentication & setup completed *)
910 | `Disconnect (** Final socket disconnection *)
911 | `Unknown of int (** newer libvirt *)
915 phase: phase; (** the phase of the connection *)
916 local: Graphics_address.t; (** the local server address *)
917 remote: Graphics_address.t; (** the remote client address *)
918 auth_scheme: string option; (** the authentication scheme activated *)
919 subject: Graphics_subject.t; (** the authenticated subject (user) *)
922 val to_string: t -> string
925 module Control_error : sig
928 val to_string: t -> string
931 module Block_job : sig
933 | `KnownUnknown (** explicitly named UNKNOWN in the spec *)
949 disk: string option; (** fully-qualified name of the affected disk *)
950 ty: ty; (** type of block job *)
951 status: status; (** final status of the operation *)
954 val to_string: t -> string
957 module Disk_change : sig
964 old_src_path: string option; (** old source path *)
965 new_src_path: string option; (** new source path *)
966 dev_alias: string option; (** device alias name *)
967 reason: reason; (** reason why this callback was called *)
970 val to_string: t -> string
973 module Tray_change : sig
981 dev_alias: string option; (** device alias *)
982 reason: reason; (** why the tray status was changed *)
985 val to_string: t -> string
988 module PM_wakeup : sig
995 val to_string: t -> string
998 module PM_suspend : sig
1005 val to_string: t -> string
1008 module Balloon_change : sig
1011 val to_string: t -> string
1014 module PM_suspend_disk : sig
1021 val to_string: t -> string
1026 | Lifecycle of ([`R] Domain.t -> Lifecycle.t -> unit)
1027 | Reboot of ([`R] Domain.t -> Reboot.t -> unit)
1028 | RtcChange of ([`R] Domain.t -> Rtc_change.t -> unit)
1029 | Watchdog of ([`R] Domain.t -> Watchdog.t -> unit)
1030 | IOError of ([`R] Domain.t -> Io_error.t -> unit)
1031 | Graphics of ([`R] Domain.t -> Graphics.t -> unit)
1032 | IOErrorReason of ([`R] Domain.t -> Io_error.t -> unit)
1033 | ControlError of ([`R] Domain.t -> Control_error.t -> unit)
1034 | BlockJob of ([`R] Domain.t -> Block_job.t -> unit)
1035 | DiskChange of ([`R] Domain.t -> Disk_change.t -> unit)
1036 | TrayChange of ([`R] Domain.t -> Tray_change.t -> unit)
1037 | PMWakeUp of ([`R] Domain.t -> PM_wakeup.t -> unit)
1038 | PMSuspend of ([`R] Domain.t -> PM_suspend.t -> unit)
1039 | BalloonChange of ([`R] Domain.t -> Balloon_change.t -> unit)
1040 | PMSuspendDisk of ([`R] Domain.t -> PM_suspend_disk.t -> unit)
1042 (** type of a registered call back function *)
1044 val register_default_impl : unit -> unit
1045 (** Registers the default event loop based on poll(). This
1046 must be done before connections are opened.
1048 Once registered call run_default_impl in a loop. *)
1050 val run_default_impl : unit -> unit
1051 (** Runs one iteration of the event loop. Applications will
1052 generally want to have a thread which invokes this in an
1056 (** an individual event registration *)
1058 val register_any : 'a Connect.t -> ?dom:'a Domain.t -> callback -> callback_id
1059 (** [register_any con ?dom callback] registers [callback]
1060 to receive notification of arbitrary domain events. Return
1061 a registration id which can be used in [deregister_any].
1063 If [?dom] is None then register for this kind of event on
1064 all domains. If [dom] is [Some d] then register for this
1065 kind of event only on [d].
1068 val deregister_any : 'a Connect.t -> callback_id -> unit
1069 (** [deregister_any con id] deregisters the previously registered
1070 callback with id [id]. *)
1073 (** an individual timer event *)
1075 val add_timeout : 'a Connect.t -> int -> (unit -> unit) -> timer_id
1076 (** [add_timeout con ms cb] registers [cb] as a timeout callback
1077 which will be called every [ms] milliseconds *)
1079 val remove_timeout : 'a Connect.t -> timer_id -> unit
1080 (** [remove_timeout con t] deregisters timeout callback [t]. *)
1083 (** Module dealing with events generated by domain
1091 (** Network handle. Read-only handles have type [ro Network.t] and
1092 read-write handles have type [rw Network.t].
1095 val lookup_by_name : 'a Connect.t -> string -> 'a t
1096 (** Lookup a network by name. *)
1097 val lookup_by_uuid : 'a Connect.t -> uuid -> 'a t
1098 (** Lookup a network by (packed) UUID. *)
1099 val lookup_by_uuid_string : 'a Connect.t -> string -> 'a t
1100 (** Lookup a network by UUID string. *)
1101 val create_xml : [>`W] Connect.t -> xml -> rw t
1102 (** Create a network. *)
1103 val define_xml : [>`W] Connect.t -> xml -> rw t
1104 (** Define but don't activate a network. *)
1105 val undefine : [>`W] t -> unit
1106 (** Undefine configuration of a network. *)
1107 val create : [>`W] t -> unit
1108 (** Start up a defined (inactive) network. *)
1109 val destroy : [>`W] t -> unit
1110 (** Destroy a network. *)
1111 val free : [>`R] t -> unit
1112 (** [free network] frees the network object in memory.
1114 The network object is automatically freed if it is garbage
1115 collected. This function just forces it to be freed right
1119 val get_name : [>`R] t -> string
1120 (** Get network name. *)
1121 val get_uuid : [>`R] t -> uuid
1122 (** Get network packed UUID. *)
1123 val get_uuid_string : [>`R] t -> string
1124 (** Get network UUID as a printable string. *)
1125 val get_xml_desc : [>`R] t -> xml
1126 (** Get XML description of a network. *)
1127 val get_bridge_name : [>`R] t -> string
1128 (** Get bridge device name of a network. *)
1129 val get_autostart : [>`R] t -> bool
1130 (** Get the autostart flag for a network. *)
1131 val set_autostart : [>`W] t -> bool -> unit
1132 (** Set the autostart flag for a network. *)
1134 external const : [>`R] t -> ro t = "%identity"
1135 (** [const network] turns a read/write network handle into a read-only
1136 network handle. Note that the opposite operation is impossible.
1139 (** Module dealing with networks. [Network.t] is the
1142 (** {3 Storage pools} *)
1147 (** Storage pool handle. *)
1149 type pool_state = Inactive | Building | Running | Degraded
1150 (** State of the storage pool. *)
1152 type pool_build_flags = New | Repair | Resize
1153 (** Flags for creating a storage pool. *)
1155 type pool_delete_flags = Normal | Zeroed
1156 (** Flags for deleting a storage pool. *)
1159 state : pool_state; (** Pool state. *)
1160 capacity : int64; (** Logical size in bytes. *)
1161 allocation : int64; (** Currently allocated in bytes. *)
1162 available : int64; (** Remaining free space bytes. *)
1165 val lookup_by_name : 'a Connect.t -> string -> 'a t
1166 val lookup_by_uuid : 'a Connect.t -> uuid -> 'a t
1167 val lookup_by_uuid_string : 'a Connect.t -> string -> 'a t
1168 (** Look up a storage pool by name, UUID or UUID string. *)
1170 val create_xml : [>`W] Connect.t -> xml -> rw t
1171 (** Create a storage pool. *)
1172 val define_xml : [>`W] Connect.t -> xml -> rw t
1173 (** Define but don't activate a storage pool. *)
1174 val build : [>`W] t -> pool_build_flags -> unit
1175 (** Build a storage pool. *)
1176 val undefine : [>`W] t -> unit
1177 (** Undefine configuration of a storage pool. *)
1178 val create : [>`W] t -> unit
1179 (** Start up a defined (inactive) storage pool. *)
1180 val destroy : [>`W] t -> unit
1181 (** Destroy a storage pool. *)
1182 val delete : [>`W] t -> unit
1183 (** Delete a storage pool. *)
1184 val free : [>`R] t -> unit
1185 (** Free a storage pool object in memory.
1187 The storage pool object is automatically freed if it is garbage
1188 collected. This function just forces it to be freed right
1191 val refresh : [`R] t -> unit
1192 (** Refresh the list of volumes in the storage pool. *)
1194 val get_name : [`R] t -> string
1195 (** Name of the pool. *)
1196 val get_uuid : [`R] t -> uuid
1197 (** Get the UUID (as a packed byte array). *)
1198 val get_uuid_string : [`R] t -> string
1199 (** Get the UUID (as a printable string). *)
1200 val get_info : [`R] t -> pool_info
1201 (** Get information about the pool. *)
1202 val get_xml_desc : [`R] t -> xml
1203 (** Get the XML description. *)
1204 val get_autostart : [`R] t -> bool
1205 (** Get the autostart flag for the storage pool. *)
1206 val set_autostart : [>`W] t -> bool -> unit
1207 (** Set the autostart flag for the storage pool. *)
1209 val num_of_volumes : [`R] t -> int
1210 (** Returns the number of storage volumes within the storage pool. *)
1211 val list_volumes : [`R] t -> int -> string array
1212 (** Return list of storage volumes. *)
1214 external const : [>`R] t -> ro t = "%identity"
1215 (** [const conn] turns a read/write storage pool into a read-only
1216 pool. Note that the opposite operation is impossible.
1219 (** Module dealing with storage pools. *)
1221 (** {3 Storage volumes} *)
1226 (** Storage volume handle. *)
1228 type vol_type = File | Block
1229 (** Type of a storage volume. *)
1231 type vol_delete_flags = Normal | Zeroed
1232 (** Flags for deleting a storage volume. *)
1235 typ : vol_type; (** Type of storage volume. *)
1236 capacity : int64; (** Logical size in bytes. *)
1237 allocation : int64; (** Currently allocated in bytes. *)
1240 val lookup_by_name : 'a Pool.t -> string -> 'a t
1241 val lookup_by_key : 'a Connect.t -> string -> 'a t
1242 val lookup_by_path : 'a Connect.t -> string -> 'a t
1243 (** Look up a storage volume by name, key or path volume. *)
1245 val pool_of_volume : 'a t -> 'a Pool.t
1246 (** Get the storage pool containing this volume. *)
1248 val get_name : [`R] t -> string
1249 (** Name of the volume. *)
1250 val get_key : [`R] t -> string
1251 (** Key of the volume. *)
1252 val get_path : [`R] t -> string
1253 (** Path of the volume. *)
1254 val get_info : [`R] t -> vol_info
1255 (** Get information about the storage volume. *)
1256 val get_xml_desc : [`R] t -> xml
1257 (** Get the XML description. *)
1259 val create_xml : [>`W] Pool.t -> xml -> unit
1260 (** Create a storage volume. *)
1261 val delete : [>`W] t -> vol_delete_flags -> unit
1262 (** Delete a storage volume. *)
1263 val free : [>`R] t -> unit
1264 (** Free a storage volume object in memory.
1266 The storage volume object is automatically freed if it is garbage
1267 collected. This function just forces it to be freed right
1271 external const : [>`R] t -> ro t = "%identity"
1272 (** [const conn] turns a read/write storage volume into a read-only
1273 volume. Note that the opposite operation is impossible.
1276 (** Module dealing with storage volumes. *)
1283 (** Secret handle. *)
1285 type secret_usage_type =
1291 (** Usage type of a secret. *)
1293 val lookup_by_uuid : 'a Connect.t -> uuid -> 'a t
1294 (** Lookup a secret by UUID. This uses the packed byte array UUID. *)
1295 val lookup_by_uuid_string : 'a Connect.t -> string -> 'a t
1296 (** Lookup a secret by (string) UUID. *)
1297 val lookup_by_usage : 'a Connect.t -> secret_usage_type -> string -> 'a t
1298 (** Lookup a secret by usage type, and usage ID. *)
1300 val define_xml : [>`W] Connect.t -> xml -> rw t
1301 (** Define a secret. *)
1303 val get_uuid : [>`R] t -> uuid
1304 (** Get the UUID (as a packed byte array) of the secret. *)
1305 val get_uuid_string : [>`R] t -> string
1306 (** Get the UUID (as a printable string) of the secret. *)
1307 val get_usage_type : [>`R] t -> secret_usage_type
1308 (** Get the usage type of the secret. *)
1309 val get_usage_id : [>`R] t -> string
1310 (** Get the usage ID of the secret. *)
1311 val get_xml_desc : [>`R] t -> xml
1312 (** Get the XML description. *)
1314 val set_value : [>`W] t -> bytes -> unit
1315 (** Set a new value for the secret. *)
1316 val get_value : [>`R] t -> bytes
1317 (** Get the value of the secret. *)
1319 val undefine : [>`W] t -> unit
1320 (** Undefine a secret. *)
1322 val free : [>`R] t -> unit
1323 (** Free a secret object in memory.
1325 The secret object is automatically freed if it is garbage
1326 collected. This function just forces it to be freed right
1330 external const : [>`R] t -> ro t = "%identity"
1331 (** [const conn] turns a read/write secret into a read-only
1332 secret. Note that the opposite operation is impossible.
1335 (** Module dealing with secrets. *)
1337 (** {3 Error handling and exceptions} *)
1343 | VIR_ERR_INTERNAL_ERROR
1345 | VIR_ERR_NO_SUPPORT
1346 | VIR_ERR_UNKNOWN_HOST
1347 | VIR_ERR_NO_CONNECT
1348 | VIR_ERR_INVALID_CONN
1349 | VIR_ERR_INVALID_DOMAIN
1350 | VIR_ERR_INVALID_ARG
1351 | VIR_ERR_OPERATION_FAILED
1352 | VIR_ERR_GET_FAILED
1353 | VIR_ERR_POST_FAILED
1354 | VIR_ERR_HTTP_ERROR
1355 | VIR_ERR_SEXPR_SERIAL
1366 | VIR_ERR_NO_XENSTORE
1367 | VIR_ERR_DRIVER_FULL
1368 | VIR_ERR_CALL_FAILED
1371 | VIR_ERR_OPERATION_DENIED
1372 | VIR_ERR_OPEN_FAILED
1373 | VIR_ERR_READ_FAILED
1374 | VIR_ERR_PARSE_FAILED
1375 | VIR_ERR_CONF_SYNTAX
1376 | VIR_ERR_WRITE_FAILED
1377 | VIR_ERR_XML_DETAIL
1378 | VIR_ERR_INVALID_NETWORK
1379 | VIR_ERR_NETWORK_EXIST
1380 | VIR_ERR_SYSTEM_ERROR
1382 | VIR_ERR_GNUTLS_ERROR
1383 | VIR_WAR_NO_NETWORK
1385 | VIR_ERR_NO_NETWORK
1386 | VIR_ERR_INVALID_MAC
1387 | VIR_ERR_AUTH_FAILED
1388 | VIR_ERR_INVALID_STORAGE_POOL
1389 | VIR_ERR_INVALID_STORAGE_VOL
1390 | VIR_WAR_NO_STORAGE
1391 | VIR_ERR_NO_STORAGE_POOL
1392 | VIR_ERR_NO_STORAGE_VOL
1394 | VIR_ERR_INVALID_NODE_DEVICE
1395 | VIR_ERR_NO_NODE_DEVICE
1396 | VIR_ERR_NO_SECURITY_MODEL
1397 | VIR_ERR_OPERATION_INVALID
1398 | VIR_WAR_NO_INTERFACE
1399 | VIR_ERR_NO_INTERFACE
1400 | VIR_ERR_INVALID_INTERFACE
1401 | VIR_ERR_MULTIPLE_INTERFACES
1402 | VIR_WAR_NO_NWFILTER
1403 | VIR_ERR_INVALID_NWFILTER
1404 | VIR_ERR_NO_NWFILTER
1405 | VIR_ERR_BUILD_FIREWALL
1407 | VIR_ERR_INVALID_SECRET
1409 | VIR_ERR_CONFIG_UNSUPPORTED
1410 | VIR_ERR_OPERATION_TIMEOUT
1411 | VIR_ERR_MIGRATE_PERSIST_FAILED
1412 | VIR_ERR_HOOK_SCRIPT_FAILED
1413 | VIR_ERR_INVALID_DOMAIN_SNAPSHOT
1414 | VIR_ERR_NO_DOMAIN_SNAPSHOT
1415 | VIR_ERR_INVALID_STREAM
1416 | VIR_ERR_ARGUMENT_UNSUPPORTED
1417 | VIR_ERR_STORAGE_PROBE_FAILED
1418 | VIR_ERR_STORAGE_POOL_BUILT
1419 | VIR_ERR_SNAPSHOT_REVERT_RISKY
1420 | VIR_ERR_OPERATION_ABORTED
1421 | VIR_ERR_AUTH_CANCELLED
1422 | VIR_ERR_NO_DOMAIN_METADATA
1423 | VIR_ERR_MIGRATE_UNSAFE
1425 | VIR_ERR_BLOCK_COPY_ACTIVE
1426 | VIR_ERR_OPERATION_UNSUPPORTED
1428 | VIR_ERR_AGENT_UNRESPONSIVE
1429 | VIR_ERR_RESOURCE_BUSY
1430 | VIR_ERR_ACCESS_DENIED
1431 | VIR_ERR_DBUS_SERVICE
1432 | VIR_ERR_STORAGE_VOL_EXIST
1433 | VIR_ERR_CPU_INCOMPATIBLE
1434 | VIR_ERR_XML_INVALID_SCHEMA
1435 | VIR_ERR_MIGRATE_FINISH_OK
1436 | VIR_ERR_AUTH_UNAVAILABLE
1439 | VIR_ERR_AGENT_UNSYNCED
1441 | VIR_ERR_DEVICE_MISSING
1442 | VIR_ERR_INVALID_NWFILTER_BINDING
1443 | VIR_ERR_NO_NWFILTER_BINDING
1444 (* ^^ NB: If you add a variant you MUST edit
1445 libvirt_c_epilogue.c:MAX_VIR_* *)
1446 | VIR_ERR_UNKNOWN of int
1447 (** See [<libvirt/virterror.h>] for meaning of these codes. *)
1449 val string_of_code : code -> string
1468 | VIR_FROM_STATS_LINUX
1475 | VIR_FROM_XEN_INOTIFY
1478 | VIR_FROM_INTERFACE
1487 | VIR_FROM_DOMAIN_SNAPSHOT
1496 | VIR_FROM_CAPABILITIES
1500 | VIR_FROM_PARALLELS
1503 | VIR_FROM_LOCKSPACE
1520 (* ^^ NB: If you add a variant you MUST edit
1521 libvirt_c_epilogue.c: MAX_VIR_* *)
1522 | VIR_FROM_UNKNOWN of int
1523 (** Subsystem / driver which produced the error. *)
1525 val string_of_domain : domain -> string
1531 (* ^^ NB: If you add a variant you MUST edit libvirt_c.c: MAX_VIR_* *)
1532 | VIR_ERR_UNKNOWN_LEVEL of int
1533 (** No error, a warning or an error. *)
1535 val string_of_level : level -> string
1538 code : code; (** Error code. *)
1539 domain : domain; (** Origin of the error. *)
1540 message : string option; (** Human-readable message. *)
1541 level : level; (** Error or warning. *)
1542 str1 : string option; (** Informational string. *)
1543 str2 : string option; (** Informational string. *)
1544 str3 : string option; (** Informational string. *)
1545 int1 : int32; (** Informational integer. *)
1546 int2 : int32; (** Informational integer. *)
1548 (** An error object. *)
1550 val to_string : t -> string
1551 (** Turn the exception into a printable string. *)
1553 val get_last_error : unit -> t option
1554 val get_last_conn_error : [>`R] Connect.t -> t option
1555 (** Get the last error at a global or connection level.
1557 Normally you do not need to use these functions because
1558 the library automatically turns errors into exceptions.
1561 val reset_last_error : unit -> unit
1562 val reset_last_conn_error : [>`R] Connect.t -> unit
1563 (** Reset the error at a global or connection level.
1565 Normally you do not need to use these functions.
1568 val no_error : unit -> t
1569 (** Creates an empty error message.
1571 Normally you do not need to use this function.
1574 (** Module dealing with errors. *)
1576 exception Virterror of Virterror.t
1577 (** This exception can be raised by any library function that detects
1578 an error. To get a printable error message, call
1579 {!Virterror.to_string} on the content of this exception.
1582 exception Not_supported of string
1585 [Not_supported "virFoo"]
1586 (where [virFoo] is the libvirt function name) if a function is
1587 not supported at either compile or run time. This applies to
1588 any libvirt function added after version 0.2.1.
1590 See also {{:http://libvirt.org/hvsupport.html}http://libvirt.org/hvsupport.html}
1593 (** {3 Utility functions} *)
1595 val map_ignore_errors : ('a -> 'b) -> 'a list -> 'b list
1596 (** [map_ignore_errors f xs] calls function [f] for each element of [xs].
1598 This is just like [List.map] except that if [f x] throws a
1599 {!Virterror.t} exception, the error is ignored and [f x]
1600 is not returned in the final list.
1602 This function is primarily useful when dealing with domains which
1603 might 'disappear' asynchronously from the currently running