1
0
Fork 0

tuned: Improved error messages

Made tuned error messages less verbose, but more descriptive if running without
debug option. Also made class from the tuned.utils.commands helper functions.
Its logging can be enabled / disabled.

Resolves: rhbz#1068699

Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
This commit is contained in:
Jaroslav Škarvada 2014-09-24 16:06:55 +02:00
parent 7b4c1e330d
commit 56ecbd362e
18 changed files with 200 additions and 169 deletions

View file

@ -29,7 +29,7 @@ import tuned.version as ver
if __name__ == "__main__":
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", action="store_true", help=argparse.SUPPRESS)
parser.add_argument("--debug", "-d", action="store_true", help="show debug messages")
subparsers = parser.add_subparsers()
parser_list = subparsers.add_parser("list", help="list available profiles")
@ -56,8 +56,8 @@ if __name__ == "__main__":
result = False
try:
controller = tuned.admin.DBusController(consts.DBUS_BUS, consts.DBUS_OBJECT, consts.DBUS_INTERFACE)
admin = tuned.admin.Admin(controller)
controller = tuned.admin.DBusController(consts.DBUS_BUS, consts.DBUS_OBJECT, consts.DBUS_INTERFACE, debug)
admin = tuned.admin.Admin(controller, debug)
action = getattr(admin, action_name)
result = action(**options)

View file

@ -1,35 +1,35 @@
import tuned.utils.commands
from tuned.utils.commands import commands
from tuned.profiles import Locator as profiles_locator
from exceptions import TunedAdminDBusException
import tuned.consts as consts
import sys
class Admin(object):
def __init__(self, controller):
def __init__(self, controller, debug = False):
self._controller = controller
self._debug = debug
self._cmd = commands(debug)
def _error(self, message):
print >>sys.stderr, message
def list(self, dbus_warn = True):
def list(self):
try:
profile_names = self._controller.profiles()
except TunedAdminDBusException as e:
if dbus_warn:
print >> sys.stderr, e
self._error(e)
profile_names = profiles_locator(consts.LOAD_DIRECTORIES).get_known_names()
print "Available profiles:"
for profile in profile_names:
print "- %s" % profile
self.active(False)
def active(self, dbus_warn = True):
def active(self):
try:
profile_name = self._controller.active_profile()
except TunedAdminDBusException as e:
if dbus_warn:
print >> sys.stderr, e
profile_name = tuned.utils.commands.read_file(consts.ACTIVE_PROFILE_FILE, None)
self._error(e)
profile_name = self._cmd.read_file(consts.ACTIVE_PROFILE_FILE, None)
if profile_name is not None and profile_name != "":
print "Current active profile: %s" % profile_name
return True
@ -37,41 +37,39 @@ class Admin(object):
print "No current active profile."
return False
def profile(self, profiles, dbus_warn = True):
fallback = False
def profile(self, profiles):
profile_name = " ".join(profiles)
if profile_name == "":
return False
try:
ret = self._controller.switch_profile(profile_name)
except TunedAdminDBusException as e:
fallback = True
if dbus_warn:
print >> sys.stderr, e
self._error(e)
if profile_name in profiles_locator(consts.LOAD_DIRECTORIES).get_known_names():
ret = tuned.utils.commands.write_to_file(consts.ACTIVE_PROFILE_FILE, profile_name)
if self._cmd.write_to_file(consts.ACTIVE_PROFILE_FILE, profile_name):
print "You need to (re)start the tuned daemon by hand for changes to apply."
return True
else:
self._error("Unable to switch profile, do you have enough permissions?")
return False
else:
ret = False
self._error("Requested profile '%s' doesn't exist." % profile_name)
return False
if ret:
if fallback:
print "You need to (re)start the tuned daemon by hand for changes to apply."
else:
if not self._controller.is_running() and not self._controller.start():
self._error("Cannot enable the tuning.")
ret = False
if not self._controller.is_running() and not self._controller.start():
self._error("Cannot enable the tuning.")
ret = False
else:
self._error("Cannot switch the profile.")
return ret
def recommend_profile(self, dbus_warn = True):
def recommend_profile(self):
try:
profile = self._controller.recommend_profile()
except TunedAdminDBusException as e:
if dbus_warn:
print >> sys.stderr, e
profile = tuned.utils.commands.recommend_profile()
self._error(e)
profile = self._cmd.recommend_profile()
print profile
def off(self):

View file

@ -5,11 +5,12 @@ from exceptions import TunedAdminDBusException
__all__ = ["DBusController"]
class DBusController(object):
def __init__(self, bus_name, interface_name, object_name):
def __init__(self, bus_name, interface_name, object_name, debug = False):
self._bus_name = bus_name
self._interface_name = interface_name
self._object_name = object_name
self._proxy = None
self._debug = debug
def _init_proxy(self):
if self._proxy is None:
@ -26,7 +27,10 @@ class DBusController(object):
method = self._proxy.get_dbus_method(method_name)
return method(*args, **kwargs)
except dbus.exceptions.DBusException as dbus_exception:
raise TunedAdminDBusException("DBus call to Tuned daemon failed (%s)." % str(dbus_exception))
err_str = "DBus call to Tuned daemon failed"
if self._debug:
err_str += " (%s)" % str(dbus_exception)
raise TunedAdminDBusException(err_str)
def is_running(self):
return self._call("is_running")

View file

@ -2,7 +2,7 @@ from tuned import exports
import tuned.logs
import tuned.exceptions
import threading
import tuned.utils.commands
from tuned.utils.commands import commands
__all__ = ["Controller"]
@ -18,6 +18,7 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
super(self.__class__, self).__init__()
self._daemon = daemon
self._terminate = threading.Event()
self._cmd = commands()
def run(self):
"""
@ -28,7 +29,7 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
self._terminate.clear()
# we have to pass some timeout, otherwise signals will not work
while not tuned.utils.commands.wait(self._terminate, 3600):
while not self._cmd.wait(self._terminate, 3600):
pass
log.info("terminating controller")
@ -101,4 +102,4 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
@exports.export("", "s")
def recommend_profile(self):
return tuned.utils.commands.recommend_profile()
return self._cmd.recommend_profile()

View file

@ -4,7 +4,7 @@ import threading
import tuned.logs
from tuned.exceptions import TunedException
import tuned.consts as consts
import tuned.utils.commands
from tuned.utils.commands import commands
log = tuned.logs.get()
@ -34,6 +34,7 @@ class Daemon(object):
self._unit_manager = unit_manager
self._profile_loader = profile_loader
self._init_threads()
self._cmd = commands()
try:
self._init_profile(profile_name)
except TunedException as e:
@ -89,7 +90,7 @@ class Daemon(object):
# the default) is still much better than 50 ms polling with unpatched interpreter.
# For more details see tuned rhbz#917587.
_sleep_cnt = self._sleep_cycles
while not tuned.utils.commands.wait(self._terminate, self._sleep_interval):
while not self._cmd.wait(self._terminate, self._sleep_interval):
if self._dynamic_tuning:
_sleep_cnt -= 1
if _sleep_cnt <= 0:
@ -111,7 +112,7 @@ class Daemon(object):
def _set_recommended_profile(self):
log.info("no profile preset, checking what is recommended for your configuration")
profile = tuned.utils.commands.recommend_profile()
profile = self._cmd.recommend_profile()
log.info("using '%s' profile and setting it as active" % profile)
self._save_active_profile(profile)
return profile

View file

@ -1,13 +1,14 @@
import base
from decorators import *
import tuned.logs
import tuned.utils.commands
from tuned.utils.commands import commands
import os
import struct
import glob
log = tuned.logs.get()
cmd = commands()
class AudioPlugin(base.Plugin):
"""
@ -58,12 +59,12 @@ class AudioPlugin(base.Plugin):
timeout = int(value)
if timeout >= 0:
sys_file = self._timeout_path(device)
tuned.utils.commands.write_to_file(sys_file, "%d" % timeout)
cmd.write_to_file(sys_file, "%d" % timeout)
@command_get("timeout")
def _get_timeout(self, device):
sys_file = self._timeout_path(device)
value = tuned.utils.commands.read_file(sys_file)
value = cmd.read_file(sys_file)
if len(value) > 0:
return int(value)
return None
@ -72,4 +73,4 @@ class AudioPlugin(base.Plugin):
def _reset_controller(self, enabling, value, device):
sys_file = self._reset_controller_path(device)
if os.path.exists(sys_file):
tuned.utils.commands.write_to_file(sys_file, "1")
cmd.write_to_file(sys_file, "1")

View file

@ -1,7 +1,7 @@
import base
from decorators import *
import tuned.logs
import tuned.utils.commands
from tuned.utils.commands import commands
import os
import struct
@ -26,6 +26,7 @@ class CPULatencyPlugin(base.Plugin):
self._min_perf_pct_save = None
self._max_perf_pct_save = None
self._no_turbo_save = None
self._cmd = commands()
def _init_devices(self):
self._devices = set()
@ -50,7 +51,7 @@ class CPULatencyPlugin(base.Plugin):
}
def _check_cpupower(self):
if tuned.utils.commands.execute(["cpupower", "frequency-info"])[0] == 0:
if self._cmd.execute(["cpupower", "frequency-info"])[0] == 0:
self._has_cpupower = True
else:
self._has_cpupower = False
@ -58,7 +59,7 @@ class CPULatencyPlugin(base.Plugin):
def _check_energy_perf_bias(self):
self._has_energy_perf_bias = False
retcode = tuned.utils.commands.execute(["x86_energy_perf_policy", "-r"])[0]
retcode = self._cmd.execute(["x86_energy_perf_policy", "-r"])[0]
if retcode == 0:
self._has_energy_perf_bias = True
elif retcode == -1:
@ -150,11 +151,11 @@ class CPULatencyPlugin(base.Plugin):
pass
def _get_intel_pstate_attr(self, attr):
return tuned.utils.commands.read_file("/sys/devices/system/cpu/intel_pstate/%s" % attr, None)
return self._cmd.read_file("/sys/devices/system/cpu/intel_pstate/%s" % attr, None)
def _set_intel_pstate_attr(self, attr, val):
if val is not None:
tuned.utils.commands.write_to_file("/sys/devices/system/cpu/intel_pstate/%s" % attr, val)
self._cmd.write_to_file("/sys/devices/system/cpu/intel_pstate/%s" % attr, val)
def _set_latency(self, latency):
latency = int(latency)
@ -165,7 +166,7 @@ class CPULatencyPlugin(base.Plugin):
self._latency = latency
def _get_available_governors(self, device):
return tuned.utils.commands.read_file("/sys/devices/system/cpu/%s/cpufreq/scaling_available_governors" % device).split()
return self._cmd.read_file("/sys/devices/system/cpu/%s/cpufreq/scaling_available_governors" % device).split()
@command_set("governor", per_device=True)
def _set_governor(self, governor, device):
@ -175,16 +176,16 @@ class CPULatencyPlugin(base.Plugin):
log.info("setting governor '%s' on cpu '%s'" % (governor, device))
if self._has_cpupower:
cpu_id = device.lstrip("cpu")
tuned.utils.commands.execute(["cpupower", "-c", cpu_id, "frequency-set", "-g", str(governor)])
self._cmd.execute(["cpupower", "-c", cpu_id, "frequency-set", "-g", str(governor)])
else:
tuned.utils.commands.write_to_file("/sys/devices/system/cpu/%s/cpufreq/scaling_governor" % device, str(governor))
self._cmd.write_to_file("/sys/devices/system/cpu/%s/cpufreq/scaling_governor" % device, str(governor))
@command_get("governor")
def _get_governor(self, device):
governor = None
if self._has_cpupower:
cpu_id = device.lstrip("cpu")
retcode, lines = tuned.utils.commands.execute(["cpupower", "-c", cpu_id, "frequency-info", "-p"])
retcode, lines = self._cmd.execute(["cpupower", "-c", cpu_id, "frequency-info", "-p"])
if retcode == 0:
for line in lines.splitlines():
if line.startswith("analyzing"):
@ -194,7 +195,7 @@ class CPULatencyPlugin(base.Plugin):
governor = l[2].strip()
break
else:
data = tuned.utils.commands.read_file("/sys/devices/system/cpu/%s/cpufreq/scaling_governor" % device).strip()
data = self._cmd.read_file("/sys/devices/system/cpu/%s/cpufreq/scaling_governor" % device).strip()
if len(data) > 0:
governor = data
@ -209,14 +210,14 @@ class CPULatencyPlugin(base.Plugin):
if self._has_energy_perf_bias:
log.info("setting energy_perf_bias '%s' on cpu '%s'" % (energy_perf_bias, device))
cpu_id = device.lstrip("cpu")
tuned.utils.commands.execute(["x86_energy_perf_policy", "-c", cpu_id, str(energy_perf_bias)])
self._cmd.execute(["x86_energy_perf_policy", "-c", cpu_id, str(energy_perf_bias)])
@command_get("energy_perf_bias")
def _get_energy_perf_bias(self, device):
energy_perf_bias = None
if self._has_energy_perf_bias:
cpu_id = device.lstrip("cpu")
retcode, lines = tuned.utils.commands.execute(["x86_energy_perf_policy", "-c", cpu_id, "-r"])
retcode, lines = self._cmd.execute(["x86_energy_perf_policy", "-c", cpu_id, "-r"])
if retcode == 0:
for line in lines.splitlines():
l = line.split()

View file

@ -1,7 +1,7 @@
import hotplug
from decorators import *
import tuned.logs
import tuned.utils.commands
from tuned.utils.commands import commands
import os
import re
@ -20,6 +20,7 @@ class DiskPlugin(hotplug.Plugin):
self._levels = len(self._power_levels)
self._level_steps = 6
self._load_smallest = 0.01
self._cmd = commands()
def _init_devices(self):
self._devices = set()
@ -123,7 +124,7 @@ class DiskPlugin(hotplug.Plugin):
new_spindown_level = self._spindown_levels[idle["level"]]
log.debug("tuning level changed to %d (power %d, spindown %d)" % (idle["level"], new_power_level, new_spindown_level))
tuned.utils.commands.execute(["hdparm", "-S%d" % new_spindown_level, "-B%d" % new_power_level, "/dev/%s" % device])
self._cmd.execute(["hdparm", "-S%d" % new_spindown_level, "-B%d" % new_power_level, "/dev/%s" % device])
log.debug("%s load: read %0.2f, write %0.2f" % (device, stats["read"], stats["write"]))
log.debug("%s idle: read %d, write %d, level %d" % (device, idle["read"], idle["write"], idle["level"]))
@ -166,14 +167,14 @@ class DiskPlugin(hotplug.Plugin):
@command_set("elevator", per_device=True)
def _set_elevator(self, value, device):
sys_file = self._elevator_file(device)
tuned.utils.commands.write_to_file(sys_file, value)
self._cmd.write_to_file(sys_file, value)
@command_get("elevator")
def _get_elevator(self, device):
sys_file = self._elevator_file(device)
# example of scheduler file content:
# noop deadline [cfq]
return tuned.utils.commands.get_active_option(tuned.utils.commands.read_file(sys_file))
return self._cmd.get_active_option(self.cmd.read_file(sys_file))
def _alpm_policy_files(self):
policy_files = []
@ -198,23 +199,23 @@ class DiskPlugin(hotplug.Plugin):
@command_set("alpm")
def _set_alpm(self, policy):
for policy_file in self._alpm_policy_files():
tuned.utils.commands.write_to_file(policy_file, policy)
self._cmd.write_to_file(policy_file, policy)
@command_get("alpm")
def _get_alpm(self):
for policy_file in self._alpm_policy_files():
return tuned.utils.commands.read_file(policy_file)
return self._cmd.read_file(policy_file)
return None
@command_set("apm", per_device=True)
def _set_apm(self, value, device):
tuned.utils.commands.execute(["hdparm", "-B", str(value), "/dev/" + device])
self._cmd.execute(["hdparm", "-B", str(value), "/dev/" + device])
@command_get("apm")
def _get_apm(self, device):
value = None
try:
m = re.match(r".*=\s*(\d+).*", tuned.utils.commands.execute(["hdparm", "-B", "/dev/" + device])[1], re.S)
m = re.match(r".*=\s*(\d+).*", self._cmd.execute(["hdparm", "-B", "/dev/" + device])[1], re.S)
if m:
value = int(m.group(1))
except:
@ -223,7 +224,7 @@ class DiskPlugin(hotplug.Plugin):
@command_set("spindown", per_device=True)
def _set_spindown(self, value, device):
tuned.utils.commands.execute(["hdparm", "-S", str(value), "/dev/" + device])
self._cmd.execute(["hdparm", "-S", str(value), "/dev/" + device])
@command_get("spindown")
def _get_spindown(self, device):
@ -236,12 +237,12 @@ class DiskPlugin(hotplug.Plugin):
@command_set("readahead", per_device=True)
def _set_readahead(self, value, device):
sys_file = self._readahead_file(device)
tuned.utils.commands.write_to_file(sys_file, "%d" % int(value))
self._cmd.write_to_file(sys_file, "%d" % int(value))
@command_get("readahead")
def _get_readahead(self, device):
sys_file = self._readahead_file(device)
value = tuned.utils.commands.read_file(sys_file).strip()
value = self._cmd.read_file(sys_file).strip()
if len(value) == 0:
return None
return int(value)
@ -269,12 +270,12 @@ class DiskPlugin(hotplug.Plugin):
@command_set("scheduler_quantum", per_device=True)
def _set_scheduler_quantum(self, value, device):
sys_file = self._scheduler_quantum_file(device)
tuned.utils.commands.write_to_file(sys_file, "%d" % int(value))
self._cmd.write_to_file(sys_file, "%d" % int(value))
@command_get("scheduler_quantum")
def _get_scheduler_quantum(self, device):
sys_file = self._scheduler_quantum_file(device)
value = tuned.utils.commands.read_file(sys_file).strip()
value = self._cmd.read_file(sys_file).strip()
if len(value) == 0:
log.info("disk_scheduler_quantum option is not supported by this HW")
return None

View file

@ -1,7 +1,7 @@
import base
import exceptions
import tuned.logs
import tuned.utils.commands
from tuned.utils.commands import commands
import os
log = tuned.logs.get()
@ -12,6 +12,7 @@ class EeePCSHEPlugin(base.Plugin):
"""
def __init__(self, *args, **kwargs):
self._cmd = commands()
self._control_file = "/sys/devices/platform/eeepc/cpufv"
if not os.path.isfile(self._control_file):
self._control_file = "/sys/devices/platform/eeepc-wmi/cpufv"
@ -53,5 +54,5 @@ class EeePCSHEPlugin(base.Plugin):
new_mode_numeric = int(instance.options["she_%s" % new_mode])
if instance._she_mode != new_mode_numeric:
log.info("new eeepc_she mode %s (%d) " % (new_mode, new_mode_numeric))
tuned.utils.commands.write_to_file(self._control_file, "%s" % new_mode_numeric)
self._cmd.write_to_file(self._control_file, "%s" % new_mode_numeric)
self._she_mode = new_mode_numeric

View file

@ -2,10 +2,11 @@ import base
from decorators import *
from subprocess import Popen,PIPE
import tuned.logs
import tuned.utils.commands
from tuned.utils.commands import commands
import glob
log = tuned.logs.get()
cmd = commands()
class MountsPlugin(base.Plugin):
"""
@ -67,7 +68,7 @@ class MountsPlugin(base.Plugin):
"""
source_filenames = glob.glob("/sys/block/%s/device/scsi_disk/*/cache_type" % device)
for source_filename in source_filenames:
return tuned.utils.commands.read_file(source_filename).strip()
return self._cmd.read_file(source_filename).strip()
return None
def _mountpoint_has_writeback_cache(self, mountpoint):
@ -113,7 +114,7 @@ class MountsPlugin(base.Plugin):
Remounts partition.
"""
remount_command = ["/usr/bin/mount", partition, "-o", "remount,%s" % options]
tuned.utils.commands.execute(remount_command)
cmd.execute(remount_command)
@command_custom("disable_barriers", per_device=True)
def _disable_barriers(self, start, value, mountpoint):

View file

@ -2,6 +2,7 @@ import base
from decorators import *
import tuned.logs
from tuned.utils.nettool import ethcard
from tuned utils.commands import commands
import os
import re
@ -18,6 +19,7 @@ class NetTuningPlugin(base.Plugin):
super(self.__class__, self).__init__(*args, **kwargs)
self._load_smallest = 0.05
self._level_steps = 6
self._cmd = commands()
def _init_devices(self):
self._devices = set()
@ -137,13 +139,13 @@ class NetTuningPlugin(base.Plugin):
log.warn("Incorrect 'wake_on_lan' value.")
return
tuned.utils.commands.execute(["ethtool", "-s", device, "wol", value])
self._cmd.execute(["ethtool", "-s", device, "wol", value])
@command_get("wake_on_lan")
def _get_wake_on_lan(self, device):
value = None
try:
m = re.match(r".*Wake-on:\s*([" + WOL_VALUES + "]+).*", tuned.utils.commands.execute(["ethtool", device])[1], re.S)
m = re.match(r".*Wake-on:\s*([" + WOL_VALUES + "]+).*", self._cmd.execute(["ethtool", device])[1], re.S)
if m:
value = m.group(1)
except IOError:
@ -157,11 +159,11 @@ class NetTuningPlugin(base.Plugin):
hashsize = int(value)
if hashsize >= 0:
tuned.utils.commands.write_to_file(self._nf_conntrack_hashsize_path(), hashsize)
self._cmd.write_to_file(self._nf_conntrack_hashsize_path(), hashsize)
@command_get("nf_conntrack_hashsize")
def _get_nf_conntrack_hashsize(self):
value = tuned.utils.commands.read_file(self._nf_conntrack_hashsize_path())
value = self._cmd.read_file(self._nf_conntrack_hashsize_path())
if len(value) > 0:
return int(value)
return None

View file

@ -2,7 +2,7 @@ import os
import base
from decorators import *
import tuned.logs
import tuned.utils.commands
from tuned.utils.commands import commands
log = tuned.logs.get()
@ -21,6 +21,7 @@ class SelinuxPlugin(base.Plugin):
return path
def __init__(self, *args, **kwargs):
self._cmd = commands()
self._selinux_path = self._get_selinux_path()
if self._selinux_path is None:
raise exceptions.NotSupportedPluginException("SELinux is not enabled on your system or incompatible version is used.")
@ -45,11 +46,11 @@ class SelinuxPlugin(base.Plugin):
return
threshold = int(value)
if threshold >= 0:
tuned.utils.commands.write_to_file(self._cache_threshold_path, threshold)
self._cmd.write_to_file(self._cache_threshold_path, threshold)
@command_get("avc_cache_threshold")
def _get_avc_cache_threshold(self):
value = tuned.utils.commands.read_file(self._cache_threshold_path)
value = self._cmd.read_file(self._cache_threshold_path)
if len(value) > 0:
return int(value)
return None

View file

@ -2,6 +2,7 @@ import base
from decorators import *
import tuned.logs
from subprocess import *
from tuned.utils.commands import commands
log = tuned.logs.get()
@ -13,6 +14,7 @@ class SysctlPlugin(base.Plugin):
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
self._has_dynamic_options = True
self._cmd = commands()
def _sysctl_storage_key(self, instance):
return "%s/options" % instance.name
@ -51,7 +53,7 @@ class SysctlPlugin(base.Plugin):
def _execute_sysctl(self, arguments):
execute = ["/sbin/sysctl"] + arguments
log.debug("executing %s" % execute)
return tuned.utils.commands.execute(execute)
return self._cmd.execute(execute)
def _read_sysctl(self, option):
retcode, stdout = self._execute_sysctl(["-e", option])

View file

@ -4,7 +4,7 @@ import os.path
from decorators import *
import tuned.logs
from subprocess import *
import tuned.utils.commands
from tuned.utils.commands import commands
log = tuned.logs.get()
@ -18,6 +18,7 @@ class SysfsPlugin(base.Plugin):
def __init__(self, *args, **kwargs):
super(self.__class__, self).__init__(*args, **kwargs)
self._has_dynamic_options = True
self._cmd = commands()
def _instance_init(self, instance):
instance._has_dynamic_tuning = False
@ -45,11 +46,11 @@ class SysfsPlugin(base.Plugin):
return re.match(r"^/sys/.*", sysfs_file)
def _read_sysfs(self, sysfs_file):
data = tuned.utils.commands.read_file(sysfs_file)
data = self._cmd.read_file(sysfs_file)
if len(data) > 0:
return tuned.utils.commands.get_active_option(data, False)
return self._cmd.get_active_option(data, False)
else:
return None
def _write_sysfs(self, sysfs_file, value):
return tuned.utils.commands.write_to_file(sysfs_file, value)
return self._cmd.write_to_file(sysfs_file, value)

View file

@ -1,7 +1,7 @@
import base
from decorators import *
import tuned.logs
import tuned.utils.commands
from tuned.utils.commands import commands
import glob
log = tuned.logs.get()
@ -19,6 +19,7 @@ class USBPlugin(base.Plugin):
self._devices.add(device.sys_name)
self._free_devices = self._devices.copy()
self._cmd = commands()
def _get_config_options(self):
return {
@ -42,9 +43,9 @@ class USBPlugin(base.Plugin):
return
sys_file = self._autosuspend_sysfile(device)
tuned.utils.commands.write_to_file(sys_file, "1" if enable else "0")
self._cmd.write_to_file(sys_file, "1" if enable else "0")
@command_get("autosuspend")
def _get_autosuspend(self, device):
sys_file = self._autosuspend_sysfile(device)
return tuned.utils.commands.read_file(sys_file)
return self._cmd.read_file(sys_file)

View file

@ -1,7 +1,7 @@
import base
from decorators import *
import tuned.logs
from tuned.utils.commands import *
from tuned.utils.commands import commands
import os
log = tuned.logs.get()
@ -20,6 +20,7 @@ class VideoPlugin(base.Plugin):
self._devices.add(device.sys_name)
self._free_devices = self._devices.copy()
self._cmd = commands()
def _get_config_options(self):
return {
@ -47,14 +48,14 @@ class VideoPlugin(base.Plugin):
return
if value in ["default", "auto", "low", "mid", "high"]:
tuned.utils.commands.write_to_file(sys_files["method"], "profile")
tuned.utils.commands.write_to_file(sys_files["profile"], value)
self._cmd.write_to_file(sys_files["method"], "profile")
self._cmd.write_to_file(sys_files["profile"], value)
elif value == "dynpm":
tuned.utils.commands.write_to_file(sys_files["method"], "dynpm")
self._cmd.write_to_file(sys_files["method"], "dynpm")
else:
log.warn("Invalid option for radeon_powersave.")
@command_get("radeon_powersave")
def _get_radeon_powersave(self, device):
sys_files = self._radeon_powersave_files(device)
return tuned.utils.commands.read_file(sys_files["profile"])
return self._cmd.read_file(sys_files["profile"])

View file

@ -5,8 +5,10 @@ import tuned.logs
import os
import struct
import glob
from tuned.utils.commands import commands
log = tuned.logs.get()
cmd = commands()
class VMPlugin(base.Plugin):
"""
@ -40,7 +42,7 @@ class VMPlugin(base.Plugin):
sys_file = self._thp_file()
if os.path.exists(sys_file):
tuned.utils.commands.write_to_file(sys_file, value)
cmd.write_to_file(sys_file, value)
else:
log.warn("Option 'transparent_hugepages' is not supported on current hardware.")
@ -48,6 +50,6 @@ class VMPlugin(base.Plugin):
def _get_transparent_hugepages(self):
sys_file = self._thp_file()
if os.path.exists(sys_file):
return tuned.utils.commands.get_active_option(tuned.utils.commands.read_file(sys_file))
return cmd.get_active_option(cmd.read_file(sys_file))
else:
return None

View file

@ -6,88 +6,100 @@ from configobj import ConfigObj
import re
from subprocess import *
__all__ = ["write_to_file", "read_file", "execute"]
log = tuned.logs.get()
def write_to_file(f, data):
log.debug("Writing to file: %s < %s" % (f, data))
try:
fd = open(f, "w")
fd.write(str(data))
fd.close()
rc = True
except (OSError,IOError) as e:
rc = False
log.error("Writing to file %s error: %s" % (f, e))
return rc
class commands:
def read_file(f, err_ret = ""):
old_value = err_ret
try:
f = open(f, "r")
old_value = f.read()
f.close()
except (OSError,IOError) as e:
log.error("Reading %s error: %s" % (f, e))
return old_value
def __init__(self, logging = True):
self._environment = None
self._logging = logging
def execute(args):
retcode = None
if not hasattr(execute, "_environment"):
execute._environment = os.environ.copy()
execute._environment["LC_ALL"] = "C"
def _error(self, msg):
if self._logging:
log.error(msg)
log.debug("Executing %s." % str(args))
out = ""
try:
proc = Popen(args, stdout=PIPE, stderr=PIPE, env=execute._environment, close_fds=True)
out, err = proc.communicate()
def _debug(self, msg):
if self._logging:
log.debug(msg)
retcode = proc.returncode
if retcode:
err_out = err[:-1]
if len(err_out) == 0:
err_out = out[:-1]
log.error("Executing %s error: %s" % (args[0], err_out))
except (OSError,IOError) as e:
retcode = -1
log.error("Executing %s error: %s" % (args[0], e))
return retcode, out
def write_to_file(self, f, data):
self._debug("Writing to file: %s < %s" % (f, data))
try:
fd = open(f, "w")
fd.write(str(data))
fd.close()
rc = True
except (OSError,IOError) as e:
rc = False
self._error("Writing to file %s error: %s" % (f, e))
return rc
# Helper for parsing kernel options like:
# [always] never
# It will return 'always'
def get_active_option(options, dosplit = True):
m = re.match(r'.*\[([^\]]+)\].*', options)
if m:
return m.group(1)
if dosplit:
return options.split()[0]
return options
def read_file(self, f, err_ret = ""):
old_value = err_ret
try:
f = open(f, "r")
old_value = f.read()
f.close()
except (OSError,IOError) as e:
self._error("Reading %s error: %s" % (f, e))
return old_value
def recommend_profile():
profile = consts.DEFAULT_PROFILE
for f in consts.LOAD_DIRECTORIES:
config = ConfigObj(os.path.join(f, consts.AUTODETECT_FILE))
for section in reversed(config.keys()):
match1 = match2 = True
for option in config[section].keys():
value = config[section][option]
if value == "":
value = r"^$"
if option == "virt":
if not re.match(value, execute("virt-what")[1], re.S):
match1 = False
elif option == "system":
if not re.match(value, read_file(consts.SYSTEM_RELEASE_FILE), re.S):
match2 = False
if match1 and match2:
profile = section
return profile
def execute(self, args):
retcode = None
if self._environment is None:
self._environment = os.environ.copy()
self._environment["LC_ALL"] = "C"
def wait(terminate, time):
try:
return terminate.wait(time, False)
except:
return terminate.wait(time)
self._debug("Executing %s." % str(args))
out = ""
try:
proc = Popen(args, stdout=PIPE, stderr=PIPE, env=self._environment, close_fds=True)
out, err = proc.communicate()
retcode = proc.returncode
if retcode:
err_out = err[:-1]
if len(err_out) == 0:
err_out = out[:-1]
self._error("Executing %s error: %s" % (args[0], err_out))
except (OSError,IOError) as e:
retcode = -1
self._error("Executing %s error: %s" % (args[0], e))
return retcode, out
# Helper for parsing kernel options like:
# [always] never
# It will return 'always'
def get_active_option(self, options, dosplit = True):
m = re.match(r'.*\[([^\]]+)\].*', options)
if m:
return m.group(1)
if dosplit:
return options.split()[0]
return options
def recommend_profile(self):
profile = consts.DEFAULT_PROFILE
for f in consts.LOAD_DIRECTORIES:
config = ConfigObj(os.path.join(f, consts.AUTODETECT_FILE))
for section in reversed(config.keys()):
match1 = match2 = True
for option in config[section].keys():
value = config[section][option]
if value == "":
value = r"^$"
if option == "virt":
if not re.match(value, self.execute("virt-what")[1], re.S):
match1 = False
elif option == "system":
if not re.match(value, self.read_file(consts.SYSTEM_RELEASE_FILE), re.S):
match2 = False
if match1 and match2:
profile = section
return profile
def wait(self, terminate, time):
try:
return terminate.wait(time, False)
except:
return terminate.wait(time)