From ecfbf79541c76a884b25af6b022b601570f39b25 Mon Sep 17 00:00:00 2001 From: Stefan Berger Date: Mon, 27 Jun 2011 12:53:59 -0400 Subject: [PATCH] nwfilter: Return error message about unresolvable variables 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: that references the following 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. --- src/nwfilter/nwfilter_gentech_driver.c | 82 ++++++++++++++++++++++++-- 1 file changed, 78 insertions(+), 4 deletions(-) diff --git a/src/nwfilter/nwfilter_gentech_driver.c b/src/nwfilter/nwfilter_gentech_driver.c index 3e8961d8bb..bf44fc4ed9 100644 --- a/src/nwfilter/nwfilter_gentech_driver.c +++ b/src/nwfilter/nwfilter_gentech_driver.c @@ -199,6 +199,68 @@ virNWFilterCreateVarHashmap(char *macaddr, char *ipaddr) { } +/** + * 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 + * @separator: 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 @@ -575,6 +637,7 @@ virNWFilterInstantiate(virConnectPtr conn, 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 conn, } 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,19 @@ 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 " + "variables: %s"), buf); + VIR_FREE(buf); + } + + rc = 1; + goto err_exit; }