1
0
Fork 0

recommend: add global config option to disable 'recommend' functionality

On some platforms the 'recommend' functionality doens't make sense
as there is only one product variant. On such platforms the recommend
functionality can be disabled by adding/changing the following in
the global config (/etc/tuned/tuned-main.conf):

recommend_command = 0

Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
This commit is contained in:
Jaroslav Škarvada 2015-06-10 16:26:36 +02:00
parent d2043dfaf3
commit c73bc90ae8
10 changed files with 79 additions and 39 deletions

View file

@ -25,8 +25,10 @@ import traceback
import tuned.admin
import tuned.consts as consts
import tuned.version as ver
from tuned.utils.global_config import GlobalConfig
if __name__ == "__main__":
config = GlobalConfig()
parser = argparse.ArgumentParser(description="Manage tuned daemon.")
parser.add_argument('--version', "-v", action = "version", version = "%%(prog)s %s.%s.%s" % (ver.TUNED_VERSION_MAJOR, ver.TUNED_VERSION_MINOR, ver.TUNED_VERSION_PATCH))
parser.add_argument("--debug", "-d", action="store_true", help="show debug messages")
@ -45,8 +47,9 @@ if __name__ == "__main__":
parser_profile.set_defaults(action="profile")
parser_profile.add_argument("profiles", metavar="profile", type=str, nargs="+", help="profile name")
parser_off = subparsers.add_parser("recommend", help="recommend profile")
parser_off.set_defaults(action="recommend_profile")
if config.get(consts.CFG_RECOMMEND_COMMAND, consts.CFG_DEF_RECOMMEND_COMMAND):
parser_off = subparsers.add_parser("recommend", help="recommend profile")
parser_off.set_defaults(action="recommend_profile")
parser_off = subparsers.add_parser("verify", help="verify profile")
parser_off.set_defaults(action="verify_profile")

View file

@ -97,6 +97,7 @@ class Base(object):
self._cmd = commands(debug)
self.config = GlobalConfig()
self.builder = Gtk.Builder()
try:
self.builder.add_from_file(GLADEUI)
@ -298,7 +299,8 @@ class Base(object):
self.builder.get_object('buttonDeleteSelectedProfile')
self.label_actual_profile.set_text(self.controller.active_profile())
self.label_recommended_profile.set_text(self.controller.recommend_profile())
if self.config.get(consts.CFG_RECOMMEND_COMMAND):
self.label_recommended_profile.set_text(self.controller.recommend_profile())
self.listbox_summary_of_active_profile = \
self.builder.get_object('listboxSummaryOfActiveProfile')

View file

@ -10,3 +10,8 @@ sleep_interval = 1
# Update interval for dynamic tunings (in seconds).
# It must be multiply of the sleep_interval
update_interval = 10
# Recommend functionality, if disabled "recommend" command will be not
# available in CLI, daemon will not parse recommend.conf but will return
# one hardcoded profile (by default "balanced")
recommend_command = 1

View file

@ -39,12 +39,19 @@ ENV_PREFIX = "TUNED_"
PREFIX_PROFILE_FACTORY = "Factory"
PREFIX_PROFILE_USER = "User"
CFG_DYNAMIC_TUNING = "dynamic_tuning"
CFG_SLEEP_INTERVAL = "sleep_interval"
CFG_UPDATE_INTERVAL = "update_interval"
CFG_RECOMMEND_COMMAND = "recommend_command"
# default configuration
CFG_DEF_DYNAMIC_TUNING = True
# how long to sleep before checking for events (in seconds)
CFG_DEF_SLEEP_INTERVAL = 1
# update interval for dynamic tuning (in seconds)
CFG_DEF_UPDATE_INTERVAL = 10
# recommend command availability
CFG_DEF_RECOMMEND_COMMAND = 1
STR_VERIFY_PROFILE_DEVICE_VALUE_OK = "verify: passed: device %s: %s = %s"
STR_VERIFY_PROFILE_VALUE_OK = "verify: passed: %s = %s"

View file

@ -1,7 +1,5 @@
from tuned import storage, units, monitors, plugins, profiles, exports, hardware
from tuned.exceptions import TunedException
from configobj import ConfigObj, ConfigObjError
from validate import Validator
import tuned.logs
import controller
import daemon
@ -10,15 +8,12 @@ import os
import sys
import select
import tuned.consts as consts
from tuned.utils.global_config import GlobalConfig
log = tuned.logs.get()
__all__ = ["Application"]
global_config_spec = ["dynamic_tuning = boolean(default=%s)" % consts.CFG_DEF_DYNAMIC_TUNING,
"sleep_interval = integer(default=%s)" % consts.CFG_DEF_SLEEP_INTERVAL,
"update_interval = integer(default=%s)" % consts.CFG_DEF_UPDATE_INTERVAL]
class Application(object):
def __init__(self, profile_name=None):
storage_provider = storage.PickleProvider()
@ -30,8 +25,8 @@ class Application(object):
plugin_instance_factory = plugins.instance.Factory()
self.variables = profiles.variables.Variables()
self.config = self._load_global_config()
if self.config.get("dynamic_tuning"):
self.config = GlobalConfig()
if self.config.get(consts.CFG_DYNAMIC_TUNING):
log.info("dynamic tuning is enabled (can be overriden in plugins)")
else:
log.info("dynamic tuning is globally disabled")
@ -44,9 +39,8 @@ class Application(object):
profile_locator = profiles.Locator(consts.LOAD_DIRECTORIES)
profile_loader = profiles.Loader(profile_locator, profile_factory, profile_merger, self.variables)
self._daemon = daemon.Daemon(unit_manager, profile_loader, profile_name, self.config)
self._controller = controller.Controller(self._daemon)
self._controller = controller.Controller(self._daemon, self.config)
self._dbus_exporter = None
self._init_signals()
@ -175,22 +169,6 @@ class Application(object):
else:
sys.exit(1)
def _load_global_config(self, file_name = consts.GLOBAL_CONFIG_FILE):
"""
Loads global configuration file.
"""
log.debug("reading and parsing global configuration file '%s'" % consts.GLOBAL_CONFIG_FILE)
try:
config = ConfigObj(file_name, configspec=global_config_spec, raise_errors = True, file_error = True, list_values = False, interpolation = False)
except IOError as e:
raise TunedException("Global tuned configuration file '%s' not found." % file_name)
except ConfigObjError as e:
raise TunedException("Error parsing global tuned configuration file '%s'." % file_name)
vdt = Validator()
if (not config.validate(vdt, copy=True)):
raise TunedException("Global tuned configuration file '%s' is not valid." % file_name)
return config
@property
def daemon(self):
return self._daemon

View file

@ -2,6 +2,7 @@ from tuned import exports
import tuned.logs
import tuned.exceptions
import threading
import tuned.consts as consts
from tuned.utils.commands import commands
__all__ = ["Controller"]
@ -14,9 +15,10 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
and export the controller interface (currently only over D-Bus).
"""
def __init__(self, daemon):
def __init__(self, daemon, global_config):
super(self.__class__, self).__init__()
self._daemon = daemon
self._global_config = global_config
self._terminate = threading.Event()
self._cmd = commands()
@ -105,7 +107,7 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
@exports.export("", "s")
def recommend_profile(self):
return self._cmd.recommend_profile()
return self._cmd.recommend_profile(hardcoded = not self._global_config.get(consts.CFG_RECOMMEND_COMMAND, consts.CFG_DEF_RECOMMEND_COMMAND))
@exports.export("", "b")
def verify_profile(self):

View file

@ -16,10 +16,12 @@ class Daemon(object):
self._sleep_interval = int(consts.CFG_DEF_SLEEP_INTERVAL)
self._update_interval = int(consts.CFG_DEF_UPDATE_INTERVAL)
self._dynamic_tuning = consts.CFG_DEF_DYNAMIC_TUNING
self._recommend_command = True
if config is not None:
self._sleep_interval = int(config.get("sleep_interval", consts.CFG_DEF_SLEEP_INTERVAL))
self._update_interval = int(config.get("update_interval", consts.CFG_DEF_UPDATE_INTERVAL))
self._dynamic_tuning = config.get("dynamic_tuning", consts.CFG_DEF_DYNAMIC_TUNING)
self._sleep_interval = int(config.get(consts.CFG_SLEEP_INTERVAL, consts.CFG_DEF_SLEEP_INTERVAL))
self._update_interval = int(config.get(consts.CFG_UPDATE_INTERVAL, consts.CFG_DEF_UPDATE_INTERVAL))
self._dynamic_tuning = config.get(consts.CFG_DYNAMIC_TUNING, consts.CFG_DEF_DYNAMIC_TUNING)
self._recommend_command = config.get(consts.CFG_RECOMMEND_COMMAND, consts.CFG_DEF_RECOMMEND_COMMAND)
if self._sleep_interval <= 0:
self._sleep_interval = int(consts.CFG_DEF_SLEEP_INTERVAL)
if self._update_interval == 0:
@ -136,7 +138,7 @@ class Daemon(object):
def _set_recommended_profile(self):
log.info("no profile preset, checking what is recommended for your configuration")
profile = self._cmd.recommend_profile()
profile = self._cmd.recommend_profile(hardcoded = not self._recommend_command)
log.info("using '%s' profile and setting it as active" % profile)
self._save_active_profile(profile)
return profile

View file

@ -185,7 +185,7 @@ class Plugin(object):
if instance.has_static_tuning:
self._instance_apply_static(instance)
if instance.has_dynamic_tuning and self._global_cfg.get("dynamic_tuning", consts.CFG_DEF_DYNAMIC_TUNING):
if instance.has_dynamic_tuning and self._global_cfg.get(consts.CFG_DYNAMIC_TUNING, consts.CFG_DEF_DYNAMIC_TUNING):
self._run_for_each_device(instance, self._instance_apply_dynamic)
def instance_verify_tuning(self, instance):
@ -206,7 +206,7 @@ class Plugin(object):
"""
if not instance.active:
return
if instance.has_dynamic_tuning and self._global_cfg.get("dynamic_tuning", consts.CFG_DEF_DYNAMIC_TUNING):
if instance.has_dynamic_tuning and self._global_cfg.get(consts.CFG_DYNAMIC_TUNING, consts.CFG_DEF_DYNAMIC_TUNING):
self._run_for_each_device(instance, self._instance_update_dynamic)
# profile_switch is true if unapplying tuning due to profile switch
@ -214,7 +214,7 @@ class Plugin(object):
"""
Remove all tunings applied by the plugin instance.
"""
if instance.has_dynamic_tuning and self._global_cfg.get("dynamic_tuning", consts.CFG_DEF_DYNAMIC_TUNING):
if instance.has_dynamic_tuning and self._global_cfg.get(consts.CFG_DYNAMIC_TUNING, consts.CFG_DEF_DYNAMIC_TUNING):
self._run_for_each_device(instance, self._instance_unapply_dynamic)
if instance.has_static_tuning:
self._instance_unapply_static(instance, profile_switch)

View file

@ -203,8 +203,10 @@ class commands:
s = s.zfill(ls)
return ",".join(s[i:i + 8] for i in range(0, len(s), 8))
def recommend_profile(self):
def recommend_profile(self, hardcoded = False):
profile = consts.DEFAULT_PROFILE
if hardcoded:
return profile
for f in consts.LOAD_DIRECTORIES:
config = ConfigObj(os.path.join(f, consts.AUTODETECT_FILE), list_values = False, interpolation = False)
for section in reversed(config.keys()):

View file

@ -0,0 +1,39 @@
import tuned.logs
from configobj import ConfigObj, ConfigObjError
from validate import Validator
from tuned.exceptions import TunedException
import tuned.consts as consts
__all__ = ["GlobalConfig"]
log = tuned.logs.get()
class GlobalConfig():
global_config_spec = ["dynamic_tuning = boolean(default=%s)" % consts.CFG_DEF_DYNAMIC_TUNING,
"sleep_interval = integer(default=%s)" % consts.CFG_DEF_SLEEP_INTERVAL,
"update_interval = integer(default=%s)" % consts.CFG_DEF_UPDATE_INTERVAL,
"recommend_command = boolean(default=%s)" % consts.CFG_DEF_RECOMMEND_COMMAND]
def __init__(self):
self._cfg = {}
self.load_config()
def load_config(self, file_name = consts.GLOBAL_CONFIG_FILE):
"""
Loads global configuration file.
"""
log.debug("reading and parsing global configuration file '%s'" % consts.GLOBAL_CONFIG_FILE)
try:
self._cfg = ConfigObj(file_name, configspec = self.global_config_spec, raise_errors = True, \
file_error = True, list_values = False, interpolation = False)
except IOError as e:
raise TunedException("Global tuned configuration file '%s' not found." % file_name)
except ConfigObjError as e:
raise TunedException("Error parsing global tuned configuration file '%s'." % file_name)
vdt = Validator()
if (not self._cfg.validate(vdt, copy=True)):
raise TunedException("Global tuned configuration file '%s' is not valid." % file_name)
def get(self, key, default = None):
return self._cfg.get(key, default)