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 -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list