[libvirt] [PATCH 4/5] network_conf: change TXT record to pointer to pointer type

Guannan Ren gren at redhat.com
Sun Jul 8 10:53:42 UTC 2012


Change the type of txtrecords from virNetworkDNSTxtRecordsDefPtr to
virNetworkDNSTxtRecordsDefPtr *.
Refacotr the virNetworkDNSDefParseXML to create a new TXT xml Parsing
function.
Make value (text field in TXT RR) optional according to dnsmasq
manpage.

--txt-record=<name>[[,<text>],<text>]
---
 src/conf/network_conf.c     |  111 +++++++++++++++++++++++++++----------------
 src/conf/network_conf.h     |    2 +-
 src/network/bridge_driver.c |   16 +++++-
 3 files changed, 84 insertions(+), 45 deletions(-)

diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
index 99c6fc1..b720c9f 100644
--- a/src/conf/network_conf.c
+++ b/src/conf/network_conf.c
@@ -125,8 +125,8 @@ static void virNetworkDNSDefFree(virNetworkDNSDefPtr def)
     if (def) {
         if (def->txtrecords) {
             while (def->ntxtrecords--) {
-                VIR_FREE(def->txtrecords[def->ntxtrecords].name);
-                VIR_FREE(def->txtrecords[def->ntxtrecords].value);
+                VIR_FREE(def->txtrecords[def->ntxtrecords]->name);
+                VIR_FREE(def->txtrecords[def->ntxtrecords]->value);
             }
         }
         VIR_FREE(def->txtrecords);
@@ -512,6 +512,44 @@ virNetworkDHCPRangeDefParseXML(const char *networkName,
     return 0;
 }
 
+static virNetworkDNSTxtRecordsDefPtr
+virNetworkDNSTxtDefParseXML(xmlNodePtr cur)
+
+{
+    virNetworkDNSTxtRecordsDefPtr txt = NULL;
+
+    if (VIR_ALLOC(txt) < 0) {
+        virReportOOMError();
+        return NULL;
+    }
+
+    if (!(txt->name = virXMLPropString(cur, "name"))) {
+        virNetworkReportError(VIR_ERR_XML_DETAIL,
+                              "%s", _("Missing required name attribute in dns txt record"));
+        goto error;
+    }
+
+    /* The text field for dnsmasq is optional */
+    txt->value = virXMLPropString(cur, "value");
+    if (txt->value && *txt->value == '\0')
+        txt->value = NULL;
+
+    if (strchr(txt->name, ' ') != NULL) {
+        virNetworkReportError(VIR_ERR_XML_DETAIL,
+                              _("spaces are not allowed in DNS TXT record names (name is '%s')"), txt->name);
+        goto error;
+    }
+
+    return txt;
+error:
+    if (txt) {
+        VIR_FREE(txt->name);
+        VIR_FREE(txt->value);
+    }
+    VIR_FREE(txt);
+    return NULL;
+}
+
 static int
 virNetworkDNSHostsDefParseXML(virNetworkDNSDefPtr def,
                               xmlNodePtr node)
@@ -751,8 +789,6 @@ virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef,
     xmlNodePtr cur;
     int i, n;
     int ret = -1;
-    char *name = NULL;
-    char *value = NULL;
     virNetworkDNSDefPtr def = NULL;
 
     if (VIR_ALLOC(def) < 0) {
@@ -781,38 +817,31 @@ virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef,
     }
     VIR_FREE(nodes);
 
-    cur = node->children;
-    while (cur != NULL) {
-        if (cur->type == XML_ELEMENT_NODE &&
-            xmlStrEqual(cur->name, BAD_CAST "txt")) {
-            if (!(name = virXMLPropString(cur, "name"))) {
-                virNetworkReportError(VIR_ERR_XML_DETAIL,
-                                      "%s", _("Missing required name attribute in dns txt record"));
-                goto error;
-            }
-            if (!(value = virXMLPropString(cur, "value"))) {
-                virNetworkReportError(VIR_ERR_XML_DETAIL,
-                                      _("Missing required value attribute in dns txt record '%s'"), name);
-                goto error;
-            }
+    if ((n = virXPathNodeSet("./dns/txt", ctxt, &nodes)) < 0) {
+        virNetworkReportError(VIR_ERR_INTERNAL_ERROR,
+                              "%s", _("cannot extract txt nodes"));
+        goto error;
+    }
 
-            if (strchr(name, ' ') != NULL) {
-                virNetworkReportError(VIR_ERR_XML_DETAIL,
-                                      _("spaces are not allowed in DNS TXT record names (name is '%s')"), name);
-                goto error;
-            }
+    if (n && VIR_REALLOC_N(def->txtrecords, def->ntxtrecords + n) < 0) {
+        virReportOOMError();
+        goto error;
+    }
+    for (i = 0; i < n; i++) {
+        virNetworkDNSTxtRecordsDefPtr txt;
 
-            if (VIR_REALLOC_N(def->txtrecords, def->ntxtrecords + 1) < 0) {
-                virReportOOMError();
-                goto error;
-            }
+        txt = virNetworkDNSTxtDefParseXML(nodes[i]);
+        if (!txt)
+            goto error;
 
-            def->txtrecords[def->ntxtrecords].name = name;
-            def->txtrecords[def->ntxtrecords].value = value;
-            def->ntxtrecords++;
-            name = NULL;
-            value = NULL;
-        } else if (cur->type == XML_ELEMENT_NODE &&
+        def->txtrecords[def->ntxtrecords++] = txt;
+    }
+    VIR_FREE(nodes);
+
+
+    cur = node->children;
+    while (cur != NULL) {
+        if (cur->type == XML_ELEMENT_NODE &&
             xmlStrEqual(cur->name, BAD_CAST "host")) {
             ret = virNetworkDNSHostsDefParseXML(def, cur);
             if (ret < 0)
@@ -824,13 +853,11 @@ virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef,
 
     ret = 0;
 error:
-    if (ret < 0) {
-        VIR_FREE(name);
-        VIR_FREE(value);
+    if (ret < 0)
         virNetworkDNSDefFree(def);
-    } else {
+    else
         *dnsdef = def;
-    }
+
     return ret;
 }
 
@@ -1400,9 +1427,11 @@ virNetworkDNSDefFormat(virBufferPtr buf,
     virBufferAddLit(buf, "  <dns>\n");
 
     for (i = 0 ; i < def->ntxtrecords ; i++) {
-        virBufferAsprintf(buf, "    <txt name='%s' value='%s' />\n",
-                              def->txtrecords[i].name,
-                              def->txtrecords[i].value);
+        virBufferAsprintf(buf, "    <txt name='%s'", def->txtrecords[i]->name);
+        if (def->txtrecords[i]->value)
+            virBufferAsprintf(buf, " value='%s'", def->txtrecords[i]->value);
+
+        virBufferAsprintf(buf, "/>\n");
     }
 
     for (i = 0 ; i < def->nsrvrecords ; i++) {
diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
index 345c99f..16fbe81 100644
--- a/src/conf/network_conf.h
+++ b/src/conf/network_conf.h
@@ -99,7 +99,7 @@ typedef struct _virNetworkDNSHostsDef *virNetworkDNSHostsDefPtr;
 
 struct _virNetworkDNSDef {
     unsigned int ntxtrecords;
-    virNetworkDNSTxtRecordsDefPtr txtrecords;
+    virNetworkDNSTxtRecordsDefPtr *txtrecords;
     unsigned int nhosts;
     virNetworkDNSHostsDefPtr hosts;
     unsigned int nsrvrecords;
diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
index 95a9b96..c0b05bd 100644
--- a/src/network/bridge_driver.c
+++ b/src/network/bridge_driver.c
@@ -459,6 +459,7 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
     int r, ret = -1;
     int nbleases = 0;
     int ii;
+    char *txtValue = NULL;
     char *domain = NULL;
     char *target = NULL;
     char *record = NULL;
@@ -522,9 +523,17 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
         int i;
 
         for (i = 0; i < dns->ntxtrecords; i++) {
-            virCommandAddArgFormat(cmd, "--txt-record=%s,%s",
-                                   dns->txtrecords[i].name,
-                                   dns->txtrecords[i].value);
+            if (dns->txtrecords[i]->value) {
+                if (virAsprintf(&txtValue, ",%s",
+                                dns->txtrecords[i]->value) < 0) {
+                    virReportOOMError();
+                    goto cleanup;
+                }
+            }
+            virCommandAddArgFormat(cmd, "--txt-record=%s%s",
+                                   dns->txtrecords[i]->name,
+                                   txtValue ? txtValue : "");
+            VIR_FREE(txtValue);
         }
 
         for (i = 0; i < dns->nsrvrecords; i++) {
@@ -682,6 +691,7 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
 
     ret = 0;
 cleanup:
+    VIR_FREE(txtValue);
     VIR_FREE(domain);
     VIR_FREE(target);
     VIR_FREE(record);
-- 
1.7.7.5




More information about the libvir-list mailing list