mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-03-20 06:50:22 +03:00
qemu: Pass correct qemuCaps to virDomainDefParseNode
Since qemuDomainDefPostParse callback requires qemuCaps, we need to make sure it gets the capabilities stored in the domain's private data if the domain is running. Passing NULL may cause QEMU capabilities probing to be triggered in case QEMU binary changed in the meantime. When this happens while a running domain object is locked, QMP event delivered to the domain before QEMU capabilities probing finishes will deadlock the event loop. Several general snapshot and checkpoint APIs were lazily passing NULL as the parseOpaque pointer instead of letting their callers pass the right data. This patch fixes all paths leading to virDomainDefParseNode. Signed-off-by: Jiri Denemark <jdenemar@redhat.com> Reviewed-by: Michal Privoznik <mprivozn@redhat.com>
This commit is contained in:
parent
c90fb5a828
commit
577a1f98fc
@ -128,6 +128,7 @@ static virDomainCheckpointDefPtr
|
|||||||
virDomainCheckpointDefParse(xmlXPathContextPtr ctxt,
|
virDomainCheckpointDefParse(xmlXPathContextPtr ctxt,
|
||||||
virCapsPtr caps,
|
virCapsPtr caps,
|
||||||
virDomainXMLOptionPtr xmlopt,
|
virDomainXMLOptionPtr xmlopt,
|
||||||
|
void *parseOpaque,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
virDomainCheckpointDefPtr ret = NULL;
|
virDomainCheckpointDefPtr ret = NULL;
|
||||||
@ -174,7 +175,7 @@ virDomainCheckpointDefParse(xmlXPathContextPtr ctxt,
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
def->parent.dom = virDomainDefParseNode(ctxt->node->doc, domainNode,
|
def->parent.dom = virDomainDefParseNode(ctxt->node->doc, domainNode,
|
||||||
caps, xmlopt, NULL,
|
caps, xmlopt, parseOpaque,
|
||||||
domainflags);
|
domainflags);
|
||||||
if (!def->parent.dom)
|
if (!def->parent.dom)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -207,6 +208,7 @@ virDomainCheckpointDefParseNode(xmlDocPtr xml,
|
|||||||
xmlNodePtr root,
|
xmlNodePtr root,
|
||||||
virCapsPtr caps,
|
virCapsPtr caps,
|
||||||
virDomainXMLOptionPtr xmlopt,
|
virDomainXMLOptionPtr xmlopt,
|
||||||
|
void *parseOpaque,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
xmlXPathContextPtr ctxt = NULL;
|
xmlXPathContextPtr ctxt = NULL;
|
||||||
@ -234,7 +236,7 @@ virDomainCheckpointDefParseNode(xmlDocPtr xml,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctxt->node = root;
|
ctxt->node = root;
|
||||||
def = virDomainCheckpointDefParse(ctxt, caps, xmlopt, flags);
|
def = virDomainCheckpointDefParse(ctxt, caps, xmlopt, parseOpaque, flags);
|
||||||
cleanup:
|
cleanup:
|
||||||
xmlXPathFreeContext(ctxt);
|
xmlXPathFreeContext(ctxt);
|
||||||
return def;
|
return def;
|
||||||
@ -244,6 +246,7 @@ virDomainCheckpointDefPtr
|
|||||||
virDomainCheckpointDefParseString(const char *xmlStr,
|
virDomainCheckpointDefParseString(const char *xmlStr,
|
||||||
virCapsPtr caps,
|
virCapsPtr caps,
|
||||||
virDomainXMLOptionPtr xmlopt,
|
virDomainXMLOptionPtr xmlopt,
|
||||||
|
void *parseOpaque,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
virDomainCheckpointDefPtr ret = NULL;
|
virDomainCheckpointDefPtr ret = NULL;
|
||||||
@ -253,7 +256,7 @@ virDomainCheckpointDefParseString(const char *xmlStr,
|
|||||||
if ((xml = virXMLParse(NULL, xmlStr, _("(domain_checkpoint)")))) {
|
if ((xml = virXMLParse(NULL, xmlStr, _("(domain_checkpoint)")))) {
|
||||||
xmlKeepBlanksDefault(keepBlanksDefault);
|
xmlKeepBlanksDefault(keepBlanksDefault);
|
||||||
ret = virDomainCheckpointDefParseNode(xml, xmlDocGetRootElement(xml),
|
ret = virDomainCheckpointDefParseNode(xml, xmlDocGetRootElement(xml),
|
||||||
caps, xmlopt, flags);
|
caps, xmlopt, parseOpaque, flags);
|
||||||
xmlFreeDoc(xml);
|
xmlFreeDoc(xml);
|
||||||
}
|
}
|
||||||
xmlKeepBlanksDefault(keepBlanksDefault);
|
xmlKeepBlanksDefault(keepBlanksDefault);
|
||||||
|
@ -75,6 +75,7 @@ virDomainCheckpointDefPtr
|
|||||||
virDomainCheckpointDefParseString(const char *xmlStr,
|
virDomainCheckpointDefParseString(const char *xmlStr,
|
||||||
virCapsPtr caps,
|
virCapsPtr caps,
|
||||||
virDomainXMLOptionPtr xmlopt,
|
virDomainXMLOptionPtr xmlopt,
|
||||||
|
void *parseOpaque,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
|
|
||||||
virDomainCheckpointDefPtr
|
virDomainCheckpointDefPtr
|
||||||
|
@ -228,6 +228,7 @@ static virDomainSnapshotDefPtr
|
|||||||
virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
|
virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
|
||||||
virCapsPtr caps,
|
virCapsPtr caps,
|
||||||
virDomainXMLOptionPtr xmlopt,
|
virDomainXMLOptionPtr xmlopt,
|
||||||
|
void *parseOpaque,
|
||||||
bool *current,
|
bool *current,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
@ -303,7 +304,8 @@ virDomainSnapshotDefParse(xmlXPathContextPtr ctxt,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
def->parent.dom = virDomainDefParseNode(ctxt->node->doc, domainNode,
|
def->parent.dom = virDomainDefParseNode(ctxt->node->doc, domainNode,
|
||||||
caps, xmlopt, NULL, domainflags);
|
caps, xmlopt, parseOpaque,
|
||||||
|
domainflags);
|
||||||
if (!def->parent.dom)
|
if (!def->parent.dom)
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
} else {
|
} else {
|
||||||
@ -413,6 +415,7 @@ virDomainSnapshotDefParseNode(xmlDocPtr xml,
|
|||||||
xmlNodePtr root,
|
xmlNodePtr root,
|
||||||
virCapsPtr caps,
|
virCapsPtr caps,
|
||||||
virDomainXMLOptionPtr xmlopt,
|
virDomainXMLOptionPtr xmlopt,
|
||||||
|
void *parseOpaque,
|
||||||
bool *current,
|
bool *current,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
@ -443,7 +446,7 @@ virDomainSnapshotDefParseNode(xmlDocPtr xml,
|
|||||||
}
|
}
|
||||||
|
|
||||||
ctxt->node = root;
|
ctxt->node = root;
|
||||||
def = virDomainSnapshotDefParse(ctxt, caps, xmlopt, current, flags);
|
def = virDomainSnapshotDefParse(ctxt, caps, xmlopt, parseOpaque, current, flags);
|
||||||
cleanup:
|
cleanup:
|
||||||
xmlXPathFreeContext(ctxt);
|
xmlXPathFreeContext(ctxt);
|
||||||
return def;
|
return def;
|
||||||
@ -453,6 +456,7 @@ virDomainSnapshotDefPtr
|
|||||||
virDomainSnapshotDefParseString(const char *xmlStr,
|
virDomainSnapshotDefParseString(const char *xmlStr,
|
||||||
virCapsPtr caps,
|
virCapsPtr caps,
|
||||||
virDomainXMLOptionPtr xmlopt,
|
virDomainXMLOptionPtr xmlopt,
|
||||||
|
void *parseOpaque,
|
||||||
bool *current,
|
bool *current,
|
||||||
unsigned int flags)
|
unsigned int flags)
|
||||||
{
|
{
|
||||||
@ -463,7 +467,8 @@ virDomainSnapshotDefParseString(const char *xmlStr,
|
|||||||
if ((xml = virXMLParse(NULL, xmlStr, _("(domain_snapshot)")))) {
|
if ((xml = virXMLParse(NULL, xmlStr, _("(domain_snapshot)")))) {
|
||||||
xmlKeepBlanksDefault(keepBlanksDefault);
|
xmlKeepBlanksDefault(keepBlanksDefault);
|
||||||
ret = virDomainSnapshotDefParseNode(xml, xmlDocGetRootElement(xml),
|
ret = virDomainSnapshotDefParseNode(xml, xmlDocGetRootElement(xml),
|
||||||
caps, xmlopt, current, flags);
|
caps, xmlopt, parseOpaque,
|
||||||
|
current, flags);
|
||||||
xmlFreeDoc(xml);
|
xmlFreeDoc(xml);
|
||||||
}
|
}
|
||||||
xmlKeepBlanksDefault(keepBlanksDefault);
|
xmlKeepBlanksDefault(keepBlanksDefault);
|
||||||
|
@ -106,12 +106,14 @@ unsigned int virDomainSnapshotFormatConvertXMLFlags(unsigned int flags);
|
|||||||
virDomainSnapshotDefPtr virDomainSnapshotDefParseString(const char *xmlStr,
|
virDomainSnapshotDefPtr virDomainSnapshotDefParseString(const char *xmlStr,
|
||||||
virCapsPtr caps,
|
virCapsPtr caps,
|
||||||
virDomainXMLOptionPtr xmlopt,
|
virDomainXMLOptionPtr xmlopt,
|
||||||
|
void *parseOpaque,
|
||||||
bool *current,
|
bool *current,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
virDomainSnapshotDefPtr virDomainSnapshotDefParseNode(xmlDocPtr xml,
|
virDomainSnapshotDefPtr virDomainSnapshotDefParseNode(xmlDocPtr xml,
|
||||||
xmlNodePtr root,
|
xmlNodePtr root,
|
||||||
virCapsPtr caps,
|
virCapsPtr caps,
|
||||||
virDomainXMLOptionPtr xmlopt,
|
virDomainXMLOptionPtr xmlopt,
|
||||||
|
void *parseOpaque,
|
||||||
bool *current,
|
bool *current,
|
||||||
unsigned int flags);
|
unsigned int flags);
|
||||||
virDomainSnapshotDefPtr virDomainSnapshotDefNew(void);
|
virDomainSnapshotDefPtr virDomainSnapshotDefNew(void);
|
||||||
|
@ -4117,7 +4117,7 @@ esxDomainSnapshotCreateXML(virDomainPtr domain, const char *xmlDesc,
|
|||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
def = virDomainSnapshotDefParseString(xmlDesc, priv->caps,
|
def = virDomainSnapshotDefParseString(xmlDesc, priv->caps,
|
||||||
priv->xmlopt, NULL, parse_flags);
|
priv->xmlopt, NULL, NULL, parse_flags);
|
||||||
|
|
||||||
if (!def)
|
if (!def)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -464,8 +464,12 @@ qemuDomainSnapshotLoad(virDomainObjPtr vm,
|
|||||||
int ret = -1;
|
int ret = -1;
|
||||||
virCapsPtr caps = NULL;
|
virCapsPtr caps = NULL;
|
||||||
int direrr;
|
int direrr;
|
||||||
|
qemuDomainObjPrivatePtr priv;
|
||||||
|
|
||||||
virObjectLock(vm);
|
virObjectLock(vm);
|
||||||
|
|
||||||
|
priv = vm->privateData;
|
||||||
|
|
||||||
if (virAsprintf(&snapDir, "%s/%s", baseDir, vm->def->name) < 0) {
|
if (virAsprintf(&snapDir, "%s/%s", baseDir, vm->def->name) < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Failed to allocate memory for "
|
_("Failed to allocate memory for "
|
||||||
@ -504,7 +508,8 @@ qemuDomainSnapshotLoad(virDomainObjPtr vm,
|
|||||||
}
|
}
|
||||||
|
|
||||||
def = virDomainSnapshotDefParseString(xmlStr, caps,
|
def = virDomainSnapshotDefParseString(xmlStr, caps,
|
||||||
qemu_driver->xmlopt, &cur,
|
qemu_driver->xmlopt,
|
||||||
|
priv->qemuCaps, &cur,
|
||||||
flags);
|
flags);
|
||||||
if (def == NULL) {
|
if (def == NULL) {
|
||||||
/* Nothing we can do here, skip this one */
|
/* Nothing we can do here, skip this one */
|
||||||
@ -579,8 +584,11 @@ qemuDomainCheckpointLoad(virDomainObjPtr vm,
|
|||||||
int ret = -1;
|
int ret = -1;
|
||||||
virCapsPtr caps = NULL;
|
virCapsPtr caps = NULL;
|
||||||
int direrr;
|
int direrr;
|
||||||
|
qemuDomainObjPrivatePtr priv;
|
||||||
|
|
||||||
virObjectLock(vm);
|
virObjectLock(vm);
|
||||||
|
priv = vm->privateData;
|
||||||
|
|
||||||
if (virAsprintf(&chkDir, "%s/%s", baseDir, vm->def->name) < 0) {
|
if (virAsprintf(&chkDir, "%s/%s", baseDir, vm->def->name) < 0) {
|
||||||
virReportError(VIR_ERR_INTERNAL_ERROR,
|
virReportError(VIR_ERR_INTERNAL_ERROR,
|
||||||
_("Failed to allocate memory for "
|
_("Failed to allocate memory for "
|
||||||
@ -620,6 +628,7 @@ qemuDomainCheckpointLoad(virDomainObjPtr vm,
|
|||||||
|
|
||||||
def = virDomainCheckpointDefParseString(xmlStr, caps,
|
def = virDomainCheckpointDefParseString(xmlStr, caps,
|
||||||
qemu_driver->xmlopt,
|
qemu_driver->xmlopt,
|
||||||
|
priv->qemuCaps,
|
||||||
flags);
|
flags);
|
||||||
if (!def || virDomainCheckpointAlignDisks(def) < 0) {
|
if (!def || virDomainCheckpointAlignDisks(def) < 0) {
|
||||||
/* Nothing we can do here, skip this one */
|
/* Nothing we can do here, skip this one */
|
||||||
@ -15804,6 +15813,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
priv = vm->privateData;
|
||||||
cfg = virQEMUDriverGetConfig(driver);
|
cfg = virQEMUDriverGetConfig(driver);
|
||||||
|
|
||||||
if (virDomainSnapshotCreateXMLEnsureACL(domain->conn, vm->def, flags) < 0)
|
if (virDomainSnapshotCreateXMLEnsureACL(domain->conn, vm->def, flags) < 0)
|
||||||
@ -15831,7 +15841,7 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
|
|||||||
parse_flags |= VIR_DOMAIN_SNAPSHOT_PARSE_VALIDATE;
|
parse_flags |= VIR_DOMAIN_SNAPSHOT_PARSE_VALIDATE;
|
||||||
|
|
||||||
if (!(def = virDomainSnapshotDefParseString(xmlDesc, caps, driver->xmlopt,
|
if (!(def = virDomainSnapshotDefParseString(xmlDesc, caps, driver->xmlopt,
|
||||||
NULL, parse_flags)))
|
priv->qemuCaps, NULL, parse_flags)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
/* reject snapshot names containing slashes or starting with dot as
|
/* reject snapshot names containing slashes or starting with dot as
|
||||||
@ -15908,8 +15918,6 @@ qemuDomainSnapshotCreateXML(virDomainPtr domain,
|
|||||||
|
|
||||||
qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE);
|
qemuDomainObjSetAsyncJobMask(vm, QEMU_JOB_NONE);
|
||||||
|
|
||||||
priv = vm->privateData;
|
|
||||||
|
|
||||||
if (redefine) {
|
if (redefine) {
|
||||||
if (virDomainSnapshotRedefinePrep(domain, vm, &def, &snap,
|
if (virDomainSnapshotRedefinePrep(domain, vm, &def, &snap,
|
||||||
driver->xmlopt,
|
driver->xmlopt,
|
||||||
@ -17182,7 +17190,7 @@ qemuDomainCheckpointCreateXML(virDomainPtr domain,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(def = virDomainCheckpointDefParseString(xmlDesc, caps, driver->xmlopt,
|
if (!(def = virDomainCheckpointDefParseString(xmlDesc, caps, driver->xmlopt,
|
||||||
parse_flags)))
|
priv->qemuCaps, parse_flags)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
/* Unlike snapshots, the RNG schema already ensured a sane filename. */
|
/* Unlike snapshots, the RNG schema already ensured a sane filename. */
|
||||||
|
|
||||||
|
@ -902,6 +902,7 @@ testParseDomainSnapshots(testDriverPtr privconn,
|
|||||||
def = virDomainSnapshotDefParseNode(ctxt->doc, node,
|
def = virDomainSnapshotDefParseNode(ctxt->doc, node,
|
||||||
privconn->caps,
|
privconn->caps,
|
||||||
privconn->xmlopt,
|
privconn->xmlopt,
|
||||||
|
NULL,
|
||||||
&cur,
|
&cur,
|
||||||
VIR_DOMAIN_SNAPSHOT_PARSE_DISKS |
|
VIR_DOMAIN_SNAPSHOT_PARSE_DISKS |
|
||||||
VIR_DOMAIN_SNAPSHOT_PARSE_INTERNAL |
|
VIR_DOMAIN_SNAPSHOT_PARSE_INTERNAL |
|
||||||
@ -8207,7 +8208,7 @@ testDomainSnapshotCreateXML(virDomainPtr domain,
|
|||||||
if (!(def = virDomainSnapshotDefParseString(xmlDesc,
|
if (!(def = virDomainSnapshotDefParseString(xmlDesc,
|
||||||
privconn->caps,
|
privconn->caps,
|
||||||
privconn->xmlopt,
|
privconn->xmlopt,
|
||||||
NULL,
|
NULL, NULL,
|
||||||
parse_flags)))
|
parse_flags)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -8668,7 +8669,7 @@ testDomainCheckpointCreateXML(virDomainPtr domain,
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (!(def = virDomainCheckpointDefParseString(xmlDesc, privconn->caps,
|
if (!(def = virDomainCheckpointDefParseString(xmlDesc, privconn->caps,
|
||||||
privconn->xmlopt,
|
privconn->xmlopt, NULL,
|
||||||
parse_flags)))
|
parse_flags)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
|
@ -5505,7 +5505,7 @@ vboxDomainSnapshotCreateXML(virDomainPtr dom,
|
|||||||
parse_flags |= VIR_DOMAIN_SNAPSHOT_PARSE_VALIDATE;
|
parse_flags |= VIR_DOMAIN_SNAPSHOT_PARSE_VALIDATE;
|
||||||
|
|
||||||
if (!(def = virDomainSnapshotDefParseString(xmlDesc, data->caps,
|
if (!(def = virDomainSnapshotDefParseString(xmlDesc, data->caps,
|
||||||
data->xmlopt, NULL,
|
data->xmlopt, NULL, NULL,
|
||||||
parse_flags)))
|
parse_flags)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
@ -6949,7 +6949,7 @@ vboxDomainSnapshotDeleteMetadataOnly(virDomainSnapshotPtr snapshot)
|
|||||||
}
|
}
|
||||||
def = virDomainSnapshotDefParseString(defXml,
|
def = virDomainSnapshotDefParseString(defXml,
|
||||||
data->caps,
|
data->caps,
|
||||||
data->xmlopt, NULL,
|
data->xmlopt, NULL, NULL,
|
||||||
VIR_DOMAIN_SNAPSHOT_PARSE_DISKS |
|
VIR_DOMAIN_SNAPSHOT_PARSE_DISKS |
|
||||||
VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE);
|
VIR_DOMAIN_SNAPSHOT_PARSE_REDEFINE);
|
||||||
if (!def) {
|
if (!def) {
|
||||||
|
@ -54,7 +54,7 @@ testCompareXMLToXMLFiles(const char *inxml,
|
|||||||
return -1;
|
return -1;
|
||||||
|
|
||||||
if (!(def = virDomainCheckpointDefParseString(inXmlData, driver.caps,
|
if (!(def = virDomainCheckpointDefParseString(inXmlData, driver.caps,
|
||||||
driver.xmlopt,
|
driver.xmlopt, NULL,
|
||||||
parseflags))) {
|
parseflags))) {
|
||||||
if (flags & TEST_INVALID)
|
if (flags & TEST_INVALID)
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -55,7 +55,7 @@ testCompareXMLToXMLFiles(const char *inxml,
|
|||||||
goto cleanup;
|
goto cleanup;
|
||||||
|
|
||||||
if (!(def = virDomainSnapshotDefParseString(inXmlData, driver.caps,
|
if (!(def = virDomainSnapshotDefParseString(inXmlData, driver.caps,
|
||||||
driver.xmlopt, &cur,
|
driver.xmlopt, NULL, &cur,
|
||||||
parseflags)))
|
parseflags)))
|
||||||
goto cleanup;
|
goto cleanup;
|
||||||
if (cur) {
|
if (cur) {
|
||||||
|
Loading…
x
Reference in New Issue
Block a user