KTune plugin
This commit is contained in:
parent
1d3badfef2
commit
3948453c17
4 changed files with 105 additions and 72 deletions
4
test.cfg
4
test.cfg
|
|
@ -57,6 +57,10 @@ vm.dirty_ratio = 50
|
|||
# Doesn't exist for 2.6.30++ anymore
|
||||
# vm.pagecache = 90
|
||||
|
||||
[my_ktune_plugin]
|
||||
type=ktune
|
||||
script=test.sh
|
||||
elevator=deadline
|
||||
|
||||
[my_cpu_plugin]
|
||||
type=cpu
|
||||
|
|
|
|||
84
tuned/plugins/plugin_ktune.py
Normal file
84
tuned/plugins/plugin_ktune.py
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import tuned.plugins
|
||||
import tuned.logs
|
||||
import tuned.monitors
|
||||
import os
|
||||
import struct
|
||||
import glob
|
||||
from subprocess import *
|
||||
|
||||
log = tuned.logs.get()
|
||||
|
||||
class KTunePlugin(tuned.plugins.Plugin):
|
||||
"""
|
||||
"""
|
||||
|
||||
def __init__(self, devices, options):
|
||||
"""
|
||||
"""
|
||||
super(self.__class__, self).__init__(None, options)
|
||||
self._updated = False
|
||||
self._scripts = []
|
||||
self._load_ktuned()
|
||||
self._scripts.append(self._options["script"])
|
||||
|
||||
@classmethod
|
||||
def _get_default_options(cls):
|
||||
# TODO: match cciss* somehow
|
||||
return {
|
||||
"elevator" : "",
|
||||
"script" : "",
|
||||
"elevator_devs" : "/sys/block/sd*/queue/scheduler",
|
||||
}
|
||||
|
||||
def _load_ktuned(self):
|
||||
for sh in glob.glob("/etc/ktune.d/*.sh"):
|
||||
script = os.path.join("/etc/ktune.d/", sh)
|
||||
if not script in self._scripts:
|
||||
self._scripts.append(script)
|
||||
return True
|
||||
|
||||
def _apply_elevator(self):
|
||||
for dev in glob.glob(self._options["elevator_devs"]):
|
||||
log.debug("Applying elevator: %s < %s" % (dev, self._options["elevator"]))
|
||||
try:
|
||||
f = open(dev, "w")
|
||||
f.write(self._options["elevator"])
|
||||
f.close()
|
||||
except (OSError,IOError) as e:
|
||||
log.error("Setting elevator on %s error: %s" % (dev, e))
|
||||
return True
|
||||
|
||||
def _revert_elevator(self):
|
||||
for dev in glob.glob(self._options["elevator_devs"]):
|
||||
log.debug("Applying elevator: %s < cfs" % (dev))
|
||||
try:
|
||||
f = open(dev, "w")
|
||||
f.write("cfs")
|
||||
f.close()
|
||||
except (OSError,IOError) as e:
|
||||
log.error("Setting elevator on %s error: %s" % (dev, e))
|
||||
|
||||
def _call_scripts(self, arg = "start"):
|
||||
for script in self._scripts:
|
||||
log.info("Calling script %s" % (script))
|
||||
try:
|
||||
proc = Popen([script, arg], stdout=PIPE, stderr=PIPE)
|
||||
out, err = proc.communicate()
|
||||
|
||||
if proc.returncode:
|
||||
log.error("script %s error: %s" % (script, err[:-1]))
|
||||
except (OSError,IOError) as e:
|
||||
log.error("Script %s error: %s" % (script, e))
|
||||
return True
|
||||
|
||||
def cleanup(self):
|
||||
self._revert_elevator()
|
||||
self._call_scripts("stop")
|
||||
|
||||
def update_tuning(self):
|
||||
if self._updated:
|
||||
return
|
||||
|
||||
self._updated = True
|
||||
self._apply_elevator()
|
||||
self._call_scripts()
|
||||
|
|
@ -3,6 +3,7 @@ import tuned.logs
|
|||
import tuned.monitors
|
||||
import os
|
||||
import struct
|
||||
import glob
|
||||
from subprocess import *
|
||||
|
||||
log = tuned.logs.get()
|
||||
|
|
@ -16,9 +17,20 @@ class SysctlPlugin(tuned.plugins.Plugin):
|
|||
"""
|
||||
super(self.__class__, self).__init__(None, options)
|
||||
self._options = options
|
||||
self._latency = None
|
||||
self._updated = False
|
||||
self._sysctl_original = {}
|
||||
self._load_ktuned()
|
||||
|
||||
def _load_ktuned(self):
|
||||
for cfg in glob.glob("/etc/ktune.d/*.conf"):
|
||||
f = open(os.path.join("/etc/ktune.d/", cfg))
|
||||
for line in f.readlines():
|
||||
if not line.strip().startswith("#") and line.find("=") != -1:
|
||||
k = line.split('=')[0].strip()
|
||||
v = line.split('=')[1].strip()
|
||||
self._options[k] = v
|
||||
f.close()
|
||||
return True
|
||||
|
||||
def _exec_sysctl(self, data, write = False):
|
||||
if write:
|
||||
|
|
@ -49,7 +61,6 @@ class SysctlPlugin(tuned.plugins.Plugin):
|
|||
|
||||
def cleanup(self):
|
||||
self._revert_sysctl()
|
||||
os.close(self._cpu_latency_fd)
|
||||
|
||||
def update_tuning(self):
|
||||
if self._updated:
|
||||
|
|
@ -57,5 +68,3 @@ class SysctlPlugin(tuned.plugins.Plugin):
|
|||
|
||||
self._updated = True
|
||||
self._apply_sysctl()
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -34,61 +34,8 @@ class Profile(object):
|
|||
def __init__(self, manager, config_file):
|
||||
self._manager = manager
|
||||
self._config_file = config_file
|
||||
self._scripts = []
|
||||
self._elevator = ""
|
||||
# TODO: match cciss* somehow
|
||||
self._elevator_devs = "/sys/block/sd*/queue/scheduler"
|
||||
self._plugin_configs = {}
|
||||
|
||||
def _load_ktuned(self):
|
||||
for cfg in glob.glob("/etc/ktune.d/*.conf"):
|
||||
f = open(os.path.join("/etc/ktune.d/", cfg))
|
||||
for line in f.readlines():
|
||||
if not line.strip().startswith("#") and line.find("=") != -1:
|
||||
k = out.split('=')[0].strip()
|
||||
v = out.split('=')[1].strip()
|
||||
self._sysctl[k] = v
|
||||
f.close()
|
||||
for sh in glob.glob("/etc/ktune.d/*.sh"):
|
||||
script = os.path.join("/etc/ktune.d/", sh)
|
||||
if not script in self._scripts:
|
||||
self._scripts.append(script)
|
||||
return True
|
||||
|
||||
def _apply_elevator(self):
|
||||
for dev in glob.glob(self._elevator_devs):
|
||||
log.debug("Applying elevator: %s < %s" % (dev, self._elevator))
|
||||
try:
|
||||
f = open(dev, "w")
|
||||
f.write(self._elevator)
|
||||
f.close()
|
||||
except (OSError,IOError) as e:
|
||||
log.error("Setting elevator on %s error: %s" % (dev, e))
|
||||
return True
|
||||
|
||||
def _revert_elevator(self):
|
||||
for dev in glob.glob(self._elevator_devs):
|
||||
log.debug("Applying elevator: %s < cfs" % (dev))
|
||||
try:
|
||||
f = open(dev, "w")
|
||||
f.write("cfs")
|
||||
f.close()
|
||||
except (OSError,IOError) as e:
|
||||
log.error("Setting elevator on %s error: %s" % (dev, e))
|
||||
|
||||
def _call_scripts(self, arg = "start"):
|
||||
for script in self._scripts:
|
||||
log.info("Calling script %s" % (script))
|
||||
try:
|
||||
proc = Popen([script, arg], stdout=PIPE, stderr=PIPE)
|
||||
out, err = proc.communicate()
|
||||
|
||||
if proc.returncode:
|
||||
log.error("script %s error: %s" % (script, err[:-1]))
|
||||
except (OSError,IOError) as e:
|
||||
log.error("Script %s error: %s" % (script, e))
|
||||
return True
|
||||
|
||||
def _replace_plugin(self, name, plugin_cfg):
|
||||
# Iterates over already loaded plugins.
|
||||
# If the already loaded plugin contains the same device as the newly
|
||||
|
|
@ -176,18 +123,9 @@ class Profile(object):
|
|||
if cfg.has_option("main", "include"):
|
||||
self._load_config(manager, cfg.get("main", "include"))
|
||||
|
||||
if cfg.has_option("main", "script"):
|
||||
script = os.path.abspath(cfg.get("main", "script"))
|
||||
if not script in self._scripts:
|
||||
self._scripts.append(script)
|
||||
|
||||
if cfg.has_option("main", "elevator"):
|
||||
self._elevator = cfg.get("main", "elevator")
|
||||
|
||||
if cfg.has_option("main", "elevator_tune_devs"):
|
||||
self._elevator_devs = cfg.get("main", "elevator_tune_devs")
|
||||
|
||||
for section in cfg.sections():
|
||||
if section == "main":
|
||||
continue
|
||||
if not cfg.has_option(section, "type"):
|
||||
log.error("No 'type' option for %s plugin" % (section))
|
||||
continue
|
||||
|
|
@ -198,9 +136,7 @@ class Profile(object):
|
|||
|
||||
def load(self):
|
||||
return (self._load_config(self._manager, self._config_file) and
|
||||
self._apply_config() and self._load_ktuned() and
|
||||
self._apply_elevator() and self._call_scripts())
|
||||
self._apply_config())
|
||||
|
||||
def cleanup(self):
|
||||
self._revert_elevator()
|
||||
self._call_scripts("stop")
|
||||
pass
|
||||
|
|
|
|||
Loading…
Reference in a new issue