Monitors for the same devices are loaded only once, disk plugin ported from tuned1
This commit is contained in:
parent
1da86d6a14
commit
fa4e8745b8
5 changed files with 122 additions and 5 deletions
4
test.cfg
4
test.cfg
|
|
@ -72,3 +72,7 @@ merge=1
|
|||
[my_broken_plugin]
|
||||
type=broken
|
||||
|
||||
[my_disk_plugin]
|
||||
type=disk
|
||||
|
||||
|
||||
|
|
|
|||
|
|
@ -11,6 +11,13 @@ class DiskMonitor(tuned.monitors.Monitor):
|
|||
available = set(filter(cls._is_device_supported, block_devices))
|
||||
cls._available_devices = available
|
||||
|
||||
for d in available:
|
||||
cls._load[d] = {}
|
||||
cls._load[d]["new"] = ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0']
|
||||
cls._load[d]["max"] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||
cls._update_disk(d)
|
||||
cls._load[d]["max"] = [1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
|
||||
|
||||
@classmethod
|
||||
def _is_device_supported(cls, device):
|
||||
vendor_file = "/sys/block/%s/device/vendor" % device
|
||||
|
|
@ -24,9 +31,26 @@ class DiskMonitor(tuned.monitors.Monitor):
|
|||
@classmethod
|
||||
def update(cls):
|
||||
for device in cls._updating_devices:
|
||||
# TODO
|
||||
cls._load[device] = None
|
||||
cls._update_disk(device)
|
||||
|
||||
|
||||
@classmethod
|
||||
def _update_disk(cls, name):
|
||||
pass
|
||||
def _update_disk(cls, dev):
|
||||
l = open("/sys/block/"+dev+"/stat", "r").read()
|
||||
cls._load[dev]["old"] = cls._load[dev]["new"]
|
||||
cls._load[dev]["new"] = l.split()
|
||||
l = cls._calcdiff(dev)
|
||||
for i in xrange(len(l)):
|
||||
if l[i] > cls._load[dev]["max"][i]:
|
||||
cls._load[dev]["max"][i] = l[i]
|
||||
|
||||
cls._load[dev]['diff'] = cls._calcdiff(dev)
|
||||
cls._load[dev]["READ"] = float(cls._load[dev]["diff"][1]) / float(cls._load[dev]["max"][1])
|
||||
cls._load[dev]["WRITE"] = float(cls._load[dev]["diff"][5]) / float(cls._load[dev]["max"][5])
|
||||
|
||||
@classmethod
|
||||
def _calcdiff(cls, dev):
|
||||
l = []
|
||||
for i in xrange(len(cls._load[dev]["old"])):
|
||||
l.append(int(cls._load[dev]["new"][i]) - int(cls._load[dev]["old"][i]))
|
||||
return l
|
||||
|
|
|
|||
|
|
@ -14,6 +14,12 @@ class MonitorRepository(tuned.patterns.Singleton):
|
|||
log.debug("creating monitor %s" % plugin_name)
|
||||
# TODO: exception handling
|
||||
monitor_cls = self._loader.load(plugin_name)
|
||||
|
||||
for monitor in self._monitors:
|
||||
if (isinstance(monitor, monitor_cls) and
|
||||
(monitor.devices == devices or devices == None)):
|
||||
return monitor
|
||||
|
||||
monitor_instance = monitor_cls(devices)
|
||||
self._monitors.add(monitor_instance)
|
||||
return monitor_instance
|
||||
|
|
|
|||
84
tuned/plugins/plugin_disk.py
Normal file
84
tuned/plugins/plugin_disk.py
Normal file
|
|
@ -0,0 +1,84 @@
|
|||
import os, copy
|
||||
import tuned.plugins
|
||||
import tuned.logs
|
||||
import tuned.monitors
|
||||
import struct
|
||||
|
||||
log = tuned.logs.get()
|
||||
|
||||
class DiskPlugin(tuned.plugins.Plugin):
|
||||
|
||||
_supported_vendors = ["ATA", "SCSI"]
|
||||
|
||||
def __init__(self, devices, options):
|
||||
"""
|
||||
"""
|
||||
super(self.__class__, self).__init__(None, options)
|
||||
|
||||
self.devidle = {}
|
||||
self.power = ["255", "225", "195", "165", "145", "125", "105", "85", "70", "55", "30", "20"]
|
||||
self.spindown = ["0", "250", "230", "210", "190", "170", "150", "130", "110", "90", "70", "60"]
|
||||
self.levels = len(self.power)
|
||||
|
||||
self._load_monitor = tuned.monitors.get_repository().create("disk", devices)
|
||||
|
||||
@classmethod
|
||||
def tunable_devices(cls):
|
||||
block_devices = os.listdir("/sys/block")
|
||||
available = set(filter(cls._is_device_supported, block_devices))
|
||||
cls._available_devices = available
|
||||
|
||||
@classmethod
|
||||
def _is_device_supported(cls, device):
|
||||
vendor_file = "/sys/block/%s/device/vendor" % device
|
||||
try:
|
||||
vendor = open(vendor_file).read().strip()
|
||||
except IOError:
|
||||
return False
|
||||
|
||||
return vendor in cls._supported_vendors
|
||||
|
||||
def _updateIdle(self, dev, devload):
|
||||
idle = self.devidle.setdefault(dev, {})
|
||||
idle.setdefault("LEVEL", 0)
|
||||
for type in ("READ", "WRITE"):
|
||||
if devload[type] == 0.0:
|
||||
idle.setdefault(type, 0)
|
||||
idle[type] += 1
|
||||
else:
|
||||
idle.setdefault(type, 0)
|
||||
idle[type] = 0
|
||||
|
||||
|
||||
def cleanup(self):
|
||||
log.debug("Cleanup")
|
||||
|
||||
for dev in self.devidle.keys():
|
||||
if self.devidle[dev]["LEVEL"] > 0:
|
||||
os.system("hdparm -S0 -B255 /dev/"+dev+" > /dev/null 2>&1")
|
||||
|
||||
def update_tuning(self):
|
||||
load = self._load_monitor.get_load()
|
||||
for dev, devload in load.iteritems():
|
||||
self._updateIdle(dev, devload)
|
||||
|
||||
if self.devidle[dev]["LEVEL"] < self.levels-1 and self.devidle[dev]["READ"] >= 6 and self.devidle[dev]["WRITE"] >= 6:
|
||||
self.devidle[dev].setdefault("LEVEL", 0)
|
||||
self.devidle[dev]["LEVEL"] += 1
|
||||
level = self.devidle[dev]["LEVEL"]
|
||||
|
||||
log.debug("Level changed to %d (power %s, spindown %s)" % (level, self.power[level], self.spindown[level]))
|
||||
os.system("hdparm -S"+self.power[level]+" -B"+self.spindown[level]+" /dev/"+dev+" > /dev/null 2>&1")
|
||||
|
||||
if self.devidle[dev]["LEVEL"] > 0 and (self.devidle[dev]["READ"] == 0 or self.devidle[dev]["WRITE"] == 0):
|
||||
self.devidle[dev].setdefault("LEVEL", 0)
|
||||
self.devidle[dev]["LEVEL"] -= 2
|
||||
if self.devidle[dev]["LEVEL"] < 0:
|
||||
self.devidle[dev]["LEVEL"] = 0
|
||||
level = self.devidle[dev]["LEVEL"]
|
||||
|
||||
log.debug("Level changed to %d (power %s, spindown %s)" % (level, self.power[level], self.spindown[level]))
|
||||
os.system("hdparm -S"+self.power[level]+" -B"+self.spindown[level]+" /dev/"+dev+" > /dev/null 2>&1")
|
||||
|
||||
log.debug("%s load: read %f, write %f" % (dev, load[dev]["READ"], load[dev]["WRITE"]))
|
||||
log.debug("%s idle: read %d, write %d, level %d" % (dev, self.devidle[dev]["READ"], self.devidle[dev]["WRITE"], self.devidle[dev]["LEVEL"]))
|
||||
|
|
@ -49,7 +49,6 @@ class NetTuningPlugin(tuned.plugins.Plugin):
|
|||
load = self._load_monitor.get_load()
|
||||
for dev, devload in load.iteritems():
|
||||
self._updateIdle(dev, devload)
|
||||
print self.devidle
|
||||
if self.devidle[dev]["LEVEL"] == 0 and self.devidle[dev]["READ"] >= 6 and self.devidle[dev]["WRITE"] >= 6:
|
||||
self.devidle[dev]["LEVEL"] = 1
|
||||
|
||||
|
|
|
|||
Loading…
Reference in a new issue