xenserver: Add vm-id to the external_ids.
authorGurucharan Shetty <gshetty@nicira.com>
Mon, 5 Mar 2012 18:20:00 +0000 (10:20 -0800)
committerGurucharan Shetty <gshetty@nicira.com>
Tue, 6 Mar 2012 22:26:09 +0000 (14:26 -0800)
The vm-id external id in the interface table will uniquely identify a VM
that is connected to a bridge through that interface.

In xenserver, this will have the same value as the external id - xs-vm-uuid
and can be overridden by setting the nicira-vm-id key in the other_config
field of VM record of XAPI.

Bug #10020.
Signed-off-by: Gurucharan Shetty <gshetty@nicira.com>
tests/MockXenAPI.py
tests/ovs-xapi-sync.at
vswitchd/vswitch.xml
xenserver/usr_share_openvswitch_scripts_ovs-xapi-sync

index f6ac22f..24f8bd7 100644 (file)
@@ -30,6 +30,7 @@ class XenAPI(object):
         self.network = Network()
         self.pool = Pool()
         self.VIF = VIF()
+        self.VM = VM()
 
     def login_with_password(self, unused_username, unused_password):
         pass
@@ -87,3 +88,11 @@ class VIF(Table):
 
     def __init__(self):
         Table.__init__(self, VIF.__records)
+
+class VM(Table):
+    __records = ({"uuid": "fcb8a3f6-dc04-41d2-8b8a-55afd2b755b8",
+                  "other_config":
+                      {"nicira-vm-id": "custom vm ID"}},)
+
+    def __init__(self):
+        Table.__init__(self, VM.__records)
index 7c467bb..1f0f766 100644 (file)
@@ -51,7 +51,7 @@ AT_CHECK([ovs_vsctl \
                 -- set Interface vif1.0 'external-ids={attached-mac="00:11:22:33:44:55", xs-network-uuid="9b66c68b-a74e-4d34-89a5-20a8ab352d1e", xs-vif-uuid="6ab1b260-398e-49ba-827b-c7696108964c", xs-vm-uuid="fcb8a3f6-dc04-41d2-8b8a-55afd2b755b8"'}])
 OVS_WAIT_UNTIL([ovs_vsctl get interface vif1.0 external-ids:iface-id >/dev/null 2>&1])
 AT_CHECK([ovs_vsctl get interface vif1.0 external-ids], [0],
-  [{attached-mac="00:11:22:33:44:55", iface-id="custom iface ID", iface-status=active, xs-network-uuid="9b66c68b-a74e-4d34-89a5-20a8ab352d1e", xs-vif-uuid="6ab1b260-398e-49ba-827b-c7696108964c", xs-vm-uuid="fcb8a3f6-dc04-41d2-8b8a-55afd2b755b8"}
+  [{attached-mac="00:11:22:33:44:55", iface-id="custom iface ID", iface-status=active, vm-id="custom vm ID", xs-network-uuid="9b66c68b-a74e-4d34-89a5-20a8ab352d1e", xs-vif-uuid="6ab1b260-398e-49ba-827b-c7696108964c", xs-vm-uuid="fcb8a3f6-dc04-41d2-8b8a-55afd2b755b8"}
 ])
 
 # Add corresponding tap and check daemon's work.
@@ -60,15 +60,15 @@ OVS_WAIT_UNTIL([ovs_vsctl get interface tap1.0 external-ids:iface-id >/dev/null
 AT_CHECK([ovs_vsctl \
                 -- get interface vif1.0 external-ids \
                 -- get interface tap1.0 external-ids], [0],
-  [{attached-mac="00:11:22:33:44:55", iface-id="custom iface ID", iface-status=inactive, xs-network-uuid="9b66c68b-a74e-4d34-89a5-20a8ab352d1e", xs-vif-uuid="6ab1b260-398e-49ba-827b-c7696108964c", xs-vm-uuid="fcb8a3f6-dc04-41d2-8b8a-55afd2b755b8"}
-{attached-mac="00:11:22:33:44:55", iface-id="custom iface ID", iface-status=active, xs-network-uuid="9b66c68b-a74e-4d34-89a5-20a8ab352d1e", xs-vif-uuid="6ab1b260-398e-49ba-827b-c7696108964c", xs-vm-uuid="fcb8a3f6-dc04-41d2-8b8a-55afd2b755b8"}
+  [{attached-mac="00:11:22:33:44:55", iface-id="custom iface ID", iface-status=inactive, vm-id="custom vm ID", xs-network-uuid="9b66c68b-a74e-4d34-89a5-20a8ab352d1e", xs-vif-uuid="6ab1b260-398e-49ba-827b-c7696108964c", xs-vm-uuid="fcb8a3f6-dc04-41d2-8b8a-55afd2b755b8"}
+{attached-mac="00:11:22:33:44:55", iface-id="custom iface ID", iface-status=active, vm-id="custom vm ID", xs-network-uuid="9b66c68b-a74e-4d34-89a5-20a8ab352d1e", xs-vif-uuid="6ab1b260-398e-49ba-827b-c7696108964c", xs-vm-uuid="fcb8a3f6-dc04-41d2-8b8a-55afd2b755b8"}
 ])
 
 # Remove corresponding tap and check daemon's work.
 AT_CHECK([ovs_vsctl del-port tap1.0])
 OVS_WAIT_UNTIL([test `ovs_vsctl get interface vif1.0 external-ids:iface-status` = active])
 AT_CHECK([ovs_vsctl get interface vif1.0 external-ids], [0],
-  [{attached-mac="00:11:22:33:44:55", iface-id="custom iface ID", iface-status=active, xs-network-uuid="9b66c68b-a74e-4d34-89a5-20a8ab352d1e", xs-vif-uuid="6ab1b260-398e-49ba-827b-c7696108964c", xs-vm-uuid="fcb8a3f6-dc04-41d2-8b8a-55afd2b755b8"}
+  [{attached-mac="00:11:22:33:44:55", iface-id="custom iface ID", iface-status=active, vm-id="custom vm ID", xs-network-uuid="9b66c68b-a74e-4d34-89a5-20a8ab352d1e", xs-vif-uuid="6ab1b260-398e-49ba-827b-c7696108964c", xs-vm-uuid="fcb8a3f6-dc04-41d2-8b8a-55afd2b755b8"}
 ])
 
 AT_CLEANUP
index 00cfda6..7739793 100644 (file)
         The virtual network to which this interface is attached.
       </column>
 
+      <column name="external_ids" key="vm-id">
+        The VM to which this interface belongs. On XenServer, this will be the
+        same as <ref column="external_ids" key="xs-vm-uuid"/>.
+      </column>
+
       <column name="external_ids" key="xs-vm-uuid">
         The VM to which this interface belongs.
       </column>
index 43af406..7132726 100755 (executable)
@@ -113,6 +113,30 @@ def get_iface_id(if_name, xs_vif_uuid):
         return xs_vif_uuid
 
 
+# By default, the "vm-id" external id in the Interface table is the
+# same as "xs-vm-uuid".  This may be overridden by defining a
+# "nicira-vm-id" key in the "other_config" field of the VM
+# record of XAPI.
+def get_vm_id(if_name, xs_vm_uuid):
+    if not if_name.startswith("vif") and not if_name.startswith("tap"):
+        # Treat whatever was passed into 'xs_vm_uuid' as a default
+        # value for non-VIFs.
+        return xs_vm_uuid
+
+    if not init_session():
+        vlog.warn("Failed to get vm id for interface id %s because"
+                " XAPI session could not be initialized" % if_name)
+        return xs_vm_uuid
+
+    try:
+        vm = session.xenapi.VM.get_by_uuid(xs_vm_uuid)
+        rec = session.xenapi.VM.get_record(vm)
+        return rec['other_config'].get('nicira-vm-id', xs_vm_uuid)
+    except XenAPI.Failure:
+        vlog.warn("Could not find XAPI entry for VIF %s" % if_name)
+        return xs_vm_uuid
+
+
 def set_or_delete(d, key, value):
     if value is None:
         if key in d:
@@ -247,6 +271,7 @@ def main():
 
     bridges = {}                # Map from bridge name to xs_network_uuids
     iface_ids = {}              # Map from xs-vif-uuid to iface-id
+    vm_ids = {}                 # Map from xs-vm-uuid to vm-id
     while True:
         if not force_run and not idl.run():
             poller = ovs.poller.Poller()
@@ -258,6 +283,7 @@ def main():
             vlog.info("Forced to re-run as the result of a SIGHUP")
             bridges = {}
             iface_ids = {}
+            vm_ids = {}
             force_run = False
 
         txn = ovs.db.idl.Transaction(idl)
@@ -280,6 +306,7 @@ def main():
             iface_by_name[row.name] = row
 
         new_iface_ids = {}
+        new_vm_ids = {}
         for row in idl.tables["Interface"].rows.itervalues():
             # Match up paired vif and tap devices.
             if row.name.startswith("vif"):
@@ -315,6 +342,17 @@ def main():
                 iface_id = None
             set_external_id(row, "iface-id", iface_id)
 
+            # Map from xs-vm-uuid to vm-id.
+            xvmu = row.external_ids.get("xs-vm-uuid")
+            if xvmu:
+                vm_id = (new_vm_ids.get(xvmu)
+                         or vm_ids.get(xvmu)
+                         or get_vm_id(row.name, xvmu))
+                new_vm_ids[xvmu] = vm_id
+            else:
+                vm_id = None
+            set_external_id(row, "vm-id", vm_id)
+
             # When there's a vif and a tap, the tap is active (used for
             # traffic).  When there's just a vif, the vif is active.
             #
@@ -329,6 +367,7 @@ def main():
             else:
                 set_external_id(row, "iface-status", None)
         iface_ids = new_iface_ids
+        vm_ids = new_vm_ids
 
         txn.commit_block()