From 14c23e444accefc5d1489729a9598a03c5ba3e8d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jaroslav=20=C5=A0karvada?= Date: Fri, 6 Apr 2012 11:00:39 +0200 Subject: [PATCH 1/4] spec: utils now requires base package (rhbz#809934) --- tuned.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/tuned.spec b/tuned.spec index 04d860b..5fe2c4b 100644 --- a/tuned.spec +++ b/tuned.spec @@ -26,6 +26,7 @@ network and ATA harddisk devices are implemented. %package utils Summary: Disk and net statistic monitoring systemtap scripts +Requires: %{name} = %{version}-%{release} Requires: systemtap %description utils From b23cd4412459e89e60f466cb70eebbeb12ed3176 Mon Sep 17 00:00:00 2001 From: Jan Vcelak Date: Tue, 10 Apr 2012 14:21:18 +0200 Subject: [PATCH 2/4] spec: require python-decorator (rhbz#811196) --- tuned.spec | 1 + 1 file changed, 1 insertion(+) diff --git a/tuned.spec b/tuned.spec index 5fe2c4b..dff7804 100644 --- a/tuned.spec +++ b/tuned.spec @@ -16,6 +16,7 @@ BuildRequires: python, systemd-units Requires(post): systemd-units Requires(preun): systemd-units Requires(postun): systemd-units +Requires: python-decorator %description The tuned package contains a daemon that tunes system settings dynamically. From 4c8d64f98aef5015cad05fdbc987d4fba6e4ae13 Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Mon, 16 Apr 2012 10:55:50 +0200 Subject: [PATCH 3/4] Added is_supported class method into plugin API. It is used to detect if the plugin is supported by the HW and can be loaded. --- tuned/plugins/base.py | 4 ++++ tuned/plugins/plugin_eeepc_she.py | 7 +++++-- tuned/plugins/repository.py | 8 ++++++++ tuned/profile.py | 6 ++++++ 4 files changed, 23 insertions(+), 2 deletions(-) diff --git a/tuned/plugins/base.py b/tuned/plugins/base.py index 7bcfc40..6c8ec6c 100644 --- a/tuned/plugins/base.py +++ b/tuned/plugins/base.py @@ -19,6 +19,10 @@ class Plugin(object): def tunable_devices(cls): return None + @classmethod + def is_supported(cls): + return True + # instance methods def __init__(self, devices = None, options = None): diff --git a/tuned/plugins/plugin_eeepc_she.py b/tuned/plugins/plugin_eeepc_she.py index 42041d4..f7b13ef 100644 --- a/tuned/plugins/plugin_eeepc_she.py +++ b/tuned/plugins/plugin_eeepc_she.py @@ -17,11 +17,14 @@ class EeePCSHEPlugin(tuned.plugins.Plugin): self._she_mode = None self._load_monitor = tuned.monitors.get_repository().create("load", devices) + + @classmethod + def is_supported(cls): try: os.open("/sys/devices/platform/eeepc/cpufv", os.O_WRONLY) + return True except: - log.info("eeepc_she is not supported on you system") - raise + return False @classmethod def _get_default_options(cls): diff --git a/tuned/plugins/repository.py b/tuned/plugins/repository.py index 9ad673e..8c49041 100644 --- a/tuned/plugins/repository.py +++ b/tuned/plugins/repository.py @@ -31,6 +31,14 @@ class PluginRepository(tuned.patterns.Singleton): plugin_exception = tuned.plugins.exception.LoadPluginException(plugin_name, exception) raise plugin_exception + def is_supported(self, plugin_name): + try: + plugin_cls = self._loader.load(plugin_name) + return plugin_cls.is_supported() + except Exception as exception: + plugin_exception = tuned.plugins.exception.LoadPluginException(plugin_name, exception) + raise plugin_exception + def delete(self, plugin): assert isinstance(plugin, self._loader.interface) log.debug("removing plugin %s" % plugin) diff --git a/tuned/profile.py b/tuned/profile.py index b1701f7..f7ddfe4 100644 --- a/tuned/profile.py +++ b/tuned/profile.py @@ -134,6 +134,12 @@ class Profile(object): def _store_plugin_config(self, name, plugin_cfg): plugin = plugin_cfg["type"] + + # Check if the plugin is supported on this HW + if not tuned.plugins.get_repository().is_supported(plugin): + log.info("Plugin %s is not supported on this HW" % (plugin)) + return + # If there are no devices set, set all tunable_devices as default if not plugin_cfg.has_key("devices"): try: From 916c0157f02a95e35ee6bdd713f5aaf06bb8672a Mon Sep 17 00:00:00 2001 From: Jan Kaluza Date: Mon, 16 Apr 2012 12:29:05 +0200 Subject: [PATCH 4/4] Removed unused code from profile.py --- tuned/profile.py | 92 +++++++++++++++++++----------------------------- 1 file changed, 36 insertions(+), 56 deletions(-) diff --git a/tuned/profile.py b/tuned/profile.py index f7ddfe4..7b8e58c 100644 --- a/tuned/profile.py +++ b/tuned/profile.py @@ -52,6 +52,15 @@ class Profile(object): return name + def _apply_config(self): + pp = pprint.PrettyPrinter(indent=4) + log.debug("Loaded config: %s" % (pp.pformat(self._plugin_configs))) + + for name, cfg in self._plugin_configs.iteritems(): + plugin = cfg["type"] + del cfg["type"] + p = self._manager.create(name, plugin, cfg) + def _disable_plugin(self, name, plugin_cfg): # Iterates over already loaded plugins. # If the already loaded plugin contains the same device as the newly @@ -80,34 +89,6 @@ class Profile(object): log.debug("Removing plugin %s because it is useless after disabling" % (plugin)) del self._plugin_configs[plugin] - def _replace_plugin(self, name, plugin_cfg): - # Iterates over already loaded plugins. - # If the already loaded plugin contains the same device as the newly - # loaded one, remove the device from the already loaded one. - plugins_to_remove = [] - for plugin, cfg in self._plugin_configs.iteritems(): - if cfg["type"] != plugin_cfg["type"]: - continue - - if cfg.has_key("devices") and cfg["devices"] != None: - for device in plugin_cfg["devices"]: - if device in cfg["devices"]: - cfg["devices"].remove(device) - log.debug("Replacing plugin %s device %s by %s" % (plugin, device, name)) - # If we removed all devices, this plugin is not useful anymore, - # so we should remove it too: - if (len(cfg["devices"]) == 0): - plugins_to_remove.append(plugin) - else: - # If the plugin does not have any device set, it can be - # run only once, so remove previous occurence - log.debug("Replacing plugin %s by %s" % (plugin, name)) - plugins_to_remove.append(plugin) - - for plugin in plugins_to_remove: - log.debug("Removing plugin %s because it is useless after replace" % (plugin)) - del self._plugin_configs[plugin] - def _merge_plugin(self, name, plugin_cfg): # Iterates over already loaded plugins. # Merges the option of two plugins with the same types together @@ -132,12 +113,18 @@ class Profile(object): log.debug("Removing plugin %s because it is useless after merge" % (plugin)) del self._plugin_configs[plugin] + def _store_plugin_config(self, name, plugin_cfg): plugin = plugin_cfg["type"] # Check if the plugin is supported on this HW - if not tuned.plugins.get_repository().is_supported(plugin): - log.info("Plugin %s is not supported on this HW" % (plugin)) + try: + if not tuned.plugins.get_repository().is_supported(plugin): + log.info("Plugin %s is not supported on this HW" % (plugin)) + return + except: + e.log() + log.error("unable to create unit %s" % plugin) return # If there are no devices set, set all tunable_devices as default @@ -156,22 +143,13 @@ class Profile(object): return if plugin_cfg.has_key("replace"): - self._replace_plugin(name, plugin_cfg) + self._disable_plugin(name, plugin_cfg) del plugin_cfg["replace"] else: self._merge_plugin(name, plugin_cfg) self._plugin_configs[name] = plugin_cfg - def _apply_config(self): - pp = pprint.PrettyPrinter(indent=4) - log.debug("Loaded config: %s" % (pp.pformat(self._plugin_configs))) - - for name, cfg in self._plugin_configs.iteritems(): - plugin = cfg["type"] - del cfg["type"] - p = self._manager.create(name, plugin, cfg) - - def _get_unique_name(self, name): + def _get_unique_plugin_name(self, name): i = 1 n = name while n in self._plugin_configs.keys(): @@ -179,7 +157,19 @@ class Profile(object): i += 1 return n - def _load_config(self, manager, config): + def _load_plugins(self, cfg, load_path): + for section in cfg.sections(): + if section == "main": + continue + if not cfg.has_option(section, "type"): + log.info("No 'type' option for %s plugin, will treat '%s' as a plugin type" % (section, section)) + cfg.set(section, "type", section) + cfg.set(section, "_load_path", load_path) + + self._store_plugin_config(self._get_unique_plugin_name(section), dict(cfg.items(section))) + return True + + def _load_config(self, config): if not os.path.exists(config): log.error("Config file %s does not exist" % (config)) return False @@ -189,23 +179,13 @@ class Profile(object): if cfg.has_option("main", "include"): included_cfg = self.find_profile(cfg.get("main", "include")) - self._load_config(manager, included_cfg) + if not self._load_config(included_cfg): + return False - for section in cfg.sections(): - if section == "main": - continue - if not cfg.has_option(section, "type"): - log.info("No 'type' option for %s plugin, will treat '%s' as a plugin type" % (section, section)) - cfg.set(section, "type", section) - cfg.set(section, "_load_path", os.path.dirname(config)) - - self._store_plugin_config(self._get_unique_name(section), dict(cfg.items(section))) - - return True + return self._load_plugins(cfg, os.path.dirname(config)) def load(self): - return (self._load_config(self._manager, self._config_file) and - self._apply_config()) + return (self._load_config(self._config_file) and self._apply_config()) def cleanup(self): pass