1
0
Fork 0

Merge pull request #218 from yarda/arch-specific-tuning

plugins: support cpuinfo_regex and uname_regex matching
This commit is contained in:
Jaroslav Škarvada 2019-11-26 14:40:45 +01:00 committed by GitHub
commit 668e8fec7d
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
5 changed files with 86 additions and 1 deletions

View file

@ -0,0 +1,32 @@
import re
import tuned.logs
from . import base
log = tuned.logs.get()
class cpuinfo_check(base.Function):
"""
Checks regexes against /proc/cpuinfo. Accepts arguments in the
following form: REGEX1, STR1, REGEX2, STR2, ...[, STR_FALLBACK]
If REGEX1 matches something in /proc/cpuinfo it expands to STR1,
if REGEX2 matches it expands to STR2. It stops on the first match,
i.e. if REGEX1 matches, no more regexes are processed. If none
regex matches it expands to STR_FALLBACK. If there is no fallback,
it expands to empty string.
"""
def __init__(self):
# unlimited number of arguments, min 2 arguments
super(cpuinfo_check, self).__init__("cpuinfo_check", 0, 2)
def execute(self, args):
if not super(cpuinfo_check, self).execute(args):
return None
cpuinfo = self._cmd.read_file("/proc/cpuinfo")
for i in range(0, len(args), 2):
if i + 1 < len(args):
if re.search(args[i], cpuinfo, re.MULTILINE):
return args[i + 1]
if len(args) % 2:
return args[-1]
else:
return ""

View file

@ -62,12 +62,18 @@ class Loader(object):
del(final_profile.units["variables"])
# FIXME hack, do all variable expansions in one place
self._expand_vars_in_devices(final_profile)
self._expand_vars_in_regexes(final_profile)
return final_profile
def _expand_vars_in_devices(self, profile):
for unit in profile.units:
profile.units[unit].devices = self._variables.expand(profile.units[unit].devices)
def _expand_vars_in_regexes(self, profile):
for unit in profile.units:
profile.units[unit].cpuinfo_regex = self._variables.expand(profile.units[unit].cpuinfo_regex)
profile.units[unit].uname_regex = self._variables.expand(profile.units[unit].uname_regex)
def _load_profile(self, profile_names, profiles, processed_files):
for name in profile_names:
filename = self._profile_locator.get_config(name, processed_files)

View file

@ -35,6 +35,10 @@ class Merger(object):
profile_a.units[unit_name].devices = unit.devices
if unit.devices_udev_regex is not None:
profile_a.units[unit_name].devices_udev_regex = unit.devices_udev_regex
if unit.cpuinfo_regex is not None:
profile_a.units[unit_name].cpuinfo_regex = unit.cpuinfo_regex
if unit.uname_regex is not None:
profile_a.units[unit_name].uname_regex = unit.uname_regex
if unit.script_pre is not None:
profile_a.units[unit_name].script_pre = unit.script_pre
if unit.script_post is not None:

View file

@ -6,7 +6,7 @@ class Unit(object):
"""
__slots__ = [ "_name", "_type", "_enabled", "_replace", "_devices", "_devices_udev_regex", \
"_script_pre", "_script_post", "_options" ]
"_cpuinfo_regex", "_uname_regex", "_script_pre", "_script_post", "_options" ]
def __init__(self, name, config):
self._name = name
@ -15,6 +15,8 @@ class Unit(object):
self._replace = config.pop("replace", False) in [True, "true", 1, "1"]
self._devices = config.pop("devices", "*")
self._devices_udev_regex = config.pop("devices_udev_regex", None)
self._cpuinfo_regex = config.pop("cpuinfo_regex", None)
self._uname_regex = config.pop("uname_regex", None)
self._script_pre = config.pop("script_pre", None)
self._script_post = config.pop("script_post", None)
self._options = collections.OrderedDict(config)
@ -59,6 +61,22 @@ class Unit(object):
def devices_udev_regex(self, value):
self._devices_udev_regex = value
@property
def cpuinfo_regex(self):
return self._cpuinfo_regex
@cpuinfo_regex.setter
def cpuinfo_regex(self, value):
self._cpuinfo_regex = value
@property
def uname_regex(self):
return self._uname_regex
@uname_regex.setter
def uname_regex(self, value):
self._uname_regex = value
@property
def script_pre(self):
return self._script_pre

View file

@ -1,9 +1,12 @@
import collections
import os
import re
import traceback
import tuned.exceptions
import tuned.logs
import tuned.plugins.exceptions
import tuned.consts as consts
from tuned.utils.commands import commands
log = tuned.logs.get()
@ -23,6 +26,7 @@ class Manager(object):
self._hardware_inventory = hardware_inventory
self._instances = []
self._plugins = []
self._cmd = commands()
@property
def plugins(self):
@ -36,12 +40,33 @@ class Manager(object):
def plugins_repository(self):
return self._plugins_repository
def _unit_matches_cpuinfo(self, unit):
if unit.cpuinfo_regex is None:
return True
return re.search(unit.cpuinfo_regex,
self._cmd.read_file("/proc/cpuinfo"),
re.MULTILINE) is not None
def _unit_matches_uname(self, unit):
if unit.uname_regex is None:
return True
return re.search(unit.uname_regex,
" ".join(os.uname()),
re.MULTILINE) is not None
def create(self, instances_config):
instance_info_list = []
for instance_name, instance_info in list(instances_config.items()):
if not instance_info.enabled:
log.debug("skipping disabled instance '%s'" % instance_name)
continue
if not self._unit_matches_cpuinfo(instance_info):
log.debug("skipping instance '%s', cpuinfo does not match" % instance_name)
continue
if not self._unit_matches_uname(instance_info):
log.debug("skipping instance '%s', uname does not match" % instance_name)
continue
instance_info.options.setdefault("priority", self._def_instance_priority)
instance_info.options["priority"] = int(instance_info.options["priority"])
instance_info_list.append(instance_info)