Capabilities
diff --git a/docs/formatstorageencryption.html b/docs/formatstorageencryption.html
new file mode 100644
index 0000000000000000000000000000000000000000..15175fe5fb1fe440b0b15e832f5ce151ca17850c
--- /dev/null
+++ b/docs/formatstorageencryption.html
@@ -0,0 +1,209 @@
+
+
+
+
+
+
+
+
+
libvirt: Storage volume encryption XML format
+
+
+
+
+
+
+
+
Storage volume encryption XML format
+
+
+
+ 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.
+
+
+ The top-level tag of volume encryption specification
+ is encryption
, with a mandatory
+ attribute format
. Currently defined values
+ of format
are default
and qcow
.
+ Each value of format
implies some expectations about the
+ content of the encryption
tag. Other format values may be
+ defined in the future.
+
+
+ The encryption
tag can currently contain a sequence of
+ secret
tags, each with mandatory attributes type
+ and uuid
. The only currently defined value of
+ type
is passphrase
. uuid
+ refers to a secret known to libvirt. libvirt can use a secret value
+ previously set using virSecretSetValue()
, 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 uuid
.
+
+
+
+
+
+ <encryption type="default"/>
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 encryption
tag will be updated.
+ The unmodified contents of the encryption
tag can be used
+ in later operations with the volume, or when setting up a domain that
+ uses the volume.
+
+
+
+ The qcow
format specifies that the built-in encryption
+ support in qcow
- or qcow2
-formatted volume
+ images should be used. A single
+ <secret type='passphrase'>
element is expected. If
+ the secret
element is not present during volume creation,
+ a secret is automatically generated and attached to the volume.
+
+
+
+ Here is a simple example, specifying use of the qcow
format:
+
+
+ <encryption format='qcow'>
+ <secret type='passphrase' uuid='c1f11a6d-8c5d-4a3e-ac7a-4e171c5e0d4a' />
+ </encryption>
+
+
+
+
+
diff --git a/docs/formatstorageencryption.html.in b/docs/formatstorageencryption.html.in
new file mode 100644
index 0000000000000000000000000000000000000000..0e5dcee96b3e716307aa781cd517a109c73c4348
--- /dev/null
+++ b/docs/formatstorageencryption.html.in
@@ -0,0 +1,65 @@
+
+
+
Storage volume encryption XML format
+
+
+
+
+
+
+ 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.
+
+
+ The top-level tag of volume encryption specification
+ is encryption
, with a mandatory
+ attribute format
. Currently defined values
+ of format
are default
and qcow
.
+ Each value of format
implies some expectations about the
+ content of the encryption
tag. Other format values may be
+ defined in the future.
+
+
+ The encryption
tag can currently contain a sequence of
+ secret
tags, each with mandatory attributes type
+ and uuid
. The only currently defined value of
+ type
is passphrase
. uuid
+ refers to a secret known to libvirt. libvirt can use a secret value
+ previously set using virSecretSetValue()
, 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 uuid
.
+
+
+
+ <encryption type="default"/>
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 encryption
tag will be updated.
+ The unmodified contents of the encryption
tag can be used
+ in later operations with the volume, or when setting up a domain that
+ uses the volume.
+
+
+
+ The qcow
format specifies that the built-in encryption
+ support in qcow
- or qcow2
-formatted volume
+ images should be used. A single
+ <secret type='passphrase'>
element is expected. If
+ the secret
element is not present during volume creation,
+ a secret is automatically generated and attached to the volume.
+
+
+
+
+
+ Here is a simple example, specifying use of the qcow
format:
+
+
+
+ <encryption format='qcow'>
+ <secret type='passphrase' uuid='c1f11a6d-8c5d-4a3e-ac7a-4e171c5e0d4a' />
+ </encryption>
+
+
diff --git a/docs/schemas/Makefile.am b/docs/schemas/Makefile.am
index a064518607c746237226e8ada1d452ce4aef0c54..c217d69482a3c4bd2e1e4094aa6c024abc6e4aaf 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 0000000000000000000000000000000000000000..8f9cd6260b2efa5bd23544958ac68dcc8523fe77
--- /dev/null
+++ b/docs/schemas/storageencryption.rng
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+ default
+ qcow
+
+
+
+
+
+
+
+
+
+
+
+
+ passphrase
+
+
+
+
+
+
+
+
+
+
+
diff --git a/docs/sitemap.html b/docs/sitemap.html
index 901633d502385097e40b3f6d85d560b438d6f7b0..24300d56db0b24f6f3c0fd16d16c5f2c58f32f92 100644
--- a/docs/sitemap.html
+++ b/docs/sitemap.html
@@ -135,6 +135,9 @@
Storage
The storage pool and volume XML format
+
+ Storage Encryption
+ Storage volume encryption XML format
Capabilities
The driver capabilities XML format
diff --git a/docs/sitemap.html.in b/docs/sitemap.html.in
index 2ed25c6cacf8572bec7e7efc89f5c650aad4940a..65de169f736312c504a84f574ba3769dbcd7450c 100644
--- a/docs/sitemap.html.in
+++ b/docs/sitemap.html.in
@@ -98,6 +98,10 @@
Storage
The storage pool and volume XML format
+
+ Storage Encryption
+ Storage volume encryption XML format
+
Capabilities
The driver capabilities XML format
diff --git a/libvirt.spec.in b/libvirt.spec.in
index 966cdf137a33a05776f326148f895128e7ca5fd8..1c04fae360df5966562c4b32dc9a1658eff3e27a 100644
--- a/libvirt.spec.in
+++ b/libvirt.spec.in
@@ -582,6 +582,7 @@ fi
%{_datadir}/libvirt/schemas/capability.rng
%{_datadir}/libvirt/schemas/interface.rng
%{_datadir}/libvirt/schemas/secret.rng
+%{_datadir}/libvirt/schemas/storageencryption.rng
%if %{with_sasl}
%config(noreplace) %{_sysconfdir}/sasl2/libvirt.conf
diff --git a/mingw32-libvirt.spec.in b/mingw32-libvirt.spec.in
index 093c45a08b8e4c49c802f2f74e0456b770393930..769c3ff1203c4d6950870ddf9d360e357236082e 100644
--- a/mingw32-libvirt.spec.in
+++ b/mingw32-libvirt.spec.in
@@ -95,6 +95,7 @@ rm -rf $RPM_BUILD_ROOT
%{_mingw32_datadir}/libvirt/schemas/capability.rng
%{_mingw32_datadir}/libvirt/schemas/interface.rng
%{_mingw32_datadir}/libvirt/schemas/secret.rng
+%{_mingw32_datadir}/libvirt/schemas/storageencryption.rng
%{_mingw32_datadir}/locale/*/LC_MESSAGES/libvirt.mo
diff --git a/po/POTFILES.in b/po/POTFILES.in
index 66d3ebd7f789d9ec0c89c0ba6b8906acafd593f6..0a53dab069cf0ba37c3418722f164dbed6fcaa90 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_conf.c
src/test.c
src/uml_conf.c
src/uml_driver.c
diff --git a/src/Makefile.am b/src/Makefile.am
index 95674907702f56ddf3359189a53b0980d1f9dfd9..bedeb840ccfa022fb9c0dd4c5ab8fbe6b1172542 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_conf.h storage_encryption_conf.c \
threads.c threads.h \
threads-pthread.h \
threads-win32.h \
diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
index f2c0736447db62043b154a71702fa8c0e3d28f54..8db9fcd96d9a2c38398af68076012217e1c8ae6d 100644
--- a/src/libvirt_private.syms
+++ b/src/libvirt_private.syms
@@ -344,6 +344,11 @@ virStoragePartedFsTypeTypeToString;
virStoragePoolObjLock;
virStoragePoolObjUnlock;
+virStorageEncryptionFree;
+virStorageEncryptionDropSecrets;
+virStorageEncryptionParseNode;
+virStorageEncryptionFormat;
+
# threads.h
virMutexInit;
diff --git a/src/storage_encryption_conf.c b/src/storage_encryption_conf.c
new file mode 100644
index 0000000000000000000000000000000000000000..69cfaf110ce605f798a8c11e2f89501c3c8bd07a
--- /dev/null
+++ b/src/storage_encryption_conf.c
@@ -0,0 +1,241 @@
+/*
+ * storage_encryption_conf.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č
+ */
+
+#include
+
+#include "internal.h"
+
+#include "base64.h"
+#include "buf.h"
+#include "memory.h"
+#include "storage_conf.h"
+#include "storage_encryption_conf.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, " 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, " \n", format);
+
+ for (i = 0; i < enc->nsecrets; i++) {
+ if (virStorageEncryptionSecretFormat(conn, buf, enc->secrets[i]) < 0)
+ return -1;
+ }
+
+ virBufferAddLit(buf, " \n");
+
+ return 0;
+}
diff --git a/src/storage_encryption_conf.h b/src/storage_encryption_conf.h
new file mode 100644
index 0000000000000000000000000000000000000000..3e653b5ab8fbad0d1f67214f718fabba348f28b8
--- /dev/null
+++ b/src/storage_encryption_conf.h
@@ -0,0 +1,72 @@
+/*
+ * storage_encryption_conf.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č
+ */
+
+#ifndef __VIR_STORAGE_ENCRYPTION_H__
+#define __VIR_STORAGE_ENCRYPTION_H__
+
+#include "internal.h"
+#include "buf.h"
+#include "util.h"
+
+#include
+#include
+
+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__ */