KVM: configure bridged NICs at migration start
authorApollon Oikonomopoulos <apollon@noc.grnet.gr>
Wed, 22 Jun 2011 09:03:41 +0000 (12:03 +0300)
committerGuido Trotter <ultrotter@google.com>
Mon, 27 Jun 2011 21:56:09 +0000 (17:56 -0400)
Commit 5d9bfd870 moved tap interface handling from KVM to Ganeti, partly
to also solve the problem of routed interfaces getting configured too
early during live migrations, causing network anomalies. In that
direction, configuration of NICs of incoming instances was deferred to
FinalizeMigration time.

However, this causes minor issues with bridged interfaces; KVM sends out
an ARP-like packet upon migration finish, which is lost because the tap
interface is not yet configured. As a consequence, intermediate network
equipment (i.e. switches) does not get notified about the topology
change, until the instance transmits another packet after the bridge has
been configured, or the switch's ARP cache expires.

The proper solution to that is to support different phases in network
configuration (pre/post migration), which also requires separate ifup
scripts. Until then we fall back to configuring bridged interfaces on
incoming instances at migration start, instead of finish.

Signed-off-by: Apollon Oikonomopoulos <apollon@noc.grnet.gr>
Signed-off-by: Guido Trotter <ultrotter@google.com>
Reviewed-by: Guido Trotter <ultrotter@google.com>
Reviewed-by: Michael Hanselmann <hansmi@google.com>

lib/hypervisor/hv_kvm.py

index e65d330..475b99d 100644 (file)
@@ -857,11 +857,13 @@ class KVMHypervisor(hv_base.BaseHypervisor):
       utils.EnsureDirs([(self._InstanceChrootDir(name),
                          constants.SECURE_DIR_MODE)])
 
-    if not incoming:
-      # Configure the network now for starting instances, during
-      # FinalizeMigration for incoming instances
-      for nic_seq, nic in enumerate(kvm_nics):
-        self._ConfigureNIC(instance, nic_seq, nic, taps[nic_seq])
+    # Configure the network now for starting instances and bridged interfaces,
+    # during FinalizeMigration for incoming instances' routed interfaces
+    for nic_seq, nic in enumerate(kvm_nics):
+      if (incoming and
+          nic.nicparams[constants.NIC_MODE] != constants.NIC_MODE_BRIDGED):
+        continue
+      self._ConfigureNIC(instance, nic_seq, nic, taps[nic_seq])
 
     if security_model == constants.HT_SM_POOL:
       ss = ssconf.SimpleStore()
@@ -1026,6 +1028,9 @@ class KVMHypervisor(hv_base.BaseHypervisor):
       kvm_nics = kvm_runtime[1]
 
       for nic_seq, nic in enumerate(kvm_nics):
+        if nic.nicparams[constants.NIC_MODE] == constants.NIC_MODE_BRIDGED:
+          # Bridged interfaces have already been configured
+          continue
         try:
           tap = utils.ReadFile(self._InstanceNICFile(instance.name, nic_seq))
         except EnvironmentError, err: