[libvirt] [PATCH] Implement DNS SRV record into the bridge driver

Michal Novotny minovotn at redhat.com
Thu Aug 11 13:18:09 UTC 2011


Thanks for your review, Daniel. I already sent v2 of the patch now ;-)

Michal

On 08/11/2011 04:42 AM, Daniel Veillard wrote:
> On Thu, Aug 11, 2011 at 10:13:34AM +0800, Daniel Veillard wrote:
>> On Tue, Aug 09, 2011 at 05:50:55PM +0200, Michal Novotny wrote:
>>> Hi,
>>> this is the patch to the bridge driver and libvirt XML
>>> file to include support for the SRV records in the DNS.
>>> The syntax is based on DNSMasq man page and tests for
>>> both xml2xml and xml2argv were added as well.
>>>
>>> Signed-off-by: Michal Novotny <minovotn at redhat.com>
>>> ---
>>>  docs/formatnetwork.html.in                         |   12 ++
>>>  docs/schemas/network.rng                           |   30 +++++
>>>  src/conf/network_conf.c                            |  125 ++++++++++++++++++++
>>>  src/conf/network_conf.h                            |   14 ++
>>>  src/network/bridge_driver.c                        |   18 +++
>>>  .../nat-network-dns-srv-record.argv                |    1 +
>>>  .../nat-network-dns-srv-record.xml                 |   26 ++++
>>>  tests/networkxml2argvtest.c                        |    1 +
>>>  .../nat-network-dns-srv-record.xml                 |   26 ++++
>>>  .../nat-network-dns-srv-record.xml                 |   26 ++++
>>>  tests/networkxml2xmltest.c                         |    1 +
>>>  12 files changed, 281 insertions(+), 1 deletions(-)
>>>  create mode 100644 tests/networkxml2argvdata/nat-network-dns-srv-record.argv
>>>  create mode 100644 tests/networkxml2argvdata/nat-network-dns-srv-record.xml
>>>  create mode 100644 tests/networkxml2xmlin/nat-network-dns-srv-record.xml
>>>  create mode 100644 tests/networkxml2xmlout/nat-network-dns-srv-record.xml
>>>
>>> diff --git a/docs/formatnetwork.html.in b/docs/formatnetwork.html.in
>>> index ddfa77c..4f748c4 100644
>>> --- a/docs/formatnetwork.html.in
>>> +++ b/docs/formatnetwork.html.in
>>> @@ -148,6 +148,7 @@
>>>          <mac address='00:16:3E:5D:C7:9E'/>
>>>          <dns>
>>>            <txt name="example" value="example value" />
>>> +          <srv service="name" protocol="tcp" domain="test-domain-name" target="." port="1024" priority="10" weight="10"/>
>>>          </dns>
>>>          <ip address="192.168.122.1" netmask="255.255.255.0">
>>>            <dhcp>
>>> @@ -196,6 +197,17 @@
>>>              <span class="since">Since 0.9.3</span>
>>>            </dd>
>>>          </dl>
>>> +        <dl>
>>> +          <dt><code>srv</code></dt>
>>> +          <dd>The <code>dns</code> element can have also 0 or more <code>srv</code>
>>> +            record elements. Each srv record element defines a DNS SRV record
>>> +            and has 2 mandatory and 4 optional attributes. The mandatory attributes
>>> +            are service name and protocol (tcp, udp) and you can define optional
>>> +            target, port, priority and weight arguments. The body of the element
>>> +            have to be set to some data and therefore it's a pair tag.
>>> +            <span class="since">Since 0.9.5</span>
>>> +          </dd>
>>> +        </dl>
>>>        </dd>
>>>        <dt><code>ip</code></dt>
>>>        <dd>The <code>address</code> attribute defines an IPv4 address in
>>> diff --git a/docs/schemas/network.rng b/docs/schemas/network.rng
>>> index 1c44471..413698a 100644
>>> --- a/docs/schemas/network.rng
>>> +++ b/docs/schemas/network.rng
>>> @@ -138,6 +138,22 @@
>>>                  </element>
>>>                </zeroOrMore>
>>>                <zeroOrMore>
>>> +                <element name="srv">
>>> +                  <attribute name="service"><text/></attribute>
>>> +                  <attribute name="protocol">
>>> +                    <choice>
>>> +                      <value>tcp</value>
>>> +                      <value>udp</value>
>>> +                    </choice>
>>> +                  </attribute>
>>> +                  <attribute name="domain"><text/></attribute>
>>> +                  <attribute name="target"><text/></attribute>
>>> +                  <attribute name="port"><ref name="port-for-user"/></attribute>
>   Actually I just looked at http://tools.ietf.org/html/rfc2782
>
>>> +                  <attribute name="priority"><ref name="short-int"/></attribute>
>>> +                  <attribute name="weight"><ref name="short-int"/></attribute>
>>> +                </element>
>>> +              </zeroOrMore>
>>> +              <zeroOrMore>
>>>                  <element name="host">
>>>                    <attribute name="ip"><ref name="ipv4Addr"/></attribute>
>>>                    <oneOrMore>
>>> @@ -206,6 +222,20 @@
>>>      </element>
>>>    </define>
>>>  
>>> +  <define name="port-for-user">
>>> +    <data type="integer">
>>> +      <param name="minInclusive">1024</param>
>>> +      <param name="maxInclusive">65535</param>
>>> +    </data>
>>> +  </define>
>   and the full set of allowed port values is correct for an SRV record
>
>   page 3:
>
>    Port
>         The port on this target host of this service.  The range is 0-
>         65535.  This is a 16 bit unsigned integer in network byte order.
>         This is often as specified in Assigned Numbers but need not be.
>
> is that a limitation of dnsmasq ?
>
>>> +  <define name="short-int">
>>> +    <data type="integer">
>>> +      <param name="minInclusive">0</param>
>>> +      <param name="maxInclusive">127</param>
>>> +    </data>
>>> +  </define>
>>> +
>>>    <define name='addr-family'>
>>>      <data type='string'>
>>>        <param name="pattern">(ipv4)|(ipv6)</param>
>>> diff --git a/src/conf/network_conf.c b/src/conf/network_conf.c
>>> index b11c482..120b149 100644
>>> --- a/src/conf/network_conf.c
>>> +++ b/src/conf/network_conf.c
>>> @@ -137,6 +137,14 @@ static void virNetworkDNSDefFree(virNetworkDNSDefPtr def)
>>>              }
>>>              VIR_FREE(def->hosts);
>>>          }
>>> +	if (def->nsrvrecords) {
>>    ^^^^ please remove the tab above before commit, are you sure you ran
>>    "make syntax-check" ?
>>
>>> +            while (def->nsrvrecords--) {
>>> +              VIR_FREE(def->srvrecords[def->nsrvrecords].domain);
>>> +              VIR_FREE(def->srvrecords[def->nsrvrecords].service);
>>> +              VIR_FREE(def->srvrecords[def->nsrvrecords].protocol);
>>> +              VIR_FREE(def->srvrecords[def->nsrvrecords].target);
>>> +            }
>>> +        }
>>>          VIR_FREE(def);
>>>      }
>>>  }
>>> @@ -552,6 +560,107 @@ error:
>>>  }
>>>  
>>>  static int
>>> +virNetworkDNSSrvDefParseXML(virNetworkDNSDefPtr def,
>>> +                            xmlNodePtr cur)
>>> +{
>>> +    char *domain = NULL;
>>> +    char *service = NULL;
>>   Somehow I guess Clang or other tools will complain about the extra
>> initialization here, but IMHO that's fine. An option would be to move
>> the def->srvrecords allocation before the fetch of service attribute.
>>
>>> +    char *protocol = NULL;
>>> +    char *target = NULL;
>>> +    char *portString = NULL;
>>> +    char *priorityString = NULL;
>>> +    char *weightString = NULL;
>>> +    int port;
>>> +    int priority;
>>> +    int weight;
>>> +    int ret = 0;
>>> +
>>> +    if (!(service = virXMLPropString(cur, "service"))) {
>>> +        virNetworkReportError(VIR_ERR_XML_DETAIL,
>>> +                              "%s", _("Missing required service attribute in dns srv record"));
>>> +        goto error;
>>> +    }
>>> +    if (!(protocol = virXMLPropString(cur, "protocol"))) {
>>> +        virNetworkReportError(VIR_ERR_XML_DETAIL,
>>> +                              _("Missing required protocol attribute in dns srv record '%s'"), service);
>>> +        goto error;
>>> +    }
>>> +
>>> +    target = virXMLPropString(cur, "target");
>>> +    domain = virXMLPropString(cur, "domain");
>>> +    portString = virXMLPropString(cur, "port");
>>> +    priorityString = virXMLPropString(cur, "priority");
>>> +    weightString = virXMLPropString(cur, "weight");
>>> +
>>> +    if (VIR_REALLOC_N(def->srvrecords, def->nsrvrecords + 1) < 0) {
>>> +        virReportOOMError();
>>> +        goto error;
>>> +    }
>>> +
>>> +    if (portString &&
>>> +        virStrToLong_i(portString, NULL, 10, &port) < 0) {
>>> +        virNetworkReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>>> +                             _("Cannot parse 'port' attribute"));
>>> +        goto error;
>>> +    }
>>> +
>>> +    if (priorityString &&
>>> +        virStrToLong_i(priorityString, NULL, 10, &priority) < 0) {
>>> +        virNetworkReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>>> +                             _("Cannot parse 'priority' attribute"));
>>> +        goto error;
>>> +    }
>>> +
>>> +    if (weightString &&
>>> +        virStrToLong_i(weightString, NULL, 10, &weight) < 0) {
>>> +        virNetworkReportError(VIR_ERR_INTERNAL_ERROR, "%s",
>>> +                             _("Cannot parse 'weight' attribute"));
>>> +        goto error;
>>> +    }
>>
>>   Hum, using virXPathInt() using the XPath expressions "@port",
>>   "@priority" and "@weight" would probably allow to simplify all this
>>   quite a bit, but you would have to extend virNetworkDNSDefParseXML()
>>   to carry the xpath context from virNetworkDefParseXML() and
>>   update the node for it.
>>
>>> +    def->srvrecords[def->nsrvrecords].domain = domain;
>>> +    def->srvrecords[def->nsrvrecords].service = service;
>>> +    def->srvrecords[def->nsrvrecords].protocol = protocol;
>>> +    def->srvrecords[def->nsrvrecords].target = target;
>>> +    def->srvrecords[def->nsrvrecords].port = port;
>>> +    def->srvrecords[def->nsrvrecords].priority = priority;
>>> +    def->srvrecords[def->nsrvrecords].weight = weight;
>>   Hum, the range values, service and target should all be checked
>> you need at least the set of minimal check you provided in the rng
>> to be done in the C parsing.
>   and protocol must be checked for being "udp" or "tcp" only
> One of the warning raised in the RFC is that there is often a limit
> of 512 bytes for DNS UDP messages so maybe the service name lenght
> should be checked too, along with the characters used.
>
>>> +    def->nsrvrecords++;
>>> +
>>> +    goto cleanup;
>>> +
>>> +error:
>>> +    if (domain)
>>> +        VIR_FREE(domain);
>>> +    if (service)
>>> +        VIR_FREE(service);
>>> +    if (protocol)
>>> +        VIR_FREE(protocol);
>>> +    if (target)
>>> +        VIR_FREE(target);
>>> +
>>> +    ret = 1;
>>> +
>>> +cleanup:
>>> +    if (portString)
>>> +        VIR_FREE(portString);
>>> +    if (priorityString)
>>> +        VIR_FREE(priorityString);
>>> +    if (weightString)
>>> +        VIR_FREE(weightString);
>>> +
>>> +    domain = NULL;
>>> +    service = NULL;
>>> +    protocol = NULL;
>>> +    target = NULL;
>>> +    portString = NULL;
>>> +    priorityString = NULL;
>>> +    weightString = NULL;
>>> +
>>> +    return ret;
>>> +}
>>> +
>>> +static int
>>>  virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef,
>>>                           xmlNodePtr node)
>>>  {
>>> @@ -598,6 +707,11 @@ virNetworkDNSDefParseXML(virNetworkDNSDefPtr *dnsdef,
>>>              name = NULL;
>>>              value = NULL;
>>>          } else if (cur->type == XML_ELEMENT_NODE &&
>>> +            xmlStrEqual(cur->name, BAD_CAST "srv")) {
>>> +            ret = virNetworkDNSSrvDefParseXML(def, cur);
>>> +            if (ret < 0)
>>> +                goto error;
>>> +        } else if (cur->type == XML_ELEMENT_NODE &&
>>>              xmlStrEqual(cur->name, BAD_CAST "host")) {
>>>              ret = virNetworkDNSHostsDefParseXML(def, cur);
>>>              if (ret < 0)
>>> @@ -1147,6 +1261,17 @@ virNetworkDNSDefFormat(virBufferPtr buf,
>>>                                def->txtrecords[i].value);
>>>      }
>>>  
>>> +    for (i = 0 ; i < def->nsrvrecords ; i++) {
>>> +        virBufferAsprintf(buf, "    <srv service='%s' protocol='%s' domain='%s' target='%s' port='%d' priority='%d' weight='%d' />\n",
>>> +                              def->srvrecords[i].service,
>>> +                              def->srvrecords[i].protocol,
>>> +                              def->srvrecords[i].domain,
>>> +                              def->srvrecords[i].target,
>>> +                              def->srvrecords[i].port,
>>> +                              def->srvrecords[i].priority,
>>> +                              def->srvrecords[i].weight);
>>> +    }
>>> +
>>   Hum, if attributes are optional is that a good idea to serialize back
>> the default value when saving the XML, I would think the answer is no.
>> But that requires to use special values when parsing like -1 or NULL
>> and check them here. In any case it seems this code would fail and
>> print for example target="(null)" or crash if target wasn't specified in
>> the input XML.
>>
>   Also I think we need to either verify the service string on input
> or use virBufferEscapeString to serialize it back,
>
>>>  
>>> diff --git a/src/conf/network_conf.h b/src/conf/network_conf.h
>>> index 869085e..08e08b2 100644
>>> --- a/src/conf/network_conf.h
>>> +++ b/src/conf/network_conf.h
>>> @@ -67,6 +67,18 @@ struct _virNetworkDNSTxtRecordsDef {
>>>      char *value;
>>>  };
>>>  
>>> +typedef struct _virNetworkDNSSrvRecordsDef virNetworkDNSSrvRecordsDef;
>>> +typedef virNetworkDNSSrvRecordsDef *virNetworkDNSSrvRecordsDefPtr;
>>> +struct _virNetworkDNSSrvRecordsDef {
>>> +    char *domain;
>>> +    char *service;
>>> +    char *protocol;
>>> +    char *target;
>>> +    int port;
>>> +    int priority;
>>> +    int weight;
>>> +};
>>> +
>>>  struct _virNetworkDNSHostsDef {
>>>      virSocketAddr ip;
>>>      int nnames;
>>> @@ -80,6 +92,8 @@ struct _virNetworkDNSDef {
>>>      virNetworkDNSTxtRecordsDefPtr txtrecords;
>>>      unsigned int nhosts;
>>>      virNetworkDNSHostsDefPtr hosts;
>>> +    unsigned int nsrvrecords;
>>> +    virNetworkDNSSrvRecordsDefPtr srvrecords;
>>>  };
>>>  
>>>  typedef struct _virNetworkDNSDef *virNetworkDNSDefPtr;
>>> diff --git a/src/network/bridge_driver.c b/src/network/bridge_driver.c
>>> index c90db63..e7f3b26 100644
>>> --- a/src/network/bridge_driver.c
>>> +++ b/src/network/bridge_driver.c
>>> @@ -559,6 +559,24 @@ networkBuildDnsmasqArgv(virNetworkObjPtr network,
>>>              virCommandAddArgPair(cmd, "--txt-record", record);
>>>              VIR_FREE(record);
>>>          }
>>> +
>>> +        for (i = 0; i < dns->nsrvrecords; i++) {
>>> +            char *record = NULL;
>>> +            if (virAsprintf(&record, "%s.%s.%s,%s,%d,%d,%d",
>>> +                            dns->srvrecords[i].service,
>>> +                            dns->srvrecords[i].protocol,
>>> +                            dns->srvrecords[i].domain,
>>> +                            dns->srvrecords[i].target,
>>> +                            dns->srvrecords[i].port,
>>> +                            dns->srvrecords[i].priority,
>>> +                            dns->srvrecords[i].weight) < 0) {
>>> +                virReportOOMError();
>>> +                goto cleanup;
>>> +            }
>>   okay, but this fully need to be checked for default values...
>>
>>> +            virCommandAddArgPair(cmd, "--srv-host", record);
>>> +            VIR_FREE(record);
>>> +        }
>>>      }
>>>  
>>>      /*
>>> diff --git a/tests/networkxml2argvdata/nat-network-dns-srv-record.argv b/tests/networkxml2argvdata/nat-network-dns-srv-record.argv
>>> new file mode 100644
>>> index 0000000..2ea9809
>>> --- /dev/null
>>> +++ b/tests/networkxml2argvdata/nat-network-dns-srv-record.argv
>>> @@ -0,0 +1 @@
>>> +/usr/sbin/dnsmasq --strict-order --bind-interfaces --conf-file= --except-interface lo --srv-host=name.tcp.test-domain-name,.,1024,10,10 --listen-address 192.168.122.1 --listen-address 192.168.123.1 --listen-address 2001:db8:ac10:fe01::1 --listen-address 2001:db8:ac10:fd01::1 --listen-address 10.24.10.1 --dhcp-range 192.168.122.2,192.168.122.254 --dhcp-leasefile=/var/lib/libvirt/dnsmasq/default.leases --dhcp-lease-max=253 --dhcp-no-override --dhcp-hostsfile=/var/lib/libvirt/dnsmasq/default.hostsfile
>>> \ No newline at end of file
>>> diff --git a/tests/networkxml2argvdata/nat-network-dns-srv-record.xml b/tests/networkxml2argvdata/nat-network-dns-srv-record.xml
>>> new file mode 100644
>>> index 0000000..4be85b5
>>> --- /dev/null
>>> +++ b/tests/networkxml2argvdata/nat-network-dns-srv-record.xml
>>> @@ -0,0 +1,26 @@
>>> +<network>
>>> +  <name>default</name>
>>> +  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
>>> +  <forward dev='eth1' mode='nat'>
>>> +    <interface dev='eth1'/>
>>> +  </forward>
>>> +  <bridge name='virbr0' stp='on' delay='0' />
>>> +  <dns>
>>> +    <srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10' />
>>   need to add more SRV records to test for optional attributes handling
>>
>>> +  </dns>
>>> +  <ip address='192.168.122.1' netmask='255.255.255.0'>
>>> +    <dhcp>
>>> +      <range start='192.168.122.2' end='192.168.122.254' />
>>> +      <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
>>> +      <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
>>> +    </dhcp>
>>> +  </ip>
>>> +  <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
>>> +  </ip>
>>> +  <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
>>> +  </ip>
>>> +  <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
>>> +  </ip>
>>> +  <ip family='ipv4' address='10.24.10.1'>
>>> +  </ip>
>>> +</network>
>>> diff --git a/tests/networkxml2argvtest.c b/tests/networkxml2argvtest.c
>>> index 4a11d6f..a9da613 100644
>>> --- a/tests/networkxml2argvtest.c
>>> +++ b/tests/networkxml2argvtest.c
>>> @@ -120,6 +120,7 @@ mymain(void)
>>>      DO_TEST("netboot-network");
>>>      DO_TEST("netboot-proxy-network");
>>>      DO_TEST("nat-network-dns-txt-record");
>>> +    DO_TEST("nat-network-dns-srv-record");
>>>      DO_TEST("nat-network-dns-hosts");
>>>  
>>>      return (ret==0 ? EXIT_SUCCESS : EXIT_FAILURE);
>>> diff --git a/tests/networkxml2xmlin/nat-network-dns-srv-record.xml b/tests/networkxml2xmlin/nat-network-dns-srv-record.xml
>>> new file mode 100644
>>> index 0000000..4be85b5
>>> --- /dev/null
>>> +++ b/tests/networkxml2xmlin/nat-network-dns-srv-record.xml
>>> @@ -0,0 +1,26 @@
>>> +<network>
>>> +  <name>default</name>
>>> +  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
>>> +  <forward dev='eth1' mode='nat'>
>>> +    <interface dev='eth1'/>
>>> +  </forward>
>>> +  <bridge name='virbr0' stp='on' delay='0' />
>>> +  <dns>
>>> +    <srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10' />
>>> +  </dns>
>>> +  <ip address='192.168.122.1' netmask='255.255.255.0'>
>>> +    <dhcp>
>>> +      <range start='192.168.122.2' end='192.168.122.254' />
>>> +      <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
>>> +      <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
>>> +    </dhcp>
>>> +  </ip>
>>> +  <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
>>> +  </ip>
>>> +  <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
>>> +  </ip>
>>> +  <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
>>> +  </ip>
>>> +  <ip family='ipv4' address='10.24.10.1'>
>>> +  </ip>
>>> +</network>
>>> diff --git a/tests/networkxml2xmlout/nat-network-dns-srv-record.xml b/tests/networkxml2xmlout/nat-network-dns-srv-record.xml
>>> new file mode 100644
>>> index 0000000..4be85b5
>>> --- /dev/null
>>> +++ b/tests/networkxml2xmlout/nat-network-dns-srv-record.xml
>>> @@ -0,0 +1,26 @@
>>> +<network>
>>> +  <name>default</name>
>>> +  <uuid>81ff0d90-c91e-6742-64da-4a736edb9a9b</uuid>
>>> +  <forward dev='eth1' mode='nat'>
>>> +    <interface dev='eth1'/>
>>> +  </forward>
>>> +  <bridge name='virbr0' stp='on' delay='0' />
>>> +  <dns>
>>> +    <srv service='name' protocol='tcp' domain='test-domain-name' target='.' port='1024' priority='10' weight='10' />
>>> +  </dns>
>>> +  <ip address='192.168.122.1' netmask='255.255.255.0'>
>>> +    <dhcp>
>>> +      <range start='192.168.122.2' end='192.168.122.254' />
>>> +      <host mac='00:16:3e:77:e2:ed' name='a.example.com' ip='192.168.122.10' />
>>> +      <host mac='00:16:3e:3e:a9:1a' name='b.example.com' ip='192.168.122.11' />
>>> +    </dhcp>
>>> +  </ip>
>>> +  <ip family='ipv4' address='192.168.123.1' netmask='255.255.255.0'>
>>> +  </ip>
>>> +  <ip family='ipv6' address='2001:db8:ac10:fe01::1' prefix='64'>
>>> +  </ip>
>>> +  <ip family='ipv6' address='2001:db8:ac10:fd01::1' prefix='64'>
>>> +  </ip>
>>> +  <ip family='ipv4' address='10.24.10.1'>
>>> +  </ip>
>>> +</network>
>>> diff --git a/tests/networkxml2xmltest.c b/tests/networkxml2xmltest.c
>>> index 5cdbedb..8ee8e0e 100644
>>> --- a/tests/networkxml2xmltest.c
>>> +++ b/tests/networkxml2xmltest.c
>>> @@ -87,6 +87,7 @@ mymain(void)
>>>      DO_TEST("netboot-network");
>>>      DO_TEST("netboot-proxy-network");
>>>      DO_TEST("nat-network-dns-txt-record");
>>> +    DO_TEST("nat-network-dns-srv-record");
>>>      DO_TEST("nat-network-dns-hosts");
>>>      DO_TEST("8021Qbh-net");
>>>      DO_TEST("direct-net");
>>   I like the principle and directions of the patch but there is some
>> needed checks and cleanup before pushing it :-)
> Daniel
>


-- 
Michal Novotny <minovotn at redhat.com>, RHCE, Red Hat
Virtualization | libvirt-php bindings | php-virt-control.org




More information about the libvir-list mailing list