}
+static int
+virDomainDeviceDefValidateInternal(const virDomainDeviceDef *dev ATTRIBUTE_UNUSED,
+ const virDomainDef *def ATTRIBUTE_UNUSED)
+{
+ return 0;
+}
+
+
+static int
+virDomainDeviceDefValidate(const virDomainDeviceDef *dev,
+ const virDomainDef *def,
+ unsigned int parseFlags,
+ virDomainXMLOptionPtr xmlopt)
+{
+ /* validate configuration only in certain places */
+ if (parseFlags & VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)
+ return 0;
+
+ if (xmlopt->config.deviceValidateCallback &&
+ xmlopt->config.deviceValidateCallback(dev, def, xmlopt->config.priv))
+ return -1;
+
+ if (virDomainDeviceDefValidateInternal(dev, def) < 0)
+ return -1;
+
+ return 0;
+}
+
+
+static int
+virDomainDefValidateDeviceIterator(virDomainDefPtr def,
+ virDomainDeviceDefPtr dev,
+ virDomainDeviceInfoPtr info ATTRIBUTE_UNUSED,
+ void *opaque)
+{
+ struct virDomainDefPostParseDeviceIteratorData *data = opaque;
+ return virDomainDeviceDefValidate(dev, def,
+ data->parseFlags, data->xmlopt);
+}
+
+
static int
virDomainDefValidateInternal(const virDomainDef *def ATTRIBUTE_UNUSED)
{
* appropriate message.
*/
int
-virDomainDefValidate(const virDomainDef *def,
+virDomainDefValidate(virDomainDefPtr def,
virCapsPtr caps,
unsigned int parseFlags,
virDomainXMLOptionPtr xmlopt)
{
+ struct virDomainDefPostParseDeviceIteratorData data = {
+ .caps = caps,
+ .xmlopt = xmlopt,
+ .parseFlags = parseFlags,
+ };
+
/* validate configuration only in certain places */
if (parseFlags & VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)
return 0;
xmlopt->config.domainValidateCallback(def, caps, xmlopt->config.priv) < 0)
return -1;
+ /* iterate the devices */
+ if (virDomainDeviceInfoIterateInternal(def,
+ virDomainDefValidateDeviceIterator,
+ true, &data) < 0)
+ return -1;
+
if (virDomainDefValidateInternal(def) < 0)
return -1;
if (virDomainDeviceDefPostParse(dev, def, caps, flags, xmlopt) < 0)
goto error;
+ /* validate the configuration */
+ if (virDomainDeviceDefValidate(dev, def, flags, xmlopt) < 0)
+ goto error;
+
cleanup:
xmlFreeDoc(xml);
xmlXPathFreeContext(ctxt);
xmlStr = virBufferContentAndReset(&buf);
ret = virDomainDeviceDefParse(xmlStr, def, caps, xmlopt,
- VIR_DOMAIN_DEF_PARSE_INACTIVE);
+ VIR_DOMAIN_DEF_PARSE_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE);
cleanup:
VIR_FREE(xmlStr);
virCapsPtr caps,
void *opaque);
+/* Called once per device, for adjusting per-device settings while
+ * leaving the overall domain otherwise unchanged. */
+typedef int (*virDomainDeviceDefValidateCallback)(const virDomainDeviceDef *dev,
+ const virDomainDef *def,
+ void *opaque);
+
typedef struct _virDomainDefParserConfig virDomainDefParserConfig;
typedef virDomainDefParserConfig *virDomainDefParserConfigPtr;
struct _virDomainDefParserConfig {
/* validation callbacks */
virDomainDefValidateCallback domainValidateCallback;
+ virDomainDeviceDefValidateCallback deviceValidateCallback;
/* private data for the callbacks */
void *priv;
unsigned int parseFlags,
virDomainXMLOptionPtr xmlopt);
-int virDomainDefValidate(const virDomainDef *def,
+int virDomainDefValidate(virDomainDefPtr def,
virCapsPtr caps,
unsigned int parseFlags,
virDomainXMLOptionPtr xmlopt);
if (flags & VIR_DOMAIN_DEVICE_MODIFY_CONFIG) {
if (!(dev = virDomainDeviceDefParse(xml, vm->def,
cfg->caps, driver->xmlopt,
- VIR_DOMAIN_DEF_PARSE_INACTIVE)))
+ VIR_DOMAIN_DEF_PARSE_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)))
goto endjob;
/* Make a copy for updated domain. */
virDomainDeviceDefFree(dev);
if (!(dev = virDomainDeviceDefParse(xml, vm->def,
cfg->caps, driver->xmlopt,
- VIR_DOMAIN_DEF_PARSE_INACTIVE)))
+ VIR_DOMAIN_DEF_PARSE_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)))
goto endjob;
if (libxlDomainDetachDeviceLive(driver, vm, dev) < 0)
dev = dev_copy = virDomainDeviceDefParse(xml, vm->def,
caps, driver->xmlopt,
- VIR_DOMAIN_DEF_PARSE_INACTIVE);
+ VIR_DOMAIN_DEF_PARSE_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE);
if (dev == NULL)
goto endjob;
virDomainDefPtr vmdef = NULL;
virDomainDeviceDefPtr dev = NULL, dev_copy = NULL;
int ret = -1;
- unsigned int parse_flags = 0;
+ unsigned int parse_flags = VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE;
virQEMUCapsPtr qemuCaps = NULL;
qemuDomainObjPrivatePtr priv;
virQEMUDriverConfigPtr cfg = NULL;
}
dev = virDomainDeviceDefParse(xml, vm->def, driver->caps, driver->xmlopt,
- VIR_DOMAIN_DEF_PARSE_INACTIVE);
+ VIR_DOMAIN_DEF_PARSE_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE);
if (dev == NULL)
goto cleanup;
def->os.type = VIR_DOMAIN_OSTYPE_HVM;
dev = virDomainDeviceDefParse(xml, def, data->caps, data->xmlopt,
- VIR_DOMAIN_DEF_PARSE_INACTIVE);
+ VIR_DOMAIN_DEF_PARSE_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE);
if (dev == NULL)
goto cleanup;
goto cleanup;
dev = virDomainDeviceDefParse(xml, privdom->def, privconn->driver->caps,
- privconn->driver->xmlopt, VIR_DOMAIN_XML_INACTIVE);
+ privconn->driver->xmlopt,
+ VIR_DOMAIN_XML_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE);
if (dev == NULL)
goto cleanup;
goto cleanup;
if (!(dev = virDomainDeviceDefParse(xml, def, priv->caps, priv->xmlopt,
- VIR_DOMAIN_DEF_PARSE_INACTIVE)))
+ VIR_DOMAIN_DEF_PARSE_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)))
goto cleanup;
if (virDomainXMLDevID(conn, minidef, dev, class, ref, sizeof(ref)))
if (!(dev = virDomainDeviceDefParse(xml, entry->def,
priv->caps,
priv->xmlopt,
- VIR_DOMAIN_DEF_PARSE_INACTIVE)))
+ VIR_DOMAIN_DEF_PARSE_INACTIVE |
+ VIR_DOMAIN_DEF_PARSE_SKIP_VALIDATE)))
goto cleanup;
switch (dev->type) {