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:

    <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.
This commit is contained in:
Stefan Berger 2011-06-27 12:53:59 -04:00
parent 28e45afc3f
commit ecfbf79541

View File

@ -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;
}