提交 a48c7141 编写于 作者: D Daniel P. Berrange

storage: remove "luks" storage volume type

The current LUKS support has a "luks" volume type which has
a "luks" encryption format.

This partially makes sense if you consider the QEMU shorthand
syntax only requires you to specify a format=luks, and it'll
automagically uses "raw" as the next level driver. QEMU will
however let you override the "raw" with any other driver it
supports (vmdk, qcow, rbd, iscsi, etc, etc)

IOW the intention though is that the "luks" encryption format
is applied to all disk formats (whether raw, qcow2, rbd, gluster
or whatever). As such it doesn't make much sense for libvirt
to say the volume type is "luks" - we should be saying that it
is a "raw" file, but with "luks" encryption applied.

IOW, when creating a storage volume we should use this XML

  <volume>
    <name>demo.raw</name>
    <capacity>5368709120</capacity>
    <target>
      <format type='raw'/>
      <encryption format='luks'>
        <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccd2f80d6f'/>
      </encryption>
    </target>
  </volume>

and when configuring a guest disk we should use

  <disk type='file' device='disk'>
    <driver name='qemu' type='raw'/>
    <source file='/home/berrange/VirtualMachines/demo.raw'/>
    <target dev='sda' bus='scsi'/>
    <encryption format='luks'>
      <secret type='passphrase' uuid='0a81f5b2-8403-7b23-c8d6-21ccd2f80d6f'/>
    </encryption>
  </disk>

This commit thus removes the "luks" storage volume type added
in

  commit 318ebb36
  Author: John Ferlan <jferlan@redhat.com>
  Date:   Tue Jun 21 12:59:54 2016 -0400

    util: Add 'luks' to the FileTypeInfo

The storage file probing code is modified so that it can probe
the actual encryption formats explicitly, rather than merely
probing existance of encryption and letting the storage driver
guess the format.

The rest of the code is then adapted to deal with
VIR_STORAGE_FILE_RAW w/ VIR_STORAGE_ENCRYPTION_FORMAT_LUKS
instead of just VIR_STORAGE_FILE_LUKS.

The commit mentioned above was included in libvirt v2.0.0.
So when querying volume XML this will be a change in behaviour
vs the 2.0.0 release - it'll report 'raw' instead of 'luks'
for the volume format, but still report 'luks' for encryption
format.  I think this change is OK because the storage driver
did not include any support for creating volumes, nor starting
guets with luks volumes in v2.0.0 - that only since then.
Clearly if we change this we must do it before v2.1.0 though.
Signed-off-by: NDaniel P. Berrange <berrange@redhat.com>
上级 970f42ab
...@@ -761,7 +761,7 @@ ...@@ -761,7 +761,7 @@
&lt;capacity unit="G"&gt;5&lt;/capacity&gt; &lt;capacity unit="G"&gt;5&lt;/capacity&gt;
&lt;target&gt; &lt;target&gt;
&lt;path&gt;/var/lib/virt/images/MyLuks.img&lt;/path&gt; &lt;path&gt;/var/lib/virt/images/MyLuks.img&lt;/path&gt;
&lt;format type='luks'/&gt; &lt;format type='raw'/&gt;
&lt;encryption format='luks'&gt; &lt;encryption format='luks'&gt;
&lt;secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc572'/&gt; &lt;secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc572'/&gt;
&lt;/encryption&gt; &lt;/encryption&gt;
......
...@@ -153,7 +153,7 @@ ...@@ -153,7 +153,7 @@
&lt;capacity unit='G'&gt;5&lt;/capacity&gt; &lt;capacity unit='G'&gt;5&lt;/capacity&gt;
&lt;target&gt; &lt;target&gt;
&lt;path&gt;/var/lib/libvirt/images/demo.luks&lt;/path&gt; &lt;path&gt;/var/lib/libvirt/images/demo.luks&lt;/path&gt;
&lt;format type='luks'/&gt; &lt;format type='raw'/&gt;
&lt;encryption format='luks'&gt; &lt;encryption format='luks'&gt;
&lt;secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc572'/&gt; &lt;secret type='passphrase' uuid='f52a81b2-424e-490c-823d-6bd4235bc572'/&gt;
&lt;cipher name='twofish' size='256' mode='cbc' hash='sha256'/&gt; &lt;cipher name='twofish' size='256' mode='cbc' hash='sha256'/&gt;
......
...@@ -1303,9 +1303,13 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk, ...@@ -1303,9 +1303,13 @@ qemuBuildDriveSourceStr(virDomainDiskDefPtr disk,
encinfo->s.aes.alias); encinfo->s.aes.alias);
if (disk->src->format > 0 && if (disk->src->format > 0 &&
disk->src->type != VIR_STORAGE_TYPE_DIR) disk->src->type != VIR_STORAGE_TYPE_DIR) {
virBufferAsprintf(buf, "format=%s,", const char *qemuformat = virStorageFileFormatTypeToString(disk->src->format);
virStorageFileFormatTypeToString(disk->src->format)); if (disk->src->encryption &&
disk->src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS)
qemuformat = "luks";
virBufferAsprintf(buf, "format=%s,", qemuformat);
}
ret = 0; ret = 0;
......
...@@ -1078,7 +1078,7 @@ qemuDomainSecretDiskPrepare(virConnectPtr conn, ...@@ -1078,7 +1078,7 @@ qemuDomainSecretDiskPrepare(virConnectPtr conn,
} }
if (!virStorageSourceIsEmpty(src) && src->encryption && if (!virStorageSourceIsEmpty(src) && src->encryption &&
src->format == VIR_STORAGE_FILE_LUKS) { src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
if (VIR_ALLOC(secinfo) < 0) if (VIR_ALLOC(secinfo) < 0)
return -1; return -1;
......
...@@ -2989,7 +2989,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver, ...@@ -2989,7 +2989,7 @@ qemuDomainRemoveDiskDevice(virQEMUDriverPtr driver,
* can remove the luks object password too * can remove the luks object password too
*/ */
if (!virStorageSourceIsEmpty(disk->src) && disk->src->encryption && if (!virStorageSourceIsEmpty(disk->src) && disk->src->encryption &&
disk->src->format == VIR_STORAGE_FILE_LUKS) { disk->src->encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
if (!(encAlias = if (!(encAlias =
qemuDomainGetSecretAESAlias(disk->info.alias, true))) { qemuDomainGetSecretAESAlias(disk->info.alias, true))) {
......
...@@ -963,12 +963,7 @@ virStorageBackendCreateQemuImgOpts(virStorageEncryptionInfoDefPtr enc, ...@@ -963,12 +963,7 @@ virStorageBackendCreateQemuImgOpts(virStorageEncryptionInfoDefPtr enc,
{ {
virBuffer buf = VIR_BUFFER_INITIALIZER; virBuffer buf = VIR_BUFFER_INITIALIZER;
if (info.format == VIR_STORAGE_FILE_LUKS) { if (info.format == VIR_STORAGE_FILE_RAW && enc) {
if (!enc) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("missing luks encryption information"));
goto error;
}
virQEMUBuildLuksOpts(&buf, enc, info.secretAlias); virQEMUBuildLuksOpts(&buf, enc, info.secretAlias);
} else { } else {
if (info.backingPath) if (info.backingPath)
...@@ -1049,7 +1044,7 @@ virStorageBackendCreateQemuImgCheckEncryption(int format, ...@@ -1049,7 +1044,7 @@ virStorageBackendCreateQemuImgCheckEncryption(int format,
if (virStorageGenerateQcowEncryption(conn, vol) < 0) if (virStorageGenerateQcowEncryption(conn, vol) < 0)
return -1; return -1;
} }
} else if (format == VIR_STORAGE_FILE_LUKS) { } else if (format == VIR_STORAGE_FILE_RAW) {
if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) { if (enc->format != VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
_("unsupported volume encryption format %d"), _("unsupported volume encryption format %d"),
...@@ -1116,9 +1111,9 @@ virStorageBackendCreateQemuImgSetBacking(virStoragePoolObjPtr pool, ...@@ -1116,9 +1111,9 @@ virStorageBackendCreateQemuImgSetBacking(virStoragePoolObjPtr pool,
int accessRetCode = -1; int accessRetCode = -1;
char *absolutePath = NULL; char *absolutePath = NULL;
if (info->format == VIR_STORAGE_FILE_LUKS) { if (info->format == VIR_STORAGE_FILE_RAW) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("cannot set backing store for luks volume")); _("cannot set backing store for raw volume"));
return -1; return -1;
} }
...@@ -1283,10 +1278,11 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, ...@@ -1283,10 +1278,11 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn,
_("format features only available with qcow2")); _("format features only available with qcow2"));
return NULL; return NULL;
} }
if (info.format == VIR_STORAGE_FILE_LUKS) { if (info.format == VIR_STORAGE_FILE_RAW &&
vol->target.encryption != NULL) {
if (inputvol) { if (inputvol) {
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
_("cannot use inputvol with luks volume")); _("cannot use inputvol with encrypted raw volume"));
return NULL; return NULL;
} }
if (!info.encryption) { if (!info.encryption) {
...@@ -1294,6 +1290,13 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, ...@@ -1294,6 +1290,13 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn,
_("missing encryption description")); _("missing encryption description"));
return NULL; return NULL;
} }
if (vol->target.encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
type = "luks";
} else {
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
_("Only luks encryption is supported for raw files"));
return NULL;
}
} }
if (inputvol && if (inputvol &&
...@@ -1329,7 +1332,9 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn, ...@@ -1329,7 +1332,9 @@ virStorageBackendCreateQemuImgCmdFromVol(virConnectPtr conn,
if (info.backingPath) if (info.backingPath)
virCommandAddArgList(cmd, "-b", info.backingPath, NULL); virCommandAddArgList(cmd, "-b", info.backingPath, NULL);
if (info.format == VIR_STORAGE_FILE_LUKS) { if (info.format == VIR_STORAGE_FILE_RAW &&
vol->target.encryption != NULL &&
vol->target.encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
if (virStorageBackendCreateQemuImgSecretObject(cmd, vol, &info) < 0) { if (virStorageBackendCreateQemuImgSecretObject(cmd, vol, &info) < 0) {
VIR_FREE(info.secretAlias); VIR_FREE(info.secretAlias);
virCommandFree(cmd); virCommandFree(cmd);
...@@ -1453,7 +1458,8 @@ virStorageBackendCreateQemuImg(virConnectPtr conn, ...@@ -1453,7 +1458,8 @@ virStorageBackendCreateQemuImg(virConnectPtr conn,
if (imgformat < 0) if (imgformat < 0)
goto cleanup; goto cleanup;
if (vol->target.format == VIR_STORAGE_FILE_LUKS) { if (vol->target.format == VIR_STORAGE_FILE_RAW &&
vol->target.encryption->format == VIR_STORAGE_ENCRYPTION_FORMAT_LUKS) {
if (!(secretPath = if (!(secretPath =
virStorageBackendCreateQemuImgSecretPath(conn, pool, vol))) virStorageBackendCreateQemuImgSecretPath(conn, pool, vol)))
goto cleanup; goto cleanup;
...@@ -1484,13 +1490,15 @@ virStorageBackendGetBuildVolFromFunction(virStorageVolDefPtr vol, ...@@ -1484,13 +1490,15 @@ virStorageBackendGetBuildVolFromFunction(virStorageVolDefPtr vol,
if (!inputvol) if (!inputvol)
return NULL; return NULL;
/* If either volume is a non-raw file vol, we need to use an external /* If either volume is a non-raw file vol, or uses encryption,
* tool for converting * we need to use an external tool for converting
*/ */
if ((vol->type == VIR_STORAGE_VOL_FILE && if ((vol->type == VIR_STORAGE_VOL_FILE &&
vol->target.format != VIR_STORAGE_FILE_RAW) || (vol->target.format != VIR_STORAGE_FILE_RAW ||
vol->target.encryption != NULL)) ||
(inputvol->type == VIR_STORAGE_VOL_FILE && (inputvol->type == VIR_STORAGE_VOL_FILE &&
inputvol->target.format != VIR_STORAGE_FILE_RAW)) { (inputvol->target.format != VIR_STORAGE_FILE_RAW ||
inputvol->target.encryption != NULL))) {
return virStorageBackendCreateQemuImg; return virStorageBackendCreateQemuImg;
} }
......
...@@ -152,20 +152,6 @@ virStorageBackendProbeTarget(virStorageSourcePtr target, ...@@ -152,20 +152,6 @@ virStorageBackendProbeTarget(virStorageSourcePtr target,
*encryption = meta->encryption; *encryption = meta->encryption;
meta->encryption = NULL; meta->encryption = NULL;
switch (target->format) {
case VIR_STORAGE_FILE_QCOW:
case VIR_STORAGE_FILE_QCOW2:
(*encryption)->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
break;
case VIR_STORAGE_FILE_LUKS:
(*encryption)->format = VIR_STORAGE_ENCRYPTION_FORMAT_LUKS;
break;
case VIR_STORAGE_ENCRYPTION_FORMAT_LAST:
break;
}
/* XXX ideally we'd fill in secret UUID here /* XXX ideally we'd fill in secret UUID here
* but we cannot guarantee 'conn' is non-NULL * but we cannot guarantee 'conn' is non-NULL
* at this point in time :-( So we only fill * at this point in time :-( So we only fill
...@@ -1182,7 +1168,8 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn, ...@@ -1182,7 +1168,8 @@ _virStorageBackendFileSystemVolBuild(virConnectPtr conn,
inputvol); inputvol);
if (!create_func) if (!create_func)
return -1; return -1;
} else if (vol->target.format == VIR_STORAGE_FILE_RAW) { } else if (vol->target.format == VIR_STORAGE_FILE_RAW &&
vol->target.encryption == NULL) {
create_func = virStorageBackendCreateRaw; create_func = virStorageBackendCreateRaw;
} else if (vol->target.format == VIR_STORAGE_FILE_DIR) { } else if (vol->target.format == VIR_STORAGE_FILE_DIR) {
create_func = createFileDir; create_func = createFileDir;
......
...@@ -318,11 +318,6 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state, ...@@ -318,11 +318,6 @@ virStorageBackendGlusterRefreshVol(virStorageBackendGlusterStatePtr state,
if (meta->encryption) { if (meta->encryption) {
vol->target.encryption = meta->encryption; vol->target.encryption = meta->encryption;
meta->encryption = NULL; meta->encryption = NULL;
if (vol->target.format == VIR_STORAGE_FILE_QCOW ||
vol->target.format == VIR_STORAGE_FILE_QCOW2)
vol->target.encryption->format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW;
if (vol->target.format == VIR_STORAGE_FILE_LUKS)
vol->target.encryption->format = VIR_STORAGE_ENCRYPTION_FORMAT_LUKS;
} }
vol->target.features = meta->features; vol->target.features = meta->features;
meta->features = NULL; meta->features = NULL;
......
...@@ -44,6 +44,7 @@ ...@@ -44,6 +44,7 @@
#include "dirname.h" #include "dirname.h"
#include "virbuffer.h" #include "virbuffer.h"
#include "virjson.h" #include "virjson.h"
#include "virstorageencryption.h"
#define VIR_FROM_THIS VIR_FROM_STORAGE #define VIR_FROM_THIS VIR_FROM_STORAGE
...@@ -64,7 +65,7 @@ VIR_ENUM_IMPL(virStorageFileFormat, ...@@ -64,7 +65,7 @@ VIR_ENUM_IMPL(virStorageFileFormat,
"cloop", "dmg", "iso", "cloop", "dmg", "iso",
"vpc", "vdi", "vpc", "vdi",
/* Not direct file formats, but used for various drivers */ /* Not direct file formats, but used for various drivers */
"fat", "vhd", "ploop", "luks", "fat", "vhd", "ploop",
/* Formats with backing file below here */ /* Formats with backing file below here */
"cow", "qcow", "qcow2", "qed", "vmdk") "cow", "qcow", "qcow2", "qed", "vmdk")
...@@ -115,6 +116,26 @@ enum { ...@@ -115,6 +116,26 @@ enum {
#define FILE_TYPE_VERSIONS_LAST 2 #define FILE_TYPE_VERSIONS_LAST 2
struct FileEncryptionInfo {
int format; /* Encryption format to assign */
int magicOffset; /* Byte offset of the magic */
const char *magic; /* Optional string of magic */
enum lv_endian endian; /* Endianness of file format */
int versionOffset; /* Byte offset from start of file
* where we find version number,
* -1 to always fail the version test,
* -2 to always pass the version test */
int versionSize; /* Size in bytes of version data (0, 2, or 4) */
int versionNumbers[FILE_TYPE_VERSIONS_LAST];
/* Version numbers to validate. Zeroes are ignored. */
int modeOffset; /* Byte offset of the format native encryption mode */
char modeValue; /* Value expected at offset */
};
/* Either 'magic' or 'extension' *must* be provided */ /* Either 'magic' or 'extension' *must* be provided */
struct FileTypeInfo { struct FileTypeInfo {
int magicOffset; /* Byte offset of the magic */ int magicOffset; /* Byte offset of the magic */
...@@ -138,15 +159,14 @@ struct FileTypeInfo { ...@@ -138,15 +159,14 @@ struct FileTypeInfo {
/* Store a COW base image path (possibly relative), /* Store a COW base image path (possibly relative),
* or NULL if there is no COW base image, to RES; * or NULL if there is no COW base image, to RES;
* return BACKING_STORE_* */ * return BACKING_STORE_* */
int qcowCryptOffset; /* Byte offset from start of file const struct FileEncryptionInfo *cryptInfo; /* Encryption info */
* where to find encryption mode,
* -1 if encryption is not used */
int (*getBackingStore)(char **res, int *format, int (*getBackingStore)(char **res, int *format,
const char *buf, size_t buf_size); const char *buf, size_t buf_size);
int (*getFeatures)(virBitmapPtr *features, int format, int (*getFeatures)(virBitmapPtr *features, int format,
char *buf, ssize_t len); char *buf, ssize_t len);
}; };
static int cowGetBackingStore(char **, int *, static int cowGetBackingStore(char **, int *,
const char *, size_t); const char *, size_t);
static int qcow1GetBackingStore(char **, int *, static int qcow1GetBackingStore(char **, int *,
...@@ -197,19 +217,75 @@ qedGetBackingStore(char **, int *, const char *, size_t); ...@@ -197,19 +217,75 @@ qedGetBackingStore(char **, int *, const char *, size_t);
/* Format described by qemu commit id '3e308f20e' */ /* Format described by qemu commit id '3e308f20e' */
#define LUKS_HDR_VERSION_OFFSET LUKS_HDR_MAGIC_LEN #define LUKS_HDR_VERSION_OFFSET LUKS_HDR_MAGIC_LEN
static struct FileEncryptionInfo const luksEncryptionInfo[] = {
{
.format = VIR_STORAGE_ENCRYPTION_FORMAT_LUKS,
/* Magic is 'L','U','K','S', 0xBA, 0xBE */
.magicOffset = 0,
.magic = "\x4c\x55\x4b\x53\xba\xbe",
.endian = LV_BIG_ENDIAN,
.versionOffset = LUKS_HDR_VERSION_OFFSET,
.versionSize = LUKS_HDR_VERSION_LEN,
.versionNumbers = {1},
.modeOffset = -1,
.modeValue = -1,
},
{ 0 }
};
static struct FileEncryptionInfo const qcow1EncryptionInfo[] = {
{
.format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW,
.magicOffset = 0,
.magic = NULL,
.endian = LV_BIG_ENDIAN,
.versionOffset = -1,
.versionSize = 0,
.versionNumbers = {},
.modeOffset = QCOW1_HDR_CRYPT,
.modeValue = 1,
},
{ 0 }
};
static struct FileEncryptionInfo const qcow2EncryptionInfo[] = {
{
.format = VIR_STORAGE_ENCRYPTION_FORMAT_QCOW,
.magicOffset = 0,
.magic = NULL,
.endian = LV_BIG_ENDIAN,
.versionOffset = -1,
.versionSize = 0,
.versionNumbers = {},
.modeOffset = QCOW2_HDR_CRYPT,
.modeValue = 1,
},
{ 0 }
};
static struct FileTypeInfo const fileTypeInfo[] = { static struct FileTypeInfo const fileTypeInfo[] = {
[VIR_STORAGE_FILE_NONE] = { 0, NULL, NULL, LV_LITTLE_ENDIAN, [VIR_STORAGE_FILE_NONE] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
-1, 0, {0}, 0, 0, 0, 0, NULL, NULL }, -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL },
[VIR_STORAGE_FILE_RAW] = { 0, NULL, NULL, LV_LITTLE_ENDIAN, [VIR_STORAGE_FILE_RAW] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
-1, 0, {0}, 0, 0, 0, 0, NULL, NULL }, -1, 0, {0}, 0, 0, 0,
luksEncryptionInfo,
NULL, NULL },
[VIR_STORAGE_FILE_DIR] = { 0, NULL, NULL, LV_LITTLE_ENDIAN, [VIR_STORAGE_FILE_DIR] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
-1, 0, {0}, 0, 0, 0, 0, NULL, NULL }, -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL },
[VIR_STORAGE_FILE_BOCHS] = { [VIR_STORAGE_FILE_BOCHS] = {
/*"Bochs Virtual HD Image", */ /* Untested */ /*"Bochs Virtual HD Image", */ /* Untested */
0, NULL, NULL, 0, NULL, NULL,
LV_LITTLE_ENDIAN, 64, 4, {0x20000}, LV_LITTLE_ENDIAN, 64, 4, {0x20000},
32+16+16+4+4+4+4+4, 8, 1, -1, NULL, NULL 32+16+16+4+4+4+4+4, 8, 1, NULL, NULL, NULL
}, },
[VIR_STORAGE_FILE_CLOOP] = { [VIR_STORAGE_FILE_CLOOP] = {
/* #!/bin/sh /* #!/bin/sh
...@@ -218,7 +294,7 @@ static struct FileTypeInfo const fileTypeInfo[] = { ...@@ -218,7 +294,7 @@ static struct FileTypeInfo const fileTypeInfo[] = {
*/ /* Untested */ */ /* Untested */
0, NULL, NULL, 0, NULL, NULL,
LV_LITTLE_ENDIAN, -1, 0, {0}, LV_LITTLE_ENDIAN, -1, 0, {0},
-1, 0, 0, -1, NULL, NULL -1, 0, 0, NULL, NULL, NULL
}, },
[VIR_STORAGE_FILE_DMG] = { [VIR_STORAGE_FILE_DMG] = {
/* XXX QEMU says there's no magic for dmg, /* XXX QEMU says there's no magic for dmg,
...@@ -226,71 +302,69 @@ static struct FileTypeInfo const fileTypeInfo[] = { ...@@ -226,71 +302,69 @@ static struct FileTypeInfo const fileTypeInfo[] = {
* would have to match) but then disables that check. */ * would have to match) but then disables that check. */
0, NULL, ".dmg", 0, NULL, ".dmg",
0, -1, 0, {0}, 0, -1, 0, {0},
-1, 0, 0, -1, NULL, NULL -1, 0, 0, NULL, NULL, NULL
}, },
[VIR_STORAGE_FILE_ISO] = { [VIR_STORAGE_FILE_ISO] = {
32769, "CD001", ".iso", 32769, "CD001", ".iso",
LV_LITTLE_ENDIAN, -2, 0, {0}, LV_LITTLE_ENDIAN, -2, 0, {0},
-1, 0, 0, -1, NULL, NULL -1, 0, 0, NULL, NULL, NULL
}, },
[VIR_STORAGE_FILE_VPC] = { [VIR_STORAGE_FILE_VPC] = {
0, "conectix", NULL, 0, "conectix", NULL,
LV_BIG_ENDIAN, 12, 4, {0x10000}, LV_BIG_ENDIAN, 12, 4, {0x10000},
8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, -1, NULL, NULL 8 + 4 + 4 + 8 + 4 + 4 + 2 + 2 + 4, 8, 1, NULL, NULL, NULL
}, },
/* TODO: add getBackingStore function */ /* TODO: add getBackingStore function */
[VIR_STORAGE_FILE_VDI] = { [VIR_STORAGE_FILE_VDI] = {
64, "\x7f\x10\xda\xbe", ".vdi", 64, "\x7f\x10\xda\xbe", ".vdi",
LV_LITTLE_ENDIAN, 68, 4, {0x00010001}, LV_LITTLE_ENDIAN, 68, 4, {0x00010001},
64 + 5 * 4 + 256 + 7 * 4, 8, 1, -1, NULL, NULL}, 64 + 5 * 4 + 256 + 7 * 4, 8, 1, NULL, NULL, NULL},
/* Not direct file formats, but used for various drivers */ /* Not direct file formats, but used for various drivers */
[VIR_STORAGE_FILE_FAT] = { 0, NULL, NULL, LV_LITTLE_ENDIAN, [VIR_STORAGE_FILE_FAT] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
-1, 0, {0}, 0, 0, 0, 0, NULL, NULL }, -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL },
[VIR_STORAGE_FILE_VHD] = { 0, NULL, NULL, LV_LITTLE_ENDIAN, [VIR_STORAGE_FILE_VHD] = { 0, NULL, NULL, LV_LITTLE_ENDIAN,
-1, 0, {0}, 0, 0, 0, 0, NULL, NULL }, -1, 0, {0}, 0, 0, 0, NULL, NULL, NULL },
[VIR_STORAGE_FILE_PLOOP] = { 0, "WithouFreSpacExt", NULL, LV_LITTLE_ENDIAN, [VIR_STORAGE_FILE_PLOOP] = { 0, "WithouFreSpacExt", NULL, LV_LITTLE_ENDIAN,
-2, 0, {0}, PLOOP_IMAGE_SIZE_OFFSET, 0, -2, 0, {0}, PLOOP_IMAGE_SIZE_OFFSET, 0,
PLOOP_SIZE_MULTIPLIER, -1, NULL, NULL }, PLOOP_SIZE_MULTIPLIER, NULL, NULL, NULL },
/* Magic is 'L','U','K','S', 0xBA, 0xBE
* Set sizeOffset = -1 and let hypervisor handle */
[VIR_STORAGE_FILE_LUKS] = {
0, "\x4c\x55\x4b\x53\xba\xbe", NULL,
LV_BIG_ENDIAN, LUKS_HDR_VERSION_OFFSET, 2, {1},
-1, 0, 0, -1, NULL, NULL
},
/* All formats with a backing store probe below here */ /* All formats with a backing store probe below here */
[VIR_STORAGE_FILE_COW] = { [VIR_STORAGE_FILE_COW] = {
0, "OOOM", NULL, 0, "OOOM", NULL,
LV_BIG_ENDIAN, 4, 4, {2}, LV_BIG_ENDIAN, 4, 4, {2},
4+4+1024+4, 8, 1, -1, cowGetBackingStore, NULL 4+4+1024+4, 8, 1, NULL, cowGetBackingStore, NULL
}, },
[VIR_STORAGE_FILE_QCOW] = { [VIR_STORAGE_FILE_QCOW] = {
0, "QFI", NULL, 0, "QFI", NULL,
LV_BIG_ENDIAN, 4, 4, {1}, LV_BIG_ENDIAN, 4, 4, {1},
QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW1_HDR_CRYPT, qcow1GetBackingStore, NULL QCOWX_HDR_IMAGE_SIZE, 8, 1,
qcow1EncryptionInfo,
qcow1GetBackingStore, NULL
}, },
[VIR_STORAGE_FILE_QCOW2] = { [VIR_STORAGE_FILE_QCOW2] = {
0, "QFI", NULL, 0, "QFI", NULL,
LV_BIG_ENDIAN, 4, 4, {2, 3}, LV_BIG_ENDIAN, 4, 4, {2, 3},
QCOWX_HDR_IMAGE_SIZE, 8, 1, QCOW2_HDR_CRYPT, qcow2GetBackingStore, QCOWX_HDR_IMAGE_SIZE, 8, 1,
qcow2EncryptionInfo,
qcow2GetBackingStore,
qcow2GetFeatures qcow2GetFeatures
}, },
[VIR_STORAGE_FILE_QED] = { [VIR_STORAGE_FILE_QED] = {
/* http://wiki.qemu.org/Features/QED */ /* http://wiki.qemu.org/Features/QED */
0, "QED", NULL, 0, "QED", NULL,
LV_LITTLE_ENDIAN, -2, 0, {0}, LV_LITTLE_ENDIAN, -2, 0, {0},
QED_HDR_IMAGE_SIZE, 8, 1, -1, qedGetBackingStore, NULL QED_HDR_IMAGE_SIZE, 8, 1, NULL, qedGetBackingStore, NULL
}, },
[VIR_STORAGE_FILE_VMDK] = { [VIR_STORAGE_FILE_VMDK] = {
0, "KDMV", NULL, 0, "KDMV", NULL,
LV_LITTLE_ENDIAN, 4, 4, {1, 2}, LV_LITTLE_ENDIAN, 4, 4, {1, 2},
4+4+4, 8, 512, -1, vmdk4GetBackingStore, NULL 4+4+4, 8, 512, NULL, vmdk4GetBackingStore, NULL
}, },
}; };
verify(ARRAY_CARDINALITY(fileTypeInfo) == VIR_STORAGE_FILE_LAST); verify(ARRAY_CARDINALITY(fileTypeInfo) == VIR_STORAGE_FILE_LAST);
/* qcow2 compatible features in the order they appear on-disk */ /* qcow2 compatible features in the order they appear on-disk */
enum qcow2CompatibleFeature { enum qcow2CompatibleFeature {
QCOW2_COMPATIBLE_FEATURE_LAZY_REFCOUNTS = 0, QCOW2_COMPATIBLE_FEATURE_LAZY_REFCOUNTS = 0,
...@@ -644,7 +718,7 @@ virStorageFileMatchesVersion(int versionOffset, ...@@ -644,7 +718,7 @@ virStorageFileMatchesVersion(int versionOffset,
char *buf, char *buf,
size_t buflen) size_t buflen)
{ {
int version = 0; int version;
size_t i; size_t i;
/* Validate version number info */ /* Validate version number info */
...@@ -808,6 +882,43 @@ qcow2GetFeatures(virBitmapPtr *features, ...@@ -808,6 +882,43 @@ qcow2GetFeatures(virBitmapPtr *features,
} }
static bool
virStorageFileHasEncryptionFormat(const struct FileEncryptionInfo *info,
char *buf,
size_t len)
{
if (!info->magic && info->modeOffset == -1)
return 0; /* Shouldn't happen - expect at least one */
if (info->magic) {
if (!virStorageFileMatchesMagic(info->magicOffset,
info->magic,
buf, len))
return false;
if (info->versionOffset != -1 &&
!virStorageFileMatchesVersion(info->versionOffset,
info->versionSize,
info->versionNumbers,
info->endian,
buf, len))
return false;
return true;
} else if (info->modeOffset != -1) {
if (info->modeOffset >= len)
return false;
if (buf[info->modeOffset] != info->modeValue)
return false;
return true;
} else {
return false;
}
}
/* Given a header in BUF with length LEN, as parsed from the storage file /* Given a header in BUF with length LEN, as parsed from the storage file
* assuming it has the given FORMAT, populate information into META * assuming it has the given FORMAT, populate information into META
* with information about the file and its backing store. Return format * with information about the file and its backing store. Return format
...@@ -820,6 +931,7 @@ virStorageFileGetMetadataInternal(virStorageSourcePtr meta, ...@@ -820,6 +931,7 @@ virStorageFileGetMetadataInternal(virStorageSourcePtr meta,
int *backingFormat) int *backingFormat)
{ {
int ret = -1; int ret = -1;
size_t i;
VIR_DEBUG("path=%s, buf=%p, len=%zu, meta->format=%d", VIR_DEBUG("path=%s, buf=%p, len=%zu, meta->format=%d",
meta->path, buf, len, meta->format); meta->path, buf, len, meta->format);
...@@ -834,6 +946,18 @@ virStorageFileGetMetadataInternal(virStorageSourcePtr meta, ...@@ -834,6 +946,18 @@ virStorageFileGetMetadataInternal(virStorageSourcePtr meta,
goto cleanup; goto cleanup;
} }
if (fileTypeInfo[meta->format].cryptInfo != NULL) {
for (i = 0; fileTypeInfo[meta->format].cryptInfo[i].format != 0; i++) {
if (virStorageFileHasEncryptionFormat(&fileTypeInfo[meta->format].cryptInfo[i],
buf, len)) {
if (VIR_ALLOC(meta->encryption) < 0)
goto cleanup;
meta->encryption->format = fileTypeInfo[meta->format].cryptInfo[i].format;
}
}
}
/* XXX we should consider moving virStorageBackendUpdateVolInfo /* XXX we should consider moving virStorageBackendUpdateVolInfo
* code into this method, for non-magic files * code into this method, for non-magic files
*/ */
...@@ -858,22 +982,6 @@ virStorageFileGetMetadataInternal(virStorageSourcePtr meta, ...@@ -858,22 +982,6 @@ virStorageFileGetMetadataInternal(virStorageSourcePtr meta,
meta->capacity *= fileTypeInfo[meta->format].sizeMultiplier; meta->capacity *= fileTypeInfo[meta->format].sizeMultiplier;
} }
if (fileTypeInfo[meta->format].qcowCryptOffset != -1) {
int crypt_format;
crypt_format = virReadBufInt32BE(buf +
fileTypeInfo[meta->format].qcowCryptOffset);
if (crypt_format && !meta->encryption &&
VIR_ALLOC(meta->encryption) < 0)
goto cleanup;
}
if (meta->format == VIR_STORAGE_FILE_LUKS) {
/* By definition, this is encrypted */
if (!meta->encryption && VIR_ALLOC(meta->encryption) < 0)
goto cleanup;
}
VIR_FREE(meta->backingStoreRaw); VIR_FREE(meta->backingStoreRaw);
if (fileTypeInfo[meta->format].getBackingStore != NULL) { if (fileTypeInfo[meta->format].getBackingStore != NULL) {
int store = fileTypeInfo[meta->format].getBackingStore(&meta->backingStoreRaw, int store = fileTypeInfo[meta->format].getBackingStore(&meta->backingStoreRaw,
......
...@@ -74,7 +74,6 @@ typedef enum { ...@@ -74,7 +74,6 @@ typedef enum {
VIR_STORAGE_FILE_FAT, VIR_STORAGE_FILE_FAT,
VIR_STORAGE_FILE_VHD, VIR_STORAGE_FILE_VHD,
VIR_STORAGE_FILE_PLOOP, VIR_STORAGE_FILE_PLOOP,
VIR_STORAGE_FILE_LUKS,
/* Not a format, but a marker: all formats below this point have /* Not a format, but a marker: all formats below this point have
* libvirt support for following a backing chain */ * libvirt support for following a backing chain */
......
...@@ -15,7 +15,7 @@ ...@@ -15,7 +15,7 @@
<devices> <devices>
<emulator>/usr/bin/qemu</emulator> <emulator>/usr/bin/qemu</emulator>
<disk type='file' device='disk'> <disk type='file' device='disk'>
<driver name='qemu' type='luks'/> <driver name='qemu' type='raw'/>
<source file='/storage/guest_disks/encryptdisk'/> <source file='/storage/guest_disks/encryptdisk'/>
<target dev='vda' bus='virtio'/> <target dev='vda' bus='virtio'/>
<encryption format='luks'> <encryption format='luks'>
...@@ -24,7 +24,7 @@ ...@@ -24,7 +24,7 @@
<address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/> <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
</disk> </disk>
<disk type='file' device='disk'> <disk type='file' device='disk'>
<driver name='qemu' type='luks'/> <driver name='qemu' type='raw'/>
<source file='/storage/guest_disks/encryptdisk2'/> <source file='/storage/guest_disks/encryptdisk2'/>
<target dev='vdb' bus='virtio'/> <target dev='vdb' bus='virtio'/>
<encryption format='luks'> <encryption format='luks'>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<allocation>294912</allocation> <allocation>294912</allocation>
<target> <target>
<path>/var/lib/libvirt/images/LuksDemo.img</path> <path>/var/lib/libvirt/images/LuksDemo.img</path>
<format type='luks'/> <format type='raw'/>
<permissions> <permissions>
<mode>0644</mode> <mode>0644</mode>
<owner>0</owner> <owner>0</owner>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<allocation>294912</allocation> <allocation>294912</allocation>
<target> <target>
<path>/var/lib/libvirt/images/LuksDemo.img</path> <path>/var/lib/libvirt/images/LuksDemo.img</path>
<format type='luks'/> <format type='raw'/>
<permissions> <permissions>
<mode>0644</mode> <mode>0644</mode>
<owner>0</owner> <owner>0</owner>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<allocation unit='bytes'>294912</allocation> <allocation unit='bytes'>294912</allocation>
<target> <target>
<path>/var/lib/libvirt/images/LuksDemo.img</path> <path>/var/lib/libvirt/images/LuksDemo.img</path>
<format type='luks'/> <format type='raw'/>
<permissions> <permissions>
<mode>0644</mode> <mode>0644</mode>
<owner>0</owner> <owner>0</owner>
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
<allocation unit='bytes'>294912</allocation> <allocation unit='bytes'>294912</allocation>
<target> <target>
<path>/var/lib/libvirt/images/LuksDemo.img</path> <path>/var/lib/libvirt/images/LuksDemo.img</path>
<format type='luks'/> <format type='raw'/>
<permissions> <permissions>
<mode>0644</mode> <mode>0644</mode>
<owner>0</owner> <owner>0</owner>
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册