On Wed, Feb 03, 2021 at 10:27:01AM +0100, Peter Krempa wrote: > On Tue, Feb 02, 2021 at 16:04:10 +0100, Pavel Hrdina wrote: > > Signed-off-by: Pavel Hrdina <phrdina@xxxxxxxxxx> > > --- > > > > We need to find a better way to validate different combinations of XML > > elements and attributes. > > > > src/conf/domain_conf.c | 85 ++++++++ > > src/conf/domain_validate.c | 187 ++++++++++++++++++ > > src/conf/storage_source_conf.c | 3 + > > src/conf/storage_source_conf.h | 4 + > > src/libxl/xen_xl.c | 1 + > > src/qemu/qemu_block.c | 4 + > > src/qemu/qemu_command.c | 1 + > > src/qemu/qemu_migration.c | 2 + > > src/qemu/qemu_snapshot.c | 4 + > > src/storage_file/storage_source.c | 1 + > > tests/qemuxml2argvdata/disk-vhostuser.xml | 29 +++ > > .../disk-vhostuser.x86_64-latest.xml | 48 +++++ > > tests/qemuxml2xmltest.c | 1 + > > 13 files changed, 370 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 97fa841bff..43552c36c3 100644 > > --- a/src/conf/domain_conf.c > > +++ b/src/conf/domain_conf.c > > @@ -5228,6 +5228,11 @@ 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; > > @@ -8361,6 +8366,55 @@ virDomainDiskSourceNVMeParse(xmlNodePtr node, > > } > > > > > > +static int > > +virDomainChrSourceReconnectDefParseXML(virDomainChrSourceReconnectDefPtr def, > > + xmlNodePtr node, > > + xmlXPathContextPtr ctxt); > > [... see below note on forward decls.] > > > + > > + > > +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); > > 'path' doesn't really need a temp variable. True, but IMHO it makes the code more readable. Without the variable it would look like this: g_autofree char *type = virXMLPropString(node, "type"); 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 (!(src->vhostuser = virDomainChrSourceDefNew(xmlopt))) return -1; src->vhostuser->type = virDomainChrTypeFromString(type); src->vhostuser->data.nix.path = virXMLPropString(node, "path"); if (!src->vhostuser->data.nix.path) { virReportError(VIR_ERR_XML_ERROR, "%s", _("missing 'path' attribute for vhostuser disk source")); return -1; } if (virDomainChrSourceReconnectDefParseXML(&src->vhostuser->data.nix.reconnect, node, ctxt) < 0) { return -1; } return 0; which is mixing the checks and assignment together. > > > + > > + if (virDomainChrSourceReconnectDefParseXML(&src->vhostuser->data.nix.reconnect, > > + node, > > + ctxt) < 0) { > > + return -1; > > + } > > + > > + return 0; > > +} > > [...] > > > @@ -23939,6 +23997,23 @@ virDomainDiskSourceNVMeFormat(virBufferPtr attrBuf, > > } > > > > > > +static void > > +virDomainChrSourceReconnectDefFormat(virBufferPtr buf, > > + virDomainChrSourceReconnectDefPtr def); > > + > > + > > [...] > > > @@ -23989,6 +24064,12 @@ virDomainDiskSourceFormatSlices(virBufferPtr buf, > > } > > > > > > +static void > > +virDomainChrSourceDefFormat(virBufferPtr buf, > > + virDomainChrSourceDefPtr def, > > + unsigned int flags); > > + > > + > > Preferably put the forward declarations at the top of the file. > > [...] > > > diff --git a/src/conf/domain_validate.c b/src/conf/domain_validate.c > > index c56b03ff3a..c60300e750 100644 > > --- a/src/conf/domain_validate.c > > +++ b/src/conf/domain_validate.c > > [...] > > > @@ -254,6 +255,187 @@ virDomainCheckVirtioOptionsAreAbsent(virDomainVirtioOptionsPtr virtio) > > } > > > > > > +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 drive attributes */ > > s/drive/dirver/ Fixed, thanks. > > > + > > + 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; > > + } > > + > > + if (disk->src->metadataCacheMaxSize > 0) { > > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > > + _("metadata_cache is not supported with vhostuser disk")); > > + return -1; > > + } > > + > > + /* Unsupported driver elements */ > > s/driver/virtio/ ? This was future proofing the comment :) currently there is only single child element <virtio>. So I would be OK with both versions: /* Unsupported driver child elements */ /* Unsupported virtio element */ > > > + > > + 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; > > + } > > + > > + if (disk->virtio->packed != VIR_TRISTATE_SWITCH_ABSENT) { > > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s", > > + _("packed is not supported with vhostuser disk")); > > + return -1; > > + } > > + } > > [...] > > > diff --git a/src/qemu/qemu_block.c b/src/qemu/qemu_block.c > > index 6456100170..f6e81a7503 100644 > > --- a/src/qemu/qemu_block.c > > +++ b/src/qemu/qemu_block.c > > @@ -1173,6 +1173,9 @@ qemuBlockStorageSourceGetBackendProps(virStorageSourcePtr src, > > return NULL; > > break; > > > > + case VIR_STORAGE_TYPE_VHOST_USER: > > + break; > > This case must return NULL and an error per API contract of the function. Fixed. It should never happen but I agree that we should make sure to error out if it happens. Pavel > > > + > > case VIR_STORAGE_TYPE_VOLUME: > > virReportError(VIR_ERR_INTERNAL_ERROR, > > _("storage source pool '%s' volume '%s' is not translated"),
Attachment:
signature.asc
Description: PGP signature