Sysctl plugin
This commit is contained in:
parent
66d5f81945
commit
1d3badfef2
4 changed files with 67 additions and 47 deletions
|
|
@ -2,6 +2,7 @@
|
|||
script=included_script.sh
|
||||
|
||||
[sysctl]
|
||||
type=sysctl
|
||||
net.core.rmem_max = 8388609
|
||||
|
||||
[my_included_plugin]
|
||||
|
|
|
|||
4
test.cfg
4
test.cfg
|
|
@ -3,7 +3,9 @@ include=included.cfg
|
|||
script=script.sh
|
||||
elevator=deadline
|
||||
|
||||
[sysctl]
|
||||
[my_sysctl]
|
||||
merge=1
|
||||
type=sysctl
|
||||
# ktune sysctl settings for EL 5 servers
|
||||
|
||||
# 256 KB default performs well experimentally, and is often recommended by ISVs.
|
||||
|
|
|
|||
61
tuned/plugins/plugin_sysctl.py
Normal file
61
tuned/plugins/plugin_sysctl.py
Normal file
|
|
@ -0,0 +1,61 @@
|
|||
import tuned.plugins
|
||||
import tuned.logs
|
||||
import tuned.monitors
|
||||
import os
|
||||
import struct
|
||||
from subprocess import *
|
||||
|
||||
log = tuned.logs.get()
|
||||
|
||||
class SysctlPlugin(tuned.plugins.Plugin):
|
||||
"""
|
||||
"""
|
||||
|
||||
def __init__(self, devices, options):
|
||||
"""
|
||||
"""
|
||||
super(self.__class__, self).__init__(None, options)
|
||||
self._options = options
|
||||
self._latency = None
|
||||
self._updated = False
|
||||
self._sysctl_original = {}
|
||||
|
||||
def _exec_sysctl(self, data, write = False):
|
||||
if write:
|
||||
log.debug("Setting sysctl: %s" % (data))
|
||||
proc = Popen(["/sbin/sysctl", "-q", "-w", data], stdout=PIPE, stderr=PIPE)
|
||||
else:
|
||||
proc = Popen(["/sbin/sysctl", "-e", data], stdout=PIPE, stderr=PIPE)
|
||||
out, err = proc.communicate()
|
||||
|
||||
if proc.returncode:
|
||||
log.error("sysctl error: %s" % (err[:-1]))
|
||||
return (proc.returncode, out, err)
|
||||
|
||||
def _apply_sysctl(self):
|
||||
for key, value in self._options.iteritems():
|
||||
returncode, out, err = self._exec_sysctl(key)
|
||||
if not returncode and len(out.split('=')) == 2:
|
||||
k = out.split('=')[0].strip()
|
||||
v = out.split('=')[1].strip()
|
||||
self._sysctl_original[k] = v
|
||||
|
||||
self._exec_sysctl(key + "=" + value, True)
|
||||
return True
|
||||
|
||||
def _revert_sysctl(self):
|
||||
for key, value in self._sysctl_original.iteritems():
|
||||
self._exec_sysctl(key + "=" + value, True)
|
||||
|
||||
def cleanup(self):
|
||||
self._revert_sysctl()
|
||||
os.close(self._cpu_latency_fd)
|
||||
|
||||
def update_tuning(self):
|
||||
if self._updated:
|
||||
return
|
||||
|
||||
self._updated = True
|
||||
self._apply_sysctl()
|
||||
|
||||
|
||||
|
|
@ -34,18 +34,12 @@ class Profile(object):
|
|||
def __init__(self, manager, config_file):
|
||||
self._manager = manager
|
||||
self._config_file = config_file
|
||||
self._sysctl = {}
|
||||
self._sysctl_original = {}
|
||||
self._scripts = []
|
||||
self._elevator = ""
|
||||
# TODO: match cciss* somehow
|
||||
self._elevator_devs = "/sys/block/sd*/queue/scheduler"
|
||||
self._plugin_configs = {}
|
||||
|
||||
def _load_sysctl(self, cfg):
|
||||
if cfg.has_section("sysctl"):
|
||||
self._sysctl.update(cfg.items("sysctl"))
|
||||
|
||||
def _load_ktuned(self):
|
||||
for cfg in glob.glob("/etc/ktune.d/*.conf"):
|
||||
f = open(os.path.join("/etc/ktune.d/", cfg))
|
||||
|
|
@ -61,39 +55,6 @@ class Profile(object):
|
|||
self._scripts.append(script)
|
||||
return True
|
||||
|
||||
def _exec_sysctl(self, data, write = False):
|
||||
if write:
|
||||
log.debug("Setting sysctl: %s" % (data))
|
||||
proc = Popen(["/sbin/sysctl", "-q", "-w", data], stdout=PIPE, stderr=PIPE)
|
||||
else:
|
||||
proc = Popen(["/sbin/sysctl", "-e", data], stdout=PIPE, stderr=PIPE)
|
||||
out, err = proc.communicate()
|
||||
|
||||
if proc.returncode:
|
||||
log.error("sysctl error: %s" % (err[:-1]))
|
||||
return (proc.returncode, out, err)
|
||||
|
||||
def _apply_sysctl(self):
|
||||
if len(self._elevator) == 0:
|
||||
return
|
||||
|
||||
for key, value in self._sysctl.iteritems():
|
||||
returncode, out, err = self._exec_sysctl(key)
|
||||
if not returncode:
|
||||
k = out.split('=')[0].strip()
|
||||
v = out.split('=')[1].strip()
|
||||
self._sysctl_original[k] = v
|
||||
|
||||
self._exec_sysctl(key + "=" + value, True)
|
||||
return True
|
||||
|
||||
def _revert_sysctl(self):
|
||||
if len(self._elevator) == 0:
|
||||
return
|
||||
|
||||
for key, value in self._sysctl_original.iteritems():
|
||||
self._exec_sysctl(key + "=" + value, True)
|
||||
|
||||
def _apply_elevator(self):
|
||||
for dev in glob.glob(self._elevator_devs):
|
||||
log.debug("Applying elevator: %s < %s" % (dev, self._elevator))
|
||||
|
|
@ -193,6 +154,7 @@ class Profile(object):
|
|||
|
||||
if plugin_cfg.has_key("merge"):
|
||||
self._merge_plugin(name, plugin_cfg)
|
||||
del plugin_cfg["merge"]
|
||||
else:
|
||||
self._replace_plugin(name, plugin_cfg)
|
||||
self._plugin_configs[name] = plugin_cfg
|
||||
|
|
@ -225,12 +187,7 @@ class Profile(object):
|
|||
if cfg.has_option("main", "elevator_tune_devs"):
|
||||
self._elevator_devs = cfg.get("main", "elevator_tune_devs")
|
||||
|
||||
self._load_sysctl(cfg)
|
||||
|
||||
for section in cfg.sections():
|
||||
if section in ["main", "sysctl"]:
|
||||
continue
|
||||
|
||||
if not cfg.has_option(section, "type"):
|
||||
log.error("No 'type' option for %s plugin" % (section))
|
||||
continue
|
||||
|
|
@ -241,10 +198,9 @@ 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_sysctl() and
|
||||
self._apply_config() and self._load_ktuned() and
|
||||
self._apply_elevator() and self._call_scripts())
|
||||
|
||||
def cleanup(self):
|
||||
self._revert_sysctl()
|
||||
self._revert_elevator()
|
||||
self._call_scripts("stop")
|
||||
|
|
|
|||
Loading…
Reference in a new issue