79c4324644
Change-Id: I2d302dda68298877c65c99147f5bf22186a59aac
618 lines
22 KiB
Diff
618 lines
22 KiB
Diff
From 02565aca5158fb4d9870546ea29be85278649511 Mon Sep 17 00:00:00 2001
|
|
From: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
|
|
Date: Wed, 30 Nov 2022 18:13:36 +0800
|
|
Subject: [PATCH 15/24] conf: implement support for vhostuser disk
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Signed-off-by: Pavel Hrdina <phrdina@redhat.com>
|
|
Reviewed-by: Ján Tomko <jtomko@redhat.com>
|
|
Reviewed-by: Peter Krempa <pkrempa@redhat.com>
|
|
(cherry picked from commit f00fe96eb045eed2b6b40d5046449bec6d495875)
|
|
Signed-off-by: Luo Yifan <luoyifan_yewu@cmss.chinamobile.com>
|
|
---
|
|
src/conf/domain_conf.c | 254 ++++++++++++++++++
|
|
src/libxl/xen_xl.c | 1 +
|
|
src/qemu/qemu_block.c | 6 +
|
|
src/qemu/qemu_command.c | 1 +
|
|
src/qemu/qemu_driver.c | 4 +
|
|
src/qemu/qemu_migration.c | 2 +
|
|
src/util/virstoragefile.c | 4 +
|
|
src/util/virstoragefile.h | 4 +
|
|
tests/qemuxml2argvdata/disk-vhostuser.xml | 30 +++
|
|
.../disk-vhostuser.x86_64-latest.xml | 48 ++++
|
|
tests/qemuxml2xmltest.c | 1 +
|
|
11 files changed, 355 insertions(+)
|
|
create mode 100644 tests/qemuxml2argvdata/disk-vhostuser.xml
|
|
create mode 100644 tests/qemuxml2xmloutdata/disk-vhostuser.x86_64-latest.xml
|
|
|
|
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
|
|
index b60b9d31a1..8b1ca76d39 100644
|
|
--- a/src/conf/domain_conf.c
|
|
+++ b/src/conf/domain_conf.c
|
|
@@ -1278,6 +1278,17 @@ static virClassPtr virDomainXMLOptionClass;
|
|
static void virDomainObjDispose(void *obj);
|
|
static void virDomainXMLOptionDispose(void *obj);
|
|
|
|
+static int
|
|
+virDomainChrSourceDefFormat(virBufferPtr buf,
|
|
+ virDomainChrSourceDefPtr def,
|
|
+ unsigned int flags);
|
|
+
|
|
+
|
|
+static int
|
|
+virDomainChrSourceReconnectDefParseXML(virDomainChrSourceReconnectDefPtr def,
|
|
+ xmlNodePtr node,
|
|
+ xmlXPathContextPtr ctxt);
|
|
+
|
|
static int virDomainObjOnceInit(void)
|
|
{
|
|
if (!VIR_CLASS_NEW(virDomainObj, virClassForObjectLockable()))
|
|
@@ -5200,6 +5211,12 @@ virDomainDiskDefPostParse(virDomainDiskDefPtr disk,
|
|
disk->src->nvme->managed = VIR_TRISTATE_BOOL_YES;
|
|
}
|
|
|
|
+ /* vhost-user doesn't allow us to snapshot, disable snapshots by default */
|
|
+ if (disk->src->type == VIR_STORAGE_TYPE_VHOST_USER &&
|
|
+ disk->snapshot == VIR_DOMAIN_SNAPSHOT_LOCATION_DEFAULT) {
|
|
+ disk->snapshot = VIR_DOMAIN_SNAPSHOT_LOCATION_NONE;
|
|
+ }
|
|
+
|
|
if (disk->info.type == VIR_DOMAIN_DEVICE_ADDRESS_TYPE_NONE &&
|
|
virDomainDiskDefAssignAddress(xmlopt, disk, def) < 0) {
|
|
return -1;
|
|
@@ -5995,6 +6012,174 @@ virDomainDiskAddressDiskBusCompatibility(virDomainDiskBus bus,
|
|
return true;
|
|
}
|
|
|
|
+static int
|
|
+virDomainDiskVhostUserValidate(const virDomainDiskDef *disk)
|
|
+{
|
|
+ if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("vhostuser disk supports only virtio bus"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->snapshot != VIR_DOMAIN_SNAPSHOT_LOCATION_NONE) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("only snapshot=no is supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* Unsupported driver attributes */
|
|
+
|
|
+ if (disk->cachemode != VIR_DOMAIN_DISK_CACHE_DEFAULT) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("cache is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->error_policy || disk->rerror_policy) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("error_policy is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->iomode) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("io is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->ioeventfd != VIR_TRISTATE_SWITCH_ABSENT) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("ioeventfd is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->copy_on_read) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("copy_on_read is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->discard) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("discard is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->iothread) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("iothread is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->detect_zeroes) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("detect_zeroes is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ /* Unsupported driver elements */
|
|
+
|
|
+ if (disk->virtio) {
|
|
+ if (disk->virtio->iommu != VIR_TRISTATE_SWITCH_ABSENT) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("iommu is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->virtio->ats != VIR_TRISTATE_SWITCH_ABSENT) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("ats is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Unsupported disk elements */
|
|
+
|
|
+ if (disk->blkdeviotune.group_name ||
|
|
+ virDomainBlockIoTuneInfoHasAny(&disk->blkdeviotune)) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("iotune is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->src->backingStore) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("backingStore is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->src->encryption) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("encryption is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->src->readonly) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("readonly is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->src->shared) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("shareable is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->transient) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("transient is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->serial) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("serial is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->wwn) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("wwn is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->vendor) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("vendor is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->product) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("product is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->src->auth) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("auth is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->geometry.cylinders > 0 ||
|
|
+ disk->geometry.heads > 0 ||
|
|
+ disk->geometry.sectors > 0 ||
|
|
+ disk->geometry.trans != VIR_DOMAIN_DISK_TRANS_DEFAULT) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("geometry is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (disk->blockio.logical_block_size > 0 ||
|
|
+ disk->blockio.physical_block_size > 0) {
|
|
+ virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
|
|
+ _("blockio is not supported with vhostuser disk"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
|
|
static int
|
|
virSecurityDeviceLabelDefValidateXML(virSecurityDeviceLabelDefPtr *seclabels,
|
|
@@ -6095,6 +6280,11 @@ virDomainDiskDefValidate(const virDomainDef *def,
|
|
}
|
|
}
|
|
|
|
+ if (disk->src->type == VIR_STORAGE_TYPE_VHOST_USER &&
|
|
+ virDomainDiskVhostUserValidate(disk) < 0) {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
for (next = disk->src; next; next = next->backingStore) {
|
|
if (virSecurityDeviceLabelDefValidateXML(next->seclabels,
|
|
next->nseclabels,
|
|
@@ -9530,6 +9720,47 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
|
|
return 0;
|
|
}
|
|
|
|
+static int
|
|
+virDomainDiskSourceVHostUserParse(xmlNodePtr node,
|
|
+ virStorageSourcePtr src,
|
|
+ virDomainXMLOptionPtr xmlopt,
|
|
+ xmlXPathContextPtr ctxt)
|
|
+{
|
|
+ g_autofree char *type = virXMLPropString(node, "type");
|
|
+ g_autofree char *path = virXMLPropString(node, "path");
|
|
+
|
|
+ if (!type) {
|
|
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
+ _("missing 'type' attribute for vhostuser disk source"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (STRNEQ(type, "unix")) {
|
|
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
+ _("invalid 'type' attribute for vhostuser disk source"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (!path) {
|
|
+ virReportError(VIR_ERR_XML_ERROR, "%s",
|
|
+ _("missing 'path' attribute for vhostuser disk source"));
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ if (!(src->vhostuser = virDomainChrSourceDefNew(xmlopt)))
|
|
+ return -1;
|
|
+
|
|
+ src->vhostuser->type = virDomainChrTypeFromString(type);
|
|
+ src->vhostuser->data.nix.path = g_steal_pointer(&path);
|
|
+
|
|
+ if (virDomainChrSourceReconnectDefParseXML(&src->vhostuser->data.nix.reconnect,
|
|
+ node,
|
|
+ ctxt) < 0) {
|
|
+ return -1;
|
|
+ }
|
|
+
|
|
+ return 0;
|
|
+}
|
|
|
|
static int
|
|
virDomainDiskSourceNVMeParse(xmlNodePtr node,
|
|
@@ -9746,6 +9977,10 @@ virDomainStorageSourceParse(xmlNodePtr node,
|
|
if (virDomainDiskSourceNVMeParse(node, ctxt, src) < 0)
|
|
return -1;
|
|
break;
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
+ if (virDomainDiskSourceVHostUserParse(node, src, xmlopt, ctxt) < 0)
|
|
+ return -1;
|
|
+ break;
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
case VIR_STORAGE_TYPE_LAST:
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
@@ -24682,6 +24917,21 @@ virDomainDiskSourceNVMeFormat(virBufferPtr attrBuf,
|
|
virPCIDeviceAddressFormat(childBuf, nvme->pciAddr, false);
|
|
}
|
|
|
|
+static void
|
|
+virDomainChrSourceReconnectDefFormat(virBufferPtr buf,
|
|
+ virDomainChrSourceReconnectDefPtr def);
|
|
+
|
|
+
|
|
+static void
|
|
+virDomainDiskSourceVhostuserFormat(virBufferPtr attrBuf,
|
|
+ virBufferPtr childBuf,
|
|
+ virDomainChrSourceDefPtr vhostuser)
|
|
+{
|
|
+ virBufferAddLit(attrBuf, " type='unix'");
|
|
+ virBufferAsprintf(attrBuf, " path='%s'", vhostuser->data.nix.path);
|
|
+
|
|
+ virDomainChrSourceReconnectDefFormat(childBuf, &vhostuser->data.nix.reconnect);
|
|
+}
|
|
|
|
static int
|
|
virDomainDiskSourceFormatPrivateData(virBufferPtr buf,
|
|
@@ -24796,6 +25046,10 @@ virDomainDiskSourceFormat(virBufferPtr buf,
|
|
virDomainDiskSourceNVMeFormat(&attrBuf, &childBuf, src->nvme);
|
|
break;
|
|
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
+ virDomainDiskSourceVhostuserFormat(&attrBuf, &childBuf, src->vhostuser);
|
|
+ break;
|
|
+
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
case VIR_STORAGE_TYPE_LAST:
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
diff --git a/src/libxl/xen_xl.c b/src/libxl/xen_xl.c
|
|
index 91b1825399..08eea48d6c 100644
|
|
--- a/src/libxl/xen_xl.c
|
|
+++ b/src/libxl/xen_xl.c
|
|
@@ -1641,6 +1641,7 @@ xenFormatXLDiskSrc(virStorageSourcePtr src, char **srcstr)
|
|
|
|
case VIR_STORAGE_TYPE_VOLUME:
|
|
case VIR_STORAGE_TYPE_NVME:
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
case VIR_STORAGE_TYPE_LAST:
|
|
break;
|
|
diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c
|
|
index d32277d7fd..8bd6238238 100644
|
|
--- a/src/qemu/qemu_block.c
|
|
+++ b/src/qemu/qemu_block.c
|
|
@@ -1108,6 +1108,11 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src,
|
|
return NULL;
|
|
break;
|
|
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
+ virReportError(VIR_ERR_INTERNAL_ERROR, "%s",
|
|
+ _("unable to create blockdev props for vhostuser disk type"));
|
|
+ return NULL;
|
|
+
|
|
case VIR_STORAGE_TYPE_VOLUME:
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
_("storage source pool '%s' volume '%s' is not translated"),
|
|
@@ -2491,6 +2496,7 @@ qemuBlockStorageSourceCreateGetStorageProps(virStorageSourcePtr src,
|
|
case VIR_STORAGE_TYPE_DIR:
|
|
case VIR_STORAGE_TYPE_VOLUME:
|
|
case VIR_STORAGE_TYPE_NVME:
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
return 0;
|
|
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
diff --git a/src/qemu/qemu_command.c b/src/qemu/qemu_command.c
|
|
index 9157008b73..bc62843783 100644
|
|
--- a/src/qemu/qemu_command.c
|
|
+++ b/src/qemu/qemu_command.c
|
|
@@ -1166,6 +1166,7 @@ qemuGetDriveSourceString(virStorageSourcePtr src,
|
|
|
|
case VIR_STORAGE_TYPE_VOLUME:
|
|
case VIR_STORAGE_TYPE_NVME:
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
case VIR_STORAGE_TYPE_LAST:
|
|
break;
|
|
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
|
|
index 854b56a563..b2ad021e4d 100644
|
|
--- a/src/qemu/qemu_driver.c
|
|
+++ b/src/qemu/qemu_driver.c
|
|
@@ -14536,6 +14536,7 @@ qemuDomainSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDefPtr snapdi
|
|
case VIR_STORAGE_TYPE_DIR:
|
|
case VIR_STORAGE_TYPE_VOLUME:
|
|
case VIR_STORAGE_TYPE_NVME:
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
case VIR_STORAGE_TYPE_LAST:
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
@@ -14553,6 +14554,7 @@ qemuDomainSnapshotPrepareDiskExternalInactive(virDomainSnapshotDiskDefPtr snapdi
|
|
case VIR_STORAGE_TYPE_DIR:
|
|
case VIR_STORAGE_TYPE_VOLUME:
|
|
case VIR_STORAGE_TYPE_NVME:
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
case VIR_STORAGE_TYPE_LAST:
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
@@ -14621,6 +14623,7 @@ qemuDomainSnapshotPrepareDiskExternalActive(virDomainSnapshotDiskDefPtr snapdisk
|
|
case VIR_STORAGE_TYPE_DIR:
|
|
case VIR_STORAGE_TYPE_VOLUME:
|
|
case VIR_STORAGE_TYPE_NVME:
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
case VIR_STORAGE_TYPE_LAST:
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
@@ -14749,6 +14752,7 @@ qemuDomainSnapshotPrepareDiskInternal(virDomainDiskDefPtr disk,
|
|
case VIR_STORAGE_TYPE_DIR:
|
|
case VIR_STORAGE_TYPE_VOLUME:
|
|
case VIR_STORAGE_TYPE_NVME:
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
case VIR_STORAGE_TYPE_LAST:
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
|
|
index 1c48138ce3..faf4e223a8 100644
|
|
--- a/src/qemu/qemu_migration.c
|
|
+++ b/src/qemu/qemu_migration.c
|
|
@@ -228,6 +228,7 @@ qemuMigrationDstPrecreateDisk(virConnectPtr conn,
|
|
case VIR_STORAGE_TYPE_BLOCK:
|
|
case VIR_STORAGE_TYPE_DIR:
|
|
case VIR_STORAGE_TYPE_NVME:
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
case VIR_STORAGE_TYPE_LAST:
|
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
|
@@ -1358,6 +1359,7 @@ qemuMigrationSrcIsSafe(virDomainDefPtr def,
|
|
unsafe = true;
|
|
break;
|
|
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
case VIR_STORAGE_TYPE_BLOCK:
|
|
case VIR_STORAGE_TYPE_DIR:
|
|
diff --git a/src/util/virstoragefile.c b/src/util/virstoragefile.c
|
|
index ffc8bdb344..2515dbf5ed 100644
|
|
--- a/src/util/virstoragefile.c
|
|
+++ b/src/util/virstoragefile.c
|
|
@@ -56,6 +56,7 @@ VIR_ENUM_IMPL(virStorage,
|
|
"network",
|
|
"volume",
|
|
"nvme",
|
|
+ "vhostuser",
|
|
);
|
|
|
|
VIR_ENUM_IMPL(virStorageFileFormat,
|
|
@@ -2617,6 +2618,7 @@ virStorageSourceIsLocalStorage(const virStorageSource *src)
|
|
/* While NVMe disks are local, they are not accessible via src->path.
|
|
* Therefore, we have to return false here. */
|
|
case VIR_STORAGE_TYPE_NVME:
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
case VIR_STORAGE_TYPE_LAST:
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
return false;
|
|
@@ -4164,6 +4166,7 @@ virStorageSourceUpdatePhysicalSize(virStorageSourcePtr src,
|
|
/* We shouldn't get VOLUME, but the switch requires all cases */
|
|
case VIR_STORAGE_TYPE_VOLUME:
|
|
case VIR_STORAGE_TYPE_NVME:
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
case VIR_STORAGE_TYPE_LAST:
|
|
return -1;
|
|
@@ -4610,6 +4613,7 @@ virStorageSourceIsRelative(virStorageSourcePtr src)
|
|
case VIR_STORAGE_TYPE_NETWORK:
|
|
case VIR_STORAGE_TYPE_VOLUME:
|
|
case VIR_STORAGE_TYPE_NVME:
|
|
+ case VIR_STORAGE_TYPE_VHOST_USER:
|
|
case VIR_STORAGE_TYPE_NONE:
|
|
case VIR_STORAGE_TYPE_LAST:
|
|
return false;
|
|
diff --git a/src/util/virstoragefile.h b/src/util/virstoragefile.h
|
|
index 7939c09cd5..f2096b8705 100644
|
|
--- a/src/util/virstoragefile.h
|
|
+++ b/src/util/virstoragefile.h
|
|
@@ -28,6 +28,7 @@
|
|
#include "virseclabel.h"
|
|
#include "virstorageencryption.h"
|
|
#include "virsecret.h"
|
|
+#include "../conf/virconftypes.h"
|
|
#include "virenum.h"
|
|
#include "virpci.h"
|
|
|
|
@@ -52,6 +53,7 @@ typedef enum {
|
|
VIR_STORAGE_TYPE_NETWORK,
|
|
VIR_STORAGE_TYPE_VOLUME,
|
|
VIR_STORAGE_TYPE_NVME,
|
|
+ VIR_STORAGE_TYPE_VHOST_USER,
|
|
|
|
VIR_STORAGE_TYPE_LAST
|
|
} virStorageType;
|
|
@@ -302,6 +304,8 @@ struct _virStorageSource {
|
|
|
|
virStorageSourceNVMeDefPtr nvme; /* type == VIR_STORAGE_TYPE_NVME */
|
|
|
|
+ virDomainChrSourceDefPtr vhostuser; /* type == VIR_STORAGE_TYPE_VHOST_USER */
|
|
+
|
|
virStorageSourceInitiatorDef initiator;
|
|
|
|
virObjectPtr privateData;
|
|
diff --git a/tests/qemuxml2argvdata/disk-vhostuser.xml b/tests/qemuxml2argvdata/disk-vhostuser.xml
|
|
new file mode 100644
|
|
index 0000000000..c96ef9119c
|
|
--- /dev/null
|
|
+++ b/tests/qemuxml2argvdata/disk-vhostuser.xml
|
|
@@ -0,0 +1,30 @@
|
|
+<domain type='qemu'>
|
|
+ <name>QEMUGuest1</name>
|
|
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
|
+ <memory unit='KiB'>219136</memory>
|
|
+ <currentMemory unit='KiB'>219136</currentMemory>
|
|
+ <memoryBacking>
|
|
+ <source type='memfd'/>
|
|
+ <access mode='shared'/>
|
|
+ </memoryBacking>
|
|
+ <vcpu placement='static'>1</vcpu>
|
|
+ <os>
|
|
+ <type arch='i686' machine='pc'>hvm</type>
|
|
+ </os>
|
|
+ <devices>
|
|
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
|
|
+ <disk type='vhostuser' device='disk'>
|
|
+ <driver name='qemu' type='raw'/>
|
|
+ <source type='unix' path='/tmp/vhost1.sock'/>
|
|
+ <target dev='vda' bus='virtio'/>
|
|
+ <boot order='1'/>
|
|
+ </disk>
|
|
+ <disk type='vhostuser' device='disk'>
|
|
+ <driver name='qemu' type='raw'/>
|
|
+ <source type='unix' path='/tmp/vhost1.sock'>
|
|
+ <reconnect enabled='yes' timeout='10'/>
|
|
+ </source>
|
|
+ <target dev='vdb' bus='virtio'/>
|
|
+ </disk>
|
|
+ </devices>
|
|
+</domain>
|
|
diff --git a/tests/qemuxml2xmloutdata/disk-vhostuser.x86_64-latest.xml b/tests/qemuxml2xmloutdata/disk-vhostuser.x86_64-latest.xml
|
|
new file mode 100644
|
|
index 0000000000..9712dc0b12
|
|
--- /dev/null
|
|
+++ b/tests/qemuxml2xmloutdata/disk-vhostuser.x86_64-latest.xml
|
|
@@ -0,0 +1,48 @@
|
|
+<domain type='qemu'>
|
|
+ <name>QEMUGuest1</name>
|
|
+ <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
|
|
+ <memory unit='KiB'>219136</memory>
|
|
+ <currentMemory unit='KiB'>219136</currentMemory>
|
|
+ <memoryBacking>
|
|
+ <source type='memfd'/>
|
|
+ <access mode='shared'/>
|
|
+ </memoryBacking>
|
|
+ <vcpu placement='static'>1</vcpu>
|
|
+ <os>
|
|
+ <type arch='i686' machine='pc'>hvm</type>
|
|
+ </os>
|
|
+ <cpu mode='custom' match='exact' check='none'>
|
|
+ <model fallback='forbid'>qemu64</model>
|
|
+ </cpu>
|
|
+ <clock offset='utc'/>
|
|
+ <on_poweroff>destroy</on_poweroff>
|
|
+ <on_reboot>restart</on_reboot>
|
|
+ <on_crash>destroy</on_crash>
|
|
+ <devices>
|
|
+ <emulator>/usr/bin/qemu-system-x86_64</emulator>
|
|
+ <disk type='vhostuser' device='disk' snapshot='no'>
|
|
+ <driver name='qemu' type='raw'/>
|
|
+ <source type='unix' path='/tmp/vhost1.sock'/>
|
|
+ <target dev='vda' bus='virtio'/>
|
|
+ <boot order='1'/>
|
|
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x02' function='0x0'/>
|
|
+ </disk>
|
|
+ <disk type='vhostuser' device='disk' snapshot='no'>
|
|
+ <driver name='qemu' type='raw'/>
|
|
+ <source type='unix' path='/tmp/vhost1.sock'>
|
|
+ <reconnect enabled='yes' timeout='10'/>
|
|
+ </source>
|
|
+ <target dev='vdb' bus='virtio'/>
|
|
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
|
|
+ </disk>
|
|
+ <controller type='usb' index='0' model='piix3-uhci'>
|
|
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
|
|
+ </controller>
|
|
+ <controller type='pci' index='0' model='pci-root'/>
|
|
+ <input type='mouse' bus='ps2'/>
|
|
+ <input type='keyboard' bus='ps2'/>
|
|
+ <memballoon model='virtio'>
|
|
+ <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
|
|
+ </memballoon>
|
|
+ </devices>
|
|
+</domain>
|
|
diff --git a/tests/qemuxml2xmltest.c b/tests/qemuxml2xmltest.c
|
|
index 3a2539596b..2569c27261 100644
|
|
--- a/tests/qemuxml2xmltest.c
|
|
+++ b/tests/qemuxml2xmltest.c
|
|
@@ -338,6 +338,7 @@ mymain(void)
|
|
DO_TEST("disk-network-vxhs", NONE);
|
|
DO_TEST("disk-network-tlsx509", NONE);
|
|
DO_TEST("disk-nvme", QEMU_CAPS_VIRTIO_SCSI, QEMU_CAPS_QCOW2_LUKS);
|
|
+ DO_TEST_CAPS_LATEST("disk-vhostuser");
|
|
DO_TEST("disk-scsi", QEMU_CAPS_SCSI_LSI, QEMU_CAPS_SCSI_MEGASAS,
|
|
QEMU_CAPS_SCSI_MPTSAS1068, QEMU_CAPS_SCSI_DISK_WWN);
|
|
DO_TEST("disk-virtio-scsi-reservations",
|
|
--
|
|
2.27.0
|
|
|