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