diff --git a/src/qemu/qemu_domain.c b/src/qemu/qemu_domain.c index c0b32afc2e9c83b712362603d5b63729d73fca1b..1be6cfccfff89ffc5e052c031cee262465fe51bf 100644 --- a/src/qemu/qemu_domain.c +++ b/src/qemu/qemu_domain.c @@ -62,6 +62,7 @@ #include "locking/domain_lock.h" #include "virdomainsnapshotobjlist.h" #include "virdomaincheckpointobjlist.h" +#include "backup_conf.h" #ifdef MAJOR_IN_MKDEV # include @@ -2236,6 +2237,9 @@ qemuDomainObjPrivateDataClear(qemuDomainObjPrivatePtr priv) priv->pflash0 = NULL; virObjectUnref(priv->pflash1); priv->pflash1 = NULL; + + virDomainBackupDefFree(priv->backup); + priv->backup = NULL; } @@ -2643,6 +2647,26 @@ qemuDomainObjPrivateXMLFormatBlockjobs(virBufferPtr buf, } +static int +qemuDomainObjPrivateXMLFormatBackups(virBufferPtr buf, + virDomainObjPtr vm) +{ + qemuDomainObjPrivatePtr priv = vm->privateData; + g_auto(virBuffer) attrBuf = VIR_BUFFER_INITIALIZER; + g_auto(virBuffer) childBuf = VIR_BUFFER_INIT_CHILD(buf); + + if (!virQEMUCapsGet(priv->qemuCaps, QEMU_CAPS_INCREMENTAL_BACKUP)) + return 0; + + if (priv->backup && + virDomainBackupDefFormat(&childBuf, priv->backup, true) < 0) + return -1; + + virXMLFormatElement(buf, "backups", &attrBuf, &childBuf); + return 0; +} + + void qemuDomainObjPrivateXMLFormatAllowReboot(virBufferPtr buf, virTristateBool allowReboot) @@ -2938,6 +2962,9 @@ qemuDomainObjPrivateXMLFormat(virBufferPtr buf, virBufferAsprintf(buf, "%i\n", priv->agentTimeout); + if (qemuDomainObjPrivateXMLFormatBackups(buf, vm) < 0) + return -1; + return 0; } @@ -3314,6 +3341,34 @@ qemuDomainObjPrivateXMLParseBlockjobs(virDomainObjPtr vm, } +static int +qemuDomainObjPrivateXMLParseBackups(qemuDomainObjPrivatePtr priv, + xmlXPathContextPtr ctxt) +{ + g_autofree xmlNodePtr *nodes = NULL; + ssize_t nnodes = 0; + + if ((nnodes = virXPathNodeSet("./backups/domainbackup", ctxt, &nodes)) < 0) + return -1; + + if (nnodes > 1) { + virReportError(VIR_ERR_INTERNAL_ERROR, "%s", + _("only one backup job is supported")); + return -1; + } + + if (nnodes == 0) + return 0; + + if (!(priv->backup = virDomainBackupDefParseNode(ctxt->doc, nodes[0], + priv->driver->xmlopt, + VIR_DOMAIN_BACKUP_PARSE_INTERNAL))) + return -1; + + return 0; +} + + int qemuDomainObjPrivateXMLParseAllowReboot(xmlXPathContextPtr ctxt, virTristateBool *allowReboot) @@ -3743,6 +3798,9 @@ qemuDomainObjPrivateXMLParse(xmlXPathContextPtr ctxt, if (qemuDomainObjPrivateXMLParseBlockjobs(vm, priv, ctxt) < 0) goto error; + if (qemuDomainObjPrivateXMLParseBackups(priv, ctxt) < 0) + goto error; + qemuDomainStorageIdReset(priv); if (virXPathULongLong("string(./nodename/@index)", ctxt, &priv->nodenameindex) == -2) { diff --git a/src/qemu/qemu_domain.h b/src/qemu/qemu_domain.h index 7c752abc8037c6bcd9c236a4e8099a21009a2a8b..4c47b62b589002088cfea41aa2c1d953c0bd009f 100644 --- a/src/qemu/qemu_domain.h +++ b/src/qemu/qemu_domain.h @@ -414,6 +414,9 @@ struct _qemuDomainObjPrivate { * commandline for pflash drives. */ virStorageSourcePtr pflash0; virStorageSourcePtr pflash1; + + /* running backup job */ + virDomainBackupDefPtr backup; }; #define QEMU_DOMAIN_PRIVATE(vm) \