mirror of
https://gitlab.com/libvirt/libvirt.git
synced 2025-01-10 14:57:42 +00:00
conf: Add callbacks that allocate per-def private data
Some drivers use def-specific private data across callbacks (e.g. qemuCaps in the qemu driver). Currently it's mostly allocated in every single callback. This is rather wasteful, given that every single call to the device callback allocates it. The new callback will allocate the data (if not provided externally) and then use it for the VM, address and device post parse callbacks.
This commit is contained in:
parent
03132bf487
commit
e168bc8a72
@ -4675,6 +4675,31 @@ virDomainDeviceDefPostParse(virDomainDeviceDefPtr dev,
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int
|
||||
virDomainDeviceDefPostParseOne(virDomainDeviceDefPtr dev,
|
||||
const virDomainDef *def,
|
||||
virCapsPtr caps,
|
||||
unsigned int flags,
|
||||
virDomainXMLOptionPtr xmlopt)
|
||||
{
|
||||
void *parseOpaque = NULL;
|
||||
int ret;
|
||||
|
||||
if (xmlopt->config.domainPostParseDataAlloc) {
|
||||
if (xmlopt->config.domainPostParseDataAlloc(def, caps, flags,
|
||||
xmlopt->config.priv,
|
||||
&parseOpaque) < 0)
|
||||
return -1;
|
||||
}
|
||||
|
||||
ret = virDomainDeviceDefPostParse(dev, def, caps, flags, xmlopt, parseOpaque);
|
||||
|
||||
if (parseOpaque && xmlopt->config.domainPostParseDataFree)
|
||||
xmlopt->config.domainPostParseDataFree(parseOpaque);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
struct virDomainDefPostParseDeviceIteratorData {
|
||||
virCapsPtr caps;
|
||||
@ -4821,6 +4846,7 @@ virDomainDefPostParse(virDomainDefPtr def,
|
||||
void *parseOpaque)
|
||||
{
|
||||
int ret;
|
||||
bool localParseOpaque = false;
|
||||
struct virDomainDefPostParseDeviceIteratorData data = {
|
||||
.caps = caps,
|
||||
.xmlopt = xmlopt,
|
||||
@ -4837,6 +4863,17 @@ virDomainDefPostParse(virDomainDefPtr def,
|
||||
return ret;
|
||||
}
|
||||
|
||||
if (!data.parseOpaque &&
|
||||
xmlopt->config.domainPostParseDataAlloc) {
|
||||
ret = xmlopt->config.domainPostParseDataAlloc(def, caps, parseFlags,
|
||||
xmlopt->config.priv,
|
||||
&data.parseOpaque);
|
||||
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
localParseOpaque = true;
|
||||
}
|
||||
|
||||
/* this must be done before the hypervisor-specific callback,
|
||||
* in case presence of a controller at a specific index is checked
|
||||
*/
|
||||
@ -4846,9 +4883,9 @@ virDomainDefPostParse(virDomainDefPtr def,
|
||||
if (xmlopt->config.domainPostParseCallback) {
|
||||
ret = xmlopt->config.domainPostParseCallback(def, caps, parseFlags,
|
||||
xmlopt->config.priv,
|
||||
parseOpaque);
|
||||
data.parseOpaque);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
/* iterate the devices */
|
||||
@ -4856,24 +4893,30 @@ virDomainDefPostParse(virDomainDefPtr def,
|
||||
virDomainDefPostParseDeviceIterator,
|
||||
true,
|
||||
&data)) < 0)
|
||||
return ret;
|
||||
goto cleanup;
|
||||
|
||||
|
||||
if ((ret = virDomainDefPostParseInternal(def, &data)) < 0)
|
||||
return ret;
|
||||
goto cleanup;
|
||||
|
||||
if (xmlopt->config.assignAddressesCallback) {
|
||||
ret = xmlopt->config.assignAddressesCallback(def, caps, parseFlags,
|
||||
xmlopt->config.priv,
|
||||
parseOpaque);
|
||||
data.parseOpaque);
|
||||
if (ret < 0)
|
||||
return ret;
|
||||
goto cleanup;
|
||||
}
|
||||
|
||||
if (virDomainDefPostParseCheckFeatures(def, xmlopt) < 0)
|
||||
return -1;
|
||||
if ((ret = virDomainDefPostParseCheckFeatures(def, xmlopt)) < 0)
|
||||
goto cleanup;
|
||||
|
||||
return 0;
|
||||
ret = 0;
|
||||
|
||||
cleanup:
|
||||
if (localParseOpaque && xmlopt->config.domainPostParseDataFree)
|
||||
xmlopt->config.domainPostParseDataFree(data.parseOpaque);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
@ -14679,7 +14722,7 @@ virDomainDeviceDefParse(const char *xmlStr,
|
||||
}
|
||||
|
||||
/* callback to fill driver specific device aspects */
|
||||
if (virDomainDeviceDefPostParse(dev, def, caps, flags, xmlopt, NULL) < 0)
|
||||
if (virDomainDeviceDefPostParseOne(dev, def, caps, flags, xmlopt) < 0)
|
||||
goto error;
|
||||
|
||||
/* validate the configuration */
|
||||
|
@ -2538,6 +2538,13 @@ typedef int (*virDomainDefAssignAddressesCallback)(virDomainDef *def,
|
||||
void *opaque,
|
||||
void *parseOpaque);
|
||||
|
||||
typedef int (*virDomainDefPostParseDataAlloc)(const virDomainDef *def,
|
||||
virCapsPtr caps,
|
||||
unsigned int parseFlags,
|
||||
void *opaque,
|
||||
void **parseOpaque);
|
||||
typedef void (*virDomainDefPostParseDataFree)(void *parseOpaque);
|
||||
|
||||
/* Called in appropriate places where the domain conf parser can return failure
|
||||
* for configurations that were previously accepted. This shall not modify the
|
||||
* config. */
|
||||
@ -2556,9 +2563,11 @@ typedef virDomainDefParserConfig *virDomainDefParserConfigPtr;
|
||||
struct _virDomainDefParserConfig {
|
||||
/* driver domain definition callbacks */
|
||||
virDomainDefPostParseBasicCallback domainPostParseBasicCallback;
|
||||
virDomainDefPostParseDataAlloc domainPostParseDataAlloc;
|
||||
virDomainDefPostParseCallback domainPostParseCallback;
|
||||
virDomainDeviceDefPostParseCallback devicesPostParseCallback;
|
||||
virDomainDefAssignAddressesCallback assignAddressesCallback;
|
||||
virDomainDefPostParseDataFree domainPostParseDataFree;
|
||||
|
||||
/* validation callbacks */
|
||||
virDomainDefValidateCallback domainValidateCallback;
|
||||
|
Loading…
Reference in New Issue
Block a user