def _supports_dynamic_update(self, vios=None): """ This method returns whether the VIOS supports dynamically updating VLAN ids on VEAs or not. On HMC, this depends on the system's capabilities. :param vios: VioServer DOM object representing VIOS running against :returns boolean: True if dynamic updates supported, False otherwise """ ras.function_tracepoint(LOG, __name__, ras.TRACE_DEBUG, "Enter") if self._supports_dynamic_vlans is None: # Older firmware cannot dynamically update a VEA with vlans (boo). # We cache the ManagedSystem K2Response because that shouldn't # ever change. ras.trace(LOG, __name__, ras.TRACE_DEBUG, ras.msg('info', 'K2_GET_MS')) # Make the K2 call to get the ManagedSystem response ras.function_tracepoint(LOG, __name__, ras.TRACE_DEBUG, 'Getting ManagedSystem') k2entry_ms = self._topo._find_k2_managed_system() ras.function_tracepoint(LOG, __name__, ras.TRACE_DEBUG, 'Got ManagedSystem') # Now check to see if the system supports dynamic vlan additions caps = k2entry_ms.element.find('AssociatedSystem' 'Capabilities') dynamic_lpar = caps.findtext('VirtualEthernetAdapterDynamic' 'LogicalPartitionCapable') # Convert and return what we found as a boolean self._supports_dynamic_vlans = (dynamic_lpar == 'true') return self._supports_dynamic_vlans
def _find_vlan_users(self, vios, vlanid, vswitch=None): """ This method will search for the given vlanid on the system and return two things. First, the pvid of the SEA on the VIOS containing the vlanid. Second, the number of users of that vlanid total (ie, client LPARs in addition to VIOS). :param vios: VIOS dom object we're operating on :param vlanid: VLANID to search for :param vswitch: vswitch name to associate with this vlanid :returns pvid: port vlanid of the SEA on the VIOS containing the vlanid. Will be 0 if not found. :returns num_users: Total number of adapters found with this vlanid. """ ras.function_tracepoint(LOG, __name__, ras.TRACE_DEBUG, "Enter") pvid = 0 num_users = 0 # Find the VIOS's VEA (if any) that has this vlanid configured on it. # Note that this is coming from the database, not the live system. # We assume the database is up to date and if we had a race condition # where two processes were unplugging the same vlanid (and this is # protected by a lock, so only one runs at a time) and the first guy # totally removed the vlanid from the system, the database would # have been updated and the second unplug will see no evidence of that # vlanid on the VIOS reflected in the database at this point. for vea in vios.get_all_virtual_ethernet_adapters(): if vea.is_vlan_configured(vlanid, vswitch): # Found a user of the vlanid num_users += 1 # Remember pvid of adapter containing vlanid pvid = vea.pvid break # Now, get all client lpar adapters to see if any of them have the # vlanid configured. This will be an actual K2 call to the HMC... # which means if there are a lot of LPARs, this will be SLOOOOWWW.... # Apparently this will be coming from the database at some point, so # we got that going for us. Note, we don't cache the LogicalPartition # K2Response because client LPARs come and go. ras.function_tracepoint(LOG, __name__, ras.TRACE_DEBUG, 'Getting LPARs') k2response = self._k2op.read( rootType='ManagedSystem', rootId=self._topo._find_managed_system(), childType='LogicalPartition', timeout=hmc.K2_READ_SEC, xag=[None]) ras.function_tracepoint(LOG, __name__, ras.TRACE_DEBUG, 'Got LPARs') # If we found no client LPARs, just return if not k2response.feed or not k2response.feed.entries: ras.trace(LOG, __name__, ras.TRACE_INFO, ras.msg('info', 'NO_CLIENT_LPAR') % self._topo.host_name) return pvid, num_users # For each LPAR for lpar in k2response.feed.entries: # Build a link to all the ClientNetworkAdapters. cna_links = lpar.element.findall('./ClientNetworkAdapters/link') # If there were some ClientNetworkAdapters if cna_links: # Get the link for the next K2 call. Just use the first # CNA link found because we're going to strip the UUID to get # all adapters in one K2 call anyways. href = cna_links[0].getattrib()['href'] # Strip the UUID href = href[0:href.rfind('/')] + '?group=None' # Get the adapters ras.function_tracepoint(LOG, __name__, ras.TRACE_DEBUG, 'Getting client adapters') k2_adapter_response = self._k2op.readbyhref( href=href, timeout=hmc.K2_READ_SEC) ras.function_tracepoint(LOG, __name__, ras.TRACE_DEBUG, 'Got client adapters') # Be sure we found some client adapters if not k2_adapter_response.feed or \ not k2_adapter_response.feed.entries: ras.trace(LOG, __name__, ras.TRACE_INFO, ras.msg('info', 'NO_CLIENT_ADAPTERS') % {'lpar': lpar.element.findtext('PartitionName'), 'lparid': lpar.element.findtext('PartitionID')}) # Move on to the next client lpar continue # Loop through all adapters and look for our vlanid for adapter in k2_adapter_response.feed.entries: # Get the client adapter's PVID client_pvid = adapter.element.findtext('PortVLANID') # If we found a pvid and it matches our vlanid if client_pvid and int(client_pvid) == vlanid: # Bump the users count num_users += 1 # I don't think we have additional vlans to worry about, # but just in case... addl_vlans = adapter.element.findtext('TaggedVLANIDs') # If we found some additional vlans if addl_vlans: # Make a string list addl_vlans = addl_vlans.split(',') # Now search for our vlanid. Our vlanid is an int, # so we use list comprehension to convert the list of # strings to a list of ints if vlanid in [str(x) for x in addl_vlans]: num_users += 1 return pvid, num_users