diff options
Diffstat (limited to 'azurelinuxagent/pa/rdma')
-rw-r--r-- | azurelinuxagent/pa/rdma/factory.py | 4 | ||||
-rw-r--r-- | azurelinuxagent/pa/rdma/suse.py | 7 | ||||
-rw-r--r-- | azurelinuxagent/pa/rdma/ubuntu.py | 122 |
3 files changed, 130 insertions, 3 deletions
diff --git a/azurelinuxagent/pa/rdma/factory.py b/azurelinuxagent/pa/rdma/factory.py index 535b3d3..92bd2e0 100644 --- a/azurelinuxagent/pa/rdma/factory.py +++ b/azurelinuxagent/pa/rdma/factory.py @@ -21,6 +21,7 @@ from azurelinuxagent.common.version import DISTRO_FULL_NAME, DISTRO_VERSION from azurelinuxagent.common.rdma import RDMAHandler from .suse import SUSERDMAHandler from .centos import CentOSRDMAHandler +from .ubuntu import UbuntuRDMAHandler def get_rdma_handler( @@ -37,5 +38,8 @@ def get_rdma_handler( if distro_full_name == 'CentOS Linux' or distro_full_name == 'CentOS': return CentOSRDMAHandler(distro_version) + if distro_full_name == 'Ubuntu': + return UbuntuRDMAHandler() + logger.info("No RDMA handler exists for distro='{0}' version='{1}'", distro_full_name, distro_version) return RDMAHandler() diff --git a/azurelinuxagent/pa/rdma/suse.py b/azurelinuxagent/pa/rdma/suse.py index d31b2b0..20f06cd 100644 --- a/azurelinuxagent/pa/rdma/suse.py +++ b/azurelinuxagent/pa/rdma/suse.py @@ -36,8 +36,9 @@ class SUSERDMAHandler(RDMAHandler): logger.error(error_msg) return zypper_install = 'zypper -n in %s' + zypper_install_noref = 'zypper -n --no-refresh in %s' zypper_remove = 'zypper -n rm %s' - zypper_search = 'zypper se -s %s' + zypper_search = 'zypper -n se -s %s' package_name = 'msft-rdma-kmp-default' cmd = zypper_search % package_name status, repo_package_info = shellutil.run_get_output(cmd) @@ -108,9 +109,9 @@ class SUSERDMAHandler(RDMAHandler): fw_version in local_package ): logger.info("RDMA: Installing: %s" % local_package) - cmd = zypper_install % local_package + cmd = zypper_install_noref % local_package result = shellutil.run(cmd) - if result: + if result and result != 106: error_msg = 'RDMA: Failed install of package "%s" ' error_msg += 'from local package cache' logger.error(error_msg % local_package) diff --git a/azurelinuxagent/pa/rdma/ubuntu.py b/azurelinuxagent/pa/rdma/ubuntu.py new file mode 100644 index 0000000..050797d --- /dev/null +++ b/azurelinuxagent/pa/rdma/ubuntu.py @@ -0,0 +1,122 @@ +# Microsoft Azure Linux Agent +# +# Copyright 2014 Microsoft Corporation +# +# Licensed under the Apache License, Version 2.0 (the "License"); +# you may not use this file except in compliance with the License. +# You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, software +# distributed under the License is distributed on an "AS IS" BASIS, +# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# See the License for the specific language governing permissions and +# limitations under the License. +# +# Requires Python 2.4+ and Openssl 1.0+ +# + +import glob +import os +import re +import time +import azurelinuxagent.common.conf as conf +import azurelinuxagent.common.logger as logger +import azurelinuxagent.common.utils.shellutil as shellutil +from azurelinuxagent.common.rdma import RDMAHandler + + +class UbuntuRDMAHandler(RDMAHandler): + + def install_driver(self): + #Install the appropriate driver package for the RDMA firmware + + nd_version = RDMAHandler.get_rdma_version() + if not nd_version: + logger.error("RDMA: Could not determine firmware version. No driver will be installed") + return + #replace . with _, we are looking for number like 144_0 + nd_version = re.sub('\.', '_', nd_version) + + #Check to see if we need to reconfigure driver + status,module_name = shellutil.run_get_output('modprobe -R hv_network_direct', chk_err=False) + if status != 0: + logger.info("RDMA: modprobe -R hv_network_direct failed. Use module name hv_network_direct") + module_name = "hv_network_direct" + else: + module_name = module_name.strip() + logger.info("RDMA: current RDMA driver %s nd_version %s" % (module_name, nd_version)) + if module_name == 'hv_network_direct_%s' % nd_version: + logger.info("RDMA: driver is installed and ND version matched. Skip reconfiguring driver") + return + + #Reconfigure driver if one is available + status,output = shellutil.run_get_output('modinfo hv_network_direct_%s' % nd_version); + if status == 0: + logger.info("RDMA: driver with ND version is installed. Link to module name") + self.update_modprobed_conf(nd_version) + return + + #Driver not found. We need to check to see if we need to update kernel + if not conf.enable_rdma_update(): + logger.info("RDMA: driver update is disabled. Skip kernel update") + return + + status,output = shellutil.run_get_output('uname -r') + if status != 0: + return + if not re.search('-azure$', output): + logger.error("RDMA: skip driver update on non-Azure kernel") + return + kernel_version = re.sub('-azure$', '', output) + kernel_version = re.sub('-', '.', kernel_version) + + #Find the new kernel package version + status,output = shellutil.run_get_output('apt-get update') + if status != 0: + return + status,output = shellutil.run_get_output('apt-cache show --no-all-versions linux-azure') + if status != 0: + return + r = re.search('Version: (\S+)', output) + if not r: + logger.error("RDMA: version not found in package linux-azure.") + return + package_version = r.groups()[0] + #Remove the ending .<upload number> after <ABI number> + package_version = re.sub("\.\d+$", "", package_version) + + logger.info('RDMA: kernel_version=%s package_version=%s' % (kernel_version, package_version)) + kernel_version_array = [ int(x) for x in kernel_version.split('.') ] + package_version_array = [ int(x) for x in package_version.split('.') ] + if kernel_version_array < package_version_array: + logger.info("RDMA: newer version available, update kernel and reboot") + status,output = shellutil.run_get_output('apt-get -y install linux-azure') + if status: + logger.error("RDMA: kernel update failed") + return + self.reboot_system() + else: + logger.error("RDMA: no kernel update is avaiable for ND version %s" % nd_version) + + def update_modprobed_conf(self, nd_version): + #Update /etc/modprobe.d/vmbus-rdma.conf to point to the correct driver + + modprobed_file = '/etc/modprobe.d/vmbus-rdma.conf' + lines = '' + if not os.path.isfile(modprobed_file): + logger.info("RDMA: %s not found, it will be created" % modprobed_file) + else: + f = open(modprobed_file, 'r') + lines = f.read() + f.close() + r = re.search('alias hv_network_direct hv_network_direct_\S+', lines) + if r: + lines = re.sub('alias hv_network_direct hv_network_direct_\S+', 'alias hv_network_direct hv_network_direct_%s' % nd_version, lines) + else: + lines += '\nalias hv_network_direct hv_network_direct_%s\n' % nd_version + f = open('/etc/modprobe.d/vmbus-rdma.conf', 'w') + f.write(lines) + f.close() + logger.info("RDMA: hv_network_direct alias updated to ND %s" % nd_version) |