]> xenbits.xensource.com Git - libvirt.git/commitdiff
conf: parse/format <teaming> subelement of <interface>
authorLaine Stump <laine@redhat.com>
Wed, 22 Jan 2020 21:24:10 +0000 (16:24 -0500)
committerLaine Stump <laine@redhat.com>
Wed, 29 Jan 2020 20:33:29 +0000 (15:33 -0500)
The subelement <teaming> of <interface> devices is used to configure a
simple teaming association between two interfaces in a domain. Example:

  <interface type='bridge'>
    <source bridge='br0'/>
    <model type='virtio'/>
    <mac address='00:11:22:33:44:55'/>
    <alias name='ua-backup0'/>
    <teaming type='persistent'/>
  </interface>
  <interface type='hostdev'>
    <source>
      <address type='pci' bus='0x02' slot='0x10' function='0x4'/>
    </source>
    <mac address='00:11:22:33:44:55'/>
    <teaming type='transient' persistent='ua-backup0'/>
  </interface>

The interface with <teaming type='persistent'/> is assumed to always
be present, while the interface with type='transient' may be be
unplugged and later re-plugged; the persistent='blah' attribute (and
in the one currently available implementation, also the matching MAC
addresses) is what associates the two devices with each other. It is
up to the hypervisor and the guest network drivers to determine what
to do with this information.

Signed-off-by: Laine Stump <laine@redhat.com>
Reviewed-by: Daniel P. Berrangé <berrange@redhat.com>
docs/schemas/domaincommon.rng
src/conf/domain_conf.c
src/conf/domain_conf.h
tests/qemuxml2argvdata/net-virtio-teaming-network.xml [new file with mode: 0644]
tests/qemuxml2argvdata/net-virtio-teaming.xml [new file with mode: 0644]
tests/qemuxml2xmloutdata/net-virtio-teaming-network.xml [new file with mode: 0644]
tests/qemuxml2xmloutdata/net-virtio-teaming.xml [new file with mode: 0644]
tests/qemuxml2xmltest.c

index 992525765002efe8e6f8f3946a3916eda02f0792..ea237a05e56654bc3ed3c0c3aad891bfe8e6ca3a 100644 (file)
       <optional>
         <ref name="vlan"/>
       </optional>
+      <optional>
+        <element name="teaming">
+          <choice>
+            <group>
+              <attribute name="type">
+                <value>persistent</value>
+              </attribute>
+            </group>
+            <group>
+              <attribute name="type">
+                <value>transient</value>
+              </attribute>
+              <attribute name="persistent">
+                <ref name="aliasName"/>
+              </attribute>
+            </group>
+          </choice>
+        </element>
+      </optional>
     </interleave>
   </define>
 
index 2443e408ed8a6d00f537bd27cf6e08c81790c329..e696a8ff76be627fe9b8f0b21f4b426b4e5ab00e 100644 (file)
@@ -555,6 +555,13 @@ VIR_ENUM_IMPL(virDomainNetVirtioTxMode,
               "timer",
 );
 
+VIR_ENUM_IMPL(virDomainNetTeaming,
+              VIR_DOMAIN_NET_TEAMING_TYPE_LAST,
+              "none",
+              "persistent",
+              "transient",
+);
+
 VIR_ENUM_IMPL(virDomainNetInterfaceLinkState,
               VIR_DOMAIN_NET_INTERFACE_LINK_STATE_LAST,
               "default",
@@ -6306,6 +6313,21 @@ virDomainNetDefValidate(const virDomainNetDef *net)
                        virDomainNetTypeToString(net->type));
         return -1;
     }
+
+    if (net->teaming.type == VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT) {
+        if (!net->teaming.persistent) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED, "%s",
+                           _("teaming persistent attribute must be set if teaming type is 'transient'"));
+            return -1;
+        }
+    } else {
+        if (net->teaming.persistent) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("teaming persistent attribute not allowed if teaming type is '%s'"),
+                           virDomainNetTeamingTypeToString(net->teaming.type));
+            return -1;
+        }
+    }
     return 0;
 }
 
@@ -11588,6 +11610,8 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
     g_autofree char *vhostuser_type = NULL;
     g_autofree char *trustGuestRxFilters = NULL;
     g_autofree char *vhost_path = NULL;
+    g_autofree char *teamingType = NULL;
+    g_autofree char *teamingPersistent = NULL;
     const char *prefix = xmlopt ? xmlopt->config.netPrefix : NULL;
 
     if (!(def = virDomainNetDefNew(xmlopt)))
@@ -11789,6 +11813,10 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
                 if (!vhost_path && (tmp = virXMLPropString(cur, "vhost")))
                     vhost_path = virFileSanitizePath(tmp);
                 VIR_FREE(tmp);
+            } else if (virXMLNodeNameEqual(cur, "teaming") &&
+                       !teamingType && !teamingPersistent) {
+                teamingType = virXMLPropString(cur, "type");
+                teamingPersistent =  virXMLPropString(cur, "persistent");
             }
         }
         cur = cur->next;
@@ -12310,6 +12338,19 @@ virDomainNetDefParseXML(virDomainXMLOptionPtr xmlopt,
         }
     }
 
+    if (teamingType) {
+        int tmpTeaming;
+
+        if ((tmpTeaming = virDomainNetTeamingTypeFromString(teamingType)) <= 0) {
+            virReportError(VIR_ERR_CONFIG_UNSUPPORTED,
+                           _("unknown teaming type '%s'"),
+                           teamingType);
+            goto error;
+        }
+        def->teaming.type = tmpTeaming;
+    }
+    def->teaming.persistent = g_steal_pointer(&teamingPersistent);
+
     rv = virXPathULong("string(./tune/sndbuf)", ctxt, &def->tune.sndbuf);
     if (rv >= 0) {
         def->tune.sndbuf_specified = true;
@@ -25885,6 +25926,12 @@ virDomainNetDefFormat(virBufferPtr buf,
         virBufferAddLit(buf,   "</tune>\n");
     }
 
+    if (def->teaming.type != VIR_DOMAIN_NET_TEAMING_TYPE_NONE) {
+        virBufferAsprintf(buf, "<teaming type='%s'",
+                          virDomainNetTeamingTypeToString(def->teaming.type));
+        virBufferEscapeString(buf, " persistent='%s'", def->teaming.persistent);
+        virBufferAddLit(buf, "/>\n");
+    }
     if (def->linkstate) {
         virBufferAsprintf(buf, "<link state='%s'/>\n",
                           virDomainNetInterfaceLinkStateTypeToString(def->linkstate));
index 5feb70938e40b53ea9630c2b89991c76becdd947..e144f3aad3d7fce464eb1ede57b15da9debfdcc7 100644 (file)
@@ -886,6 +886,15 @@ typedef enum {
     VIR_DOMAIN_NET_VIRTIO_TX_MODE_LAST
 } virDomainNetVirtioTxModeType;
 
+/* the type of teaming device */
+typedef enum {
+    VIR_DOMAIN_NET_TEAMING_TYPE_NONE,
+    VIR_DOMAIN_NET_TEAMING_TYPE_PERSISTENT,
+    VIR_DOMAIN_NET_TEAMING_TYPE_TRANSIENT,
+
+    VIR_DOMAIN_NET_TEAMING_TYPE_LAST
+} virDomainNetTeamingType;
+
 /* link interface states */
 typedef enum {
         VIR_DOMAIN_NET_INTERFACE_LINK_STATE_DEFAULT = 0, /* Default link state (up) */
@@ -960,6 +969,10 @@ struct _virDomainNetDef {
         char *tap;
         char *vhost;
     } backend;
+    struct {
+        virDomainNetTeamingType type;
+        char *persistent; /* alias name of persistent device */
+    } teaming;
     union {
         virDomainChrSourceDefPtr vhostuser;
         struct {
@@ -3430,6 +3443,7 @@ VIR_ENUM_DECL(virDomainFSModel);
 VIR_ENUM_DECL(virDomainNet);
 VIR_ENUM_DECL(virDomainNetBackend);
 VIR_ENUM_DECL(virDomainNetVirtioTxMode);
+VIR_ENUM_DECL(virDomainNetTeaming);
 VIR_ENUM_DECL(virDomainNetInterfaceLinkState);
 VIR_ENUM_DECL(virDomainNetModel);
 VIR_ENUM_DECL(virDomainChrDevice);
diff --git a/tests/qemuxml2argvdata/net-virtio-teaming-network.xml b/tests/qemuxml2argvdata/net-virtio-teaming-network.xml
new file mode 100644 (file)
index 0000000..edab52f
--- /dev/null
@@ -0,0 +1,37 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-i386</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <interface type='network'>
+      <mac address='00:11:22:33:44:55'/>
+      <source network='mybridge'/>
+      <model type='virtio'/>
+      <teaming type='persistent'/>
+      <alias name='ua-backup0'/>
+    </interface>
+    <interface type='network'>
+      <mac address='00:11:22:33:44:55'/>
+      <source network='myhostdevpool'/>
+      <model type='virtio'/>
+      <teaming type='transient' persistent='ua-backup0'/>
+    </interface>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2argvdata/net-virtio-teaming.xml b/tests/qemuxml2argvdata/net-virtio-teaming.xml
new file mode 100644 (file)
index 0000000..830ce28
--- /dev/null
@@ -0,0 +1,50 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-i386</emulator>
+    <disk type='block' device='disk'>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+    </disk>
+    <controller type='usb' index='0'/>
+    <interface type='user'>
+      <mac address='00:11:22:33:44:55'/>
+      <model type='virtio'/>
+      <teaming type='persistent'/>
+      <alias name='ua-backup0'/>
+    </interface>
+    <interface type='user'>
+      <mac address='66:44:33:22:11:00'/>
+      <model type='virtio'/>
+      <teaming type='persistent'/>
+      <alias name='ua-backup1'/>
+    </interface>
+    <interface type='hostdev' managed='yes'>
+      <mac address='00:11:22:33:44:55'/>
+      <source>
+        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x1'/>
+      </source>
+      <teaming type='transient' persistent='ua-backup0'/>
+    </interface>
+    <interface type='hostdev' managed='yes'>
+      <mac address='66:44:33:22:11:00'/>
+      <source>
+        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x2'/>
+      </source>
+      <teaming type='transient' persistent='ua-backup1'/>
+    </interface>
+    <memballoon model='virtio'/>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/net-virtio-teaming-network.xml b/tests/qemuxml2xmloutdata/net-virtio-teaming-network.xml
new file mode 100644 (file)
index 0000000..e0dbeaf
--- /dev/null
@@ -0,0 +1,51 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-i386</emulator>
+    <disk type='block' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'/>
+    <controller type='ide' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <interface type='network'>
+      <mac address='00:11:22:33:44:55'/>
+      <source network='mybridge'/>
+      <model type='virtio'/>
+      <teaming type='persistent'/>
+      <alias name='ua-backup0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </interface>
+    <interface type='network'>
+      <mac address='00:11:22:33:44:55'/>
+      <source network='myhostdevpool'/>
+      <model type='virtio'/>
+      <teaming type='transient' persistent='ua-backup0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+    </interface>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='virtio'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
+    </memballoon>
+  </devices>
+</domain>
diff --git a/tests/qemuxml2xmloutdata/net-virtio-teaming.xml b/tests/qemuxml2xmloutdata/net-virtio-teaming.xml
new file mode 100644 (file)
index 0000000..5a56957
--- /dev/null
@@ -0,0 +1,66 @@
+<domain type='qemu'>
+  <name>QEMUGuest1</name>
+  <uuid>c7a5fdbd-edaf-9455-926a-d65c16db1809</uuid>
+  <memory unit='KiB'>219100</memory>
+  <currentMemory unit='KiB'>219100</currentMemory>
+  <vcpu placement='static'>1</vcpu>
+  <os>
+    <type arch='i686' machine='pc'>hvm</type>
+    <boot dev='hd'/>
+  </os>
+  <clock offset='utc'/>
+  <on_poweroff>destroy</on_poweroff>
+  <on_reboot>restart</on_reboot>
+  <on_crash>destroy</on_crash>
+  <devices>
+    <emulator>/usr/bin/qemu-system-i386</emulator>
+    <disk type='block' device='disk'>
+      <driver name='qemu' type='raw'/>
+      <source dev='/dev/HostVG/QEMUGuest1'/>
+      <target dev='hda' bus='ide'/>
+      <address type='drive' controller='0' bus='0' target='0' unit='0'/>
+    </disk>
+    <controller type='usb' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x2'/>
+    </controller>
+    <controller type='pci' index='0' model='pci-root'/>
+    <controller type='ide' index='0'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x01' function='0x1'/>
+    </controller>
+    <interface type='user'>
+      <mac address='00:11:22:33:44:55'/>
+      <model type='virtio'/>
+      <teaming type='persistent'/>
+      <alias name='ua-backup0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x03' function='0x0'/>
+    </interface>
+    <interface type='user'>
+      <mac address='66:44:33:22:11:00'/>
+      <model type='virtio'/>
+      <teaming type='persistent'/>
+      <alias name='ua-backup1'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x04' function='0x0'/>
+    </interface>
+    <interface type='hostdev' managed='yes'>
+      <mac address='00:11:22:33:44:55'/>
+      <source>
+        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x1'/>
+      </source>
+      <teaming type='transient' persistent='ua-backup0'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x05' function='0x0'/>
+    </interface>
+    <interface type='hostdev' managed='yes'>
+      <mac address='66:44:33:22:11:00'/>
+      <source>
+        <address type='pci' domain='0x0000' bus='0x03' slot='0x07' function='0x2'/>
+      </source>
+      <teaming type='transient' persistent='ua-backup1'/>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x06' function='0x0'/>
+    </interface>
+    <input type='mouse' bus='ps2'/>
+    <input type='keyboard' bus='ps2'/>
+    <memballoon model='virtio'>
+      <address type='pci' domain='0x0000' bus='0x00' slot='0x07' function='0x0'/>
+    </memballoon>
+  </devices>
+</domain>
index 2c62de8fe8d6394d4e9dfec94200d7980d862696..fa238ec339249aac2bb2ca0d34ef836adcd9a775 100644 (file)
@@ -455,6 +455,12 @@ mymain(void)
     DO_TEST("net-eth-unmanaged-tap", NONE);
     DO_TEST("net-virtio-network-portgroup", NONE);
     DO_TEST("net-virtio-rxtxqueuesize", NONE);
+    DO_TEST("net-virtio-teaming",
+            QEMU_CAPS_VIRTIO_NET_FAILOVER,
+            QEMU_CAPS_DEVICE_VFIO_PCI);
+    DO_TEST("net-virtio-teaming-network",
+            QEMU_CAPS_VIRTIO_NET_FAILOVER,
+            QEMU_CAPS_DEVICE_VFIO_PCI);
     DO_TEST("net-hostdev", NONE);
     DO_TEST("net-hostdev-bootorder", NONE);
     DO_TEST("net-hostdev-vfio", QEMU_CAPS_DEVICE_VFIO_PCI);