
On 3/27/19 9:01 AM, Ján Tomko wrote:
On Wed, Mar 27, 2019 at 05:10:40AM -0500, Eric Blake wrote:
Add a new file checkpoint_conf.c that performs the translation to and from new XML describing a checkpoint. The code shares a common base class with snapshots, since a checkpoint similarly represents the domain state at a moment in time. Add some basic testing of round trip XML handling through the new code.
+static virDomainCheckpointDefPtr +virDomainCheckpointDefParse(xmlXPathContextPtr ctxt, + virCapsPtr caps, + virDomainXMLOptionPtr xmlopt, + bool *current, + unsigned int flags) +{ + virDomainCheckpointDefPtr def = NULL; + virDomainCheckpointDefPtr ret = NULL; + xmlNodePtr *nodes = NULL; + size_t i; + int n; + char *creation = NULL; + struct timeval tv; + int active; + char *tmp; + + if (VIR_ALLOC(def) < 0) + goto cleanup; + + gettimeofday(&tv, NULL); +
Eww. I'd expect an XML parsing function to behave the same regardless of the time of day.
For domains, we'd put this kind of stuff into a post-parse function.
Ah, life has improved since I wrote snapshots. This is verbatim copy-and-paste from what snapshots currently do, but I agree that it would be nicer to first fix snapshots to switch to post-parse functions and then copy that fixed approach here (it would also make writing tests for this easier - I was struggling for how to write a meaningful test that does not just filter out all lines containing a dynamic timestamp - but if the test can supply its own post-parse hooks, we can provide a reproducible result).
+ + if (flags & VIR_DOMAIN_CHECKPOINT_PARSE_REDEFINE) { + if (virXPathLongLong("string(./creationTime)", ctxt, + &def->common.creationTime) < 0) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing creationTime from existing checkpoint")); + goto cleanup; + } + + def->common.parent = virXPathString("string(./parent/name)", ctxt); +
+ if ((tmp = virXPathString("string(./domain/@type)", ctxt))) {
tmp is freed right away and the error reported on else is duplicate with the one a few lines below.
+ int domainflags = VIR_DOMAIN_DEF_PARSE_INACTIVE | + VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE; + xmlNodePtr domainNode = virXPathNode("./domain", ctxt); + + VIR_FREE(tmp); + if (!domainNode) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing domain in checkpoint")); + goto cleanup; + } + def->common.dom = virDomainDefParseNode(ctxt->node->doc, domainNode, + caps, xmlopt, NULL, + domainflags); + if (!def->common.dom) + goto cleanup; + } else { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("missing domain in checkpoint redefine")); + goto cleanup; + }
Yeah, there's probably a way to write that more succinctly. The snapshot code is hairier because it DOES permit an omitted <domain> subelement for back-compat reasons, but I didn't want to copy that here. -- Eric Blake, Principal Software Engineer Red Hat, Inc. +1-919-301-3226 Virtualization: qemu.org | libvirt.org