summaryrefslogtreecommitdiffstats
path: root/extras/vpp_config/vpplib/VppGrubUtil.py
diff options
context:
space:
mode:
Diffstat (limited to 'extras/vpp_config/vpplib/VppGrubUtil.py')
-rw-r--r--extras/vpp_config/vpplib/VppGrubUtil.py236
1 files changed, 236 insertions, 0 deletions
diff --git a/extras/vpp_config/vpplib/VppGrubUtil.py b/extras/vpp_config/vpplib/VppGrubUtil.py
new file mode 100644
index 00000000000..4aac427c22a
--- /dev/null
+++ b/extras/vpp_config/vpplib/VppGrubUtil.py
@@ -0,0 +1,236 @@
+# Copyright (c) 2016 Cisco and/or its affiliates.
+# 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.
+
+"""VPP Grub Utility Library."""
+
+import re
+
+from vpplib.VPPUtil import VPPUtil
+
+__all__ = ['VppGrubUtil']
+
+
+class VppGrubUtil(object):
+ """ VPP Grub Utilities."""
+
+ def _get_current_cmdline(self):
+ """
+ Using /proc/cmdline return the current grub cmdline
+
+ :returns: The current grub cmdline
+ :rtype: string
+ """
+
+ # Get the memory information using /proc/meminfo
+ cmd = 'sudo cat /proc/cmdline'
+ (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
+ if ret != 0:
+ raise RuntimeError('{} on node {} {} {}'.
+ format(cmd, self._node['host'],
+ stdout, stderr))
+
+ self._current_cmdline = stdout.strip('\n')
+
+ def _get_default_cmdline(self):
+ """
+ Using /etc/default/grub return the default grub cmdline
+
+ :returns: The default grub cmdline
+ :rtype: string
+ """
+
+ # Get the default grub cmdline
+ rootdir = self._node['rootdir']
+ gfile = self._node['cpu']['grub_config_file']
+ grubcmdline = self._node['cpu']['grubcmdline']
+ cmd = 'cat {}'.format(rootdir + gfile)
+ (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
+ if ret != 0:
+ raise RuntimeError('{} Executing failed on node {} {}'.
+ format(cmd, self._node['host'], stderr))
+
+ # Get the Default Linux command line, ignoring commented lines
+ lines = stdout.split('\n')
+ for line in lines:
+ if line == '' or line[0] == '#':
+ continue
+ ldefault = re.findall(r'{}=.+'.format(grubcmdline), line)
+ if ldefault:
+ self._default_cmdline = ldefault[0]
+ break
+
+ def get_current_cmdline(self):
+ """
+ Returns the saved grub cmdline
+
+ :returns: The saved grub cmdline
+ :rtype: string
+ """
+ return self._current_cmdline
+
+ def get_default_cmdline(self):
+ """
+ Returns the default grub cmdline
+
+ :returns: The default grub cmdline
+ :rtype: string
+ """
+ return self._default_cmdline
+
+ def create_cmdline(self, isolated_cpus):
+ """
+ Create the new grub cmdline
+
+ :param isolated_cpus: The isolated cpu string
+ :type isolated_cpus: string
+ :returns: The command line
+ :rtype: string
+ """
+ grubcmdline = self._node['cpu']['grubcmdline']
+ cmdline = self._default_cmdline
+ value = cmdline.split('{}='.format(grubcmdline))[1]
+ value = value.rstrip('"').lstrip('"')
+
+ iommu = re.findall(r'iommu=\w+', value)
+ pstate = re.findall(r'intel_pstate=\w+', value)
+ # If there is already some iommu commands set, leave them,
+ # if not use ours
+ if iommu == [] and pstate == []:
+ value = '{} intel_pstate=disable'.format(value)
+
+ # Replace isolcpus with ours
+ isolcpus = re.findall(r'isolcpus=[\w+\-,]+', value)
+ if not isolcpus:
+ if isolated_cpus != '':
+ value = "{} isolcpus={}".format(value, isolated_cpus)
+ else:
+ if isolated_cpus != '':
+ value = re.sub(r'isolcpus=[\w+\-,]+',
+ 'isolcpus={}'.format(isolated_cpus),
+ value)
+ else:
+ value = re.sub(r'isolcpus=[\w+\-,]+', '', value)
+
+ nohz = re.findall(r'nohz_full=[\w+\-,]+', value)
+ if not nohz:
+ if isolated_cpus != '':
+ value = "{} nohz_full={}".format(value, isolated_cpus)
+ else:
+ if isolated_cpus != '':
+ value = re.sub(r'nohz_full=[\w+\-,]+',
+ 'nohz_full={}'.format(isolated_cpus),
+ value)
+ else:
+ value = re.sub(r'nohz_full=[\w+\-,]+', '', value)
+
+ rcu = re.findall(r'rcu_nocbs=[\w+\-,]+', value)
+ if not rcu:
+ if isolated_cpus != '':
+ value = "{} rcu_nocbs={}".format(value, isolated_cpus)
+ else:
+ if isolated_cpus != '':
+ value = re.sub(r'rcu_nocbs=[\w+\-,]+',
+ 'rcu_nocbs={}'.format(isolated_cpus),
+ value)
+ else:
+ value = re.sub(r'rcu_nocbs=[\w+\-,]+', '', value)
+
+ value = value.lstrip(' ').rstrip(' ')
+ cmdline = '{}="{}"'.format(grubcmdline, value)
+ return cmdline
+
+ def apply_cmdline(self, node, isolated_cpus):
+ """
+ Apply cmdline to the default grub file
+
+ :param node: Node dictionary with cpuinfo.
+ :param isolated_cpus: The isolated cpu string
+ :type node: dict
+ :type isolated_cpus: string
+ :return The vpp cmdline
+ :rtype string
+ """
+
+ vpp_cmdline = self.create_cmdline(isolated_cpus)
+ if vpp_cmdline == '':
+ return vpp_cmdline
+
+ # Update grub
+ # Save the original file
+ rootdir = node['rootdir']
+ grubcmdline = node['cpu']['grubcmdline']
+ ofilename = rootdir + node['cpu']['grub_config_file'] + '.orig'
+ filename = rootdir + node['cpu']['grub_config_file']
+
+ # Write the output file
+ # Does a copy of the original file exist, if not create one
+ (ret, stdout, stderr) = VPPUtil.exec_command('ls {}'.format(ofilename))
+ if ret != 0:
+ if stdout.strip('\n') != ofilename:
+ cmd = 'sudo cp {} {}'.format(filename, ofilename)
+ (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
+ if ret != 0:
+ raise RuntimeError('{} failed on node {} {}'.
+ format(cmd, self._node['host'], stderr))
+
+ # Get the contents of the current grub config file
+ cmd = 'cat {}'.format(filename)
+ (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
+ if ret != 0:
+ raise RuntimeError('{} failed on node {} {}'.format(
+ cmd,
+ self._node['host'],
+ stderr))
+
+ # Write the new contents
+ # Get the Default Linux command line, ignoring commented lines
+ content = ""
+ lines = stdout.split('\n')
+ for line in lines:
+ if line == '':
+ content += line + '\n'
+ continue
+ if line[0] == '#':
+ content += line + '\n'
+ continue
+
+ ldefault = re.findall(r'{}=.+'.format(grubcmdline), line)
+ if ldefault:
+ content += vpp_cmdline + '\n'
+ else:
+ content += line + '\n'
+
+ content = content.replace(r"`", r"\`")
+ content = content.rstrip('\n')
+ cmd = "sudo cat > {0} << EOF\n{1}\n".format(filename, content)
+ (ret, stdout, stderr) = VPPUtil.exec_command(cmd)
+ if ret != 0:
+ raise RuntimeError('{} failed on node {} {}'.format(
+ cmd,
+ self._node['host'],
+ stderr))
+
+ return vpp_cmdline
+
+ def __init__(self, node):
+ distro = VPPUtil.get_linux_distro()
+ if distro[0] == 'Ubuntu':
+ node['cpu']['grubcmdline'] = 'GRUB_CMDLINE_LINUX_DEFAULT'
+ else:
+ node['cpu']['grubcmdline'] = 'GRUB_CMDLINE_LINUX'
+
+ self._node = node
+ self._current_cmdline = ""
+ self._default_cmdline = ""
+ self._get_current_cmdline()
+ self._get_default_cmdline()