[libvirt] [PATCH] nwfiler: Return error message about unresolvable variables

Stefan Berger stefanb at linux.vnet.ibm.com
Mon Jun 27 14:14:42 UTC 2011


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 at linux.vnet.ibm.com>

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




More information about the libvir-list mailing list