tuned: added verify command
The verify command verifies whether the current system settings matches activated profile. It also writes all settings from the active profile with the current / expected values to the log. It is good for checking what is exactly set and what changed during the run. Currently custom commands and plugin_scheduler are not supported. Resolves: rhbz#1150047 Fixes: #34 Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
This commit is contained in:
parent
da99153f99
commit
6940d280b6
19 changed files with 317 additions and 77 deletions
|
|
@ -48,6 +48,9 @@ if __name__ == "__main__":
|
|||
parser_off = subparsers.add_parser("recommend", help="recommend profile")
|
||||
parser_off.set_defaults(action="recommend_profile")
|
||||
|
||||
parser_off = subparsers.add_parser("verify", help="verify profile")
|
||||
parser_off.set_defaults(action="verify_profile")
|
||||
|
||||
args = parser.parse_args(sys.argv[1:])
|
||||
|
||||
options = vars(args)
|
||||
|
|
|
|||
|
|
@ -87,6 +87,23 @@ class Admin(object):
|
|||
profile = self._cmd.recommend_profile()
|
||||
print profile
|
||||
|
||||
def verify_profile(self):
|
||||
ret = False
|
||||
try:
|
||||
ret = self._controller.verify_profile()
|
||||
except TunedAdminDBusException as e:
|
||||
self._error(e)
|
||||
self._error("Cannot verify profile if there is no connection to daemon")
|
||||
return False
|
||||
|
||||
if ret:
|
||||
print "Verfication succeeded, current system settings match the preset profile."
|
||||
else:
|
||||
print "Verification failed, current system settings differ from the preset profile."
|
||||
print "See tuned.log for details. You can mostly fix this by Tuned restart:"
|
||||
print " systemctl restart tuned"
|
||||
return ret
|
||||
|
||||
def off(self):
|
||||
result = self._controller.off()
|
||||
if not result:
|
||||
|
|
|
|||
|
|
@ -55,5 +55,8 @@ class DBusController(object):
|
|||
def recommend_profile(self):
|
||||
return self._call("recommend_profile")
|
||||
|
||||
def verify_profile(self):
|
||||
return self._call("verify_profile")
|
||||
|
||||
def off(self):
|
||||
return self._call("disable")
|
||||
|
|
|
|||
|
|
@ -106,3 +106,7 @@ class Controller(tuned.exports.interfaces.ExportableInterface):
|
|||
@exports.export("", "s")
|
||||
def recommend_profile(self):
|
||||
return self._cmd.recommend_profile()
|
||||
|
||||
@exports.export("", "b")
|
||||
def verify_profile(self):
|
||||
return self._daemon.verify_profile()
|
||||
|
|
|
|||
|
|
@ -45,6 +45,10 @@ class Daemon(object):
|
|||
self._terminate = threading.Event()
|
||||
# Flag which is set if terminating due to profile_switch
|
||||
self._terminate_profile_switch = threading.Event()
|
||||
# Flag which is set if there is no operation in progress
|
||||
self._not_used = threading.Event()
|
||||
self._not_used.set()
|
||||
self._profile_applied = threading.Event()
|
||||
|
||||
def _init_profile(self, profile_name):
|
||||
if profile_name is None:
|
||||
|
|
@ -87,6 +91,7 @@ class Daemon(object):
|
|||
self._unit_manager.create(self._profile.units)
|
||||
self._save_active_profile(self._profile.name)
|
||||
self._unit_manager.start_tuning()
|
||||
self._profile_applied.set()
|
||||
|
||||
# In python 2 interpreter with applied patch for rhbz#917709 we need to periodically
|
||||
# poll, otherwise the python will not have chance to update events / locks (due to GIL)
|
||||
|
|
@ -104,6 +109,14 @@ class Daemon(object):
|
|||
log.debug("performing tunings")
|
||||
self._unit_manager.update_tuning()
|
||||
|
||||
self._profile_applied.clear()
|
||||
|
||||
# wait for others to complete their tasks, use timeout 3 x sleep_interval to prevent
|
||||
# deadlocks
|
||||
i = 0
|
||||
while not self._cmd.wait(self._not_used, self._sleep_interval) and i < 3:
|
||||
i += 1
|
||||
|
||||
# if terminating due to profile switch
|
||||
if self._terminate_profile_switch.is_set():
|
||||
profile_switch = True
|
||||
|
|
@ -159,12 +172,34 @@ class Daemon(object):
|
|||
return False
|
||||
|
||||
log.info("starting tuning")
|
||||
self._not_used.set()
|
||||
self._thread = threading.Thread(target=self._thread_code)
|
||||
self._terminate_profile_switch.clear()
|
||||
self._terminate.clear()
|
||||
self._thread.start()
|
||||
return True
|
||||
|
||||
def verify_profile(self):
|
||||
if not self.is_running():
|
||||
log.error("tuned is not running")
|
||||
return False
|
||||
|
||||
if self._profile is None:
|
||||
log.error("no profile is set")
|
||||
return False
|
||||
|
||||
if not self._profile_applied.is_set():
|
||||
log.error("profile is not applied")
|
||||
return False
|
||||
|
||||
# using deamon, the main loop mustn't exit before our completion
|
||||
self._not_used.clear()
|
||||
log.info("verifying profile(s): %s" % self._profile.name)
|
||||
ret = self._unit_manager.verify_tuning()
|
||||
# main loop is allowed to exit
|
||||
self._not_used.set()
|
||||
return ret
|
||||
|
||||
# profile_switch is helper telling plugins whether the stop is due to profile switch
|
||||
def stop(self, profile_switch = False):
|
||||
if not self.is_running():
|
||||
|
|
|
|||
|
|
@ -184,6 +184,18 @@ class Plugin(object):
|
|||
if instance.has_dynamic_tuning and self._global_cfg.get("dynamic_tuning", consts.CFG_DEF_DYNAMIC_TUNING):
|
||||
self._run_for_each_device(instance, self._instance_apply_dynamic)
|
||||
|
||||
def instance_verify_tuning(self, instance):
|
||||
"""
|
||||
Verify static tuning if the plugin instance is active.
|
||||
"""
|
||||
if not instance.active:
|
||||
return None
|
||||
|
||||
if instance.has_static_tuning:
|
||||
return self._instance_verify_static(instance)
|
||||
else:
|
||||
return None
|
||||
|
||||
def instance_update_tuning(self, instance):
|
||||
"""
|
||||
Apply dynamic tuning if the plugin instance is active.
|
||||
|
|
@ -207,6 +219,14 @@ class Plugin(object):
|
|||
self._execute_all_non_device_commands(instance)
|
||||
self._execute_all_device_commands(instance, instance.devices)
|
||||
|
||||
def _instance_verify_static(self, instance):
|
||||
ret = True
|
||||
if self._verify_all_non_device_commands(instance) == False:
|
||||
ret = False
|
||||
if self._verify_all_device_commands(instance, instance.devices) == False:
|
||||
ret = False
|
||||
return ret
|
||||
|
||||
def _instance_unapply_static(self, instance, profile_switch = False):
|
||||
self._cleanup_all_device_commands(instance, instance.devices)
|
||||
self._cleanup_all_non_device_commands(instance)
|
||||
|
|
@ -301,7 +321,7 @@ class Plugin(object):
|
|||
return self._storage.unset(key)
|
||||
|
||||
#
|
||||
# Command execution and cleanup.
|
||||
# Command execution, verification, and cleanup.
|
||||
#
|
||||
|
||||
def _execute_all_non_device_commands(self, instance):
|
||||
|
|
@ -318,32 +338,58 @@ class Plugin(object):
|
|||
for device in devices:
|
||||
self._execute_device_command(instance, command, device, new_value)
|
||||
|
||||
def _check_and_save_value(self, instance, command, device = None, new_value = None):
|
||||
if device is not None:
|
||||
current_value = command["get"](device)
|
||||
else:
|
||||
current_value = command["get"]()
|
||||
def _verify_all_non_device_commands(self, instance):
|
||||
ret = True
|
||||
for command in filter(lambda command: not command["per_device"], self._commands.values()):
|
||||
new_value = instance.options.get(command["name"], None)
|
||||
if new_value is not None:
|
||||
if self._verify_non_device_command(instance, command, new_value) == False:
|
||||
ret = False
|
||||
return ret
|
||||
|
||||
def _verify_all_device_commands(self, instance, devices):
|
||||
ret = True
|
||||
for command in filter(lambda command: command["per_device"], self._commands.values()):
|
||||
new_value = instance.options.get(command["name"], None)
|
||||
if new_value is None:
|
||||
continue
|
||||
for device in devices:
|
||||
if self._verify_device_command(instance, command, device, new_value) == False:
|
||||
ret = False
|
||||
return ret
|
||||
|
||||
def _process_assignment_modifiers(self, new_value, current_value):
|
||||
if new_value is not None:
|
||||
nws = str(new_value)
|
||||
op = nws[:1]
|
||||
val = nws[1:]
|
||||
if current_value is None:
|
||||
return val
|
||||
try:
|
||||
if op == ">":
|
||||
if int(val) > int(current_value):
|
||||
new_value = val;
|
||||
return val
|
||||
else:
|
||||
current_value = None
|
||||
new_value = None
|
||||
return None
|
||||
elif op == "<":
|
||||
if int(val) < int(current_value):
|
||||
new_value = val;
|
||||
return val
|
||||
else:
|
||||
current_value = None
|
||||
new_value = None
|
||||
return None
|
||||
except ValueError:
|
||||
log.warn("cannot compare new value '%s' with current value '%s' by operator '%s', using '%s' directly as new value" % (val, current_value, op, new_value))
|
||||
return new_value
|
||||
|
||||
if current_value is not None:
|
||||
def _get_current_value(self, command, device = None):
|
||||
if device is not None:
|
||||
return command["get"](device)
|
||||
else:
|
||||
return command["get"]()
|
||||
|
||||
def _check_and_save_value(self, instance, command, device = None, new_value = None):
|
||||
current_value = self._get_current_value(command, device)
|
||||
new_value = self._process_assignment_modifiers(new_value, current_value)
|
||||
if new_value is not None and current_value is not None:
|
||||
self._storage_set(instance, command, current_value, device)
|
||||
return new_value
|
||||
|
||||
|
|
@ -353,7 +399,7 @@ class Plugin(object):
|
|||
else:
|
||||
new_value = self._check_and_save_value(instance, command, device, new_value)
|
||||
if new_value is not None:
|
||||
command["set"](new_value, device)
|
||||
command["set"](new_value, device, sim = False)
|
||||
|
||||
def _execute_non_device_command(self, instance, command, new_value):
|
||||
if command["custom"] is not None:
|
||||
|
|
@ -361,7 +407,43 @@ class Plugin(object):
|
|||
else:
|
||||
new_value = self._check_and_save_value(instance, command, None, new_value)
|
||||
if new_value is not None:
|
||||
command["set"](new_value)
|
||||
command["set"](new_value, sim = False)
|
||||
|
||||
def _verify_device_command(self, instance, command, device, new_value):
|
||||
# custom commands not supported for verification
|
||||
if command["custom"] is not None:
|
||||
return None
|
||||
current_value = self._get_current_value(command, device)
|
||||
new_value = self._process_assignment_modifiers(new_value, current_value)
|
||||
if new_value is None:
|
||||
return None
|
||||
new_value = command["set"](new_value, device, sim = True)
|
||||
if new_value is None:
|
||||
return None
|
||||
if new_value == current_value:
|
||||
log.info("verify: device %s: %s = %s" % (device, command["name"], current_value))
|
||||
return True
|
||||
else:
|
||||
log.info("verify: device %s: %s = %s, expected %s" % (device, command["name"], current_value, new_value))
|
||||
return False
|
||||
|
||||
def _verify_non_device_command(self, instance, command, new_value):
|
||||
# custom commands not supported for verification
|
||||
if command["custom"] is not None:
|
||||
return None
|
||||
current_value = self._get_current_value(command)
|
||||
new_value = self._process_assignment_modifiers(new_value, current_value)
|
||||
if new_value is None:
|
||||
return None
|
||||
new_value = command["set"](new_value, sim = True)
|
||||
if new_value is None:
|
||||
return None
|
||||
if new_value == current_value:
|
||||
log.info("verify: %s = %s" % (command["name"], current_value))
|
||||
return True
|
||||
else:
|
||||
log.info("verify: %s = %s, expected %s" % (command["name"], current_value, new_value))
|
||||
return False
|
||||
|
||||
def _cleanup_all_non_device_commands(self, instance):
|
||||
for command in filter(lambda command: not command["per_device"], self._commands.values()):
|
||||
|
|
@ -380,7 +462,7 @@ class Plugin(object):
|
|||
else:
|
||||
old_value = self._storage_get(instance, command, device)
|
||||
if old_value is not None:
|
||||
command["set"](old_value, device)
|
||||
command["set"](old_value, device, sim = False)
|
||||
self._storage_unset(instance, command, device)
|
||||
|
||||
def _cleanup_non_device_command(self, instance, command):
|
||||
|
|
@ -389,5 +471,5 @@ class Plugin(object):
|
|||
else:
|
||||
old_value = self._storage_get(instance, command)
|
||||
if old_value is not None:
|
||||
command["set"](old_value)
|
||||
command["set"](old_value, sim = False)
|
||||
self._storage_unset(instance, command)
|
||||
|
|
|
|||
|
|
@ -53,6 +53,9 @@ class Instance(object):
|
|||
def apply_tuning(self):
|
||||
self._plugin.instance_apply_tuning(self)
|
||||
|
||||
def verify_tuning(self):
|
||||
return self._plugin.instance_verify_tuning(self)
|
||||
|
||||
def update_tuning(self):
|
||||
self._plugin.instance_update_tuning(self)
|
||||
|
||||
|
|
|
|||
|
|
@ -55,11 +55,15 @@ class AudioPlugin(base.Plugin):
|
|||
return "/sys/module/%s/parameters/power_save_controller" % device
|
||||
|
||||
@command_set("timeout", per_device=True)
|
||||
def _set_timeout(self, value, device):
|
||||
def _set_timeout(self, value, device, sim):
|
||||
timeout = int(value)
|
||||
if timeout >= 0:
|
||||
sys_file = self._timeout_path(device)
|
||||
cmd.write_to_file(sys_file, "%d" % timeout)
|
||||
if not sim:
|
||||
cmd.write_to_file(sys_file, "%d" % timeout)
|
||||
return timeout
|
||||
else:
|
||||
return None
|
||||
|
||||
@command_get("timeout")
|
||||
def _get_timeout(self, device):
|
||||
|
|
|
|||
|
|
@ -151,7 +151,7 @@ class CPULatencyPlugin(base.Plugin):
|
|||
pass
|
||||
|
||||
def _get_intel_pstate_attr(self, attr):
|
||||
return self._cmd.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).strip()
|
||||
|
||||
def _set_intel_pstate_attr(self, attr, val):
|
||||
if val is not None:
|
||||
|
|
@ -166,19 +166,22 @@ class CPULatencyPlugin(base.Plugin):
|
|||
self._latency = latency
|
||||
|
||||
def _get_available_governors(self, device):
|
||||
return self._cmd.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).strip().split()
|
||||
|
||||
@command_set("governor", per_device=True)
|
||||
def _set_governor(self, governor, device):
|
||||
def _set_governor(self, governor, device, sim):
|
||||
if governor not in self._get_available_governors(device):
|
||||
log.info("ignoring governor '%s' on cpu '%s', it is not supported" % (governor, device))
|
||||
return
|
||||
log.info("setting governor '%s' on cpu '%s'" % (governor, device))
|
||||
if self._has_cpupower:
|
||||
cpu_id = device.lstrip("cpu")
|
||||
self._cmd.execute(["cpupower", "-c", cpu_id, "frequency-set", "-g", str(governor)])
|
||||
else:
|
||||
self._cmd.write_to_file("/sys/devices/system/cpu/%s/cpufreq/scaling_governor" % device, str(governor))
|
||||
if not sim:
|
||||
log.info("ignoring governor '%s' on cpu '%s', it is not supported" % (governor, device))
|
||||
return None
|
||||
if not sim:
|
||||
log.info("setting governor '%s' on cpu '%s'" % (governor, device))
|
||||
if self._has_cpupower:
|
||||
cpu_id = device.lstrip("cpu")
|
||||
self._cmd.execute(["cpupower", "-c", cpu_id, "frequency-set", "-g", str(governor)])
|
||||
else:
|
||||
self._cmd.write_to_file("/sys/devices/system/cpu/%s/cpufreq/scaling_governor" % device, str(governor))
|
||||
return str(governor)
|
||||
|
||||
@command_get("governor")
|
||||
def _get_governor(self, device):
|
||||
|
|
@ -206,11 +209,15 @@ class CPULatencyPlugin(base.Plugin):
|
|||
return governor
|
||||
|
||||
@command_set("energy_perf_bias", per_device=True)
|
||||
def _set_energy_perf_bias(self, energy_perf_bias, device):
|
||||
def _set_energy_perf_bias(self, energy_perf_bias, device, sim):
|
||||
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")
|
||||
self._cmd.execute(["x86_energy_perf_policy", "-c", cpu_id, str(energy_perf_bias)])
|
||||
if not sim:
|
||||
log.info("setting energy_perf_bias '%s' on cpu '%s'" % (energy_perf_bias, device))
|
||||
self._cmd.execute(["x86_energy_perf_policy", "-c", cpu_id, str(energy_perf_bias)])
|
||||
return str(energy_perf_bias)
|
||||
else:
|
||||
return None
|
||||
|
||||
def _try_parse_num(self, s):
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -196,9 +196,11 @@ class DiskPlugin(hotplug.Plugin):
|
|||
return os.path.join("/sys/block/", device, "queue/scheduler")
|
||||
|
||||
@command_set("elevator", per_device=True)
|
||||
def _set_elevator(self, value, device):
|
||||
def _set_elevator(self, value, device, sim):
|
||||
sys_file = self._elevator_file(device)
|
||||
self._cmd.write_to_file(sys_file, value)
|
||||
if not sim:
|
||||
self._cmd.write_to_file(sys_file, value)
|
||||
return value
|
||||
|
||||
@command_get("elevator")
|
||||
def _get_elevator(self, device):
|
||||
|
|
@ -228,21 +230,27 @@ class DiskPlugin(hotplug.Plugin):
|
|||
return policy_files
|
||||
|
||||
@command_set("alpm")
|
||||
def _set_alpm(self, policy):
|
||||
for policy_file in self._alpm_policy_files():
|
||||
self._cmd.write_to_file(policy_file, policy)
|
||||
def _set_alpm(self, policy, sim):
|
||||
if not sim:
|
||||
for policy_file in self._alpm_policy_files():
|
||||
self._cmd.write_to_file(policy_file, policy)
|
||||
return policy
|
||||
|
||||
@command_get("alpm")
|
||||
def _get_alpm(self):
|
||||
for policy_file in self._alpm_policy_files():
|
||||
return self._cmd.read_file(policy_file)
|
||||
return self._cmd.read_file(policy_file).strip()
|
||||
return None
|
||||
|
||||
@command_set("apm", per_device=True)
|
||||
def _set_apm(self, value, device):
|
||||
def _set_apm(self, value, device, sim):
|
||||
if self._apm_errcnt < consts.ERROR_THRESHOLD:
|
||||
(rc, out) = self._cmd.execute(["hdparm", "-B", str(value), "/dev/" + device])
|
||||
self._update_apm_errcnt(rc)
|
||||
if not sim:
|
||||
(rc, out) = self._cmd.execute(["hdparm", "-B", str(value), "/dev/" + device])
|
||||
self._update_apm_errcnt(rc)
|
||||
return str(value)
|
||||
else:
|
||||
return None
|
||||
|
||||
@command_get("apm")
|
||||
def _get_apm(self, device):
|
||||
|
|
@ -256,10 +264,14 @@ class DiskPlugin(hotplug.Plugin):
|
|||
return value
|
||||
|
||||
@command_set("spindown", per_device=True)
|
||||
def _set_spindown(self, value, device):
|
||||
def _set_spindown(self, value, device, sim):
|
||||
if self._spindown_errcnt < consts.ERROR_THRESHOLD:
|
||||
(rc, out) = self._cmd.execute(["hdparm", "-S", str(value), "/dev/" + device])
|
||||
self._update_spindown_errcnt(rc)
|
||||
if not sim:
|
||||
(rc, out) = self._cmd.execute(["hdparm", "-S", str(value), "/dev/" + device])
|
||||
self._update_spindown_errcnt(rc)
|
||||
return str(value)
|
||||
else:
|
||||
return None
|
||||
|
||||
@command_get("spindown")
|
||||
def _get_spindown(self, device):
|
||||
|
|
@ -278,9 +290,12 @@ class DiskPlugin(hotplug.Plugin):
|
|||
return v
|
||||
|
||||
@command_set("readahead", per_device=True)
|
||||
def _set_readahead(self, value, device):
|
||||
def _set_readahead(self, value, device, sim):
|
||||
sys_file = self._readahead_file(device)
|
||||
self._cmd.write_to_file(sys_file, "%d" % self._parse_ra(value))
|
||||
val = self._parse_ra(value)
|
||||
if not sim:
|
||||
self._cmd.write_to_file(sys_file, "%d" % val)
|
||||
return val
|
||||
|
||||
@command_get("readahead")
|
||||
def _get_readahead(self, device):
|
||||
|
|
@ -311,9 +326,11 @@ class DiskPlugin(hotplug.Plugin):
|
|||
return os.path.join("/sys/block/", device, "queue/iosched/quantum")
|
||||
|
||||
@command_set("scheduler_quantum", per_device=True)
|
||||
def _set_scheduler_quantum(self, value, device):
|
||||
def _set_scheduler_quantum(self, value, device, sim):
|
||||
sys_file = self._scheduler_quantum_file(device)
|
||||
self._cmd.write_to_file(sys_file, "%d" % int(value))
|
||||
if not sim:
|
||||
self._cmd.write_to_file(sys_file, "%d" % int(value))
|
||||
return value
|
||||
|
||||
@command_get("scheduler_quantum")
|
||||
def _get_scheduler_quantum(self, device):
|
||||
|
|
|
|||
|
|
@ -129,17 +129,19 @@ class NetTuningPlugin(base.Plugin):
|
|||
return "/sys/module/nf_conntrack/parameters/hashsize"
|
||||
|
||||
@command_set("wake_on_lan", per_device=True)
|
||||
def _set_wake_on_lan(self, value, device):
|
||||
def _set_wake_on_lan(self, value, device, sim):
|
||||
if value is None:
|
||||
return
|
||||
return None
|
||||
|
||||
# see man ethtool for possible wol values, 0 added as an alias for 'd'
|
||||
value = re.sub(r"0", "d", str(value));
|
||||
if not re.match(r"^[" + WOL_VALUES + r"]+$", value):
|
||||
log.warn("Incorrect 'wake_on_lan' value.")
|
||||
return
|
||||
return None
|
||||
|
||||
self._cmd.execute(["ethtool", "-s", device, "wol", value])
|
||||
if not sim:
|
||||
self._cmd.execute(["ethtool", "-s", device, "wol", value])
|
||||
return value
|
||||
|
||||
@command_get("wake_on_lan")
|
||||
def _get_wake_on_lan(self, device):
|
||||
|
|
@ -153,13 +155,17 @@ class NetTuningPlugin(base.Plugin):
|
|||
return value
|
||||
|
||||
@command_set("nf_conntrack_hashsize")
|
||||
def _set_nf_conntrack_hashsize(self, value):
|
||||
def _set_nf_conntrack_hashsize(self, value, sim):
|
||||
if value is None:
|
||||
return
|
||||
return None
|
||||
|
||||
hashsize = int(value)
|
||||
if hashsize >= 0:
|
||||
self._cmd.write_to_file(self._nf_conntrack_hashsize_path(), hashsize)
|
||||
if not sim:
|
||||
self._cmd.write_to_file(self._nf_conntrack_hashsize_path(), hashsize)
|
||||
return hashsize
|
||||
else:
|
||||
return None
|
||||
|
||||
@command_get("nf_conntrack_hashsize")
|
||||
def _get_nf_conntrack_hashsize(self):
|
||||
|
|
|
|||
|
|
@ -41,12 +41,16 @@ class SelinuxPlugin(base.Plugin):
|
|||
pass
|
||||
|
||||
@command_set("avc_cache_threshold")
|
||||
def _set_avc_cache_threshold(self, value):
|
||||
def _set_avc_cache_threshold(self, value, sim):
|
||||
if value is None:
|
||||
return
|
||||
return None
|
||||
threshold = int(value)
|
||||
if threshold >= 0:
|
||||
self._cmd.write_to_file(self._cache_threshold_path, threshold)
|
||||
if not sim:
|
||||
self._cmd.write_to_file(self._cache_threshold_path, threshold)
|
||||
return threshold
|
||||
else:
|
||||
return None
|
||||
|
||||
@command_get("avc_cache_threshold")
|
||||
def _get_avc_cache_threshold(self):
|
||||
|
|
|
|||
|
|
@ -46,6 +46,17 @@ class SysctlPlugin(base.Plugin):
|
|||
|
||||
self._storage.set("options", instance._sysctl_original)
|
||||
|
||||
def _instance_verify_static(self, instance):
|
||||
ret = True
|
||||
for option, value in instance._sysctl.iteritems():
|
||||
curr_val = self._read_sysctl(option)
|
||||
if curr_val == value:
|
||||
log.info("verify: %s = %s" % (option, curr_val))
|
||||
else:
|
||||
ret = False
|
||||
log.info("verify: %s = %s, expected %s" % (option, curr_val, value))
|
||||
return ret
|
||||
|
||||
def _instance_unapply_static(self, instance, profile_switch = False):
|
||||
for option, value in instance._sysctl_original.iteritems():
|
||||
self._write_sysctl(option, value)
|
||||
|
|
|
|||
|
|
@ -38,6 +38,18 @@ class SysfsPlugin(base.Plugin):
|
|||
else:
|
||||
log.error("rejecting write to '%s' (not inside /sys)" % key)
|
||||
|
||||
def _instance_verify_static(self, instance):
|
||||
ret = True
|
||||
for key, value in instance._sysfs.iteritems():
|
||||
if self._check_sysfs(key):
|
||||
curr_val = self._read_sysfs(key)
|
||||
if curr_val == value:
|
||||
log.info("verify: %s = %s" % (key, curr_val))
|
||||
else:
|
||||
ret = False
|
||||
log.info("verify: %s = %s, expectede %s" % (key, curr_val, value))
|
||||
return ret
|
||||
|
||||
def _instance_unapply_static(self, instance, profile_switch = False):
|
||||
for key, value in instance._sysfs_original.iteritems():
|
||||
self._write_sysfs(key, value)
|
||||
|
|
|
|||
|
|
@ -37,15 +37,18 @@ class USBPlugin(base.Plugin):
|
|||
return "/sys/bus/usb/devices/%s/power/autosuspend" % device
|
||||
|
||||
@command_set("autosuspend", per_device=True)
|
||||
def _set_autosuspend(self, value, device):
|
||||
def _set_autosuspend(self, value, device, sim):
|
||||
enable = self._option_bool(value)
|
||||
if enable is None:
|
||||
return
|
||||
return None
|
||||
|
||||
sys_file = self._autosuspend_sysfile(device)
|
||||
self._cmd.write_to_file(sys_file, "1" if enable else "0")
|
||||
val = "1" if enable else "0"
|
||||
if not sim:
|
||||
sys_file = self._autosuspend_sysfile(device)
|
||||
self._cmd.write_to_file(sys_file, val)
|
||||
return val
|
||||
|
||||
@command_get("autosuspend")
|
||||
def _get_autosuspend(self, device):
|
||||
sys_file = self._autosuspend_sysfile(device)
|
||||
return self._cmd.read_file(sys_file)
|
||||
return self._cmd.read_file(sys_file).strip()
|
||||
|
|
|
|||
|
|
@ -41,21 +41,35 @@ class VideoPlugin(base.Plugin):
|
|||
}
|
||||
|
||||
@command_set("radeon_powersave", per_device=True)
|
||||
def _set_radeon_powersave(self, value, device):
|
||||
def _set_radeon_powersave(self, value, device, sim):
|
||||
sys_files = self._radeon_powersave_files(device)
|
||||
if not os.path.exists(sys_files["method"]):
|
||||
log.warn("radeon_powersave is not supported on '%s'" % device)
|
||||
return
|
||||
if not sim:
|
||||
log.warn("radeon_powersave is not supported on '%s'" % device)
|
||||
return None
|
||||
|
||||
if value in ["default", "auto", "low", "mid", "high"]:
|
||||
self._cmd.write_to_file(sys_files["method"], "profile")
|
||||
self._cmd.write_to_file(sys_files["profile"], value)
|
||||
if not sim:
|
||||
self._cmd.write_to_file(sys_files["method"], "profile")
|
||||
self._cmd.write_to_file(sys_files["profile"], value)
|
||||
return value
|
||||
elif value == "dynpm":
|
||||
self._cmd.write_to_file(sys_files["method"], "dynpm")
|
||||
if not sim:
|
||||
self._cmd.write_to_file(sys_files["method"], "dynpm")
|
||||
return "dynpm"
|
||||
else:
|
||||
log.warn("Invalid option for radeon_powersave.")
|
||||
if not sim:
|
||||
log.warn("Invalid option for radeon_powersave.")
|
||||
return None
|
||||
|
||||
|
||||
@command_get("radeon_powersave")
|
||||
def _get_radeon_powersave(self, device):
|
||||
sys_files = self._radeon_powersave_files(device)
|
||||
return self._cmd.read_file(sys_files["profile"])
|
||||
method = self._cmd.read_file(sys_files["method"]).strip()
|
||||
if method == "profile":
|
||||
return self._cmd.read_file(sys_files["profile"]).strip()
|
||||
elif method == "dynpm":
|
||||
return "dynpm"
|
||||
else:
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -35,16 +35,21 @@ class VMPlugin(base.Plugin):
|
|||
return path
|
||||
|
||||
@command_set("transparent_hugepages")
|
||||
def _set_transparent_hugepages(self, value):
|
||||
def _set_transparent_hugepages(self, value, sim):
|
||||
if value not in ["always", "never"]:
|
||||
log.warn("Incorrect 'transparent_hugepages' value.")
|
||||
return
|
||||
if not sim:
|
||||
log.warn("Incorrect 'transparent_hugepages' value.")
|
||||
return None
|
||||
|
||||
sys_file = self._thp_file()
|
||||
if os.path.exists(sys_file):
|
||||
cmd.write_to_file(sys_file, value)
|
||||
if not sim:
|
||||
cmd.write_to_file(sys_file, value)
|
||||
return value
|
||||
else:
|
||||
log.warn("Option 'transparent_hugepages' is not supported on current hardware.")
|
||||
if not sim:
|
||||
log.warn("Option 'transparent_hugepages' is not supported on current hardware.")
|
||||
return None
|
||||
|
||||
@command_get("transparent_hugepages")
|
||||
def _get_transparent_hugepages(self):
|
||||
|
|
|
|||
|
|
@ -80,6 +80,13 @@ class Manager(object):
|
|||
for instance in self._instances:
|
||||
instance.apply_tuning()
|
||||
|
||||
def verify_tuning(self):
|
||||
ret = True
|
||||
for instance in self._instances:
|
||||
if instance.verify_tuning() == False:
|
||||
ret = False
|
||||
return ret
|
||||
|
||||
def update_tuning(self):
|
||||
for instance in self._instances:
|
||||
instance.update_tuning()
|
||||
|
|
|
|||
|
|
@ -104,6 +104,9 @@ class commands:
|
|||
profile = section
|
||||
return profile
|
||||
|
||||
# Do not make balancing on patched Python 2 interpreter (rhbz#1028122).
|
||||
# It means less CPU usage on patchet interpreter. On non-patched interpreter
|
||||
# it is not allowed to sleep longer than 50 ms.
|
||||
def wait(self, terminate, time):
|
||||
try:
|
||||
return terminate.wait(time, False)
|
||||
|
|
|
|||
Loading…
Reference in a new issue