]> xenbits.xensource.com Git - people/liuw/libxenctrl-split/libvirt.git/commitdiff
nwfilter: Return error message about unresolvable variables
authorStefan Berger <stefanb@us.ibm.com>
Mon, 27 Jun 2011 16:53:59 +0000 (12:53 -0400)
committerStefan Berger <stefanb@us.ibm.com>
Mon, 27 Jun 2011 16:53:59 +0000 (12:53 -0400)
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.

src/nwfilter/nwfilter_gentech_driver.c

index 3e8961d8bbcac8a90ae56dd06b7f51b166c973eb..bf44fc4ed9c045bfcf7f452f034f651d5641de3f 100644 (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;
 }