[libvirt] [PATCH v2 03/11] Add virXMLValidateAgainstSchema helper method

Daniel P. Berrange berrange at redhat.com
Mon Jan 12 16:03:33 UTC 2015


On Mon, Jan 12, 2015 at 04:55:59PM +0100, Jiri Denemark wrote:
> On Thu, Jan 08, 2015 at 15:48:14 +0000, Daniel Berrange wrote:
> > Add a helper method that can validate an XML document against
> > an RNG schema
> > ---
> >  include/libvirt/virterror.h |  1 +
> >  src/internal.h              |  4 +++
> >  src/libvirt_private.syms    |  1 +
> >  src/util/virerror.c         |  6 ++++
> >  src/util/virxml.c           | 74 +++++++++++++++++++++++++++++++++++++++++++++
> >  src/util/virxml.h           |  5 +++
> >  6 files changed, 91 insertions(+)
> > 
> > diff --git a/include/libvirt/virterror.h b/include/libvirt/virterror.h
> > index 85dd74c..3d3d80a 100644
> > --- a/include/libvirt/virterror.h
> > +++ b/include/libvirt/virterror.h
> > @@ -304,6 +304,7 @@ typedef enum {
> >      VIR_ERR_STORAGE_VOL_EXIST = 90,     /* the storage vol already exists */
> >      VIR_ERR_CPU_INCOMPATIBLE = 91,      /* given CPU is incompatible with host
> >                                             CPU*/
> > +    VIR_ERR_XML_INVALID_SCHEMA = 92,    /* XML document doens't validate against schema */
> >  } virErrorNumber;
> >  
> >  /**
> > diff --git a/src/internal.h b/src/internal.h
> > index 30445c1..9855c49 100644
> > --- a/src/internal.h
> > +++ b/src/internal.h
> > @@ -234,11 +234,15 @@
> >  #  define VIR_WARNINGS_NO_CAST_ALIGN \
> >      _Pragma ("GCC diagnostic push") \
> >      _Pragma ("GCC diagnostic ignored \"-Wcast-align\"")
> > +#  define VIR_WARNINGS_NO_PRINTF \
> > +    _Pragma ("GCC diagnostic push") \
> > +    _Pragma ("GCC diagnostic ignored \"-Wsuggest-attribute=format\"")
> >  
> >  #  define VIR_WARNINGS_RESET \
> >      _Pragma ("GCC diagnostic pop")
> >  # else
> >  #  define VIR_WARNINGS_NO_CAST_ALIGN
> > +#  define VIR_WARNINGS_NO_PRINTF
> >  #  define VIR_WARNINGS_RESET
> >  # endif
> >  
> > diff --git a/src/libvirt_private.syms b/src/libvirt_private.syms
> > index fb5d003..a376e2d 100644
> > --- a/src/libvirt_private.syms
> > +++ b/src/libvirt_private.syms
> > @@ -2251,6 +2251,7 @@ virXMLParseHelper;
> >  virXMLPickShellSafeComment;
> >  virXMLPropString;
> >  virXMLSaveFile;
> > +virXMLValidateAgainstSchema;
> >  virXPathBoolean;
> >  virXPathInt;
> >  virXPathLong;
> > diff --git a/src/util/virerror.c b/src/util/virerror.c
> > index 4aa6d04..f5d7f54 100644
> > --- a/src/util/virerror.c
> > +++ b/src/util/virerror.c
> > @@ -1285,6 +1285,12 @@ virErrorMsg(virErrorNumber error, const char *info)
> >              else
> >                  errmsg = _("the CPU is incompatible with host CPU: %s");
> >              break;
> > +        case VIR_ERR_XML_INVALID_SCHEMA:
> > +            if (info == NULL)
> > +                errmsg = _("XML document failed to validate against schema");
> > +            else
> > +                errmsg = _("XML document failed to validate against schema: %s");
> > +            break;
> >      }
> >      return errmsg;
> >  }
> > diff --git a/src/util/virxml.c b/src/util/virxml.c
> > index 93f8590..f2c63aa 100644
> > --- a/src/util/virxml.c
> > +++ b/src/util/virxml.c
> > @@ -1082,3 +1082,77 @@ virXMLInjectNamespace(xmlNodePtr node,
> >  
> >      return 0;
> >  }
> > +
> > +static void catchRNGError(void *ctx,
> > +                          const char *msg,
> > +                          ...)
> > +{
> > +    virBufferPtr buf = ctx;
> > +    va_list args;
> > +
> > +    va_start(args, msg);
> > +    VIR_WARNINGS_NO_PRINTF;
> > +    virBufferVasprintf(buf, msg, args);
> > +    VIR_WARNINGS_RESET;
> > +    va_end(args);
> > +}
> > +
> > +
> > +static void ignoreRNGError(void *ctx ATTRIBUTE_UNUSED,
> > +                           const char *msg ATTRIBUTE_UNUSED,
> > +                           ...)
> > +{}
> > +
> > +
> > +int
> > +virXMLValidateAgainstSchema(const char *schemafile,
> > +                            xmlDocPtr doc)
> > +{
> > +    xmlRelaxNGParserCtxtPtr rngParser = NULL;
> > +    xmlRelaxNGPtr rng = NULL;
> > +    xmlRelaxNGValidCtxtPtr rngValid = NULL;
> > +    virBuffer buf = VIR_BUFFER_INITIALIZER;
> > +    int ret = -1;
> > +
> > +    if (!(rngParser = xmlRelaxNGNewParserCtxt(schemafile))) {
> > +        virReportError(VIR_ERR_INTERNAL_ERROR,
> > +                       _("Unable to create RNG parser for %s"),
> > +                       schemafile);
> > +        goto cleanup;
> > +    }
> > +
> > +    if (!(rng = xmlRelaxNGParse(rngParser))) {
> > +        virReportError(VIR_ERR_INTERNAL_ERROR,
> > +                       _("Unable to parse RNG %s"),
> > +                       schemafile);
> > +        goto cleanup;
> > +    }
> 
> Do xmlRelaxNGNewParserCtxt and xmlRelaxNGParse functions provide any
> usable error messages so that we can report some details about why
> parsing RNG failed? For example, if the schema file is missing,
> unreadable...

Might be able to get something using xmlRelaxNGSetParserErrors, but
i'm fuzzy on just what that does right now. Will check...

Regards,
Daniel
-- 
|: http://berrange.com      -o-    http://www.flickr.com/photos/dberrange/ :|
|: http://libvirt.org              -o-             http://virt-manager.org :|
|: http://autobuild.org       -o-         http://search.cpan.org/~danberr/ :|
|: http://entangle-photo.org       -o-       http://live.gnome.org/gtk-vnc :|




More information about the libvir-list mailing list