Ido Barkan has uploaded a new change for review. Change subject: network: restore sriov devices number of vfs ......................................................................
network: restore sriov devices number of vfs vdsm-restore-net-config will attempt to restore the number of vfs from the last successful change. If no sriov devices are found the function only tries to collect garbage. This is done before network restoration so that networks can be configured based on the restored vfs. The patch also introduces a 'safe' changing of number of vfs of an sriov card which also checks if the connectivity to the engine was lost as a consequence. Change-Id: I76b898019840ffe65939ffad4a1e98829ad3c887 Signed-off-by: Ido Barkan <ibar...@redhat.com> --- M vdsm/network/api.py M vdsm/vdsm-restore-net-config 2 files changed, 85 insertions(+), 5 deletions(-) git pull ssh://gerrit.ovirt.org:29418/vdsm refs/changes/88/40088/1 diff --git a/vdsm/network/api.py b/vdsm/network/api.py index bc2dbd2..07f2640 100755 --- a/vdsm/network/api.py +++ b/vdsm/network/api.py @@ -40,6 +40,7 @@ import hooks # TODO: Turn into parent package import when vdsm is a package CONNECTIVITY_TIMEOUT_DEFAULT = 4 +_SYSFS_SRIOV_NUMVFS = '/sys/bus/pci/devices/{}/sriov_numvfs' def _getConfiguratorClass(): @@ -541,17 +542,51 @@ 'connectivity check failed') -def changeNumvfs(device_name, numvfs): - with open('/sys/bus/pci/devices/{}/sriov_numvfs'.format( - device_name), 'w', 0) as f: +def _update_num_vfs(device_name, num_vfs): + with open(_SYSFS_SRIOV_NUMVFS.format(device_name), 'w', 0) as f: # Zero needs to be written first in order to remove previous VFs. # Trying to just write the number (if n > 0 VF's existed before) # results in 'write error: Device or resource busy' # https://www.kernel.org/doc/Documentation/PCI/pci-iov-howto.txt f.write('0') + f.write(str(num_vfs)) + + +def _persist_num_vfs(device_name, numvfs): + dir_path = os.path.join(constants.P_VDSM_LIB, 'virtual_functions') + try: + os.makedirs(dir_path) + except OSError as ose: + if errno.EEXIST != ose.errno: + raise + with open(dir_path, device_name, 'w') as f: f.write(str(numvfs)) +def changeNumvfs(device_name, num_vfs): + """Change number of virtual functions of a device in a 'safe' way. If the + connectivity to engine is lost as a consequence, the value is restored. + Since calling this verb is currently blocked by engine if this device is + already in use, the logic does not attempt to do anything further, such as + restoring possibly lost networks. + The persistence is stored in a place which is writable also in ovirt-node. + Garbage is will be collected during restoration. + """ + original_value = _get_num_vfs(device_name) + _update_num_vfs(device_name, num_vfs) + if not clientSeen(): + _update_num_vfs(device_name, original_value) + raise ConfigNetworkError( + ne.ERR_LOST_CONNECTION, 'connectivity check failed') + + _persist_num_vfs(device_name, num_vfs) + + +def _get_num_vfs(device_name): + with open(_SYSFS_SRIOV_NUMVFS.format(device_name), 'r', 0) as f: + return int(f.read()) + + def _validateNetworkSetup(networks, bondings): for network, networkAttrs in networks.iteritems(): if networkAttrs.get('remove', False): diff --git a/vdsm/vdsm-restore-net-config b/vdsm/vdsm-restore-net-config index 21d6592..afe4abd 100755 --- a/vdsm/vdsm-restore-net-config +++ b/vdsm/vdsm-restore-net-config @@ -27,21 +27,64 @@ from vdsm.config import config from vdsm import netinfo -from vdsm.constants import P_VDSM_RUN +from vdsm.constants import P_VDSM_RUN, P_VDSM_LIB +import hostdev # Ifcfg persistence restoration from network.configurators import ifcfg # Unified persistence restoration -from network.api import setupNetworks +from network.api import setupNetworks, changeNumvfs from network import configurators from vdsm.netconfpersistence import RunningConfig, PersistentConfig import pkgutil _NETS_RESTORED_MARK = os.path.join(P_VDSM_RUN, 'nets_restored') +_VIRTUAL_FUNCTIONS_PATH = os.path.join(P_VDSM_LIB, 'virtual_functions') + + +def _get_sriov_devices(): + devices = hostdev.list_by_caps() + sriov_pci_addrs = [addr for addr, device in devices.iteritems() + if 'totalvfs' in device['params']] + net_devs = [device for device in devices.itervalues() + if device['params']['capability'] == 'net'] + return [device['params']['interface'] for device in net_devs + if device['params']['parent'] in sriov_pci_addrs] + + +def _get_persisted_numvfs(existing_sriov_devices): + num_vfs_by_device = {} + missing_devices = [] + for file_name in os.listdir(_VIRTUAL_FUNCTIONS_PATH): + if file_name not in existing_sriov_devices: + missing_devices.append(file_name) + else: + with open(os.path.join( + _VIRTUAL_FUNCTIONS_PATH, file_name), 'r') as f: + num_vfs_by_device[file_name] = int(f.read().strip()) + + return num_vfs_by_device, missing_devices + + +def _remove_missing_devices_persistence(missing_devices): + for file_name in missing_devices: + os.remove(os.path.join(_VIRTUAL_FUNCTIONS_PATH, file_name)) + + +def _restore_sriov_num_vfs(): + sriov_devices = _get_sriov_devices() + persisted_num_vfs, missing_devices = _get_persisted_numvfs(sriov_devices) + + for device in sriov_devices: + changeNumvfs(device, persisted_num_vfs[device]) + + _remove_missing_devices_persistence(missing_devices) def ifcfg_restoration(): + _restore_sriov_num_vfs() + configWriter = ifcfg.ConfigWriter() configWriter.restorePersistentBackup() @@ -51,6 +94,8 @@ Builds a setupNetworks command from the persistent configuration to set it as running configuration. """ + _restore_sriov_num_vfs() + runningConfig = RunningConfig() removeNetworks = {} removeBonds = {} -- To view, visit https://gerrit.ovirt.org/40088 To unsubscribe, visit https://gerrit.ovirt.org/settings Gerrit-MessageType: newchange Gerrit-Change-Id: I76b898019840ffe65939ffad4a1e98829ad3c887 Gerrit-PatchSet: 1 Gerrit-Project: vdsm Gerrit-Branch: master Gerrit-Owner: Ido Barkan <ibar...@redhat.com> _______________________________________________ vdsm-patches mailing list vdsm-patches@lists.fedorahosted.org https://lists.fedorahosted.org/mailman/listinfo/vdsm-patches