- for rec in idl.data["Bridge"].itervalues():
- name = rec.name.as_scalar()
- xs_network_uuids = rec.external_ids.get("xs-network-uuids")
- bridge_id = rec.external_ids.get("bridge-id")
- new_bridges[name] = {"xs-network-uuids": xs_network_uuids,
- "bridge-id": bridge_id}
-
- new_interfaces = {}
- for rec in idl.data["Interface"].itervalues():
- name = rec.name.as_scalar()
- xs_vif_uuid = rec.external_ids.get("xs-vif-uuid")
- iface_id = rec.external_ids.get("iface-id")
- new_interfaces[name] = {"xs-vif-uuid": xs_vif_uuid,
- "iface-id": iface_id}
-
- if bridges != new_bridges:
- for name,ids in new_bridges.items():
- if name not in bridges:
- update_fail_mode(name)
- update_in_band_mgmt(name)
-
- if (name not in bridges) or (bridges[name] != ids):
- update_bridge_id(name, ids)
-
- bridges = new_bridges
-
- if interfaces != new_interfaces:
- for name,ids in new_interfaces.items():
- if (name not in interfaces) or (interfaces[name] != ids):
- update_iface_id(name, ids)
- interfaces = new_interfaces
+ for row in idl.tables["Bridge"].rows.itervalues():
+ old_xnu = bridges.get(row.name)
+ new_xnu = row.external_ids.get("xs-network-uuids", "")
+ if old_xnu is None:
+ # New bridge.
+ update_fail_mode(row)
+ update_in_band_mgmt(row)
+
+ update_bridge_id(row)
+ new_bridges[row.name] = new_xnu
+ bridges = new_bridges
+
+ iface_by_name = {}
+ for row in idl.tables["Interface"].rows.itervalues():
+ 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"):
+ vif = row
+ tap = iface_by_name.get("tap%s" % row.name[3:])
+ elif row.name.startswith("tap"):
+ tap = row
+ vif = iface_by_name.get("vif%s" % row.name[3:])
+ else:
+ tap = vif = None
+
+ # Several tap external-ids need to be copied from the vif.
+ if row == tap and vif:
+ keys = ["attached-mac",
+ "xs-network-uuid",
+ "xs-vif-uuid",
+ "xs-vm-uuid"]
+ for k in keys:
+ set_external_id(row, k, vif.external_ids.get(k))
+
+ # Map from xs-vif-uuid to iface-id.
+ #
+ # (A tap's xs-vif-uuid comes from its vif. That falls out
+ # naturally from the copy loop above.)
+ xvu = row.external_ids.get("xs-vif-uuid")
+ if xvu:
+ iface_id = (new_iface_ids.get(xvu)
+ or iface_ids.get(xvu)
+ or get_iface_id(row.name, xvu))
+ new_iface_ids[xvu] = iface_id
+ else:
+ # No xs-vif-uuid therefore no iface-id.
+ 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.
+ #
+ # A tap on its own shouldn't happen, and we don't know
+ # anything about other kinds of devices, so we don't use
+ # an iface-status for those devices at all.
+ if vif and tap:
+ set_external_id(tap, "iface-status", "active")
+ set_external_id(vif, "iface-status", "inactive")
+ elif vif:
+ set_external_id(vif, "iface-status", "active")
+ else:
+ set_external_id(row, "iface-status", None)
+ iface_ids = new_iface_ids
+ vm_ids = new_vm_ids
+
+ txn.commit_block()
+