[libvirt] [PATCH 00/20] Add support for (qcow*) volume encryption.

Hello, the following patches add full support for qcow/qcow2 volume encryption, assuming a client that supports it. (Main changes since the previous version: * Use a separate API for "secret" management * Auto-generate the encryption format and passphrase if not supplied See the specific patch change logs for more details; patches without change logs are entirely new.) New XML tags are defined to represent encryption parameters (currently format and passphrase, more can be added in the future), e.g. <encryption format='qcow'> <secret type='passphrase' secret_id='724d95f2-0ed2-6ff9-84d0-0f3d1618428d'/> </encryption> The <encryption> tag can be added to a <volume> node passed to virStorageVolCreateXML() to create an encrypted volume, or to a <disk> node inside a <domain> to specify what encryption parameters to use for a domain. secret_id above refers to a separately-managed secret, which was set using virSecretSetValue(). Other properties of the secret can be managed using an XML representation. Detailed documentation of the formats and features is inside the patches.

This patch adds a "secret" as a separately managed object, using a special-purpose API to transfer the secret values between nodes and libvirt users. Rather than add explicit accessors for attributes of secrets, and hard-code the "secrets are related to storage volumes" association in the API, the API uses XML to manipulate the association as well as other attributes, similarly to other areas of libvirt. The user can allocate an ID for the secret using virSecretAllocateID() (or use some other way to allocate secret IDs, e.g. reuse IDs used by the user in other databases), set attributes of the secret using XML, e.g. <secret ephemeral='no' private='yes'> <volume>/var/lib/libvirt/images/mail.img</volume> <description>LUKS passphrase for our mail server</description> </secret> The secret value can be either generated and stored by libvirt during volume creation, or supplied by the user using virSecretSetValue(). A simple API is provided for enumeration of all secrets. Very large deployments will manage secret IDs automatically, so it is probably not necessary to provide a specialized lookup function (allowing the volume key -> secret ID lookup in less than O(number of secrets)). These functions can eventually be added later. --- docs/format.html | 4 + docs/formatcaps.html | 4 + docs/formatdomain.html | 4 + docs/formatnetwork.html | 4 + docs/formatnode.html | 4 + docs/formatsecret.html | 166 ++++++++++++++++++++++++++++++++++++++++++ docs/formatsecret.html.in | 46 ++++++++++++ docs/formatstorage.html | 4 + docs/schemas/Makefile.am | 1 + docs/schemas/secret.rng | 39 ++++++++++ docs/sitemap.html | 3 + docs/sitemap.html.in | 4 + include/libvirt/libvirt.h | 24 ++++++ include/libvirt/libvirt.h.in | 24 ++++++ src/libvirt_public.syms | 8 ++ 15 files changed, 339 insertions(+), 0 deletions(-) create mode 100644 docs/formatsecret.html create mode 100644 docs/formatsecret.html.in create mode 100644 docs/schemas/secret.rng diff --git a/docs/format.html b/docs/format.html index e97d0e7..8aed8d3 100644 --- a/docs/format.html +++ b/docs/format.html @@ -70,6 +70,10 @@ <div> <a title="The host device XML format" class="inactive" href="formatnode.html">Node Devices</a> </div> + </li><li> + <div> + <a title="The secret attribute XML format" class="inactive" href="formatsecret.html">Secrets</a> + </div> </li></ul> </div> </li><li> diff --git a/docs/formatcaps.html b/docs/formatcaps.html index 5b20aac..8e2e5d1 100644 --- a/docs/formatcaps.html +++ b/docs/formatcaps.html @@ -70,6 +70,10 @@ <div> <a title="The host device XML format" class="inactive" href="formatnode.html">Node Devices</a> </div> + </li><li> + <div> + <a title="The secret attribute XML format" class="inactive" href="formatsecret.html">Secrets</a> + </div> </li></ul> </div> </li><li> diff --git a/docs/formatdomain.html b/docs/formatdomain.html index 5415200..bbce989 100644 --- a/docs/formatdomain.html +++ b/docs/formatdomain.html @@ -70,6 +70,10 @@ <div> <a title="The host device XML format" class="inactive" href="formatnode.html">Node Devices</a> </div> + </li><li> + <div> + <a title="The secret attribute XML format" class="inactive" href="formatsecret.html">Secrets</a> + </div> </li></ul> </div> </li><li> diff --git a/docs/formatnetwork.html b/docs/formatnetwork.html index 0b25a0b..6049492 100644 --- a/docs/formatnetwork.html +++ b/docs/formatnetwork.html @@ -70,6 +70,10 @@ <div> <a title="The host device XML format" class="inactive" href="formatnode.html">Node Devices</a> </div> + </li><li> + <div> + <a title="The secret attribute XML format" class="inactive" href="formatsecret.html">Secrets</a> + </div> </li></ul> </div> </li><li> diff --git a/docs/formatnode.html b/docs/formatnode.html index 4d30b0c..cca75ff 100644 --- a/docs/formatnode.html +++ b/docs/formatnode.html @@ -70,6 +70,10 @@ <div> <span class="active">Node Devices</span> </div> + </li><li> + <div> + <a title="The secret attribute XML format" class="inactive" href="formatsecret.html">Secrets</a> + </div> </li></ul> </div> </li><li> diff --git a/docs/formatsecret.html b/docs/formatsecret.html new file mode 100644 index 0000000..8c6e0c6 --- /dev/null +++ b/docs/formatsecret.html @@ -0,0 +1,166 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- + This file is autogenerated from formatsecret.html.in + Do not edit this file. Changes will be lost. + --> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> + <link rel="stylesheet" type="text/css" href="main.css" /> + <link rel="SHORTCUT ICON" href="32favicon.png" /> + <title>libvirt: Secret attributes XML format</title> + <meta name="description" content="libvirt, virtualization, virtualization API" /> + </head> + <body> + <div id="header"> + <div id="headerLogo"></div> + <div id="headerSearch"> + <form action="search.php" enctype="application/x-www-form-urlencoded" method="get"><div> + <input id="query" name="query" type="text" size="12" value="" /> + <input id="submit" name="submit" type="submit" value="Search" /> + </div></form> + </div> + </div> + <div id="body"> + <div id="menu"> + <ul class="l0"><li> + <div> + <a title="Front page of the libvirt website" class="inactive" href="index.html">Home</a> + </div> + </li><li> + <div> + <a title="Details of new features and bugs fixed in each release" class="inactive" href="news.html">News</a> + </div> + </li><li> + <div> + <a title="Get the latest source releases, binary builds and get access to the source repository" class="inactive" href="downloads.html">Downloads</a> + </div> + </li><li> + <div> + <a title="Information for users, administrators and developers" class="active" href="docs.html">Documentation</a> + <ul class="l1"><li> + <div> + <a title="Information about deploying and using libvirt" class="inactive" href="deployment.html">Deployment</a> + </div> + </li><li> + <div> + <a title="Overview of the logical subsystems in the libvirt API" class="inactive" href="intro.html">Architecture</a> + </div> + </li><li> + <div> + <a title="Description of the XML formats used in libvirt" class="active" href="format.html">XML format</a> + <ul class="l2"><li> + <div> + <a title="The domain XML format" class="inactive" href="formatdomain.html">Domains</a> + </div> + </li><li> + <div> + <a title="The virtual network XML format" class="inactive" href="formatnetwork.html">Networks</a> + </div> + </li><li> + <div> + <a title="The storage pool and volume XML format" class="inactive" href="formatstorage.html">Storage</a> + </div> + </li><li> + <div> + <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> + </div> + </li><li> + <div> + <a title="The host device XML format" class="inactive" href="formatnode.html">Node Devices</a> + </div> + </li><li> + <div> + <span class="active">Secrets</span> + </div> + </li></ul> + </div> + </li><li> + <div> + <a title="Hypervisor specific driver information" class="inactive" href="drivers.html">Drivers</a> + </div> + </li><li> + <div> + <a title="Reference manual for the C public API" class="inactive" href="html/index.html">API reference</a> + </div> + </li><li> + <div> + <a title="Bindings of the libvirt API for other languages" class="inactive" href="bindings.html">Language bindings</a> + </div> + </li><li> + <div> + <a title="Working on the internals of libvirt API, driver and daemon code" class="inactive" href="internals.html">Internals</a> + </div> + </li></ul> + </div> + </li><li> + <div> + <a title="User contributed content" class="inactive" href="http://wiki.libvirt.org">Wiki</a> + </div> + </li><li> + <div> + <a title="Frequently asked questions" class="inactive" href="FAQ.html">FAQ</a> + </div> + </li><li> + <div> + <a title="How and where to report bugs and request features" class="inactive" href="bugs.html">Bug reports</a> + </div> + </li><li> + <div> + <a title="How to contact the developers via email and IRC" class="inactive" href="contact.html">Contact</a> + </div> + </li><li> + <div> + <a title="Miscellaneous links of interest related to libvirt" class="inactive" href="relatedlinks.html">Related Links</a> + </div> + </li><li> + <div> + <a title="Overview of all content on the website" class="inactive" href="sitemap.html">Sitemap</a> + </div> + </li></ul> + </div> + <div id="content"> + <h1>Secret attributes XML format</h1> + <ul><li> + <a href="#SecretAttributes">Secret attributes XML</a> + </li><li> + <a href="#example">Example</a> + </li></ul> + <h2> + <a name="SecretAttributes" id="SecretAttributes">Secret attributes XML</a> + </h2> + <p> + Secrets stored by libvirt may have attributes associated with them, using + the <code>secret</code> element. The <code>secret</code> element has two + optional attributes, each with values '<code>yes</code>' and + '<code>no</code>', and defaulting to '<code>no</code>': + </p> + <dl><dt><code>ephemeral</code></dt><dd>This secret must only be kept in memory, never stored persistently. + </dd><dt><code>private</code></dt><dd>The value of the secret must not be revealed to any caller of libvirt, + nor to any other node. + </dd></dl> + <p> + The top-level <code>secret</code> element may contain the following + elements: + </p> + <dl><dt><code>volume</code></dt><dd>Key of a volume this secret is associated with. It is safe to delete + the secret after the volume is deleted. + </dd><dt><code>description</code></dt><dd>A human-readable description of the purpose of the secret. + </dd></dl> + <h2> + <a name="example" id="example">Example</a> + </h2> + <pre> + <secret ephemeral='no' private='yes'> + <volume>/var/lib/libvirt/images/mail.img</volume> + <description>LUKS passphrase for the main hard drive of our mail server</description> + </secret></pre> + </div> + </div> + <div id="footer"> + <p id="sponsor"> + Sponsored by:<br /><a href="http://et.redhat.com/"><img src="et.png" alt="Project sponsored by Red Hat Emerging Technology" /></a></p> + </div> + </body> +</html> diff --git a/docs/formatsecret.html.in b/docs/formatsecret.html.in new file mode 100644 index 0000000..0960d86 --- /dev/null +++ b/docs/formatsecret.html.in @@ -0,0 +1,46 @@ +<html> + <body> + <h1>Secret attributes XML format</h1> + + <ul id="toc"></ul> + + <h2><a name="SecretAttributes">Secret attributes XML</a></h2> + + <p> + Secrets stored by libvirt may have attributes associated with them, using + the <code>secret</code> element. The <code>secret</code> element has two + optional attributes, each with values '<code>yes</code>' and + '<code>no</code>', and defaulting to '<code>no</code>': + </p> + <dl> + <dt><code>ephemeral</code></dt> + <dd>This secret must only be kept in memory, never stored persistently. + </dd> + <dt><code>private</code></dt> + <dd>The value of the secret must not be revealed to any caller of libvirt, + nor to any other node. + </dd> + </dl> + <p> + The top-level <code>secret</code> element may contain the following + elements: + </p> + <dl> + <dt><code>volume</code></dt> + <dd>Key of a volume this secret is associated with. It is safe to delete + the secret after the volume is deleted. + </dd> + <dt><code>description</code></dt> + <dd>A human-readable description of the purpose of the secret. + </dd> + </dl> + + <h2><a name="example">Example</a></h2> + + <pre> + <secret ephemeral='no' private='yes'> + <volume>/var/lib/libvirt/images/mail.img</volume> + <description>LUKS passphrase for the main hard drive of our mail server</description> + </secret></pre> + </body> +</html> diff --git a/docs/formatstorage.html b/docs/formatstorage.html index 91e63b4..e21e3d2 100644 --- a/docs/formatstorage.html +++ b/docs/formatstorage.html @@ -70,6 +70,10 @@ <div> <a title="The host device XML format" class="inactive" href="formatnode.html">Node Devices</a> </div> + </li><li> + <div> + <a title="The secret attribute XML format" class="inactive" href="formatsecret.html">Secrets</a> + </div> </li></ul> </div> </li><li> diff --git a/docs/schemas/Makefile.am b/docs/schemas/Makefile.am index ef41a63..a064518 100644 --- a/docs/schemas/Makefile.am +++ b/docs/schemas/Makefile.am @@ -5,6 +5,7 @@ schema_DATA = \ domain.rng \ interface.rng \ network.rng \ + secret.rng \ storagepool.rng \ storagevol.rng \ nodedev.rng \ diff --git a/docs/schemas/secret.rng b/docs/schemas/secret.rng new file mode 100644 index 0000000..3d70412 --- /dev/null +++ b/docs/schemas/secret.rng @@ -0,0 +1,39 @@ +<!-- A Relax NG schema for the libvirt secret properties XML format --> +<grammar xmlns="http://relaxng.org/ns/structure/1.0"> + <start> + <ref name='secret'/> + </start> + + <define name='secret'> + <element name='secret'> + <optional> + <attribute name='ephemeral'> + <choice> + <value>yes</value> + <value>no</value> + </choice> + </attribute> + </optional> + <optional> + <attribute name='private'> + <choice> + <value>yes</value> + <value>no</value> + </choice> + </attribute> + </optional> + <interleave> + <optional> + <element name='description'> + <text/> + </element> + </optional> + <optional> + <element name='volume'> + <text/> + </element> + </optional> + </interleave> + </element> + </define> +</grammar> diff --git a/docs/sitemap.html b/docs/sitemap.html index f79a533..cf43088 100644 --- a/docs/sitemap.html +++ b/docs/sitemap.html @@ -141,6 +141,9 @@ </li><li> <a href="formatnode.html">Node Devices</a> <span>The host device XML format</span> + </li><li> + <a href="formatsecret.html">Secrets</a> + <span>The secret attribute XML format</span> </li></ul></li><li> <a href="drivers.html">Drivers</a> <span>Hypervisor specific driver information</span> diff --git a/docs/sitemap.html.in b/docs/sitemap.html.in index 9589878..4c4dfa4 100644 --- a/docs/sitemap.html.in +++ b/docs/sitemap.html.in @@ -106,6 +106,10 @@ <a href="formatnode.html">Node Devices</a> <span>The host device XML format</span> </li> + <li> + <a href="formatsecret.html">Secrets</a> + <span>The secret attribute XML format</span> + </li> </ul> </li> <li> diff --git a/include/libvirt/libvirt.h b/include/libvirt/libvirt.h index 86f56e5..eca9816 100644 --- a/include/libvirt/libvirt.h +++ b/include/libvirt/libvirt.h @@ -1448,6 +1448,30 @@ void virEventRegisterImpl(virEventAddHandleFunc addHandle, virEventAddTimeoutFunc addTimeout, virEventUpdateTimeoutFunc updateTimeout, virEventRemoveTimeoutFunc removeTimeout); + +/* + * Secret manipulation API + */ +char * virSecretAllocateID (virConnectPtr conn); +int virSecretSetXML (virConnectPtr conn, + const char *secret_id, + const char *xml); +char * virSecretGetXML (virConnectPtr conn, + const char *secret_id); +int virSecretSetValue (virConnectPtr conn, + const char *secret_id, + const void *secret, + size_t secret_size); +void * virSecretGetValue (virConnectPtr conn, + const char *secret_id, + size_t *secret_size); +int virSecretDelete (virConnectPtr conn, + const char *secret_id); +int virSecretNumOfSecrets (virConnectPtr conn); +int virSecretListSecrets (virConnectPtr conn, + char **ids, + int maxids); + #ifdef __cplusplus } #endif diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index e6536c7..093c89e 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1448,6 +1448,30 @@ void virEventRegisterImpl(virEventAddHandleFunc addHandle, virEventAddTimeoutFunc addTimeout, virEventUpdateTimeoutFunc updateTimeout, virEventRemoveTimeoutFunc removeTimeout); + +/* + * Secret manipulation API + */ +char * virSecretAllocateID (virConnectPtr conn); +int virSecretSetXML (virConnectPtr conn, + const char *secret_id, + const char *xml); +char * virSecretGetXML (virConnectPtr conn, + const char *secret_id); +int virSecretSetValue (virConnectPtr conn, + const char *secret_id, + const void *secret, + size_t secret_size); +void * virSecretGetValue (virConnectPtr conn, + const char *secret_id, + size_t *secret_size); +int virSecretDelete (virConnectPtr conn, + const char *secret_id); +int virSecretNumOfSecrets (virConnectPtr conn); +int virSecretListSecrets (virConnectPtr conn, + char **ids, + int maxids); + #ifdef __cplusplus } #endif diff --git a/src/libvirt_public.syms b/src/libvirt_public.syms index c06f51e..fc21082 100644 --- a/src/libvirt_public.syms +++ b/src/libvirt_public.syms @@ -289,6 +289,14 @@ LIBVIRT_0.7.0 { global: virConnectNumOfDefinedInterfaces; virConnectListDefinedInterfaces; + virSecretAllocateID; + virSecretSetXML; + virSecretGetXML; + virSecretSetValue; + virSecretGetValue; + virSecretDelete; + virSecretNumOfSecrets; + virSecretListSecrets; } LIBVIRT_0.6.4; # .... define new API here using predicted next version number .... -- 1.6.2.5

On Tue, Aug 04, 2009 at 10:28:16PM +0200, Miloslav Trma?? wrote:
This patch adds a "secret" as a separately managed object, using a special-purpose API to transfer the secret values between nodes and libvirt users.
Rather than add explicit accessors for attributes of secrets, and hard-code the "secrets are related to storage volumes" association in the API, the API uses XML to manipulate the association as well as other attributes, similarly to other areas of libvirt.
The user can allocate an ID for the secret using virSecretAllocateID() (or use some other way to allocate secret IDs, e.g. reuse IDs used by the user in other databases), set attributes of the secret using XML, e.g. <secret ephemeral='no' private='yes'> <volume>/var/lib/libvirt/images/mail.img</volume> <description>LUKS passphrase for our mail server</description> </secret> The secret value can be either generated and stored by libvirt during volume creation, or supplied by the user using virSecretSetValue().
A simple API is provided for enumeration of all secrets. Very large deployments will manage secret IDs automatically, so it is probably not necessary to provide a specialized lookup function (allowing the volume key -> secret ID lookup in less than O(number of secrets)). These functions can eventually be added later.
diff --git a/include/libvirt/libvirt.h.in b/include/libvirt/libvirt.h.in index e6536c7..093c89e 100644 --- a/include/libvirt/libvirt.h.in +++ b/include/libvirt/libvirt.h.in @@ -1448,6 +1448,30 @@ void virEventRegisterImpl(virEventAddHandleFunc addHandle, virEventAddTimeoutFunc addTimeout, virEventUpdateTimeoutFunc updateTimeout, virEventRemoveTimeoutFunc removeTimeout); + +/* + * Secret manipulation API + */ +char * virSecretAllocateID (virConnectPtr conn); +int virSecretSetXML (virConnectPtr conn, + const char *secret_id, + const char *xml); +char * virSecretGetXML (virConnectPtr conn, + const char *secret_id); +int virSecretSetValue (virConnectPtr conn, + const char *secret_id, + const void *secret, + size_t secret_size); +void * virSecretGetValue (virConnectPtr conn, + const char *secret_id, + size_t *secret_size); +int virSecretDelete (virConnectPtr conn, + const char *secret_id); +int virSecretNumOfSecrets (virConnectPtr conn); +int virSecretListSecrets (virConnectPtr conn, + char **ids, + int maxids); +
This looks like a reasonable set of operations to start with, just have a couple of minor tweaks to suggest. - Instead of using "const char *secret_id" as the entity to pass around the APIs, introduce a opaque struct type. eg in libvirt.h.in typedef struct _virSecret virSecret; typedef virSecret *virSecretPtr; and internally in datatypes.h, have that struct be struct _virSecret { unsigned int magic; /* specific value to check */ int refs; /* reference count */ virConnectPtr conn; /* pointer back to the connection */ unsigned char uuid[VIR_UUID_BUFLEN]; /* the unique secret identifier */ }; this just gives us a little more flexibility in the API for dealing with the unexpected in the future, and follows the paradigm of the other APIs. - Rename virSecretSetXML() to virSecretDefineXML() and rename virSecretDelete() to virSecretUndefine() Again this is simply for consistency with API naming scheme used by other objects in libvirt. virSecretAllocateID() would then be unneccessary, since virSecretDefineXML would simply return an instance of the virSecretPtr object. We would probably want a virSecretGetUUID() method to retrieve the id for an object, and a virSecretLookupByID() method to fetch an existing secret based off its identifier - that would allow O(1) lookup from the ID in a volume XML doc as you suggested. In the SetValue/GetValue fields you have a const void *secret size_t secret_size This implies an arbitrary data type being passed in or out. I'm guessing that you're really meaning a opaque byte array, in which case I think it would be preferrable to use 'unsigned char *' for the data instead of 'void *' Regards, Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

Adds a new driver type. --- include/libvirt/virterror.h | 2 + src/datatypes.h | 1 + src/driver.h | 61 +++++++++++++++++++++++++++++++++++++++++++ src/libvirt.c | 55 ++++++++++++++++++++++++++++++++++++++ src/virterror.c | 9 ++++++ 5 files changed, 128 insertions(+), 0 deletions(-) diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index e4d013f..64e0143 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -67,6 +67,7 @@ typedef enum { VIR_FROM_ONE, /* Error from OpenNebula driver */ VIR_FROM_ESX, /* Error from ESX driver */ VIR_FROM_PHYP, /* Error from IBM power hypervisor */ + VIR_FROM_SECRET, /* Error from secret storage */ } virErrorDomain; @@ -166,6 +167,7 @@ typedef enum { VIR_ERR_NO_INTERFACE, /* interface driver not running */ VIR_ERR_INVALID_INTERFACE, /* invalid interface object */ VIR_ERR_MULTIPLE_INTERFACES, /* more than one matching interface found */ + VIR_WAR_NO_SECRET, /* failed to start secret storage */ } virErrorNumber; /** diff --git a/src/datatypes.h b/src/datatypes.h index da83e02..58a6d32 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -119,6 +119,7 @@ struct _virConnect { virInterfaceDriverPtr interfaceDriver; virStorageDriverPtr storageDriver; virDeviceMonitorPtr deviceMonitor; + virSecretDriverPtr secretDriver; /* Private data pointer which can be used by driver and * network driver as they wish. diff --git a/src/driver.h b/src/driver.h index 79d46ff..e411212 100644 --- a/src/driver.h +++ b/src/driver.h @@ -6,6 +6,9 @@ #ifndef __VIR_DRIVER_H__ #define __VIR_DRIVER_H__ +#include "config.h" +#include <stdbool.h> + #include <libxml/uri.h> #include "internal.h" @@ -799,6 +802,63 @@ struct _virDeviceMonitor { virDrvNodeDeviceDestroy deviceDestroy; }; +typedef char * + (*virDrvSecretAllocateID) (virConnectPtr conn); +typedef int + (*virDrvSecretSetXML) (virConnectPtr conn, + const char *secret_id, + const char *xml); +typedef char * + (*virDrvSecretGetXML) (virConnectPtr conn, + const char *secret_id); +typedef int + (*virDrvSecretSetValue) (virConnectPtr conn, + const char *secret_id, + const void *secret, + size_t secret_size); +typedef void * + (*virDrvSecretGetValue) (virConnectPtr conn, + const char *secret_id, + size_t *secret_size, + bool libvirt_internal_call); +typedef int + (*virDrvSecretDelete) (virConnectPtr conn, + const char *secret_id); +typedef int + (*virDrvSecretNumOfSecrets) (virConnectPtr conn); +typedef int + (*virDrvSecretListSecrets) (virConnectPtr conn, + char **ids, + int maxids); + +typedef struct _virSecretDriver virSecretDriver; +typedef virSecretDriver *virSecretDriverPtr; + +/** + * _virSecretDriver: + * + * Structure associated to a driver for storing secrets, defining the various + * entry points for it. + * + * All drivers must support the following fields/methods: + * - open + * - close + */ +struct _virSecretDriver { + const char *name; + virDrvOpen open; + virDrvClose close; + + virDrvSecretAllocateID allocateID; + virDrvSecretSetXML setXML; + virDrvSecretGetXML getXML; + virDrvSecretSetValue setValue; + virDrvSecretGetValue getValue; + virDrvSecretDelete delete; + virDrvSecretNumOfSecrets numOfSecrets; + virDrvSecretListSecrets listSecrets; +}; + /* * Registration * TODO: also need ways to (des)activate a given driver @@ -809,6 +869,7 @@ int virRegisterNetworkDriver(virNetworkDriverPtr); int virRegisterInterfaceDriver(virInterfaceDriverPtr); int virRegisterStorageDriver(virStorageDriverPtr); int virRegisterDeviceMonitor(virDeviceMonitorPtr); +int virRegisterSecretDriver(virSecretDriverPtr); #ifdef WITH_LIBVIRTD int virRegisterStateDriver(virStateDriverPtr); #endif diff --git a/src/libvirt.c b/src/libvirt.c index 889f77f..22bc34c 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -86,6 +86,8 @@ static virStorageDriverPtr virStorageDriverTab[MAX_DRIVERS]; static int virStorageDriverTabCount = 0; static virDeviceMonitorPtr virDeviceMonitorTab[MAX_DRIVERS]; static int virDeviceMonitorTabCount = 0; +static virSecretDriverPtr virSecretDriverTab[MAX_DRIVERS]; +static int virSecretDriverTabCount = 0; #ifdef WITH_LIBVIRTD static virStateDriverPtr virStateDriverTab[MAX_DRIVERS]; static int virStateDriverTabCount = 0; @@ -701,6 +703,37 @@ virRegisterDeviceMonitor(virDeviceMonitorPtr driver) } /** + * virRegisterSecretDriver: + * @driver: pointer to a secret driver block + * + * Register a secret driver + * + * Returns the driver priority or -1 in case of error. + */ +int +virRegisterSecretDriver(virSecretDriverPtr driver) +{ + if (virInitialize() < 0) + return -1; + + if (driver == NULL) { + virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); + return(-1); + } + + if (virSecretDriverTabCount >= MAX_DRIVERS) { + virLibConnError(NULL, VIR_ERR_INVALID_ARG, __FUNCTION__); + return(-1); + } + + DEBUG ("registering %s as secret driver %d", + driver->name, virSecretDriverTabCount); + + virSecretDriverTab[virSecretDriverTabCount] = driver; + return virSecretDriverTabCount++; +} + +/** * virRegisterDriver: * @driver: pointer to a driver block * @@ -1113,6 +1146,26 @@ do_open (const char *name, } } + /* Secret manipulation driver. Optional */ + for (i = 0; i < virSecretDriverTabCount; i++) { + res = virSecretDriverTab[i]->open (ret, auth, flags); + DEBUG("secret driver %d %s returned %s", + i, virSecretDriverTab[i]->name, + res == VIR_DRV_OPEN_SUCCESS ? "SUCCESS" : + (res == VIR_DRV_OPEN_DECLINED ? "DECLINED" : + (res == VIR_DRV_OPEN_ERROR ? "ERROR" : "unknown status"))); + if (res == VIR_DRV_OPEN_ERROR) { + if (STREQ(virSecretDriverTab[i]->name, "remote")) { + virLibConnWarning (NULL, VIR_WAR_NO_SECRET, + "Is the daemon running ?"); + } + break; + } else if (res == VIR_DRV_OPEN_SUCCESS) { + ret->secretDriver = virSecretDriverTab[i]; + break; + } + } + return ret; failed: @@ -1246,6 +1299,8 @@ virConnectClose(virConnectPtr conn) conn->storageDriver->close (conn); if (conn->deviceMonitor) conn->deviceMonitor->close (conn); + if (conn->secretDriver) + conn->secretDriver->close (conn); conn->driver->close (conn); if (virUnrefConnect(conn) < 0) diff --git a/src/virterror.c b/src/virterror.c index 362d8ef..ba66238 100644 --- a/src/virterror.c +++ b/src/virterror.c @@ -169,6 +169,9 @@ static const char *virErrorDomainName(virErrorDomain domain) { case VIR_FROM_ESX: dom = "ESX "; break; + case VIR_FROM_SECRET: + dom = "Secret Storage "; + break; } return(dom); } @@ -1068,6 +1071,12 @@ virErrorMsg(virErrorNumber error, const char *info) else errmsg = _("multiple matching interfaces found: %s"); break; + case VIR_WAR_NO_SECRET: + if (info == NULL) + errmsg = _("Failed to find a secret storage driver"); + else + errmsg = _("Failed to find a secret storage driver: %s"); + break; } return (errmsg); } -- 1.6.2.5

--- src/libvirt.c | 365 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 365 insertions(+), 0 deletions(-) diff --git a/src/libvirt.c b/src/libvirt.c index 22bc34c..4beb822 100644 --- a/src/libvirt.c +++ b/src/libvirt.c @@ -8660,3 +8660,368 @@ error: virSetConnError(conn); return -1; } + +/** + * virSecretAllocateID: + * @conn: virConnect connection + * + * Allocates a secret ID (a printable string) without associating a secret + * value with the ID. + * + * Returns the secret ID on success, or NULL on failure. The caller must + * free() the secret ID. + */ +char * +virSecretAllocateID(virConnectPtr conn) +{ + VIR_DEBUG("conn=%p", conn); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return NULL; + } + if (conn->flags & VIR_CONNECT_RO) { + virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + + if (conn->secretDriver != NULL && conn->secretDriver->allocateID != NULL) { + char *ret; + + ret = conn->secretDriver->allocateID(conn); + if (ret == NULL) + goto error; + return ret; + } + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(conn); + return NULL; +} + +/** + * virSecretSetXML: + * @conn: virConnect connection + * @secret_id: A secret ID + * @xml: XML containing attributes of the secret. + * + * Replaces all attributes of the secret specified by secret_id by attributes + * specified in xml (any attributes not specified in xml are + * discarded). Allocates secret_id if it was not previously allocated. + * + * Returns 0 on success, -1 on failure. + */ +int +virSecretSetXML(virConnectPtr conn, const char *secret_id, const char *xml) +{ + VIR_DEBUG("conn=%p, secret_id=%s, xml=%s", conn, secret_id, xml); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return -1; + } + if (conn->flags & VIR_CONNECT_RO) { + virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + if (secret_id == NULL || xml == NULL) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + if (conn->secretDriver != NULL && conn->secretDriver->setXML != NULL) { + int ret; + + ret = conn->secretDriver->setXML(conn, secret_id, xml); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(conn); + return -1; +} + +/** + * virSecretGetXML: + * @conn: virConnect connection + * @secret_id: A secret ID + * + * Fetches an XML document describing attributes of the secret. + * + * Returns the XML document on success, NULL on failure. The caller must + * free() the XML. + */ +char * +virSecretGetXML(virConnectPtr conn, const char *secret_id) +{ + VIR_DEBUG("conn=%p, secret_id=%s", conn, secret_id); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return NULL; + } + if (secret_id == NULL) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + if (conn->secretDriver != NULL && conn->secretDriver->getXML != NULL) { + char *ret; + + ret = conn->secretDriver->getXML(conn, secret_id); + if (ret == NULL) + goto error; + return ret; + } + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(conn); + return NULL; +} + +/** + * virSecretSetValue: + * @conn: virConnect connection + * @secret_id: A secret ID + * @secret: The secret + * @secret_size: Size of the secret + * + * Associates a secret value with secret_id. Allocates secret_id if it was + * not previously allocated. + * + * Returns 0 on success, -1 on failure. + */ +int +virSecretSetValue(virConnectPtr conn, const char *secret_id, const void *secret, + size_t secret_size) +{ + VIR_DEBUG("conn=%p, secret_id=%s, secret=%p, secret_size=%zu", conn, + secret_id, secret, secret_size); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return -1; + } + if (conn->flags & VIR_CONNECT_RO) { + virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + if (secret_id == NULL || secret == NULL) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + if (conn->secretDriver != NULL && conn->secretDriver->setValue != NULL) { + int ret; + + ret = conn->secretDriver->setValue(conn, secret_id, secret, + secret_size); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(conn); + return -1; +} + +/** + * virSecretGetValue: + * @conn: virConnect connection + * @secret_id: A secret ID + * @secret_size: Place for storing size of the secret + * + * Fetches the secret value associated with secret_id. + * + * Returns the secret value on success, NULL on failure. The caller must + * free() the secret value. + */ +void * +virSecretGetValue(virConnectPtr conn, const char *secret_id, + size_t *secret_size) +{ + VIR_DEBUG("conn=%p, secret_id=%s, secret_size=%p", conn, secret_id, + secret_size); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return NULL; + } + if (conn->flags & VIR_CONNECT_RO) { + virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + if (secret_id == NULL || secret_size == NULL) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + if (conn->secretDriver != NULL && conn->secretDriver->getValue != NULL) { + void *ret; + + ret = conn->secretDriver->getValue(conn, secret_id, secret_size, false); + if (ret == NULL) + goto error; + return ret; + } + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(conn); + return NULL; +} + +/** + * virSecretDelete: + * @conn: virConnect connection + * @secret_id: A secret ID + * + * Deletes the secret with secret_id (including the secret value and all + * attributes). + * + * Returns 0 on success, -1 on failure. + */ +int +virSecretDelete(virConnectPtr conn, const char *secret_id) +{ + VIR_DEBUG("conn=%p, secret_id=%s", conn, secret_id); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return -1; + } + if (conn->flags & VIR_CONNECT_RO) { + virLibConnError(conn, VIR_ERR_OPERATION_DENIED, __FUNCTION__); + goto error; + } + if (secret_id == NULL) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + if (conn->secretDriver != NULL && conn->secretDriver->delete != NULL) { + int ret; + + ret = conn->secretDriver->delete(conn, secret_id); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(conn); + return -1; +} + +/** + * virSecretNumOfSecrets: + * @conn: virConnect connection + * + * Fetch number of currently defined secret IDs. + * + * Returns the number currently defined secret IDs. + */ +int +virSecretNumOfSecrets(virConnectPtr conn) +{ + VIR_DEBUG("conn=%p", conn); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return -1; + } + + if (conn->secretDriver != NULL && + conn->secretDriver->numOfSecrets != NULL) { + int ret; + + ret = conn->secretDriver->numOfSecrets(conn); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(conn); + return -1; +} + +/** + * virSecretListSecrets: + * @conn: virConnect connection + * @ids: Pointer to an array to store the IDs + * @maxids: size of the array. + * + * List the defined secret IDs, store pointers to names in ids. + * + * Returns the number of IDs provided in the array, or -1 on failure. + */ +int +virSecretListSecrets(virConnectPtr conn, char **ids, int maxids) +{ + VIR_DEBUG("conn=%p, ids=%p, maxids=%d", conn, ids, maxids); + + virResetLastError(); + + if (!VIR_IS_CONNECT(conn)) { + virLibConnError(NULL, VIR_ERR_INVALID_CONN, __FUNCTION__); + return -1; + } + if (ids == NULL || maxids < 0) { + virLibConnError(conn, VIR_ERR_INVALID_ARG, __FUNCTION__); + goto error; + } + + if (conn->secretDriver != NULL && conn->secretDriver->listSecrets != NULL) { + int ret; + + ret = conn->secretDriver->listSecrets(conn, ids, maxids); + if (ret < 0) + goto error; + return ret; + } + + virLibConnError (conn, VIR_ERR_NO_SUPPORT, __FUNCTION__); + +error: + /* Copy to connection error object for back compatability */ + virSetConnError(conn); + return -1; +} -- 1.6.2.5

--- qemud/remote_dispatch_args.h | 6 ++ qemud/remote_dispatch_prototypes.h | 56 +++++++++++++++++++ qemud/remote_dispatch_ret.h | 5 ++ qemud/remote_dispatch_table.h | 40 +++++++++++++ qemud/remote_protocol.c | 107 ++++++++++++++++++++++++++++++++++++ qemud/remote_protocol.h | 98 +++++++++++++++++++++++++++++++++ qemud/remote_protocol.x | 67 ++++++++++++++++++++++- 7 files changed, 378 insertions(+), 1 deletions(-) diff --git a/qemud/remote_dispatch_args.h b/qemud/remote_dispatch_args.h index 9dacfb8..37d7f48 100644 --- a/qemud/remote_dispatch_args.h +++ b/qemud/remote_dispatch_args.h @@ -117,3 +117,9 @@ remote_domain_xml_from_native_args val_remote_domain_xml_from_native_args; remote_domain_xml_to_native_args val_remote_domain_xml_to_native_args; remote_list_defined_interfaces_args val_remote_list_defined_interfaces_args; + remote_secret_set_xml_args val_remote_secret_set_xml_args; + remote_secret_get_xml_args val_remote_secret_get_xml_args; + remote_secret_set_value_args val_remote_secret_set_value_args; + remote_secret_get_value_args val_remote_secret_get_value_args; + remote_secret_delete_args val_remote_secret_delete_args; + remote_secret_list_secrets_args val_remote_secret_list_secrets_args; diff --git a/qemud/remote_dispatch_prototypes.h b/qemud/remote_dispatch_prototypes.h index d9f6aad..dbb23ea 100644 --- a/qemud/remote_dispatch_prototypes.h +++ b/qemud/remote_dispatch_prototypes.h @@ -772,6 +772,62 @@ static int remoteDispatchOpen( remote_error *err, remote_open_args *args, void *ret); +static int remoteDispatchSecretAllocateId( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + void *args, + remote_secret_allocate_id_ret *ret); +static int remoteDispatchSecretDelete( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + remote_secret_delete_args *args, + void *ret); +static int remoteDispatchSecretGetValue( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + remote_secret_get_value_args *args, + remote_secret_get_value_ret *ret); +static int remoteDispatchSecretGetXml( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + remote_secret_get_xml_args *args, + remote_secret_get_xml_ret *ret); +static int remoteDispatchSecretListSecrets( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + remote_secret_list_secrets_args *args, + remote_secret_list_secrets_ret *ret); +static int remoteDispatchSecretNumOfSecrets( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + void *args, + remote_secret_num_of_secrets_ret *ret); +static int remoteDispatchSecretSetValue( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + remote_secret_set_value_args *args, + void *ret); +static int remoteDispatchSecretSetXml( + struct qemud_server *server, + struct qemud_client *client, + virConnectPtr conn, + remote_error *err, + remote_secret_set_xml_args *args, + void *ret); static int remoteDispatchStoragePoolBuild( struct qemud_server *server, struct qemud_client *client, diff --git a/qemud/remote_dispatch_ret.h b/qemud/remote_dispatch_ret.h index 5376960..d28f445 100644 --- a/qemud/remote_dispatch_ret.h +++ b/qemud/remote_dispatch_ret.h @@ -99,3 +99,8 @@ remote_domain_xml_to_native_ret val_remote_domain_xml_to_native_ret; remote_num_of_defined_interfaces_ret val_remote_num_of_defined_interfaces_ret; remote_list_defined_interfaces_ret val_remote_list_defined_interfaces_ret; + remote_secret_allocate_id_ret val_remote_secret_allocate_id_ret; + remote_secret_get_xml_ret val_remote_secret_get_xml_ret; + remote_secret_get_value_ret val_remote_secret_get_value_ret; + remote_secret_num_of_secrets_ret val_remote_secret_num_of_secrets_ret; + remote_secret_list_secrets_ret val_remote_secret_list_secrets_ret; diff --git a/qemud/remote_dispatch_table.h b/qemud/remote_dispatch_table.h index 449786d..aad9b41 100644 --- a/qemud/remote_dispatch_table.h +++ b/qemud/remote_dispatch_table.h @@ -697,3 +697,43 @@ .args_filter = (xdrproc_t) xdr_remote_list_defined_interfaces_args, .ret_filter = (xdrproc_t) xdr_remote_list_defined_interfaces_ret, }, +{ /* SecretAllocateId => 139 */ + .fn = (dispatch_fn) remoteDispatchSecretAllocateId, + .args_filter = (xdrproc_t) xdr_void, + .ret_filter = (xdrproc_t) xdr_remote_secret_allocate_id_ret, +}, +{ /* SecretSetXml => 140 */ + .fn = (dispatch_fn) remoteDispatchSecretSetXml, + .args_filter = (xdrproc_t) xdr_remote_secret_set_xml_args, + .ret_filter = (xdrproc_t) xdr_void, +}, +{ /* SecretGetXml => 141 */ + .fn = (dispatch_fn) remoteDispatchSecretGetXml, + .args_filter = (xdrproc_t) xdr_remote_secret_get_xml_args, + .ret_filter = (xdrproc_t) xdr_remote_secret_get_xml_ret, +}, +{ /* SecretSetValue => 142 */ + .fn = (dispatch_fn) remoteDispatchSecretSetValue, + .args_filter = (xdrproc_t) xdr_remote_secret_set_value_args, + .ret_filter = (xdrproc_t) xdr_void, +}, +{ /* SecretGetValue => 143 */ + .fn = (dispatch_fn) remoteDispatchSecretGetValue, + .args_filter = (xdrproc_t) xdr_remote_secret_get_value_args, + .ret_filter = (xdrproc_t) xdr_remote_secret_get_value_ret, +}, +{ /* SecretDelete => 144 */ + .fn = (dispatch_fn) remoteDispatchSecretDelete, + .args_filter = (xdrproc_t) xdr_remote_secret_delete_args, + .ret_filter = (xdrproc_t) xdr_void, +}, +{ /* SecretNumOfSecrets => 145 */ + .fn = (dispatch_fn) remoteDispatchSecretNumOfSecrets, + .args_filter = (xdrproc_t) xdr_void, + .ret_filter = (xdrproc_t) xdr_remote_secret_num_of_secrets_ret, +}, +{ /* SecretListSecrets => 146 */ + .fn = (dispatch_fn) remoteDispatchSecretListSecrets, + .args_filter = (xdrproc_t) xdr_remote_secret_list_secrets_args, + .ret_filter = (xdrproc_t) xdr_remote_secret_list_secrets_ret, +}, diff --git a/qemud/remote_protocol.c b/qemud/remote_protocol.c index 7b46096..519f4f2 100644 --- a/qemud/remote_protocol.c +++ b/qemud/remote_protocol.c @@ -2534,6 +2534,113 @@ xdr_remote_domain_xml_to_native_ret (XDR *xdrs, remote_domain_xml_to_native_ret } bool_t +xdr_remote_secret_allocate_id_ret (XDR *xdrs, remote_secret_allocate_id_ret *objp) +{ + + if (!xdr_remote_nonnull_string (xdrs, &objp->secretID)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_secret_set_xml_args (XDR *xdrs, remote_secret_set_xml_args *objp) +{ + + if (!xdr_remote_nonnull_string (xdrs, &objp->secretID)) + return FALSE; + if (!xdr_remote_nonnull_string (xdrs, &objp->xml)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_secret_get_xml_args (XDR *xdrs, remote_secret_get_xml_args *objp) +{ + + if (!xdr_remote_nonnull_string (xdrs, &objp->secretID)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_secret_get_xml_ret (XDR *xdrs, remote_secret_get_xml_ret *objp) +{ + + if (!xdr_remote_nonnull_string (xdrs, &objp->xml)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_secret_set_value_args (XDR *xdrs, remote_secret_set_value_args *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->value.value_val; + + if (!xdr_remote_nonnull_string (xdrs, &objp->secretID)) + return FALSE; + if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->value.value_len, REMOTE_SECRET_VALUE_MAX)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_secret_get_value_args (XDR *xdrs, remote_secret_get_value_args *objp) +{ + + if (!xdr_remote_nonnull_string (xdrs, &objp->secretID)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_secret_get_value_ret (XDR *xdrs, remote_secret_get_value_ret *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->value.value_val; + + if (!xdr_bytes (xdrs, objp_cpp0, (u_int *) &objp->value.value_len, REMOTE_SECRET_VALUE_MAX)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_secret_delete_args (XDR *xdrs, remote_secret_delete_args *objp) +{ + + if (!xdr_remote_nonnull_string (xdrs, &objp->secretID)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_secret_num_of_secrets_ret (XDR *xdrs, remote_secret_num_of_secrets_ret *objp) +{ + + if (!xdr_int (xdrs, &objp->num)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_secret_list_secrets_args (XDR *xdrs, remote_secret_list_secrets_args *objp) +{ + + if (!xdr_int (xdrs, &objp->maxids)) + return FALSE; + return TRUE; +} + +bool_t +xdr_remote_secret_list_secrets_ret (XDR *xdrs, remote_secret_list_secrets_ret *objp) +{ + char **objp_cpp0 = (char **) (void *) &objp->ids.ids_val; + + if (!xdr_array (xdrs, objp_cpp0, (u_int *) &objp->ids.ids_len, REMOTE_SECRET_ID_LIST_MAX, + sizeof (remote_nonnull_string), (xdrproc_t) xdr_remote_nonnull_string)) + return FALSE; + return TRUE; +} + +bool_t xdr_remote_procedure (XDR *xdrs, remote_procedure *objp) { diff --git a/qemud/remote_protocol.h b/qemud/remote_protocol.h index 2e5bc81..621a991 100644 --- a/qemud/remote_protocol.h +++ b/qemud/remote_protocol.h @@ -43,6 +43,8 @@ typedef remote_nonnull_string *remote_string; #define REMOTE_SECURITY_MODEL_MAX VIR_SECURITY_MODEL_BUFLEN #define REMOTE_SECURITY_LABEL_MAX VIR_SECURITY_LABEL_BUFLEN #define REMOTE_SECURITY_DOI_MAX VIR_SECURITY_DOI_BUFLEN +#define REMOTE_SECRET_VALUE_MAX 65536 +#define REMOTE_SECRET_ID_LIST_MAX 16384 typedef char remote_uuid[VIR_UUID_BUFLEN]; @@ -1427,6 +1429,72 @@ struct remote_domain_xml_to_native_ret { remote_nonnull_string nativeConfig; }; typedef struct remote_domain_xml_to_native_ret remote_domain_xml_to_native_ret; + +struct remote_secret_allocate_id_ret { + remote_nonnull_string secretID; +}; +typedef struct remote_secret_allocate_id_ret remote_secret_allocate_id_ret; + +struct remote_secret_set_xml_args { + remote_nonnull_string secretID; + remote_nonnull_string xml; +}; +typedef struct remote_secret_set_xml_args remote_secret_set_xml_args; + +struct remote_secret_get_xml_args { + remote_nonnull_string secretID; +}; +typedef struct remote_secret_get_xml_args remote_secret_get_xml_args; + +struct remote_secret_get_xml_ret { + remote_nonnull_string xml; +}; +typedef struct remote_secret_get_xml_ret remote_secret_get_xml_ret; + +struct remote_secret_set_value_args { + remote_nonnull_string secretID; + struct { + u_int value_len; + char *value_val; + } value; +}; +typedef struct remote_secret_set_value_args remote_secret_set_value_args; + +struct remote_secret_get_value_args { + remote_nonnull_string secretID; +}; +typedef struct remote_secret_get_value_args remote_secret_get_value_args; + +struct remote_secret_get_value_ret { + struct { + u_int value_len; + char *value_val; + } value; +}; +typedef struct remote_secret_get_value_ret remote_secret_get_value_ret; + +struct remote_secret_delete_args { + remote_nonnull_string secretID; +}; +typedef struct remote_secret_delete_args remote_secret_delete_args; + +struct remote_secret_num_of_secrets_ret { + int num; +}; +typedef struct remote_secret_num_of_secrets_ret remote_secret_num_of_secrets_ret; + +struct remote_secret_list_secrets_args { + int maxids; +}; +typedef struct remote_secret_list_secrets_args remote_secret_list_secrets_args; + +struct remote_secret_list_secrets_ret { + struct { + u_int ids_len; + remote_nonnull_string *ids_val; + } ids; +}; +typedef struct remote_secret_list_secrets_ret remote_secret_list_secrets_ret; #define REMOTE_PROGRAM 0x20008086 #define REMOTE_PROTOCOL_VERSION 1 @@ -1569,6 +1637,14 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_XML_TO_NATIVE = 136, REMOTE_PROC_NUM_OF_DEFINED_INTERFACES = 137, REMOTE_PROC_LIST_DEFINED_INTERFACES = 138, + REMOTE_PROC_SECRET_ALLOCATE_ID = 139, + REMOTE_PROC_SECRET_SET_XML = 140, + REMOTE_PROC_SECRET_GET_XML = 141, + REMOTE_PROC_SECRET_SET_VALUE = 142, + REMOTE_PROC_SECRET_GET_VALUE = 143, + REMOTE_PROC_SECRET_DELETE = 144, + REMOTE_PROC_SECRET_NUM_OF_SECRETS = 145, + REMOTE_PROC_SECRET_LIST_SECRETS = 146, }; typedef enum remote_procedure remote_procedure; @@ -1831,6 +1907,17 @@ extern bool_t xdr_remote_domain_xml_from_native_args (XDR *, remote_domain_xml_ extern bool_t xdr_remote_domain_xml_from_native_ret (XDR *, remote_domain_xml_from_native_ret*); extern bool_t xdr_remote_domain_xml_to_native_args (XDR *, remote_domain_xml_to_native_args*); extern bool_t xdr_remote_domain_xml_to_native_ret (XDR *, remote_domain_xml_to_native_ret*); +extern bool_t xdr_remote_secret_allocate_id_ret (XDR *, remote_secret_allocate_id_ret*); +extern bool_t xdr_remote_secret_set_xml_args (XDR *, remote_secret_set_xml_args*); +extern bool_t xdr_remote_secret_get_xml_args (XDR *, remote_secret_get_xml_args*); +extern bool_t xdr_remote_secret_get_xml_ret (XDR *, remote_secret_get_xml_ret*); +extern bool_t xdr_remote_secret_set_value_args (XDR *, remote_secret_set_value_args*); +extern bool_t xdr_remote_secret_get_value_args (XDR *, remote_secret_get_value_args*); +extern bool_t xdr_remote_secret_get_value_ret (XDR *, remote_secret_get_value_ret*); +extern bool_t xdr_remote_secret_delete_args (XDR *, remote_secret_delete_args*); +extern bool_t xdr_remote_secret_num_of_secrets_ret (XDR *, remote_secret_num_of_secrets_ret*); +extern bool_t xdr_remote_secret_list_secrets_args (XDR *, remote_secret_list_secrets_args*); +extern bool_t xdr_remote_secret_list_secrets_ret (XDR *, remote_secret_list_secrets_ret*); extern bool_t xdr_remote_procedure (XDR *, remote_procedure*); extern bool_t xdr_remote_message_type (XDR *, remote_message_type*); extern bool_t xdr_remote_message_status (XDR *, remote_message_status*); @@ -2069,6 +2156,17 @@ extern bool_t xdr_remote_domain_xml_from_native_args (); extern bool_t xdr_remote_domain_xml_from_native_ret (); extern bool_t xdr_remote_domain_xml_to_native_args (); extern bool_t xdr_remote_domain_xml_to_native_ret (); +extern bool_t xdr_remote_secret_allocate_id_ret (); +extern bool_t xdr_remote_secret_set_xml_args (); +extern bool_t xdr_remote_secret_get_xml_args (); +extern bool_t xdr_remote_secret_get_xml_ret (); +extern bool_t xdr_remote_secret_set_value_args (); +extern bool_t xdr_remote_secret_get_value_args (); +extern bool_t xdr_remote_secret_get_value_ret (); +extern bool_t xdr_remote_secret_delete_args (); +extern bool_t xdr_remote_secret_num_of_secrets_ret (); +extern bool_t xdr_remote_secret_list_secrets_args (); +extern bool_t xdr_remote_secret_list_secrets_ret (); extern bool_t xdr_remote_procedure (); extern bool_t xdr_remote_message_type (); extern bool_t xdr_remote_message_status (); diff --git a/qemud/remote_protocol.x b/qemud/remote_protocol.x index 8f9b6db..268a8b4 100644 --- a/qemud/remote_protocol.x +++ b/qemud/remote_protocol.x @@ -136,6 +136,16 @@ const REMOTE_SECURITY_LABEL_MAX = VIR_SECURITY_LABEL_BUFLEN; */ const REMOTE_SECURITY_DOI_MAX = VIR_SECURITY_DOI_BUFLEN; +/* + * Maximum size of a secret value. + */ +const REMOTE_SECRET_VALUE_MAX = 65536; + +/* + * Upper limit on list of secrets. + */ +const REMOTE_SECRET_ID_LIST_MAX = 16384; + /* UUID. VIR_UUID_BUFLEN definition comes from libvirt.h */ typedef opaque remote_uuid[VIR_UUID_BUFLEN]; @@ -1266,6 +1276,52 @@ struct remote_domain_xml_to_native_ret { }; +struct remote_secret_allocate_id_ret { + remote_nonnull_string secretID; +}; + +struct remote_secret_set_xml_args { + remote_nonnull_string secretID; + remote_nonnull_string xml; +}; + +struct remote_secret_get_xml_args { + remote_nonnull_string secretID; +}; + +struct remote_secret_get_xml_ret { + remote_nonnull_string xml; +}; + +struct remote_secret_set_value_args { + remote_nonnull_string secretID; + opaque value<REMOTE_SECRET_VALUE_MAX>; +}; + +struct remote_secret_get_value_args { + remote_nonnull_string secretID; +}; + +struct remote_secret_get_value_ret { + opaque value<REMOTE_SECRET_VALUE_MAX>; +}; + +struct remote_secret_delete_args { + remote_nonnull_string secretID; +}; + +struct remote_secret_num_of_secrets_ret { + int num; +}; + +struct remote_secret_list_secrets_args { + int maxids; +}; + +struct remote_secret_list_secrets_ret { + remote_nonnull_string ids<REMOTE_SECRET_ID_LIST_MAX>; +}; + /*----- Protocol. -----*/ /* Define the program number, protocol version and procedure numbers here. */ @@ -1424,7 +1480,16 @@ enum remote_procedure { REMOTE_PROC_DOMAIN_XML_TO_NATIVE = 136, REMOTE_PROC_NUM_OF_DEFINED_INTERFACES = 137, - REMOTE_PROC_LIST_DEFINED_INTERFACES = 138 + REMOTE_PROC_LIST_DEFINED_INTERFACES = 138, + + REMOTE_PROC_SECRET_ALLOCATE_ID = 139, + REMOTE_PROC_SECRET_SET_XML = 140, + REMOTE_PROC_SECRET_GET_XML = 141, + REMOTE_PROC_SECRET_SET_VALUE = 142, + REMOTE_PROC_SECRET_GET_VALUE = 143, + REMOTE_PROC_SECRET_DELETE = 144, + REMOTE_PROC_SECRET_NUM_OF_SECRETS = 145, + REMOTE_PROC_SECRET_LIST_SECRETS = 146 }; -- 1.6.2.5

--- src/datatypes.h | 1 + src/remote_internal.c | 306 +++++++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 307 insertions(+), 0 deletions(-) diff --git a/src/datatypes.h b/src/datatypes.h index 58a6d32..d17253f 100644 --- a/src/datatypes.h +++ b/src/datatypes.h @@ -130,6 +130,7 @@ struct _virConnect { void * interfacePrivateData; void * storagePrivateData; void * devMonPrivateData; + void * secretPrivateData; /* * The lock mutex must be acquired before accessing/changing diff --git a/src/remote_internal.c b/src/remote_internal.c index a58b768..3272e0d 100644 --- a/src/remote_internal.c +++ b/src/remote_internal.c @@ -6319,6 +6319,297 @@ done: return rv; } +static virDrvOpenStatus +remoteSecretOpen (virConnectPtr conn, + virConnectAuthPtr auth, + int flags) +{ + if (inside_daemon) + return VIR_DRV_OPEN_DECLINED; + + if (conn && + conn->driver && + STREQ (conn->driver->name, "remote")) { + struct private_data *priv; + + /* If we're here, the remote driver is already + * in use due to a) a QEMU uri, or b) a remote + * URI. So we can re-use existing connection + */ + priv = conn->privateData; + remoteDriverLock(priv); + priv->localUses++; + conn->secretPrivateData = priv; + remoteDriverUnlock(priv); + return VIR_DRV_OPEN_SUCCESS; + } else if (conn->networkDriver && + STREQ (conn->networkDriver->name, "remote")) { + struct private_data *priv = conn->networkPrivateData; + remoteDriverLock(priv); + conn->secretPrivateData = priv; + priv->localUses++; + remoteDriverUnlock(priv); + return VIR_DRV_OPEN_SUCCESS; + } else { + /* Using a non-remote driver, so we need to open a + * new connection for secret APIs, forcing it to + * use the UNIX transport. + */ + struct private_data *priv; + int ret; + ret = remoteOpenSecondaryDriver(conn, + auth, + flags, + &priv); + if (ret == VIR_DRV_OPEN_SUCCESS) + conn->secretPrivateData = priv; + return ret; + } +} + +static int +remoteSecretClose (virConnectPtr conn) +{ + int rv = 0; + struct private_data *priv = conn->secretPrivateData; + + conn->secretPrivateData = NULL; + remoteDriverLock(priv); + priv->localUses--; + if (!priv->localUses) { + rv = doRemoteClose(conn, priv); + remoteDriverUnlock(priv); + virMutexDestroy(&priv->lock); + VIR_FREE(priv); + } + if (priv) + remoteDriverUnlock(priv); + return rv; +} + +static char * +remoteSecretAllocateID (virConnectPtr conn) +{ + char *rv = NULL; + remote_secret_allocate_id_ret ret; + struct private_data *priv = conn->secretPrivateData; + + remoteDriverLock (priv); + + memset (&ret, 0, sizeof (ret)); + if (call (conn, priv, 0, REMOTE_PROC_SECRET_ALLOCATE_ID, + (xdrproc_t) xdr_void, (char *) NULL, + (xdrproc_t) xdr_remote_secret_allocate_id_ret, + (char *) &ret) == -1) + goto done; + + /* Caller frees this. */ + rv = ret.secretID; + +done: + remoteDriverUnlock (priv); + return rv; +} + +static int +remoteSecretSetXML (virConnectPtr conn, const char *secret_id, const char *xml) +{ + int rv = -1; + remote_secret_set_xml_args args; + struct private_data *priv = conn->secretPrivateData; + + remoteDriverLock (priv); + + args.secretID = (char *) secret_id; + args.xml = (char *) xml; + + if (call (conn, priv, 0, REMOTE_PROC_SECRET_SET_XML, + (xdrproc_t) xdr_remote_secret_set_xml_args, (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock (priv); + return rv; +} + +static char * +remoteSecretGetXML (virConnectPtr conn, const char *secret_id) +{ + char *rv = NULL; + remote_secret_get_xml_args args; + remote_secret_get_xml_ret ret; + struct private_data *priv = conn->secretPrivateData; + + remoteDriverLock (priv); + + args.secretID = (char *) secret_id; + + memset (&ret, 0, sizeof (ret)); + if (call (conn, priv, 0, REMOTE_PROC_SECRET_GET_XML, + (xdrproc_t) xdr_remote_secret_get_xml_args, (char *) &args, + (xdrproc_t) xdr_remote_secret_get_xml_ret, (char *) &ret) == -1) + goto done; + + /* Caller frees. */ + rv = ret.xml; + +done: + remoteDriverUnlock (priv); + return rv; +} + +static int +remoteSecretSetValue (virConnectPtr conn, const char *secret_id, + const void *secret, size_t secret_size) +{ + int rv = -1; + remote_secret_set_value_args args; + struct private_data *priv = conn->secretPrivateData; + + remoteDriverLock (priv); + + args.secretID = (char *) secret_id; + args.value.value_len = secret_size; + args.value.value_val = (char *) secret; + + if (call (conn, priv, 0, REMOTE_PROC_SECRET_SET_VALUE, + (xdrproc_t) xdr_remote_secret_set_value_args, (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock (priv); + return rv; +} + +static void * +remoteSecretGetValue (virConnectPtr conn, const char *secret_id, + size_t *secret_size, + /* If the call goes over a socket, it's not internal */ + bool libvirt_internal_call ATTRIBUTE_UNUSED) +{ + void *rv = NULL; + remote_secret_get_value_args args; + remote_secret_get_value_ret ret; + struct private_data *priv = conn->secretPrivateData; + + remoteDriverLock (priv); + + args.secretID = (char *) secret_id; + + memset (&ret, 0, sizeof (ret)); + if (call (conn, priv, 0, REMOTE_PROC_SECRET_GET_VALUE, + (xdrproc_t) xdr_remote_secret_get_value_args, (char *) &args, + (xdrproc_t) xdr_remote_secret_get_value_ret, (char *) &ret) == -1) + goto done; + + *secret_size = ret.value.value_len; + rv = ret.value.value_val; /* Caller frees. */ + +done: + remoteDriverUnlock (priv); + return rv; +} + +static int +remoteSecretDelete (virConnectPtr conn, const char *secret_id) +{ + int rv = -1; + remote_secret_delete_args args; + struct private_data *priv = conn->secretPrivateData; + + remoteDriverLock (priv); + + args.secretID = (char *) secret_id; + + if (call (conn, priv, 0, REMOTE_PROC_SECRET_DELETE, + (xdrproc_t) xdr_remote_secret_delete_args, (char *) &args, + (xdrproc_t) xdr_void, (char *) NULL) == -1) + goto done; + + rv = 0; + +done: + remoteDriverUnlock (priv); + return rv; +} + +static int +remoteSecretNumOfSecrets (virConnectPtr conn) +{ + int rv = -1; + remote_secret_num_of_secrets_ret ret; + struct private_data *priv = conn->secretPrivateData; + + remoteDriverLock (priv); + + memset (&ret, 0, sizeof (ret)); + if (call (conn, priv, 0, REMOTE_PROC_SECRET_NUM_OF_SECRETS, + (xdrproc_t) xdr_void, (char *) NULL, + (xdrproc_t) xdr_remote_secret_num_of_secrets_ret, + (char *) &ret) == -1) + goto done; + + rv = ret.num; + +done: + remoteDriverUnlock (priv); + return rv; +} + +static int +remoteSecretListSecrets (virConnectPtr conn, char **ids, int maxids) +{ + int rv = -1; + int i; + remote_secret_list_secrets_args args; + remote_secret_list_secrets_ret ret; + struct private_data *priv = conn->secretPrivateData; + + remoteDriverLock(priv); + + if (maxids > REMOTE_SECRET_ID_LIST_MAX) { + errorf (conn, VIR_ERR_RPC, _("too many remote secret IDs: %d > %d"), + maxids, REMOTE_SECRET_ID_LIST_MAX); + goto done; + } + args.maxids = maxids; + + memset (&ret, 0, sizeof ret); + if (call (conn, priv, 0, REMOTE_PROC_SECRET_LIST_SECRETS, + (xdrproc_t) xdr_remote_secret_list_secrets_args, (char *) &args, + (xdrproc_t) xdr_remote_secret_list_secrets_ret, + (char *) &ret) == -1) + goto done; + + if (ret.ids.ids_len > maxids) { + errorf (conn, VIR_ERR_RPC, _("too many remote secret IDs: %d > %d"), + ret.ids.ids_len, maxids); + goto cleanup; + } + + /* This call is caller-frees. However xdr_free will free up both the + * names and the list of pointers, so we have to strdup the + * names here. + */ + for (i = 0; i < ret.ids.ids_len; ++i) + ids[i] = strdup (ret.ids.ids_val[i]); + + rv = ret.ids.ids_len; + +cleanup: + xdr_free ((xdrproc_t) xdr_remote_secret_list_secrets_ret, (char *) &ret); + +done: + remoteDriverUnlock(priv); + return rv; +} + /*----------------------------------------------------------------------*/ @@ -7607,6 +7898,20 @@ static virStorageDriver storage_driver = { .volGetPath = remoteStorageVolGetPath, }; +static virSecretDriver secret_driver = { + .name = "remote", + .open = remoteSecretOpen, + .close = remoteSecretClose, + .allocateID = remoteSecretAllocateID, + .setXML = remoteSecretSetXML, + .getXML = remoteSecretGetXML, + .setValue = remoteSecretSetValue, + .getValue = remoteSecretGetValue, + .delete = remoteSecretDelete, + .numOfSecrets = remoteSecretNumOfSecrets, + .listSecrets = remoteSecretListSecrets +}; + static virDeviceMonitor dev_monitor = { .name = "remote", .open = remoteDevMonOpen, @@ -7644,6 +7949,7 @@ remoteRegister (void) if (virRegisterInterfaceDriver (&interface_driver) == -1) return -1; if (virRegisterStorageDriver (&storage_driver) == -1) return -1; if (virRegisterDeviceMonitor (&dev_monitor) == -1) return -1; + if (virRegisterSecretDriver (&secret_driver) == -1) return -1; #ifdef WITH_LIBVIRTD if (virRegisterStateDriver (&state_driver) == -1) return -1; #endif -- 1.6.2.5

--- qemud/remote.c | 149 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 149 insertions(+), 0 deletions(-) diff --git a/qemud/remote.c b/qemud/remote.c index d32d513..2ecf55b 100644 --- a/qemud/remote.c +++ b/qemud/remote.c @@ -4515,6 +4515,155 @@ error: VIR_FREE(msg); } +static int +remoteDispatchSecretAllocateId (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_error *err, + void *args ATTRIBUTE_UNUSED, + remote_secret_allocate_id_ret *ret) +{ + char *secret_id; + + secret_id = virSecretAllocateID (conn); + if (secret_id == NULL) { + remoteDispatchConnError (err, conn); + return -1; + } + + ret->secretID = secret_id; + return 0; +} + +static int +remoteDispatchSecretDelete (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, + remote_error *err, remote_secret_delete_args *args, + void *ret ATTRIBUTE_UNUSED) +{ + if (virSecretDelete (conn, args->secretID) < 0) { + remoteDispatchConnError (err, conn); + return -1; + } + + return 0; +} + +static int +remoteDispatchSecretGetValue (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, remote_error *err, + remote_secret_get_value_args *args, + remote_secret_get_value_ret *ret) +{ + size_t secret_size; + void *secret; + + secret = virSecretGetValue (conn, args->secretID, &secret_size); + if (secret == NULL) { + remoteDispatchConnError (err, conn); + return -1; + } + + ret->value.value_len = secret_size; + ret->value.value_val = secret; + + return 0; +} + +static int +remoteDispatchSecretGetXml (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, remote_error *err, + remote_secret_get_xml_args *args, + remote_secret_get_xml_ret *ret) +{ + ret->xml = virSecretGetXML (conn, args->secretID); + if (ret->xml == NULL) { + remoteDispatchConnError (err, conn); + return -1; + } + return 0; +} + +static int +remoteDispatchSecretListSecrets (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, remote_error *err, + remote_secret_list_secrets_args *args, + remote_secret_list_secrets_ret *ret) +{ + if (args->maxids > REMOTE_SECRET_ID_LIST_MAX) { + remoteDispatchFormatError (err, "%s", + _("maxids > REMOTE_SECRET_ID_LIST_MAX")); + return -1; + } + + if (VIR_ALLOC_N (ret->ids.ids_val, args->maxids) < 0) { + remoteDispatchOOMError (err); + return -1; + } + + ret->ids.ids_len = virSecretListSecrets (conn, ret->ids.ids_val, + args->maxids); + if (ret->ids.ids_len == -1) { + VIR_FREE (ret->ids.ids_val); + remoteDispatchConnError (err, conn); + return -1; + } + + return 0; +} + +static int +remoteDispatchSecretNumOfSecrets (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, remote_error *err, + void *args ATTRIBUTE_UNUSED, + remote_secret_num_of_secrets_ret *ret) +{ + ret->num = virSecretNumOfSecrets (conn); + if (ret->num == -1) { + remoteDispatchConnError (err, conn); + return -1; + } + + return 0; +} + +static int +remoteDispatchSecretSetValue (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, remote_error *err, + remote_secret_set_value_args *args, + void *ret ATTRIBUTE_UNUSED) +{ + if (virSecretSetValue (conn, args->secretID, args->value.value_val, + args->value.value_len) < 0) { + remoteDispatchConnError (err, conn); + return -1; + } + + return 0; +} + +static int +remoteDispatchSecretSetXml (struct qemud_server *server ATTRIBUTE_UNUSED, + struct qemud_client *client ATTRIBUTE_UNUSED, + virConnectPtr conn, remote_error *err, + remote_secret_set_xml_args *args, + void *ret ATTRIBUTE_UNUSED) +{ + if (virSecretSetXML (conn, args->secretID, args->xml) < 0) { + remoteDispatchConnError (err, conn); + return -1; + } + + return 0; +} + + /*----- Helpers. -----*/ /* get_nonnull_domain and get_nonnull_network turn an on-wire -- 1.6.2.5

This implementation stores the secrets in an unencrypted text file, for simplicity in implementation and debugging. (Symmetric encryption, e.g. using gpgme, will not be difficult to add. Because the TLS private key used by libvirtd is stored unencrypted, encrypting the secrets file does not currently provide much additional security.) --- include/libvirt/virterror.h | 1 + po/POTFILES.in | 1 + qemud/qemud.c | 3 + src/Makefile.am | 14 + src/libvirt_private.syms | 2 + src/secret_driver.c | 1077 +++++++++++++++++++++++++++++++++++++++++++ src/secret_driver.h | 28 ++ src/test.c | 21 + src/virterror.c | 6 + 9 files changed, 1153 insertions(+), 0 deletions(-) create mode 100644 src/secret_driver.c create mode 100644 src/secret_driver.h diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index 64e0143..fc24251 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -168,6 +168,7 @@ typedef enum { VIR_ERR_INVALID_INTERFACE, /* invalid interface object */ VIR_ERR_MULTIPLE_INTERFACES, /* more than one matching interface found */ VIR_WAR_NO_SECRET, /* failed to start secret storage */ + VIR_ERR_NO_SECRET, /* secret not found */ } virErrorNumber; /** diff --git a/po/POTFILES.in b/po/POTFILES.in index 141f58b..cf0ec8d 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -29,6 +29,7 @@ src/proxy_internal.c src/qemu_conf.c src/qemu_driver.c src/remote_internal.c +src/secret_driver.c src/security.c src/security_selinux.c src/storage_backend.c diff --git a/qemud/qemud.c b/qemud/qemud.c index 3e551ca..01426da 100644 --- a/qemud/qemud.c +++ b/qemud/qemud.c @@ -92,6 +92,7 @@ #ifdef WITH_NODE_DEVICES #include "node_device.h" #endif +#include "secret_driver.h" #endif @@ -819,6 +820,7 @@ static struct qemud_server *qemudInitialize(int sigread) { virDriverLoadModule("network"); virDriverLoadModule("storage"); virDriverLoadModule("nodedev"); + virDriverLoadModule("secret"); virDriverLoadModule("qemu"); virDriverLoadModule("lxc"); virDriverLoadModule("uml"); @@ -837,6 +839,7 @@ static struct qemud_server *qemudInitialize(int sigread) { (defined(HAVE_HAL) || defined(HAVE_DEVKIT)) nodedevRegister(); #endif + secretRegister(); #ifdef WITH_QEMU qemuRegister(); #endif diff --git a/src/Makefile.am b/src/Makefile.am index 9567490..ce33695 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -176,6 +176,9 @@ NETWORK_DRIVER_SOURCES = \ INTERFACE_DRIVER_SOURCES = \ interface_driver.h interface_driver.c +SECRET_DRIVER_SOURCES = \ + secret_driver.h secret_driver.c + # Storage backend specific impls STORAGE_DRIVER_SOURCES = \ storage_driver.h storage_driver.c \ @@ -448,6 +451,17 @@ endif libvirt_driver_interface_la_SOURCES = $(INTERFACE_DRIVER_SOURCES) endif +if WITH_DRIVER_MODULES +mod_LTLIBRARIES += libvirt_driver_secret.la +else +noinst_LTLIBRARIES += libvirt_driver_secret.la +libvirt_la_LIBADD += libvirt_driver_secret.la +endif +if WITH_DRIVER_MODULES +libvirt_driver_secret_la_LDFLAGS = -module -avoid-version +endif +libvirt_driver_secret_la_SOURCES = $(SECRET_DRIVER_SOURCES) + # Needed to keep automake quiet about conditionals libvirt_driver_storage_la_SOURCES = if WITH_STORAGE_DIR diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index bd63692..343a71e 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -285,6 +285,8 @@ qparam_get_query; qparam_query_parse; free_qparam_set; +# secret.h +secretRegister; # security.h virSecurityDriverVerify; diff --git a/src/secret_driver.c b/src/secret_driver.c new file mode 100644 index 0000000..07e4642 --- /dev/null +++ b/src/secret_driver.c @@ -0,0 +1,1077 @@ +/* + * secret_driver.c: local driver for secret manipulation API + * + * Copyright (C) 2009 Red Hat, Inc. + * + * 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.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Red Hat Author: Miloslav Trmač <mitr@redhat.com> + */ + +#include <config.h> + +#include <fcntl.h> +#include <stdbool.h> +#include <string.h> +#include <sys/stat.h> +#include <unistd.h> + +#include "internal.h" +#include "base64.h" +#include "buf.h" +#include "datatypes.h" +#include "driver.h" +#include "memory.h" +#include "secret_driver.h" +#include "threads.h" +#include "util.h" +#include "uuid.h" +#include "virterror_internal.h" +#include "xml.h" + +#define VIR_FROM_THIS VIR_FROM_SECRET + +#define virSecretReportError(conn, code, fmt...) \ + virReportErrorHelper(conn, VIR_FROM_SECRET, code, __FILE__, \ + __FUNCTION__, __LINE__, fmt) + +#define secretLog(msg...) fprintf(stderr, msg) + +typedef struct _virSecret virSecret; +typedef virSecret *virSecretPtr; +struct _virSecret { + virSecretPtr next; + char *id; /* We generate UUIDs, but don't restrict user-chosen IDs */ + void *value; /* May be NULL */ + size_t value_size; + unsigned ephemeral : 1; + unsigned private : 1; + char *description, *volume; /* May be NULL */ +}; + +typedef struct _virSecretDriverState virSecretDriverState; +typedef virSecretDriverState *virSecretDriverStatePtr; +struct _virSecretDriverState { + virMutex lock; + virSecret *secrets; + char *filename; +}; + +static virSecretDriverStatePtr driverState; + +static void +secretDriverLock(virSecretDriverStatePtr driver) +{ + virMutexLock(&driver->lock); +} + +static void +secretDriverUnlock(virSecretDriverStatePtr driver) +{ + virMutexUnlock(&driver->lock); +} + +static virSecretPtr +listUnlink(virSecretPtr *pptr) +{ + virSecretPtr secret; + + secret = *pptr; + *pptr = secret->next; + return secret; +} + +static void +listInsert(virSecretPtr *pptr, virSecretPtr secret) +{ + secret->next = *pptr; + *pptr = secret; +} + +static void +secretFree(virSecretPtr secret) +{ + if (secret == NULL) + return; + + VIR_FREE(secret->id); + if (secret->value != NULL) { + memset(secret->value, 0, secret->value_size); + VIR_FREE(secret->value); + } + VIR_FREE(secret->description); + VIR_FREE(secret->volume); + VIR_FREE(secret); +} + +static virSecretPtr * +secretFind(virSecretDriverStatePtr driver, const char *secret_id) +{ + virSecretPtr *pptr, s; + + for (pptr = &driver->secrets; (s = *pptr) != NULL; pptr = &s->next) { + if (STREQ(s->id, secret_id)) + return pptr; + } + return NULL; +} + +static virSecretPtr +secretCreate(virConnectPtr conn, virSecretDriverStatePtr driver, + const char *secret_id) +{ + virSecretPtr secret = NULL; + + if (VIR_ALLOC(secret) < 0) + goto no_memory; + secret->id = strdup(secret_id); + if (secret->id == NULL) + goto no_memory; + listInsert(&driver->secrets, secret); + return secret; + + no_memory: + virReportOOMError(conn); + secretFree(secret); + return NULL; +} + +static virSecretPtr +secretFindOrCreate(virConnectPtr conn, virSecretDriverStatePtr driver, + const char *secret_id, bool *created_new) +{ + virSecretPtr *pptr, secret; + + pptr = secretFind(driver, secret_id); + if (pptr != NULL) { + if (created_new != NULL) + *created_new = false; + return *pptr; + } + + secret = secretCreate(conn, driver, secret_id); + if (secret != NULL && created_new != NULL) + *created_new = true; + return secret; +} + +/* The secret storage file format is intentionally simplistic, in order to + minimize the number of copies of unencrypted secrets in memory. */ + +static int +writeString(virConnectPtr conn, int fd, const char *s) +{ + int ret; + + ret = safewrite(fd, s, strlen(s)); + if (ret < 0) + virReportSystemError (conn, errno, "%s", + _("cannot write secrets file")); + return ret; +} + +static int +writeBase64Data(virConnectPtr conn, int fd, const char *field, + const void *data, size_t size) +{ + int ret = -1; + char *base64 = NULL; + + if (writeString(conn, fd, field) < 0 || writeString(conn, fd, " ") < 0) + goto cleanup; + + base64_encode_alloc(data, size, &base64); + if (base64 == NULL) { + virReportOOMError(conn); + goto cleanup; + } + if (writeString(conn, fd, base64) < 0 || writeString(conn, fd, "\n") < 0) + goto cleanup; + ret = 0; + + cleanup: + VIR_FREE(base64); + return ret; +} + +static int +writeSecret(virConnectPtr conn, int fd, const virSecret *secret) +{ + const char *s; + + if (writeBase64Data(conn, fd, "id", secret->id, strlen(secret->id)) < 0) + return -1; + + if (secret->ephemeral) + s = "ephemeral yes\n"; + else + s = "ephemeral no\n"; + if (writeString(conn, fd, s) < 0) + return -1; + + if (secret->private) + s = "private yes\n"; + else + s = "private no\n"; + if (writeString(conn, fd, s) < 0) + return -1; + + if (secret->value != NULL && + writeBase64Data(conn, fd, "value", secret->value, + secret->value_size) < 0) + return -1; + if (secret->description != NULL && + writeBase64Data(conn, fd, "description", secret->description, + strlen(secret->description)) < 0) + return -1; + if (secret->volume != NULL && + writeBase64Data(conn, fd, "volume", secret->volume, + strlen(secret->volume)) < 0) + return -1; + + return 0; +} + +static int +saveSecrets(virConnectPtr conn, virSecretDriverStatePtr driver) +{ + const virSecret *secret; + char *tmp_path = NULL; + int fd = -1, ret = -1; + + if (virAsprintf(&tmp_path, "%sXXXXXX", driver->filename) < 0) { + virReportOOMError(conn); + goto cleanup; + } + fd = mkstemp (tmp_path); + if (fd == -1) { + virReportSystemError (conn, errno, _("mkstemp(\"%s\") failed"), + tmp_path); + goto cleanup; + } + + for (secret = driver->secrets; secret != NULL; secret = secret->next) { + if (!secret->ephemeral && writeSecret(conn, fd, secret) < 0) + goto cleanup; + } + close(fd); + fd = -1; + if (rename(tmp_path, driver->filename) < 0) { + virReportSystemError (conn, errno, _("rename(%s, %s) failed"), + tmp_path, driver->filename); + goto cleanup; + } + tmp_path = NULL; + ret = 0; + + cleanup: + if (fd != -1) + close(fd); + if (tmp_path != NULL) { + unlink(tmp_path); + VIR_FREE(tmp_path); + } + return ret; +} + +static int +parseBase64String(virConnectPtr conn, const char *base64, char **string) +{ + char *tmp; + size_t size; + + if (!base64_decode_alloc(base64, strlen(base64), &tmp, &size)) { + virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("invalid format of base64 in secret storage")); + return -1; + } + if (tmp == NULL || VIR_ALLOC_N(*string, size + 1) < 0) { + virReportOOMError(conn); + return -1; + } + + memcpy(*string, tmp, size); + (*string)[size] = '\0'; + return 0; +} + +static int +parseKeyValue(virConnectPtr conn, virSecretPtr *list, virSecretPtr *secret, + const char *key, const char *value) +{ + virSecretPtr s; + + s = *secret; + if (s == NULL) { + if (VIR_ALLOC(s) < 0) + goto no_memory; + *secret = s; + } + if (STREQ(key, "id")) { + if (s->id != NULL) { + listInsert(list, s); + if (VIR_ALLOC(s) < 0) + goto no_memory; + *secret = s; + } + if (parseBase64String(conn, value, &s->id) < 0) + return -1; + } else if (STREQ(key, "ephemeral")) { + if (STREQ(value, "yes")) + s->ephemeral = 1; + else if (STREQ(value, "no")) + s->ephemeral = 0; + else + goto invalid; + } else if (STREQ(key, "private")) { + if (STREQ(value, "yes")) + s->private = 1; + else if (STREQ(value, "no")) + s->private = 0; + else + goto invalid; + } else if (STREQ(key, "value")) { + char *raw; + + if (s->value != NULL) + return -1; + if (!base64_decode_alloc(value, strlen(value), &raw, &s->value_size)) + goto invalid; + if (raw == NULL) + goto no_memory; + s->value = raw; + } else if (STREQ(key, "description")) { + if (s->description != NULL) + goto invalid; + if (parseBase64String(conn, value, &s->description) < 0) + return -1; + } else if (STREQ(key, "volume")) { + if (s->volume != NULL) + goto invalid; + if (parseBase64String(conn, value, &s->volume) < 0) + return -1; + } else + goto invalid; + + return 0; + + invalid: + virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("invalid format of secret storage")); + return -1; + + no_memory: + virReportOOMError(conn); + return -1; +} + +static int +loadSecrets(virConnectPtr conn, virSecretDriverStatePtr driver, + virSecretPtr *dest) +{ + int ret = -1, fd = -1; + struct stat st; + char *contents = NULL, *strtok_data = NULL, *strtok_first; + const char *key, *value; + virSecretPtr secret = NULL, list = NULL; + + if (stat(driver->filename, &st) < 0) { + if (errno == ENOENT) + return 0; + virReportSystemError (conn, errno, _("cannot stat '%s'"), + driver->filename); + goto cleanup; + } + if ((size_t)st.st_size != st.st_size || (size_t)(st.st_size + 1) == 0) { + virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("secrets file does not fit in memory")); + goto cleanup; + } + + fd = open(driver->filename, O_RDONLY); + if (fd == -1) { + virReportSystemError (conn, errno, _("cannot open '%s'"), + driver->filename); + goto cleanup; + } + if (VIR_ALLOC_N(contents, st.st_size + 1) < 0) { + virReportOOMError(conn); + goto cleanup; + } + if (saferead(fd, contents, st.st_size) != st.st_size) { + virReportSystemError (conn, errno, _("cannot read '%s'"), + driver->filename); + goto cleanup; + } + close(fd); + fd = -1; + + strtok_first = contents; + while ((key = strtok_r(strtok_first, " ", &strtok_data)) != NULL) { + strtok_first = NULL; + value = strtok_r(strtok_first, "\n", &strtok_data); + if (value == NULL) { + virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("invalid format of secret storage")); + goto cleanup; + } + if (parseKeyValue(conn, &list, &secret, key, value) < 0) + goto cleanup; + } + if (secret != NULL) { + if (secret->id == NULL) { + virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("invalid format of secret storage")); + goto cleanup; + } + listInsert(&list, secret); + } + + /* The secrets were collected into "list" in reverse order. This happens + to reverse the order again, preserving the original order of secrets + in the file. */ + while (list != NULL) { + secret = listUnlink(&list); + listInsert(dest, secret); + } + secret = NULL; + + ret = 0; + goto cleanup; + + + cleanup: + secretFree(secret); + while (list != NULL) { + secret = listUnlink(&list); + secretFree(secret); + } + if (fd != -1) + close(fd); + if (contents != NULL) { + memset(contents, 0, st.st_size); + VIR_FREE(contents); + } + return ret; +} + +static virSecretPtr +secretXMLParseNode(virConnectPtr conn, xmlDocPtr xml, xmlNodePtr root) +{ + xmlXPathContextPtr ctxt = NULL; + virSecretPtr secret, ret = NULL; + char *prop; + + if (!xmlStrEqual(root->name, BAD_CAST "secret")) { + virSecretReportError(conn, VIR_ERR_XML_ERROR, "%s", + _("incorrect root element")); + goto cleanup; + } + + ctxt = xmlXPathNewContext(xml); + if (ctxt == NULL) { + virReportOOMError(conn); + goto cleanup; + } + ctxt->node = root; + + if (VIR_ALLOC(secret) < 0) { + virReportOOMError(conn); + goto cleanup; + } + + prop = virXPathString(conn, "string(./@ephemeral)", ctxt); + if (prop != NULL && STREQ(prop, "yes")) + secret->ephemeral = 1; + VIR_FREE(prop); + + prop = virXPathString(conn, "string(./@private)", ctxt); + if (prop != NULL && STREQ(prop, "yes")) + secret->private = 1; + VIR_FREE(prop); + + secret->description = virXPathString(conn, "string(./description)", ctxt); + secret->volume = virXPathString(conn, "string(./volume)", ctxt); + + ret = secret; + secret = NULL; + + cleanup: + secretFree(secret); + xmlXPathFreeContext(ctxt); + return ret; +} + +/* Called from SAX on parsing errors in the XML. */ +static void +catchXMLError(void *ctx, const char *msg ATTRIBUTE_UNUSED, ...) +{ + xmlParserCtxtPtr ctxt = (xmlParserCtxtPtr) ctx; + + if (ctxt) { + virConnectPtr conn = ctxt->_private; + + if (virGetLastError() == NULL && + ctxt->lastError.level == XML_ERR_FATAL && + ctxt->lastError.message != NULL) { + virSecretReportError(conn, VIR_ERR_XML_DETAIL, _("at line %d: %s"), + ctxt->lastError.line, ctxt->lastError.message); + } + } +} + +static virSecretPtr +secretXMLParseString(virConnectPtr conn, const char *xmlStr) +{ + xmlParserCtxtPtr pctxt; + xmlDocPtr xml = NULL; + xmlNodePtr root; + virSecretPtr ret = NULL; + + pctxt = xmlNewParserCtxt(); + if (pctxt == NULL || pctxt->sax == NULL) + goto cleanup; + pctxt->sax->error = catchXMLError; + pctxt->_private = conn; + + xml = xmlCtxtReadDoc(pctxt, BAD_CAST xmlStr, "secret.xml", NULL, + XML_PARSE_NOENT | XML_PARSE_NONET | + XML_PARSE_NOWARNING); + if (xml == NULL) { + if (conn->err.code == VIR_ERR_NONE) + virSecretReportError(conn, VIR_ERR_XML_ERROR, "%s", + _("failed to parse xml document")); + goto cleanup; + } + + root = xmlDocGetRootElement(xml); + if (root == NULL) { + virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("missing root element")); + goto cleanup; + } + + ret = secretXMLParseNode(conn, xml, root); + + cleanup: + xmlFreeDoc(xml); + xmlFreeParserCtxt(pctxt); + return ret; +} + +static char * +secretXMLFormat(virConnectPtr conn, const virSecret *secret) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + char *tmp; + + virBufferVSprintf(&buf, "<secret ephemeral='%s' private='%s'>\n", + secret->ephemeral ? "yes" : "no", + secret->private ? "yes" : "no"); + if (secret->description != NULL) + virBufferEscapeString(&buf, " <description>%s</description>\n", + secret->description); + if (secret->volume != NULL) + virBufferEscapeString(&buf, " <volume>%s</volume>\n", secret->volume); + virBufferAddLit(&buf, "</secret>\n"); + + if (virBufferError(&buf)) + goto no_memory; + + return virBufferContentAndReset(&buf); + + no_memory: + virReportOOMError(conn); + tmp = virBufferContentAndReset(&buf); + VIR_FREE(tmp); + return NULL; +} + +static virDrvOpenStatus +secretOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED) { + if (driverState == NULL) + return VIR_DRV_OPEN_DECLINED; + + conn->secretPrivateData = driverState; + return VIR_DRV_OPEN_SUCCESS; +} + +static int +secretClose(virConnectPtr conn) { + conn->secretPrivateData = NULL; + return 0; +} + +static char * +secretAllocateID(virConnectPtr conn) +{ + char *secret_id, *ret = NULL; + unsigned attempt; + virSecretDriverStatePtr driver = conn->secretPrivateData; + + if (VIR_ALLOC_N(secret_id, VIR_UUID_STRING_BUFLEN) < 0) { + virReportOOMError(conn); + return NULL; + } + + secretDriverLock(driver); + + for (attempt = 0; attempt < 65536; attempt++) { + unsigned char uuid[VIR_UUID_BUFLEN]; + + if (virUUIDGenerate(uuid) < 0) { + virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("unable to generate uuid")); + goto cleanup; + } + virUUIDFormat(uuid, secret_id); + if (secretFind(driver, secret_id) == NULL) { + virSecretPtr s; + + s = secretCreate(conn, driver, secret_id); + if (s != NULL) { + ret = secret_id; + secret_id = NULL; + } + goto cleanup; + } + } + virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("too many conflicts when generating an uuid")); + + cleanup: + secretDriverUnlock(driver); + + VIR_FREE(secret_id); + return ret; +} + +static void +shallowCopyAttributes(virSecretPtr dest, const virSecret *src) +{ + dest->ephemeral = src->ephemeral; + dest->private = src->private; + dest->description = src->description; + dest->volume = src->volume; +} + +static int +secretSetXML(virConnectPtr conn, const char *secret_id, const char *xml) +{ + virSecretDriverStatePtr driver = conn->secretPrivateData; + int ret = -1; + virSecret backup; + virSecretPtr secret, new_attrs; + bool secret_is_new; + + new_attrs = secretXMLParseString(conn, xml); + if (new_attrs == NULL) + return -1; + + secretDriverLock(driver); + + secret = secretFindOrCreate(conn, driver, secret_id, &secret_is_new); + if (secret == NULL) + goto cleanup; + + /* Save old values of the attributes */ + shallowCopyAttributes(&backup, secret); + + if (backup.private && !new_attrs->private) { + virSecretReportError(conn, VIR_ERR_OPERATION_DENIED, "%s", + virErrorMsg(VIR_ERR_OPERATION_DENIED, NULL)); + goto cleanup; + } + + shallowCopyAttributes(secret, new_attrs); + if (!new_attrs->ephemeral || !backup.ephemeral) { + if (saveSecrets(conn, driver) < 0) + goto restore_backup; + } + /* Saved succesfully - drop old values */ + new_attrs = NULL; + VIR_FREE(backup.description); + VIR_FREE(backup.volume); + + ret = 0; + goto cleanup; + + restore_backup: + /* Error - restore previous state and free new attributes */ + shallowCopyAttributes(secret, &backup); + if (secret_is_new) { + /* "secret" was added to the head of the list above */ + if (listUnlink(&driverState->secrets) != secret) + /* abort() instead? */ + virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("list of secrets is inconsistent")); + else + secretFree(secret); + } + + cleanup: + secretFree(new_attrs); + secretDriverUnlock(driver); + + return ret; +} + +static char * +secretGetXML(virConnectPtr conn, const char *secret_id) +{ + virSecretDriverStatePtr driver = conn->secretPrivateData; + char *ret = NULL; + virSecretPtr *pptr; + + secretDriverLock(driver); + + pptr = secretFind(driver, secret_id); + if (pptr == NULL) { + virSecretReportError(conn, VIR_ERR_NO_SECRET, + _("no secret with matching id '%s'"), secret_id); + goto cleanup; + } + + ret = secretXMLFormat(conn, *pptr); + + cleanup: + secretDriverUnlock(driver); + + return ret; +} + +static int +secretSetValue(virConnectPtr conn, const char *secret_id, const void *value, + size_t value_size) +{ + virSecretDriverStatePtr driver = conn->secretPrivateData; + int ret = -1; + void *old_value; + unsigned char *new_value; + size_t old_value_size; + virSecretPtr secret; + bool secret_is_new; + + if (VIR_ALLOC_N(new_value, value_size) < 0) { + virReportOOMError(conn); + return -1; + } + + secretDriverLock(driver); + + secret = secretFindOrCreate(conn, driver, secret_id, &secret_is_new); + if (secret == NULL) + goto cleanup; + + old_value = secret->value; + old_value_size = secret->value_size; + + memcpy(new_value, value, value_size); + secret->value = new_value; + secret->value_size = value_size; + if (!secret->ephemeral) { + if (saveSecrets(conn, driver) < 0) + goto restore_backup; + } + /* Saved succesfully - drop old value */ + if (old_value != NULL) { + memset(old_value, 0, old_value_size); + VIR_FREE(old_value); + } + new_value = NULL; + + ret = 0; + goto cleanup; + + restore_backup: + /* Error - restore previous state and free new value */ + secret->value = old_value; + secret->value_size = old_value_size; + memset(new_value, 0, value_size); + if (secret_is_new) { + /* "secret" was added to the head of the list above */ + if (listUnlink(&driverState->secrets) != secret) + /* abort() instead? */ + virSecretReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("list of secrets is inconsistent")); + else + secretFree(secret); + } + + cleanup: + secretDriverUnlock(driver); + + VIR_FREE(new_value); + + return ret; +} + +static void * +secretGetValue(virConnectPtr conn, const char *secret_id, size_t *secret_size, + bool libvirt_internal_call) +{ + virSecretDriverStatePtr driver = conn->secretPrivateData; + unsigned char *ret = NULL; + virSecretPtr *pptr, secret; + + secretDriverLock(driver); + + pptr = secretFind(driver, secret_id); + if (pptr == NULL || (*pptr)->value == NULL) { + virSecretReportError(conn, VIR_ERR_NO_SECRET, + _("no secret with matching id '%s'"), secret_id); + goto cleanup; + } + secret = *pptr; + + if (!libvirt_internal_call && secret->private) { + virSecretReportError(conn, VIR_ERR_OPERATION_DENIED, "%s", + virErrorMsg(VIR_ERR_OPERATION_DENIED, NULL)); + goto cleanup; + } + + if (VIR_ALLOC_N(ret, secret->value_size) < 0) { + virReportOOMError(conn); + goto cleanup; + } + memcpy(ret, secret->value, secret->value_size); + *secret_size = secret->value_size; + + cleanup: + secretDriverUnlock(driver); + + return ret; +} + +static int +secretDelete(virConnectPtr conn, const char *secret_id) +{ + virSecretDriverStatePtr driver = conn->secretPrivateData; + int ret = -1; + virSecretPtr *pptr, secret; + + secretDriverLock(driver); + + pptr = secretFind(driver, secret_id); + if (pptr == NULL) { + virSecretReportError(conn, VIR_ERR_NO_SECRET, + _("no secret with matching id '%s'"), secret_id); + goto cleanup; + } + + secret = listUnlink(pptr); + if (!secret->ephemeral) { + if (saveSecrets(conn, driver) < 0) + goto restore_backup; + } + secretFree(secret); + + ret = 0; + goto cleanup; + + restore_backup: + /* This may change the order of secrets in the list. We don't care. */ + listInsert(&driver->secrets, secret); + + cleanup: + secretDriverUnlock(driver); + + return ret; +} + +static int +secretNumOfSecrets(virConnectPtr conn) +{ + virSecretDriverStatePtr driver = conn->secretPrivateData; + int i; + virSecretPtr secret; + + secretDriverLock(driver); + + i = 0; + for (secret = driver->secrets; secret != NULL; secret = secret->next) + i++; + + secretDriverUnlock(driver); + return i; +} + +static int +secretListSecrets(virConnectPtr conn, char **ids, int maxids) +{ + virSecretDriverStatePtr driver = conn->secretPrivateData; + int i; + virSecretPtr secret; + + memset(ids, 0, maxids * sizeof(*ids)); + + secretDriverLock(driver); + + i = 0; + for (secret = driver->secrets; secret != NULL; secret = secret->next) { + if (i == maxids) + break; + ids[i] = strdup(secret->id); + if (ids[i] == NULL) + goto cleanup; + i++; + } + + secretDriverUnlock(driver); + return i; + + cleanup: + secretDriverUnlock(driver); + + for (i = 0; i < maxids; i++) + VIR_FREE(ids[i]); + + return -1; +} + +static int +secretDriverCleanup(void) +{ + if (driverState == NULL) + return -1; + + secretDriverLock(driverState); + + while (driverState->secrets != NULL) { + virSecretPtr s; + + s = listUnlink(&driverState->secrets); + secretFree(s); + } + VIR_FREE(driverState->filename); + + secretDriverUnlock(driverState); + virMutexDestroy(&driverState->lock); + VIR_FREE(driverState); + + return 0; +} + +static int +secretDriverStartup(int privileged) +{ + char *base = NULL; + + if (VIR_ALLOC(driverState) < 0) + return -1; + + if (virMutexInit(&driverState->lock) < 0) { + VIR_FREE(driverState); + return -1; + } + secretDriverLock(driverState); + + if (privileged) { + base = strdup(SYSCONF_DIR "/libvirt"); + if (base == NULL) + goto out_of_memory; + } else { + uid_t uid = geteuid(); + char *userdir = virGetUserDirectory(NULL, uid); + + if (!userdir) + goto error; + + if (virAsprintf(&base, "%s/.libvirt", userdir) == -1) { + secretLog("out of memory in virAsprintf"); + VIR_FREE(userdir); + goto out_of_memory; + } + VIR_FREE(userdir); + } + if (virAsprintf(&driverState->filename, "%s/secrets", base) == -1) + goto out_of_memory; + VIR_FREE(base); + + if (loadSecrets(NULL, driverState, &driverState->secrets) < 0) + goto error; + + secretDriverUnlock(driverState); + return 0; + + out_of_memory: + secretLog("virSecretStartup: out of memory"); + error: + VIR_FREE(base); + secretDriverUnlock(driverState); + secretDriverCleanup(); + return -1; +} + +static int +secretDriverReload(void) +{ + virSecretPtr new_secrets = NULL; + + if (!driverState) + return -1; + + secretDriverLock(driverState); + + if (loadSecrets(NULL, driverState, &new_secrets) < 0) + goto end; + + /* Keep ephemeral secrets from current state. Discard non-ephemeral secrets + that were removed by the secrets file. */ + while (driverState->secrets != NULL) { + virSecretPtr s; + + s = listUnlink(&driverState->secrets); + if (s->ephemeral) + listInsert(&new_secrets, s); + else + secretFree(s); + } + driverState->secrets = new_secrets; + + end: + secretDriverUnlock(driverState); + return 0; +} + +static virSecretDriver secretDriver = { + .name = "secret", + .open = secretOpen, + .close = secretClose, + .allocateID = secretAllocateID, + .setXML = secretSetXML, + .getXML = secretGetXML, + .setValue = secretSetValue, + .getValue = secretGetValue, + .delete = secretDelete, + .numOfSecrets = secretNumOfSecrets, + .listSecrets = secretListSecrets +}; + +static virStateDriver stateDriver = { + .initialize = secretDriverStartup, + .cleanup = secretDriverCleanup, + .reload = secretDriverReload, + .active = NULL /* All persistent state is immediately saved to disk */ +}; + +int +secretRegister(void) +{ + virRegisterSecretDriver(&secretDriver); + virRegisterStateDriver(&stateDriver); + return 0; +} diff --git a/src/secret_driver.h b/src/secret_driver.h new file mode 100644 index 0000000..0d0b80a --- /dev/null +++ b/src/secret_driver.h @@ -0,0 +1,28 @@ +/* + * secret_driver.h: local driver for secret manipulation API + * + * Copyright (C) 2009 Red Hat, Inc. + * + * 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.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Red Hat Author: Miloslav Trmač <mitr@redhat.com> + */ + +#ifndef __VIR_SECRET_DRIVER_H__ +#define __VIR_SECRET_DRIVER_H__ + +int secretRegister(void); + +#endif /* __VIR_SECRET_DRIVER_H__ */ diff --git a/src/test.c b/src/test.c index 305f2c9..7c8f85b 100644 --- a/src/test.c +++ b/src/test.c @@ -4173,6 +4173,20 @@ static void testDomainEventQueue(testConnPtr driver, virEventUpdateTimeout(driver->domainEventTimer, 0); } +static virDrvOpenStatus testSecretOpen(virConnectPtr conn, + virConnectAuthPtr auth ATTRIBUTE_UNUSED, + int flags ATTRIBUTE_UNUSED) { + if (STRNEQ(conn->driver->name, "Test")) + return VIR_DRV_OPEN_DECLINED; + + conn->secretPrivateData = conn->privateData; + return VIR_DRV_OPEN_SUCCESS; +} + +static int testSecretClose(virConnectPtr conn) { + conn->secretPrivateData = NULL; + return 0; +} static virDriver testDriver = { VIR_DRV_TEST, @@ -4328,6 +4342,11 @@ static virDeviceMonitor testDevMonitor = { .close = testDevMonClose, }; +static virSecretDriver testSecretDriver = { + .name = "Test", + .open = testSecretOpen, + .close = testSecretClose, +}; /** @@ -4348,6 +4367,8 @@ testRegister(void) return -1; if (virRegisterDeviceMonitor(&testDevMonitor) < 0) return -1; + if (virRegisterSecretDriver(&testSecretDriver) < 0) + return -1; return 0; } diff --git a/src/virterror.c b/src/virterror.c index ba66238..137405a 100644 --- a/src/virterror.c +++ b/src/virterror.c @@ -1077,6 +1077,12 @@ virErrorMsg(virErrorNumber error, const char *info) else errmsg = _("Failed to find a secret storage driver: %s"); break; + case VIR_ERR_NO_SECRET: + if (info == NULL) + errmsg = _("Secret not found"); + else + errmsg = _("Secret not found: %s"); + break; } return (errmsg); } -- 1.6.2.5

--- src/virsh.c | 304 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 files changed, 304 insertions(+), 0 deletions(-) diff --git a/src/virsh.c b/src/virsh.c index 94c3c4e..ad49052 100644 --- a/src/virsh.c +++ b/src/virsh.c @@ -41,6 +41,7 @@ #endif #include "internal.h" +#include "base64.h" #include "buf.h" #include "console.h" #include "util.h" @@ -5249,9 +5250,303 @@ cmdVolPath(vshControl *ctl, const vshCmd *cmd) } +/* + * "secret-allocate-id" command + */ +static const vshCmdInfo info_secret_allocate_id[] = { + {"help", gettext_noop("allocate an ID for a secret")}, + {"desc", gettext_noop("Allocate an ID for a secret")}, + {NULL, NULL} +}; + +static int +cmdSecretAllocateID(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) +{ + char *secret_id; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + return FALSE; + + secret_id = virSecretAllocateID(ctl->conn); + if (secret_id == NULL) { + vshError(ctl, FALSE, "%s", _("failed to allocate a secret ID")); + return FALSE; + } + + vshPrint(ctl, "%s\n", secret_id); + free(secret_id); + + return TRUE; +} + +/* + * "secret-set-xml" command + */ +static const vshCmdInfo info_secret_set_xml[] = { + {"help", gettext_noop("set attributes of a secret from an XML file")}, + {"desc", gettext_noop("Set attributes of a secret from an XML file")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_secret_set_xml[] = { + {"secret-id", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("secret ID")}, + {"file", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("file containing secret attributes in XML")}, + {NULL, 0, 0, NULL} +}; +static int +cmdSecretSetXML(vshControl *ctl, const vshCmd *cmd) +{ + char *secret_id, *from; + int found, res; + char *buffer; + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + return FALSE; + secret_id = vshCommandOptString(cmd, "secret-id", &found); + if (!found) + return FALSE; + + from = vshCommandOptString(cmd, "file", &found); + if (!found) + return FALSE; + + if (virFileReadAll(from, VIRSH_MAX_XML_FILE, &buffer) < 0) + return FALSE; + + res = virSecretSetXML(ctl->conn, secret_id, buffer); + free (buffer); + + if (res != 0) { + vshError(ctl, FALSE, _("Failed to set attributes from %s"), from); + return FALSE; + } + vshPrint(ctl, _("Attributes set from %s\n"), from); + return TRUE; +} + +/* + * "secret-get-xml" command + */ +static const vshCmdInfo info_secret_get_xml[] = { + {"help", gettext_noop("secret attributes in XML")}, + {"desc", gettext_noop("Output attributes of a secret as an XML dump to stdout.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_secret_get_xml[] = { + {"secret-id", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("secret ID")}, + {NULL, 0, 0, NULL} +}; + +static int +cmdSecretGetXML(vshControl *ctl, const vshCmd *cmd) +{ + char *secret_id; + int found; + char *xml; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + return FALSE; + + secret_id = vshCommandOptString(cmd, "secret-id", &found); + if (!found) + return FALSE; + + xml = virSecretGetXML(ctl->conn, secret_id); + if (xml == NULL) + return FALSE; + + printf("%s", xml); + free(xml); + return TRUE; +} + +/* + * "secret-set-value" command + */ +static const vshCmdInfo info_secret_set_value[] = { + {"help", gettext_noop("set a secret value")}, + {"desc", gettext_noop("Set a secret value")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_secret_set_value[] = { + {"secret-id", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("secret ID")}, + {"base64", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("base64-encoded secret value")}, + {NULL, 0, 0, NULL} +}; + +static int +cmdSecretSetValue(vshControl *ctl, const vshCmd *cmd) +{ + size_t value_size; + char *secret_id, *base64, *value; + int found, res; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + return FALSE; + + secret_id = vshCommandOptString(cmd, "secret-id", &found); + if (!found) + return FALSE; + + base64 = vshCommandOptString(cmd, "base64", &found); + if (!base64) + return FALSE; + + if (!base64_decode_alloc(base64, strlen(base64), &value, &value_size)) { + vshError(ctl, FALSE, _("Invalid base64 data")); + return FALSE; + } + if (value == NULL) { + vshError(ctl, FALSE, "%s", _("Failed to allocate memory")); + return FALSE; + } + + res = virSecretSetValue(ctl->conn, secret_id, value, value_size); + memset(value, 0, value_size); + free (value); + + if (res != 0) { + vshError(ctl, FALSE, "%s", _("Failed to set secret value")); + return FALSE; + } + vshPrint(ctl, "%s", _("Secret value set\n")); + return TRUE; +} + +/* + * "secret-get-value" command + */ +static const vshCmdInfo info_secret_get_value[] = { + {"help", gettext_noop("Output a secret value")}, + {"desc", gettext_noop("Output a secret value to stdout.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_secret_get_value[] = { + {"secret-id", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("secret ID")}, + {NULL, 0, 0, NULL} +}; + +static int +cmdSecretGetValue(vshControl *ctl, const vshCmd *cmd) +{ + char *secret_id, *base64; + int found; + size_t value_size; + void *value; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + return FALSE; + + secret_id = vshCommandOptString(cmd, "secret-id", &found); + if (!found) + return FALSE; + + value = virSecretGetValue(ctl->conn, secret_id, &value_size); + if (value == NULL) + return FALSE; + + base64_encode_alloc(value, value_size, &base64); + memset(value, 0, value_size); + free(value); + + if (base64 == NULL) { + vshError(ctl, FALSE, "%s", _("Failed to allocate memory")); + return FALSE; + } + printf("%s", base64); + memset(base64, 0, strlen(base64)); + free(base64); + + return TRUE; +} + +/* + * "secret-delete" command + */ +static const vshCmdInfo info_secret_delete[] = { + {"help", gettext_noop("delete a secret")}, + {"desc", gettext_noop("Delete a secret.")}, + {NULL, NULL} +}; + +static const vshCmdOptDef opts_secret_delete[] = { + {"secret-id", VSH_OT_DATA, VSH_OFLAG_REQ, gettext_noop("secret ID")}, + {NULL, 0, 0, NULL} +}; + +static int +cmdSecretDelete(vshControl *ctl, const vshCmd *cmd) +{ + char *secret_id; + int found, ret; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + return FALSE; + + secret_id = vshCommandOptString(cmd, "secret-id", &found); + if (!found) + return FALSE; + + ret = virSecretDelete(ctl->conn, secret_id); + if (ret < 0) { + vshError(ctl, FALSE, _("Failed to delete secret %s"), secret_id); + return FALSE; + } + + vshPrint(ctl, _("Secret %s deleted\n"), secret_id); + + return TRUE; +} + +/* + * "secret-list" command + */ +static const vshCmdInfo info_secret_list[] = { + {"help", gettext_noop("list secrets")}, + {"desc", gettext_noop("Returns a list of secrets")}, + {NULL, NULL} +}; + +static int +cmdSecretList(vshControl *ctl, const vshCmd *cmd ATTRIBUTE_UNUSED) +{ + int maxids = 0, i; + char **ids = NULL; + + if (!vshConnectionUsability(ctl, ctl->conn, TRUE)) + return FALSE; + + maxids = virSecretNumOfSecrets(ctl->conn); + if (maxids < 0) { + vshError(ctl, FALSE, "%s", _("Failed to list secrets")); + return FALSE; + } + ids = vshMalloc(ctl, sizeof(*ids) * maxids); + + maxids = virSecretListSecrets(ctl->conn, ids, maxids); + if (maxids < 0) { + vshError(ctl, FALSE, "%s", _("Failed to list secrets")); + free(ids); + return FALSE; + } + + qsort(ids, maxids, sizeof(char *), namesorter); + + vshPrintExtra(ctl, "%s\n", _("Secret ID")); + vshPrintExtra(ctl, "-----------------------------------------\n"); + + for (i = 0; i < maxids; i++) { + vshPrint(ctl, "%-36s\n", ids[i]); + free(ids[i]); + } + free(ids); + return TRUE; +} /* @@ -6921,6 +7216,15 @@ static const vshCmdDef commands[] = { {"pool-undefine", cmdPoolUndefine, opts_pool_undefine, info_pool_undefine}, {"pool-uuid", cmdPoolUuid, opts_pool_uuid, info_pool_uuid}, + {"secret-allocate-id", cmdSecretAllocateID, NULL, info_secret_allocate_id}, + {"secret-set-xml", cmdSecretSetXML, opts_secret_set_xml, info_secret_set_xml}, + {"secret-get-xml", cmdSecretGetXML, opts_secret_get_xml, info_secret_get_xml}, + {"secret-set-value", cmdSecretSetValue, opts_secret_set_value, info_secret_set_value}, + {"secret-get-value", cmdSecretGetValue, opts_secret_get_value, info_secret_get_value}, + {"secret-delete", cmdSecretDelete, opts_secret_delete, info_secret_delete}, + {"secret-list", cmdSecretList, NULL, info_secret_list}, + + #ifndef WIN32 {"pwd", cmdPwd, NULL, info_pwd}, #endif -- 1.6.2.5

This commit represents results of (make -C docs api) - if this patch does not apply, just re-run the command. The API data gathered by this commit is necessary to make step 10 (Python bindings) usable. --- docs/devhelp/libvirt-libvirt.html | 73 +++++- docs/devhelp/libvirt-virterror.html | 11 +- docs/html/libvirt-libvirt.html | 40 +++- docs/html/libvirt-virterror.html | 4 +- docs/libvirt-api.xml | 125 +++++++++-- docs/libvirt-refs.xml | 417 ++++++++++++++++++++++++++--------- 6 files changed, 528 insertions(+), 142 deletions(-) diff --git a/docs/devhelp/libvirt-libvirt.html b/docs/devhelp/libvirt-libvirt.html index 439934a..ce2b90a 100644 --- a/docs/devhelp/libvirt-libvirt.html +++ b/docs/devhelp/libvirt-libvirt.html @@ -131,7 +131,7 @@ int <a href="#virConnectDomainEventDeregister">virConnectDomainEventDeregister</ int <a href="#virDomainGetSchedulerParameters">virDomainGetSchedulerParameters</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br/> <a href="libvirt-libvirt.html#virSchedParameterPtr">virSchedParameterPtr</a> params, <br/> int * nparams); <a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> <a href="#virDomainLookupByUUIDString">virDomainLookupByUUIDString</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * uuidstr); int <a href="#virConnectNumOfDefinedNetworks">virConnectNumOfDefinedNetworks</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn); -int <a href="#virConnectNumOfDomains">virConnectNumOfDomains</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn); +int <a href="#virConnectListDefinedInterfaces">virConnectListDefinedInterfaces</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> char ** const names, <br/> int maxnames); int <a href="#virNetworkGetUUID">virNetworkGetUUID</a> (<a href="libvirt-libvirt.html#virNetworkPtr">virNetworkPtr</a> network, <br/> unsigned char * uuid); char * <a href="#virInterfaceGetXMLDesc">virInterfaceGetXMLDesc</a> (<a href="libvirt-libvirt.html#virInterfacePtr">virInterfacePtr</a> iface, <br/> unsigned int flags); <a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> <a href="#virStoragePoolGetConnect">virStoragePoolGetConnect</a> (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool); @@ -148,6 +148,7 @@ int <a href="#virDomainSetMaxMemory">virDomainSetMaxMemory</a> (<a href="libvir void <a href="#virEventRegisterImpl">virEventRegisterImpl</a> (<a href="libvirt-libvirt.html#virEventAddHandleFunc">virEventAddHandleFunc</a> addHandle, <br/> <a href="libvirt-libvirt.html#virEventUpdateHandleFunc">virEventUpdateHandleFunc</a> updateHandle, <br/> <a href="libvirt-libvirt.html#virEventRemoveHandleFunc">virEventRemoveHandleFunc</a> removeHandle, <br/> <a href="libvirt-libvirt.html#virEventAddTimeoutFunc">virEventAddTimeoutFunc</a> addTimeout, <br/> <a href="libvirt-libvirt.html#virEventUpdateTimeoutFunc">virEventUpdateTimeoutFunc</a> updateTimeout, <br/> <a href="libvirt-libvirt.html#virEventRemoveTimeoutFunc">virEventRemoveTimeoutFunc</a> removeTimeout); <a href="libvirt-libvirt.html#virInterfacePtr">virInterfacePtr</a> <a href="#virInterfaceDefineXML">virInterfaceDefineXML</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * xml, <br/> unsigned int flags); <a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> <a href="#virDomainMigrate">virDomainMigrate</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br/> <a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> dconn, <br/> unsigned long flags, <br/> const char * dname, <br/> const char * uri, <br/> unsigned long bandwidth); +int <a href="#virSecretNumOfSecrets">virSecretNumOfSecrets</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn); int <a href="#virDomainSuspend">virDomainSuspend</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain); <a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> <a href="#virDomainCreateLinux">virDomainCreateLinux</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * xmlDesc, <br/> unsigned int flags); char * <a href="#virNodeDeviceGetXMLDesc">virNodeDeviceGetXMLDesc</a> (<a href="libvirt-libvirt.html#virNodeDevicePtr">virNodeDevicePtr</a> dev, <br/> unsigned int flags); @@ -172,17 +173,20 @@ char * <a href="#virConnectDomainXMLToNative">virConnectDomainXMLToNative</a> (< int <a href="#virDomainSetSchedulerParameters">virDomainSetSchedulerParameters</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br/> <a href="libvirt-libvirt.html#virSchedParameterPtr">virSchedParameterPtr</a> params, <br/> int nparams); const char * <a href="#virConnectGetType">virConnectGetType</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn); <a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> <a href="#virStorageVolCreateXML">virStorageVolCreateXML</a> (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br/> const char * xmldesc, <br/> unsigned int flags); +int <a href="#virSecretSetXML">virSecretSetXML</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * secret_id, <br/> const char * xml); int <a href="#virDomainSave">virDomainSave</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br/> const char * to); int <a href="#virDomainCreate">virDomainCreate</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain); int <a href="#virConnectListDomains">virConnectListDomains</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> int * ids, <br/> int maxids); int <a href="#virDomainCoreDump">virDomainCoreDump</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br/> const char * to, <br/> int flags); int <a href="#virDomainSetMemory">virDomainSetMemory</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br/> unsigned long memory); +int <a href="#virSecretDelete">virSecretDelete</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * secret_id); const char * <a href="#virInterfaceGetName">virInterfaceGetName</a> (<a href="libvirt-libvirt.html#virInterfacePtr">virInterfacePtr</a> iface); int <a href="#virStoragePoolCreate">virStoragePoolCreate</a> (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br/> unsigned int flags); int <a href="#virNodeGetInfo">virNodeGetInfo</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> <a href="libvirt-libvirt.html#virNodeInfoPtr">virNodeInfoPtr</a> info); int <a href="#virNetworkSetAutostart">virNetworkSetAutostart</a> (<a href="libvirt-libvirt.html#virNetworkPtr">virNetworkPtr</a> network, <br/> int autostart); unsigned long <a href="#virDomainGetMaxMemory">virDomainGetMaxMemory</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain); int <a href="#virStoragePoolFree">virStoragePoolFree</a> (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool); +int <a href="#virConnectNumOfDefinedInterfaces">virConnectNumOfDefinedInterfaces</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn); typedef void <a href="#virFreeCallback">virFreeCallback</a> (void * opaque); <a href="libvirt-libvirt.html#virNetworkPtr">virNetworkPtr</a> <a href="#virNetworkDefineXML">virNetworkDefineXML</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * xml); int <a href="#virNodeDeviceListCaps">virNodeDeviceListCaps</a> (<a href="libvirt-libvirt.html#virNodeDevicePtr">virNodeDevicePtr</a> dev, <br/> char ** const names, <br/> int maxnames); @@ -209,8 +213,10 @@ char * <a href="#virConnectFindStoragePoolSources">virConnectFindStoragePoolSour int <a href="#virDomainPinVcpu">virDomainPinVcpu</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br/> unsigned int vcpu, <br/> unsigned char * cpumap, <br/> int maplen); int <a href="#virNodeGetSecurityModel">virNodeGetSecurityModel</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> <a href="libvirt-libvirt.html#virSecurityModelPtr">virSecurityModelPtr</a> secmodel); int <a href="#virDomainRestore">virDomainRestore</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * from); +char * <a href="#virSecretAllocateID">virSecretAllocateID</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn); int <a href="#virNodeDeviceDestroy">virNodeDeviceDestroy</a> (<a href="libvirt-libvirt.html#virNodeDevicePtr">virNodeDevicePtr</a> dev); char * <a href="#virStorageVolGetPath">virStorageVolGetPath</a> (<a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> vol); +char * <a href="#virSecretGetXML">virSecretGetXML</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * secret_id); <a href="libvirt-libvirt.html#virNetworkPtr">virNetworkPtr</a> <a href="#virNetworkLookupByUUIDString">virNetworkLookupByUUIDString</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * uuidstr); typedef int <a href="#virConnectDomainEventCallback">virConnectDomainEventCallback</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> <a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> dom, <br/> int event, <br/> int detail, <br/> void * opaque); <a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> <a href="#virDomainLookupByID">virDomainLookupByID</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> int id); @@ -223,6 +229,7 @@ int <a href="#virConnectListDefinedNetworks">virConnectListDefinedNetworks</a> ( int <a href="#virConnectRef">virConnectRef</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn); int <a href="#virDomainGetUUID">virDomainGetUUID</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br/> unsigned char * uuid); <a href="libvirt-libvirt.html#virNetworkPtr">virNetworkPtr</a> <a href="#virNetworkCreateXML">virNetworkCreateXML</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * xmlDesc); +int <a href="#virNetworkUndefine">virNetworkUndefine</a> (<a href="libvirt-libvirt.html#virNetworkPtr">virNetworkPtr</a> network); int <a href="#virConnectDomainEventRegister">virConnectDomainEventRegister</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> <a href="libvirt-libvirt.html#virConnectDomainEventCallback">virConnectDomainEventCallback</a> cb, <br/> void * opaque, <br/> <a href="libvirt-libvirt.html#virFreeCallback">virFreeCallback</a> freecb); int <a href="#virDomainGetVcpus">virDomainGetVcpus</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br/> <a href="libvirt-libvirt.html#virVcpuInfoPtr">virVcpuInfoPtr</a> info, <br/> int maxinfo, <br/> unsigned char * cpumaps, <br/> int maplen); <a href="libvirt-libvirt.html#virNodeDevicePtr">virNodeDevicePtr</a> <a href="#virNodeDeviceLookupByName">virNodeDeviceLookupByName</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * name); @@ -230,7 +237,7 @@ int <a href="#virStoragePoolGetInfo">virStoragePoolGetInfo</a> (<a href="libvir int <a href="#virDomainResume">virDomainResume</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain); int <a href="#virInterfaceRef">virInterfaceRef</a> (<a href="libvirt-libvirt.html#virInterfacePtr">virInterfacePtr</a> iface); const char * <a href="#virInterfaceGetMACString">virInterfaceGetMACString</a> (<a href="libvirt-libvirt.html#virInterfacePtr">virInterfacePtr</a> iface); -int <a href="#virNetworkRef">virNetworkRef</a> (<a href="libvirt-libvirt.html#virNetworkPtr">virNetworkPtr</a> network); +int <a href="#virConnectNumOfDomains">virConnectNumOfDomains</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn); int <a href="#virStoragePoolRefresh">virStoragePoolRefresh</a> (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br/> unsigned int flags); int <a href="#virConnectNumOfDefinedDomains">virConnectNumOfDefinedDomains</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn); <a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> <a href="#virStorageVolCreateXMLFrom">virStorageVolCreateXMLFrom</a> (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br/> const char * xmldesc, <br/> <a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> clonevol, <br/> unsigned int flags); @@ -254,7 +261,7 @@ char * <a href="#virConnectGetURI">virConnectGetURI</a> (<a href="libvirt-libvi int <a href="#virNetworkFree">virNetworkFree</a> (<a href="libvirt-libvirt.html#virNetworkPtr">virNetworkPtr</a> network); <a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> <a href="#virStoragePoolLookupByUUID">virStoragePoolLookupByUUID</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const unsigned char * uuid); typedef int <a href="#virEventAddHandleFunc">virEventAddHandleFunc</a> (int fd, <br/> int event, <br/> <a href="libvirt-libvirt.html#virEventHandleCallback">virEventHandleCallback</a> cb, <br/> void * opaque, <br/> <a href="libvirt-libvirt.html#virFreeCallback">virFreeCallback</a> ff); -int <a href="#virNetworkUndefine">virNetworkUndefine</a> (<a href="libvirt-libvirt.html#virNetworkPtr">virNetworkPtr</a> network); +int <a href="#virNetworkRef">virNetworkRef</a> (<a href="libvirt-libvirt.html#virNetworkPtr">virNetworkPtr</a> network); int <a href="#virConnectListDefinedStoragePools">virConnectListDefinedStoragePools</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> char ** const names, <br/> int maxnames); typedef void <a href="#virEventTimeoutCallback">virEventTimeoutCallback</a> (int timer, <br/> void * opaque); int <a href="#virInterfaceFree">virInterfaceFree</a> (<a href="libvirt-libvirt.html#virInterfacePtr">virInterfacePtr</a> iface); @@ -263,11 +270,13 @@ int <a href="#virNodeDeviceNumOfCaps">virNodeDeviceNumOfCaps</a> (<a href="libv <a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> <a href="#virNetworkGetConnect">virNetworkGetConnect</a> (<a href="libvirt-libvirt.html#virNetworkPtr">virNetworkPtr</a> net); unsigned long long <a href="#virNodeGetFreeMemory">virNodeGetFreeMemory</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn); int <a href="#virInterfaceDestroy">virInterfaceDestroy</a> (<a href="libvirt-libvirt.html#virInterfacePtr">virInterfacePtr</a> iface, <br/> unsigned int flags); +int <a href="#virSecretSetValue">virSecretSetValue</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * secret_id, <br/> const void * secret, <br/> size_t secret_size); <a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> <a href="#virStorageVolGetConnect">virStorageVolGetConnect</a> (<a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> vol); int <a href="#virNodeNumOfDevices">virNodeNumOfDevices</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * cap, <br/> unsigned int flags); int <a href="#virStoragePoolDestroy">virStoragePoolDestroy</a> (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool); <a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> <a href="#virStoragePoolLookupByVolume">virStoragePoolLookupByVolume</a> (<a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> vol); <a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> <a href="#virDomainLookupByUUID">virDomainLookupByUUID</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const unsigned char * uuid); +int <a href="#virSecretListSecrets">virSecretListSecrets</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> char ** ids, <br/> int maxids); char * <a href="#virDomainGetOSType">virDomainGetOSType</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain); int <a href="#virStoragePoolBuild">virStoragePoolBuild</a> (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br/> unsigned int flags); int <a href="#virConnectGetMaxVcpus">virConnectGetMaxVcpus</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * type); @@ -289,6 +298,7 @@ typedef int <a href="#virEventAddTimeoutFunc">virEventAddTimeoutFunc</a> (int t <a href="libvirt-libvirt.html#virInterfacePtr">virInterfacePtr</a> <a href="#virInterfaceLookupByName">virInterfaceLookupByName</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * name); int <a href="#virDomainInterfaceStats">virDomainInterfaceStats</a> (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> dom, <br/> const char * path, <br/> <a href="libvirt-libvirt.html#virDomainInterfaceStatsPtr">virDomainInterfaceStatsPtr</a> stats, <br/> size_t size); int <a href="#virConnectListNetworks">virConnectListNetworks</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> char ** const names, <br/> int maxnames); +void * <a href="#virSecretGetValue">virSecretGetValue</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * secret_id, <br/> size_t * secret_size); <a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> <a href="#virStorageVolLookupByKey">virStorageVolLookupByKey</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * key); </pre> </div> @@ -527,7 +537,8 @@ The content of this structure is not made public by the API. </div> <hr/> <div class="refsect2" lang="en"><h3><a name="virDomainMemoryFlags">Enum </a>virDomainMemoryFlags</h3><pre class="programlisting">enum <a href="#virDomainMemoryFlags">virDomainMemoryFlags</a> { - <a name="VIR_MEMORY_VIRTUAL">VIR_MEMORY_VIRTUAL</a> = 1 /* addresses are virtual addresses */ + <a name="VIR_MEMORY_VIRTUAL">VIR_MEMORY_VIRTUAL</a> = 1 /* addresses are virtual addresses */ + <a name="VIR_MEMORY_PHYSICAL">VIR_MEMORY_PHYSICAL</a> = 2 /* addresses are physical addresses */ }; </pre><p/> </div> @@ -863,6 +874,10 @@ The content of this structure is not made public by the API. </pre><p>list the defined but inactive domains, stores the pointers to the names in @names</p> <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>pointer to an array to store the names</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of the array</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of names provided in the array or -1 in case of error</td></tr></tbody></table></div></div> <hr/> + <div class="refsect2" lang="en"><h3><a name="virConnectListDefinedInterfaces"/>virConnectListDefinedInterfaces ()</h3><pre class="programlisting">int virConnectListDefinedInterfaces (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> char ** const names, <br/> int maxnames)<br/> +</pre><p>Collect the list of defined (inactive) physical host interfaces, and store their names in @names.</p> +<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>array to collect the list of names of interfaces</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of @names</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of interfaces found or -1 in case of error</td></tr></tbody></table></div></div> + <hr/> <div class="refsect2" lang="en"><h3><a name="virConnectListDefinedNetworks"/>virConnectListDefinedNetworks ()</h3><pre class="programlisting">int virConnectListDefinedNetworks (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> char ** const names, <br/> int maxnames)<br/> </pre><p>list the inactive networks, stores the pointers to the names in @names</p> <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>pointer to an array to store the names</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of the array</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of names provided in the array or -1 in case of error</td></tr></tbody></table></div></div> @@ -876,7 +891,7 @@ The content of this structure is not made public by the API. <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>ids</tt></i>:</span></td><td>array to collect the list of IDs of active domains</td></tr><tr><td><span class="term"><i><tt>maxids</tt></i>:</span></td><td>size of @ids</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of domain found or -1 in case of error</td></tr></tbody></table></div></div> <hr/> <div class="refsect2" lang="en"><h3><a name="virConnectListInterfaces"/>virConnectListInterfaces ()</h3><pre class="programlisting">int virConnectListInterfaces (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> char ** const names, <br/> int maxnames)<br/> -</pre><p>Collect the list of physical host interfaces, and store their names in @names</p> +</pre><p>Collect the list of active physical host interfaces, and store their names in @names</p> <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>array to collect the list of names of interfaces</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of @names</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of interfaces found or -1 in case of error</td></tr></tbody></table></div></div> <hr/> <div class="refsect2" lang="en"><h3><a name="virConnectListNetworks"/>virConnectListNetworks ()</h3><pre class="programlisting">int virConnectListNetworks (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> char ** const names, <br/> int maxnames)<br/> @@ -891,6 +906,10 @@ The content of this structure is not made public by the API. </pre><p>Provides the number of defined but inactive domains.</p> <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of domain found or -1 in case of error</td></tr></tbody></table></div></div> <hr/> + <div class="refsect2" lang="en"><h3><a name="virConnectNumOfDefinedInterfaces"/>virConnectNumOfDefinedInterfaces ()</h3><pre class="programlisting">int virConnectNumOfDefinedInterfaces (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br/> +</pre><p>Provides the number of defined (inactive) interfaces on the physical host.</p> +<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of defined interface found or -1 in case of error</td></tr></tbody></table></div></div> + <hr/> <div class="refsect2" lang="en"><h3><a name="virConnectNumOfDefinedNetworks"/>virConnectNumOfDefinedNetworks ()</h3><pre class="programlisting">int virConnectNumOfDefinedNetworks (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br/> </pre><p>Provides the number of inactive networks.</p> <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of networks found or -1 in case of error</td></tr></tbody></table></div></div> @@ -904,8 +923,8 @@ The content of this structure is not made public by the API. <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of domain found or -1 in case of error</td></tr></tbody></table></div></div> <hr/> <div class="refsect2" lang="en"><h3><a name="virConnectNumOfInterfaces"/>virConnectNumOfInterfaces ()</h3><pre class="programlisting">int virConnectNumOfInterfaces (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br/> -</pre><p>Provides the number of interfaces on the physical host.</p> -<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of interface found or -1 in case of error</td></tr></tbody></table></div></div> +</pre><p>Provides the number of active interfaces on the physical host.</p> +<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of active interfaces found or -1 in case of error</td></tr></tbody></table></div></div> <hr/> <div class="refsect2" lang="en"><h3><a name="virConnectNumOfNetworks"/>virConnectNumOfNetworks ()</h3><pre class="programlisting">int virConnectNumOfNetworks (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br/> </pre><p>Provides the number of active networks.</p> @@ -917,14 +936,14 @@ The content of this structure is not made public by the API. <hr/> <div class="refsect2" lang="en"><h3><a name="virConnectOpen"/>virConnectOpen ()</h3><pre class="programlisting"><a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> virConnectOpen (const char * name)<br/> </pre><p>This function should be called first to get a connection to the Hypervisor and xen store</p> -<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>name</tt></i>:</span></td><td>URI of the hypervisor</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the hypervisor connection or NULL in case of error URIs are documented at http://libvirt.org/uri.html</td></tr></tbody></table></div></div> +<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>name</tt></i>:</span></td><td>URI of the hypervisor</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the hypervisor connection or NULL in case of error If @name is NULL then probing will be done to determine a suitable default driver to activate. This involves trying each hypervisor in turn until one successfully opens. If the LIBVIRT_DEFAULT_URI environment variable is set, then it will be used in preference to probing for a driver. If connecting to an unprivileged hypervisor driver which requires the libvirtd daemon to be active, it will automatically be launched if not already running. This can be prevented by setting the environment variable LIBVIRT_AUTOSTART=0 URIs are documented at http://libvirt.org/uri.html</td></tr></tbody></table></div></div> <hr/> <div class="refsect2" lang="en"><h3><a name="virConnectOpenAuth"/>virConnectOpenAuth ()</h3><pre class="programlisting"><a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> virConnectOpenAuth (const char * name, <br/> <a href="libvirt-libvirt.html#virConnectAuthPtr">virConnectAuthPtr</a> auth, <br/> int flags)<br/> -</pre><p>This function should be called first to get a connection to the Hypervisor. If necessary, authentication will be performed fetching credentials via the callback</p> +</pre><p>This function should be called first to get a connection to the Hypervisor. If necessary, authentication will be performed fetching credentials via the callback See <a href="libvirt-libvirt.html#virConnectOpen">virConnectOpen</a> for notes about environment variables which can have an effect on opening drivers</p> <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>name</tt></i>:</span></td><td>URI of the hypervisor</td></tr><tr><td><span class="term"><i><tt>auth</tt></i>:</span></td><td>Authenticate callback parameters</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>Open flags</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the hypervisor connection or NULL in case of error URIs are documented at http://libvirt.org/uri.html</td></tr></tbody></table></div></div> <hr/> <div class="refsect2" lang="en"><h3><a name="virConnectOpenReadOnly"/>virConnectOpenReadOnly ()</h3><pre class="programlisting"><a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> virConnectOpenReadOnly (const char * name)<br/> -</pre><p>This function should be called first to get a restricted connection to the library functionalities. The set of APIs usable are then restricted on the available methods to control the domains.</p> +</pre><p>This function should be called first to get a restricted connection to the library functionalities. The set of APIs usable are then restricted on the available methods to control the domains. See <a href="libvirt-libvirt.html#virConnectOpen">virConnectOpen</a> for notes about environment variables which can have an effect on opening drivers</p> <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>name</tt></i>:</span></td><td>URI of the hypervisor</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the hypervisor connection or NULL in case of error URIs are documented at http://libvirt.org/uri.html</td></tr></tbody></table></div></div> <hr/> <div class="refsect2" lang="en"><h3><a name="virConnectRef"/>virConnectRef ()</h3><pre class="programlisting">int virConnectRef (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br/> @@ -1327,6 +1346,38 @@ The content of this structure is not made public by the API. </pre><p>Provides the number of node devices. If the optional 'cap' argument is non-NULL, then the count will be restricted to devices with the specified capability</p> <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>cap</tt></i>:</span></td><td>capability name</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>flags (unused, pass 0)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of node devices or -1 in case of error</td></tr></tbody></table></div></div> <hr/> + <div class="refsect2" lang="en"><h3><a name="virSecretAllocateID"/>virSecretAllocateID ()</h3><pre class="programlisting">char * virSecretAllocateID (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br/> +</pre><p>Allocates a secret ID (a printable string) without associating a secret value with the ID.</p> +<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the secret ID on success, or NULL on failure. The caller must free() the secret ID.</td></tr></tbody></table></div></div> + <hr/> + <div class="refsect2" lang="en"><h3><a name="virSecretDelete"/>virSecretDelete ()</h3><pre class="programlisting">int virSecretDelete (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * secret_id)<br/> +</pre><p>Deletes the secret with secret_id (including the secret value and all attributes).</p> +<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>secret_id</tt></i>:</span></td><td>A secret ID</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, -1 on failure.</td></tr></tbody></table></div></div> + <hr/> + <div class="refsect2" lang="en"><h3><a name="virSecretGetValue"/>virSecretGetValue ()</h3><pre class="programlisting">void * virSecretGetValue (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * secret_id, <br/> size_t * secret_size)<br/> +</pre><p>Fetches the secret value associated with secret_id.</p> +<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>secret_id</tt></i>:</span></td><td>A secret ID</td></tr><tr><td><span class="term"><i><tt>secret_size</tt></i>:</span></td><td>Place for storing size of the secret</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the secret value on success, NULL on failure. The caller must free() the secret value.</td></tr></tbody></table></div></div> + <hr/> + <div class="refsect2" lang="en"><h3><a name="virSecretGetXML"/>virSecretGetXML ()</h3><pre class="programlisting">char * virSecretGetXML (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * secret_id)<br/> +</pre><p>Fetches an XML document describing attributes of the secret.</p> +<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>secret_id</tt></i>:</span></td><td>A secret ID</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the XML document on success, NULL on failure. The caller must free() the XML.</td></tr></tbody></table></div></div> + <hr/> + <div class="refsect2" lang="en"><h3><a name="virSecretListSecrets"/>virSecretListSecrets ()</h3><pre class="programlisting">int virSecretListSecrets (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> char ** ids, <br/> int maxids)<br/> +</pre><p>List the defined secret IDs, store pointers to names in ids.</p> +<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>ids</tt></i>:</span></td><td>Pointer to an array to store the IDs</td></tr><tr><td><span class="term"><i><tt>maxids</tt></i>:</span></td><td>size of the array.</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of IDs provided in the array, or -1 on failure.</td></tr></tbody></table></div></div> + <hr/> + <div class="refsect2" lang="en"><h3><a name="virSecretNumOfSecrets"/>virSecretNumOfSecrets ()</h3><pre class="programlisting">int virSecretNumOfSecrets (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br/> +</pre><p>Fetch number of currently defined secret IDs.</p> +<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number currently defined secret IDs.</td></tr></tbody></table></div></div> + <hr/> + <div class="refsect2" lang="en"><h3><a name="virSecretSetValue"/>virSecretSetValue ()</h3><pre class="programlisting">int virSecretSetValue (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * secret_id, <br/> const void * secret, <br/> size_t secret_size)<br/> +</pre><p>Associates a secret value with secret_id. Allocates secret_id if it was not previously allocated.</p> +<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>secret_id</tt></i>:</span></td><td>A secret ID</td></tr><tr><td><span class="term"><i><tt>secret</tt></i>:</span></td><td>The secret</td></tr><tr><td><span class="term"><i><tt>secret_size</tt></i>:</span></td><td>Size of the secret</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, -1 on failure.</td></tr></tbody></table></div></div> + <hr/> + <div class="refsect2" lang="en"><h3><a name="virSecretSetXML"/>virSecretSetXML ()</h3><pre class="programlisting">int virSecretSetXML (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br/> const char * secret_id, <br/> const char * xml)<br/> +</pre><p>Replaces all attributes of the secret specified by secret_id by attributes specified in xml (any attributes not specified in xml are discarded). Allocates secret_id if it was not previously allocated.</p> +<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>secret_id</tt></i>:</span></td><td>A secret ID</td></tr><tr><td><span class="term"><i><tt>xml</tt></i>:</span></td><td>XML containing attributes of the secret.</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, -1 on failure.</td></tr></tbody></table></div></div> + <hr/> <div class="refsect2" lang="en"><h3><a name="virStoragePoolBuild"/>virStoragePoolBuild ()</h3><pre class="programlisting">int virStoragePoolBuild (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br/> unsigned int flags)<br/> </pre><p>Build the underlying storage pool</p> <div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>pool</tt></i>:</span></td><td>pointer to storage pool</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>future flags, use 0 for now</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, or -1 upon failure</td></tr></tbody></table></div></div> @@ -1421,7 +1472,7 @@ The content of this structure is not made public by the API. <hr/> <div class="refsect2" lang="en"><h3><a name="virStoragePoolUndefine"/>virStoragePoolUndefine ()</h3><pre class="programlisting">int virStoragePoolUndefine (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool)<br/> </pre><p>Undefine an inactive storage pool</p> -<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>pool</tt></i>:</span></td><td>pointer to storage pool</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a <a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> object, or NULL if creation failed</td></tr></tbody></table></div></div> +<div class="variablelist"><table border="0"><col align="left"/><tbody><tr><td><span class="term"><i><tt>pool</tt></i>:</span></td><td>pointer to storage pool</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, -1 on failure</td></tr></tbody></table></div></div> <hr/> <div class="refsect2" lang="en"><h3><a name="virStorageVolCreateXML"/>virStorageVolCreateXML ()</h3><pre class="programlisting"><a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> virStorageVolCreateXML (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br/> const char * xmldesc, <br/> unsigned int flags)<br/> </pre><p>Create a storage volume within a pool based on an XML description. Not all pools support creation of volumes</p> diff --git a/docs/devhelp/libvirt-virterror.html b/docs/devhelp/libvirt-virterror.html index 9f2efae..9107731 100644 --- a/docs/devhelp/libvirt-virterror.html +++ b/docs/devhelp/libvirt-virterror.html @@ -109,7 +109,10 @@ void <a href="#virConnResetLastError">virConnResetLastError</a> (<a href="libvi <a name="VIR_FROM_SECURITY">VIR_FROM_SECURITY</a> = 24 /* Error from security framework */ <a name="VIR_FROM_VBOX">VIR_FROM_VBOX</a> = 25 /* Error from VirtualBox driver */ <a name="VIR_FROM_INTERFACE">VIR_FROM_INTERFACE</a> = 26 /* Error when operating on an interface */ - <a name="VIR_FROM_ONE">VIR_FROM_ONE</a> = 27 /* Error from OpenNebula driver */ + <a name="VIR_FROM_ONE">VIR_FROM_ONE</a> = 27 /* Error from OpenNebula driver */ + <a name="VIR_FROM_ESX">VIR_FROM_ESX</a> = 28 /* Error from ESX driver */ + <a name="VIR_FROM_PHYP">VIR_FROM_PHYP</a> = 29 /* Error from IBM power hypervisor */ + <a name="VIR_FROM_SECRET">VIR_FROM_SECRET</a> = 30 /* Error from secret storage */ }; </pre><p/> </div> @@ -181,7 +184,11 @@ void <a href="#virConnResetLastError">virConnResetLastError</a> (<a href="libvi <a name="VIR_ERR_OPERATION_INVALID">VIR_ERR_OPERATION_INVALID</a> = 55 /* operation is not applicable at this time */ <a name="VIR_WAR_NO_INTERFACE">VIR_WAR_NO_INTERFACE</a> = 56 /* failed to start interface driver */ <a name="VIR_ERR_NO_INTERFACE">VIR_ERR_NO_INTERFACE</a> = 57 /* interface driver not running */ - <a name="VIR_ERR_INVALID_INTERFACE">VIR_ERR_INVALID_INTERFACE</a> = 58 /* invalid interface object */ + <a name="VIR_ERR_INVALID_INTERFACE">VIR_ERR_INVALID_INTERFACE</a> = 58 /* invalid interface object */ + <a name="VIR_ERR_MULTIPLE_INTERFACES">VIR_ERR_MULTIPLE_INTERFACES</a> = 59 /* more than one matching interface found */ + <a name="VIR_WAR_NO_SECRET">VIR_WAR_NO_SECRET</a> = 60 /* failed to start secret storage */ + <a name="VIR_ERR_NO_SECRET">VIR_ERR_NO_SECRET</a> = 61 /* secret not found */ + <a name="VIR_ERR_INVALID_SECRET">VIR_ERR_INVALID_SECRET</a> = 62 /* invalid secret */ }; </pre><p/> </div> diff --git a/docs/html/libvirt-libvirt.html b/docs/html/libvirt-libvirt.html index 3eba3ad..766a57c 100644 --- a/docs/html/libvirt-libvirt.html +++ b/docs/html/libvirt-libvirt.html @@ -96,6 +96,7 @@ const char * <a href="#virConnectGetType">virConnectGetType</a> (<a href="libvir char * <a href="#virConnectGetURI">virConnectGetURI</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn) int <a href="#virConnectGetVersion">virConnectGetVersion</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> unsigned long * hvVer) int <a href="#virConnectListDefinedDomains">virConnectListDefinedDomains</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames) +int <a href="#virConnectListDefinedInterfaces">virConnectListDefinedInterfaces</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames) int <a href="#virConnectListDefinedNetworks">virConnectListDefinedNetworks</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames) int <a href="#virConnectListDefinedStoragePools">virConnectListDefinedStoragePools</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames) int <a href="#virConnectListDomains">virConnectListDomains</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> int * ids, <br /> int maxids) @@ -103,6 +104,7 @@ int <a href="#virConnectListInterfaces">virConnectListInterfaces</a> (<a href="l int <a href="#virConnectListNetworks">virConnectListNetworks</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames) int <a href="#virConnectListStoragePools">virConnectListStoragePools</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames) int <a href="#virConnectNumOfDefinedDomains">virConnectNumOfDefinedDomains</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn) +int <a href="#virConnectNumOfDefinedInterfaces">virConnectNumOfDefinedInterfaces</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn) int <a href="#virConnectNumOfDefinedNetworks">virConnectNumOfDefinedNetworks</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn) int <a href="#virConnectNumOfDefinedStoragePools">virConnectNumOfDefinedStoragePools</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn) int <a href="#virConnectNumOfDomains">virConnectNumOfDomains</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn) @@ -239,6 +241,14 @@ int <a href="#virNodeGetInfo">virNodeGetInfo</a> (<a href="libvirt-libvirt.htm int <a href="#virNodeGetSecurityModel">virNodeGetSecurityModel</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> <a href="libvirt-libvirt.html#virSecurityModelPtr">virSecurityModelPtr</a> secmodel) int <a href="#virNodeListDevices">virNodeListDevices</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * cap, <br /> char ** const names, <br /> int maxnames, <br /> unsigned int flags) int <a href="#virNodeNumOfDevices">virNodeNumOfDevices</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * cap, <br /> unsigned int flags) +char * <a href="#virSecretAllocateID">virSecretAllocateID</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn) +int <a href="#virSecretDelete">virSecretDelete</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * secret_id) +void * <a href="#virSecretGetValue">virSecretGetValue</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * secret_id, <br /> size_t * secret_size) +char * <a href="#virSecretGetXML">virSecretGetXML</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * secret_id) +int <a href="#virSecretListSecrets">virSecretListSecrets</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** ids, <br /> int maxids) +int <a href="#virSecretNumOfSecrets">virSecretNumOfSecrets</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn) +int <a href="#virSecretSetValue">virSecretSetValue</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * secret_id, <br /> const void * secret, <br /> size_t secret_size) +int <a href="#virSecretSetXML">virSecretSetXML</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * secret_id, <br /> const char * xml) int <a href="#virStoragePoolBuild">virStoragePoolBuild</a> (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br /> unsigned int flags) int <a href="#virStoragePoolCreate">virStoragePoolCreate</a> (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br /> unsigned int flags) <a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> <a href="#virStoragePoolCreateXML">virStoragePoolCreateXML</a> (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * xmlDesc, <br /> unsigned int flags) @@ -319,7 +329,7 @@ int <a href="#virStorageVolRef">virStorageVolRef</a> (<a href="libvirt-libvirt. </pre><table><tr><td>long long</td><td>rx_bytes</td></tr><tr><td>long long</td><td>rx_packets</td></tr><tr><td>long long</td><td>rx_errs</td></tr><tr><td>long long</td><td>rx_drop</td></tr><tr><td>long long</td><td>tx_bytes</td></tr><tr><td>long long</td><td>tx_packets</td></tr><tr><td>long long</td><td>tx_errs</td></tr><tr><td>long long</td><td>tx_drop</td></tr></table><pre> } </pre></div><h3><a name="virDomainMemoryFlags" id="virDomainMemoryFlags"><code>virDomainMemoryFlags</code></a></h3><div class="api"><pre>enum virDomainMemoryFlags { -</pre><table><tr><td><a name="VIR_MEMORY_VIRTUAL" id="VIR_MEMORY_VIRTUAL">VIR_MEMORY_VIRTUAL</a></td><td> = </td><td>1</td><td> : addresses are virtual addresses</td></tr></table><pre>} +</pre><table><tr><td><a name="VIR_MEMORY_VIRTUAL" id="VIR_MEMORY_VIRTUAL">VIR_MEMORY_VIRTUAL</a></td><td> = </td><td>1</td><td> : addresses are virtual addresses</td></tr><tr><td><a name="VIR_MEMORY_PHYSICAL" id="VIR_MEMORY_PHYSICAL">VIR_MEMORY_PHYSICAL</a></td><td> = </td><td>2</td><td> : addresses are physical addresses</td></tr></table><pre>} </pre></div><h3><a name="virDomainMigrateFlags" id="virDomainMigrateFlags"><code>virDomainMigrateFlags</code></a></h3><div class="api"><pre>enum virDomainMigrateFlags { </pre><table><tr><td><a name="VIR_MIGRATE_LIVE" id="VIR_MIGRATE_LIVE">VIR_MIGRATE_LIVE</a></td><td> = </td><td>1</td><td> : live migration</td></tr></table><pre>} </pre></div><h3><a name="virDomainState" id="virDomainState"><code>virDomainState</code></a></h3><div class="api"><pre>enum virDomainState { @@ -393,23 +403,25 @@ int <a href="#virStorageVolRef">virStorageVolRef</a> (<a href="libvirt-libvirt. </pre><p>Get the name of the Hypervisor software used.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>NULL in case of error, a static zero terminated string otherwise. See also: http://www.redhat.com/archives/libvir-list/2007-February/msg00096.html</td></tr></tbody></table></div><h3><a name="virConnectGetURI" id="virConnectGetURI"><code>virConnectGetURI</code></a></h3><pre class="programlisting">char * virConnectGetURI (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> </pre><p>This returns the URI (name) of the hypervisor connection. Normally this is the same as or similar to the string passed to the virConnectOpen/virConnectOpenReadOnly call, but the driver may make the URI canonical. If name == NULL was passed to virConnectOpen, then the driver will return a non-NULL URI which can be used to connect to the same hypervisor later.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to a hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the URI string which must be freed by the caller, or NULL if there was an error.</td></tr></tbody></table></div><h3><a name="virConnectGetVersion" id="virConnectGetVersion"><code>virConnectGetVersion</code></a></h3><pre class="programlisting">int virConnectGetVersion (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> unsigned long * hv! Ver)<br /> </pre><p>Get the version level of the Hypervisor running. This may work only with hypervisor call, i.e. with privileged access to the hypervisor, not with a Read-Only connection.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>hvVer</tt></i>:</span></td><td>return value for the version of the running hypervisor (OUT)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>-1 in case of error, 0 otherwise. if the version can't be extracted by lack of capacities returns 0 and @hvVer is 0, otherwise @hvVer value is major * 1,000,000 + minor * 1,000 + release</td></tr></tbody></table></div><h3><a name="virConnectListDefinedDomains" id="virConnectListDefinedDomains"><code>virConnectListDefinedDomains</code></a></h3><pre class="programlisting">int virConnectListDefinedDomains (<a href="libvirt! -libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)<br /> -</pre><p>list the defined but inactive domains, stores the pointers to the names in @names</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>pointer to an array to store the names</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of the array</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of names provided in the array or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectListDefinedNetworks" id="virConnectListDefinedNetworks"><code>virConnectListDefinedNetworks</code></a></h3><pre class="programlisting">int virConnectListDefinedNetworks (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)<br /> +</pre><p>list the defined but inactive domains, stores the pointers to the names in @names</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>pointer to an array to store the names</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of the array</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of names provided in the array or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectListDefinedInterfaces" id="virConnectListDefinedInterfaces"><code>virConnectListDefinedInterfaces</code></a></h3><pre class="programlisting">int virConnectListDefinedInterfaces (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)<br /> +</pre><p>Collect the list of defined (inactive) physical host interfaces, and store their names in @names.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>array to collect the list of names of interfaces</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of @names</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of interfaces found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectListDefinedNetworks" id="virConnectListDefinedNetworks"><code>virConnectListDefinedNetworks</code></a></h3><pre class="programlisting">int virConnectListDefinedNetworks (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)<br /> </pre><p>list the inactive networks, stores the pointers to the names in @names</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>pointer to an array to store the names</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of the array</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of names provided in the array or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectListDefinedStoragePools" id="virConnectListDefinedStoragePools"><code>virConnectListDefinedStoragePools</code></a></h3><pre class="programlisting">int virConnectListDefinedStoragePools (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)<br /> </pre><p>Provides the list of names of inactive storage pools upto maxnames. If there are more than maxnames, the remaining names will be silently ignored.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>array of char * to fill with pool names (allocated by caller)</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of the names array</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, -1 on error</td></tr></tbody></table></div><h3><a name="virConnectListDomains" id="virConnectListDomains"><code>virConnectListDomains</code></a></h3><pre class="programlisting">int virConnectListDomains (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> int * ids, <br /> int maxids)<br /> </pre><p>Collect the list of active domains, and store their ID in @maxids</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>ids</tt></i>:</span></td><td>array to collect the list of IDs of active domains</td></tr><tr><td><span class="term"><i><tt>maxids</tt></i>:</span></td><td>size of @ids</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of domain found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectListInterfaces" id="virConnectListInterfaces"><code>virConnectListInterfaces</code></a></h3><pre class="programlisting">int virConnectListInterfaces (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)<br /> -</pre><p>Collect the list of physical host interfaces, and store their names in @names</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>array to collect the list of names of interfaces</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of @names</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of interfaces found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectListNetworks" id="virConnectListNetworks"><code>virConnectListNetworks</code></a></h3><pre class="programlisting">int virConnectListNetworks (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)<br /> +</pre><p>Collect the list of active physical host interfaces, and store their names in @names</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>array to collect the list of names of interfaces</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of @names</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of interfaces found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectListNetworks" id="virConnectListNetworks"><code>virConnectListNetworks</code></a></h3><pre class="programlisting">int virConnectListNetworks (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)<br /> </pre><p>Collect the list of active networks, and store their names in @names</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>array to collect the list of names of active networks</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of @names</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of networks found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectListStoragePools" id="virConnectListStoragePools"><code>virConnectListStoragePools</code></a></h3><pre class="programlisting">int virConnectListStoragePools (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** const names, <br /> int maxnames)<br /> </pre><p>Provides the list of names of active storage pools upto maxnames. If there are more than maxnames, the remaining names will be silently ignored.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to hypervisor connection</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>array of char * to fill with pool names (allocated by caller)</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of the names array</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, -1 on error</td></tr></tbody></table></div><h3><a name="virConnectNumOfDefinedDomains" id="virConnectNumOfDefinedDomains"><code>virConnectNumOfDefinedDomains</code></a></h3><pre class="programlisting">int virConnectNumOfDefinedDomains (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> -</pre><p>Provides the number of defined but inactive domains.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of domain found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectNumOfDefinedNetworks" id="virConnectNumOfDefinedNetworks"><code>virConnectNumOfDefinedNetworks</code></a></h3><pre class="programlisting">int virConnectNumOfDefinedNetworks (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> +</pre><p>Provides the number of defined but inactive domains.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of domain found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectNumOfDefinedInterfaces" id="virConnectNumOfDefinedInterfaces"><code>virConnectNumOfDefinedInterfaces</code></a></h3><pre class="programlisting">int virConnectNumOfDefinedInterfaces (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> +</pre><p>Provides the number of defined (inactive) interfaces on the physical host.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of defined interface found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectNumOfDefinedNetworks" id="virConnectNumOfDefinedNetworks"><code>virConnectNumOfDefinedNetworks</code></a></h3><pre class="programlisting">int virConnectNumOfDefinedNetworks (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> </pre><p>Provides the number of inactive networks.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of networks found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectNumOfDefinedStoragePools" id="virConnectNumOfDefinedStoragePools"><code>virConnectNumOfDefinedStoragePools</code></a></h3><pre class="programlisting">int virConnectNumOfDefinedStoragePools (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> </pre><p>Provides the number of inactive storage pools</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of pools found, or -1 on error</td></tr></tbody></table></div><h3><a name="virConnectNumOfDomains" id="virConnectNumOfDomains"><code>virConnectNumOfDomains</code></a></h3><pre class="programlisting">int virConnectNumOfDomains (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> </pre><p>Provides the number of active domains.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of domain found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectNumOfInterfaces" id="virConnectNumOfInterfaces"><code>virConnectNumOfInterfaces</code></a></h3><pre class="programlisting">int virConnectNumOfInterfaces (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> -</pre><p>Provides the number of interfaces on the physical host.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of interface found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectNumOfNetworks" id="virConnectNumOfNetworks"><code>virConnectNumOfNetworks</code></a></h3><pre class="programlisting">int virConnectNumOfNetworks (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> +</pre><p>Provides the number of active interfaces on the physical host.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of active interfaces found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectNumOfNetworks" id="virConnectNumOfNetworks"><code>virConnectNumOfNetworks</code></a></h3><pre class="programlisting">int virConnectNumOfNetworks (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> </pre><p>Provides the number of active networks.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of network found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virConnectNumOfStoragePools" id="virConnectNumOfStoragePools"><code>virConnectNumOfStoragePools</code></a></h3><pre class="programlisting">int virConnectNumOfStoragePools (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> </pre><p>Provides the number of active storage pools</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of pools found, or -1 on error</td></tr></tbody></table></div><h3><a name="virConnectOpen" id="virConnectOpen"><code>virConnectOpen</code></a></h3><pre class="programlisting"><a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> virConnectOpen (const char * name)<br /> -</pre><p>This function should be called first to get a connection to the Hypervisor and xen store</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>name</tt></i>:</span></td><td>URI of the hypervisor</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the hypervisor connection or NULL in case of error URIs are documented at http://libvirt.org/uri.html</td></tr></tbody></table></div><h3><a name="virConnectOpenAuth" id="virConnectOpenAuth"><code>virConnectOpenAuth</code></a></h3><pre class="programlisting"><a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> virConnectOpenAuth (const char * name, <br /> <a href="libvirt-libvirt.html#virConnectAuthPtr">virConnectAuthPtr</a> auth, <br /> int flags)<br /> -</pre><p>This function should be called first to get a connection to the Hypervisor. If necessary, authentication will be performed fetching credentials via the callback</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>name</tt></i>:</span></td><td>URI of the hypervisor</td></tr><tr><td><span class="term"><i><tt>auth</tt></i>:</span></td><td>Authenticate callback parameters</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>Open flags</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the hypervisor connection or NULL in case of error URIs are documented at http://libvirt.org/uri.html</td></tr></tbody></table></div><h3><a name="virConnectOpenReadOnly" id="virConnectOpenReadOnly"><code>virConnectOpenReadOnly</code></a></h3><pre class="programlisting"><a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> virConnectOpenReadOnly (const char * name)<br! /> -</pre><p>This function should be called first to get a restricted connection to the library functionalities. The set of APIs usable are then restricted on the available methods to control the domains.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>name</tt></i>:</span></td><td>URI of the hypervisor</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the hypervisor connection or NULL in case of error URIs are documented at http://libvirt.org/uri.html</td></tr></tbody></table></div><h3><a name="virConnectRef" id="virConnectRef"><code>virConnectRef</code></a></h3><pre class="programlisting">int virConnectRef (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> +</pre><p>This function should be called first to get a connection to the Hypervisor and xen store</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>name</tt></i>:</span></td><td>URI of the hypervisor</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the hypervisor connection or NULL in case of error If @name is NULL then probing will be done to determine a suitable default driver to activate. This involves trying each hypervisor in turn until one successfully opens. If the LIBVIRT_DEFAULT_URI environment variable is set, then it will be used in preference to probing for a driver. If connecting to an unprivileged hypervisor driver which requires the libvirtd daemon to be active, it will automatically be launched if not already running. This can be prevented by setting the environment variable LIBVIRT_AUTOSTART=0 URIs are documented at http://libvirt.org/uri.html</td></tr></tbody>! </table></div><h3><a name="virConnectOpenAuth" id="virConnectOpenAuth"><code>virConnectOpenAuth</code></a></h3><pre class="programlisting"><a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> virConnectOpenAuth (const char * name, <br /> <a href="libvirt-libvirt.html#virConnectAuthPtr">virConnectAuthPtr</a> auth, <br /> int flags)<br /> +</pre><p>This function should be called first to get a connection to the Hypervisor. If necessary, authentication will be performed fetching credentials via the callback See <a href="libvirt-libvirt.html#virConnectOpen">virConnectOpen</a> for notes about environment variables which can have an effect on opening drivers</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>name</tt></i>:</span></td><td>URI of the hypervisor</td></tr><tr><td><span class="term"><i><tt>auth</tt></i>:</span></td><td>Authenticate callback parameters</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>Open flags</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the hypervisor connection or NULL in case of error URIs are documented at http://libvirt.org/uri.html</td></tr></tbody></table></div><h3><a name="virConnectOpenReadOnly" id="virConnectOpenReadOnly"><code>virConnectOpenReadOnly<! /code></a></h3><pre class="programlisting"><a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> virConnectOpenReadOnly (const char * name)<br /> +</pre><p>This function should be called first to get a restricted connection to the library functionalities. The set of APIs usable are then restricted on the available methods to control the domains. See <a href="libvirt-libvirt.html#virConnectOpen">virConnectOpen</a> for notes about environment variables which can have an effect on opening drivers</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>name</tt></i>:</span></td><td>URI of the hypervisor</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the hypervisor connection or NULL in case of error URIs are documented at http://libvirt.org/uri.html</td></tr></tbody></table></div><h3><a name="virConnectRef" id="virConnectRef"><code>virConnectRef</code></a></h3><pre class="programlisting">int virConnectRef (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> </pre><p>Increment the reference count on the connection. For each additional call to this method, there shall be a corresponding call to <a href="libvirt-libvirt.html#virConnectClose">virConnectClose</a> to release the reference count, once the caller no longer needs the reference to this object. This method is typically useful for applications where multiple threads are using a connection, and it is required that the connection remain open until all threads have finished using it. ie, each new thread using a connection would increment the reference count.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>the connection to hold a reference on</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 in case of success, -1 in case of failure</td></tr></tbody></table></div><h3><a name="virDomainAttachDevice" id="virDomainAttachDevice"><code>virDomainAttachDevice</code>! </a></h3><pre class="programlisting">int virDomainAttachDevice (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> domain, <br /> const char * xml)<br /> </pre><p>Create a virtual device attachment to backend.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>domain</tt></i>:</span></td><td>pointer to domain object</td></tr><tr><td><span class="term"><i><tt>xml</tt></i>:</span></td><td>pointer to XML description of one device</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 in case of success, -1 in case of failure.</td></tr></tbody></table></div><h3><a name="virDomainBlockPeek" id="virDomainBlockPeek"><code>virDomainBlockPeek</code></a></h3><pre class="programlisting">int virDomainBlockPeek (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> dom, <br /> const char * path, <br /> unsigned long long offset, <br /> size_t size, <br /> void * buffer, <br /> unsigned int flags)<br /> </pre><p>This function allows you to read the contents of a domain's disk device. Typical uses for this are to determine if the domain has written a Master Boot Record (indicating that the domain has completed installation), or to try to work out the state of the domain's filesystems. (Note that in the local case you might try to open the block device or file directly, but that won't work in the remote case, nor if you don't have sufficient permission. Hence the need for this call). 'path' must be a device or file corresponding to the domain. In other words it must be the precise string returned in a <disk><source dev='...'/></disk> from virDomainGetXMLDesc. 'offset' and 'size' represent an area which must lie entirely within the device or file. 'size' may be 0 to test if the call would succeed. 'buffer' is the return buffer and must be at least 'size' bytes. NB. The remote driver imposes a 64K byte limit on 'size'. For your program to be able to work reli! ably over a remote connection you should split large requests to <= 65536 bytes.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>dom</tt></i>:</span></td><td>pointer to the domain object</td></tr><tr><td><span class="term"><i><tt>path</tt></i>:</span></td><td>path to the block device</td></tr><tr><td><span class="term"><i><tt>offset</tt></i>:</span></td><td>offset within block device</td></tr><tr><td><span class="term"><i><tt>size</tt></i>:</span></td><td>size to read</td></tr><tr><td><span class="term"><i><tt>buffer</tt></i>:</span></td><td>return buffer (must be at least size bytes)</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>unused, always pass 0</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 in case of success or -1 in case of failure. really 64 bits</td></tr></tbody></table></div><h3><a name="virDomainBlockStats" id="virDomainBlockStats"><code>vir! DomainBlockStats</code></a></h3><pre class="programlisting">int virDom ainBlockStats (<a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a> dom, <br /> const char * path, <br /> <a href="libvirt-libvirt.html#virDomainBlockStatsPtr">virDomainBlockStatsPtr</a> stats, <br /> size_t size)<br /> @@ -518,7 +530,15 @@ int <a href="#virStorageVolRef">virStorageVolRef</a> (<a href="libvirt-libvirt. </pre><p>Extract hardware information about the node.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>info</tt></i>:</span></td><td>pointer to a <a href="libvirt-libvirt.html#virNodeInfo">virNodeInfo</a> structure allocated by the user</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 in case of success and -1 in case of failure.</td></tr></tbody></table></div><h3><a name="virNodeGetSecurityModel" id="virNodeGetSecurityModel"><code>virNodeGetSecurityModel</code></a></h3><pre class="programlisting">int virNodeGetSecurityModel (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> <a href="libvirt-libvirt.html#virSecurityModelPtr">virSecurityModelPtr</a> secmodel)<br /> </pre><p>Extract the security model of a hypervisor. The 'model' field in the @secmodel argument may be initialized to the empty string if the driver has not activated a security model.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>a connection object</td></tr><tr><td><span class="term"><i><tt>secmodel</tt></i>:</span></td><td>pointer to a <a href="libvirt-libvirt.html#virSecurityModel">virSecurityModel</a> structure</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 in case of success, -1 in case of failure</td></tr></tbody></table></div><h3><a name="virNodeListDevices" id="virNodeListDevices"><code>virNodeListDevices</code></a></h3><pre class="programlisting">int virNodeListDevices (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * cap, <br /> char ** const names, <br /> int maxnames, <br /> unsi! gned int flags)<br /> </pre><p>Collect the list of node devices, and store their names in @names If the optional 'cap' argument is non-NULL, then the count will be restricted to devices with the specified capability</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>cap</tt></i>:</span></td><td>capability name</td></tr><tr><td><span class="term"><i><tt>names</tt></i>:</span></td><td>array to collect the list of node device names</td></tr><tr><td><span class="term"><i><tt>maxnames</tt></i>:</span></td><td>size of @names</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>flags (unused, pass 0)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of node devices found or -1 in case of error</td></tr></tbody></table></div><h3><a name="virNodeNumOfDevices" id="virNodeNumOfDevices"! ><code>virNodeNumOfDevices</code></a></h3><pre class="programlisting">int virNodeNumOfDevices (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * cap, <br /> unsigned int flags)<br /> -</pre><p>Provides the number of node devices. If the optional 'cap' argument is non-NULL, then the count will be restricted to devices with the specified capability</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>cap</tt></i>:</span></td><td>capability name</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>flags (unused, pass 0)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of node devices or -1 in case of error</td></tr></tbody></table></div><h3><a name="virStoragePoolBuild" id="virStoragePoolBuild"><code>virStoragePoolBuild</code></a></h3><pre class="programlisting">int virStoragePoolBuild (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br /> unsigned int flags)<br /> +</pre><p>Provides the number of node devices. If the optional 'cap' argument is non-NULL, then the count will be restricted to devices with the specified capability</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>cap</tt></i>:</span></td><td>capability name</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>flags (unused, pass 0)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of node devices or -1 in case of error</td></tr></tbody></table></div><h3><a name="virSecretAllocateID" id="virSecretAllocateID"><code>virSecretAllocateID</code></a></h3><pre class="programlisting">char * virSecretAllocateID (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> +</pre><p>Allocates a secret ID (a printable string) without associating a secret value with the ID.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the secret ID on success, or NULL on failure. The caller must free() the secret ID.</td></tr></tbody></table></div><h3><a name="virSecretDelete" id="virSecretDelete"><code>virSecretDelete</code></a></h3><pre class="programlisting">int virSecretDelete (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * secret_id)<br /> +</pre><p>Deletes the secret with secret_id (including the secret value and all attributes).</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>secret_id</tt></i>:</span></td><td>A secret ID</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, -1 on failure.</td></tr></tbody></table></div><h3><a name="virSecretGetValue" id="virSecretGetValue"><code>virSecretGetValue</code></a></h3><pre class="programlisting">void * virSecretGetValue (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * secret_id, <br /> size_t * secret_size)<br /> +</pre><p>Fetches the secret value associated with secret_id.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>secret_id</tt></i>:</span></td><td>A secret ID</td></tr><tr><td><span class="term"><i><tt>secret_size</tt></i>:</span></td><td>Place for storing size of the secret</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the secret value on success, NULL on failure. The caller must free() the secret value.</td></tr></tbody></table></div><h3><a name="virSecretGetXML" id="virSecretGetXML"><code>virSecretGetXML</code></a></h3><pre class="programlisting">char * virSecretGetXML (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * secret_id)<br /> +</pre><p>Fetches an XML document describing attributes of the secret.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>secret_id</tt></i>:</span></td><td>A secret ID</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the XML document on success, NULL on failure. The caller must free() the XML.</td></tr></tbody></table></div><h3><a name="virSecretListSecrets" id="virSecretListSecrets"><code>virSecretListSecrets</code></a></h3><pre class="programlisting">int virSecretListSecrets (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> char ** ids, <br /> int maxids)<br /> +</pre><p>List the defined secret IDs, store pointers to names in ids.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>ids</tt></i>:</span></td><td>Pointer to an array to store the IDs</td></tr><tr><td><span class="term"><i><tt>maxids</tt></i>:</span></td><td>size of the array.</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number of IDs provided in the array, or -1 on failure.</td></tr></tbody></table></div><h3><a name="virSecretNumOfSecrets" id="virSecretNumOfSecrets"><code>virSecretNumOfSecrets</code></a></h3><pre class="programlisting">int virSecretNumOfSecrets (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> +</pre><p>Fetch number of currently defined secret IDs.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the number currently defined secret IDs.</td></tr></tbody></table></div><h3><a name="virSecretSetValue" id="virSecretSetValue"><code>virSecretSetValue</code></a></h3><pre class="programlisting">int virSecretSetValue (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * secret_id, <br /> const void * secret, <br /> size_t secret_size)<br /> +</pre><p>Associates a secret value with secret_id. Allocates secret_id if it was not previously allocated.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>secret_id</tt></i>:</span></td><td>A secret ID</td></tr><tr><td><span class="term"><i><tt>secret</tt></i>:</span></td><td>The secret</td></tr><tr><td><span class="term"><i><tt>secret_size</tt></i>:</span></td><td>Size of the secret</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, -1 on failure.</td></tr></tbody></table></div><h3><a name="virSecretSetXML" id="virSecretSetXML"><code>virSecretSetXML</code></a></h3><pre class="programlisting">int virSecretSetXML (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * secret_id, <br /> const ch! ar * xml)<br /> +</pre><p>Replaces all attributes of the secret specified by secret_id by attributes specified in xml (any attributes not specified in xml are discarded). Allocates secret_id if it was not previously allocated.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td><a href="libvirt-libvirt.html#virConnect">virConnect</a> connection</td></tr><tr><td><span class="term"><i><tt>secret_id</tt></i>:</span></td><td>A secret ID</td></tr><tr><td><span class="term"><i><tt>xml</tt></i>:</span></td><td>XML containing attributes of the secret.</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, -1 on failure.</td></tr></tbody></table></div><h3><a name="virStoragePoolBuild" id="virStoragePoolBuild"><code>virStoragePoolBuild</code></a></h3><pre class="programlisting">int virStoragePoolBuild (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <b! r /> unsigned int flags)<br /> </pre><p>Build the underlying storage pool</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>pool</tt></i>:</span></td><td>pointer to storage pool</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>future flags, use 0 for now</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, or -1 upon failure</td></tr></tbody></table></div><h3><a name="virStoragePoolCreate" id="virStoragePoolCreate"><code>virStoragePoolCreate</code></a></h3><pre class="programlisting">int virStoragePoolCreate (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br /> unsigned int flags)<br /> </pre><p>Starts an inactive storage pool</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>pool</tt></i>:</span></td><td>pointer to storage pool</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>future flags, use 0 for now</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, or -1 if it could not be started</td></tr></tbody></table></div><h3><a name="virStoragePoolCreateXML" id="virStoragePoolCreateXML"><code>virStoragePoolCreateXML</code></a></h3><pre class="programlisting"><a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> virStoragePoolCreateXML (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * xmlDesc, <br /> unsigned int flags)<br /> </pre><p>Create a new storage based on its XML description. The pool is not persistent, so its definition will disappear when it is destroyed, or if the host is restarted</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to hypervisor connection</td></tr><tr><td><span class="term"><i><tt>xmlDesc</tt></i>:</span></td><td>XML description for new pool</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>future flags, use 0 for now</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a <a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> object, or NULL if creation failed</td></tr></tbody></table></div><h3><a name="virStoragePoolDefineXML" id="virStoragePoolDefineXML"><code>virStoragePoolDefineXML</code></a></h3><pre class="programlisting"><a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> virStoragePoo! lDefineXML (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> const char * xml, <br /> unsigned int flags)<br /> @@ -542,7 +562,7 @@ int <a href="#virStorageVolRef">virStorageVolRef</a> (<a href="libvirt-libvirt. </pre><p>Increment the reference count on the pool. For each additional call to this method, there shall be a corresponding call to <a href="libvirt-libvirt.html#virStoragePoolFree">virStoragePoolFree</a> to release the reference count, once the caller no longer needs the reference to this object. This method is typically useful for applications where multiple threads are using a connection, and it is required that the connection remain open until all threads have finished using it. ie, each new thread using a pool would increment the reference count.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>pool</tt></i>:</span></td><td>the pool to hold a reference on</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 in case of success, -1 in case of failure.</td></tr></tbody></table></div><h3><a name="virStoragePoolRefresh" id="virStoragePoolRefresh"><code>virStoragePoolRefresh</code></a></h3><p! re class="programlisting">int virStoragePoolRefresh (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br /> unsigned int flags)<br /> </pre><p>Request that the pool refresh its list of volumes. This may involve communicating with a remote server, and/or initializing new devices at the OS layer</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>pool</tt></i>:</span></td><td>pointer to storage pool</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>flags to control refresh behaviour (currently unused, use 0)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 if the volume list was refreshed, -1 on failure</td></tr></tbody></table></div><h3><a name="virStoragePoolSetAutostart" id="virStoragePoolSetAutostart"><code>virStoragePoolSetAutostart</code></a></h3><pre class="programlisting">int virStoragePoolSetAutostart (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br /> int autostart)<br /> </pre><p>Sets the autostart flag</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>pool</tt></i>:</span></td><td>pointer to storage pool</td></tr><tr><td><span class="term"><i><tt>autostart</tt></i>:</span></td><td>new flag setting</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, -1 on failure</td></tr></tbody></table></div><h3><a name="virStoragePoolUndefine" id="virStoragePoolUndefine"><code>virStoragePoolUndefine</code></a></h3><pre class="programlisting">int virStoragePoolUndefine (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool)<br /> -</pre><p>Undefine an inactive storage pool</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>pool</tt></i>:</span></td><td>pointer to storage pool</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a <a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> object, or NULL if creation failed</td></tr></tbody></table></div><h3><a name="virStorageVolCreateXML" id="virStorageVolCreateXML"><code>virStorageVolCreateXML</code></a></h3><pre class="programlisting"><a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> virStorageVolCreateXML (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br /> const char * xmldesc, <br /> unsigned int flags)<br /> +</pre><p>Undefine an inactive storage pool</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>pool</tt></i>:</span></td><td>pointer to storage pool</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, -1 on failure</td></tr></tbody></table></div><h3><a name="virStorageVolCreateXML" id="virStorageVolCreateXML"><code>virStorageVolCreateXML</code></a></h3><pre class="programlisting"><a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> virStorageVolCreateXML (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br /> const char * xmldesc, <br /> unsigned int flags)<br /> </pre><p>Create a storage volume within a pool based on an XML description. Not all pools support creation of volumes</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>pool</tt></i>:</span></td><td>pointer to storage pool</td></tr><tr><td><span class="term"><i><tt>xmldesc</tt></i>:</span></td><td>description of volume to create</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>flags for creation (unused, pass 0)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the storage volume, or NULL on error</td></tr></tbody></table></div><h3><a name="virStorageVolCreateXMLFrom" id="virStorageVolCreateXMLFrom"><code>virStorageVolCreateXMLFrom</code></a></h3><pre class="programlisting"><a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> virStorageVolCreateXMLFrom (<a href="libvirt-libvirt.html#virStoragePoolPtr">virStoragePoolPtr</a> pool, <br /> const cha! r * xmldesc, <br /> <a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> clonevol, <br /> unsigned int flags)<br /> </pre><p>Create a storage volume in the parent pool, using the 'clonevol' volume as input. Information for the new volume (name, perms) are passed via a typical volume XML description.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>pool</tt></i>:</span></td><td>pointer to parent pool for the new volume</td></tr><tr><td><span class="term"><i><tt>xmldesc</tt></i>:</span></td><td>description of volume to create</td></tr><tr><td><span class="term"><i><tt>clonevol</tt></i>:</span></td><td>storage volume to use as input</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>flags for creation (unused, pass 0)</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>the storage volume, or NULL on error</td></tr></tbody></table></div><h3><a name="virStorageVolDelete" id="virStorageVolDelete"><code>virStorageVolDelete</code></a></h3><pre class="programlisting">int virStorageVolDelete ! (<a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> vol, <br /> unsigned int flags)<br /> </pre><p>Delete the storage volume from the pool</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>vol</tt></i>:</span></td><td>pointer to storage volume</td></tr><tr><td><span class="term"><i><tt>flags</tt></i>:</span></td><td>future flags, use 0 for now</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>0 on success, or -1 on error</td></tr></tbody></table></div><h3><a name="virStorageVolFree" id="virStorageVolFree"><code>virStorageVolFree</code></a></h3><pre class="programlisting">int virStorageVolFree (<a href="libvirt-libvirt.html#virStorageVolPtr">virStorageVolPtr</a> vol)<br /> diff --git a/docs/html/libvirt-virterror.html b/docs/html/libvirt-virterror.html index 93415bf..d76acff 100644 --- a/docs/html/libvirt-virterror.html +++ b/docs/html/libvirt-virterror.html @@ -27,11 +27,11 @@ void <a href="#virSetErrorFunc">virSetErrorFunc</a> (void * userData, <br /> </pre><table><tr><td>int</td><td>code</td><td> : The error code, a <a href="libvirt-virterror.html#virErrorNumber">virErrorNumber</a></td></tr><tr><td>int</td><td>domain</td><td> : What part of the library raised this error</td></tr><tr><td>char *</td><td>message</td><td> : human-readable informative error message</td></tr><tr><td><a href="libvirt-virterror.html#virErrorLevel">virErrorLevel</a></td><td>level</td><td> : how consequent is the error</td></tr><tr><td><a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a></td><td>conn</td><td> : connection if available, deprecated see note above</td></tr><tr><td><a href="libvirt-libvirt.html#virDomainPtr">virDomainPtr</a></td><td>dom</td><td> : domain if available, deprecated see note above</td></tr><tr><td>char *</td><td>str1</td><td> : extra string information</td></tr><tr><td>char *</td><td>str2</td><td> : extra string information</td></tr><tr><td>char *</td><td>str3</td><td> : extra string information</td></tr><tr><t! d>int</td><td>int1</td><td> : extra number information</td></tr><tr><td>int</td><td>int2</td><td> : extra number information</td></tr><tr><td><a href="libvirt-libvirt.html#virNetworkPtr">virNetworkPtr</a></td><td>net</td><td> : network if available, deprecated see note above</td></tr></table><pre> } </pre></div><h3><a name="virErrorDomain" id="virErrorDomain"><code>virErrorDomain</code></a></h3><div class="api"><pre>enum virErrorDomain { -</pre><table><tr><td><a name="VIR_FROM_NONE" id="VIR_FROM_NONE">VIR_FROM_NONE</a></td><td> = </td><td>0</td></tr><tr><td><a name="VIR_FROM_XEN" id="VIR_FROM_XEN">VIR_FROM_XEN</a></td><td> = </td><td>1</td><td> : Error at Xen hypervisor layer</td></tr><tr><td><a name="VIR_FROM_XEND" id="VIR_FROM_XEND">VIR_FROM_XEND</a></td><td> = </td><td>2</td><td> : Error at connection with xend daemon</td></tr><tr><td><a name="VIR_FROM_XENSTORE" id="VIR_FROM_XENSTORE">VIR_FROM_XENSTORE</a></td><td> = </td><td>3</td><td> : Error at connection with xen store</td></tr><tr><td><a name="VIR_FROM_SEXPR" id="VIR_FROM_SEXPR">VIR_FROM_SEXPR</a></td><td> = </td><td>4</td><td> : Error in the S-Expression code</td></tr><tr><td><a name="VIR_FROM_XML" id="VIR_FROM_XML">VIR_FROM_XML</a></td><td> = </td><td>5</td><td> : Error in the XML code</td></tr><tr><td><a name="VIR_FROM_DOM" id="VIR_FROM_DOM">VIR_FROM_DOM</a></td><td> = </td><td>6</td><td> : Error when operating on a domain</td></tr><tr><td><a name! ="VIR_FROM_RPC" id="VIR_FROM_RPC">VIR_FROM_RPC</a></td><td> = </td><td>7</td><td> : Error in the XML-RPC code</td></tr><tr><td><a name="VIR_FROM_PROXY" id="VIR_FROM_PROXY">VIR_FROM_PROXY</a></td><td> = </td><td>8</td><td> : Error in the proxy code</td></tr><tr><td><a name="VIR_FROM_CONF" id="VIR_FROM_CONF">VIR_FROM_CONF</a></td><td> = </td><td>9</td><td> : Error in the configuration file handling</td></tr><tr><td><a name="VIR_FROM_QEMU" id="VIR_FROM_QEMU">VIR_FROM_QEMU</a></td><td> = </td><td>10</td><td> : Error at the QEMU daemon</td></tr><tr><td><a name="VIR_FROM_NET" id="VIR_FROM_NET">VIR_FROM_NET</a></td><td> = </td><td>11</td><td> : Error when operating on a network</td></tr><tr><td><a name="VIR_FROM_TEST" id="VIR_FROM_TEST">VIR_FROM_TEST</a></td><td> = </td><td>12</td><td> : Error from test driver</td></tr><tr><td><a name="VIR_FROM_REMOTE" id="VIR_FROM_REMOTE">VIR_FROM_REMOTE</a></td><td> = </td><td>13</td><td> : Error from remote driver</td></tr><tr><td><a name="VIR_! FROM_OPENVZ" id="VIR_FROM_OPENVZ">VIR_FROM_OPENVZ</a></td><td> = </td> <td>14</td><td> : Error from OpenVZ driver</td></tr><tr><td><a name="VIR_FROM_XENXM" id="VIR_FROM_XENXM">VIR_FROM_XENXM</a></td><td> = </td><td>15</td><td> : Error at Xen XM layer</td></tr><tr><td><a name="VIR_FROM_STATS_LINUX" id="VIR_FROM_STATS_LINUX">VIR_FROM_STATS_LINUX</a></td><td> = </td><td>16</td><td> : Error in the Linux Stats code</td></tr><tr><td><a name="VIR_FROM_LXC" id="VIR_FROM_LXC">VIR_FROM_LXC</a></td><td> = </td><td>17</td><td> : Error from Linux Container driver</td></tr><tr><td><a name="VIR_FROM_STORAGE" id="VIR_FROM_STORAGE">VIR_FROM_STORAGE</a></td><td> = </td><td>18</td><td> : Error from storage driver</td></tr><tr><td><a name="VIR_FROM_NETWORK" id="VIR_FROM_NETWORK">VIR_FROM_NETWORK</a></td><td> = </td><td>19</td><td> : Error from network config</td></tr><tr><td><a name="VIR_FROM_DOMAIN" id="VIR_FROM_DOMAIN">VIR_FROM_DOMAIN</a></td><td> = </td><td>20</td><td> : Error from domain config</td></tr><tr><td><a name="VIR_FROM_UML" id="VIR_FROM_UML">VIR_FROM! _UML</a></td><td> = </td><td>21</td><td> : Error at the UML driver</td></tr><tr><td><a name="VIR_FROM_NODEDEV" id="VIR_FROM_NODEDEV">VIR_FROM_NODEDEV</a></td><td> = </td><td>22</td><td> : Error from node device monitor</td></tr><tr><td><a name="VIR_FROM_XEN_INOTIFY" id="VIR_FROM_XEN_INOTIFY">VIR_FROM_XEN_INOTIFY</a></td><td> = </td><td>23</td><td> : Error from xen inotify layer</td></tr><tr><td><a name="VIR_FROM_SECURITY" id="VIR_FROM_SECURITY">VIR_FROM_SECURITY</a></td><td> = </td><td>24</td><td> : Error from security framework</td></tr><tr><td><a name="VIR_FROM_VBOX" id="VIR_FROM_VBOX">VIR_FROM_VBOX</a></td><td> = </td><td>25</td><td> : Error from VirtualBox driver</td></tr><tr><td><a name="VIR_FROM_INTERFACE" id="VIR_FROM_INTERFACE">VIR_FROM_INTERFACE</a></td><td> = </td><td>26</td><td> : Error when operating on an interface</td></tr><tr><td><a name="VIR_FROM_ONE" id="VIR_FROM_ONE">VIR_FROM_ONE</a></td><td> = </td><td>27</td><td> : Error from OpenNebula driver</td></tr><! /table><pre>} +</pre><table><tr><td><a name="VIR_FROM_NONE" id="VIR_FROM_NONE">VIR_FROM_NONE</a></td><td> = </td><td>0</td></tr><tr><td><a name="VIR_FROM_XEN" id="VIR_FROM_XEN">VIR_FROM_XEN</a></td><td> = </td><td>1</td><td> : Error at Xen hypervisor layer</td></tr><tr><td><a name="VIR_FROM_XEND" id="VIR_FROM_XEND">VIR_FROM_XEND</a></td><td> = </td><td>2</td><td> : Error at connection with xend daemon</td></tr><tr><td><a name="VIR_FROM_XENSTORE" id="VIR_FROM_XENSTORE">VIR_FROM_XENSTORE</a></td><td> = </td><td>3</td><td> : Error at connection with xen store</td></tr><tr><td><a name="VIR_FROM_SEXPR" id="VIR_FROM_SEXPR">VIR_FROM_SEXPR</a></td><td> = </td><td>4</td><td> : Error in the S-Expression code</td></tr><tr><td><a name="VIR_FROM_XML" id="VIR_FROM_XML">VIR_FROM_XML</a></td><td> = </td><td>5</td><td> : Error in the XML code</td></tr><tr><td><a name="VIR_FROM_DOM" id="VIR_FROM_DOM">VIR_FROM_DOM</a></td><td> = </td><td>6</td><td> : Error when operating on a domain</td></tr><tr><td><a name! ="VIR_FROM_RPC" id="VIR_FROM_RPC">VIR_FROM_RPC</a></td><td> = </td><td>7</td><td> : Error in the XML-RPC code</td></tr><tr><td><a name="VIR_FROM_PROXY" id="VIR_FROM_PROXY">VIR_FROM_PROXY</a></td><td> = </td><td>8</td><td> : Error in the proxy code</td></tr><tr><td><a name="VIR_FROM_CONF" id="VIR_FROM_CONF">VIR_FROM_CONF</a></td><td> = </td><td>9</td><td> : Error in the configuration file handling</td></tr><tr><td><a name="VIR_FROM_QEMU" id="VIR_FROM_QEMU">VIR_FROM_QEMU</a></td><td> = </td><td>10</td><td> : Error at the QEMU daemon</td></tr><tr><td><a name="VIR_FROM_NET" id="VIR_FROM_NET">VIR_FROM_NET</a></td><td> = </td><td>11</td><td> : Error when operating on a network</td></tr><tr><td><a name="VIR_FROM_TEST" id="VIR_FROM_TEST">VIR_FROM_TEST</a></td><td> = </td><td>12</td><td> : Error from test driver</td></tr><tr><td><a name="VIR_FROM_REMOTE" id="VIR_FROM_REMOTE">VIR_FROM_REMOTE</a></td><td> = </td><td>13</td><td> : Error from remote driver</td></tr><tr><td><a name="VIR_! FROM_OPENVZ" id="VIR_FROM_OPENVZ">VIR_FROM_OPENVZ</a></td><td> = </td> <td>14</td><td> : Error from OpenVZ driver</td></tr><tr><td><a name="VIR_FROM_XENXM" id="VIR_FROM_XENXM">VIR_FROM_XENXM</a></td><td> = </td><td>15</td><td> : Error at Xen XM layer</td></tr><tr><td><a name="VIR_FROM_STATS_LINUX" id="VIR_FROM_STATS_LINUX">VIR_FROM_STATS_LINUX</a></td><td> = </td><td>16</td><td> : Error in the Linux Stats code</td></tr><tr><td><a name="VIR_FROM_LXC" id="VIR_FROM_LXC">VIR_FROM_LXC</a></td><td> = </td><td>17</td><td> : Error from Linux Container driver</td></tr><tr><td><a name="VIR_FROM_STORAGE" id="VIR_FROM_STORAGE">VIR_FROM_STORAGE</a></td><td> = </td><td>18</td><td> : Error from storage driver</td></tr><tr><td><a name="VIR_FROM_NETWORK" id="VIR_FROM_NETWORK">VIR_FROM_NETWORK</a></td><td> = </td><td>19</td><td> : Error from network config</td></tr><tr><td><a name="VIR_FROM_DOMAIN" id="VIR_FROM_DOMAIN">VIR_FROM_DOMAIN</a></td><td> = </td><td>20</td><td> : Error from domain config</td></tr><tr><td><a name="VIR_FROM_UML" id="VIR_FROM_UML">VIR_FROM! _UML</a></td><td> = </td><td>21</td><td> : Error at the UML driver</td></tr><tr><td><a name="VIR_FROM_NODEDEV" id="VIR_FROM_NODEDEV">VIR_FROM_NODEDEV</a></td><td> = </td><td>22</td><td> : Error from node device monitor</td></tr><tr><td><a name="VIR_FROM_XEN_INOTIFY" id="VIR_FROM_XEN_INOTIFY">VIR_FROM_XEN_INOTIFY</a></td><td> = </td><td>23</td><td> : Error from xen inotify layer</td></tr><tr><td><a name="VIR_FROM_SECURITY" id="VIR_FROM_SECURITY">VIR_FROM_SECURITY</a></td><td> = </td><td>24</td><td> : Error from security framework</td></tr><tr><td><a name="VIR_FROM_VBOX" id="VIR_FROM_VBOX">VIR_FROM_VBOX</a></td><td> = </td><td>25</td><td> : Error from VirtualBox driver</td></tr><tr><td><a name="VIR_FROM_INTERFACE" id="VIR_FROM_INTERFACE">VIR_FROM_INTERFACE</a></td><td> = </td><td>26</td><td> : Error when operating on an interface</td></tr><tr><td><a name="VIR_FROM_ONE" id="VIR_FROM_ONE">VIR_FROM_ONE</a></td><td> = </td><td>27</td><td> : Error from OpenNebula driver</td></tr><! tr><td><a name="VIR_FROM_ESX" id="VIR_FROM_ESX">VIR_FROM_ESX</a></td>< td> = </td><td>28</td><td> : Error from ESX driver</td></tr><tr><td><a name="VIR_FROM_PHYP" id="VIR_FROM_PHYP">VIR_FROM_PHYP</a></td><td> = </td><td>29</td><td> : Error from IBM power hypervisor</td></tr><tr><td><a name="VIR_FROM_SECRET" id="VIR_FROM_SECRET">VIR_FROM_SECRET</a></td><td> = </td><td>30</td><td> : Error from secret storage</td></tr></table><pre>} </pre></div><h3><a name="virErrorLevel" id="virErrorLevel"><code>virErrorLevel</code></a></h3><div class="api"><pre>enum virErrorLevel { </pre><table><tr><td><a name="VIR_ERR_NONE" id="VIR_ERR_NONE">VIR_ERR_NONE</a></td><td> = </td><td>0</td></tr><tr><td><a name="VIR_ERR_WARNING" id="VIR_ERR_WARNING">VIR_ERR_WARNING</a></td><td> = </td><td>1</td><td> : A simple warning</td></tr><tr><td><a name="VIR_ERR_ERROR" id="VIR_ERR_ERROR">VIR_ERR_ERROR</a></td><td> = </td><td>2</td><td> : An error</td></tr></table><pre>} </pre></div><h3><a name="virErrorNumber" id="virErrorNumber"><code>virErrorNumber</code></a></h3><div class="api"><pre>enum virErrorNumber { -</pre><table><tr><td><a name="VIR_ERR_OK" id="VIR_ERR_OK">VIR_ERR_OK</a></td><td> = </td><td>0</td></tr><tr><td><a name="VIR_ERR_INTERNAL_ERROR" id="VIR_ERR_INTERNAL_ERROR">VIR_ERR_INTERNAL_ERROR</a></td><td> = </td><td>1</td><td> : internal error</td></tr><tr><td><a name="VIR_ERR_NO_MEMORY" id="VIR_ERR_NO_MEMORY">VIR_ERR_NO_MEMORY</a></td><td> = </td><td>2</td><td> : memory allocation failure</td></tr><tr><td><a name="VIR_ERR_NO_SUPPORT" id="VIR_ERR_NO_SUPPORT">VIR_ERR_NO_SUPPORT</a></td><td> = </td><td>3</td><td> : no support for this function</td></tr><tr><td><a name="VIR_ERR_UNKNOWN_HOST" id="VIR_ERR_UNKNOWN_HOST">VIR_ERR_UNKNOWN_HOST</a></td><td> = </td><td>4</td><td> : could not resolve hostname</td></tr><tr><td><a name="VIR_ERR_NO_CONNECT" id="VIR_ERR_NO_CONNECT">VIR_ERR_NO_CONNECT</a></td><td> = </td><td>5</td><td> : can't connect to hypervisor</td></tr><tr><td><a name="VIR_ERR_INVALID_CONN" id="VIR_ERR_INVALID_CONN">VIR_ERR_INVALID_CONN</a></td><td> = </td><td>6</t! d><td> : invalid connection object</td></tr><tr><td><a name="VIR_ERR_INVALID_DOMAIN" id="VIR_ERR_INVALID_DOMAIN">VIR_ERR_INVALID_DOMAIN</a></td><td> = </td><td>7</td><td> : invalid domain object</td></tr><tr><td><a name="VIR_ERR_INVALID_ARG" id="VIR_ERR_INVALID_ARG">VIR_ERR_INVALID_ARG</a></td><td> = </td><td>8</td><td> : invalid function argument</td></tr><tr><td><a name="VIR_ERR_OPERATION_FAILED" id="VIR_ERR_OPERATION_FAILED">VIR_ERR_OPERATION_FAILED</a></td><td> = </td><td>9</td><td> : a command to hypervisor failed</td></tr><tr><td><a name="VIR_ERR_GET_FAILED" id="VIR_ERR_GET_FAILED">VIR_ERR_GET_FAILED</a></td><td> = </td><td>10</td><td> : a HTTP GET command to failed</td></tr><tr><td><a name="VIR_ERR_POST_FAILED" id="VIR_ERR_POST_FAILED">VIR_ERR_POST_FAILED</a></td><td> = </td><td>11</td><td> : a HTTP POST command to failed</td></tr><tr><td><a name="VIR_ERR_HTTP_ERROR" id="VIR_ERR_HTTP_ERROR">VIR_ERR_HTTP_ERROR</a></td><td> = </td><td>12</td><td> : unexpected HTTP erro! r code</td></tr><tr><td><a name="VIR_ERR_SEXPR_SERIAL" id="VIR_ERR_SEX PR_SERIAL">VIR_ERR_SEXPR_SERIAL</a></td><td> = </td><td>13</td><td> : failure to serialize an S-Expr</td></tr><tr><td><a name="VIR_ERR_NO_XEN" id="VIR_ERR_NO_XEN">VIR_ERR_NO_XEN</a></td><td> = </td><td>14</td><td> : could not open Xen hypervisor control</td></tr><tr><td><a name="VIR_ERR_XEN_CALL" id="VIR_ERR_XEN_CALL">VIR_ERR_XEN_CALL</a></td><td> = </td><td>15</td><td> : failure doing an hypervisor call</td></tr><tr><td><a name="VIR_ERR_OS_TYPE" id="VIR_ERR_OS_TYPE">VIR_ERR_OS_TYPE</a></td><td> = </td><td>16</td><td> : unknown OS type</td></tr><tr><td><a name="VIR_ERR_NO_KERNEL" id="VIR_ERR_NO_KERNEL">VIR_ERR_NO_KERNEL</a></td><td> = </td><td>17</td><td> : missing kernel information</td></tr><tr><td><a name="VIR_ERR_NO_ROOT" id="VIR_ERR_NO_ROOT">VIR_ERR_NO_ROOT</a></td><td> = </td><td>18</td><td> : missing root device information</td></tr><tr><td><a name="VIR_ERR_NO_SOURCE" id="VIR_ERR_NO_SOURCE">VIR_ERR_NO_SOURCE</a></td><td> = </td><td>19</td><td> : missing source device ! information</td></tr><tr><td><a name="VIR_ERR_NO_TARGET" id="VIR_ERR_NO_TARGET">VIR_ERR_NO_TARGET</a></td><td> = </td><td>20</td><td> : missing target device information</td></tr><tr><td><a name="VIR_ERR_NO_NAME" id="VIR_ERR_NO_NAME">VIR_ERR_NO_NAME</a></td><td> = </td><td>21</td><td> : missing domain name information</td></tr><tr><td><a name="VIR_ERR_NO_OS" id="VIR_ERR_NO_OS">VIR_ERR_NO_OS</a></td><td> = </td><td>22</td><td> : missing domain OS information</td></tr><tr><td><a name="VIR_ERR_NO_DEVICE" id="VIR_ERR_NO_DEVICE">VIR_ERR_NO_DEVICE</a></td><td> = </td><td>23</td><td> : missing domain devices information</td></tr><tr><td><a name="VIR_ERR_NO_XENSTORE" id="VIR_ERR_NO_XENSTORE">VIR_ERR_NO_XENSTORE</a></td><td> = </td><td>24</td><td> : could not open Xen Store control</td></tr><tr><td><a name="VIR_ERR_DRIVER_FULL" id="VIR_ERR_DRIVER_FULL">VIR_ERR_DRIVER_FULL</a></td><td> = </td><td>25</td><td> : too many drivers registered</td></tr><tr><td><a name="VIR_ERR_CALL_FAILED"! id="VIR_ERR_CALL_FAILED">VIR_ERR_CALL_FAILED</a></td><td> = </td><td> 26</td><td> : not supported by the drivers (DEPRECATED)</td></tr><tr><td><a name="VIR_ERR_XML_ERROR" id="VIR_ERR_XML_ERROR">VIR_ERR_XML_ERROR</a></td><td> = </td><td>27</td><td> : an XML description is not well formed or broken</td></tr><tr><td><a name="VIR_ERR_DOM_EXIST" id="VIR_ERR_DOM_EXIST">VIR_ERR_DOM_EXIST</a></td><td> = </td><td>28</td><td> : the domain already exist</td></tr><tr><td><a name="VIR_ERR_OPERATION_DENIED" id="VIR_ERR_OPERATION_DENIED">VIR_ERR_OPERATION_DENIED</a></td><td> = </td><td>29</td><td> : operation forbidden on read-only connections</td></tr><tr><td><a name="VIR_ERR_OPEN_FAILED" id="VIR_ERR_OPEN_FAILED">VIR_ERR_OPEN_FAILED</a></td><td> = </td><td>30</td><td> : failed to open a conf file</td></tr><tr><td><a name="VIR_ERR_READ_FAILED" id="VIR_ERR_READ_FAILED">VIR_ERR_READ_FAILED</a></td><td> = </td><td>31</td><td> : failed to read a conf file</td></tr><tr><td><a name="VIR_ERR_PARSE_FAILED" id="VIR_ERR_PARSE_FAILED">VIR_ERR_PARSE_FAILED</a></td><td> ! = </td><td>32</td><td> : failed to parse a conf file</td></tr><tr><td><a name="VIR_ERR_CONF_SYNTAX" id="VIR_ERR_CONF_SYNTAX">VIR_ERR_CONF_SYNTAX</a></td><td> = </td><td>33</td><td> : failed to parse the syntax of a conf file</td></tr><tr><td><a name="VIR_ERR_WRITE_FAILED" id="VIR_ERR_WRITE_FAILED">VIR_ERR_WRITE_FAILED</a></td><td> = </td><td>34</td><td> : failed to write a conf file</td></tr><tr><td><a name="VIR_ERR_XML_DETAIL" id="VIR_ERR_XML_DETAIL">VIR_ERR_XML_DETAIL</a></td><td> = </td><td>35</td><td> : detail of an XML error</td></tr><tr><td><a name="VIR_ERR_INVALID_NETWORK" id="VIR_ERR_INVALID_NETWORK">VIR_ERR_INVALID_NETWORK</a></td><td> = </td><td>36</td><td> : invalid network object</td></tr><tr><td><a name="VIR_ERR_NETWORK_EXIST" id="VIR_ERR_NETWORK_EXIST">VIR_ERR_NETWORK_EXIST</a></td><td> = </td><td>37</td><td> : the network already exist</td></tr><tr><td><a name="VIR_ERR_SYSTEM_ERROR" id="VIR_ERR_SYSTEM_ERROR">VIR_ERR_SYSTEM_ERROR</a></td><td> = </td><td>38</td! ><td> : general system call failure</td></tr><tr><td><a name="VIR_ERR_ RPC" id="VIR_ERR_RPC">VIR_ERR_RPC</a></td><td> = </td><td>39</td><td> : some sort of RPC error</td></tr><tr><td><a name="VIR_ERR_GNUTLS_ERROR" id="VIR_ERR_GNUTLS_ERROR">VIR_ERR_GNUTLS_ERROR</a></td><td> = </td><td>40</td><td> : error from a GNUTLS call</td></tr><tr><td><a name="VIR_WAR_NO_NETWORK" id="VIR_WAR_NO_NETWORK">VIR_WAR_NO_NETWORK</a></td><td> = </td><td>41</td><td> : failed to start network</td></tr><tr><td><a name="VIR_ERR_NO_DOMAIN" id="VIR_ERR_NO_DOMAIN">VIR_ERR_NO_DOMAIN</a></td><td> = </td><td>42</td><td> : domain not found or unexpectedly disappeared</td></tr><tr><td><a name="VIR_ERR_NO_NETWORK" id="VIR_ERR_NO_NETWORK">VIR_ERR_NO_NETWORK</a></td><td> = </td><td>43</td><td> : network not found</td></tr><tr><td><a name="VIR_ERR_INVALID_MAC" id="VIR_ERR_INVALID_MAC">VIR_ERR_INVALID_MAC</a></td><td> = </td><td>44</td><td> : invalid MAC address</td></tr><tr><td><a name="VIR_ERR_AUTH_FAILED" id="VIR_ERR_AUTH_FAILED">VIR_ERR_AUTH_FAILED</a></td><td> = </td><td>45</t! d><td> : authentication failed</td></tr><tr><td><a name="VIR_ERR_INVALID_STORAGE_POOL" id="VIR_ERR_INVALID_STORAGE_POOL">VIR_ERR_INVALID_STORAGE_POOL</a></td><td> = </td><td>46</td><td> : invalid storage pool object</td></tr><tr><td><a name="VIR_ERR_INVALID_STORAGE_VOL" id="VIR_ERR_INVALID_STORAGE_VOL">VIR_ERR_INVALID_STORAGE_VOL</a></td><td> = </td><td>47</td><td> : invalid storage vol object</td></tr><tr><td><a name="VIR_WAR_NO_STORAGE" id="VIR_WAR_NO_STORAGE">VIR_WAR_NO_STORAGE</a></td><td> = </td><td>48</td><td> : failed to start storage</td></tr><tr><td><a name="VIR_ERR_NO_STORAGE_POOL" id="VIR_ERR_NO_STORAGE_POOL">VIR_ERR_NO_STORAGE_POOL</a></td><td> = </td><td>49</td><td> : storage pool not found</td></tr><tr><td><a name="VIR_ERR_NO_STORAGE_VOL" id="VIR_ERR_NO_STORAGE_VOL">VIR_ERR_NO_STORAGE_VOL</a></td><td> = </td><td>50</td><td> : storage pool not found</td></tr><tr><td><a name="VIR_WAR_NO_NODE" id="VIR_WAR_NO_NODE">VIR_WAR_NO_NODE</a></td><td> = </td><td>51</td><t! d> : failed to start node driver</td></tr><tr><td><a name="VIR_ERR_INV ALID_NODE_DEVICE" id="VIR_ERR_INVALID_NODE_DEVICE">VIR_ERR_INVALID_NODE_DEVICE</a></td><td> = </td><td>52</td><td> : invalid node device object</td></tr><tr><td><a name="VIR_ERR_NO_NODE_DEVICE" id="VIR_ERR_NO_NODE_DEVICE">VIR_ERR_NO_NODE_DEVICE</a></td><td> = </td><td>53</td><td> : node device not found</td></tr><tr><td><a name="VIR_ERR_NO_SECURITY_MODEL" id="VIR_ERR_NO_SECURITY_MODEL">VIR_ERR_NO_SECURITY_MODEL</a></td><td> = </td><td>54</td><td> : security model not found</td></tr><tr><td><a name="VIR_ERR_OPERATION_INVALID" id="VIR_ERR_OPERATION_INVALID">VIR_ERR_OPERATION_INVALID</a></td><td> = </td><td>55</td><td> : operation is not applicable at this time</td></tr><tr><td><a name="VIR_WAR_NO_INTERFACE" id="VIR_WAR_NO_INTERFACE">VIR_WAR_NO_INTERFACE</a></td><td> = </td><td>56</td><td> : failed to start interface driver</td></tr><tr><td><a name="VIR_ERR_NO_INTERFACE" id="VIR_ERR_NO_INTERFACE">VIR_ERR_NO_INTERFACE</a></td><td> = </td><td>57</td><td> : interface driver not ru! nning</td></tr><tr><td><a name="VIR_ERR_INVALID_INTERFACE" id="VIR_ERR_INVALID_INTERFACE">VIR_ERR_INVALID_INTERFACE</a></td><td> = </td><td>58</td><td> : invalid interface object</td></tr></table><pre>} +</pre><table><tr><td><a name="VIR_ERR_OK" id="VIR_ERR_OK">VIR_ERR_OK</a></td><td> = </td><td>0</td></tr><tr><td><a name="VIR_ERR_INTERNAL_ERROR" id="VIR_ERR_INTERNAL_ERROR">VIR_ERR_INTERNAL_ERROR</a></td><td> = </td><td>1</td><td> : internal error</td></tr><tr><td><a name="VIR_ERR_NO_MEMORY" id="VIR_ERR_NO_MEMORY">VIR_ERR_NO_MEMORY</a></td><td> = </td><td>2</td><td> : memory allocation failure</td></tr><tr><td><a name="VIR_ERR_NO_SUPPORT" id="VIR_ERR_NO_SUPPORT">VIR_ERR_NO_SUPPORT</a></td><td> = </td><td>3</td><td> : no support for this function</td></tr><tr><td><a name="VIR_ERR_UNKNOWN_HOST" id="VIR_ERR_UNKNOWN_HOST">VIR_ERR_UNKNOWN_HOST</a></td><td> = </td><td>4</td><td> : could not resolve hostname</td></tr><tr><td><a name="VIR_ERR_NO_CONNECT" id="VIR_ERR_NO_CONNECT">VIR_ERR_NO_CONNECT</a></td><td> = </td><td>5</td><td> : can't connect to hypervisor</td></tr><tr><td><a name="VIR_ERR_INVALID_CONN" id="VIR_ERR_INVALID_CONN">VIR_ERR_INVALID_CONN</a></td><td> = </td><td>6</t! d><td> : invalid connection object</td></tr><tr><td><a name="VIR_ERR_INVALID_DOMAIN" id="VIR_ERR_INVALID_DOMAIN">VIR_ERR_INVALID_DOMAIN</a></td><td> = </td><td>7</td><td> : invalid domain object</td></tr><tr><td><a name="VIR_ERR_INVALID_ARG" id="VIR_ERR_INVALID_ARG">VIR_ERR_INVALID_ARG</a></td><td> = </td><td>8</td><td> : invalid function argument</td></tr><tr><td><a name="VIR_ERR_OPERATION_FAILED" id="VIR_ERR_OPERATION_FAILED">VIR_ERR_OPERATION_FAILED</a></td><td> = </td><td>9</td><td> : a command to hypervisor failed</td></tr><tr><td><a name="VIR_ERR_GET_FAILED" id="VIR_ERR_GET_FAILED">VIR_ERR_GET_FAILED</a></td><td> = </td><td>10</td><td> : a HTTP GET command to failed</td></tr><tr><td><a name="VIR_ERR_POST_FAILED" id="VIR_ERR_POST_FAILED">VIR_ERR_POST_FAILED</a></td><td> = </td><td>11</td><td> : a HTTP POST command to failed</td></tr><tr><td><a name="VIR_ERR_HTTP_ERROR" id="VIR_ERR_HTTP_ERROR">VIR_ERR_HTTP_ERROR</a></td><td> = </td><td>12</td><td> : unexpected HTTP erro! r code</td></tr><tr><td><a name="VIR_ERR_SEXPR_SERIAL" id="VIR_ERR_SEX PR_SERIAL">VIR_ERR_SEXPR_SERIAL</a></td><td> = </td><td>13</td><td> : failure to serialize an S-Expr</td></tr><tr><td><a name="VIR_ERR_NO_XEN" id="VIR_ERR_NO_XEN">VIR_ERR_NO_XEN</a></td><td> = </td><td>14</td><td> : could not open Xen hypervisor control</td></tr><tr><td><a name="VIR_ERR_XEN_CALL" id="VIR_ERR_XEN_CALL">VIR_ERR_XEN_CALL</a></td><td> = </td><td>15</td><td> : failure doing an hypervisor call</td></tr><tr><td><a name="VIR_ERR_OS_TYPE" id="VIR_ERR_OS_TYPE">VIR_ERR_OS_TYPE</a></td><td> = </td><td>16</td><td> : unknown OS type</td></tr><tr><td><a name="VIR_ERR_NO_KERNEL" id="VIR_ERR_NO_KERNEL">VIR_ERR_NO_KERNEL</a></td><td> = </td><td>17</td><td> : missing kernel information</td></tr><tr><td><a name="VIR_ERR_NO_ROOT" id="VIR_ERR_NO_ROOT">VIR_ERR_NO_ROOT</a></td><td> = </td><td>18</td><td> : missing root device information</td></tr><tr><td><a name="VIR_ERR_NO_SOURCE" id="VIR_ERR_NO_SOURCE">VIR_ERR_NO_SOURCE</a></td><td> = </td><td>19</td><td> : missing source device ! information</td></tr><tr><td><a name="VIR_ERR_NO_TARGET" id="VIR_ERR_NO_TARGET">VIR_ERR_NO_TARGET</a></td><td> = </td><td>20</td><td> : missing target device information</td></tr><tr><td><a name="VIR_ERR_NO_NAME" id="VIR_ERR_NO_NAME">VIR_ERR_NO_NAME</a></td><td> = </td><td>21</td><td> : missing domain name information</td></tr><tr><td><a name="VIR_ERR_NO_OS" id="VIR_ERR_NO_OS">VIR_ERR_NO_OS</a></td><td> = </td><td>22</td><td> : missing domain OS information</td></tr><tr><td><a name="VIR_ERR_NO_DEVICE" id="VIR_ERR_NO_DEVICE">VIR_ERR_NO_DEVICE</a></td><td> = </td><td>23</td><td> : missing domain devices information</td></tr><tr><td><a name="VIR_ERR_NO_XENSTORE" id="VIR_ERR_NO_XENSTORE">VIR_ERR_NO_XENSTORE</a></td><td> = </td><td>24</td><td> : could not open Xen Store control</td></tr><tr><td><a name="VIR_ERR_DRIVER_FULL" id="VIR_ERR_DRIVER_FULL">VIR_ERR_DRIVER_FULL</a></td><td> = </td><td>25</td><td> : too many drivers registered</td></tr><tr><td><a name="VIR_ERR_CALL_FAILED"! id="VIR_ERR_CALL_FAILED">VIR_ERR_CALL_FAILED</a></td><td> = </td><td> 26</td><td> : not supported by the drivers (DEPRECATED)</td></tr><tr><td><a name="VIR_ERR_XML_ERROR" id="VIR_ERR_XML_ERROR">VIR_ERR_XML_ERROR</a></td><td> = </td><td>27</td><td> : an XML description is not well formed or broken</td></tr><tr><td><a name="VIR_ERR_DOM_EXIST" id="VIR_ERR_DOM_EXIST">VIR_ERR_DOM_EXIST</a></td><td> = </td><td>28</td><td> : the domain already exist</td></tr><tr><td><a name="VIR_ERR_OPERATION_DENIED" id="VIR_ERR_OPERATION_DENIED">VIR_ERR_OPERATION_DENIED</a></td><td> = </td><td>29</td><td> : operation forbidden on read-only connections</td></tr><tr><td><a name="VIR_ERR_OPEN_FAILED" id="VIR_ERR_OPEN_FAILED">VIR_ERR_OPEN_FAILED</a></td><td> = </td><td>30</td><td> : failed to open a conf file</td></tr><tr><td><a name="VIR_ERR_READ_FAILED" id="VIR_ERR_READ_FAILED">VIR_ERR_READ_FAILED</a></td><td> = </td><td>31</td><td> : failed to read a conf file</td></tr><tr><td><a name="VIR_ERR_PARSE_FAILED" id="VIR_ERR_PARSE_FAILED">VIR_ERR_PARSE_FAILED</a></td><td> ! = </td><td>32</td><td> : failed to parse a conf file</td></tr><tr><td><a name="VIR_ERR_CONF_SYNTAX" id="VIR_ERR_CONF_SYNTAX">VIR_ERR_CONF_SYNTAX</a></td><td> = </td><td>33</td><td> : failed to parse the syntax of a conf file</td></tr><tr><td><a name="VIR_ERR_WRITE_FAILED" id="VIR_ERR_WRITE_FAILED">VIR_ERR_WRITE_FAILED</a></td><td> = </td><td>34</td><td> : failed to write a conf file</td></tr><tr><td><a name="VIR_ERR_XML_DETAIL" id="VIR_ERR_XML_DETAIL">VIR_ERR_XML_DETAIL</a></td><td> = </td><td>35</td><td> : detail of an XML error</td></tr><tr><td><a name="VIR_ERR_INVALID_NETWORK" id="VIR_ERR_INVALID_NETWORK">VIR_ERR_INVALID_NETWORK</a></td><td> = </td><td>36</td><td> : invalid network object</td></tr><tr><td><a name="VIR_ERR_NETWORK_EXIST" id="VIR_ERR_NETWORK_EXIST">VIR_ERR_NETWORK_EXIST</a></td><td> = </td><td>37</td><td> : the network already exist</td></tr><tr><td><a name="VIR_ERR_SYSTEM_ERROR" id="VIR_ERR_SYSTEM_ERROR">VIR_ERR_SYSTEM_ERROR</a></td><td> = </td><td>38</td! ><td> : general system call failure</td></tr><tr><td><a name="VIR_ERR_ RPC" id="VIR_ERR_RPC">VIR_ERR_RPC</a></td><td> = </td><td>39</td><td> : some sort of RPC error</td></tr><tr><td><a name="VIR_ERR_GNUTLS_ERROR" id="VIR_ERR_GNUTLS_ERROR">VIR_ERR_GNUTLS_ERROR</a></td><td> = </td><td>40</td><td> : error from a GNUTLS call</td></tr><tr><td><a name="VIR_WAR_NO_NETWORK" id="VIR_WAR_NO_NETWORK">VIR_WAR_NO_NETWORK</a></td><td> = </td><td>41</td><td> : failed to start network</td></tr><tr><td><a name="VIR_ERR_NO_DOMAIN" id="VIR_ERR_NO_DOMAIN">VIR_ERR_NO_DOMAIN</a></td><td> = </td><td>42</td><td> : domain not found or unexpectedly disappeared</td></tr><tr><td><a name="VIR_ERR_NO_NETWORK" id="VIR_ERR_NO_NETWORK">VIR_ERR_NO_NETWORK</a></td><td> = </td><td>43</td><td> : network not found</td></tr><tr><td><a name="VIR_ERR_INVALID_MAC" id="VIR_ERR_INVALID_MAC">VIR_ERR_INVALID_MAC</a></td><td> = </td><td>44</td><td> : invalid MAC address</td></tr><tr><td><a name="VIR_ERR_AUTH_FAILED" id="VIR_ERR_AUTH_FAILED">VIR_ERR_AUTH_FAILED</a></td><td> = </td><td>45</t! d><td> : authentication failed</td></tr><tr><td><a name="VIR_ERR_INVALID_STORAGE_POOL" id="VIR_ERR_INVALID_STORAGE_POOL">VIR_ERR_INVALID_STORAGE_POOL</a></td><td> = </td><td>46</td><td> : invalid storage pool object</td></tr><tr><td><a name="VIR_ERR_INVALID_STORAGE_VOL" id="VIR_ERR_INVALID_STORAGE_VOL">VIR_ERR_INVALID_STORAGE_VOL</a></td><td> = </td><td>47</td><td> : invalid storage vol object</td></tr><tr><td><a name="VIR_WAR_NO_STORAGE" id="VIR_WAR_NO_STORAGE">VIR_WAR_NO_STORAGE</a></td><td> = </td><td>48</td><td> : failed to start storage</td></tr><tr><td><a name="VIR_ERR_NO_STORAGE_POOL" id="VIR_ERR_NO_STORAGE_POOL">VIR_ERR_NO_STORAGE_POOL</a></td><td> = </td><td>49</td><td> : storage pool not found</td></tr><tr><td><a name="VIR_ERR_NO_STORAGE_VOL" id="VIR_ERR_NO_STORAGE_VOL">VIR_ERR_NO_STORAGE_VOL</a></td><td> = </td><td>50</td><td> : storage pool not found</td></tr><tr><td><a name="VIR_WAR_NO_NODE" id="VIR_WAR_NO_NODE">VIR_WAR_NO_NODE</a></td><td> = </td><td>51</td><t! d> : failed to start node driver</td></tr><tr><td><a name="VIR_ERR_INV ALID_NODE_DEVICE" id="VIR_ERR_INVALID_NODE_DEVICE">VIR_ERR_INVALID_NODE_DEVICE</a></td><td> = </td><td>52</td><td> : invalid node device object</td></tr><tr><td><a name="VIR_ERR_NO_NODE_DEVICE" id="VIR_ERR_NO_NODE_DEVICE">VIR_ERR_NO_NODE_DEVICE</a></td><td> = </td><td>53</td><td> : node device not found</td></tr><tr><td><a name="VIR_ERR_NO_SECURITY_MODEL" id="VIR_ERR_NO_SECURITY_MODEL">VIR_ERR_NO_SECURITY_MODEL</a></td><td> = </td><td>54</td><td> : security model not found</td></tr><tr><td><a name="VIR_ERR_OPERATION_INVALID" id="VIR_ERR_OPERATION_INVALID">VIR_ERR_OPERATION_INVALID</a></td><td> = </td><td>55</td><td> : operation is not applicable at this time</td></tr><tr><td><a name="VIR_WAR_NO_INTERFACE" id="VIR_WAR_NO_INTERFACE">VIR_WAR_NO_INTERFACE</a></td><td> = </td><td>56</td><td> : failed to start interface driver</td></tr><tr><td><a name="VIR_ERR_NO_INTERFACE" id="VIR_ERR_NO_INTERFACE">VIR_ERR_NO_INTERFACE</a></td><td> = </td><td>57</td><td> : interface driver not ru! nning</td></tr><tr><td><a name="VIR_ERR_INVALID_INTERFACE" id="VIR_ERR_INVALID_INTERFACE">VIR_ERR_INVALID_INTERFACE</a></td><td> = </td><td>58</td><td> : invalid interface object</td></tr><tr><td><a name="VIR_ERR_MULTIPLE_INTERFACES" id="VIR_ERR_MULTIPLE_INTERFACES">VIR_ERR_MULTIPLE_INTERFACES</a></td><td> = </td><td>59</td><td> : more than one matching interface found</td></tr><tr><td><a name="VIR_WAR_NO_SECRET" id="VIR_WAR_NO_SECRET">VIR_WAR_NO_SECRET</a></td><td> = </td><td>60</td><td> : failed to start secret storage</td></tr><tr><td><a name="VIR_ERR_NO_SECRET" id="VIR_ERR_NO_SECRET">VIR_ERR_NO_SECRET</a></td><td> = </td><td>61</td><td> : secret not found</td></tr><tr><td><a name="VIR_ERR_INVALID_SECRET" id="VIR_ERR_INVALID_SECRET">VIR_ERR_INVALID_SECRET</a></td><td> = </td><td>62</td><td> : invalid secret</td></tr></table><pre>} </pre></div><h3><a name="functions" id="functions">Functions</a></h3><h3><a name="virConnCopyLastError" id="virConnCopyLastError"><code>virConnCopyLastError</code></a></h3><pre class="programlisting">int virConnCopyLastError (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn, <br /> <a href="libvirt-virterror.html#virErrorPtr">virErrorPtr</a> to)<br /> </pre><p>Copy the content of the last error caught on that connection This method is not protected against access from multiple threads. In a multi-threaded application, always use the global virGetLastError() API which is backed by thread local storage. If the connection object was discovered to be invalid by an API call, then the error will be reported against the global error object. Since 0.6.0, all errors reported in the per-connection object are also duplicated in the global error object. As such an application can always use virGetLastError(). This method remains for backwards compatability. One will need to free the result with virResetError()</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>to</tt></i>:</span></td><td>target to receive the copy</td></tr><tr><td><span class="term"><i><tt>Returns</tt>! </i>:</span></td><td>0 if no error was found and the error code otherwise and -1 in case of parameter error.</td></tr></tbody></table></div><h3><a name="virConnGetLastError" id="virConnGetLastError"><code>virConnGetLastError</code></a></h3><pre class="programlisting"><a href="libvirt-virterror.html#virErrorPtr">virErrorPtr</a> virConnGetLastError (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> </pre><p>Provide a pointer to the last error caught on that connection This method is not protected against access from multiple threads. In a multi-threaded application, always use the global virGetLastError() API which is backed by thread local storage. If the connection object was discovered to be invalid by an API call, then the error will be reported against the global error object. Since 0.6.0, all errors reported in the per-connection object are also duplicated in the global error object. As such an application can always use virGetLastError(). This method remains for backwards compatability.</p><div class="variablelist"><table border="0"><col align="left" /><tbody><tr><td><span class="term"><i><tt>conn</tt></i>:</span></td><td>pointer to the hypervisor connection</td></tr><tr><td><span class="term"><i><tt>Returns</tt></i>:</span></td><td>a pointer to the last error or NULL if none occurred.</td></tr></tbody></table></div><h3><a name="virConnResetLastError" id="virCo! nnResetLastError"><code>virConnResetLastError</code></a></h3><pre class="programlisting">void virConnResetLastError (<a href="libvirt-libvirt.html#virConnectPtr">virConnectPtr</a> conn)<br /> diff --git a/docs/libvirt-api.xml b/docs/libvirt-api.xml index 8ded57a..fd52e62 100644 --- a/docs/libvirt-api.xml +++ b/docs/libvirt-api.xml @@ -51,6 +51,7 @@ <exports symbol='VIR_CRED_USERNAME' type='enum'/> <exports symbol='VIR_DOMAIN_EVENT_RESUMED_UNPAUSED' type='enum'/> <exports symbol='VIR_DOMAIN_RUNNING' type='enum'/> + <exports symbol='VIR_STORAGE_VOL_DELETE_ZEROED' type='enum'/> <exports symbol='VIR_EVENT_HANDLE_ERROR' type='enum'/> <exports symbol='VIR_DOMAIN_NOSTATE' type='enum'/> <exports symbol='VIR_DOMAIN_SHUTOFF' type='enum'/> @@ -60,7 +61,7 @@ <exports symbol='VIR_STORAGE_POOL_BUILD_NEW' type='enum'/> <exports symbol='VIR_DOMAIN_EVENT_SUSPENDED_PAUSED' type='enum'/> <exports symbol='VIR_STORAGE_POOL_DELETE_NORMAL' type='enum'/> - <exports symbol='VIR_STORAGE_VOL_DELETE_ZEROED' type='enum'/> + <exports symbol='VIR_MEMORY_PHYSICAL' type='enum'/> <exports symbol='VIR_DOMAIN_SCHED_FIELD_INT' type='enum'/> <exports symbol='VIR_DOMAIN_SCHED_FIELD_ULLONG' type='enum'/> <exports symbol='VIR_DOMAIN_EVENT_STOPPED_SHUTDOWN' type='enum'/> @@ -181,7 +182,7 @@ <exports symbol='virDomainGetSchedulerParameters' type='function'/> <exports symbol='virDomainLookupByUUIDString' type='function'/> <exports symbol='virConnectNumOfDefinedNetworks' type='function'/> - <exports symbol='virConnectNumOfDomains' type='function'/> + <exports symbol='virConnectListDefinedInterfaces' type='function'/> <exports symbol='virNetworkGetUUID' type='function'/> <exports symbol='virInterfaceGetXMLDesc' type='function'/> <exports symbol='virStoragePoolGetConnect' type='function'/> @@ -198,6 +199,7 @@ <exports symbol='virEventRegisterImpl' type='function'/> <exports symbol='virInterfaceDefineXML' type='function'/> <exports symbol='virDomainMigrate' type='function'/> + <exports symbol='virSecretNumOfSecrets' type='function'/> <exports symbol='virDomainSuspend' type='function'/> <exports symbol='virDomainCreateLinux' type='function'/> <exports symbol='virNodeDeviceGetXMLDesc' type='function'/> @@ -222,17 +224,20 @@ <exports symbol='virDomainSetSchedulerParameters' type='function'/> <exports symbol='virConnectGetType' type='function'/> <exports symbol='virStorageVolCreateXML' type='function'/> + <exports symbol='virSecretSetXML' type='function'/> <exports symbol='virDomainSave' type='function'/> <exports symbol='virDomainCreate' type='function'/> <exports symbol='virConnectListDomains' type='function'/> <exports symbol='virDomainCoreDump' type='function'/> <exports symbol='virDomainSetMemory' type='function'/> + <exports symbol='virSecretDelete' type='function'/> <exports symbol='virInterfaceGetName' type='function'/> <exports symbol='virStoragePoolCreate' type='function'/> <exports symbol='virNodeGetInfo' type='function'/> <exports symbol='virNetworkSetAutostart' type='function'/> <exports symbol='virDomainGetMaxMemory' type='function'/> <exports symbol='virStoragePoolFree' type='function'/> + <exports symbol='virConnectNumOfDefinedInterfaces' type='function'/> <exports symbol='virFreeCallback' type='function'/> <exports symbol='virNetworkDefineXML' type='function'/> <exports symbol='virNodeDeviceListCaps' type='function'/> @@ -259,8 +264,10 @@ <exports symbol='virDomainPinVcpu' type='function'/> <exports symbol='virNodeGetSecurityModel' type='function'/> <exports symbol='virDomainRestore' type='function'/> + <exports symbol='virSecretAllocateID' type='function'/> <exports symbol='virNodeDeviceDestroy' type='function'/> <exports symbol='virStorageVolGetPath' type='function'/> + <exports symbol='virSecretGetXML' type='function'/> <exports symbol='virNetworkLookupByUUIDString' type='function'/> <exports symbol='virConnectDomainEventCallback' type='function'/> <exports symbol='virDomainLookupByID' type='function'/> @@ -273,6 +280,7 @@ <exports symbol='virConnectRef' type='function'/> <exports symbol='virDomainGetUUID' type='function'/> <exports symbol='virNetworkCreateXML' type='function'/> + <exports symbol='virNetworkUndefine' type='function'/> <exports symbol='virConnectDomainEventRegister' type='function'/> <exports symbol='virDomainGetVcpus' type='function'/> <exports symbol='virNodeDeviceLookupByName' type='function'/> @@ -280,7 +288,7 @@ <exports symbol='virDomainResume' type='function'/> <exports symbol='virInterfaceRef' type='function'/> <exports symbol='virInterfaceGetMACString' type='function'/> - <exports symbol='virNetworkRef' type='function'/> + <exports symbol='virConnectNumOfDomains' type='function'/> <exports symbol='virStoragePoolRefresh' type='function'/> <exports symbol='virConnectNumOfDefinedDomains' type='function'/> <exports symbol='virStorageVolCreateXMLFrom' type='function'/> @@ -304,7 +312,7 @@ <exports symbol='virNetworkFree' type='function'/> <exports symbol='virStoragePoolLookupByUUID' type='function'/> <exports symbol='virEventAddHandleFunc' type='function'/> - <exports symbol='virNetworkUndefine' type='function'/> + <exports symbol='virNetworkRef' type='function'/> <exports symbol='virConnectListDefinedStoragePools' type='function'/> <exports symbol='virEventTimeoutCallback' type='function'/> <exports symbol='virInterfaceFree' type='function'/> @@ -313,11 +321,13 @@ <exports symbol='virNetworkGetConnect' type='function'/> <exports symbol='virNodeGetFreeMemory' type='function'/> <exports symbol='virInterfaceDestroy' type='function'/> + <exports symbol='virSecretSetValue' type='function'/> <exports symbol='virStorageVolGetConnect' type='function'/> <exports symbol='virNodeNumOfDevices' type='function'/> <exports symbol='virStoragePoolDestroy' type='function'/> <exports symbol='virStoragePoolLookupByVolume' type='function'/> <exports symbol='virDomainLookupByUUID' type='function'/> + <exports symbol='virSecretListSecrets' type='function'/> <exports symbol='virDomainGetOSType' type='function'/> <exports symbol='virStoragePoolBuild' type='function'/> <exports symbol='virConnectGetMaxVcpus' type='function'/> @@ -339,6 +349,7 @@ <exports symbol='virInterfaceLookupByName' type='function'/> <exports symbol='virDomainInterfaceStats' type='function'/> <exports symbol='virConnectListNetworks' type='function'/> + <exports symbol='virSecretGetValue' type='function'/> <exports symbol='virStorageVolLookupByKey' type='function'/> </file> <file name='virterror'> @@ -352,12 +363,14 @@ <exports symbol='VIR_ERR_NO_MEMORY' type='enum'/> <exports symbol='VIR_WAR_NO_NODE' type='enum'/> <exports symbol='VIR_ERR_NO_STORAGE_VOL' type='enum'/> + <exports symbol='VIR_FROM_XML' type='enum'/> <exports symbol='VIR_FROM_CONF' type='enum'/> <exports symbol='VIR_ERR_INVALID_NETWORK' type='enum'/> <exports symbol='VIR_ERR_PARSE_FAILED' type='enum'/> <exports symbol='VIR_ERR_POST_FAILED' type='enum'/> <exports symbol='VIR_ERR_INVALID_CONN' type='enum'/> <exports symbol='VIR_ERR_GET_FAILED' type='enum'/> + <exports symbol='VIR_FROM_XEN' type='enum'/> <exports symbol='VIR_ERR_NO_SOURCE' type='enum'/> <exports symbol='VIR_ERR_NETWORK_EXIST' type='enum'/> <exports symbol='VIR_ERR_NONE' type='enum'/> @@ -367,9 +380,10 @@ <exports symbol='VIR_ERR_READ_FAILED' type='enum'/> <exports symbol='VIR_FROM_INTERFACE' type='enum'/> <exports symbol='VIR_ERR_NO_CONNECT' type='enum'/> - <exports symbol='VIR_ERR_CALL_FAILED' type='enum'/> + <exports symbol='VIR_FROM_ESX' type='enum'/> <exports symbol='VIR_FROM_VBOX' type='enum'/> <exports symbol='VIR_FROM_TEST' type='enum'/> + <exports symbol='VIR_ERR_MULTIPLE_INTERFACES' type='enum'/> <exports symbol='VIR_ERR_NO_DEVICE' type='enum'/> <exports symbol='VIR_FROM_SEXPR' type='enum'/> <exports symbol='VIR_ERR_INVALID_MAC' type='enum'/> @@ -379,6 +393,7 @@ <exports symbol='VIR_FROM_STATS_LINUX' type='enum'/> <exports symbol='VIR_FROM_OPENVZ' type='enum'/> <exports symbol='VIR_ERR_OS_TYPE' type='enum'/> + <exports symbol='VIR_WAR_NO_SECRET' type='enum'/> <exports symbol='VIR_WAR_NO_NETWORK' type='enum'/> <exports symbol='VIR_FROM_UML' type='enum'/> <exports symbol='VIR_ERR_NO_NAME' type='enum'/> @@ -390,6 +405,7 @@ <exports symbol='VIR_ERR_CONF_SYNTAX' type='enum'/> <exports symbol='VIR_ERR_NO_SUPPORT' type='enum'/> <exports symbol='VIR_ERR_NO_SECURITY_MODEL' type='enum'/> + <exports symbol='VIR_FROM_PHYP' type='enum'/> <exports symbol='VIR_ERR_SEXPR_SERIAL' type='enum'/> <exports symbol='VIR_FROM_XENSTORE' type='enum'/> <exports symbol='VIR_ERR_OPEN_FAILED' type='enum'/> @@ -403,20 +419,22 @@ <exports symbol='VIR_ERR_GNUTLS_ERROR' type='enum'/> <exports symbol='VIR_ERR_XML_ERROR' type='enum'/> <exports symbol='VIR_ERR_OK' type='enum'/> - <exports symbol='VIR_ERR_INVALID_INTERFACE' type='enum'/> <exports symbol='VIR_FROM_STORAGE' type='enum'/> <exports symbol='VIR_FROM_PROXY' type='enum'/> <exports symbol='VIR_ERR_DRIVER_FULL' type='enum'/> <exports symbol='VIR_FROM_DOMAIN' type='enum'/> - <exports symbol='VIR_FROM_XML' type='enum'/> + <exports symbol='VIR_ERR_INVALID_SECRET' type='enum'/> <exports symbol='VIR_ERR_OPERATION_DENIED' type='enum'/> <exports symbol='VIR_ERR_INVALID_STORAGE_POOL' type='enum'/> + <exports symbol='VIR_FROM_SECRET' type='enum'/> <exports symbol='VIR_ERR_NO_DOMAIN' type='enum'/> - <exports symbol='VIR_FROM_XEN' type='enum'/> + <exports symbol='VIR_ERR_INVALID_INTERFACE' type='enum'/> <exports symbol='VIR_ERR_RPC' type='enum'/> <exports symbol='VIR_ERR_WARNING' type='enum'/> <exports symbol='VIR_ERR_INVALID_ARG' type='enum'/> + <exports symbol='VIR_ERR_CALL_FAILED' type='enum'/> <exports symbol='VIR_ERR_ERROR' type='enum'/> + <exports symbol='VIR_ERR_NO_SECRET' type='enum'/> <exports symbol='VIR_WAR_NO_INTERFACE' type='enum'/> <exports symbol='VIR_ERR_DOM_EXIST' type='enum'/> <exports symbol='VIR_FROM_LXC' type='enum'/> @@ -577,12 +595,14 @@ <enum name='VIR_ERR_INVALID_ARG' file='virterror' value='8' type='virErrorNumber' info='invalid function argument'/> <enum name='VIR_ERR_INVALID_CONN' file='virterror' value='6' type='virErrorNumber' info='invalid connection object'/> <enum name='VIR_ERR_INVALID_DOMAIN' file='virterror' value='7' type='virErrorNumber' info='invalid domain object'/> - <enum name='VIR_ERR_INVALID_INTERFACE' file='virterror' value='58' type='virErrorNumber' info=' invalid interface object'/> + <enum name='VIR_ERR_INVALID_INTERFACE' file='virterror' value='58' type='virErrorNumber' info='invalid interface object'/> <enum name='VIR_ERR_INVALID_MAC' file='virterror' value='44' type='virErrorNumber' info='invalid MAC address'/> <enum name='VIR_ERR_INVALID_NETWORK' file='virterror' value='36' type='virErrorNumber' info='invalid network object'/> <enum name='VIR_ERR_INVALID_NODE_DEVICE' file='virterror' value='52' type='virErrorNumber' info='invalid node device object'/> + <enum name='VIR_ERR_INVALID_SECRET' file='virterror' value='62' type='virErrorNumber' info=' invalid secret'/> <enum name='VIR_ERR_INVALID_STORAGE_POOL' file='virterror' value='46' type='virErrorNumber' info='invalid storage pool object'/> <enum name='VIR_ERR_INVALID_STORAGE_VOL' file='virterror' value='47' type='virErrorNumber' info='invalid storage vol object'/> + <enum name='VIR_ERR_MULTIPLE_INTERFACES' file='virterror' value='59' type='virErrorNumber' info='more than one matching interface found'/> <enum name='VIR_ERR_NETWORK_EXIST' file='virterror' value='37' type='virErrorNumber' info='the network already exist'/> <enum name='VIR_ERR_NONE' file='virterror' value='0' type='virErrorLevel'/> <enum name='VIR_ERR_NO_CONNECT' file='virterror' value='5' type='virErrorNumber' info='can't connect to hypervisor'/> @@ -596,6 +616,7 @@ <enum name='VIR_ERR_NO_NODE_DEVICE' file='virterror' value='53' type='virErrorNumber' info='node device not found'/> <enum name='VIR_ERR_NO_OS' file='virterror' value='22' type='virErrorNumber' info='missing domain OS information'/> <enum name='VIR_ERR_NO_ROOT' file='virterror' value='18' type='virErrorNumber' info='missing root device information'/> + <enum name='VIR_ERR_NO_SECRET' file='virterror' value='61' type='virErrorNumber' info='secret not found'/> <enum name='VIR_ERR_NO_SECURITY_MODEL' file='virterror' value='54' type='virErrorNumber' info='security model not found'/> <enum name='VIR_ERR_NO_SOURCE' file='virterror' value='19' type='virErrorNumber' info='missing source device information'/> <enum name='VIR_ERR_NO_STORAGE_POOL' file='virterror' value='49' type='virErrorNumber' info='storage pool not found'/> @@ -629,18 +650,21 @@ <enum name='VIR_FROM_CONF' file='virterror' value='9' type='virErrorDomain' info='Error in the configuration file handling'/> <enum name='VIR_FROM_DOM' file='virterror' value='6' type='virErrorDomain' info='Error when operating on a domain'/> <enum name='VIR_FROM_DOMAIN' file='virterror' value='20' type='virErrorDomain' info='Error from domain config'/> + <enum name='VIR_FROM_ESX' file='virterror' value='28' type='virErrorDomain' info='Error from ESX driver'/> <enum name='VIR_FROM_INTERFACE' file='virterror' value='26' type='virErrorDomain' info='Error when operating on an interface'/> <enum name='VIR_FROM_LXC' file='virterror' value='17' type='virErrorDomain' info='Error from Linux Container driver'/> <enum name='VIR_FROM_NET' file='virterror' value='11' type='virErrorDomain' info='Error when operating on a network'/> <enum name='VIR_FROM_NETWORK' file='virterror' value='19' type='virErrorDomain' info='Error from network config'/> <enum name='VIR_FROM_NODEDEV' file='virterror' value='22' type='virErrorDomain' info='Error from node device monitor'/> <enum name='VIR_FROM_NONE' file='virterror' value='0' type='virErrorDomain'/> - <enum name='VIR_FROM_ONE' file='virterror' value='27' type='virErrorDomain' info=' Error from OpenNebula driver'/> + <enum name='VIR_FROM_ONE' file='virterror' value='27' type='virErrorDomain' info='Error from OpenNebula driver'/> <enum name='VIR_FROM_OPENVZ' file='virterror' value='14' type='virErrorDomain' info='Error from OpenVZ driver'/> + <enum name='VIR_FROM_PHYP' file='virterror' value='29' type='virErrorDomain' info='Error from IBM power hypervisor'/> <enum name='VIR_FROM_PROXY' file='virterror' value='8' type='virErrorDomain' info='Error in the proxy code'/> <enum name='VIR_FROM_QEMU' file='virterror' value='10' type='virErrorDomain' info='Error at the QEMU daemon'/> <enum name='VIR_FROM_REMOTE' file='virterror' value='13' type='virErrorDomain' info='Error from remote driver'/> <enum name='VIR_FROM_RPC' file='virterror' value='7' type='virErrorDomain' info='Error in the XML-RPC code'/> + <enum name='VIR_FROM_SECRET' file='virterror' value='30' type='virErrorDomain' info=' Error from secret storage'/> <enum name='VIR_FROM_SECURITY' file='virterror' value='24' type='virErrorDomain' info='Error from security framework'/> <enum name='VIR_FROM_SEXPR' file='virterror' value='4' type='virErrorDomain' info='Error in the S-Expression code'/> <enum name='VIR_FROM_STATS_LINUX' file='virterror' value='16' type='virErrorDomain' info='Error in the Linux Stats code'/> @@ -654,7 +678,8 @@ <enum name='VIR_FROM_XENXM' file='virterror' value='15' type='virErrorDomain' info='Error at Xen XM layer'/> <enum name='VIR_FROM_XEN_INOTIFY' file='virterror' value='23' type='virErrorDomain' info='Error from xen inotify layer'/> <enum name='VIR_FROM_XML' file='virterror' value='5' type='virErrorDomain' info='Error in the XML code'/> - <enum name='VIR_MEMORY_VIRTUAL' file='libvirt' value='1' type='virDomainMemoryFlags' info=' addresses are virtual addresses'/> + <enum name='VIR_MEMORY_PHYSICAL' file='libvirt' value='2' type='virDomainMemoryFlags' info=' addresses are physical addresses'/> + <enum name='VIR_MEMORY_VIRTUAL' file='libvirt' value='1' type='virDomainMemoryFlags' info='addresses are virtual addresses'/> <enum name='VIR_MIGRATE_LIVE' file='libvirt' value='1' type='virDomainMigrateFlags' info=' live migration'/> <enum name='VIR_STORAGE_POOL_BUILDING' file='libvirt' value='1' type='virStoragePoolState' info='Initializing pool, not available'/> <enum name='VIR_STORAGE_POOL_BUILD_NEW' file='libvirt' value='0' type='virStoragePoolBuildFlags' info='Regular build from scratch'/> @@ -675,6 +700,7 @@ <enum name='VIR_WAR_NO_INTERFACE' file='virterror' value='56' type='virErrorNumber' info='failed to start interface driver'/> <enum name='VIR_WAR_NO_NETWORK' file='virterror' value='41' type='virErrorNumber' info='failed to start network'/> <enum name='VIR_WAR_NO_NODE' file='virterror' value='51' type='virErrorNumber' info='failed to start node driver'/> + <enum name='VIR_WAR_NO_SECRET' file='virterror' value='60' type='virErrorNumber' info='failed to start secret storage'/> <enum name='VIR_WAR_NO_STORAGE' file='virterror' value='48' type='virErrorNumber' info='failed to start storage'/> <struct name='virConnect' file='libvirt' type='struct _virConnect'/> <struct name='virConnectAuth' file='libvirt' type='struct _virConnectAuth'> @@ -966,6 +992,13 @@ see note above'/> <arg name='names' type='char ** const' info='pointer to an array to store the names'/> <arg name='maxnames' type='int' info='size of the array'/> </function> + <function name='virConnectListDefinedInterfaces' file='libvirt' module='libvirt'> + <info>Collect the list of defined (inactive) physical host interfaces, and store their names in @names.</info> + <return type='int' info='the number of interfaces found or -1 in case of error'/> + <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/> + <arg name='names' type='char ** const' info='array to collect the list of names of interfaces'/> + <arg name='maxnames' type='int' info='size of @names'/> + </function> <function name='virConnectListDefinedNetworks' file='libvirt' module='libvirt'> <info>list the inactive networks, stores the pointers to the names in @names</info> <return type='int' info='the number of names provided in the array or -1 in case of error'/> @@ -988,7 +1021,7 @@ see note above'/> <arg name='maxids' type='int' info='size of @ids'/> </function> <function name='virConnectListInterfaces' file='libvirt' module='libvirt'> - <info>Collect the list of physical host interfaces, and store their names in @names</info> + <info>Collect the list of active physical host interfaces, and store their names in @names</info> <return type='int' info='the number of interfaces found or -1 in case of error'/> <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/> <arg name='names' type='char ** const' info='array to collect the list of names of interfaces'/> @@ -1013,6 +1046,11 @@ see note above'/> <return type='int' info='the number of domain found or -1 in case of error'/> <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/> </function> + <function name='virConnectNumOfDefinedInterfaces' file='libvirt' module='libvirt'> + <info>Provides the number of defined (inactive) interfaces on the physical host.</info> + <return type='int' info='the number of defined interface found or -1 in case of error'/> + <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/> + </function> <function name='virConnectNumOfDefinedNetworks' file='libvirt' module='libvirt'> <info>Provides the number of inactive networks.</info> <return type='int' info='the number of networks found or -1 in case of error'/> @@ -1029,8 +1067,8 @@ see note above'/> <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/> </function> <function name='virConnectNumOfInterfaces' file='libvirt' module='libvirt'> - <info>Provides the number of interfaces on the physical host.</info> - <return type='int' info='the number of interface found or -1 in case of error'/> + <info>Provides the number of active interfaces on the physical host.</info> + <return type='int' info='the number of active interfaces found or -1 in case of error'/> <arg name='conn' type='virConnectPtr' info='pointer to the hypervisor connection'/> </function> <function name='virConnectNumOfNetworks' file='libvirt' module='libvirt'> @@ -1045,18 +1083,18 @@ see note above'/> </function> <function name='virConnectOpen' file='libvirt' module='libvirt'> <info>This function should be called first to get a connection to the Hypervisor and xen store</info> - <return type='virConnectPtr' info='a pointer to the hypervisor connection or NULL in case of error URIs are documented at http://libvirt.org/uri.html'/> + <return type='virConnectPtr' info='a pointer to the hypervisor connection or NULL in case of error If @name is NULL then probing will be done to determine a suitable default driver to activate. This involves trying each hypervisor in turn until one successfully opens. If the LIBVIRT_DEFAULT_URI environment variable is set, then it will be used in preference to probing for a driver. If connecting to an unprivileged hypervisor driver which requires the libvirtd daemon to be active, it will automatically be launched if not already running. This can be prevented by setting the environment variable LIBVIRT_AUTOSTART=0 URIs are documented at http://libvirt.org/uri.html'/> <arg name='name' type='const char *' info='URI of the hypervisor'/> </function> <function name='virConnectOpenAuth' file='libvirt' module='libvirt'> - <info>This function should be called first to get a connection to the Hypervisor. If necessary, authentication will be performed fetching credentials via the callback</info> + <info>This function should be called first to get a connection to the Hypervisor. If necessary, authentication will be performed fetching credentials via the callback See virConnectOpen for notes about environment variables which can have an effect on opening drivers</info> <return type='virConnectPtr' info='a pointer to the hypervisor connection or NULL in case of error URIs are documented at http://libvirt.org/uri.html'/> <arg name='name' type='const char *' info='URI of the hypervisor'/> <arg name='auth' type='virConnectAuthPtr' info='Authenticate callback parameters'/> <arg name='flags' type='int' info='Open flags'/> </function> <function name='virConnectOpenReadOnly' file='libvirt' module='libvirt'> - <info>This function should be called first to get a restricted connection to the library functionalities. The set of APIs usable are then restricted on the available methods to control the domains.</info> + <info>This function should be called first to get a restricted connection to the library functionalities. The set of APIs usable are then restricted on the available methods to control the domains. See virConnectOpen for notes about environment variables which can have an effect on opening drivers</info> <return type='virConnectPtr' info='a pointer to the hypervisor connection or NULL in case of error URIs are documented at http://libvirt.org/uri.html'/> <arg name='name' type='const char *' info='URI of the hypervisor'/> </function> @@ -1754,6 +1792,57 @@ see note above'/> <info>Save the last error into a new error object.</info> <return type='virErrorPtr' info='a pointer to the copied error or NULL if allocation failed. It is the caller's responsibility to free the error with virFreeError().'/> </function> + <function name='virSecretAllocateID' file='libvirt' module='libvirt'> + <info>Allocates a secret ID (a printable string) without associating a secret value with the ID.</info> + <return type='char *' info='the secret ID on success, or NULL on failure. The caller must free() the secret ID.'/> + <arg name='conn' type='virConnectPtr' info='virConnect connection'/> + </function> + <function name='virSecretDelete' file='libvirt' module='libvirt'> + <info>Deletes the secret with secret_id (including the secret value and all attributes).</info> + <return type='int' info='0 on success, -1 on failure.'/> + <arg name='conn' type='virConnectPtr' info='virConnect connection'/> + <arg name='secret_id' type='const char *' info='A secret ID'/> + </function> + <function name='virSecretGetValue' file='libvirt' module='libvirt'> + <info>Fetches the secret value associated with secret_id.</info> + <return type='void *' info='the secret value on success, NULL on failure. The caller must free() the secret value.'/> + <arg name='conn' type='virConnectPtr' info='virConnect connection'/> + <arg name='secret_id' type='const char *' info='A secret ID'/> + <arg name='secret_size' type='size_t *' info='Place for storing size of the secret'/> + </function> + <function name='virSecretGetXML' file='libvirt' module='libvirt'> + <info>Fetches an XML document describing attributes of the secret.</info> + <return type='char *' info='the XML document on success, NULL on failure. The caller must free() the XML.'/> + <arg name='conn' type='virConnectPtr' info='virConnect connection'/> + <arg name='secret_id' type='const char *' info='A secret ID'/> + </function> + <function name='virSecretListSecrets' file='libvirt' module='libvirt'> + <info>List the defined secret IDs, store pointers to names in ids.</info> + <return type='int' info='the number of IDs provided in the array, or -1 on failure.'/> + <arg name='conn' type='virConnectPtr' info='virConnect connection'/> + <arg name='ids' type='char **' info='Pointer to an array to store the IDs'/> + <arg name='maxids' type='int' info='size of the array.'/> + </function> + <function name='virSecretNumOfSecrets' file='libvirt' module='libvirt'> + <info>Fetch number of currently defined secret IDs.</info> + <return type='int' info='the number currently defined secret IDs.'/> + <arg name='conn' type='virConnectPtr' info='virConnect connection'/> + </function> + <function name='virSecretSetValue' file='libvirt' module='libvirt'> + <info>Associates a secret value with secret_id. Allocates secret_id if it was not previously allocated.</info> + <return type='int' info='0 on success, -1 on failure.'/> + <arg name='conn' type='virConnectPtr' info='virConnect connection'/> + <arg name='secret_id' type='const char *' info='A secret ID'/> + <arg name='secret' type='const void *' info='The secret'/> + <arg name='secret_size' type='size_t' info='Size of the secret'/> + </function> + <function name='virSecretSetXML' file='libvirt' module='libvirt'> + <info>Replaces all attributes of the secret specified by secret_id by attributes specified in xml (any attributes not specified in xml are discarded). Allocates secret_id if it was not previously allocated.</info> + <return type='int' info='0 on success, -1 on failure.'/> + <arg name='conn' type='virConnectPtr' info='virConnect connection'/> + <arg name='secret_id' type='const char *' info='A secret ID'/> + <arg name='xml' type='const char *' info='XML containing attributes of the secret.'/> + </function> <function name='virSetErrorFunc' file='virterror' module='virterror'> <info>Set a library global error handling function, if @handler is NULL, it will reset to default printing on stderr. The error raised there are those for which no handler at the connection level could caught.</info> <return type='void'/> @@ -1896,7 +1985,7 @@ see note above'/> </function> <function name='virStoragePoolUndefine' file='libvirt' module='libvirt'> <info>Undefine an inactive storage pool</info> - <return type='int' info='a virStoragePoolPtr object, or NULL if creation failed'/> + <return type='int' info='0 on success, -1 on failure'/> <arg name='pool' type='virStoragePoolPtr' info='pointer to storage pool'/> </function> <function name='virStorageVolCreateXML' file='libvirt' module='libvirt'> diff --git a/docs/libvirt-refs.xml b/docs/libvirt-refs.xml index 2f8ffe5..e6dd007 100644 --- a/docs/libvirt-refs.xml +++ b/docs/libvirt-refs.xml @@ -71,8 +71,10 @@ <reference name='VIR_ERR_INVALID_MAC' href='html/libvirt-virterror.html#VIR_ERR_INVALID_MAC'/> <reference name='VIR_ERR_INVALID_NETWORK' href='html/libvirt-virterror.html#VIR_ERR_INVALID_NETWORK'/> <reference name='VIR_ERR_INVALID_NODE_DEVICE' href='html/libvirt-virterror.html#VIR_ERR_INVALID_NODE_DEVICE'/> + <reference name='VIR_ERR_INVALID_SECRET' href='html/libvirt-virterror.html#VIR_ERR_INVALID_SECRET'/> <reference name='VIR_ERR_INVALID_STORAGE_POOL' href='html/libvirt-virterror.html#VIR_ERR_INVALID_STORAGE_POOL'/> <reference name='VIR_ERR_INVALID_STORAGE_VOL' href='html/libvirt-virterror.html#VIR_ERR_INVALID_STORAGE_VOL'/> + <reference name='VIR_ERR_MULTIPLE_INTERFACES' href='html/libvirt-virterror.html#VIR_ERR_MULTIPLE_INTERFACES'/> <reference name='VIR_ERR_NETWORK_EXIST' href='html/libvirt-virterror.html#VIR_ERR_NETWORK_EXIST'/> <reference name='VIR_ERR_NONE' href='html/libvirt-virterror.html#VIR_ERR_NONE'/> <reference name='VIR_ERR_NO_CONNECT' href='html/libvirt-virterror.html#VIR_ERR_NO_CONNECT'/> @@ -86,6 +88,7 @@ <reference name='VIR_ERR_NO_NODE_DEVICE' href='html/libvirt-virterror.html#VIR_ERR_NO_NODE_DEVICE'/> <reference name='VIR_ERR_NO_OS' href='html/libvirt-virterror.html#VIR_ERR_NO_OS'/> <reference name='VIR_ERR_NO_ROOT' href='html/libvirt-virterror.html#VIR_ERR_NO_ROOT'/> + <reference name='VIR_ERR_NO_SECRET' href='html/libvirt-virterror.html#VIR_ERR_NO_SECRET'/> <reference name='VIR_ERR_NO_SECURITY_MODEL' href='html/libvirt-virterror.html#VIR_ERR_NO_SECURITY_MODEL'/> <reference name='VIR_ERR_NO_SOURCE' href='html/libvirt-virterror.html#VIR_ERR_NO_SOURCE'/> <reference name='VIR_ERR_NO_STORAGE_POOL' href='html/libvirt-virterror.html#VIR_ERR_NO_STORAGE_POOL'/> @@ -119,6 +122,7 @@ <reference name='VIR_FROM_CONF' href='html/libvirt-virterror.html#VIR_FROM_CONF'/> <reference name='VIR_FROM_DOM' href='html/libvirt-virterror.html#VIR_FROM_DOM'/> <reference name='VIR_FROM_DOMAIN' href='html/libvirt-virterror.html#VIR_FROM_DOMAIN'/> + <reference name='VIR_FROM_ESX' href='html/libvirt-virterror.html#VIR_FROM_ESX'/> <reference name='VIR_FROM_INTERFACE' href='html/libvirt-virterror.html#VIR_FROM_INTERFACE'/> <reference name='VIR_FROM_LXC' href='html/libvirt-virterror.html#VIR_FROM_LXC'/> <reference name='VIR_FROM_NET' href='html/libvirt-virterror.html#VIR_FROM_NET'/> @@ -127,10 +131,12 @@ <reference name='VIR_FROM_NONE' href='html/libvirt-virterror.html#VIR_FROM_NONE'/> <reference name='VIR_FROM_ONE' href='html/libvirt-virterror.html#VIR_FROM_ONE'/> <reference name='VIR_FROM_OPENVZ' href='html/libvirt-virterror.html#VIR_FROM_OPENVZ'/> + <reference name='VIR_FROM_PHYP' href='html/libvirt-virterror.html#VIR_FROM_PHYP'/> <reference name='VIR_FROM_PROXY' href='html/libvirt-virterror.html#VIR_FROM_PROXY'/> <reference name='VIR_FROM_QEMU' href='html/libvirt-virterror.html#VIR_FROM_QEMU'/> <reference name='VIR_FROM_REMOTE' href='html/libvirt-virterror.html#VIR_FROM_REMOTE'/> <reference name='VIR_FROM_RPC' href='html/libvirt-virterror.html#VIR_FROM_RPC'/> + <reference name='VIR_FROM_SECRET' href='html/libvirt-virterror.html#VIR_FROM_SECRET'/> <reference name='VIR_FROM_SECURITY' href='html/libvirt-virterror.html#VIR_FROM_SECURITY'/> <reference name='VIR_FROM_SEXPR' href='html/libvirt-virterror.html#VIR_FROM_SEXPR'/> <reference name='VIR_FROM_STATS_LINUX' href='html/libvirt-virterror.html#VIR_FROM_STATS_LINUX'/> @@ -145,6 +151,7 @@ <reference name='VIR_FROM_XEN_INOTIFY' href='html/libvirt-virterror.html#VIR_FROM_XEN_INOTIFY'/> <reference name='VIR_FROM_XML' href='html/libvirt-virterror.html#VIR_FROM_XML'/> <reference name='VIR_GET_CPUMAP' href='html/libvirt-libvirt.html#VIR_GET_CPUMAP'/> + <reference name='VIR_MEMORY_PHYSICAL' href='html/libvirt-libvirt.html#VIR_MEMORY_PHYSICAL'/> <reference name='VIR_MEMORY_VIRTUAL' href='html/libvirt-libvirt.html#VIR_MEMORY_VIRTUAL'/> <reference name='VIR_MIGRATE_LIVE' href='html/libvirt-libvirt.html#VIR_MIGRATE_LIVE'/> <reference name='VIR_NODEINFO_MAXCPUS' href='html/libvirt-libvirt.html#VIR_NODEINFO_MAXCPUS'/> @@ -174,6 +181,7 @@ <reference name='VIR_WAR_NO_INTERFACE' href='html/libvirt-virterror.html#VIR_WAR_NO_INTERFACE'/> <reference name='VIR_WAR_NO_NETWORK' href='html/libvirt-virterror.html#VIR_WAR_NO_NETWORK'/> <reference name='VIR_WAR_NO_NODE' href='html/libvirt-virterror.html#VIR_WAR_NO_NODE'/> + <reference name='VIR_WAR_NO_SECRET' href='html/libvirt-virterror.html#VIR_WAR_NO_SECRET'/> <reference name='VIR_WAR_NO_STORAGE' href='html/libvirt-virterror.html#VIR_WAR_NO_STORAGE'/> <reference name='_virConnectAuth' href='html/libvirt-libvirt.html#_virConnectAuth'/> <reference name='_virConnectCredential' href='html/libvirt-libvirt.html#_virConnectCredential'/> @@ -215,6 +223,7 @@ <reference name='virConnectGetURI' href='html/libvirt-libvirt.html#virConnectGetURI'/> <reference name='virConnectGetVersion' href='html/libvirt-libvirt.html#virConnectGetVersion'/> <reference name='virConnectListDefinedDomains' href='html/libvirt-libvirt.html#virConnectListDefinedDomains'/> + <reference name='virConnectListDefinedInterfaces' href='html/libvirt-libvirt.html#virConnectListDefinedInterfaces'/> <reference name='virConnectListDefinedNetworks' href='html/libvirt-libvirt.html#virConnectListDefinedNetworks'/> <reference name='virConnectListDefinedStoragePools' href='html/libvirt-libvirt.html#virConnectListDefinedStoragePools'/> <reference name='virConnectListDomains' href='html/libvirt-libvirt.html#virConnectListDomains'/> @@ -222,6 +231,7 @@ <reference name='virConnectListNetworks' href='html/libvirt-libvirt.html#virConnectListNetworks'/> <reference name='virConnectListStoragePools' href='html/libvirt-libvirt.html#virConnectListStoragePools'/> <reference name='virConnectNumOfDefinedDomains' href='html/libvirt-libvirt.html#virConnectNumOfDefinedDomains'/> + <reference name='virConnectNumOfDefinedInterfaces' href='html/libvirt-libvirt.html#virConnectNumOfDefinedInterfaces'/> <reference name='virConnectNumOfDefinedNetworks' href='html/libvirt-libvirt.html#virConnectNumOfDefinedNetworks'/> <reference name='virConnectNumOfDefinedStoragePools' href='html/libvirt-libvirt.html#virConnectNumOfDefinedStoragePools'/> <reference name='virConnectNumOfDomains' href='html/libvirt-libvirt.html#virConnectNumOfDomains'/> @@ -386,6 +396,14 @@ <reference name='virSchedParameter' href='html/libvirt-libvirt.html#virSchedParameter'/> <reference name='virSchedParameterPtr' href='html/libvirt-libvirt.html#virSchedParameterPtr'/> <reference name='virSchedParameterType' href='html/libvirt-libvirt.html#virSchedParameterType'/> + <reference name='virSecretAllocateID' href='html/libvirt-libvirt.html#virSecretAllocateID'/> + <reference name='virSecretDelete' href='html/libvirt-libvirt.html#virSecretDelete'/> + <reference name='virSecretGetValue' href='html/libvirt-libvirt.html#virSecretGetValue'/> + <reference name='virSecretGetXML' href='html/libvirt-libvirt.html#virSecretGetXML'/> + <reference name='virSecretListSecrets' href='html/libvirt-libvirt.html#virSecretListSecrets'/> + <reference name='virSecretNumOfSecrets' href='html/libvirt-libvirt.html#virSecretNumOfSecrets'/> + <reference name='virSecretSetValue' href='html/libvirt-libvirt.html#virSecretSetValue'/> + <reference name='virSecretSetXML' href='html/libvirt-libvirt.html#virSecretSetXML'/> <reference name='virSecurityLabel' href='html/libvirt-libvirt.html#virSecurityLabel'/> <reference name='virSecurityLabelPtr' href='html/libvirt-libvirt.html#virSecurityLabelPtr'/> <reference name='virSecurityModel' href='html/libvirt-libvirt.html#virSecurityModel'/> @@ -520,8 +538,10 @@ <ref name='VIR_ERR_INVALID_MAC'/> <ref name='VIR_ERR_INVALID_NETWORK'/> <ref name='VIR_ERR_INVALID_NODE_DEVICE'/> + <ref name='VIR_ERR_INVALID_SECRET'/> <ref name='VIR_ERR_INVALID_STORAGE_POOL'/> <ref name='VIR_ERR_INVALID_STORAGE_VOL'/> + <ref name='VIR_ERR_MULTIPLE_INTERFACES'/> <ref name='VIR_ERR_NETWORK_EXIST'/> <ref name='VIR_ERR_NONE'/> <ref name='VIR_ERR_NO_CONNECT'/> @@ -535,6 +555,7 @@ <ref name='VIR_ERR_NO_NODE_DEVICE'/> <ref name='VIR_ERR_NO_OS'/> <ref name='VIR_ERR_NO_ROOT'/> + <ref name='VIR_ERR_NO_SECRET'/> <ref name='VIR_ERR_NO_SECURITY_MODEL'/> <ref name='VIR_ERR_NO_SOURCE'/> <ref name='VIR_ERR_NO_STORAGE_POOL'/> @@ -568,6 +589,7 @@ <ref name='VIR_FROM_CONF'/> <ref name='VIR_FROM_DOM'/> <ref name='VIR_FROM_DOMAIN'/> + <ref name='VIR_FROM_ESX'/> <ref name='VIR_FROM_INTERFACE'/> <ref name='VIR_FROM_LXC'/> <ref name='VIR_FROM_NET'/> @@ -576,10 +598,12 @@ <ref name='VIR_FROM_NONE'/> <ref name='VIR_FROM_ONE'/> <ref name='VIR_FROM_OPENVZ'/> + <ref name='VIR_FROM_PHYP'/> <ref name='VIR_FROM_PROXY'/> <ref name='VIR_FROM_QEMU'/> <ref name='VIR_FROM_REMOTE'/> <ref name='VIR_FROM_RPC'/> + <ref name='VIR_FROM_SECRET'/> <ref name='VIR_FROM_SECURITY'/> <ref name='VIR_FROM_SEXPR'/> <ref name='VIR_FROM_STATS_LINUX'/> @@ -594,6 +618,7 @@ <ref name='VIR_FROM_XEN_INOTIFY'/> <ref name='VIR_FROM_XML'/> <ref name='VIR_GET_CPUMAP'/> + <ref name='VIR_MEMORY_PHYSICAL'/> <ref name='VIR_MEMORY_VIRTUAL'/> <ref name='VIR_MIGRATE_LIVE'/> <ref name='VIR_NODEINFO_MAXCPUS'/> @@ -623,6 +648,7 @@ <ref name='VIR_WAR_NO_INTERFACE'/> <ref name='VIR_WAR_NO_NETWORK'/> <ref name='VIR_WAR_NO_NODE'/> + <ref name='VIR_WAR_NO_SECRET'/> <ref name='VIR_WAR_NO_STORAGE'/> </letter> <letter name='_'> @@ -668,6 +694,7 @@ <ref name='virConnectGetURI'/> <ref name='virConnectGetVersion'/> <ref name='virConnectListDefinedDomains'/> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListDefinedNetworks'/> <ref name='virConnectListDefinedStoragePools'/> <ref name='virConnectListDomains'/> @@ -675,6 +702,7 @@ <ref name='virConnectListNetworks'/> <ref name='virConnectListStoragePools'/> <ref name='virConnectNumOfDefinedDomains'/> + <ref name='virConnectNumOfDefinedInterfaces'/> <ref name='virConnectNumOfDefinedNetworks'/> <ref name='virConnectNumOfDefinedStoragePools'/> <ref name='virConnectNumOfDomains'/> @@ -839,6 +867,14 @@ <ref name='virSchedParameter'/> <ref name='virSchedParameterPtr'/> <ref name='virSchedParameterType'/> + <ref name='virSecretAllocateID'/> + <ref name='virSecretDelete'/> + <ref name='virSecretGetValue'/> + <ref name='virSecretGetXML'/> + <ref name='virSecretListSecrets'/> + <ref name='virSecretNumOfSecrets'/> + <ref name='virSecretSetValue'/> + <ref name='virSecretSetXML'/> <ref name='virSecurityLabel'/> <ref name='virSecurityLabelPtr'/> <ref name='virSecurityModel'/> @@ -966,10 +1002,17 @@ <ref name='virStorageVolLookupByName'/> <ref name='virStorageVolLookupByPath'/> </type> + <type name='void *'> + <ref name='virSecretGetValue'/> + </type> </constructors> <functions> + <type name='char **'> + <ref name='virSecretListSecrets'/> + </type> <type name='char ** const'> <ref name='virConnectListDefinedDomains'/> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListDefinedNetworks'/> <ref name='virConnectListDefinedStoragePools'/> <ref name='virConnectListInterfaces'/> @@ -984,6 +1027,9 @@ <ref name='virNetworkLookupByUUID'/> <ref name='virStoragePoolLookupByUUID'/> </type> + <type name='const void *'> + <ref name='virSecretSetValue'/> + </type> <type name='int *'> <ref name='virConnectListDomains'/> <ref name='virDomainGetAutostart'/> @@ -997,6 +1043,10 @@ <ref name='virDomainBlockStats'/> <ref name='virDomainInterfaceStats'/> <ref name='virDomainMemoryPeek'/> + <ref name='virSecretSetValue'/> + </type> + <type name='size_t *'> + <ref name='virSecretGetValue'/> </type> <type name='unsigned char *'> <ref name='virDomainGetUUID'/> @@ -1082,6 +1132,7 @@ <ref name='virConnectGetURI'/> <ref name='virConnectGetVersion'/> <ref name='virConnectListDefinedDomains'/> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListDefinedNetworks'/> <ref name='virConnectListDefinedStoragePools'/> <ref name='virConnectListDomains'/> @@ -1089,6 +1140,7 @@ <ref name='virConnectListNetworks'/> <ref name='virConnectListStoragePools'/> <ref name='virConnectNumOfDefinedDomains'/> + <ref name='virConnectNumOfDefinedInterfaces'/> <ref name='virConnectNumOfDefinedNetworks'/> <ref name='virConnectNumOfDefinedStoragePools'/> <ref name='virConnectNumOfDomains'/> @@ -1121,6 +1173,14 @@ <ref name='virNodeGetSecurityModel'/> <ref name='virNodeListDevices'/> <ref name='virNodeNumOfDevices'/> + <ref name='virSecretAllocateID'/> + <ref name='virSecretDelete'/> + <ref name='virSecretGetValue'/> + <ref name='virSecretGetXML'/> + <ref name='virSecretListSecrets'/> + <ref name='virSecretNumOfSecrets'/> + <ref name='virSecretSetValue'/> + <ref name='virSecretSetXML'/> <ref name='virStoragePoolCreateXML'/> <ref name='virStoragePoolDefineXML'/> <ref name='virStoragePoolLookupByName'/> @@ -1394,6 +1454,7 @@ <ref name='VIR_EVENT_HANDLE_READABLE'/> <ref name='VIR_EVENT_HANDLE_WRITABLE'/> <ref name='VIR_GET_CPUMAP'/> + <ref name='VIR_MEMORY_PHYSICAL'/> <ref name='VIR_MEMORY_VIRTUAL'/> <ref name='VIR_MIGRATE_LIVE'/> <ref name='VIR_NODEINFO_MAXCPUS'/> @@ -1455,6 +1516,7 @@ <ref name='virConnectGetURI'/> <ref name='virConnectGetVersion'/> <ref name='virConnectListDefinedDomains'/> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListDefinedNetworks'/> <ref name='virConnectListDefinedStoragePools'/> <ref name='virConnectListDomains'/> @@ -1462,6 +1524,7 @@ <ref name='virConnectListNetworks'/> <ref name='virConnectListStoragePools'/> <ref name='virConnectNumOfDefinedDomains'/> + <ref name='virConnectNumOfDefinedInterfaces'/> <ref name='virConnectNumOfDefinedNetworks'/> <ref name='virConnectNumOfDefinedStoragePools'/> <ref name='virConnectNumOfDomains'/> @@ -1613,6 +1676,14 @@ <ref name='virSchedParameter'/> <ref name='virSchedParameterPtr'/> <ref name='virSchedParameterType'/> + <ref name='virSecretAllocateID'/> + <ref name='virSecretDelete'/> + <ref name='virSecretGetValue'/> + <ref name='virSecretGetXML'/> + <ref name='virSecretListSecrets'/> + <ref name='virSecretNumOfSecrets'/> + <ref name='virSecretSetValue'/> + <ref name='virSecretSetXML'/> <ref name='virSecurityLabel'/> <ref name='virSecurityLabelPtr'/> <ref name='virSecurityModel'/> @@ -1690,8 +1761,10 @@ <ref name='VIR_ERR_INVALID_MAC'/> <ref name='VIR_ERR_INVALID_NETWORK'/> <ref name='VIR_ERR_INVALID_NODE_DEVICE'/> + <ref name='VIR_ERR_INVALID_SECRET'/> <ref name='VIR_ERR_INVALID_STORAGE_POOL'/> <ref name='VIR_ERR_INVALID_STORAGE_VOL'/> + <ref name='VIR_ERR_MULTIPLE_INTERFACES'/> <ref name='VIR_ERR_NETWORK_EXIST'/> <ref name='VIR_ERR_NONE'/> <ref name='VIR_ERR_NO_CONNECT'/> @@ -1705,6 +1778,7 @@ <ref name='VIR_ERR_NO_NODE_DEVICE'/> <ref name='VIR_ERR_NO_OS'/> <ref name='VIR_ERR_NO_ROOT'/> + <ref name='VIR_ERR_NO_SECRET'/> <ref name='VIR_ERR_NO_SECURITY_MODEL'/> <ref name='VIR_ERR_NO_SOURCE'/> <ref name='VIR_ERR_NO_STORAGE_POOL'/> @@ -1734,6 +1808,7 @@ <ref name='VIR_FROM_CONF'/> <ref name='VIR_FROM_DOM'/> <ref name='VIR_FROM_DOMAIN'/> + <ref name='VIR_FROM_ESX'/> <ref name='VIR_FROM_INTERFACE'/> <ref name='VIR_FROM_LXC'/> <ref name='VIR_FROM_NET'/> @@ -1742,10 +1817,12 @@ <ref name='VIR_FROM_NONE'/> <ref name='VIR_FROM_ONE'/> <ref name='VIR_FROM_OPENVZ'/> + <ref name='VIR_FROM_PHYP'/> <ref name='VIR_FROM_PROXY'/> <ref name='VIR_FROM_QEMU'/> <ref name='VIR_FROM_REMOTE'/> <ref name='VIR_FROM_RPC'/> + <ref name='VIR_FROM_SECRET'/> <ref name='VIR_FROM_SECURITY'/> <ref name='VIR_FROM_SEXPR'/> <ref name='VIR_FROM_STATS_LINUX'/> @@ -1762,6 +1839,7 @@ <ref name='VIR_WAR_NO_INTERFACE'/> <ref name='VIR_WAR_NO_NETWORK'/> <ref name='VIR_WAR_NO_NODE'/> + <ref name='VIR_WAR_NO_SECRET'/> <ref name='VIR_WAR_NO_STORAGE'/> <ref name='_virError'/> <ref name='virConnCopyLastError'/> @@ -1825,9 +1903,17 @@ <word name='After'> <ref name='virDomainSave'/> </word> + <word name='Allocates'> + <ref name='virSecretAllocateID'/> + <ref name='virSecretSetValue'/> + <ref name='virSecretSetXML'/> + </word> <word name='Although'> <ref name='virDomainMemoryPeek'/> </word> + <word name='Associates'> + <ref name='virSecretSetValue'/> + </word> <word name='Attempt'> <ref name='virDomainMigrate'/> </word> @@ -1891,6 +1977,7 @@ <ref name='virDomainSetSchedulerParameters'/> </word> <word name='Collect'> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListDomains'/> <ref name='virConnectListInterfaces'/> <ref name='virConnectListNetworks'/> @@ -1944,6 +2031,9 @@ <ref name='virStoragePoolDelete'/> <ref name='virStorageVolDelete'/> </word> + <word name='Deletes'> + <ref name='virSecretDelete'/> + </word> <word name='Depending'> <ref name='virNodeDeviceDettach'/> <ref name='virNodeDeviceReAttach'/> @@ -2021,6 +2111,7 @@ <letter name='F'> <word name='Fetch'> <ref name='virNodeDeviceGetXMLDesc'/> + <ref name='virSecretNumOfSecrets'/> <ref name='virStoragePoolGetName'/> <ref name='virStoragePoolGetUUID'/> <ref name='virStoragePoolGetUUIDString'/> @@ -2040,6 +2131,8 @@ <ref name='virStorageVolLookupByPath'/> </word> <word name='Fetches'> + <ref name='virSecretGetValue'/> + <ref name='virSecretGetXML'/> <ref name='virStoragePoolGetAutostart'/> <ref name='virStorageVolGetInfo'/> </word> @@ -2110,6 +2203,8 @@ <letter name='I'> <word name='IDs'> <ref name='virConnectListDomains'/> + <ref name='virSecretListSecrets'/> + <ref name='virSecretNumOfSecrets'/> </word> <word name='Increment'> <ref name='virConnectRef'/> @@ -2154,6 +2249,12 @@ </word> </letter> <letter name='L'> + <word name='LIBVIRT_AUTOSTART=0'> + <ref name='virConnectOpen'/> + </word> + <word name='LIBVIRT_DEFAULT_URI'> + <ref name='virConnectOpen'/> + </word> <word name='Labeled'> <ref name='VIR_SECURITY_LABEL_BUFLEN'/> </word> @@ -2171,6 +2272,7 @@ </word> <word name='List'> <ref name='_virConnectAuth'/> + <ref name='virSecretListSecrets'/> </word> <word name='Lists'> <ref name='virNodeDeviceListCaps'/> @@ -2282,6 +2384,12 @@ <ref name='virEventUpdateHandleFunc'/> <ref name='virEventUpdateTimeoutFunc'/> </word> + <word name='Place'> + <ref name='virSecretGetValue'/> + </word> + <word name='Pointer'> + <ref name='virSecretListSecrets'/> + </word> <word name='Power'> <ref name='virNodeDeviceReset'/> </word> @@ -2301,6 +2409,7 @@ <ref name='virConnectListDefinedStoragePools'/> <ref name='virConnectListStoragePools'/> <ref name='virConnectNumOfDefinedDomains'/> + <ref name='virConnectNumOfDefinedInterfaces'/> <ref name='virConnectNumOfDefinedNetworks'/> <ref name='virConnectNumOfDefinedStoragePools'/> <ref name='virConnectNumOfDomains'/> @@ -2360,6 +2469,9 @@ <word name='Renamed'> <ref name='virDomainCreateLinux'/> </word> + <word name='Replaces'> + <ref name='virSecretSetXML'/> + </word> <word name='Request'> <ref name='virStoragePoolRefresh'/> </word> @@ -2394,6 +2506,8 @@ </word> <word name='See'> <ref name='virConnectGetType'/> + <ref name='virConnectOpenAuth'/> + <ref name='virConnectOpenReadOnly'/> </word> <word name='Set'> <ref name='virConnSetErrorFunc'/> @@ -2413,6 +2527,9 @@ <ref name='virConnGetLastError'/> <ref name='virDomainMigrate'/> </word> + <word name='Size'> + <ref name='virSecretSetValue'/> + </word> <word name='Some'> <ref name='virDomainMigrate'/> </word> @@ -2548,6 +2665,8 @@ <ref name='virStoragePoolGetUUIDString'/> </word> </letter> + </chunk> + <chunk name='chunk2'> <letter name='W'> <word name='WARNING:'> <ref name='virDomainGetConnect'/> @@ -2567,8 +2686,6 @@ <ref name='virStorageVolGetConnect'/> </word> </letter> - </chunk> - <chunk name='chunk2'> <letter name='X'> <word name='Xen'> <ref name='_virDomainBlockStats'/> @@ -2584,6 +2701,8 @@ <ref name='virDomainMemoryPeek'/> </word> <word name='about'> + <ref name='virConnectOpenAuth'/> + <ref name='virConnectOpenReadOnly'/> <ref name='virDomainGetInfo'/> <ref name='virDomainGetUUIDString'/> <ref name='virDomainGetVcpus'/> @@ -2622,6 +2741,9 @@ <word name='across'> <ref name='virStorageVolGetPath'/> </word> + <word name='activate'> + <ref name='virConnectOpen'/> + </word> <word name='activated'> <ref name='virNodeGetSecurityModel'/> </word> @@ -2629,11 +2751,14 @@ <ref name='VIR_NODEINFO_MAXCPUS'/> <ref name='_virNodeInfo'/> <ref name='virConnectListDomains'/> + <ref name='virConnectListInterfaces'/> <ref name='virConnectListNetworks'/> <ref name='virConnectListStoragePools'/> <ref name='virConnectNumOfDomains'/> + <ref name='virConnectNumOfInterfaces'/> <ref name='virConnectNumOfNetworks'/> <ref name='virConnectNumOfStoragePools'/> + <ref name='virConnectOpen'/> <ref name='virDomainGetSecurityLabel'/> <ref name='virDomainSuspend'/> <ref name='virStoragePoolDestroy'/> @@ -2700,6 +2825,8 @@ <ref name='virNetworkRef'/> <ref name='virNodeDeviceGetXMLDesc'/> <ref name='virNodeDeviceRef'/> + <ref name='virSecretDelete'/> + <ref name='virSecretSetXML'/> <ref name='virStoragePoolFree'/> <ref name='virStoragePoolGetXMLDesc'/> <ref name='virStoragePoolRef'/> @@ -2720,6 +2847,8 @@ <ref name='virDomainSuspend'/> <ref name='virNodeGetCellsFreeMemory'/> <ref name='virNodeGetInfo'/> + <ref name='virSecretSetValue'/> + <ref name='virSecretSetXML'/> </word> <word name='allocation'> <ref name='_virStoragePoolInfo'/> @@ -2735,6 +2864,7 @@ <ref name='virDomainMemoryPeek'/> </word> <word name='already'> + <ref name='virConnectOpen'/> <ref name='virDomainDefineXML'/> <ref name='virDomainDestroy'/> <ref name='virNetworkDestroy'/> @@ -2766,6 +2896,7 @@ </word> <word name='any'> <ref name='virNodeDeviceDettach'/> + <ref name='virSecretSetXML'/> <ref name='virStoragePoolDestroy'/> </word> <word name='anymore'> @@ -2826,6 +2957,7 @@ <ref name='virNetworkRef'/> <ref name='virNodeDeviceRef'/> <ref name='virNodeDeviceReset'/> + <ref name='virSecretSetXML'/> <ref name='virSetErrorFunc'/> <ref name='virStoragePoolRef'/> <ref name='virStorageVolCreateXMLFrom'/> @@ -2860,11 +2992,15 @@ <ref name='virInterfaceUndefine'/> <ref name='virNetworkDestroy'/> <ref name='virNetworkGetConnect'/> + <ref name='virSecretGetValue'/> <ref name='virStoragePoolDestroy'/> <ref name='virStoragePoolFree'/> <ref name='virStoragePoolGetConnect'/> <ref name='virStorageVolGetConnect'/> </word> + <word name='associating'> + <ref name='virSecretAllocateID'/> + </word> <word name='assumed'> <ref name='virDomainGetVcpus'/> <ref name='virGetVersion'/> @@ -2887,6 +3023,11 @@ <ref name='virConnectGetMaxVcpus'/> <ref name='virDomainBlockStats'/> </word> + <word name='attributes'> + <ref name='virSecretDelete'/> + <ref name='virSecretGetXML'/> + <ref name='virSecretSetXML'/> + </word> <word name='authentication'> <ref name='virConnectOpenAuth'/> </word> @@ -2894,6 +3035,7 @@ <ref name='virConnectFindStoragePoolSources'/> </word> <word name='automatically'> + <ref name='virConnectOpen'/> <ref name='virDomainGetAutostart'/> <ref name='virDomainSetAutostart'/> <ref name='virNetworkGetAutostart'/> @@ -3115,6 +3257,9 @@ <ref name='virNodeDeviceRef'/> <ref name='virNodeGetCellsFreeMemory'/> <ref name='virSaveLastError'/> + <ref name='virSecretAllocateID'/> + <ref name='virSecretGetValue'/> + <ref name='virSecretGetXML'/> <ref name='virStoragePoolRef'/> <ref name='virStorageVolRef'/> </word> @@ -3142,6 +3287,9 @@ <ref name='virConnectDomainEventRegister'/> <ref name='virConnectGetURI'/> <ref name='virConnectGetVersion'/> + <ref name='virConnectOpen'/> + <ref name='virConnectOpenAuth'/> + <ref name='virConnectOpenReadOnly'/> <ref name='virCopyLastError'/> <ref name='virDomainGetInfo'/> <ref name='virDomainMemoryPeek'/> @@ -3244,6 +3392,7 @@ </word> <word name='collect'> <ref name='_virConnectAuth'/> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListDomains'/> <ref name='virConnectListInterfaces'/> <ref name='virConnectListNetworks'/> @@ -3308,6 +3457,9 @@ <word name='connected'> <ref name='virConnectGetHostname'/> </word> + <word name='connecting'> + <ref name='virConnectOpen'/> + </word> <word name='consequent'> <ref name='_virError'/> </word> @@ -3323,6 +3475,7 @@ <ref name='virDomainCreateLinux'/> <ref name='virDomainCreateXML'/> <ref name='virNodeDeviceCreateXML'/> + <ref name='virSecretSetXML'/> </word> <word name='contains'> <ref name='virStoragePoolLookupByVolume'/> @@ -3429,7 +3582,6 @@ <word name='creation'> <ref name='virStoragePoolCreateXML'/> <ref name='virStoragePoolDefineXML'/> - <ref name='virStoragePoolUndefine'/> <ref name='virStorageVolCreateXML'/> <ref name='virStorageVolCreateXMLFrom'/> </word> @@ -3448,12 +3600,16 @@ <ref name='virNodeDeviceDettach'/> <ref name='virNodeDeviceReAttach'/> <ref name='virNodeDeviceReset'/> + <ref name='virSecretNumOfSecrets'/> <ref name='virStoragePoolRefresh'/> </word> </letter> </chunk> <chunk name='chunk4'> <letter name='d'> + <word name='daemon'> + <ref name='virConnectOpen'/> + </word> <word name='data'> <ref name='virConnSetErrorFunc'/> <ref name='virConnectDomainEventCallback'/> @@ -3494,6 +3650,7 @@ <word name='default'> <ref name='_virConnectCredential'/> <ref name='virConnSetErrorFunc'/> + <ref name='virConnectOpen'/> <ref name='virDomainMigrate'/> <ref name='virSetErrorFunc'/> </word> @@ -3502,13 +3659,17 @@ </word> <word name='defined'> <ref name='virConnectListDefinedDomains'/> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectNumOfDefinedDomains'/> + <ref name='virConnectNumOfDefinedInterfaces'/> <ref name='virDomainCreate'/> <ref name='virDomainUndefine'/> <ref name='virInterfaceCreate'/> <ref name='virInterfaceUndefine'/> <ref name='virNetworkCreate'/> <ref name='virNetworkUndefine'/> + <ref name='virSecretListSecrets'/> + <ref name='virSecretNumOfSecrets'/> </word> <word name='defining'> <ref name='virConnectGetCapabilities'/> @@ -3542,6 +3703,7 @@ <ref name='virConnectDomainXMLFromNative'/> <ref name='virConnectDomainXMLToNative'/> <ref name='virNodeDeviceGetXMLDesc'/> + <ref name='virSecretGetXML'/> <ref name='virStoragePoolGetXMLDesc'/> <ref name='virStorageVolGetXMLDesc'/> </word> @@ -3583,6 +3745,7 @@ <ref name='virConnectDomainEventCallback'/> </word> <word name='determine'> + <ref name='virConnectOpen'/> <ref name='virDomainBlockPeek'/> </word> <word name='determines'> @@ -3620,6 +3783,9 @@ <ref name='virDomainCreateXML'/> <ref name='virStoragePoolCreateXML'/> </word> + <word name='discarded'> + <ref name='virSecretSetXML'/> + </word> <word name='discover'> <ref name='virConnectFindStoragePoolSources'/> </word> @@ -3647,6 +3813,7 @@ <ref name='virConnectDomainXMLToNative'/> <ref name='virConnectFindStoragePoolSources'/> <ref name='virNodeDeviceGetXMLDesc'/> + <ref name='virSecretGetXML'/> <ref name='virStoragePoolGetXMLDesc'/> <ref name='virStorageVolGetXMLDesc'/> </word> @@ -3691,6 +3858,7 @@ <ref name='virDomainBlockPeek'/> </word> <word name='done'> + <ref name='virConnectOpen'/> <ref name='virDomainLookupByID'/> </word> <word name='down'> @@ -3700,6 +3868,7 @@ <word name='driver'> <ref name='virConnectGetCapabilities'/> <ref name='virConnectGetURI'/> + <ref name='virConnectOpen'/> <ref name='virDomainBlockPeek'/> <ref name='virDomainMemoryPeek'/> <ref name='virDomainMigrate'/> @@ -3709,6 +3878,8 @@ <ref name='virNodeGetSecurityModel'/> </word> <word name='drivers'> + <ref name='virConnectOpenAuth'/> + <ref name='virConnectOpenReadOnly'/> <ref name='virNodeDeviceDettach'/> </word> <word name='dummy'> @@ -3737,6 +3908,7 @@ <letter name='e'> <word name='each'> <ref name='virConnectFindStoragePoolSources'/> + <ref name='virConnectOpen'/> <ref name='virConnectRef'/> <ref name='virDomainBlockStats'/> <ref name='virDomainInterfaceStats'/> @@ -3751,6 +3923,10 @@ <ref name='virStoragePoolRef'/> <ref name='virStorageVolRef'/> </word> + <word name='effect'> + <ref name='virConnectOpenAuth'/> + <ref name='virConnectOpenReadOnly'/> + </word> <word name='either'> <ref name='virNodeGetCellsFreeMemory'/> <ref name='virStorageVolGetPath'/> @@ -3788,6 +3964,11 @@ <word name='entries'> <ref name='virNodeGetCellsFreeMemory'/> </word> + <word name='environment'> + <ref name='virConnectOpen'/> + <ref name='virConnectOpenAuth'/> + <ref name='virConnectOpenReadOnly'/> + </word> <word name='errors'> <ref name='virConnCopyLastError'/> <ref name='virConnGetLastError'/> @@ -3897,7 +4078,6 @@ <ref name='virSaveLastError'/> <ref name='virStoragePoolCreateXML'/> <ref name='virStoragePoolDefineXML'/> - <ref name='virStoragePoolUndefine'/> </word> <word name='feature'> <ref name='virDomainMigrate'/> @@ -4024,65 +4204,6 @@ <ref name='virInterfaceLookupByMACString'/> <ref name='virStoragePoolGetXMLDesc'/> </word> - <word name='found'> - <ref name='virConnCopyLastError'/> - <ref name='virConnectListDomains'/> - <ref name='virConnectListInterfaces'/> - <ref name='virConnectListNetworks'/> - <ref name='virConnectNumOfDefinedDomains'/> - <ref name='virConnectNumOfDefinedNetworks'/> - <ref name='virConnectNumOfDefinedStoragePools'/> - <ref name='virConnectNumOfDomains'/> - <ref name='virConnectNumOfInterfaces'/> - <ref name='virConnectNumOfNetworks'/> - <ref name='virConnectNumOfStoragePools'/> - <ref name='virCopyLastError'/> - <ref name='virDomainLookupByID'/> - <ref name='virDomainLookupByName'/> - <ref name='virDomainLookupByUUID'/> - <ref name='virDomainLookupByUUIDString'/> - <ref name='virInterfaceLookupByMACString'/> - <ref name='virInterfaceLookupByName'/> - <ref name='virNetworkLookupByName'/> - <ref name='virNetworkLookupByUUID'/> - <ref name='virNetworkLookupByUUIDString'/> - <ref name='virNodeDeviceLookupByName'/> - <ref name='virNodeListDevices'/> - <ref name='virStoragePoolLookupByName'/> - <ref name='virStoragePoolLookupByUUID'/> - <ref name='virStoragePoolLookupByUUIDString'/> - <ref name='virStoragePoolLookupByVolume'/> - <ref name='virStorageVolLookupByKey'/> - <ref name='virStorageVolLookupByName'/> - <ref name='virStorageVolLookupByPath'/> - </word> - <word name='free'> - <ref name='_virStoragePoolInfo'/> - <ref name='virConnCopyLastError'/> - <ref name='virConnectDomainXMLFromNative'/> - <ref name='virConnectDomainXMLToNative'/> - <ref name='virConnectGetCapabilities'/> - <ref name='virCopyLastError'/> - <ref name='virDomainDestroy'/> - <ref name='virDomainGetSchedulerType'/> - <ref name='virDomainGetXMLDesc'/> - <ref name='virEventAddHandleFunc'/> - <ref name='virEventAddTimeoutFunc'/> - <ref name='virFreeError'/> - <ref name='virInterfaceDestroy'/> - <ref name='virInterfaceGetXMLDesc'/> - <ref name='virInterfaceUndefine'/> - <ref name='virNetworkDestroy'/> - <ref name='virNetworkGetBridgeName'/> - <ref name='virNetworkGetXMLDesc'/> - <ref name='virNodeGetCellsFreeMemory'/> - <ref name='virNodeGetFreeMemory'/> - <ref name='virSaveLastError'/> - <ref name='virStoragePoolDelete'/> - <ref name='virStoragePoolDestroy'/> - <ref name='virStoragePoolFree'/> - <ref name='virStoragePoolGetInfo'/> - </word> <word name='freeMems'> <ref name='virNodeGetCellsFreeMemory'/> </word> @@ -4225,8 +4346,6 @@ <ref name='virNodeDeviceReset'/> </word> </letter> - </chunk> - <chunk name='chunk6'> <letter name='h'> <word name='handle'> <ref name='virConnectDomainEventRegister'/> @@ -4269,6 +4388,8 @@ <ref name='virStoragePoolDestroy'/> </word> <word name='have'> + <ref name='virConnectOpenAuth'/> + <ref name='virConnectOpenReadOnly'/> <ref name='virConnectRef'/> <ref name='virDomainBlockPeek'/> <ref name='virDomainBlockStats'/> @@ -4297,7 +4418,9 @@ </word> <word name='host'> <ref name='VIR_NODEINFO_MAXCPUS'/> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListInterfaces'/> + <ref name='virConnectNumOfDefinedInterfaces'/> <ref name='virConnectNumOfInterfaces'/> <ref name='virDomainCoreDump'/> <ref name='virDomainCreateXML'/> @@ -4343,6 +4466,8 @@ <ref name='virDomainMigrate'/> </word> </letter> + </chunk> + <chunk name='chunk6'> <letter name='i'> <word name='iSCSI'> <ref name='virConnectFindStoragePoolSources'/> @@ -4350,6 +4475,9 @@ <word name='identical'> <ref name='virDomainCreateLinux'/> </word> + <word name='ids'> + <ref name='virSecretListSecrets'/> + </word> <word name='ie:'> <ref name='cpumap'/> <ref name='virDomainGetVcpus'/> @@ -4386,9 +4514,11 @@ </word> <word name='inactive'> <ref name='virConnectListDefinedDomains'/> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListDefinedNetworks'/> <ref name='virConnectListDefinedStoragePools'/> <ref name='virConnectNumOfDefinedDomains'/> + <ref name='virConnectNumOfDefinedInterfaces'/> <ref name='virConnectNumOfDefinedNetworks'/> <ref name='virConnectNumOfDefinedStoragePools'/> <ref name='virDomainGetMaxVcpus'/> @@ -4397,6 +4527,9 @@ <ref name='virStoragePoolDefineXML'/> <ref name='virStoragePoolUndefine'/> </word> + <word name='including'> + <ref name='virSecretDelete'/> + </word> <word name='increased'> <ref name='virDomainGetConnect'/> <ref name='virInterfaceGetConnect'/> @@ -4496,7 +4629,9 @@ <ref name='virConnectClose'/> </word> <word name='interfaces'> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListInterfaces'/> + <ref name='virConnectNumOfDefinedInterfaces'/> <ref name='virConnectNumOfInterfaces'/> <ref name='virDomainInterfaceStats'/> </word> @@ -4526,6 +4661,9 @@ <ref name='virNodeDeviceReAttach'/> <ref name='virStoragePoolRefresh'/> </word> + <word name='involves'> + <ref name='virConnectOpen'/> + </word> <word name='isn'> <ref name='virDomainGetVcpus'/> </word> @@ -4564,8 +4702,6 @@ <ref name='virStoragePoolDelete'/> </word> </letter> - </chunk> - <chunk name='chunk7'> <letter name='j'> <word name='join'> <ref name='virNetworkGetBridgeName'/> @@ -4647,6 +4783,9 @@ <word name='launch'> <ref name='virDomainCreate'/> </word> + <word name='launched'> + <ref name='virConnectOpen'/> + </word> <word name='layer'> <ref name='virStoragePoolRefresh'/> </word> @@ -4708,6 +4847,9 @@ <ref name='virStoragePoolGetConnect'/> <ref name='virStorageVolGetConnect'/> </word> + <word name='libvirtd'> + <ref name='virConnectOpen'/> + </word> <word name='lie'> <ref name='virDomainBlockPeek'/> </word> @@ -4735,6 +4877,7 @@ <word name='list'> <ref name='virConnectFindStoragePoolSources'/> <ref name='virConnectListDefinedDomains'/> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListDefinedNetworks'/> <ref name='virConnectListDefinedStoragePools'/> <ref name='virConnectListDomains'/> @@ -4818,6 +4961,8 @@ <ref name='virDomainPinVcpu'/> </word> </letter> + </chunk> + <chunk name='chunk7'> <letter name='m'> <word name='machine'> <ref name='virDomainGetAutostart'/> @@ -5042,16 +5187,18 @@ <ref name='virNetworkGetBridgeName'/> <ref name='virNetworkGetXMLDesc'/> <ref name='virNodeGetCellsFreeMemory'/> + <ref name='virSecretAllocateID'/> + <ref name='virSecretGetValue'/> + <ref name='virSecretGetXML'/> </word> <word name='mysterious'> <ref name='_virDomainBlockStats'/> </word> </letter> - </chunk> - <chunk name='chunk8'> <letter name='n'> <word name='names'> <ref name='virConnectListDefinedDomains'/> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListDefinedNetworks'/> <ref name='virConnectListDefinedStoragePools'/> <ref name='virConnectListInterfaces'/> @@ -5059,6 +5206,7 @@ <ref name='virConnectListStoragePools'/> <ref name='virNodeDeviceListCaps'/> <ref name='virNodeListDevices'/> + <ref name='virSecretListSecrets'/> <ref name='virStoragePoolListVolumes'/> </word> <word name='naming'> @@ -5146,6 +5294,10 @@ <word name='note'> <ref name='_virError'/> </word> + <word name='notes'> + <ref name='virConnectOpenAuth'/> + <ref name='virConnectOpenReadOnly'/> + </word> <word name='notified'> <ref name='virEventRemoveHandleFunc'/> <ref name='virEventUpdateHandleFunc'/> @@ -5166,6 +5318,8 @@ <ref name='virInterfaceLookupByMACString'/> </word> </letter> + </chunk> + <chunk name='chunk8'> <letter name='o'> <word name='objects'> <ref name='virDomainSetSchedulerParameters'/> @@ -5210,6 +5364,7 @@ <word name='one'> <ref name='_virDomainInfo'/> <ref name='maplen'/> + <ref name='virConnectOpen'/> <ref name='virDomainAttachDevice'/> <ref name='virDomainBlockStats'/> <ref name='virDomainCreateXML'/> @@ -5248,6 +5403,13 @@ <ref name='virStoragePoolRef'/> <ref name='virStorageVolRef'/> </word> + <word name='opening'> + <ref name='virConnectOpenAuth'/> + <ref name='virConnectOpenReadOnly'/> + </word> + <word name='opens'> + <ref name='virConnectOpen'/> + </word> <word name='operating'> <ref name='virNodeDeviceDestroy'/> </word> @@ -5435,7 +5597,9 @@ <word name='physical'> <ref name='VIR_CPU_MAPLEN'/> <ref name='cpu'/> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListInterfaces'/> + <ref name='virConnectNumOfDefinedInterfaces'/> <ref name='virConnectNumOfInterfaces'/> <ref name='virDomainGetMaxMemory'/> <ref name='virDomainSetMaxMemory'/> @@ -5448,6 +5612,7 @@ <ref name='virConnectListDefinedDomains'/> <ref name='virConnectListDefinedNetworks'/> <ref name='virDomainMemoryPeek'/> + <ref name='virSecretListSecrets'/> </word> <word name='pools'> <ref name='virConnectFindStoragePoolSources'/> @@ -5477,6 +5642,12 @@ <ref name='virInterfaceDefineXML'/> <ref name='virNetworkDefineXML'/> </word> + <word name='preference'> + <ref name='virConnectOpen'/> + </word> + <word name='prevented'> + <ref name='virConnectOpen'/> + </word> <word name='previous'> <ref name='virDomainDefineXML'/> </word> @@ -5484,6 +5655,11 @@ <ref name='cpumap'/> <ref name='virNodeDeviceReAttach'/> <ref name='virNodeDeviceReset'/> + <ref name='virSecretSetValue'/> + <ref name='virSecretSetXML'/> + </word> + <word name='printable'> + <ref name='virSecretAllocateID'/> </word> <word name='printing'> <ref name='virSetErrorFunc'/> @@ -5501,6 +5677,9 @@ <ref name='virNetworkDestroy'/> <ref name='virNodeDeviceDestroy'/> </word> + <word name='probing'> + <ref name='virConnectOpen'/> + </word> <word name='problem'> <ref name='virDomainSave'/> </word> @@ -5529,6 +5708,7 @@ <ref name='virConnectListDefinedNetworks'/> <ref name='virErrorFunc'/> <ref name='virEventAddHandleFunc'/> + <ref name='virSecretListSecrets'/> <ref name='virSetErrorFunc'/> </word> <word name='provides'> @@ -5755,6 +5935,7 @@ <ref name='virStorageVolRef'/> </word> <word name='requires'> + <ref name='virConnectOpen'/> <ref name='virDomainCreateXML'/> <ref name='virDomainPinVcpu'/> <ref name='virDomainResume'/> @@ -5880,6 +6061,7 @@ <ref name='virConnectClose'/> <ref name='virConnectGetHostname'/> <ref name='virConnectGetVersion'/> + <ref name='virConnectOpen'/> <ref name='virDomainCreate'/> <ref name='virDomainDestroy'/> <ref name='virDomainFree'/> @@ -5943,6 +6125,22 @@ <ref name='virDomainMigrate'/> <ref name='virStorageVolGetName'/> </word> + <word name='secret'> + <ref name='virSecretAllocateID'/> + <ref name='virSecretDelete'/> + <ref name='virSecretGetValue'/> + <ref name='virSecretGetXML'/> + <ref name='virSecretListSecrets'/> + <ref name='virSecretNumOfSecrets'/> + <ref name='virSecretSetValue'/> + <ref name='virSecretSetXML'/> + </word> + <word name='secret_id'> + <ref name='virSecretDelete'/> + <ref name='virSecretGetValue'/> + <ref name='virSecretSetValue'/> + <ref name='virSecretSetXML'/> + </word> <word name='security'> <ref name='virDomainGetSecurityLabel'/> <ref name='virNodeGetSecurityModel'/> @@ -5974,6 +6172,7 @@ <word name='set'> <ref name='VIR_USE_CPU'/> <ref name='virConnectFindStoragePoolSources'/> + <ref name='virConnectOpen'/> <ref name='virConnectOpenReadOnly'/> <ref name='virDomainGetInfo'/> <ref name='virDomainGetXMLDesc'/> @@ -5990,6 +6189,7 @@ <ref name='virEventAddHandleFunc'/> </word> <word name='setting'> + <ref name='virConnectOpen'/> <ref name='virStoragePoolSetAutostart'/> </word> <word name='shall'> @@ -6091,6 +6291,7 @@ <ref name='virDomainMigrate'/> <ref name='virNodeListDevices'/> <ref name='virNodeNumOfDevices'/> + <ref name='virSecretSetXML'/> </word> <word name='specify'> <ref name='virDomainMigrate'/> @@ -6170,6 +6371,7 @@ <word name='store'> <ref name='VIR_CPU_MAPLEN'/> <ref name='virConnectListDefinedDomains'/> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListDefinedNetworks'/> <ref name='virConnectListDomains'/> <ref name='virConnectListInterfaces'/> @@ -6180,6 +6382,7 @@ <ref name='virInterfaceGetConnect'/> <ref name='virNetworkGetConnect'/> <ref name='virNodeListDevices'/> + <ref name='virSecretListSecrets'/> <ref name='virStoragePoolGetAutostart'/> <ref name='virStoragePoolGetConnect'/> <ref name='virStoragePoolGetInfo'/> @@ -6193,6 +6396,9 @@ <ref name='virConnectListDefinedDomains'/> <ref name='virConnectListDefinedNetworks'/> </word> + <word name='storing'> + <ref name='virSecretGetValue'/> + </word> <word name='structure'> <ref name='virDomainBlockStats'/> <ref name='virDomainFree'/> @@ -6218,6 +6424,9 @@ <ref name='virDomainSave'/> <ref name='virNodeDeviceCreateXML'/> </word> + <word name='successfully'> + <ref name='virConnectOpen'/> + </word> <word name='such'> <ref name='virConnCopyLastError'/> <ref name='virConnGetLastError'/> @@ -6230,6 +6439,7 @@ <ref name='virDomainBlockPeek'/> </word> <word name='suitable'> + <ref name='virConnectOpen'/> <ref name='virDomainMigrate'/> <ref name='virStoragePoolGetXMLDesc'/> </word> @@ -6318,6 +6528,7 @@ <ref name='virDomainSetSchedulerParameters'/> </word> <word name='their'> + <ref name='virConnectListDefinedInterfaces'/> <ref name='virConnectListDomains'/> <ref name='virConnectListInterfaces'/> <ref name='virConnectListNetworks'/> @@ -6329,6 +6540,7 @@ <ref name='virConnGetLastError'/> <ref name='virConnectGetHostname'/> <ref name='virConnectGetURI'/> + <ref name='virConnectOpen'/> <ref name='virConnectOpenReadOnly'/> <ref name='virDomainGetMaxMemory'/> <ref name='virDomainGetVcpus'/> @@ -6449,6 +6661,12 @@ <ref name='virDomainBlockPeek'/> <ref name='virDomainMigrate'/> </word> + <word name='trying'> + <ref name='virConnectOpen'/> + </word> + <word name='turn'> + <ref name='virConnectOpen'/> + </word> <word name='two'> <ref name='virDomainMigrate'/> <ref name='virGetVersion'/> @@ -6524,6 +6742,9 @@ <word name='unknown'> <ref name='virGetVersion'/> </word> + <word name='unprivileged'> + <ref name='virConnectOpen'/> + </word> <word name='unregistered'> <ref name='virEventAddHandleFunc'/> <ref name='virEventAddTimeoutFunc'/> @@ -6536,6 +6757,7 @@ <ref name='virNodeGetCellsFreeMemory'/> </word> <word name='until'> + <ref name='virConnectOpen'/> <ref name='virConnectRef'/> <ref name='virDomainDefineXML'/> <ref name='virDomainRef'/> @@ -6672,34 +6894,18 @@ <word name='valid'> <ref name='virConnectDomainEventRegister'/> </word> - <word name='value'> - <ref name='VIR_CPU_USABLE'/> - <ref name='VIR_SECURITY_LABEL_BUFLEN'/> - <ref name='_virVcpuInfo'/> - <ref name='virConnectDomainXMLFromNative'/> - <ref name='virConnectDomainXMLToNative'/> - <ref name='virConnectGetMaxVcpus'/> - <ref name='virConnectGetVersion'/> - <ref name='virDomainGetAutostart'/> - <ref name='virDomainGetSchedulerParameters'/> - <ref name='virDomainGetSchedulerType'/> - <ref name='virDomainGetXMLDesc'/> - <ref name='virDomainSetSchedulerParameters'/> - <ref name='virEventAddTimeoutFunc'/> - <ref name='virEventUpdateTimeoutFunc'/> - <ref name='virGetVersion'/> - <ref name='virInterfaceGetXMLDesc'/> - <ref name='virNetworkGetAutostart'/> - <ref name='virNetworkGetBridgeName'/> - <ref name='virNetworkGetXMLDesc'/> - <ref name='virNodeGetFreeMemory'/> - <ref name='virStoragePoolGetAutostart'/> - </word> <word name='values'> <ref name='_virConnectAuth'/> <ref name='virDomainGetSchedulerParameters'/> <ref name='virGetVersion'/> </word> + <word name='variable'> + <ref name='virConnectOpen'/> + </word> + <word name='variables'> + <ref name='virConnectOpenAuth'/> + <ref name='virConnectOpenReadOnly'/> + </word> <word name='vcpu'> <ref name='VIR_COPY_CPUMAP'/> <ref name='VIR_CPU_USABLE'/> @@ -6719,6 +6925,14 @@ </word> <word name='virConnect'> <ref name='virConnectDomainEventCallback'/> + <ref name='virSecretAllocateID'/> + <ref name='virSecretDelete'/> + <ref name='virSecretGetValue'/> + <ref name='virSecretGetXML'/> + <ref name='virSecretListSecrets'/> + <ref name='virSecretNumOfSecrets'/> + <ref name='virSecretSetValue'/> + <ref name='virSecretSetXML'/> </word> <word name='virConnectClose'> <ref name='virConnectRef'/> @@ -6735,6 +6949,8 @@ </word> <word name='virConnectOpen'> <ref name='virConnectGetURI'/> + <ref name='virConnectOpenAuth'/> + <ref name='virConnectOpenReadOnly'/> </word> <word name='virConnectOpenReadOnly'> <ref name='virConnectGetURI'/> @@ -6908,7 +7124,6 @@ <ref name='virStoragePoolLookupByUUID'/> <ref name='virStoragePoolLookupByUUIDString'/> <ref name='virStoragePoolLookupByVolume'/> - <ref name='virStoragePoolUndefine'/> </word> <word name='virStoragePoolState'> <ref name='_virStoragePoolInfo'/> @@ -6983,6 +7198,8 @@ <ref name='virEventRemoveTimeoutFunc'/> <ref name='virGetVersion'/> <ref name='virNodeDeviceFree'/> + <ref name='virSecretSetValue'/> + <ref name='virSecretSetXML'/> <ref name='virStoragePoolRefresh'/> </word> <word name='watch'> @@ -7054,6 +7271,7 @@ </word> <word name='without'> <ref name='virDomainSuspend'/> + <ref name='virSecretAllocateID'/> </word> <word name='won'> <ref name='virDomainBlockPeek'/> @@ -7107,6 +7325,7 @@ </word> <word name='xml'> <ref name='virConnectFindStoragePoolSources'/> + <ref name='virSecretSetXML'/> </word> <word name='xvda'> <ref name='virDomainBlockStats'/> @@ -7143,14 +7362,14 @@ </chunk> <chunks> <chunk name='chunk0' start='A' end='I'/> - <chunk name='chunk1' start='J' end='W'/> - <chunk name='chunk2' start='X' end='a'/> + <chunk name='chunk1' start='J' end='V'/> + <chunk name='chunk2' start='W' end='a'/> <chunk name='chunk3' start='b' end='c'/> <chunk name='chunk4' start='d' end='e'/> - <chunk name='chunk5' start='f' end='g'/> - <chunk name='chunk6' start='h' end='i'/> - <chunk name='chunk7' start='j' end='m'/> - <chunk name='chunk8' start='n' end='p'/> + <chunk name='chunk5' start='f' end='h'/> + <chunk name='chunk6' start='i' end='l'/> + <chunk name='chunk7' start='m' end='n'/> + <chunk name='chunk8' start='o' end='p'/> <chunk name='chunk9' start='q' end='r'/> <chunk name='chunk10' start='s' end='s'/> <chunk name='chunk11' start='t' end='u'/> -- 1.6.2.5

Sample session:
import libvirt c = libvirt.open('qemu:///session')
c.virSecretListSecrets() ['12247729-47d2-a783-88ce-b329d4781cd3', 'reee', 'abc']
c.virSecretAllocateID() '17427ed8-4040-b6c8-10ba-9cce86dc3d8f'
c.virSecretDelete('17427ed8-4040-b6c8-10ba-9cce86dc3d8f') 0
c.virSecretSetXML('abc', "<secret ephemeral='no' private='yes'>\n<description>Something for use</description>\n<volume>/foo/bar</volume>\n</secret>\n") 0
c.virSecretGetXML('abc') "<secret ephemeral='no' private='yes'>\n <description>Something for use</description>\n <volume>/foo/bar</volume>\n</secret>\n"
c.virSecretSetValue('reee', 'abc\0xx\xffx') 0
c.virSecretGetValue('reee') 'abc\x00xx\xffx'
python/generator.py | 6 +++ python/libvir.c | 98 +++++++++++++++++++++++++++++++++++++++++ python/libvirt-python-api.xml | 18 ++++++++ 3 files changed, 122 insertions(+), 0 deletions(-) diff --git a/python/generator.py b/python/generator.py index feff7a3..49b7f68 100755 --- a/python/generator.py +++ b/python/generator.py @@ -332,6 +332,9 @@ skip_impl = ( 'virEventRegisterImpl', 'virNodeListDevices', 'virNodeDeviceListCaps', + 'virSecretGetValue', + 'virSecretListSecrets', + 'virSecretSetValue', ) @@ -729,6 +732,9 @@ def nameFixup(name, classe, type, file): elif name[0:19] == "virStorageVolLookup": func = name[3:] func = string.lower(func[0:1]) + func[1:] + elif name[0:9] == 'virSecret': + func = name[3:] + func = string.lower(func[0:1]) + func[1:] elif name[0:12] == "virDomainGet": func = name[12:] func = string.lower(func[0:1]) + func[1:] diff --git a/python/libvir.c b/python/libvir.c index e210597..b91a801 100644 --- a/python/libvir.c +++ b/python/libvir.c @@ -1562,6 +1562,101 @@ libvirt_virNodeDeviceListCaps(PyObject *self ATTRIBUTE_UNUSED, return(py_retval); } +static PyObject * +libvirt_virSecretGetValue(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) { + PyObject *py_retval; + void *c_retval; + size_t size; + virConnectPtr conn; + const char *secret_id; + PyObject *pyobj_conn; + + if (!PyArg_ParseTuple(args, (char *)"Oz:virSecreteGetValue", &pyobj_conn, + &secret_id)) + return NULL; + conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); + + LIBVIRT_BEGIN_ALLOW_THREADS; + c_retval = virSecretGetValue(conn, secret_id, &size); + LIBVIRT_END_ALLOW_THREADS; + + if (c_retval == NULL) + return VIR_PY_NONE; + + py_retval = PyString_FromStringAndSize(c_retval, size); + memset(c_retval, 0, size); + free(c_retval); + + return py_retval; +} + +static PyObject * +libvirt_virSecretListSecrets(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) { + PyObject *py_retval; + char **ids = NULL; + virConnectPtr conn; + int c_retval, i; + PyObject *pyobj_conn; + + if (!PyArg_ParseTuple(args, (char *)"O:virSecretListSecrets", &pyobj_conn)) + return NULL; + conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); + + LIBVIRT_BEGIN_ALLOW_THREADS; + c_retval = virSecretNumOfSecrets(conn); + LIBVIRT_END_ALLOW_THREADS; + if (c_retval < 0) + return VIR_PY_NONE; + + if (c_retval) { + ids = malloc(sizeof(*ids) * c_retval); + if (!ids) + return VIR_PY_NONE; + LIBVIRT_BEGIN_ALLOW_THREADS; + c_retval = virSecretListSecrets(conn, ids, c_retval); + LIBVIRT_END_ALLOW_THREADS; + if (c_retval < 0) { + free(ids); + return VIR_PY_NONE; + } + } + py_retval = PyList_New(c_retval); + + if (ids) { + for (i = 0;i < c_retval;i++) { + PyList_SetItem(py_retval, i, libvirt_constcharPtrWrap(ids[i])); + free(ids[i]); + } + free(ids); + } + + return py_retval; +} + +static PyObject * +libvirt_virSecretSetValue(PyObject *self ATTRIBUTE_UNUSED, + PyObject *args) { + PyObject *py_retval; + int c_retval; + virConnectPtr conn; + PyObject *pyobj_conn; + const char *secret_id, *secret; + int size; + + if (!PyArg_ParseTuple(args, (char *)"Ozz#:virSecretSetValue", &pyobj_conn, + &secret_id, &secret, &size)) + return(NULL); + conn = (virConnectPtr) PyvirConnect_Get(pyobj_conn); + + LIBVIRT_BEGIN_ALLOW_THREADS; + c_retval = virSecretSetValue(conn, secret_id, secret, size); + LIBVIRT_END_ALLOW_THREADS; + + py_retval = libvirt_intWrap(c_retval); + return(py_retval); +} /******************************************* * Helper functions to avoid importing modules @@ -2261,6 +2356,9 @@ static PyMethodDef libvirtMethods[] = { {(char *) "virEventInvokeTimeoutCallback", libvirt_virEventInvokeTimeoutCallback, METH_VARARGS, NULL}, {(char *) "virNodeListDevices", libvirt_virNodeListDevices, METH_VARARGS, NULL}, {(char *) "virNodeDeviceListCaps", libvirt_virNodeDeviceListCaps, METH_VARARGS, NULL}, + {(char *) "virSecretGetValue", libvirt_virSecretGetValue, METH_VARARGS, NULL}, + {(char *) "virSecretListSecrets", libvirt_virSecretListSecrets, METH_VARARGS, NULL}, + {(char *) "virSecretSetValue", libvirt_virSecretSetValue, METH_VARARGS, NULL}, {NULL, NULL, 0, NULL} }; diff --git a/python/libvirt-python-api.xml b/python/libvirt-python-api.xml index 43a5b4e..c1d6546 100644 --- a/python/libvirt-python-api.xml +++ b/python/libvirt-python-api.xml @@ -172,5 +172,23 @@ <arg name='dev' type='virNodeDevicePtr' info='pointer to the node device'/> <return type='str *' info='the list of Names or None in case of error'/> </function> + <function name='virSecretGetValue' file='libvirt' module='libvirt'> + <info>Fetches the secret value associated with secret_id.</info> + <return type='char *' info='the secret value or None in case of error'/> + <arg name='conn' type='virConnectPtr' info='virConnect connection'/> + <arg name='secret_id' type='const char *' info='A secret ID'/> + </function> + <function name='virSecretListSecrets' file='libvirt' module='libvirt'> + <info>List the defined secret IDs</info> + <arg name='conn' type='virConnectPtr' info='virConnect connection'/> + <return type='str *' info='the list of secret IDs or None in case of error'/> + </function> + <function name='virSecretSetValue' file='libvirt' module='libvirt'> + <info>Associates a secret value with secret_id. Allocates secret_id if it was not previously allocated.</info> + <return type='int' info='0 on success, -1 on failure.'/> + <arg name='conn' type='virConnectPtr' info='virConnect connection'/> + <arg name='secret_id' type='const char *' info='A secret ID'/> + <arg name='secret' type='const char *' info='The secret'/> + </function> </symbols> </api> -- 1.6.2.5

Define an <encryption> tag specifying volume encryption format and format-depenedent parameters (e.g. passphrase, cipher name, key length, key). Currently the only defined parameter is a reference to a "secret" (passphrase/key) managed using the virSecret* API. Only the qcow/qcow2 encryption format, and a "default" format used to let libvirt choose the format during volume creation, is currently supported. This patch does not add any users; the <encryption> tag is added in the following patches to both volumes (to support encrypted volume creation) and domains. Changes since the first submission; - Use <secret type='passphrase' secret_id='...'> instead of <passphrase> with in-line passphrase. - Use a generic "sequence of secrets" representation. - Output the <secret> elements unconditionally (they don't reveal the secrets any more). - Add format "default", to be used during volume creation only. - Use "%s", _("...") for all error messages without parameters. - Add a schema for <encryption>. - Document <encryption>. --- bootstrap | 1 + docs/format.html | 4 + docs/formatcaps.html | 4 + docs/formatdomain.html | 4 + docs/formatnetwork.html | 4 + docs/formatnode.html | 4 + docs/formatsecret.html | 4 + docs/formatstorage.html | 4 + docs/formatstorageencryption.html | 218 ++++++++++++++++++++++++++++++ docs/formatstorageencryption.html.in | 70 ++++++++++ docs/schemas/Makefile.am | 1 + docs/schemas/storageencryption.rng | 37 +++++ docs/sitemap.html | 3 + docs/sitemap.html.in | 4 + po/POTFILES.in | 1 + src/Makefile.am | 1 + src/libvirt_private.syms | 5 + src/storage_encryption.c | 241 ++++++++++++++++++++++++++++++++++ src/storage_encryption.h | 72 ++++++++++ 19 files changed, 682 insertions(+), 0 deletions(-) create mode 100644 docs/formatstorageencryption.html create mode 100644 docs/formatstorageencryption.html.in create mode 100644 docs/schemas/storageencryption.rng create mode 100644 src/storage_encryption.c create mode 100644 src/storage_encryption.h diff --git a/bootstrap b/bootstrap index 8b81e0e..885b299 100755 --- a/bootstrap +++ b/bootstrap @@ -65,6 +65,7 @@ gnulib_tool=$GNULIB_SRCDIR/gnulib-tool <$gnulib_tool || exit modules=' +base64 c-ctype close connect diff --git a/docs/format.html b/docs/format.html index 8aed8d3..dbdc1e7 100644 --- a/docs/format.html +++ b/docs/format.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> </div> </li><li> diff --git a/docs/formatcaps.html b/docs/formatcaps.html index 8e2e5d1..cb8130b 100644 --- a/docs/formatcaps.html +++ b/docs/formatcaps.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <span class="active">Capabilities</span> </div> </li><li> diff --git a/docs/formatdomain.html b/docs/formatdomain.html index bbce989..f2d7855 100644 --- a/docs/formatdomain.html +++ b/docs/formatdomain.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> </div> </li><li> diff --git a/docs/formatnetwork.html b/docs/formatnetwork.html index 6049492..87f15f7 100644 --- a/docs/formatnetwork.html +++ b/docs/formatnetwork.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> </div> </li><li> diff --git a/docs/formatnode.html b/docs/formatnode.html index cca75ff..ea9c95a 100644 --- a/docs/formatnode.html +++ b/docs/formatnode.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> </div> </li><li> diff --git a/docs/formatsecret.html b/docs/formatsecret.html index 8c6e0c6..53307a3 100644 --- a/docs/formatsecret.html +++ b/docs/formatsecret.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> </div> </li><li> diff --git a/docs/formatstorage.html b/docs/formatstorage.html index e21e3d2..19936ae 100644 --- a/docs/formatstorage.html +++ b/docs/formatstorage.html @@ -64,6 +64,10 @@ </div> </li><li> <div> + <a title="Storage volume encryption XML format" class="inactive" href="formatstorageencryption.html">Storage Encryption</a> + </div> + </li><li> + <div> <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> </div> </li><li> diff --git a/docs/formatstorageencryption.html b/docs/formatstorageencryption.html new file mode 100644 index 0000000..dd7add2 --- /dev/null +++ b/docs/formatstorageencryption.html @@ -0,0 +1,218 @@ +<?xml version="1.0" encoding="ISO-8859-1"?> +<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd"> +<html xmlns="http://www.w3.org/1999/xhtml"> +<!-- + This file is autogenerated from formatstorageencryption.html.in + Do not edit this file. Changes will be lost. + --> + <head> + <meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1" /> + <link rel="stylesheet" type="text/css" href="main.css" /> + <link rel="SHORTCUT ICON" href="32favicon.png" /> + <title>libvirt: Storage volume encryption XML format</title> + <meta name="description" content="libvirt, virtualization, virtualization API" /> + </head> + <body> + <div id="header"> + <div id="headerLogo"></div> + <div id="headerSearch"> + <form action="search.php" enctype="application/x-www-form-urlencoded" method="get"><div> + <input id="query" name="query" type="text" size="12" value="" /> + <input id="submit" name="submit" type="submit" value="Search" /> + </div></form> + </div> + </div> + <div id="body"> + <div id="menu"> + <ul class="l0"><li> + <div> + <a title="Front page of the libvirt website" class="inactive" href="index.html">Home</a> + </div> + </li><li> + <div> + <a title="Details of new features and bugs fixed in each release" class="inactive" href="news.html">News</a> + </div> + </li><li> + <div> + <a title="Get the latest source releases, binary builds and get access to the source repository" class="inactive" href="downloads.html">Downloads</a> + </div> + </li><li> + <div> + <a title="Information for users, administrators and developers" class="active" href="docs.html">Documentation</a> + <ul class="l1"><li> + <div> + <a title="Information about deploying and using libvirt" class="inactive" href="deployment.html">Deployment</a> + </div> + </li><li> + <div> + <a title="Overview of the logical subsystems in the libvirt API" class="inactive" href="intro.html">Architecture</a> + </div> + </li><li> + <div> + <a title="Description of the XML formats used in libvirt" class="active" href="format.html">XML format</a> + <ul class="l2"><li> + <div> + <a title="The domain XML format" class="inactive" href="formatdomain.html">Domains</a> + </div> + </li><li> + <div> + <a title="The virtual network XML format" class="inactive" href="formatnetwork.html">Networks</a> + </div> + </li><li> + <div> + <a title="The storage pool and volume XML format" class="inactive" href="formatstorage.html">Storage</a> + </div> + </li><li> + <div> + <span class="active">Storage Encryption</span> + </div> + </li><li> + <div> + <a title="The driver capabilities XML format" class="inactive" href="formatcaps.html">Capabilities</a> + </div> + </li><li> + <div> + <a title="The host device XML format" class="inactive" href="formatnode.html">Node Devices</a> + </div> + </li><li> + <div> + <a title="The secret attribute XML format" class="inactive" href="formatsecret.html">Secrets</a> + </div> + </li></ul> + </div> + </li><li> + <div> + <a title="Hypervisor specific driver information" class="inactive" href="drivers.html">Drivers</a> + </div> + </li><li> + <div> + <a title="Reference manual for the C public API" class="inactive" href="html/index.html">API reference</a> + </div> + </li><li> + <div> + <a title="Bindings of the libvirt API for other languages" class="inactive" href="bindings.html">Language bindings</a> + </div> + </li><li> + <div> + <a title="Working on the internals of libvirt API, driver and daemon code" class="inactive" href="internals.html">Internals</a> + </div> + </li></ul> + </div> + </li><li> + <div> + <a title="User contributed content" class="inactive" href="http://wiki.libvirt.org">Wiki</a> + </div> + </li><li> + <div> + <a title="Frequently asked questions" class="inactive" href="FAQ.html">FAQ</a> + </div> + </li><li> + <div> + <a title="How and where to report bugs and request features" class="inactive" href="bugs.html">Bug reports</a> + </div> + </li><li> + <div> + <a title="How to contact the developers via email and IRC" class="inactive" href="contact.html">Contact</a> + </div> + </li><li> + <div> + <a title="Miscellaneous links of interest related to libvirt" class="inactive" href="relatedlinks.html">Related Links</a> + </div> + </li><li> + <div> + <a title="Overview of all content on the website" class="inactive" href="sitemap.html">Sitemap</a> + </div> + </li></ul> + </div> + <div id="content"> + <h1>Storage volume encryption XML format</h1> + <ul><li> + <a href="#StorageEncryption">Storage volume encryption XML</a> + <ul><li> + <a href="#StorageEncryptionUnencrypted">"unencrypted" format</a> + </li><li> + <a href="#StorageEncryptionDefault">"default" format</a> + </li><li> + <a href="#StorageEncryptionQcow">"qcow" format</a> + </li></ul> + </li><li> + <a href="#example">Example</a> + </li></ul> + <h2> + <a name="StorageEncryption" id="StorageEncryption">Storage volume encryption XML</a> + </h2> + <p> + Storage volumes may be encrypted, the XML snippet described below is used + to represent the details of the encryption. It can be used as a part + of a domain or storage configuration. + </p> + <p> + The top-level tag of volume encryption specification + is <code>encryption</code>, with a mandatory + attribute <code>format</code>. Currently defined values + of <code>format</code> are <code>unencrypted</code>, <code>default</code> + and <code>qcow</code>. Each value of <code>format</code> implies some + expectations about the content of the <code>encryption</code> tag. Other + format values may be defined in the future. + </p> + <p> + The <code>encryption</code> tag can currently contain a sequence of + <code>secret</code> tags, each with mandatory attributes <code>type</code> + and <code>secret_id</code>. The only currently defined value of + <code>type</code> is <code>passphrase</code>. <code>secret_id</code> + refers to a secret known to libvirt. libvirt can use a secret value + previously set using <code>virSecretSetValue()</code>, or, if supported + by the particular volume format and driver, automatically generate a + secret value at the time of volume creation, and store it using the + specified <code>secret_id</code>. + </p> + <p> + </p> + <h3> + <a name="StorageEncryptionUnencrypted" id="StorageEncryptionUnencrypted">"unencrypted" format</a> + </h3> + <p> + Specifying an <code><encryption type="unencrypted"/></code> is + equivalent to omitting the <code>encryption</code> tag altogether. + </p> + <h3> + <a name="StorageEncryptionDefault" id="StorageEncryptionDefault">"default" format</a> + </h3> + <p> + <code><encryption type="default"/></code> can be specified only + when creating a volume. If the volume is successfully created, the + encryption formats, parameters and secrets will be auto-generated by + libvirt and the attached <code>encryption</code> tag will be updated. + The unmodified contents of the <code>encryption</code> tag can be used + in later operations with the volume, or when setting up a domain that + uses the volume. + </p> + <h3> + <a name="StorageEncryptionQcow" id="StorageEncryptionQcow">"qcow" format</a> + </h3> + <p> + The <code>qcow</code> format specifies that the built-in encryption + support in <code>qcow</code>- or <code>qcow2</code>-formatted volume + images should be used. A single + <code><secret type='passphrase'></code> element is expected. If + the <code>secret</code> element is not present during volume creation, + a secret is automatically generated and attached to the volume. + </p> + <h2> + <a name="example" id="example">Example</a> + </h2> + <p> + Here is a simple example, specifying use of the <code>qcow</code> format: + </p> + <pre> + <encryption format='qcow'> + <secret type='passphrase' secret_id='c1f11a6d-8c5d-4a3e-ac7a-4e171c5e0d4a' /> + </encryption></pre> + </div> + </div> + <div id="footer"> + <p id="sponsor"> + Sponsored by:<br /><a href="http://et.redhat.com/"><img src="et.png" alt="Project sponsored by Red Hat Emerging Technology" /></a></p> + </div> + </body> +</html> diff --git a/docs/formatstorageencryption.html.in b/docs/formatstorageencryption.html.in new file mode 100644 index 0000000..739b018 --- /dev/null +++ b/docs/formatstorageencryption.html.in @@ -0,0 +1,70 @@ +<html> + <body> + <h1>Storage volume encryption XML format</h1> + + <ul id="toc"></ul> + + <h2><a name="StorageEncryption">Storage volume encryption XML</a></h2> + + <p> + Storage volumes may be encrypted, the XML snippet described below is used + to represent the details of the encryption. It can be used as a part + of a domain or storage configuration. + </p> + <p> + The top-level tag of volume encryption specification + is <code>encryption</code>, with a mandatory + attribute <code>format</code>. Currently defined values + of <code>format</code> are <code>unencrypted</code>, <code>default</code> + and <code>qcow</code>. Each value of <code>format</code> implies some + expectations about the content of the <code>encryption</code> tag. Other + format values may be defined in the future. + </p> + <p> + The <code>encryption</code> tag can currently contain a sequence of + <code>secret</code> tags, each with mandatory attributes <code>type</code> + and <code>secret_id</code>. The only currently defined value of + <code>type</code> is <code>passphrase</code>. <code>secret_id</code> + refers to a secret known to libvirt. libvirt can use a secret value + previously set using <code>virSecretSetValue()</code>, or, if supported + by the particular volume format and driver, automatically generate a + secret value at the time of volume creation, and store it using the + specified <code>secret_id</code>. + <p> + <h3><a name="StorageEncryptionUnencrypted">"unencrypted" format</a></h3> + <p> + Specifying an <code><encryption type="unencrypted"/></code> is + equivalent to omitting the <code>encryption</code> tag altogether. + </p> + <h3><a name="StorageEncryptionDefault">"default" format</a></h3> + <p> + <code><encryption type="default"/></code> can be specified only + when creating a volume. If the volume is successfully created, the + encryption formats, parameters and secrets will be auto-generated by + libvirt and the attached <code>encryption</code> tag will be updated. + The unmodified contents of the <code>encryption</code> tag can be used + in later operations with the volume, or when setting up a domain that + uses the volume. + </p> + <h3><a name="StorageEncryptionQcow">"qcow" format</a></h3> + <p> + The <code>qcow</code> format specifies that the built-in encryption + support in <code>qcow</code>- or <code>qcow2</code>-formatted volume + images should be used. A single + <code><secret type='passphrase'></code> element is expected. If + the <code>secret</code> element is not present during volume creation, + a secret is automatically generated and attached to the volume. + </p> + + <h2><a name="example">Example</a></h2> + + <p> + Here is a simple example, specifying use of the <code>qcow</code> format: + </p> + + <pre> + <encryption format='qcow'> + <secret type='passphrase' secret_id='c1f11a6d-8c5d-4a3e-ac7a-4e171c5e0d4a' /> + </encryption></pre> + </body> +</html> diff --git a/docs/schemas/Makefile.am b/docs/schemas/Makefile.am index a064518..c217d69 100644 --- a/docs/schemas/Makefile.am +++ b/docs/schemas/Makefile.am @@ -6,6 +6,7 @@ schema_DATA = \ interface.rng \ network.rng \ secret.rng \ + storageencryption.rng \ storagepool.rng \ storagevol.rng \ nodedev.rng \ diff --git a/docs/schemas/storageencryption.rng b/docs/schemas/storageencryption.rng new file mode 100644 index 0000000..69a2841 --- /dev/null +++ b/docs/schemas/storageencryption.rng @@ -0,0 +1,37 @@ +<!-- A Relax NG schema for the libvirt volume encryption XML format --> +<grammar xmlns="http://relaxng.org/ns/structure/1.0" + datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> + + <define name='encryption'> + <optional> + <element name='encryption'> + <attribute name='format'> + <choice> + <value>unencrypted</value> + <value>default</value> + <value>qcow</value> + </choice> + </attribute> + <zeroOrMore> + <ref name='secret'/> + </zeroOrMore> + </element> + </optional> + </define> + + <define name='secret'> + <element name='secret'> + <attribute name='type'> + <choice> + <value>passphrase</value> + </choice> + </attribute> + <optional> + <attribute name='secret_id'> + <text/> + </attribute> + </optional> + </element> + </define> + +</grammar> diff --git a/docs/sitemap.html b/docs/sitemap.html index cf43088..21516be 100644 --- a/docs/sitemap.html +++ b/docs/sitemap.html @@ -136,6 +136,9 @@ <a href="formatstorage.html">Storage</a> <span>The storage pool and volume XML format</span> </li><li> + <a href="formatstorageencryption.html">Storage Encryption</a> + <span>Storage volume encryption XML format</span> + </li><li> <a href="formatcaps.html">Capabilities</a> <span>The driver capabilities XML format</span> </li><li> diff --git a/docs/sitemap.html.in b/docs/sitemap.html.in index 4c4dfa4..cb0cb89 100644 --- a/docs/sitemap.html.in +++ b/docs/sitemap.html.in @@ -99,6 +99,10 @@ <span>The storage pool and volume XML format</span> </li> <li> + <a href="formatstorageencryption.html">Storage Encryption</a> + <span>Storage volume encryption XML format</span> + </li> + <li> <a href="formatcaps.html">Capabilities</a> <span>The driver capabilities XML format</span> </li> diff --git a/po/POTFILES.in b/po/POTFILES.in index cf0ec8d..36b83a2 100644 --- a/po/POTFILES.in +++ b/po/POTFILES.in @@ -40,6 +40,7 @@ src/storage_backend_logical.c src/storage_backend_scsi.c src/storage_conf.c src/storage_driver.c +src/storage_encryption.c src/test.c src/uml_conf.c src/uml_driver.c diff --git a/src/Makefile.am b/src/Makefile.am index ce33695..2c1c9b4 100644 --- a/src/Makefile.am +++ b/src/Makefile.am @@ -52,6 +52,7 @@ UTIL_SOURCES = \ memory.c memory.h \ pci.c pci.h \ qparams.c qparams.h \ + storage_encryption.h storage_encryption.c \ threads.c threads.h \ threads-pthread.h \ threads-win32.h \ diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms index 343a71e..de4e413 100644 --- a/src/libvirt_private.syms +++ b/src/libvirt_private.syms @@ -332,6 +332,11 @@ virStoragePartedFsTypeTypeToString; virStoragePoolObjLock; virStoragePoolObjUnlock; +virStorageEncryptionFree; +virStorageEncryptionDropSecrets; +virStorageEncryptionParseNode; +virStorageEncryptionFormat; + # threads.h virMutexInit; diff --git a/src/storage_encryption.c b/src/storage_encryption.c new file mode 100644 index 0000000..15caafd --- /dev/null +++ b/src/storage_encryption.c @@ -0,0 +1,241 @@ +/* + * storage_encryption.h: volume encryption information + * + * Copyright (C) 2009 Red Hat, Inc. + * + * 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.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Red Hat Author: Miloslav Trmač <mitr@redhat.com> + */ + +#include <config.h> + +#include "internal.h" + +#include "base64.h" +#include "buf.h" +#include "memory.h" +#include "storage_conf.h" +#include "storage_encryption.h" +#include "util.h" +#include "xml.h" +#include "virterror_internal.h" + +#define VIR_FROM_THIS VIR_FROM_STORAGE + +VIR_ENUM_IMPL(virStorageEncryptionSecretType, + VIR_STORAGE_ENCRYPTION_SECRET_TYPE_LAST, "passphrase") + +VIR_ENUM_IMPL(virStorageEncryptionFormat, + VIR_STORAGE_ENCRYPTION_FORMAT_LAST, + "unencrypted", "default", "qcow") + +static void +virStorageEncryptionSecretFree(virStorageEncryptionSecretPtr secret) +{ + if (!secret) + return; + VIR_FREE(secret->secret_id); + VIR_FREE(secret); +} + +void +virStorageEncryptionFree(virStorageEncryptionPtr enc) +{ + size_t i; + + if (!enc) + return; + + for (i = 0; i < enc->nsecrets; i++) + virStorageEncryptionSecretFree(enc->secrets[i]); + VIR_FREE(enc->secrets); + VIR_FREE(enc); +} + +static virStorageEncryptionSecretPtr +virStorageEncryptionSecretParse(virConnectPtr conn, xmlXPathContextPtr ctxt, + xmlNodePtr node) +{ + xmlNodePtr old_node; + virStorageEncryptionSecretPtr ret; + char *type_str; + int type; + + if (VIR_ALLOC(ret) < 0) { + virReportOOMError(conn); + return NULL; + } + + old_node = ctxt->node; + ctxt->node = node; + + type_str = virXPathString(conn, "string(./@type)", ctxt); + if (type_str == NULL) { + virStorageReportError(conn, VIR_ERR_XML_ERROR, "%s", + _("unknown volume encryption secret type")); + goto cleanup; + } + type = virStorageEncryptionSecretTypeTypeFromString(type_str); + if (type < 0) { + virStorageReportError(conn, VIR_ERR_XML_ERROR, + _("unknown volume encryption secret type %s"), + type_str); + VIR_FREE(type_str); + goto cleanup; + } + VIR_FREE(type_str); + ret->type = type; + + ret->secret_id = virXPathString(conn, "string(./@secret_id)", ctxt); + ctxt->node = old_node; + return ret; + + cleanup: + virStorageEncryptionSecretFree(ret); + ctxt->node = old_node; + return NULL; +} + +static virStorageEncryptionPtr +virStorageEncryptionParseXML(virConnectPtr conn, xmlXPathContextPtr ctxt) +{ + xmlNodePtr *nodes = NULL; + virStorageEncryptionPtr ret; + char *format_str; + int format, i, n; + + if (VIR_ALLOC(ret) < 0) { + virReportOOMError(conn); + return NULL; + } + + format_str = virXPathString(conn, "string(./@format)", ctxt); + if (format_str == NULL) { + virStorageReportError(conn, VIR_ERR_XML_ERROR, "%s", + _("unknown volume encryption format")); + goto cleanup; + } + format = virStorageEncryptionFormatTypeFromString(format_str); + if (format < 0) { + virStorageReportError(conn, VIR_ERR_XML_ERROR, + _("unknown volume encryption format type %s"), + format_str); + VIR_FREE(format_str); + goto cleanup; + } + VIR_FREE(format_str); + ret->format = format; + + n = virXPathNodeSet(conn, "./secret", ctxt, &nodes); + if (n < 0){ + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("cannot extract volume encryption secrets")); + goto cleanup; + } + if (n != 0 && VIR_ALLOC_N(ret->secrets, n) < 0) { + virReportOOMError(conn); + goto cleanup; + } + ret->nsecrets = n; + for (i = 0; i < n; i++) { + ret->secrets[i] = virStorageEncryptionSecretParse(conn, ctxt, nodes[i]); + if (ret->secrets[i] == NULL) + goto cleanup; + } + VIR_FREE(nodes); + + return ret; + + cleanup: + VIR_FREE(nodes); + virStorageEncryptionFree(ret); + return NULL; +} + +virStorageEncryptionPtr +virStorageEncryptionParseNode(virConnectPtr conn, + xmlDocPtr xml, xmlNodePtr root) +{ + xmlXPathContextPtr ctxt = NULL; + virStorageEncryptionPtr enc = NULL; + + if (STRNEQ((const char *) root->name, "encryption")) { + virStorageReportError(conn, VIR_ERR_XML_ERROR, + "%s", _("unknown root element for volume " + "encryption information")); + goto cleanup; + } + + ctxt = xmlXPathNewContext(xml); + if (ctxt == NULL) { + virReportOOMError(conn); + goto cleanup; + } + + ctxt->node = root; + enc = virStorageEncryptionParseXML(conn, ctxt); + + cleanup: + xmlXPathFreeContext(ctxt); + return enc; +} + +static int +virStorageEncryptionSecretFormat(virConnectPtr conn, + virBufferPtr buf, + virStorageEncryptionSecretPtr secret) +{ + const char *type; + + type = virStorageEncryptionSecretTypeTypeToString(secret->type); + if (!type) { + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("unexpected volume encryption secret type")); + return -1; + } + + virBufferVSprintf(buf, " <secret type='%s'", type); + if (secret->secret_id != NULL) + virBufferEscapeString(buf, " secret_id='%s'", secret->secret_id); + virBufferAddLit(buf, "/>\n"); + return 0; +} + +int +virStorageEncryptionFormat(virConnectPtr conn, + virBufferPtr buf, + virStorageEncryptionPtr enc) +{ + const char *format; + size_t i; + + format = virStorageEncryptionFormatTypeToString(enc->format); + if (!format) { + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("unexpected encryption format")); + return -1; + } + virBufferVSprintf(buf, " <encryption format='%s'>\n", format); + + for (i = 0; i < enc->nsecrets; i++) { + if (virStorageEncryptionSecretFormat(conn, buf, enc->secrets[i]) < 0) + return -1; + } + + virBufferAddLit(buf, " </encryption>\n"); + + return 0; +} diff --git a/src/storage_encryption.h b/src/storage_encryption.h new file mode 100644 index 0000000..3153ec8 --- /dev/null +++ b/src/storage_encryption.h @@ -0,0 +1,72 @@ +/* + * storage_encryption.h: volume encryption information + * + * Copyright (C) 2009 Red Hat, Inc. + * + * 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.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + * + * Red Hat Author: Miloslav Trmač <mitr@redhat.com> + */ + +#ifndef __VIR_STORAGE_ENCRYPTION_H__ +#define __VIR_STORAGE_ENCRYPTION_H__ + +#include "internal.h" +#include "buf.h" +#include "util.h" + +#include <stdbool.h> +#include <libxml/tree.h> + +enum virStorageEncryptionSecretType { + VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE = 0, + + VIR_STORAGE_ENCRYPTION_SECRET_TYPE_LAST +}; +VIR_ENUM_DECL(virStorageEncryptionSecretType) + +typedef struct _virStorageEncryptionSecret virStorageEncryptionSecret; +typedef virStorageEncryptionSecret *virStorageEncryptionSecretPtr; +struct _virStorageEncryptionSecret { + int type; /* enum virStorageEncryptionSecretType */ + char *secret_id; +}; + +enum virStorageEncryptionFormat { + VIR_STORAGE_ENCRYPTION_FORMAT_UNENCRYPTED = 0, + VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT, /* Only valid for volume creation */ + VIR_STORAGE_ENCRYPTION_FORMAT_QCOW, /* Both qcow and qcow2 */ + + VIR_STORAGE_ENCRYPTION_FORMAT_LAST, +}; +VIR_ENUM_DECL(virStorageEncryptionFormat) + +typedef struct _virStorageEncryption virStorageEncryption; +typedef virStorageEncryption *virStorageEncryptionPtr; +struct _virStorageEncryption { + int format; /* enum virStorageEncryptionFormat */ + + size_t nsecrets; + virStorageEncryptionSecretPtr *secrets; +}; + +void virStorageEncryptionFree(virStorageEncryptionPtr enc); +virStorageEncryptionPtr virStorageEncryptionParseNode(virConnectPtr conn, + xmlDocPtr xml, + xmlNodePtr root); +int virStorageEncryptionFormat(virConnectPtr conn, virBufferPtr buf, + virStorageEncryptionPtr enc); + +#endif /* __VIR_STORAGE_ENCRYPTION_H__ */ -- 1.6.2.5

On Tue, Aug 04, 2009 at 10:28:26PM +0200, Miloslav Trma?? wrote:
Define an <encryption> tag specifying volume encryption format and format-depenedent parameters (e.g. passphrase, cipher name, key length, key).
Currently the only defined parameter is a reference to a "secret" (passphrase/key) managed using the virSecret* API.
Only the qcow/qcow2 encryption format, and a "default" format used to let libvirt choose the format during volume creation, is currently supported.
This patch does not add any users; the <encryption> tag is added in the following patches to both volumes (to support encrypted volume creation) and domains.
Changes since the first submission; - Use <secret type='passphrase' secret_id='...'> instead of <passphrase> with in-line passphrase. - Use a generic "sequence of secrets" representation. - Output the <secret> elements unconditionally (they don't reveal the secrets any more). - Add format "default", to be used during volume creation only. - Use "%s", _("...") for all error messages without parameters. - Add a schema for <encryption>. - Document <encryption>.
diff --git a/docs/schemas/storageencryption.rng b/docs/schemas/storageencryption.rng new file mode 100644 index 0000000..69a2841 --- /dev/null +++ b/docs/schemas/storageencryption.rng @@ -0,0 +1,37 @@ +<!-- A Relax NG schema for the libvirt volume encryption XML format --> +<grammar xmlns="http://relaxng.org/ns/structure/1.0" + datatypeLibrary="http://www.w3.org/2001/XMLSchema-datatypes"> + + <define name='encryption'> + <optional> + <element name='encryption'> + <attribute name='format'> + <choice> + <value>unencrypted</value> + <value>default</value> + <value>qcow</value> + </choice> + </attribute>
I don't think we should include 'unencrypted' here. If a volume is not encrypted, we should simply omit the <encryption> element entirely in the domain / storage volume XML doc.
+ <zeroOrMore> + <ref name='secret'/> + </zeroOrMore> + </element> + </optional> + </define> + + <define name='secret'> + <element name='secret'> + <attribute name='type'> + <choice> + <value>passphrase</value> + </choice> + </attribute> + <optional> + <attribute name='secret_id'> + <text/> + </attribute>
Lets just call this attribute 'uuid' - no need to have the word 'secret' prefixed on it too.
+ </optional> + </element> + </define> + +</grammar>
+static int +virStorageEncryptionSecretFormat(virConnectPtr conn, + virBufferPtr buf, + virStorageEncryptionSecretPtr secret) +{ + const char *type; + + type = virStorageEncryptionSecretTypeTypeToString(secret->type); + if (!type) { + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("unexpected volume encryption secret type")); + return -1; + } + + virBufferVSprintf(buf, " <secret type='%s'", type); + if (secret->secret_id != NULL) + virBufferEscapeString(buf, " secret_id='%s'", secret->secret_id); + virBufferAddLit(buf, "/>\n"); + return 0; +}
Tiny indentation bug crept in there.
+ +int +virStorageEncryptionFormat(virConnectPtr conn, + virBufferPtr buf, + virStorageEncryptionPtr enc) +{ + const char *format; + size_t i; + + format = virStorageEncryptionFormatTypeToString(enc->format); + if (!format) { + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, + "%s", _("unexpected encryption format")); + return -1; + } + virBufferVSprintf(buf, " <encryption format='%s'>\n", format); + + for (i = 0; i < enc->nsecrets; i++) { + if (virStorageEncryptionSecretFormat(conn, buf, enc->secrets[i]) < 0) + return -1; + }
And there too.
+ + virBufferAddLit(buf, " </encryption>\n"); + + return 0; +}
I think this is generally ok, aside from those minor stylist changes. Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

----- "Daniel P. Berrange" <berrange@redhat.com> wrote:
diff --git a/docs/schemas/storageencryption.rng b/docs/schemas/storageencryption.rng --- /dev/null +++ b/docs/schemas/storageencryption.rng @@ -0,0 +1,37 @@ <snip> + <element name='encryption'> + <attribute name='format'> + <choice> + <value>unencrypted</value> + <value>default</value> + <value>qcow</value> + </choice> + </attribute>
I don't think we should include 'unencrypted' here. If a volume is not encrypted, we should simply omit the <encryption> element entirely in the domain / storage volume XML doc. Fixed.
+ <element name='secret'> + <attribute name='type'> + <choice> + <value>passphrase</value> + </choice> + </attribute> + <optional> + <attribute name='secret_id'> + <text/> + </attribute>
Lets just call this attribute 'uuid' - no need to have the word 'secret' prefixed on it too.
Fixed. I'd prefer to keep this attribute defined a generic string (as opposed to the strict hexadecimal UUID format) because some of the possible remote backends might require a different identifier format. <snip>
Tiny indentation bug crept in there. <snip> And there too. Fixed both.
Thanks for the review, Mirek

The XML allows <encryption format='unencrypted'/>, this implementation canonicalizes the internal representation so that "vol->encryption" is non-NULL iff the volume is encrypted. Note that partial encryption information (e.g. specifying an encryption format, but not the key/passphrase) is valid, libvirt will automatically choose value for the missing information during volume creation. The user can read the volume XML, and use the unmodified <encryption> tag in future operations (without having to be able to understand) its contents. Changes since the first submission: - Attach <encryption> inside <target>. - Update <volume> schema. - Add documentation. - Add a schema validity test. --- docs/formatstorage.html | 6 ++++++ docs/formatstorage.html.in | 8 ++++++++ docs/schemas/storagevol.rng | 3 +++ src/storage_conf.c | 20 ++++++++++++++++++++ src/storage_conf.h | 4 ++++ tests/storagevolschemadata/vol-qcow2.xml | 4 ++++ 6 files changed, 45 insertions(+), 0 deletions(-) diff --git a/docs/formatstorage.html b/docs/formatstorage.html index 19936ae..97eaa92 100644 --- a/docs/formatstorage.html +++ b/docs/formatstorage.html @@ -252,6 +252,9 @@ <mode>0744</mode> <label>virt_image_t</label> </permissions> + <encryption type='...'> + ... + </encryption> </target> </pool></pre> <dl><dt><code>path</code></dt><dd>Provides the location at which the pool will be mapped into @@ -274,6 +277,9 @@ element contains the numeric group ID. The <code>label</code> element contains the MAC (eg SELinux) label string. <span class="since">Since 0.4.1</span> + </dd><dt><code>encryption</code></dt><dd>If present, specifies how the volume is encrypted. See + the <a href="formatstorageencryption.html">Storage Encryption</a> page + for more information. </dd></dl> <h3> <a name="StoragePoolExtents" id="StoragePoolExtents">Device extents</a> diff --git a/docs/formatstorage.html.in b/docs/formatstorage.html.in index 4878d72..3ed88a2 100644 --- a/docs/formatstorage.html.in +++ b/docs/formatstorage.html.in @@ -124,6 +124,9 @@ <mode>0744</mode> <label>virt_image_t</label> </permissions> + <encryption type='...'> + ... + </encryption> </target> </pool></pre> @@ -152,6 +155,11 @@ contains the MAC (eg SELinux) label string. <span class="since">Since 0.4.1</span> </dd> + <dt><code>encryption</code></dt> + <dd>If present, specifies how the volume is encrypted. See + the <a href="formatstorageencryption.html">Storage Encryption</a> page + for more information. + </dd> </dl> <h3><a name="StoragePoolExtents">Device extents</a></h3> diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng index 7dc7876..6ab685a 100644 --- a/docs/schemas/storagevol.rng +++ b/docs/schemas/storagevol.rng @@ -6,6 +6,8 @@ <ref name='vol'/> </start> + <include href='storageencryption.rng'/> + <define name='vol'> <element name='volume'> @@ -74,6 +76,7 @@ </optional> <ref name='format'/> <ref name='permissions'/> + <ref name='encryption'/> </element> </define> diff --git a/src/storage_conf.c b/src/storage_conf.c index 075279c..9a1b0ba 100644 --- a/src/storage_conf.c +++ b/src/storage_conf.c @@ -265,8 +265,10 @@ virStorageVolDefFree(virStorageVolDefPtr def) { VIR_FREE(def->target.path); VIR_FREE(def->target.perms.label); + virStorageEncryptionFree(def->target.encryption); VIR_FREE(def->backingStore.path); VIR_FREE(def->backingStore.perms.label); + virStorageEncryptionFree(def->backingStore.encryption); VIR_FREE(def); } @@ -960,6 +962,7 @@ virStorageVolDefParseXML(virConnectPtr conn, char *allocation = NULL; char *capacity = NULL; char *unit = NULL; + xmlNodePtr node; options = virStorageVolOptionsForPoolType(pool->type); if (options == NULL) @@ -1024,6 +1027,19 @@ virStorageVolDefParseXML(virConnectPtr conn, "./target/permissions", 0600) < 0) goto cleanup; + node = virXPathNode(conn, "./target/encryption", ctxt); + if (node != NULL) { + virStorageEncryptionPtr enc; + + enc = virStorageEncryptionParseNode(conn, ctxt->doc, node); + if (enc == NULL) + goto cleanup; + if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_UNENCRYPTED) + ret->target.encryption = enc; + else + virStorageEncryptionFree(enc); + } + ret->backingStore.path = virXPathString(conn, "string(./backingStore/path)", ctxt); @@ -1194,6 +1210,10 @@ virStorageVolTargetDefFormat(virConnectPtr conn, virBufferAddLit(buf," </permissions>\n"); + if (def->encryption != NULL && + virStorageEncryptionFormat(conn, buf, def->encryption) < 0) + return -1; + virBufferVSprintf(buf, " </%s>\n", type); return 0; diff --git a/src/storage_conf.h b/src/storage_conf.h index a6c3650..8ae1742 100644 --- a/src/storage_conf.h +++ b/src/storage_conf.h @@ -26,6 +26,7 @@ #include "internal.h" #include "util.h" +#include "storage_encryption.h" #include "threads.h" #include <libxml/tree.h> @@ -77,6 +78,9 @@ struct _virStorageVolTarget { int format; virStoragePerms perms; int type; /* only used by disk backend for partition type */ + /* Only used if not "unencrypted". + Currently used only in virStorageVolDef.target, not in .backingstore. */ + virStorageEncryptionPtr encryption; }; diff --git a/tests/storagevolschemadata/vol-qcow2.xml b/tests/storagevolschemadata/vol-qcow2.xml index c1cf02f..b07c93c 100644 --- a/tests/storagevolschemadata/vol-qcow2.xml +++ b/tests/storagevolschemadata/vol-qcow2.xml @@ -14,6 +14,10 @@ <group>0</group> <label>unconfined_u:object_r:virt_image_t:s0</label> </permissions> + <encryption format='qcow'> + <secret type='passphrase' + secret_id='e78d4b51-a2af-485f-b0f5-afca709a80f4'/> + </encryption> </target> <backingStore> <path>/var/lib/libvirt/images/BaseDemo.img</path> -- 1.6.2.5

On Tue, Aug 04, 2009 at 10:28:27PM +0200, Miloslav Trma?? wrote:
The XML allows <encryption format='unencrypted'/>, this implementation canonicalizes the internal representation so that "vol->encryption" is non-NULL iff the volume is encrypted.
Note that partial encryption information (e.g. specifying an encryption format, but not the key/passphrase) is valid, libvirt will automatically choose value for the missing information during volume creation. The user can read the volume XML, and use the unmodified <encryption> tag in future operations (without having to be able to understand) its contents.
diff --git a/docs/schemas/storagevol.rng b/docs/schemas/storagevol.rng index 7dc7876..6ab685a 100644 --- a/docs/schemas/storagevol.rng +++ b/docs/schemas/storagevol.rng @@ -6,6 +6,8 @@ <ref name='vol'/> </start>
+ <include href='storageencryption.rng'/> +
<define name='vol'> <element name='volume'> @@ -74,6 +76,7 @@ </optional> <ref name='format'/> <ref name='permissions'/> + <ref name='encryption'/> </element> </define>
To allow removal of "<encryption>" for non-encrypted cases, I believe we'd need to add <optional> <ref name='encrption'/> </optional> Unless that's 'encryption' schema rule itself has <optional> already ?
diff --git a/src/storage_conf.c b/src/storage_conf.c index 075279c..9a1b0ba 100644 --- a/src/storage_conf.c +++ b/src/storage_conf.c @@ -265,8 +265,10 @@ virStorageVolDefFree(virStorageVolDefPtr def) {
VIR_FREE(def->target.path); VIR_FREE(def->target.perms.label); + virStorageEncryptionFree(def->target.encryption); VIR_FREE(def->backingStore.path); VIR_FREE(def->backingStore.perms.label); + virStorageEncryptionFree(def->backingStore.encryption); VIR_FREE(def); }
@@ -960,6 +962,7 @@ virStorageVolDefParseXML(virConnectPtr conn, char *allocation = NULL; char *capacity = NULL; char *unit = NULL; + xmlNodePtr node;
options = virStorageVolOptionsForPoolType(pool->type); if (options == NULL) @@ -1024,6 +1027,19 @@ virStorageVolDefParseXML(virConnectPtr conn, "./target/permissions", 0600) < 0) goto cleanup;
+ node = virXPathNode(conn, "./target/encryption", ctxt); + if (node != NULL) { + virStorageEncryptionPtr enc; + + enc = virStorageEncryptionParseNode(conn, ctxt->doc, node); + if (enc == NULL) + goto cleanup; + if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_UNENCRYPTED) + ret->target.encryption = enc; + else + virStorageEncryptionFree(enc); + } +
ret->backingStore.path = virXPathString(conn, "string(./backingStore/path)", ctxt); @@ -1194,6 +1210,10 @@ virStorageVolTargetDefFormat(virConnectPtr conn,
virBufferAddLit(buf," </permissions>\n");
+ if (def->encryption != NULL && + virStorageEncryptionFormat(conn, buf, def->encryption) < 0) + return -1; + virBufferVSprintf(buf, " </%s>\n", type);
return 0; diff --git a/src/storage_conf.h b/src/storage_conf.h index a6c3650..8ae1742 100644 --- a/src/storage_conf.h +++ b/src/storage_conf.h @@ -26,6 +26,7 @@
#include "internal.h" #include "util.h" +#include "storage_encryption.h" #include "threads.h"
#include <libxml/tree.h> @@ -77,6 +78,9 @@ struct _virStorageVolTarget { int format; virStoragePerms perms; int type; /* only used by disk backend for partition type */ + /* Only used if not "unencrypted". + Currently used only in virStorageVolDef.target, not in .backingstore. */ + virStorageEncryptionPtr encryption; };
diff --git a/tests/storagevolschemadata/vol-qcow2.xml b/tests/storagevolschemadata/vol-qcow2.xml index c1cf02f..b07c93c 100644 --- a/tests/storagevolschemadata/vol-qcow2.xml +++ b/tests/storagevolschemadata/vol-qcow2.xml @@ -14,6 +14,10 @@ <group>0</group> <label>unconfined_u:object_r:virt_image_t:s0</label> </permissions> + <encryption format='qcow'> + <secret type='passphrase' + secret_id='e78d4b51-a2af-485f-b0f5-afca709a80f4'/> + </encryption> </target> <backingStore> <path>/var/lib/libvirt/images/BaseDemo.img</path> -- 1.6.2.5
Daniel -- |: Red Hat, Engineering, London -o- http://people.redhat.com/berrange/ :| |: http://libvirt.org -o- http://virt-manager.org -o- http://ovirt.org :| |: http://autobuild.org -o- http://search.cpan.org/~danberr/ :| |: GnuPG: 7D3B9505 -o- F3C9 553F A1DA 4AC2 5648 23C1 B3DF F742 7D3B 9505 :|

----- "Daniel P. Berrange" <berrange@redhat.com> wrote:
<define name='vol'> <element name='volume'> @@ -74,6 +76,7 @@ </optional> <ref name='format'/> <ref name='permissions'/> + <ref name='encryption'/> </element> </define>
To allow removal of "<encryption>" for non-encrypted cases, I believe we'd need to add
<optional> <ref name='encrption'/> </optional>
Unless that's 'encryption' schema rule itself has <optional> already ? Yes, it currently does. I'll move the <optional> to the users, to be more explicit.
Thanks for the review, Mirek

(The implementation is not very generic, but that can be very easily rectified if/when new encryption formats appear.) Changes since first submission: - Move <encryption> inside <target>. --- src/storage_backend_fs.c | 61 +++++++++++++++++++++++++++++++++++---------- 1 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/storage_backend_fs.c b/src/storage_backend_fs.c index ca6d329..5568b20 100644 --- a/src/storage_backend_fs.c +++ b/src/storage_backend_fs.c @@ -26,6 +26,7 @@ #include <sys/statvfs.h> #include <sys/types.h> #include <sys/stat.h> +#include <stdbool.h> #include <stdio.h> #include <dirent.h> #include <errno.h> @@ -81,6 +82,9 @@ struct FileTypeInfo { /* Store a COW base image path (possibly relative), * or NULL if there is no COW base image, to RES; * return BACKING_STORE_* */ + int qcowCryptOffset; /* Byte offset from start of file + * where to find encryption mode, + * -1 if encryption is not used */ int (*getBackingStore)(virConnectPtr conn, char **res, const unsigned char *buf, size_t buf_size); }; @@ -89,54 +93,54 @@ struct FileTypeInfo const fileTypeInfo[] = { /* XXX Untested { VIR_STORAGE_VOL_FILE_BOCHS, "Bochs Virtual HD Image", NULL, LV_LITTLE_ENDIAN, 64, 0x20000, - 32+16+16+4+4+4+4+4, 8, 1, NULL },*/ + 32+16+16+4+4+4+4+4, 8, 1, -1, NULL },*/ /* CLoop */ /* XXX Untested { VIR_STORAGE_VOL_CLOOP, "#!/bin/sh\n#V2.0 Format\nmodprobe cloop file=$0 && mount -r -t iso9660 /dev/cloop $1\n", NULL, LV_LITTLE_ENDIAN, -1, 0, - -1, 0, 0, NULL }, */ + -1, 0, 0, -1, NULL }, */ /* Cow */ { VIR_STORAGE_VOL_FILE_COW, "OOOM", NULL, LV_BIG_ENDIAN, 4, 2, - 4+4+1024+4, 8, 1, cowGetBackingStore }, + 4+4+1024+4, 8, 1, -1, cowGetBackingStore }, /* DMG */ /* XXX QEMU says there's no magic for dmg, but we should check... */ { VIR_STORAGE_VOL_FILE_DMG, NULL, ".dmg", 0, -1, 0, - -1, 0, 0, NULL }, + -1, 0, 0, -1, NULL }, /* XXX there's probably some magic for iso we can validate too... */ { VIR_STORAGE_VOL_FILE_ISO, NULL, ".iso", 0, -1, 0, - -1, 0, 0, NULL }, + -1, 0, 0, -1, NULL }, /* Parallels */ /* XXX Untested { VIR_STORAGE_VOL_FILE_PARALLELS, "WithoutFreeSpace", NULL, LV_LITTLE_ENDIAN, 16, 2, - 16+4+4+4+4, 4, 512, NULL }, + 16+4+4+4+4, 4, 512, -1, NULL }, */ /* QCow */ { VIR_STORAGE_VOL_FILE_QCOW, "QFI", NULL, LV_BIG_ENDIAN, 4, 1, - 4+4+8+4+4, 8, 1, qcowXGetBackingStore }, + 4+4+8+4+4, 8, 1, 4+4+8+4+4+8+1+1+2, qcowXGetBackingStore }, /* QCow 2 */ { VIR_STORAGE_VOL_FILE_QCOW2, "QFI", NULL, LV_BIG_ENDIAN, 4, 2, - 4+4+8+4+4, 8, 1, qcowXGetBackingStore }, + 4+4+8+4+4, 8, 1, 4+4+8+4+4+8, qcowXGetBackingStore }, /* VMDK 3 */ /* XXX Untested { VIR_STORAGE_VOL_FILE_VMDK, "COWD", NULL, LV_LITTLE_ENDIAN, 4, 1, - 4+4+4, 4, 512, NULL }, + 4+4+4, 4, 512, -1, NULL }, */ /* VMDK 4 */ { VIR_STORAGE_VOL_FILE_VMDK, "KDMV", NULL, LV_LITTLE_ENDIAN, 4, 1, - 4+4+4, 8, 512, vmdk4GetBackingStore }, + 4+4+4, 8, 512, -1, vmdk4GetBackingStore }, /* Connectix / VirtualPC */ /* XXX Untested { VIR_STORAGE_VOL_FILE_VPC, "conectix", NULL, LV_BIG_ENDIAN, -1, 0, - -1, 0, 0, NULL}, + -1, 0, 0, -1, NULL}, */ }; @@ -282,13 +286,16 @@ static int virStorageBackendProbeTarget(virConnectPtr conn, virStorageVolTargetPtr target, char **backingStore, unsigned long long *allocation, - unsigned long long *capacity) { + unsigned long long *capacity, + virStorageEncryptionPtr *encryption) { int fd; unsigned char head[20*512]; /* vmdk4GetBackingStore needs this much. */ int len, i, ret; if (backingStore) *backingStore = NULL; + if (encryption) + *encryption = NULL; if ((fd = open(target->path, O_RDONLY)) < 0) { virReportSystemError(conn, errno, @@ -317,6 +324,8 @@ static int virStorageBackendProbeTarget(virConnectPtr conn, /* First check file magic */ for (i = 0 ; i < ARRAY_CARDINALITY(fileTypeInfo) ; i++) { int mlen; + bool encrypted_qcow = false; + if (fileTypeInfo[i].magic == NULL) continue; @@ -375,6 +384,16 @@ static int virStorageBackendProbeTarget(virConnectPtr conn, *capacity *= fileTypeInfo[i].sizeMultiplier; } + if (fileTypeInfo[i].qcowCryptOffset != -1) { + int crypt_format; + + crypt_format = (head[fileTypeInfo[i].qcowCryptOffset] << 24) | + (head[fileTypeInfo[i].qcowCryptOffset+1] << 16) | + (head[fileTypeInfo[i].qcowCryptOffset+2] << 8) | + head[fileTypeInfo[i].qcowCryptOffset+3]; + encrypted_qcow = crypt_format != 0; + } + /* Validation passed, we know the file format now */ target->format = fileTypeInfo[i].type; if (fileTypeInfo[i].getBackingStore != NULL && backingStore) { @@ -400,6 +419,18 @@ static int virStorageBackendProbeTarget(virConnectPtr conn, } } } + if (encryption != NULL && encrypted_qcow) { + virStorageEncryptionPtr enc; + + if (VIR_ALLOC(enc) < 0) { + virReportOOMError(conn); + if (backingStore) + VIR_FREE(*backingStore); + return -1; + } + enc->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW; + *encryption = enc; + } return 0; } @@ -868,7 +899,8 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn, &vol->target, &backingStore, &vol->allocation, - &vol->capacity) < 0)) { + &vol->capacity, + &vol->target.encryption) < 0)) { if (ret == -1) goto cleanup; else { @@ -908,7 +940,8 @@ virStorageBackendFileSystemRefresh(virConnectPtr conn, if ((ret = virStorageBackendProbeTarget(conn, &vol->backingStore, - NULL, NULL, NULL)) < 0) { + NULL, NULL, NULL, + NULL)) < 0) { if (ret == -1) goto cleanup; else { -- 1.6.2.5

Supports only virStorageVolCreateXML, not virStorageVolCreateXMLFrom. Curiously, qemu-img does not need the passphrase for anything to create an encrypted volume. This implementation thus does not need to touch any secrets to work with cooperating clients. More generic passphrase handling is added in the next patch. Changes since first submission: - Move <encryption> inside <target>. - Don't discard secrets after volume creation. - Refuse <encryption> specifying more than one secret when creating qcow or qcow2 volumes --- src/storage_backend.c | 47 +++++++++++++++++++++++++++++++++++++++- src/storage_backend_disk.c | 7 ++++++ src/storage_backend_fs.c | 7 ++++++ src/storage_backend_logical.c | 7 ++++++ 4 files changed, 66 insertions(+), 2 deletions(-) diff --git a/src/storage_backend.c b/src/storage_backend.c index 07a2e48..2d37b8b 100644 --- a/src/storage_backend.c +++ b/src/storage_backend.c @@ -246,6 +246,13 @@ virStorageBackendCreateRaw(virConnectPtr conn, unsigned long long remain; char *buf = NULL; + if (vol->target.encryption != NULL) { + virStorageReportError(conn, VIR_ERR_NO_SUPPORT, + "%s", _("storage pool does not support encrypted " + "volumes")); + return -1; + } + if ((fd = open(vol->target.path, O_RDWR | O_CREAT | O_EXCL, vol->target.perms.mode)) < 0) { virReportSystemError(conn, errno, @@ -346,15 +353,17 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, NULL; const char **imgargv; + /* The extra NULL field is for indicating encryption (-e). */ const char *imgargvnormal[] = { NULL, "create", "-f", type, vol->target.path, size, NULL, + NULL }; /* Extra NULL fields are for including "backingType" when using - * kvm-img. It's -F backingType + * kvm-img (-F backingType), and for indicating encryption (-e). */ const char *imgargvbacking[] = { NULL, "create", @@ -364,6 +373,7 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, size, NULL, NULL, + NULL, NULL }; const char *convargv[] = { @@ -417,6 +427,28 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, } } + if (vol->target.encryption != NULL) { + if (vol->target.format != VIR_STORAGE_VOL_FILE_QCOW && + vol->target.format != VIR_STORAGE_VOL_FILE_QCOW2) { + virStorageReportError(conn, VIR_ERR_NO_SUPPORT, + _("qcow volume encryption unsupported with " + "volume format %s"), type); + return -1; + } + if (vol->target.encryption->format != + VIR_STORAGE_ENCRYPTION_FORMAT_QCOW) { + virStorageReportError(conn, VIR_ERR_NO_SUPPORT, + _("unsupported volume encryption format %d"), + vol->target.encryption->format); + return -1; + } + if (vol->target.encryption->nsecrets > 1) { + virStorageReportError(conn, VIR_ERR_INVALID_STORAGE_VOL, + _("too many secrets for qcow encryption")); + return -1; + } + } + if ((create_tool = virFindFileInPath("kvm-img")) != NULL) use_kvmimg = 1; else if ((create_tool = virFindFileInPath("qemu-img")) != NULL) @@ -437,11 +469,16 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, imgargvbacking[7] = backingType; imgargvbacking[8] = vol->target.path; imgargvbacking[9] = size; - } + if (vol->target.encryption != NULL) + imgargvbacking[10] = "-e"; + } else if (vol->target.encryption != NULL) + imgargvbacking[8] = "-e"; imgargv = imgargvbacking; } else { imgargvnormal[0] = create_tool; imgargv = imgargvnormal; + if (vol->target.encryption != NULL) + imgargv[6] = "-e"; } @@ -489,6 +526,12 @@ virStorageBackendCreateQcowCreate(virConnectPtr conn, "qcow-create")); return -1; } + if (vol->target.encryption != NULL) { + virStorageReportError(conn, VIR_ERR_NO_SUPPORT, + "%s", _("encrypted volumes not supported with " + "qcow-create")); + return -1; + } /* Size in MB - yes different units to qemu-img :-( */ snprintf(size, sizeof(size), "%llu", vol->capacity/1024/1024); diff --git a/src/storage_backend_disk.c b/src/storage_backend_disk.c index ae2acae..6fdb566 100644 --- a/src/storage_backend_disk.c +++ b/src/storage_backend_disk.c @@ -557,6 +557,13 @@ virStorageBackendDiskCreateVol(virConnectPtr conn, NULL }; + if (vol->target.encryption != NULL) { + virStorageReportError(conn, VIR_ERR_NO_SUPPORT, + "%s", _("storage pool does not support encrypted " + "volumes")); + return -1; + } + if (virStorageBackendDiskPartFormat(conn, pool, vol, partFormat) != 0) { return -1; } diff --git a/src/storage_backend_fs.c b/src/storage_backend_fs.c index 5568b20..65b656d 100644 --- a/src/storage_backend_fs.c +++ b/src/storage_backend_fs.c @@ -1102,6 +1102,13 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn, int tool_type; if (inputvol) { + if (vol->target.encryption != NULL) { + virStorageReportError(conn, VIR_ERR_NO_SUPPORT, + "%s", _("storage pool does not support " + "building encrypted volumes from " + "other volumes")); + return -1; + } create_func = virStorageBackendGetBuildVolFromFunction(conn, vol, inputvol); if (!create_func) diff --git a/src/storage_backend_logical.c b/src/storage_backend_logical.c index 6c123ae..bc40dd7 100644 --- a/src/storage_backend_logical.c +++ b/src/storage_backend_logical.c @@ -581,6 +581,13 @@ virStorageBackendLogicalCreateVol(virConnectPtr conn, }; const char **cmdargv = cmdargvnew; + if (vol->target.encryption != NULL) { + virStorageReportError(conn, VIR_ERR_NO_SUPPORT, + "%s", _("storage pool does not support encrypted " + "volumes")); + return -1; + } + if (vol->backingStore.path) { cmdargv = cmdargvsnap; } -- 1.6.2.5

If the <encryption format='qcow'> element does not specify a secret during volume creation, generate a suitable secret and add it to the <encryption> tag. The caller can view the updated <encryption> tag using virStorageVolGetXMLDesc(). Similarly, when <encryption format='default'/> is specified while creating a qcow or qcow2-formatted volume, change the format to "qcow" and generate a secret as described above. --- src/storage_backend.c | 122 +++++++++++++++++++++++++++++++++++++++++++++++- 1 files changed, 119 insertions(+), 3 deletions(-) diff --git a/src/storage_backend.c b/src/storage_backend.c index 2d37b8b..53bca65 100644 --- a/src/storage_backend.c +++ b/src/storage_backend.c @@ -43,6 +43,7 @@ #include <selinux/selinux.h> #endif +#include "datatypes.h" #include "virterror_internal.h" #include "util.h" #include "memory.h" @@ -331,6 +332,113 @@ cleanup: } static int +virStorageGenerateQcowEncryption(virConnectPtr conn, + virStorageVolDefPtr vol) +{ + virBuffer buf = VIR_BUFFER_INITIALIZER; + virStorageEncryptionPtr enc; + virStorageEncryptionSecretPtr enc_secret = NULL; + char *secret_id = NULL, *tmp = NULL; + unsigned char secret[16]; + int ret = -1, fd = -1; + size_t i; + + if (conn->secretDriver == NULL || conn->secretDriver->allocateID == NULL || + conn->secretDriver->setXML == NULL || + conn->secretDriver->setValue == NULL) { + virStorageReportError(conn, VIR_ERR_NO_SUPPORT, "%s", + _("secret storage not supported")); + goto cleanup; + } + + enc = vol->target.encryption; + if (enc->nsecrets != 0) { + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("secrets already defined")); + goto cleanup; + } + + if (VIR_ALLOC(enc_secret) < 0 || VIR_REALLOC_N(enc->secrets, 1) < 0) { + virReportOOMError(conn); + goto cleanup; + } + + secret_id = conn->secretDriver->allocateID(conn); + if (secret_id == NULL) + goto cleanup; + + virBufferAddLit(&buf, "<secret ephemeral='no' private='no'>"); + virBufferEscapeString(&buf, + "<description>qcow passphrase for %s</description>", + vol->target.path); + virBufferEscapeString(&buf, "<volume>%s</volume>", vol->target.path); + virBufferAddLit(&buf, "</secret>"); + if (virBufferError(&buf)) { + virReportOOMError(conn); + goto cleanup; + } + tmp = virBufferContentAndReset(&buf); + if (conn->secretDriver->setXML(conn, secret_id, tmp) < 0) { + VIR_FREE(tmp); + goto cleanup; + } + VIR_FREE(tmp); + + /* A qcow passphrase is up to 16 bytes, with any data following a NUL + ignored. Prohibit control and non-ASCII characters to avoid possible + unpleasant surprises with the qemu monitor input mechanism. */ + fd = open("/dev/urandom", O_RDONLY); + if (fd < 0) { + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot open /dev/urandom")); + goto cleanup; + } + i = 0; + while (i < sizeof (secret)) { + ssize_t r; + + while ((r = read(fd, secret + i, 1)) == -1 && errno == EINTR) + ; + if (r <= 0) { + virStorageReportError(conn, VIR_ERR_INTERNAL_ERROR, "%s", + _("Cannot read from /dev/urandom")); + goto cleanup; + } + if (secret[i] >= 0x20 && secret[i] <= 0x7E) + i++; /* Got an acceptable character */ + } + close(fd); + fd = -1; + + if (conn->secretDriver->setValue(conn, secret_id, secret, + sizeof(secret)) < 0) + goto cleanup; + + enc_secret->type = VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE; + enc_secret->secret_id = secret_id; + secret_id = NULL; + enc->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW; + enc->secrets[0] = enc_secret; /* Space for secrets[0] allocated above */ + enc_secret = NULL; + enc->nsecrets = 1; + + ret = 0; + +cleanup: + if (fd != -1) + close(fd); + tmp = virBufferContentAndReset(&buf); + VIR_FREE(tmp); + if (secret_id != NULL) { + if (conn->secretDriver->delete != NULL) + conn->secretDriver->delete(conn, secret_id); + VIR_FREE(secret_id); + } + VIR_FREE(enc_secret); + return ret; +} + +static int virStorageBackendCreateQemuImg(virConnectPtr conn, virStorageVolDefPtr vol, virStorageVolDefPtr inputvol, @@ -428,6 +536,8 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, } if (vol->target.encryption != NULL) { + virStorageEncryptionPtr enc; + if (vol->target.format != VIR_STORAGE_VOL_FILE_QCOW && vol->target.format != VIR_STORAGE_VOL_FILE_QCOW2) { virStorageReportError(conn, VIR_ERR_NO_SUPPORT, @@ -435,18 +545,24 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, "volume format %s"), type); return -1; } - if (vol->target.encryption->format != - VIR_STORAGE_ENCRYPTION_FORMAT_QCOW) { + enc = vol->target.encryption; + if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_QCOW && + enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT) { virStorageReportError(conn, VIR_ERR_NO_SUPPORT, _("unsupported volume encryption format %d"), vol->target.encryption->format); return -1; } - if (vol->target.encryption->nsecrets > 1) { + if (enc->nsecrets > 1) { virStorageReportError(conn, VIR_ERR_INVALID_STORAGE_VOL, _("too many secrets for qcow encryption")); return -1; } + if (enc->format == VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT || + enc->nsecrets == 0) { + if (virStorageGenerateQcowEncryption(conn, vol) < 0) + return -1; + } } if ((create_tool = virFindFileInPath("kvm-img")) != NULL) -- 1.6.2.5

The XML allows <encryption format='unencrypted'/>, this implementation canonicalizes the internal representation so that "disk->encryption" is non-NULL iff encryption information is available. A domain with partial encryption information can be defined, completeness of the information is not verified. The domain won't start until the remaining information is added, of course. Changes since the first submission: - Add schema for the <encryption> tag. - Document the <encryption> tag. - Ignore VIR_DOMAIN_XML_SECURE, the <secret> tags are always output. --- docs/formatdomain.html | 6 ++++++ docs/formatdomain.html.in | 8 ++++++++ docs/schemas/domain.rng | 3 +++ src/domain_conf.c | 19 +++++++++++++++++++ src/domain_conf.h | 2 ++ 5 files changed, 38 insertions(+), 0 deletions(-) diff --git a/docs/formatdomain.html b/docs/formatdomain.html index f2d7855..c483195 100644 --- a/docs/formatdomain.html +++ b/docs/formatdomain.html @@ -453,6 +453,9 @@ <driver name="tap" type="aio"> <source file='/var/lib/xen/images/fv0'/> <target dev='hda' bus='ide'/> + <encryption type='...'> + ... + </encryption> </disk> ...</pre> <dl><dt><code>disk</code></dt><dd>The <code>disk</code> element is the main container for describing @@ -478,6 +481,9 @@ <code>driver</code> element allows them to be selected. The <code>name</code> attribute is the primary backend driver name, while the optional <code>type</code> attribute provides the sub-type. <span class="since">Since 0.1.8</span> + </dd><dt><code>encryption</code></dt><dd>If present, specifies how the volume is encrypted. See + the <a href="formatstorageencryption.html">Storage Encryption</a> page + for more information. </dd></dl> <h4> <a name="elementsUSB" id="elementsUSB">USB and PCI devices</a> diff --git a/docs/formatdomain.html.in b/docs/formatdomain.html.in index eb12784..211f7ed 100644 --- a/docs/formatdomain.html.in +++ b/docs/formatdomain.html.in @@ -338,6 +338,9 @@ <driver name="tap" type="aio"> <source file='/var/lib/xen/images/fv0'/> <target dev='hda' bus='ide'/> + <encryption type='...'> + ... + </encryption> </disk> ...</pre> @@ -373,6 +376,11 @@ attribute is the primary backend driver name, while the optional <code>type</code> attribute provides the sub-type. <span class="since">Since 0.1.8</span> </dd> + <dt><code>encryption</code></dt> + <dd>If present, specifies how the volume is encrypted. See + the <a href="formatstorageencryption.html">Storage Encryption</a> page + for more information. + </dd> </dl> <h4><a name="elementsUSB">USB and PCI devices</a></h4> diff --git a/docs/schemas/domain.rng b/docs/schemas/domain.rng index f857301..4defc1e 100644 --- a/docs/schemas/domain.rng +++ b/docs/schemas/domain.rng @@ -4,6 +4,8 @@ <start> <ref name="domain"/> </start> + + <include href='storageencryption.rng'/> <!-- We handle only document defining a domain --> @@ -336,6 +338,7 @@ <empty/> </element> </optional> + <ref name="encryption"/> </define> <!-- A disk description can be either of type file or block diff --git a/src/domain_conf.c b/src/domain_conf.c index 2301a96..710eff4 100644 --- a/src/domain_conf.c +++ b/src/domain_conf.c @@ -288,6 +288,7 @@ void virDomainDiskDefFree(virDomainDiskDefPtr def) VIR_FREE(def->dst); VIR_FREE(def->driverName); VIR_FREE(def->driverType); + virStorageEncryptionFree(def->encryption); VIR_FREE(def); } @@ -658,6 +659,7 @@ virDomainDiskDefParseXML(virConnectPtr conn, char *bus = NULL; char *cachetag = NULL; char *devaddr = NULL; + virStorageEncryptionPtr encryption = NULL; if (VIR_ALLOC(def) < 0) { virReportOOMError(conn); @@ -715,6 +717,17 @@ virDomainDiskDefParseXML(virConnectPtr conn, } else if ((flags & VIR_DOMAIN_XML_INTERNAL_STATUS) && xmlStrEqual(cur->name, BAD_CAST "state")) { devaddr = virXMLPropString(cur, "devaddr"); + } else if (encryption == NULL && + xmlStrEqual(cur->name, BAD_CAST "encryption")) { + encryption = virStorageEncryptionParseNode(conn, node->doc, + cur); + if (encryption == NULL) + goto error; + if (encryption->format == + VIR_STORAGE_ENCRYPTION_FORMAT_UNENCRYPTED) { + virStorageEncryptionFree(encryption); + encryption = NULL; + } } } cur = cur->next; @@ -833,6 +846,8 @@ virDomainDiskDefParseXML(virConnectPtr conn, driverName = NULL; def->driverType = driverType; driverType = NULL; + def->encryption = encryption; + encryption = NULL; cleanup: VIR_FREE(bus); @@ -844,6 +859,7 @@ cleanup: VIR_FREE(driverName); VIR_FREE(cachetag); VIR_FREE(devaddr); + virStorageEncryptionFree(encryption); return def; @@ -3501,6 +3517,9 @@ virDomainDiskDefFormat(virConnectPtr conn, virBufferAddLit(buf, " <readonly/>\n"); if (def->shared) virBufferAddLit(buf, " <shareable/>\n"); + if (def->encryption != NULL && + virStorageEncryptionFormat(conn, buf, def->encryption) < 0) + return -1; if (flags & VIR_DOMAIN_XML_INTERNAL_STATUS) { virBufferAddLit(buf, " <state"); diff --git a/src/domain_conf.h b/src/domain_conf.h index 63fca76..c8ff282 100644 --- a/src/domain_conf.h +++ b/src/domain_conf.h @@ -30,6 +30,7 @@ #include "internal.h" #include "capabilities.h" +#include "storage_encryption.h" #include "util.h" #include "threads.h" @@ -117,6 +118,7 @@ struct _virDomainDiskDef { unsigned bus; unsigned slot; } pci_addr; + virStorageEncryptionPtr encryption; }; static inline int -- 1.6.2.5

The if ((nlptr...)) implicitly assumes commptr != NULL (and that "buf" starts with "cmd"). Make the assumption explicit, it will be broken in a future patch. --- src/qemu_driver.c | 7 ++++--- 1 files changed, 4 insertions(+), 3 deletions(-) diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 412b68d..17de104 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -2357,10 +2357,11 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm, * occurence, and inbetween the command and the newline starting * the response */ - if ((commptr = strstr(buf, cmd))) + if ((commptr = strstr(buf, cmd))) { memmove(buf, commptr, strlen(commptr)+1); - if ((nlptr = strchr(buf, '\n'))) - memmove(buf+strlen(cmd), nlptr, strlen(nlptr)+1); + if ((nlptr = strchr(buf, '\n'))) + memmove(buf+strlen(cmd), nlptr, strlen(nlptr)+1); + } break; } -- 1.6.2.5

Support arbitrary callbacks for "secondary prompts". Reimplement qemudMonitorCommandExtra using such a callback. --- src/qemu_driver.c | 84 +++++++++++++++++++++++++++++++++++++++++++++------- 1 files changed, 72 insertions(+), 12 deletions(-) diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 17de104..7a2e581 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -88,6 +88,12 @@ static void qemuDriverUnlock(struct qemud_driver *driver) virMutexUnlock(&driver->lock); } +/* Return -1 for error, 0 for success */ +typedef int qemudMonitorExtraPromptHandler(const virDomainObjPtr vm, + const char *buf, + const char *prompt, + void *data); + static void qemuDomainEventFlush(int timer, void *opaque); static void qemuDomainEventQueue(struct qemud_driver *driver, virDomainEventPtr event); @@ -116,6 +122,13 @@ static int qemudMonitorCommandWithFd(const virDomainObjPtr vm, const char *cmd, int scm_fd, char **reply); +static int qemudMonitorCommandWithHandler(const virDomainObjPtr vm, + const char *cmd, + const char *extraPrompt, + qemudMonitorExtraPromptHandler extraHandler, + void *handlerData, + int scm_fd, + char **reply); static int qemudMonitorCommandExtra(const virDomainObjPtr vm, const char *cmd, const char *extra, @@ -2290,12 +2303,13 @@ out: } static int -qemudMonitorCommandExtra(const virDomainObjPtr vm, - const char *cmd, - const char *extra, - const char *extraPrompt, - int scm_fd, - char **reply) { +qemudMonitorCommandWithHandler(const virDomainObjPtr vm, + const char *cmd, + const char *extraPrompt, + qemudMonitorExtraPromptHandler extraHandler, + void *handlerData, + int scm_fd, + char **reply) { int size = 0; char *buf = NULL; @@ -2339,12 +2353,20 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm, /* Look for QEMU prompt to indicate completion */ if (buf) { - if (extra) { - if (strstr(buf, extraPrompt) != NULL) { - if (qemudMonitorSend(vm, extra, -1) < 0) - return -1; - extra = NULL; - } + char *foundPrompt; + + if (extraPrompt && + (foundPrompt = strstr(buf, extraPrompt)) != NULL) { + char *promptEnd; + + if (extraHandler(vm, buf, foundPrompt, handlerData) < 0) + return -1; + /* Discard output so far, necessary to detect whether + extraPrompt appears again. We don't need the output between + original command and this prompt anyway. */ + promptEnd = foundPrompt + strlen(extraPrompt); + memmove(buf, promptEnd, strlen(promptEnd)+1); + size -= promptEnd - buf; } else if ((tmp = strstr(buf, QEMU_CMD_PROMPT)) != NULL) { char *commptr = NULL, *nlptr = NULL; /* Preserve the newline */ @@ -2382,6 +2404,44 @@ qemudMonitorCommandExtra(const virDomainObjPtr vm, return -1; } +struct extraHandlerData +{ + const char *reply; + bool first; +}; + +static int +qemudMonitorCommandSimpleExtraHandler(const virDomainObjPtr vm, + const char *buf ATTRIBUTE_UNUSED, + const char *prompt ATTRIBUTE_UNUSED, + void *data_) +{ + struct extraHandlerData *data = data_; + + if (!data->first) + return 0; + if (qemudMonitorSend(vm, data->reply, -1) < 0) + return -1; + data->first = false; + return 0; +} + +static int +qemudMonitorCommandExtra(const virDomainObjPtr vm, + const char *cmd, + const char *extra, + const char *extraPrompt, + int scm_fd, + char **reply) { + struct extraHandlerData data; + + data.reply = extra; + data.first = true; + return qemudMonitorCommandWithHandler(vm, cmd, extraPrompt, + qemudMonitorCommandSimpleExtraHandler, + &data, scm_fd, reply); +} + static int qemudMonitorCommandWithFd(const virDomainObjPtr vm, const char *cmd, -- 1.6.2.5

The interface allows qemudMonitorSendCont() to report errors that are not overridden by its callers. Also fix a potential infinite loop in qemuDomainCoreDump() if sending cont repeatedly fails. Changes since the first submission: - Suport reporting errors that are not overridden by callers. --- src/qemu_driver.c | 78 +++++++++++++++++++++++++++++++--------------------- 1 files changed, 46 insertions(+), 32 deletions(-) diff --git a/src/qemu_driver.c b/src/qemu_driver.c index 7a2e581..d654651 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -28,6 +28,7 @@ #include <dirent.h> #include <limits.h> #include <string.h> +#include <stdbool.h> #include <stdio.h> #include <strings.h> #include <stdarg.h> @@ -135,6 +136,9 @@ static int qemudMonitorCommandExtra(const virDomainObjPtr vm, const char *extraPrompt, int scm_fd, char **reply); +static int qemudMonitorSendCont(virConnectPtr conn, + const virDomainObjPtr vm, + bool *error_reported); static int qemudDomainSetMemoryBalloon(virConnectPtr conn, virDomainObjPtr vm, unsigned long newmem); @@ -1225,7 +1229,6 @@ static int qemudInitCpus(virConnectPtr conn, virDomainObjPtr vm, const char *migrateFrom) { - char *info = NULL; #if HAVE_SCHED_GETAFFINITY cpu_set_t mask; int i, maxcpu = QEMUD_CPUMASK_LEN; @@ -1260,13 +1263,15 @@ qemudInitCpus(virConnectPtr conn, #endif /* HAVE_SCHED_GETAFFINITY */ if (migrateFrom == NULL) { + bool error_reported; + /* Allow the CPUS to start executing */ - if (qemudMonitorCommand(vm, "cont", &info) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, - "%s", _("resume operation failed")); + if (qemudMonitorSendCont(conn, vm, &error_reported) < 0) { + if (!error_reported) + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + "%s", _("resume operation failed")); return -1; } - VIR_FREE(info); } return 0; @@ -2457,6 +2462,20 @@ qemudMonitorCommand(const virDomainObjPtr vm, return qemudMonitorCommandWithFd(vm, cmd, -1, reply); } +static int +qemudMonitorSendCont(virConnectPtr conn ATTRIBUTE_UNUSED, + const virDomainObjPtr vm, + bool *error_reported) { + char *reply; + + *error_reported = false; + if (qemudMonitorCommand(vm, "cont", &reply) < 0) + return -1; + qemudDebug ("%s: cont reply: %s", vm->def->name, info); + VIR_FREE(reply); + return 0; +} + static virDrvOpenStatus qemudOpen(virConnectPtr conn, virConnectAuthPtr auth ATTRIBUTE_UNUSED, int flags ATTRIBUTE_UNUSED) { @@ -2941,7 +2960,6 @@ cleanup: static int qemudDomainResume(virDomainPtr dom) { struct qemud_driver *driver = dom->conn->privateData; - char *info; virDomainObjPtr vm; int ret = -1; virDomainEventPtr event = NULL; @@ -2962,17 +2980,18 @@ static int qemudDomainResume(virDomainPtr dom) { goto cleanup; } if (vm->state == VIR_DOMAIN_PAUSED) { - if (qemudMonitorCommand(vm, "cont", &info) < 0) { - qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, - "%s", _("resume operation failed")); + bool error_reported; + + if (qemudMonitorSendCont(dom->conn, vm, &error_reported) < 0) { + if (!error_reported) + qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, + "%s", _("resume operation failed")); goto cleanup; } vm->state = VIR_DOMAIN_RUNNING; - qemudDebug("Reply %s", info); event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_RESUMED, VIR_DOMAIN_EVENT_RESUMED_UNPAUSED); - VIR_FREE(info); } if (virDomainSaveStatus(dom->conn, driver->stateDir, vm) < 0) goto cleanup; @@ -3663,13 +3682,13 @@ cleanup: will support synchronous operations so we always get here after the migration is complete. */ if (resume && paused) { - if (qemudMonitorCommand(vm, "cont", &info) < 0) { - qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, - "%s", _("resuming after dump failed")); - goto cleanup; + bool error_reported; + + if (qemudMonitorSendCont(dom->conn, vm, &error_reported) < 0) { + if (!error_reported) + qemudReportError(dom->conn, dom, NULL, VIR_ERR_OPERATION_FAILED, + "%s", _("resuming after dump failed")); } - DEBUG ("%s: cont reply: %s", vm->def->name, info); - VIR_FREE(info); } if (vm) virDomainObjUnlock(vm); @@ -4147,13 +4166,14 @@ static int qemudDomainRestore(virConnectPtr conn, /* If it was running before, resume it now. */ if (header.was_running) { - char *info; - if (qemudMonitorCommand(vm, "cont", &info) < 0) { - qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, - "%s", _("failed to resume domain")); + bool error_reported; + + if (qemudMonitorSendCont(conn, vm, &error_reported) < 0) { + if (!error_reported) + qemudReportError(conn, NULL, NULL, VIR_ERR_OPERATION_FAILED, + "%s", _("failed to resume domain")); goto cleanup; } - VIR_FREE(info); vm->state = VIR_DOMAIN_RUNNING; } ret = 0; @@ -6591,14 +6611,11 @@ qemudDomainMigratePerform (virDomainPtr dom, ret = 0; cleanup: - /* Note that we have to free info *first*, since we are re-using the - * variable below (and otherwise might cause a memory leak) - */ - VIR_FREE(info); - if (paused) { + bool error_reported; + /* we got here through some sort of failure; start the domain again */ - if (qemudMonitorCommand (vm, "cont", &info) < 0) { + if (qemudMonitorSendCont(dom->conn, vm, &error_reported) < 0) { /* Hm, we already know we are in error here. We don't want to * overwrite the previous error, though, so we just throw something * to the logs and hope for the best @@ -6606,16 +6623,13 @@ cleanup: VIR_ERROR(_("Failed to resume guest %s after failure\n"), vm->def->name); } - else { - DEBUG ("%s: cont reply: %s", vm->def->name, info); - VIR_FREE(info); - } event = virDomainEventNewFromObj(vm, VIR_DOMAIN_EVENT_RESUMED, VIR_DOMAIN_EVENT_RESUMED_MIGRATED); } + VIR_FREE(info); if (vm) virDomainObjUnlock(vm); if (event) -- 1.6.2.5

Changes since the first submission: - Update to use the generic "secrets" encryption representation, and the separate secret store. - Use qemudMonitorSend() --- include/libvirt/virterror.h | 1 + src/qemu_driver.c | 157 ++++++++++++++++++++++++++++++++++++++++-- src/virterror.c | 6 ++ 3 files changed, 156 insertions(+), 8 deletions(-) diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h index fc24251..53f2f20 100644 --- a/include/libvirt/virterror.h +++ b/include/libvirt/virterror.h @@ -169,6 +169,7 @@ typedef enum { VIR_ERR_MULTIPLE_INTERFACES, /* more than one matching interface found */ VIR_WAR_NO_SECRET, /* failed to start secret storage */ VIR_ERR_NO_SECRET, /* secret not found */ + VIR_ERR_INVALID_SECRET, /* invalid secret */ } virErrorNumber; /** diff --git a/src/qemu_driver.c b/src/qemu_driver.c index d654651..dc6e653 100644 --- a/src/qemu_driver.c +++ b/src/qemu_driver.c @@ -1284,12 +1284,6 @@ qemudInitPasswords(virConnectPtr conn, virDomainObjPtr vm) { char *info = NULL; - /* - * NB: Might have more passwords to set in the future. eg a qcow - * disk decryption password, but there's no monitor command - * for that yet... - */ - if ((vm->def->ngraphics == 1) && vm->def->graphics[0]->type == VIR_DOMAIN_GRAPHICS_TYPE_VNC && (vm->def->graphics[0]->data.vnc.passwd || driver->vncPassword)) { @@ -2462,14 +2456,161 @@ qemudMonitorCommand(const virDomainObjPtr vm, return qemudMonitorCommandWithFd(vm, cmd, -1, reply); } +static virStorageEncryptionPtr +findDomainDiskEncryption(virConnectPtr conn, virDomainObjPtr vm, + const char *path) +{ + bool seen_volume; + int i; + + seen_volume = false; + for (i = 0; i < vm->def->ndisks; i++) { + virDomainDiskDefPtr disk; + + disk = vm->def->disks[i]; + if (disk->src != NULL && STREQ(disk->src, path)) { + seen_volume = true; + if (disk->encryption != NULL) + return disk->encryption; + } + } + if (seen_volume) + qemudReportError(conn, NULL, NULL, VIR_ERR_INVALID_DOMAIN, + _("missing <encryption> for volume %s"), path); + else + qemudReportError(conn, NULL, NULL, VIR_ERR_INTERNAL_ERROR, + _("unexpected passphrase request for volume %s"), + path); + return NULL; +} + +static char * +findVolumeQcowPassphrase(virConnectPtr conn, virDomainObjPtr vm, + const char *path, size_t *passphrase_len) +{ + virStorageEncryptionPtr enc; + char *passphrase; + void *data; + size_t size; + + if (conn->secretDriver == NULL || conn->secretDriver->getValue == NULL) { + qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SUPPORT, "%s", + _("secret storage not supported")); + return NULL; + } + + enc = findDomainDiskEncryption(conn, vm, path); + if (enc == NULL) + return NULL; + + if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_QCOW || + enc->nsecrets != 1 || + enc->secrets[0]->type != + VIR_STORAGE_ENCRYPTION_SECRET_TYPE_PASSPHRASE) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INVALID_DOMAIN, + _("invalid <encryption> for volume %s"), path); + return NULL; + } + + if (enc->secrets[0]->secret_id == NULL) { + qemudReportError(conn, NULL, NULL, VIR_ERR_INVALID_DOMAIN, + _("missing secret_id for volume %s"), path); + return NULL; + } + data = conn->secretDriver->getValue(conn, enc->secrets[0]->secret_id, + &size, true); + if (data == NULL) { + qemudReportError(conn, NULL, NULL, VIR_ERR_NO_SECRET, + _("secret not found for volume %s"), path); + return NULL; + } + + if (memchr(data, '\0', size) != NULL) { + memset(data, 0, size); + VIR_FREE(data); + qemudReportError(conn, NULL, NULL, VIR_ERR_INVALID_SECRET, + _("format='qcow' passphrase for %s must not contain a " + "'\\0'"), path); + return NULL; + } + + if (VIR_ALLOC_N(passphrase, size + 1) < 0) { + memset(data, 0, size); + VIR_FREE(data); + virReportOOMError(conn); + return NULL; + } + memcpy(passphrase, data, size); + passphrase[size] = '\0'; + + memset(data, 0, size); + VIR_FREE(data); + + *passphrase_len = size; + return passphrase; +} + +struct sendVolumePassphraseState { + virConnectPtr conn; + bool *error_reported; +}; + +static int +qemudMonitorSendVolumePassphrase(const virDomainObjPtr vm, + const char *buf, + const char *prompt, + void *data) +{ + const struct sendVolumePassphraseState *state = data; + char *passphrase, *path; + const char *prompt_path; + size_t path_len, passphrase_len = 0; + int res; + + /* The complete prompt looks like this: + ide0-hd0 (/path/to/volume) is encrypted. + Password: + "prompt" starts with ") is encrypted". Extract /path/to/volume. */ + for (prompt_path = prompt; prompt_path > buf && prompt_path[-1] != '('; + prompt_path--) + ; + if (prompt_path == buf) + return -1; + path_len = prompt - prompt_path; + if (VIR_ALLOC_N(path, path_len + 1) < 0) + return -1; + memcpy(path, prompt_path, path_len); + path[path_len] = '\0'; + + passphrase = findVolumeQcowPassphrase(state->conn, vm, path, + &passphrase_len); + VIR_FREE(path); + if (passphrase == NULL) { + *state->error_reported = true; + return -1; + } + + res = qemudMonitorSend(vm, passphrase, -1); + + memset(passphrase, 0, passphrase_len); + VIR_FREE(passphrase); + + return res; +} + static int -qemudMonitorSendCont(virConnectPtr conn ATTRIBUTE_UNUSED, +qemudMonitorSendCont(virConnectPtr conn, const virDomainObjPtr vm, bool *error_reported) { + struct sendVolumePassphraseState state; char *reply; *error_reported = false; - if (qemudMonitorCommand(vm, "cont", &reply) < 0) + state.conn = conn; + state.error_reported = error_reported; + if (qemudMonitorCommandWithHandler(vm, "cont", ") is encrypted.", + qemudMonitorSendVolumePassphrase, + &state, -1, &reply) < 0) return -1; qemudDebug ("%s: cont reply: %s", vm->def->name, info); VIR_FREE(reply); diff --git a/src/virterror.c b/src/virterror.c index 137405a..9392498 100644 --- a/src/virterror.c +++ b/src/virterror.c @@ -1083,6 +1083,12 @@ virErrorMsg(virErrorNumber error, const char *info) else errmsg = _("Secret not found: %s"); break; + case VIR_ERR_INVALID_SECRET: + if (info == NULL) + errmsg = _("Invalid secret"); + else + errmsg = _("Invalid secret: %s"); + break; } return (errmsg); } -- 1.6.2.5
participants (3)
-
Daniel P. Berrange
-
Miloslav Trmac
-
Miloslav Trmač