mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2024-08-28 19:41:16 +00:00
qemu: Refactor qemuTranslateDiskSourcePool
Before this patch, the translation function still needs a second ugly helper function to actually format the command line for qemu. But if we do the right stuff in the translation function, we don't have to bother with the second function any more. This patch removes the messy qemuBuildVolumeString function and changes qemuTranslateDiskSourcePool to set stuff up correctly so that the regular code paths meant for volumes can be used to format the command line correctly. For this purpose a new helper "qemuDiskGetActualType()" is introduced to return the type of the volume in a pool. As a part of the refactor the qemuTranslateDiskSourcePool function is fixed to do decisions based on the pool type instead of the volume type. This allows to separate pool-type-specific stuff more clearly and will ease addition of other pool types that will require certain other operations to get the correct pool source. The previously fixed tests should make sure that we don't break stuff that was working before.
This commit is contained in:
parent
ec2fb767bb
commit
e1a4d08baf
@ -686,6 +686,7 @@ struct _virDomainDiskSourcePoolDef {
|
|||||||
char *volume; /* volume name */
|
char *volume; /* volume name */
|
||||||
int voltype; /* enum virStorageVolType, internal only */
|
int voltype; /* enum virStorageVolType, internal only */
|
||||||
int pooltype; /* enum virStoragePoolType, internal only */
|
int pooltype; /* enum virStoragePoolType, internal only */
|
||||||
|
int actualtype; /* enum virDomainDiskType, internal only */
|
||||||
int mode; /* enum virDomainDiskSourcePoolMode */
|
int mode; /* enum virDomainDiskSourcePoolMode */
|
||||||
};
|
};
|
||||||
typedef virDomainDiskSourcePoolDef *virDomainDiskSourcePoolDefPtr;
|
typedef virDomainDiskSourcePoolDef *virDomainDiskSourcePoolDefPtr;
|
||||||
|
@ -696,6 +696,7 @@ virStoragePoolSourceFree;
|
|||||||
virStoragePoolSourceListFormat;
|
virStoragePoolSourceListFormat;
|
||||||
virStoragePoolSourceListNewSource;
|
virStoragePoolSourceListNewSource;
|
||||||
virStoragePoolTypeFromString;
|
virStoragePoolTypeFromString;
|
||||||
|
virStoragePoolTypeToString;
|
||||||
virStorageVolDefFindByKey;
|
virStorageVolDefFindByKey;
|
||||||
virStorageVolDefFindByName;
|
virStorageVolDefFindByName;
|
||||||
virStorageVolDefFindByPath;
|
virStorageVolDefFindByPath;
|
||||||
|
@ -3775,69 +3775,6 @@ qemuBuildNBDString(virConnectPtr conn, virDomainDiskDefPtr disk, virBufferPtr op
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int
|
|
||||||
qemuBuildVolumeString(virConnectPtr conn,
|
|
||||||
virDomainDiskDefPtr disk,
|
|
||||||
virBufferPtr opt)
|
|
||||||
{
|
|
||||||
int ret = -1;
|
|
||||||
|
|
||||||
switch ((virStorageVolType) disk->srcpool->voltype) {
|
|
||||||
case VIR_STORAGE_VOL_DIR:
|
|
||||||
if (!disk->readonly) {
|
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
||||||
_("cannot create virtual FAT disks in read-write mode"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY)
|
|
||||||
virBufferEscape(opt, ',', ",", "file=fat:floppy:%s,", disk->src);
|
|
||||||
else
|
|
||||||
virBufferEscape(opt, ',', ",", "file=fat:%s,", disk->src);
|
|
||||||
break;
|
|
||||||
case VIR_STORAGE_VOL_BLOCK:
|
|
||||||
if (disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN) {
|
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
||||||
_("tray status 'open' is invalid for "
|
|
||||||
"block type volume"));
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
if (disk->srcpool->pooltype == VIR_STORAGE_POOL_ISCSI) {
|
|
||||||
if (disk->srcpool->mode ==
|
|
||||||
VIR_DOMAIN_DISK_SOURCE_POOL_MODE_DIRECT) {
|
|
||||||
if (qemuBuildISCSIString(conn, disk, opt) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
virBufferAddChar(opt, ',');
|
|
||||||
} else if (disk->srcpool->mode ==
|
|
||||||
VIR_DOMAIN_DISK_SOURCE_POOL_MODE_HOST) {
|
|
||||||
virBufferEscape(opt, ',', ",", "file=%s,", disk->src);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
virBufferEscape(opt, ',', ",", "file=%s,", disk->src);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VIR_STORAGE_VOL_FILE:
|
|
||||||
if (disk->auth.username) {
|
|
||||||
if (qemuBuildISCSIString(conn, disk, opt) < 0)
|
|
||||||
goto cleanup;
|
|
||||||
virBufferAddChar(opt, ',');
|
|
||||||
} else {
|
|
||||||
virBufferEscape(opt, ',', ",", "file=%s,", disk->src);
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
case VIR_STORAGE_VOL_NETWORK:
|
|
||||||
case VIR_STORAGE_VOL_NETDIR:
|
|
||||||
case VIR_STORAGE_VOL_LAST:
|
|
||||||
/* Keep the compiler quiet, qemuTranslateDiskSourcePool already
|
|
||||||
* reported the unsupported error.
|
|
||||||
*/
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = 0;
|
|
||||||
|
|
||||||
cleanup:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
char *
|
char *
|
||||||
qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
||||||
@ -3851,6 +3788,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
virDomainDiskGeometryTransTypeToString(disk->geometry.trans);
|
virDomainDiskGeometryTransTypeToString(disk->geometry.trans);
|
||||||
int idx = virDiskNameToIndex(disk->dst);
|
int idx = virDiskNameToIndex(disk->dst);
|
||||||
int busid = -1, unitid = -1;
|
int busid = -1, unitid = -1;
|
||||||
|
int actualType = qemuDiskGetActualType(disk);
|
||||||
|
|
||||||
if (idx < 0) {
|
if (idx < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
@ -3934,12 +3872,13 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
|
|
||||||
/* disk->src is NULL when we use nbd disks */
|
/* disk->src is NULL when we use nbd disks */
|
||||||
if ((disk->src ||
|
if ((disk->src ||
|
||||||
(disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK &&
|
(actualType == VIR_DOMAIN_DISK_TYPE_NETWORK &&
|
||||||
disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_NBD)) &&
|
disk->protocol == VIR_DOMAIN_DISK_PROTOCOL_NBD)) &&
|
||||||
!((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
|
!((disk->device == VIR_DOMAIN_DISK_DEVICE_FLOPPY ||
|
||||||
disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
|
disk->device == VIR_DOMAIN_DISK_DEVICE_CDROM) &&
|
||||||
disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
|
disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
|
||||||
if (disk->type == VIR_DOMAIN_DISK_TYPE_DIR) {
|
|
||||||
|
if (actualType == VIR_DOMAIN_DISK_TYPE_DIR) {
|
||||||
/* QEMU only supports magic FAT format for now */
|
/* QEMU only supports magic FAT format for now */
|
||||||
if (disk->format > 0 && disk->format != VIR_STORAGE_FILE_FAT) {
|
if (disk->format > 0 && disk->format != VIR_STORAGE_FILE_FAT) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
@ -3957,7 +3896,7 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
disk->src);
|
disk->src);
|
||||||
else
|
else
|
||||||
virBufferEscape(&opt, ',', ",", "file=fat:%s,", disk->src);
|
virBufferEscape(&opt, ',', ",", "file=fat:%s,", disk->src);
|
||||||
} else if (disk->type == VIR_DOMAIN_DISK_TYPE_NETWORK) {
|
} else if (actualType == VIR_DOMAIN_DISK_TYPE_NETWORK) {
|
||||||
switch (disk->protocol) {
|
switch (disk->protocol) {
|
||||||
case VIR_DOMAIN_DISK_PROTOCOL_NBD:
|
case VIR_DOMAIN_DISK_PROTOCOL_NBD:
|
||||||
if (qemuBuildNBDString(conn, disk, &opt) < 0)
|
if (qemuBuildNBDString(conn, disk, &opt) < 0)
|
||||||
@ -4025,15 +3964,13 @@ qemuBuildDriveStr(virConnectPtr conn ATTRIBUTE_UNUSED,
|
|||||||
virBufferEscape(&opt, ',', ",", "%s,", disk->src);
|
virBufferEscape(&opt, ',', ",", "%s,", disk->src);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
} else if (disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME) {
|
|
||||||
if (qemuBuildVolumeString(conn, disk, &opt) < 0)
|
|
||||||
goto error;
|
|
||||||
} else {
|
} else {
|
||||||
if ((disk->type == VIR_DOMAIN_DISK_TYPE_BLOCK) &&
|
if ((actualType == VIR_DOMAIN_DISK_TYPE_BLOCK) &&
|
||||||
(disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
|
(disk->tray_status == VIR_DOMAIN_DISK_TRAY_OPEN)) {
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
||||||
_("tray status 'open' is invalid for "
|
disk->type == VIR_DOMAIN_DISK_TYPE_VOLUME ?
|
||||||
"block type disk"));
|
_("tray status 'open' is invalid for block type volume") :
|
||||||
|
_("tray status 'open' is invalid for block type disk"));
|
||||||
goto error;
|
goto error;
|
||||||
}
|
}
|
||||||
virBufferEscape(&opt, ',', ",", "file=%s,", disk->src);
|
virBufferEscape(&opt, ',', ",", "file=%s,", disk->src);
|
||||||
|
@ -1298,6 +1298,17 @@ cleanup:
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int
|
||||||
|
qemuDiskGetActualType(virDomainDiskDefPtr def)
|
||||||
|
{
|
||||||
|
if (def->type == VIR_DOMAIN_DISK_TYPE_VOLUME)
|
||||||
|
return def->srcpool->actualtype;
|
||||||
|
|
||||||
|
return def->type;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int
|
int
|
||||||
qemuTranslateDiskSourcePool(virConnectPtr conn,
|
qemuTranslateDiskSourcePool(virConnectPtr conn,
|
||||||
virDomainDiskDefPtr def)
|
virDomainDiskDefPtr def)
|
||||||
@ -1319,72 +1330,123 @@ qemuTranslateDiskSourcePool(virConnectPtr conn,
|
|||||||
if (!(pool = virStoragePoolLookupByName(conn, def->srcpool->pool)))
|
if (!(pool = virStoragePoolLookupByName(conn, def->srcpool->pool)))
|
||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
|
if (virStoragePoolIsActive(pool) != 1) {
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("storage pool '%s' containing volume '%s' "
|
||||||
|
"is not active"),
|
||||||
|
def->srcpool->pool, def->srcpool->volume);
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
if (!(vol = virStorageVolLookupByName(pool, def->srcpool->volume)))
|
if (!(vol = virStorageVolLookupByName(pool, def->srcpool->volume)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (virStorageVolGetInfo(vol, &info) < 0)
|
if (virStorageVolGetInfo(vol, &info) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (def->startupPolicy &&
|
if (!(poolxml = virStoragePoolGetXMLDesc(pool, 0)))
|
||||||
info.type != VIR_STORAGE_VOL_FILE) {
|
goto cleanup;
|
||||||
|
|
||||||
|
if (!(pooldef = virStoragePoolDefParseString(poolxml)))
|
||||||
|
goto cleanup;
|
||||||
|
|
||||||
|
def->srcpool->pooltype = pooldef->type;
|
||||||
|
def->srcpool->voltype = info.type;
|
||||||
|
|
||||||
|
if (def->srcpool->mode && pooldef->type != VIR_STORAGE_POOL_ISCSI) {
|
||||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
_("'startupPolicy' is only valid for 'file' type volume"));
|
_("disk source mode is only valid when "
|
||||||
|
"storage pool is of iscsi type"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch ((virStorageVolType) info.type) {
|
switch ((enum virStoragePoolType) pooldef->type) {
|
||||||
case VIR_STORAGE_VOL_FILE:
|
case VIR_STORAGE_POOL_DIR:
|
||||||
case VIR_STORAGE_VOL_DIR:
|
case VIR_STORAGE_POOL_FS:
|
||||||
|
case VIR_STORAGE_POOL_NETFS:
|
||||||
|
case VIR_STORAGE_POOL_LOGICAL:
|
||||||
|
case VIR_STORAGE_POOL_DISK:
|
||||||
|
case VIR_STORAGE_POOL_SCSI:
|
||||||
if (!(def->src = virStorageVolGetPath(vol)))
|
if (!(def->src = virStorageVolGetPath(vol)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
break;
|
|
||||||
case VIR_STORAGE_VOL_BLOCK:
|
|
||||||
if (!(poolxml = virStoragePoolGetXMLDesc(pool, 0)))
|
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (!(pooldef = virStoragePoolDefParseString(poolxml)))
|
if (def->startupPolicy && info.type != VIR_STORAGE_VOL_FILE) {
|
||||||
goto cleanup;
|
|
||||||
|
|
||||||
if (def->srcpool->mode && pooldef->type != VIR_STORAGE_POOL_ISCSI) {
|
|
||||||
virReportError(VIR_ERR_XML_ERROR, "%s",
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
_("disk source mode is only valid when "
|
_("'startupPolicy' is only valid for "
|
||||||
"storage pool is of iscsi type"));
|
"'file' type volume"));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
def->srcpool->pooltype = pooldef->type;
|
|
||||||
if (pooldef->type == VIR_STORAGE_POOL_ISCSI) {
|
|
||||||
/* Default to use the LUN's path on host */
|
|
||||||
if (!def->srcpool->mode)
|
|
||||||
def->srcpool->mode = VIR_DOMAIN_DISK_SOURCE_POOL_MODE_HOST;
|
|
||||||
|
|
||||||
if (def->srcpool->mode ==
|
switch (info.type) {
|
||||||
VIR_DOMAIN_DISK_SOURCE_POOL_MODE_DIRECT) {
|
case VIR_STORAGE_VOL_FILE:
|
||||||
if (qemuAddISCSIPoolSourceHost(def, pooldef) < 0)
|
def->srcpool->actualtype = VIR_DOMAIN_DISK_TYPE_FILE;
|
||||||
goto cleanup;
|
break;
|
||||||
} else if (def->srcpool->mode ==
|
|
||||||
VIR_DOMAIN_DISK_SOURCE_POOL_MODE_HOST) {
|
case VIR_STORAGE_VOL_DIR:
|
||||||
if (!(def->src = virStorageVolGetPath(vol)))
|
def->srcpool->actualtype = VIR_DOMAIN_DISK_TYPE_DIR;
|
||||||
goto cleanup;
|
break;
|
||||||
}
|
|
||||||
|
case VIR_STORAGE_VOL_BLOCK:
|
||||||
|
def->srcpool->actualtype = VIR_DOMAIN_DISK_TYPE_BLOCK;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_STORAGE_VOL_NETWORK:
|
||||||
|
case VIR_STORAGE_VOL_NETDIR:
|
||||||
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
|
_("unexpected storage volume type '%s' "
|
||||||
|
"for storage pool type '%s'"),
|
||||||
|
virStorageVolTypeToString(info.type),
|
||||||
|
virStoragePoolTypeToString(pooldef->type));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_STORAGE_POOL_ISCSI:
|
||||||
|
if (def->startupPolicy) {
|
||||||
|
virReportError(VIR_ERR_XML_ERROR, "%s",
|
||||||
|
_("'startupPolicy' is only valid for "
|
||||||
|
"'file' type volume"));
|
||||||
|
goto cleanup;
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (def->srcpool->mode) {
|
||||||
|
case VIR_DOMAIN_DISK_SOURCE_POOL_MODE_DEFAULT:
|
||||||
|
case VIR_DOMAIN_DISK_SOURCE_POOL_MODE_LAST:
|
||||||
|
def->srcpool->mode = VIR_DOMAIN_DISK_SOURCE_POOL_MODE_HOST;
|
||||||
|
/* fallthrough */
|
||||||
|
case VIR_DOMAIN_DISK_SOURCE_POOL_MODE_HOST:
|
||||||
|
def->srcpool->actualtype = VIR_DOMAIN_DISK_TYPE_BLOCK;
|
||||||
|
if (!(def->src = virStorageVolGetPath(vol)))
|
||||||
|
goto cleanup;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case VIR_DOMAIN_DISK_SOURCE_POOL_MODE_DIRECT:
|
||||||
|
def->srcpool->actualtype = VIR_DOMAIN_DISK_TYPE_NETWORK;
|
||||||
|
def->protocol = VIR_DOMAIN_DISK_PROTOCOL_ISCSI;
|
||||||
|
|
||||||
if (qemuTranslateDiskSourcePoolAuth(def, pooldef) < 0)
|
if (qemuTranslateDiskSourcePoolAuth(def, pooldef) < 0)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
|
||||||
if (!(def->src = virStorageVolGetPath(vol)))
|
|
||||||
goto cleanup;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (qemuAddISCSIPoolSourceHost(def, pooldef) < 0)
|
||||||
|
goto cleanup;
|
||||||
|
break;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
case VIR_STORAGE_VOL_NETWORK:
|
|
||||||
case VIR_STORAGE_VOL_NETDIR:
|
case VIR_STORAGE_POOL_MPATH:
|
||||||
case VIR_STORAGE_VOL_LAST:
|
case VIR_STORAGE_POOL_RBD:
|
||||||
virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
case VIR_STORAGE_POOL_SHEEPDOG:
|
||||||
_("Using network volume as disk source is not supported"));
|
case VIR_STORAGE_POOL_GLUSTER:
|
||||||
|
case VIR_STORAGE_POOL_LAST:
|
||||||
|
virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
|
||||||
|
_("using '%s' pools for backing 'volume' disks "
|
||||||
|
"isn't yet supported"),
|
||||||
|
virStoragePoolTypeToString(pooldef->type));
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
def->srcpool->voltype = info.type;
|
|
||||||
ret = 0;
|
ret = 0;
|
||||||
cleanup:
|
cleanup:
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
|
@ -305,6 +305,8 @@ int qemuSetUnprivSGIO(virDomainDeviceDefPtr dev);
|
|||||||
int qemuDriverAllocateID(virQEMUDriverPtr driver);
|
int qemuDriverAllocateID(virQEMUDriverPtr driver);
|
||||||
virDomainXMLOptionPtr virQEMUDriverCreateXMLConf(virQEMUDriverPtr driver);
|
virDomainXMLOptionPtr virQEMUDriverCreateXMLConf(virQEMUDriverPtr driver);
|
||||||
|
|
||||||
|
int qemuDiskGetActualType(virDomainDiskDefPtr def);
|
||||||
|
|
||||||
int qemuTranslateDiskSourcePool(virConnectPtr conn,
|
int qemuTranslateDiskSourcePool(virConnectPtr conn,
|
||||||
virDomainDiskDefPtr def);
|
virDomainDiskDefPtr def);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user