[libvirt] [PATCH 06/30] conf: move virt type / os type / arch validation to post-parse

Daniel P. Berrangé berrange at redhat.com
Tue Dec 10 10:57:44 UTC 2019


On Mon, Dec 09, 2019 at 01:21:05PM -0500, Cole Robinson wrote:
> On 12/4/19 9:20 AM, Daniel P. Berrangé wrote:
> > The XML parser currently calls virCapabilitiesDomainDataLookup during
> > parsing to find the domain capabilities matching the triple
> > 
> >   (virt type, os type, arch)
> > 
> > This is, however, bogus with the QEMU driver as it assumes that there
> > is an emulator known to the default driver capabilities that matches
> > this triple. It is entirely possible for the driver to be parsing an
> > XML file with a custom emulator path specified pointing to a binary
> > that doesn't exist in the default driver capabilities.  This will,
> > for example be the case on a RHEL host which only installs the host
> > native emulator to /usr/bin. The user can have built a custom QEMU
> > for non-native arches into $HOME and wish to use that.
> > 
> > Aside from validation, this call is also used to fill in a machine type
> > for the guest if not otherwise specified. Again, this data may be
> > incorrect for the QEMU driver because it is not taking account of
> > the emulator binary that is referenced.
> > 
> > To start fixing this, move the validation to the post-parse callbacks
> > where more intelligent driver specific logic can be applied.
> > 
> > Signed-off-by: Daniel P. Berrangé <berrange at redhat.com>
> > ---
> >  src/bhyve/bhyve_domain.c   |  7 ++++++-
> >  src/conf/capabilities.c    | 17 +++++++++++++++++
> >  src/conf/capabilities.h    |  7 +++++++
> >  src/conf/domain_conf.c     | 19 ++-----------------
> >  src/libvirt_private.syms   |  1 +
> >  src/libxl/libxl_domain.c   |  7 ++++++-
> >  src/lxc/lxc_domain.c       |  5 +++++
> >  src/openvz/openvz_conf.c   |  7 ++++++-
> >  src/phyp/phyp_driver.c     |  9 +++++++--
> >  src/qemu/qemu_domain.c     | 19 +++++++++++++++----
> >  src/vmware/vmware_driver.c |  9 +++++++--
> >  src/vmx/vmx.c              |  9 +++++++--
> >  src/vz/vz_driver.c         |  7 ++++++-
> >  13 files changed, 92 insertions(+), 31 deletions(-)
> > 
> > diff --git a/src/bhyve/bhyve_domain.c b/src/bhyve/bhyve_domain.c
> > index 7d24bb602f..575f141b53 100644
> > --- a/src/bhyve/bhyve_domain.c
> > +++ b/src/bhyve/bhyve_domain.c
> > @@ -74,11 +74,16 @@ bhyveDomainDefNeedsISAController(virDomainDefPtr def)
> >  
> >  static int
> >  bhyveDomainDefPostParse(virDomainDefPtr def,
> > -                        virCapsPtr caps G_GNUC_UNUSED,
> > +                        virCapsPtr caps,
> >                          unsigned int parseFlags G_GNUC_UNUSED,
> >                          void *opaque G_GNUC_UNUSED,
> >                          void *parseOpaque G_GNUC_UNUSED)
> >  {
> > +    if (!virCapabilitiesDomainSupported(caps, def->os.type,
> > +                                        def->os.arch,
> > +                                        def->virtType))
> > +        return -1;
> > +
> >      /* Add an implicit PCI root controller */
> >      if (virDomainDefMaybeAddController(def, VIR_DOMAIN_CONTROLLER_TYPE_PCI, 0,
> >                                         VIR_DOMAIN_CONTROLLER_MODEL_PCI_ROOT) < 0)
> > diff --git a/src/conf/capabilities.c b/src/conf/capabilities.c
> > index ff7d265621..748dd64273 100644
> > --- a/src/conf/capabilities.c
> > +++ b/src/conf/capabilities.c
> > @@ -816,6 +816,23 @@ virCapabilitiesDomainDataLookup(virCapsPtr caps,
> >  }
> >  
> >  
> > +bool
> > +virCapabilitiesDomainSupported(virCapsPtr caps,
> > +                               int ostype,
> > +                               virArch arch,
> > +                               int virttype)
> > +{
> > +    g_autofree virCapsDomainDataPtr capsdata = NULL;
> > +
> > +    capsdata = virCapabilitiesDomainDataLookup(caps, ostype,
> > +                                               arch,
> > +                                               virttype,
> > +                                               NULL, NULL);
> > +
> > +    return capsdata != NULL;
> > +}
> > +
> > +
> >  int
> >  virCapabilitiesAddStoragePool(virCapsPtr caps,
> >                                int poolType)
> > diff --git a/src/conf/capabilities.h b/src/conf/capabilities.h
> > index 8a7137d7eb..c39fe0de08 100644
> > --- a/src/conf/capabilities.h
> > +++ b/src/conf/capabilities.h
> > @@ -309,6 +309,13 @@ virCapabilitiesDomainDataLookup(virCapsPtr caps,
> >                                  const char *emulator,
> >                                  const char *machinetype);
> >  
> > +bool
> > +virCapabilitiesDomainSupported(virCapsPtr caps,
> > +                               int ostype,
> > +                               virArch arch,
> > +                               int domaintype);
> > +
> > +
> >  void
> >  virCapabilitiesClearHostNUMACellCPUTopology(virCapsHostNUMACellCPUPtr cpu,
> >                                              size_t ncpus);
> > diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
> > index 1c2b8f26ed..6abe15f721 100644
> > --- a/src/conf/domain_conf.c
> > +++ b/src/conf/domain_conf.c
> > @@ -19565,14 +19565,11 @@ virDomainCachetuneDefParse(virDomainDefPtr def,
> >  static int
> >  virDomainDefParseCaps(virDomainDefPtr def,
> >                        xmlXPathContextPtr ctxt,
> > -                      virDomainXMLOptionPtr xmlopt,
> > -                      virCapsPtr caps,
> > -                      unsigned int flags)
> > +                      virDomainXMLOptionPtr xmlopt)
> >  {
> >      g_autofree char *virttype = NULL;
> >      g_autofree char *arch = NULL;
> >      g_autofree char *ostype = NULL;
> > -    g_autofree virCapsDomainDataPtr capsdata = NULL;
> >  
> >      virttype = virXPathString("string(./@type)", ctxt);
> >      ostype = virXPathString("string(./os/type[1])", ctxt);
> > @@ -19633,18 +19630,6 @@ virDomainDefParseCaps(virDomainDefPtr def,
> >              def->os.arch = virArchFromHost();
> >      }
> >  
> > -    if (!(capsdata = virCapabilitiesDomainDataLookup(caps, def->os.type,
> > -                                                     def->os.arch,
> > -                                                     def->virtType,
> > -                                                     NULL, NULL))) {
> > -        if (!(flags & VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE))
> > -            return -1;
> > -        virResetLastError();
> > -    } else {
> > -        if (!def->os.machine)
> > -            def->os.machine = g_strdup(capsdata->machinetype);
> > -    }
> > -
> >      return 0;
> >  }
> >  
> 
> This series is a move in the right direction IMO, there's a couple
> issues though.
> 
> We drop the VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE protection here, by
> moving the equivalent into the PostParse callback and not the Validate
> callback. This reintroduces the recurring problem of VMs disappearing on
> libvirt restart, if host capabilities change.
> 
> There is VIR_DOMAIN_DEF_PARSE_ALLOW_POST_PARSE_FAIL, which has different
> behavior, all these error checks would need to 'return 1', but I think
> drivers need specially handling for this so I'm not sure if it's a
> simple change like that.

Oh, I was mislead in my reading of qemuDomainDefPostParse, as I
saw that it already returned error when os.machine is NULL, but
I didn't realize we'd never even be calling qemuDomainDefPostParse
in that case, as the virDomainDefParseCaps() willl have caused it
to be skipped.


> Another issue: other drivers use the machine= setting too, libxl at
> least. This appears to drop filling in a default machine type for them,
> at least at XML parse time.

I thought that was the case too, but I couln't find any functional use
of def->os.machine in any of the other drivers:

$ git grep os.machine | grep -v -E '(qemu|conf)/'
libvirt-domain.c: *      "os.machine" - the machine hardware name as a string
libxl/libxl_conf.c:                        def->os.machine);
libxl/xen_common.c:    def->os.machine = g_strdup(capsdata->machinetype);
vbox/vbox_common.c:    VIR_DEBUG("def->os.machine          %s", def->os.machine);
vz/vz_sdk.c:    if (def->os.machine != NULL || def->os.bootmenu != 0 ||


that libxl_conf.c usage is just an error message

The xen_common.c usage is just when parsing  XM/XL  config files,
so output only.

The vz_sdk.c usage reports error for any non-NULL machine


I guess there is a difference in that if the user does dumpxml for a
libxl guest we've no longer filled in the machine. I can fix that,
but it doesn't look like it'll have a functional effect.

Regards,
Daniel
-- 
|: https://berrange.com      -o-    https://www.flickr.com/photos/dberrange :|
|: https://libvirt.org         -o-            https://fstop138.berrange.com :|
|: https://entangle-photo.org    -o-    https://www.instagram.com/dberrange :|




More information about the libvir-list mailing list