1
0
Fork 0

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:
Jaroslav Škarvada 2023-12-06 22:33:39 +01:00
parent 2652d7c29d
commit 2f911b7e02
No known key found for this signature in database
GPG key ID: D8E1C00E076E840B
14 changed files with 127 additions and 89 deletions

View file

@ -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

View file

@ -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)

View file

@ -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)

View file

@ -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

View file

@ -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:

View file

@ -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")

View file

@ -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:

View file

@ -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)

View file

@ -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

View file

@ -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

View file

@ -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")

View file

@ -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.")

View file

@ -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:

View file

@ -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):