Similarly to the domain definition validator add a device validator. The
change to the prototype of the domain validator is necessary as
virDomainDeviceInfoIterateInternal requires a non-const pointer.
---
src/conf/domain_conf.c | 62 ++++++++++++++++++++++++++++++++++++++++++++++--
src/conf/domain_conf.h | 9 ++++++-
src/libxl/libxl_driver.c | 6 +++--
src/lxc/lxc_driver.c | 3 ++-
src/qemu/qemu_driver.c | 2 +-
src/uml/uml_driver.c | 3 ++-
src/vbox/vbox_common.c | 3 ++-
src/vz/vz_driver.c | 4 +++-
src/xen/xend_internal.c | 3 ++-
src/xen/xm_internal.c | 3 ++-
10 files changed, 86 insertions(+), 12 deletions(-)
diff --git a/src/conf/domain_conf.c b/src/conf/domain_conf.c
index 46820c2..b8a6901 100644
--- a/src/conf/domain_conf.c
+++ b/src/conf/domain_conf.c
@@ -4539,6 +4539,47 @@ virDomainDefPostParse(virDomainDefPtr def,
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)
{
return 0;
@@ -4558,11 +4599,17 @@ 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;
@@ -4572,6 +4619,12 @@ virDomainDefValidate(const virDomainDef *def,
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;
@@ -13183,6 +13236,10 @@ virDomainDeviceDefParse(const char *xmlStr,
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);
@@ -24222,7 +24279,8 @@ virDomainDeviceDefCopy(virDomainDeviceDefPtr src,
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);
diff --git a/src/conf/domain_conf.h b/src/conf/domain_conf.h
index 9c940b6..215235f 100644
--- a/src/conf/domain_conf.h
+++ b/src/conf/domain_conf.h
@@ -2368,6 +2368,12 @@ typedef int (*virDomainDefValidateCallback)(const virDomainDef
*def,
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 {
@@ -2378,6 +2384,7 @@ struct _virDomainDefParserConfig {
/* validation callbacks */
virDomainDefValidateCallback domainValidateCallback;
+ virDomainDeviceDefValidateCallback deviceValidateCallback;
/* private data for the callbacks */
void *priv;
@@ -2424,7 +2431,7 @@ virDomainDefPostParse(virDomainDefPtr def,
unsigned int parseFlags,
virDomainXMLOptionPtr xmlopt);
-int virDomainDefValidate(const virDomainDef *def,
+int virDomainDefValidate(virDomainDefPtr def,
virCapsPtr caps,
unsigned int parseFlags,
virDomainXMLOptionPtr xmlopt);
diff --git a/src/libxl/libxl_driver.c b/src/libxl/libxl_driver.c
index 6086717..bbcf8b9 100644
--- a/src/libxl/libxl_driver.c
+++ b/src/libxl/libxl_driver.c
@@ -3742,7 +3742,8 @@ libxlDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
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. */
@@ -3759,7 +3760,8 @@ libxlDomainDetachDeviceFlags(virDomainPtr dom, const char *xml,
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)
diff --git a/src/lxc/lxc_driver.c b/src/lxc/lxc_driver.c
index 05dbf3a..69cfa78 100644
--- a/src/lxc/lxc_driver.c
+++ b/src/lxc/lxc_driver.c
@@ -5315,7 +5315,8 @@ static int lxcDomainDetachDeviceFlags(virDomainPtr dom,
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;
diff --git a/src/qemu/qemu_driver.c b/src/qemu/qemu_driver.c
index 8463e8d..a7202ed 100644
--- a/src/qemu/qemu_driver.c
+++ b/src/qemu/qemu_driver.c
@@ -8422,7 +8422,7 @@ qemuDomainDetachDeviceFlags(virDomainPtr dom,
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;
diff --git a/src/uml/uml_driver.c b/src/uml/uml_driver.c
index df0e137..3d25135 100644
--- a/src/uml/uml_driver.c
+++ b/src/uml/uml_driver.c
@@ -2366,7 +2366,8 @@ static int umlDomainDetachDevice(virDomainPtr dom, const char *xml)
}
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;
diff --git a/src/vbox/vbox_common.c b/src/vbox/vbox_common.c
index b62e654..ad5cbe9 100644
--- a/src/vbox/vbox_common.c
+++ b/src/vbox/vbox_common.c
@@ -4242,7 +4242,8 @@ static int vboxDomainDetachDevice(virDomainPtr dom, const char
*xml)
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;
diff --git a/src/vz/vz_driver.c b/src/vz/vz_driver.c
index a092689..e59cf30 100644
--- a/src/vz/vz_driver.c
+++ b/src/vz/vz_driver.c
@@ -1211,7 +1211,9 @@ static int vzDomainDetachDeviceFlags(virDomainPtr dom, const char
*xml,
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;
diff --git a/src/xen/xend_internal.c b/src/xen/xend_internal.c
index 4dd6b41..3e3be58 100644
--- a/src/xen/xend_internal.c
+++ b/src/xen/xend_internal.c
@@ -2355,7 +2355,8 @@ xenDaemonDetachDeviceFlags(virConnectPtr conn,
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)))
diff --git a/src/xen/xm_internal.c b/src/xen/xm_internal.c
index ef1a460..4c9dcdf 100644
--- a/src/xen/xm_internal.c
+++ b/src/xen/xm_internal.c
@@ -1343,7 +1343,8 @@ xenXMDomainDetachDeviceFlags(virConnectPtr conn,
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) {
--
2.8.3