[libvirt] [PATCH v1 11/31] conf: Format and parse NVMe type disk
Peter Krempa
pkrempa at redhat.com
Wed Jul 17 15:13:15 UTC 2019
On Wed, Jul 17, 2019 at 17:05:08 +0200, Michal Privoznik wrote:
> On 7/16/19 3:00 PM, Peter Krempa wrote:
> > On Thu, Jul 11, 2019 at 17:53:58 +0200, Michal Privoznik wrote:
> > > To simplify implementation, some restrictions are added. For
> > > instance, an NVMe disk can't go to any bus but virtio and has to
> > > be type of 'disk' and can't have startupPolicy set.
> > >
> > > Signed-off-by: Michal Privoznik <mprivozn at redhat.com>
> > > ---
> > > src/conf/domain_conf.c | 129 +++++++++++++++++++++++++
> > > src/libvirt_private.syms | 1 +
> > > src/qemu/qemu_block.c | 1 +
> > > src/qemu/qemu_command.c | 1 +
> > > src/qemu/qemu_driver.c | 4 +
> > > src/qemu/qemu_migration.c | 1 +
> > > src/util/virstoragefile.c | 59 +++++++++++
> > > src/util/virstoragefile.h | 15 +++
> > > src/xenconfig/xen_xl.c | 1 +
> > > tests/qemuxml2argvdata/disk-nvme.xml | 12 ++-
> > > tests/qemuxml2xmloutdata/disk-nvme.xml | 1 +
> > > tests/qemuxml2xmltest.c | 1 +
> > > 12 files changed, 224 insertions(+), 2 deletions(-)
> > > create mode 120000 tests/qemuxml2xmloutdata/disk-nvme.xml
> > >
> > > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> > > index 3323c9a5b1..73f5e1fa0f 100644
> > > --- a/src/conf/domain_conf.c
> > > +++ b/src/conf/domain_conf.c
> >
> > [...]
> >
> > > @@ -5938,6 +5943,38 @@ virDomainDiskDefValidate(const virDomainDiskDef *disk)
> > > return -1;
> > > }
> > > + if (disk->src->type == VIR_STORAGE_TYPE_NVME) {
> > > + /* These might not be valid for all hypervisors, but be
> > > + * strict now and possibly refine in the future. */
> > > + if (disk->device != VIR_DOMAIN_DISK_DEVICE_DISK) {
> > > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> > > + _("Unsupported disk type '%s' for NVMe disk"),
> > > + virDomainDiskDeviceTypeToString(disk->device));
> > > + return -1;
> > > + }
> > > +
> > > + if (disk->bus != VIR_DOMAIN_DISK_BUS_VIRTIO) {
> > > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> > > + _("Unsupported bus '%s' for NVMe disk"),
> > > + virDomainDiskBusTypeToString(disk->bus));
> > > + return -1;
> > > + }
> > > +
> > > + if (disk->startupPolicy != VIR_DOMAIN_STARTUP_POLICY_DEFAULT &&
> > > + disk->startupPolicy != VIR_DOMAIN_STARTUP_POLICY_MANDATORY) {
> > > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
> > > + _("Unsupported startup policy '%s' for NVMe disk"),
> > > + virDomainStartupPolicyTypeToString(disk->startupPolicy));
> > > + return -1;
> > > + }
> > > +
> > > + if (disk->src->shared) {
> > > + virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
> > > + _("Unsupported <shareable/> for NVMe disk"));
> > > + return -1;
> > > + }
> > > + }
> > > +
> > > return 0;
> > > }
> >
> > As noted in the other thread, this really should be extracted, placed in
> > the validation callback rather than post parse and must iterate the
> > backing chain if you want this to keep working with -blockdev.
>
> I'm not sure I understand what you mean. This function is called
> virDomainDiskDefValidate() and therefore it is validation callback rather
> than post parse callback. Where do you want me to put these checks?
Sorry I thought it was in post-parse. This is okay.
>
> >
> > > @@ -9184,6 +9221,76 @@ virDomainDiskSourceNetworkParse(xmlNodePtr node,
> > > }
> > > +static int
> > > +virDomainDiskSourceNVMeParse(xmlNodePtr node,
> > > + xmlXPathContextPtr ctxt,
> > > + virStorageSourcePtr src)
> > > +{
> > > + VIR_AUTOPTR(virStorageSourceNVMeDef) nvme = NULL;
> > > + VIR_AUTOFREE(char *) type = NULL;
> > > + VIR_AUTOFREE(char *) namespace = NULL;
> > > + VIR_AUTOFREE(char *) managed = NULL;
> > > + xmlNodePtr address;
> > > +
> > > + if (VIR_ALLOC(nvme) < 0)
> > > + return -1;
> > > +
> > > + if (!(type = virXMLPropString(node, "type"))) {
> > > + virReportError(VIR_ERR_XML_ERROR, "%s",
> > > + _("missing 'type' attribute to disk source"));
> > > + return -1;
> > > + }
> > > +
> > > + if (STRNEQ(type, "pci")) {
> > > + virReportError(VIR_ERR_XML_ERROR,
> > > + _("unsupported source type '%s'"),
> > > + type);
> > > + return -1;
> > > + }
> > > +
> > > + if (!(namespace = virXMLPropString(node, "namespace"))) {
> > > + virReportError(VIR_ERR_XML_ERROR, "%s",
> > > + _("missing 'namespace' attribute to disk source"));
> > > + return -1;
> > > + }
> > > +
> > > + if (virStrToLong_ul(namespace, NULL, 10, &nvme->namespace) < 0) {
> > > + virReportError(VIR_ERR_XML_ERROR,
> > > + _("malformed namespace '%s'"),
> > > + namespace);
> > > + return -1;
> > > + }
> > > +
> > > + /* NVMe namespaces start from 1 */
> > > + if (nvme->namespace == 0) {
> > > + virReportError(VIR_ERR_XML_ERROR, "%s",
> > > + _("NVMe namespace can't be zero"));
> > > + return -1;
> > > + }
> > > +
> > > + if ((managed = virXMLPropString(node, "managed"))) {
> > > + if ((nvme->managed = virTristateBoolTypeFromString(managed)) <= 0) {
> > > + virReportError(VIR_ERR_XML_ERROR,
> > > + _("malformed managed value '%s'"),
> > > + managed);
> > > + return -1;
> > > + }
> > > + }
> > > +
> > > + if (!(address = virXPathNode("./address", ctxt))) {
> > > + virReportError(VIR_ERR_XML_ERROR, "%s",
> > > + _("NVMe disk source is missing address"));
> > > + return -1;
> > > + }
> >
> > I'm displeased that this is yet another function adding validation in
> > the parser. You don't make the status quo any worse though so this is
> > not a request to change it.
>
> What validation do you mean? namespace != 0 check? Well, that stems straight
> from NVMe specs, so it is completely independent of any driver.
> Or do you mean this !address check? Well, it's needed later in the parsing.
Yes, but that stuff still does not have to be intermixed in the parser
code. It's a pre-existing mess though.
>
> >
> > > +
> > > + if (virPCIDeviceAddressParseXML(address, &nvme->pciAddr) < 0)
> > > + return -1;
> > > +
> > > + VIR_STEAL_PTR(src->nvme, nvme);
> > > + return 0;
> > > +}
> > > +
> > > +
> > > static int
> > > virDomainDiskSourcePRParse(xmlNodePtr node,
> > > xmlXPathContextPtr ctxt,
> >
> > [...]
> >
> > > diff --git a/src/qemu/qemu_migration.c b/src/qemu/qemu_migration.c
> > > index 2436f5051b..87adccab3d 100644
> > > --- a/src/qemu/qemu_migration.c
> > > +++ b/src/qemu/qemu_migration.c
> >
> > Missing change to 'qemuMigrationSrcIsSafe' to reject VMs containing NVMe
> > disks not having shared source.
>
> A NVMe disk can't be shared. It's even explicitly denied in the validation
> callback. The reason is that there is no way to share a single PCI device
> with multiple domains.
I meant that the NVMe disk is NOT available on the destination of the
migration. That means that 'qemuMigrationSrcIsSafe' must reject it as
not having a shared storage (note that "shared" here has a different
conotation as <shareable/>, just look at he named function).
>
> But this is a good point. I'll probably put it into a different commt
> though. Even though I'm changing some parts of qemu driver here it's only
> because of the way we handle switch() with enums.
>
> >
> > Plus that function should probably check the full backing chain rather
> > than the top element only.
>
> Pre-existing, but I can try to fix it. Okay.
-------------- next part --------------
A non-text attachment was scrubbed...
Name: signature.asc
Type: application/pgp-signature
Size: 833 bytes
Desc: not available
URL: <http://listman.redhat.com/archives/libvir-list/attachments/20190717/72482e22/attachment-0001.sig>
More information about the libvir-list
mailing list