This is in response to bugzilla 664629 https://bugzilla.redhat.com/show_bug.cgi?id=664629 The patch below returns an appropriate error message if the chain of nwfilters is found to contain unresolvable variables and therefore cannot be instantiated. Example: The following XMl added to a domain: <interface type='bridge'> <mac address='52:54:00:9f:80:45'/> <source bridge='virbr0'/> <model type='virtio'/> <filterref filter='test'/> </interface> that references the following filter <filter name='test' chain='root'> <filterref filter='clean-traffic'/> <filterref filter='allow-dhcp-server'/> </filter> now displays upon 'virsh start mydomain' error: Failed to start domain mydomain error: internal error Cannot instantiate filter due to unresolvable variable: DHCPSERVER 'DHPCSERVER' is contained in allow-dhcp-server. Signed-off-by: Stefan Berger <stefanb@xxxxxxxxxxxxxxxxxx> --- src/nwfilter/nwfilter_gentech_driver.c | 84 +++++++++++++++++++++++++++++++-- 1 file changed, 80 insertions(+), 4 deletions(-) Index: libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c =================================================================== --- libvirt-acl.orig/src/nwfilter/nwfilter_gentech_driver.c +++ libvirt-acl/src/nwfilter/nwfilter_gentech_driver.c @@ -200,6 +200,68 @@ virNWFilterCreateVarHashmap(char *macadd /** + * Convert a virNWFilterHashTable into a string of comma-separated + * variable names. + */ +struct printString +{ + virBuffer buf; + const char *separator; + bool reportMAC; + bool reportIP; +}; + + +static void +_printString(void *payload ATTRIBUTE_UNUSED, const void *name, void *data) +{ + struct printString *ps = data; + + if ((STREQ((char *)name, NWFILTER_STD_VAR_IP ) && !ps->reportIP ) || + (STREQ((char *)name, NWFILTER_STD_VAR_MAC) && !ps->reportMAC)) + return; + + if (virBufferUse(&ps->buf) && ps->separator) + virBufferAdd(&ps->buf, ps->separator, -1); + + virBufferAdd(&ps->buf, name, -1); +} + +/** + * virNWFilterPrintVars + * + * @var: hash table containing variables + * @separaptro: separator to use between variable names, i.e., ", " + * @reportMAC: whether to report the 'MAC' variable + * @reportIP : whether to report the IP variable + * + * Returns a string of comma separated variable names + */ +static char * +virNWFilterPrintVars(virHashTablePtr vars, + const char *separator, + bool reportMAC, + bool reportIP) +{ + struct printString ps = { + .buf = VIR_BUFFER_INITIALIZER, + .separator = separator, + .reportMAC = reportMAC, + .reportIP = reportIP, + }; + + virHashForEach(vars, _printString, &ps); + + if (virBufferError(&ps.buf)) { + virBufferFreeAndReset(&ps.buf); + virReportOOMError(); + return NULL; + } + return virBufferContentAndReset(&ps.buf); +} + + +/** * virNWFilterRuleInstantiate: * @conn: pointer to virConnect object * @techdriver: the driver to use for instantiation @@ -575,6 +637,7 @@ virNWFilterInstantiate(virConnectPtr con virNWFilterRuleInstPtr *insts = NULL; void **ptrs = NULL; int instantiate = 1; + char *buf; virNWFilterHashTablePtr missing_vars = virNWFilterHashTableCreate(0); if (!missing_vars) { @@ -607,11 +670,9 @@ virNWFilterInstantiate(virConnectPtr con } goto err_exit; } - rc = 1; - goto err_exit; + goto err_unresolvable_vars; } else if (virHashSize(missing_vars->hashTable) > 1) { - rc = 1; - goto err_exit; + goto err_unresolvable_vars; } else if (!forceWithPendingReq && virNWFilterLookupLearnReq(ifindex) != NULL) { goto err_exit; @@ -674,6 +735,21 @@ err_exit: virNWFilterHashTableFree(missing_vars); return rc; + +err_unresolvable_vars: + + buf = virNWFilterPrintVars(missing_vars->hashTable, ", ", false, false); + if (buf) { + virNWFilterReportError(VIR_ERR_INTERNAL_ERROR, + _("Cannot instantiate filter due to unresolvable " + "variable%s: %s"), + strstr(buf, ", ") ? "s" : "", + buf); + VIR_FREE(buf); + } + + rc = 1; + goto err_exit; } -- libvir-list mailing list libvir-list@xxxxxxxxxx https://www.redhat.com/mailman/listinfo/libvir-list