hotplug: do not report ENOENT errors on device remove
It requires slight internal plugin API change, thus 3rd party plugins needs updating. Namely the 'command_set' methods for devices were extended by the 'remove' boolean parameter which is set to 'True' on the hotplug remove event. Then the method should silent the ENOENT errors where appropriate, because the device interface may be removed (by kernel/udev) before the method finishes. Resolves: RHEL-11342 Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
This commit is contained in:
parent
2652d7c29d
commit
2f911b7e02
14 changed files with 127 additions and 89 deletions
|
|
@ -211,7 +211,7 @@ class CommandsPlugin(Plugin):
|
|||
return {'size':'S','device_setting':'101'}
|
||||
|
||||
@decorators.command_set('size')
|
||||
def _set_size(self, new_size, sim):
|
||||
def _set_size(self, new_size, sim, remove):
|
||||
self._size = new_size
|
||||
return new_size
|
||||
|
||||
|
|
@ -220,7 +220,7 @@ class CommandsPlugin(Plugin):
|
|||
return self._size
|
||||
|
||||
@decorators.command_set('device_setting',per_device = True)
|
||||
def _set_device_setting(self,value,device,sim):
|
||||
def _set_device_setting(self,value,device,sim,remove):
|
||||
device.setting = value
|
||||
return device.setting
|
||||
|
||||
|
|
|
|||
|
|
@ -506,7 +506,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, sim = False)
|
||||
command["set"](new_value, device, sim = False, remove = False)
|
||||
|
||||
def _execute_non_device_command(self, instance, command, new_value):
|
||||
if command["custom"] is not None:
|
||||
|
|
@ -514,7 +514,7 @@ 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, sim = False)
|
||||
command["set"](new_value, sim = False, remove = False)
|
||||
|
||||
def _norm_value(self, value):
|
||||
v = self._cmd.unquote(str(value))
|
||||
|
|
@ -576,7 +576,7 @@ class Plugin(object):
|
|||
new_value = self._process_assignment_modifiers(new_value, current_value)
|
||||
if new_value is None:
|
||||
return None
|
||||
new_value = command["set"](new_value, device, True)
|
||||
new_value = command["set"](new_value, device, True, False)
|
||||
return self._verify_value(command["name"], new_value, current_value, ignore_missing, device)
|
||||
|
||||
def _verify_non_device_command(self, instance, command, new_value, ignore_missing):
|
||||
|
|
@ -586,7 +586,7 @@ class Plugin(object):
|
|||
new_value = self._process_assignment_modifiers(new_value, current_value)
|
||||
if new_value is None:
|
||||
return None
|
||||
new_value = command["set"](new_value, True)
|
||||
new_value = command["set"](new_value, True, False)
|
||||
return self._verify_value(command["name"], new_value, current_value, ignore_missing)
|
||||
|
||||
def _cleanup_all_non_device_commands(self, instance):
|
||||
|
|
@ -594,19 +594,19 @@ class Plugin(object):
|
|||
if (instance.options.get(command["name"], None) is not None) or (command["name"] in self._options_used_by_dynamic):
|
||||
self._cleanup_non_device_command(instance, command)
|
||||
|
||||
def _cleanup_all_device_commands(self, instance, devices):
|
||||
def _cleanup_all_device_commands(self, instance, devices, remove = False):
|
||||
for command in reversed([command for command in list(self._commands.values()) if command["per_device"]]):
|
||||
if (instance.options.get(command["name"], None) is not None) or (command["name"] in self._options_used_by_dynamic):
|
||||
for device in devices:
|
||||
self._cleanup_device_command(instance, command, device)
|
||||
self._cleanup_device_command(instance, command, device, remove)
|
||||
|
||||
def _cleanup_device_command(self, instance, command, device):
|
||||
def _cleanup_device_command(self, instance, command, device, remove = False):
|
||||
if command["custom"] is not None:
|
||||
command["custom"](False, None, device, False, False)
|
||||
else:
|
||||
old_value = self._storage_get(instance, command, device)
|
||||
if old_value is not None:
|
||||
command["set"](old_value, device, sim = False)
|
||||
command["set"](old_value, device, sim = False, remove = remove)
|
||||
self._storage_unset(instance, command, device)
|
||||
|
||||
def _cleanup_non_device_command(self, instance, command):
|
||||
|
|
@ -615,5 +615,5 @@ class Plugin(object):
|
|||
else:
|
||||
old_value = self._storage_get(instance, command)
|
||||
if old_value is not None:
|
||||
command["set"](old_value, sim = False)
|
||||
command["set"](old_value, sim = False, remove = False)
|
||||
self._storage_unset(instance, command)
|
||||
|
|
|
|||
|
|
@ -109,4 +109,4 @@ class Plugin(base.Plugin):
|
|||
def _removed_device_unapply_tuning(self, instance, device_name):
|
||||
if instance.has_dynamic_tuning and self._global_cfg.get(consts.CFG_DYNAMIC_TUNING, consts.CFG_DEF_DYNAMIC_TUNING):
|
||||
self._instance_unapply_dynamic(instance, device_name)
|
||||
self._cleanup_all_device_commands(instance, [device_name])
|
||||
self._cleanup_all_device_commands(instance, [device_name], remove = True)
|
||||
|
|
|
|||
|
|
@ -4,6 +4,7 @@ import tuned.logs
|
|||
from tuned.utils.commands import commands
|
||||
|
||||
import os
|
||||
import errno
|
||||
import struct
|
||||
import glob
|
||||
|
||||
|
|
@ -73,7 +74,7 @@ class AudioPlugin(hotplug.Plugin):
|
|||
return "/sys/module/%s/parameters/power_save_controller" % device
|
||||
|
||||
@command_set("timeout", per_device = True)
|
||||
def _set_timeout(self, value, device, sim):
|
||||
def _set_timeout(self, value, device, sim, remove):
|
||||
try:
|
||||
timeout = int(value)
|
||||
except ValueError:
|
||||
|
|
@ -82,7 +83,8 @@ class AudioPlugin(hotplug.Plugin):
|
|||
if timeout >= 0:
|
||||
sys_file = self._timeout_path(device)
|
||||
if not sim:
|
||||
cmd.write_to_file(sys_file, "%d" % timeout)
|
||||
cmd.write_to_file(sys_file, "%d" % timeout, \
|
||||
no_error = [errno.ENOENT] if remove else False)
|
||||
return timeout
|
||||
else:
|
||||
return None
|
||||
|
|
@ -96,12 +98,13 @@ class AudioPlugin(hotplug.Plugin):
|
|||
return None
|
||||
|
||||
@command_set("reset_controller", per_device = True)
|
||||
def _set_reset_controller(self, value, device, sim):
|
||||
def _set_reset_controller(self, value, device, sim, remove):
|
||||
v = cmd.get_bool(value)
|
||||
sys_file = self._reset_controller_path(device)
|
||||
if os.path.exists(sys_file):
|
||||
if not sim:
|
||||
cmd.write_to_file(sys_file, v)
|
||||
cmd.write_to_file(sys_file, v, \
|
||||
no_error = [errno.ENOENT] if remove else False)
|
||||
return v
|
||||
return None
|
||||
|
||||
|
|
|
|||
|
|
@ -5,6 +5,7 @@ from tuned.utils.commands import commands
|
|||
import tuned.consts as consts
|
||||
|
||||
import os
|
||||
import errno
|
||||
import struct
|
||||
import errno
|
||||
import platform
|
||||
|
|
@ -500,7 +501,7 @@ class CPULatencyPlugin(hotplug.Plugin):
|
|||
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, governors, device, sim):
|
||||
def _set_governor(self, governors, device, sim, remove):
|
||||
if not self._check_cpu_can_change_governor(device):
|
||||
return None
|
||||
governors = str(governors)
|
||||
|
|
@ -517,7 +518,7 @@ class CPULatencyPlugin(hotplug.Plugin):
|
|||
log.info("setting governor '%s' on cpu '%s'"
|
||||
% (governor, device))
|
||||
self._cmd.write_to_file("/sys/devices/system/cpu/%s/cpufreq/scaling_governor"
|
||||
% device, governor)
|
||||
% device, governor, no_error = [errno.ENOENT] if remove else False)
|
||||
break
|
||||
elif not sim:
|
||||
log.debug("Ignoring governor '%s' on cpu '%s', it is not supported"
|
||||
|
|
@ -546,7 +547,7 @@ class CPULatencyPlugin(hotplug.Plugin):
|
|||
return "/sys/devices/system/cpu/cpufreq/%s/sampling_down_factor" % governor
|
||||
|
||||
@command_set("sampling_down_factor", per_device = True, priority = 10)
|
||||
def _set_sampling_down_factor(self, sampling_down_factor, device, sim):
|
||||
def _set_sampling_down_factor(self, sampling_down_factor, device, sim, remove):
|
||||
val = None
|
||||
|
||||
# hack to clear governors map when the profile starts unloading
|
||||
|
|
@ -569,7 +570,7 @@ class CPULatencyPlugin(hotplug.Plugin):
|
|||
val = str(sampling_down_factor)
|
||||
if not sim:
|
||||
log.info("setting sampling_down_factor to '%s' for governor '%s'" % (val, governor))
|
||||
self._cmd.write_to_file(path, val)
|
||||
self._cmd.write_to_file(path, val, no_error = [errno.ENOENT] if remove else False)
|
||||
return val
|
||||
|
||||
@command_get("sampling_down_factor")
|
||||
|
|
@ -598,7 +599,7 @@ class CPULatencyPlugin(hotplug.Plugin):
|
|||
return "/sys/devices/system/cpu/cpu%s/power/energy_perf_bias" % cpu_id
|
||||
|
||||
@command_set("energy_perf_bias", per_device=True)
|
||||
def _set_energy_perf_bias(self, energy_perf_bias, device, sim):
|
||||
def _set_energy_perf_bias(self, energy_perf_bias, device, sim, remove):
|
||||
if not self._is_cpu_online(device):
|
||||
log.debug("%s is not online, skipping" % device)
|
||||
return None
|
||||
|
|
@ -613,10 +614,11 @@ class CPULatencyPlugin(hotplug.Plugin):
|
|||
if not sim:
|
||||
for val in vals:
|
||||
val = val.strip()
|
||||
if self._cmd.write_to_file(energy_perf_bias_path, val):
|
||||
log.info("energy_perf_bias successfully set to '%s' on cpu '%s'"
|
||||
% (val, device))
|
||||
break
|
||||
if self._cmd.write_to_file(energy_perf_bias_path, val, \
|
||||
no_error = [errno.ENOENT] if remove else False):
|
||||
log.info("energy_perf_bias successfully set to '%s' on cpu '%s'"
|
||||
% (val, device))
|
||||
break
|
||||
else:
|
||||
log.error("Failed to set energy_perf_bias on cpu '%s'. Is the value in the profile correct?"
|
||||
% device)
|
||||
|
|
@ -711,7 +713,7 @@ class CPULatencyPlugin(hotplug.Plugin):
|
|||
return self._has_pm_qos_resume_latency_us
|
||||
|
||||
@command_set("pm_qos_resume_latency_us", per_device=True)
|
||||
def _set_pm_qos_resume_latency_us(self, pm_qos_resume_latency_us, device, sim):
|
||||
def _set_pm_qos_resume_latency_us(self, pm_qos_resume_latency_us, device, sim, remove):
|
||||
if not self._is_cpu_online(device):
|
||||
log.debug("%s is not online, skipping" % device)
|
||||
return None
|
||||
|
|
@ -729,7 +731,8 @@ class CPULatencyPlugin(hotplug.Plugin):
|
|||
if not self._check_pm_qos_resume_latency_us(device):
|
||||
return None
|
||||
if not sim:
|
||||
self._cmd.write_to_file(self._pm_qos_resume_latency_us_path(device), latency)
|
||||
self._cmd.write_to_file(self._pm_qos_resume_latency_us_path(device), latency, \
|
||||
no_error = [errno.ENOENT] if remove else False)
|
||||
return latency
|
||||
|
||||
@command_get("pm_qos_resume_latency_us")
|
||||
|
|
@ -742,7 +745,7 @@ class CPULatencyPlugin(hotplug.Plugin):
|
|||
return self._cmd.read_file(self._pm_qos_resume_latency_us_path(device), no_error=ignore_missing).strip()
|
||||
|
||||
@command_set("energy_performance_preference", per_device=True)
|
||||
def _set_energy_performance_preference(self, energy_performance_preference, device, sim):
|
||||
def _set_energy_performance_preference(self, energy_performance_preference, device, sim, remove):
|
||||
if not self._is_cpu_online(device):
|
||||
log.debug("%s is not online, skipping" % device)
|
||||
return None
|
||||
|
|
@ -753,7 +756,8 @@ class CPULatencyPlugin(hotplug.Plugin):
|
|||
avail_vals = set(self._cmd.read_file(self._pstate_preference_path(cpu_id, True)).split())
|
||||
for val in vals:
|
||||
if val in avail_vals:
|
||||
self._cmd.write_to_file(self._pstate_preference_path(cpu_id), val)
|
||||
self._cmd.write_to_file(self._pstate_preference_path(cpu_id), val, \
|
||||
no_error = [errno.ENOENT] if remove else False)
|
||||
log.info("Setting energy_performance_preference value '%s' for cpu '%s'" % (val, device))
|
||||
break
|
||||
else:
|
||||
|
|
|
|||
|
|
@ -335,10 +335,11 @@ class DiskPlugin(hotplug.Plugin):
|
|||
return self._sysfs_path(device, "queue/scheduler")
|
||||
|
||||
@command_set("elevator", per_device=True)
|
||||
def _set_elevator(self, value, device, sim):
|
||||
def _set_elevator(self, value, device, sim, remove):
|
||||
sys_file = self._elevator_file(device)
|
||||
if not sim:
|
||||
self._cmd.write_to_file(sys_file, value)
|
||||
self._cmd.write_to_file(sys_file, value, \
|
||||
no_error = [errno.ENOENT] if remove else False)
|
||||
return value
|
||||
|
||||
@command_get("elevator")
|
||||
|
|
@ -349,7 +350,7 @@ class DiskPlugin(hotplug.Plugin):
|
|||
return self._cmd.get_active_option(self._cmd.read_file(sys_file, no_error=ignore_missing))
|
||||
|
||||
@command_set("apm", per_device=True)
|
||||
def _set_apm(self, value, device, sim):
|
||||
def _set_apm(self, value, device, sim, remove):
|
||||
if device not in self._hdparm_apm_devices:
|
||||
if not sim:
|
||||
log.info("apm option is not supported for device '%s'" % device)
|
||||
|
|
@ -389,7 +390,7 @@ class DiskPlugin(hotplug.Plugin):
|
|||
return value
|
||||
|
||||
@command_set("spindown", per_device=True)
|
||||
def _set_spindown(self, value, device, sim):
|
||||
def _set_spindown(self, value, device, sim, remove):
|
||||
if device not in self._hdparm_apm_devices:
|
||||
if not sim:
|
||||
log.info("spindown option is not supported for device '%s'" % device)
|
||||
|
|
@ -428,14 +429,15 @@ class DiskPlugin(hotplug.Plugin):
|
|||
return v
|
||||
|
||||
@command_set("readahead", per_device=True)
|
||||
def _set_readahead(self, value, device, sim):
|
||||
def _set_readahead(self, value, device, sim, remove):
|
||||
sys_file = self._readahead_file(device)
|
||||
val = self._parse_ra(value)
|
||||
if val is None:
|
||||
log.error("Invalid readahead value '%s' for device '%s'" % (value, device))
|
||||
else:
|
||||
if not sim:
|
||||
self._cmd.write_to_file(sys_file, "%d" % val)
|
||||
self._cmd.write_to_file(sys_file, "%d" % val, \
|
||||
no_error = [errno.ENOENT] if remove else False)
|
||||
return val
|
||||
|
||||
@command_get("readahead")
|
||||
|
|
@ -471,10 +473,11 @@ class DiskPlugin(hotplug.Plugin):
|
|||
return self._sysfs_path(device, "queue/iosched/quantum")
|
||||
|
||||
@command_set("scheduler_quantum", per_device=True)
|
||||
def _set_scheduler_quantum(self, value, device, sim):
|
||||
def _set_scheduler_quantum(self, value, device, sim, remove):
|
||||
sys_file = self._scheduler_quantum_file(device)
|
||||
if not sim:
|
||||
self._cmd.write_to_file(sys_file, "%d" % int(value))
|
||||
self._cmd.write_to_file(sys_file, "%d" % int(value), \
|
||||
no_error = [errno.ENOENT] if remove else False)
|
||||
return value
|
||||
|
||||
@command_get("scheduler_quantum")
|
||||
|
|
|
|||
|
|
@ -380,7 +380,7 @@ class NetTuningPlugin(hotplug.Plugin):
|
|||
return "/sys/module/nf_conntrack/parameters/hashsize"
|
||||
|
||||
@command_set("wake_on_lan", per_device=True)
|
||||
def _set_wake_on_lan(self, value, device, sim):
|
||||
def _set_wake_on_lan(self, value, device, sim, remove):
|
||||
if value is None:
|
||||
return None
|
||||
|
||||
|
|
@ -406,14 +406,15 @@ class NetTuningPlugin(hotplug.Plugin):
|
|||
return value
|
||||
|
||||
@command_set("nf_conntrack_hashsize")
|
||||
def _set_nf_conntrack_hashsize(self, value, sim):
|
||||
def _set_nf_conntrack_hashsize(self, value, sim, remove):
|
||||
if value is None:
|
||||
return None
|
||||
|
||||
hashsize = int(value)
|
||||
if hashsize >= 0:
|
||||
if not sim:
|
||||
self._cmd.write_to_file(self._nf_conntrack_hashsize_path(), hashsize)
|
||||
self._cmd.write_to_file(self._nf_conntrack_hashsize_path(), hashsize, \
|
||||
no_error = [errno.ENOENT] if remove else False)
|
||||
return hashsize
|
||||
else:
|
||||
return None
|
||||
|
|
@ -447,7 +448,7 @@ class NetTuningPlugin(hotplug.Plugin):
|
|||
return self._call_ip_link(args)
|
||||
|
||||
@command_set("txqueuelen", per_device=True)
|
||||
def _set_txqueuelen(self, value, device, sim):
|
||||
def _set_txqueuelen(self, value, device, sim, remove):
|
||||
if value is None:
|
||||
return None
|
||||
try:
|
||||
|
|
@ -487,7 +488,7 @@ class NetTuningPlugin(hotplug.Plugin):
|
|||
return res.group(1)
|
||||
|
||||
@command_set("mtu", per_device=True)
|
||||
def _set_mtu(self, value, device, sim):
|
||||
def _set_mtu(self, value, device, sim, remove):
|
||||
if value is None:
|
||||
return None
|
||||
try:
|
||||
|
|
|
|||
|
|
@ -1414,12 +1414,13 @@ class SchedulerPlugin(base.Plugin):
|
|||
self._secure_boot_hint = False
|
||||
return data
|
||||
|
||||
def _set_sched_knob(self, prefix, namespace, knob, value, sim):
|
||||
def _set_sched_knob(self, prefix, namespace, knob, value, sim, remove = False):
|
||||
if value is None:
|
||||
return None
|
||||
if not sim:
|
||||
if not self._cmd.write_to_file(self._get_sched_knob_path(prefix, namespace, knob), value):
|
||||
log.error("Error writing value '%s' to '%s'" % (value, knob))
|
||||
if not self._cmd.write_to_file(self._get_sched_knob_path(prefix, namespace, knob), value, \
|
||||
no_error = [errno.ENOENT] if remove else False):
|
||||
log.error("Error writing value '%s' to '%s'" % (value, knob))
|
||||
return value
|
||||
|
||||
@command_get("sched_min_granularity_ns")
|
||||
|
|
@ -1427,77 +1428,77 @@ class SchedulerPlugin(base.Plugin):
|
|||
return self._get_sched_knob("", "sched", "min_granularity_ns")
|
||||
|
||||
@command_set("sched_min_granularity_ns")
|
||||
def _set_sched_min_granularity_ns(self, value, sim):
|
||||
return self._set_sched_knob("", "sched", "min_granularity_ns", value, sim)
|
||||
def _set_sched_min_granularity_ns(self, value, sim, remove):
|
||||
return self._set_sched_knob("", "sched", "min_granularity_ns", value, sim, remove)
|
||||
|
||||
@command_get("sched_latency_ns")
|
||||
def _get_sched_latency_ns(self):
|
||||
return self._get_sched_knob("", "sched", "latency_ns")
|
||||
|
||||
@command_set("sched_latency_ns")
|
||||
def _set_sched_latency_ns(self, value, sim):
|
||||
return self._set_sched_knob("", "sched", "latency_ns", value, sim)
|
||||
def _set_sched_latency_ns(self, value, sim, remove):
|
||||
return self._set_sched_knob("", "sched", "latency_ns", value, sim, remove)
|
||||
|
||||
@command_get("sched_wakeup_granularity_ns")
|
||||
def _get_sched_wakeup_granularity_ns(self):
|
||||
return self._get_sched_knob("", "sched", "wakeup_granularity_ns")
|
||||
|
||||
@command_set("sched_wakeup_granularity_ns")
|
||||
def _set_sched_wakeup_granularity_ns(self, value, sim):
|
||||
return self._set_sched_knob("", "sched", "wakeup_granularity_ns", value, sim)
|
||||
def _set_sched_wakeup_granularity_ns(self, value, sim, remove):
|
||||
return self._set_sched_knob("", "sched", "wakeup_granularity_ns", value, sim, remove)
|
||||
|
||||
@command_get("sched_tunable_scaling")
|
||||
def _get_sched_tunable_scaling(self):
|
||||
return self._get_sched_knob("", "sched", "tunable_scaling")
|
||||
|
||||
@command_set("sched_tunable_scaling")
|
||||
def _set_sched_tunable_scaling(self, value, sim):
|
||||
return self._set_sched_knob("", "sched", "tunable_scaling", value, sim)
|
||||
def _set_sched_tunable_scaling(self, value, sim, remove):
|
||||
return self._set_sched_knob("", "sched", "tunable_scaling", value, sim, remove)
|
||||
|
||||
@command_get("sched_migration_cost_ns")
|
||||
def _get_sched_migration_cost_ns(self):
|
||||
return self._get_sched_knob("", "sched", "migration_cost_ns")
|
||||
|
||||
@command_set("sched_migration_cost_ns")
|
||||
def _set_sched_migration_cost_ns(self, value, sim):
|
||||
return self._set_sched_knob("", "sched", "migration_cost_ns", value, sim)
|
||||
def _set_sched_migration_cost_ns(self, value, sim, remove):
|
||||
return self._set_sched_knob("", "sched", "migration_cost_ns", value, sim, remove)
|
||||
|
||||
@command_get("sched_nr_migrate")
|
||||
def _get_sched_nr_migrate(self):
|
||||
return self._get_sched_knob("", "sched", "nr_migrate")
|
||||
|
||||
@command_set("sched_nr_migrate")
|
||||
def _set_sched_nr_migrate(self, value, sim):
|
||||
return self._set_sched_knob("", "sched", "nr_migrate", value, sim)
|
||||
def _set_sched_nr_migrate(self, value, sim, remove):
|
||||
return self._set_sched_knob("", "sched", "nr_migrate", value, sim, remove)
|
||||
|
||||
@command_get("numa_balancing_scan_delay_ms")
|
||||
def _get_numa_balancing_scan_delay_ms(self):
|
||||
return self._get_sched_knob("sched", "numa_balancing", "scan_delay_ms")
|
||||
|
||||
@command_set("numa_balancing_scan_delay_ms")
|
||||
def _set_numa_balancing_scan_delay_ms(self, value, sim):
|
||||
return self._set_sched_knob("sched", "numa_balancing", "scan_delay_ms", value, sim)
|
||||
def _set_numa_balancing_scan_delay_ms(self, value, sim, remove):
|
||||
return self._set_sched_knob("sched", "numa_balancing", "scan_delay_ms", value, sim, remove)
|
||||
|
||||
@command_get("numa_balancing_scan_period_min_ms")
|
||||
def _get_numa_balancing_scan_period_min_ms(self):
|
||||
return self._get_sched_knob("sched", "numa_balancing", "scan_period_min_ms")
|
||||
|
||||
@command_set("numa_balancing_scan_period_min_ms")
|
||||
def _set_numa_balancing_scan_period_min_ms(self, value, sim):
|
||||
return self._set_sched_knob("sched", "numa_balancing", "scan_period_min_ms", value, sim)
|
||||
def _set_numa_balancing_scan_period_min_ms(self, value, sim, remove):
|
||||
return self._set_sched_knob("sched", "numa_balancing", "scan_period_min_ms", value, sim, remove)
|
||||
|
||||
@command_get("numa_balancing_scan_period_max_ms")
|
||||
def _get_numa_balancing_scan_period_max_ms(self):
|
||||
return self._get_sched_knob("sched", "numa_balancing", "scan_period_max_ms")
|
||||
|
||||
@command_set("numa_balancing_scan_period_max_ms")
|
||||
def _set_numa_balancing_scan_period_max_ms(self, value, sim):
|
||||
return self._set_sched_knob("sched", "numa_balancing", "scan_period_max_ms", value, sim)
|
||||
def _set_numa_balancing_scan_period_max_ms(self, value, sim, remove):
|
||||
return self._set_sched_knob("sched", "numa_balancing", "scan_period_max_ms", value, sim, remove)
|
||||
|
||||
@command_get("numa_balancing_scan_size_mb")
|
||||
def _get_numa_balancing_scan_size_mb(self):
|
||||
return self._get_sched_knob("sched", "numa_balancing", "scan_size_mb")
|
||||
|
||||
@command_set("numa_balancing_scan_size_mb")
|
||||
def _set_numa_balancing_scan_size_mb(self, value, sim):
|
||||
return self._set_sched_knob("sched", "numa_balancing", "scan_size_mb", value, sim)
|
||||
def _set_numa_balancing_scan_size_mb(self, value, sim, remove):
|
||||
return self._set_sched_knob("sched", "numa_balancing", "scan_size_mb", value, sim, remove)
|
||||
|
|
|
|||
|
|
@ -86,13 +86,14 @@ class SCSIHostPlugin(hotplug.Plugin):
|
|||
return os.path.join("/sys/class/scsi_host/", str(device), "link_power_management_policy")
|
||||
|
||||
@command_set("alpm", per_device = True)
|
||||
def _set_alpm(self, policy, device, sim):
|
||||
def _set_alpm(self, policy, device, sim, remove):
|
||||
if policy is None:
|
||||
return None
|
||||
policy_file = self._get_alpm_policy_file(device)
|
||||
if not sim:
|
||||
if os.path.exists(policy_file):
|
||||
self._cmd.write_to_file(policy_file, policy)
|
||||
self._cmd.write_to_file(policy_file, policy, \
|
||||
no_error = [errno.ENOENT] if remove else False)
|
||||
else:
|
||||
log.info("ALPM control file ('%s') not found, skipping ALPM setting for '%s'" % (policy_file, str(device)))
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import os
|
||||
import errno
|
||||
from . import base
|
||||
from .decorators import *
|
||||
import tuned.logs
|
||||
|
|
@ -63,13 +64,14 @@ class SelinuxPlugin(base.Plugin):
|
|||
pass
|
||||
|
||||
@command_set("avc_cache_threshold")
|
||||
def _set_avc_cache_threshold(self, value, sim):
|
||||
def _set_avc_cache_threshold(self, value, sim, remove):
|
||||
if value is None:
|
||||
return None
|
||||
threshold = int(value)
|
||||
if threshold >= 0:
|
||||
if not sim:
|
||||
self._cmd.write_to_file(self._cache_threshold_path, threshold)
|
||||
self._cmd.write_to_file(self._cache_threshold_path, threshold, \
|
||||
no_error = [errno.ENOENT] if remove else False)
|
||||
return threshold
|
||||
else:
|
||||
return None
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from .decorators import *
|
|||
import tuned.logs
|
||||
from tuned.utils.commands import commands
|
||||
import glob
|
||||
import errno
|
||||
|
||||
log = tuned.logs.get()
|
||||
|
||||
|
|
@ -57,7 +58,7 @@ 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, sim):
|
||||
def _set_autosuspend(self, value, device, sim, remove):
|
||||
enable = self._option_bool(value)
|
||||
if enable is None:
|
||||
return None
|
||||
|
|
@ -65,7 +66,8 @@ class USBPlugin(base.Plugin):
|
|||
val = "1" if enable else "0"
|
||||
if not sim:
|
||||
sys_file = self._autosuspend_sysfile(device)
|
||||
self._cmd.write_to_file(sys_file, val)
|
||||
self._cmd.write_to_file(sys_file, val, \
|
||||
no_error = [errno.ENOENT] if remove else False)
|
||||
return val
|
||||
|
||||
@command_get("autosuspend")
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from .decorators import *
|
|||
import tuned.logs
|
||||
from tuned.utils.commands import commands
|
||||
import os
|
||||
import errno
|
||||
import re
|
||||
|
||||
log = tuned.logs.get()
|
||||
|
|
@ -76,7 +77,7 @@ class VideoPlugin(base.Plugin):
|
|||
}
|
||||
|
||||
@command_set("radeon_powersave", per_device=True)
|
||||
def _set_radeon_powersave(self, value, device, sim):
|
||||
def _set_radeon_powersave(self, value, device, sim, remove):
|
||||
sys_files = self._radeon_powersave_files(device)
|
||||
va = str(re.sub(r"(\s*:\s*)|(\s+)|(\s*;\s*)|(\s*,\s*)", " ", value)).split()
|
||||
if not os.path.exists(sys_files["method"]):
|
||||
|
|
@ -86,20 +87,25 @@ class VideoPlugin(base.Plugin):
|
|||
for v in va:
|
||||
if v in ["default", "auto", "low", "mid", "high"]:
|
||||
if not sim:
|
||||
if (self._cmd.write_to_file(sys_files["method"], "profile") and
|
||||
self._cmd.write_to_file(sys_files["profile"], v)):
|
||||
return v
|
||||
if (self._cmd.write_to_file(sys_files["method"], "profile", \
|
||||
no_error = [errno.ENOENT] if remove else False) and
|
||||
self._cmd.write_to_file(sys_files["profile"], v, \
|
||||
no_error = [errno.ENOENT] if remove else False)):
|
||||
return v
|
||||
elif v == "dynpm":
|
||||
if not sim:
|
||||
if (self._cmd.write_to_file(sys_files["method"], "dynpm")):
|
||||
return "dynpm"
|
||||
if (self._cmd.write_to_file(sys_files["method"], "dynpm", \
|
||||
no_error = [errno.ENOENT] if remove else False)):
|
||||
return "dynpm"
|
||||
# new DPM profiles, recommended to use if supported
|
||||
elif v in ["dpm-battery", "dpm-balanced", "dpm-performance"]:
|
||||
if not sim:
|
||||
state = v[len("dpm-"):]
|
||||
if (self._cmd.write_to_file(sys_files["method"], "dpm") and
|
||||
self._cmd.write_to_file(sys_files["dpm_state"], state)):
|
||||
return v
|
||||
if (self._cmd.write_to_file(sys_files["method"], "dpm", \
|
||||
no_error = [errno.ENOENT] if remove else False) and
|
||||
self._cmd.write_to_file(sys_files["dpm_state"], state, \
|
||||
no_error = [errno.ENOENT] if remove else False)):
|
||||
return v
|
||||
else:
|
||||
if not sim:
|
||||
log.warn("Invalid option for radeon_powersave.")
|
||||
|
|
|
|||
|
|
@ -3,6 +3,7 @@ from .decorators import *
|
|||
import tuned.logs
|
||||
|
||||
import os
|
||||
import errno
|
||||
import struct
|
||||
import glob
|
||||
from tuned.utils.commands import commands
|
||||
|
|
@ -57,7 +58,7 @@ class VMPlugin(base.Plugin):
|
|||
return path
|
||||
|
||||
@command_set("transparent_hugepages")
|
||||
def _set_transparent_hugepages(self, value, sim):
|
||||
def _set_transparent_hugepages(self, value, sim, remove):
|
||||
if value not in ["always", "never", "madvise"]:
|
||||
if not sim:
|
||||
log.warn("Incorrect 'transparent_hugepages' value '%s'." % str(value))
|
||||
|
|
@ -72,7 +73,8 @@ class VMPlugin(base.Plugin):
|
|||
sys_file = os.path.join(self._thp_path(), "enabled")
|
||||
if os.path.exists(sys_file):
|
||||
if not sim:
|
||||
cmd.write_to_file(sys_file, value)
|
||||
cmd.write_to_file(sys_file, value, \
|
||||
no_error = [errno.ENOENT] if remove else False)
|
||||
return value
|
||||
else:
|
||||
if not sim:
|
||||
|
|
@ -81,8 +83,8 @@ class VMPlugin(base.Plugin):
|
|||
|
||||
# just an alias to transparent_hugepages
|
||||
@command_set("transparent_hugepage")
|
||||
def _set_transparent_hugepage(self, value, sim):
|
||||
self._set_transparent_hugepages(value, sim)
|
||||
def _set_transparent_hugepage(self, value, sim, remove):
|
||||
self._set_transparent_hugepages(value, sim, remove)
|
||||
|
||||
@command_get("transparent_hugepages")
|
||||
def _get_transparent_hugepages(self):
|
||||
|
|
@ -98,11 +100,12 @@ class VMPlugin(base.Plugin):
|
|||
return self._get_transparent_hugepages()
|
||||
|
||||
@command_set("transparent_hugepage.defrag")
|
||||
def _set_transparent_hugepage_defrag(self, value, sim):
|
||||
def _set_transparent_hugepage_defrag(self, value, sim, remove):
|
||||
sys_file = os.path.join(self._thp_path(), "defrag")
|
||||
if os.path.exists(sys_file):
|
||||
if not sim:
|
||||
cmd.write_to_file(sys_file, value)
|
||||
cmd.write_to_file(sys_file, value, \
|
||||
no_error = [errno.ENOENT] if remove else False)
|
||||
return value
|
||||
else:
|
||||
if not sim:
|
||||
|
|
|
|||
|
|
@ -91,6 +91,17 @@ class commands:
|
|||
return None
|
||||
|
||||
def write_to_file(self, f, data, makedir = False, no_error = False):
|
||||
"""Write data to a file.
|
||||
|
||||
Parameters:
|
||||
f -- filename where to write
|
||||
data -- data to write
|
||||
makedir -- if True and the path doesn't exist, it will be created
|
||||
no_error -- if True errors are silenced, it can be also list of ignored errnos
|
||||
|
||||
Return:
|
||||
bool -- True on success
|
||||
"""
|
||||
self._debug("Writing to file: '%s' < '%s'" % (f, data))
|
||||
if makedir:
|
||||
d = os.path.dirname(f)
|
||||
|
|
@ -103,10 +114,11 @@ class commands:
|
|||
fd.write(str(data))
|
||||
fd.close()
|
||||
rc = True
|
||||
except (OSError,IOError) as e:
|
||||
except (OSError, IOError) as e:
|
||||
rc = False
|
||||
if not no_error:
|
||||
self._error("Writing to file '%s' error: '%s'" % (f, e))
|
||||
if isinstance(no_error, bool) and not no_error or \
|
||||
isinstance(no_error, list) and e.errno not in no_error:
|
||||
self._error("Writing to file '%s' error: '%s'" % (f, e))
|
||||
return rc
|
||||
|
||||
def read_file(self, f, err_ret = "", no_error = False):
|
||||
|
|
|
|||
Loading…
Reference in a new issue