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 third submission:
- Move base64 gnulib module inclusion to an earlier patch
---
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 | 209 +++++++++++++++++++++++++++++
docs/formatstorageencryption.html.in | 65 +++++++++
docs/schemas/Makefile.am | 1 +
docs/schemas/storageencryption.rng | 34 +++++
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 ++++++++++
18 files changed, 664 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/docs/format.html b/docs/format.html
index 3c20b5f..e8b1498 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 5f2bc72..3240101 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 6b655ad..efba65a 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 72a3cda..845e558 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 516c27b..b269baa 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 998e874..929eb86 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 02cbcac..8c16a0f 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..15175fe
--- /dev/null
+++ b/docs/formatstorageencryption.html
@@ -0,0 +1,209 @@
+<?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 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="#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>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>uuid</code>. The only currently defined value of
+ <code>type</code> is <code>passphrase</code>.
<code>uuid</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>uuid</code>.
+ </p>
+ <p>
+ </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'
uuid='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..0e5dcee
--- /dev/null
+++ b/docs/formatstorageencryption.html.in
@@ -0,0 +1,65 @@
+<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>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>uuid</code>. The only currently defined value of
+ <code>type</code> is <code>passphrase</code>.
<code>uuid</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>uuid</code>.
+ <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'
uuid='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..8f9cd62
--- /dev/null
+++ b/docs/schemas/storageencryption.rng
@@ -0,0 +1,34 @@
+<!-- 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'>
+ <element name='encryption'>
+ <attribute name='format'>
+ <choice>
+ <value>default</value>
+ <value>qcow</value>
+ </choice>
+ </attribute>
+ <zeroOrMore>
+ <ref name='secret'/>
+ </zeroOrMore>
+ </element>
+ </define>
+
+ <define name='secret'>
+ <element name='secret'>
+ <attribute name='type'>
+ <choice>
+ <value>passphrase</value>
+ </choice>
+ </attribute>
+ <optional>
+ <attribute name='uuid'>
+ <text/>
+ </attribute>
+ </optional>
+ </element>
+ </define>
+
+</grammar>
diff --git a/docs/sitemap.html b/docs/sitemap.html
index 901633d..24300d5 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 2ed25c6..65de169 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 e9d388a..ac3b2d6 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -41,6 +41,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 8b22030..101fbbb 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -346,6 +346,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..ccb29ed
--- /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(a)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,
+ "default", "qcow")
+
+static void
+virStorageEncryptionSecretFree(virStorageEncryptionSecretPtr secret)
+{
+ if (!secret)
+ return;
+ VIR_FREE(secret->uuid);
+ 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->uuid = virXPathString(conn, "string(./@uuid)", 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->uuid != NULL)
+ virBufferEscapeString(buf, " uuid='%s'", secret->uuid);
+ 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..0e377cb
--- /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(a)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 *uuid;
+};
+
+enum virStorageEncryptionFormat {
+ /* "default" is only valid for volume creation */
+ VIR_STORAGE_ENCRYPTION_FORMAT_DEFAULT = 0,
+ 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