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'}
|
return {'size':'S','device_setting':'101'}
|
||||||
|
|
||||||
@decorators.command_set('size')
|
@decorators.command_set('size')
|
||||||
def _set_size(self, new_size, sim):
|
def _set_size(self, new_size, sim, remove):
|
||||||
self._size = new_size
|
self._size = new_size
|
||||||
return new_size
|
return new_size
|
||||||
|
|
||||||
|
|
@ -220,7 +220,7 @@ class CommandsPlugin(Plugin):
|
||||||
return self._size
|
return self._size
|
||||||
|
|
||||||
@decorators.command_set('device_setting',per_device = True)
|
@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
|
device.setting = value
|
||||||
return device.setting
|
return device.setting
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -506,7 +506,7 @@ class Plugin(object):
|
||||||
else:
|
else:
|
||||||
new_value = self._check_and_save_value(instance, command, device, new_value)
|
new_value = self._check_and_save_value(instance, command, device, new_value)
|
||||||
if new_value is not None:
|
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):
|
def _execute_non_device_command(self, instance, command, new_value):
|
||||||
if command["custom"] is not None:
|
if command["custom"] is not None:
|
||||||
|
|
@ -514,7 +514,7 @@ class Plugin(object):
|
||||||
else:
|
else:
|
||||||
new_value = self._check_and_save_value(instance, command, None, new_value)
|
new_value = self._check_and_save_value(instance, command, None, new_value)
|
||||||
if new_value is not None:
|
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):
|
def _norm_value(self, value):
|
||||||
v = self._cmd.unquote(str(value))
|
v = self._cmd.unquote(str(value))
|
||||||
|
|
@ -576,7 +576,7 @@ class Plugin(object):
|
||||||
new_value = self._process_assignment_modifiers(new_value, current_value)
|
new_value = self._process_assignment_modifiers(new_value, current_value)
|
||||||
if new_value is None:
|
if new_value is None:
|
||||||
return 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)
|
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):
|
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)
|
new_value = self._process_assignment_modifiers(new_value, current_value)
|
||||||
if new_value is None:
|
if new_value is None:
|
||||||
return 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)
|
return self._verify_value(command["name"], new_value, current_value, ignore_missing)
|
||||||
|
|
||||||
def _cleanup_all_non_device_commands(self, instance):
|
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):
|
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)
|
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"]]):
|
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):
|
if (instance.options.get(command["name"], None) is not None) or (command["name"] in self._options_used_by_dynamic):
|
||||||
for device in devices:
|
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:
|
if command["custom"] is not None:
|
||||||
command["custom"](False, None, device, False, False)
|
command["custom"](False, None, device, False, False)
|
||||||
else:
|
else:
|
||||||
old_value = self._storage_get(instance, command, device)
|
old_value = self._storage_get(instance, command, device)
|
||||||
if old_value is not None:
|
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)
|
self._storage_unset(instance, command, device)
|
||||||
|
|
||||||
def _cleanup_non_device_command(self, instance, command):
|
def _cleanup_non_device_command(self, instance, command):
|
||||||
|
|
@ -615,5 +615,5 @@ class Plugin(object):
|
||||||
else:
|
else:
|
||||||
old_value = self._storage_get(instance, command)
|
old_value = self._storage_get(instance, command)
|
||||||
if old_value is not None:
|
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)
|
self._storage_unset(instance, command)
|
||||||
|
|
|
||||||
|
|
@ -109,4 +109,4 @@ class Plugin(base.Plugin):
|
||||||
def _removed_device_unapply_tuning(self, instance, device_name):
|
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):
|
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._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
|
from tuned.utils.commands import commands
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import errno
|
||||||
import struct
|
import struct
|
||||||
import glob
|
import glob
|
||||||
|
|
||||||
|
|
@ -73,7 +74,7 @@ class AudioPlugin(hotplug.Plugin):
|
||||||
return "/sys/module/%s/parameters/power_save_controller" % device
|
return "/sys/module/%s/parameters/power_save_controller" % device
|
||||||
|
|
||||||
@command_set("timeout", per_device = True)
|
@command_set("timeout", per_device = True)
|
||||||
def _set_timeout(self, value, device, sim):
|
def _set_timeout(self, value, device, sim, remove):
|
||||||
try:
|
try:
|
||||||
timeout = int(value)
|
timeout = int(value)
|
||||||
except ValueError:
|
except ValueError:
|
||||||
|
|
@ -82,7 +83,8 @@ class AudioPlugin(hotplug.Plugin):
|
||||||
if timeout >= 0:
|
if timeout >= 0:
|
||||||
sys_file = self._timeout_path(device)
|
sys_file = self._timeout_path(device)
|
||||||
if not sim:
|
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
|
return timeout
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
@ -96,12 +98,13 @@ class AudioPlugin(hotplug.Plugin):
|
||||||
return None
|
return None
|
||||||
|
|
||||||
@command_set("reset_controller", per_device = True)
|
@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)
|
v = cmd.get_bool(value)
|
||||||
sys_file = self._reset_controller_path(device)
|
sys_file = self._reset_controller_path(device)
|
||||||
if os.path.exists(sys_file):
|
if os.path.exists(sys_file):
|
||||||
if not sim:
|
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 v
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ from tuned.utils.commands import commands
|
||||||
import tuned.consts as consts
|
import tuned.consts as consts
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import errno
|
||||||
import struct
|
import struct
|
||||||
import errno
|
import errno
|
||||||
import platform
|
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()
|
return self._cmd.read_file("/sys/devices/system/cpu/%s/cpufreq/scaling_available_governors" % device).strip().split()
|
||||||
|
|
||||||
@command_set("governor", per_device=True)
|
@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):
|
if not self._check_cpu_can_change_governor(device):
|
||||||
return None
|
return None
|
||||||
governors = str(governors)
|
governors = str(governors)
|
||||||
|
|
@ -517,7 +518,7 @@ class CPULatencyPlugin(hotplug.Plugin):
|
||||||
log.info("setting governor '%s' on cpu '%s'"
|
log.info("setting governor '%s' on cpu '%s'"
|
||||||
% (governor, device))
|
% (governor, device))
|
||||||
self._cmd.write_to_file("/sys/devices/system/cpu/%s/cpufreq/scaling_governor"
|
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
|
break
|
||||||
elif not sim:
|
elif not sim:
|
||||||
log.debug("Ignoring governor '%s' on cpu '%s', it is not supported"
|
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
|
return "/sys/devices/system/cpu/cpufreq/%s/sampling_down_factor" % governor
|
||||||
|
|
||||||
@command_set("sampling_down_factor", per_device = True, priority = 10)
|
@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
|
val = None
|
||||||
|
|
||||||
# hack to clear governors map when the profile starts unloading
|
# hack to clear governors map when the profile starts unloading
|
||||||
|
|
@ -569,7 +570,7 @@ class CPULatencyPlugin(hotplug.Plugin):
|
||||||
val = str(sampling_down_factor)
|
val = str(sampling_down_factor)
|
||||||
if not sim:
|
if not sim:
|
||||||
log.info("setting sampling_down_factor to '%s' for governor '%s'" % (val, governor))
|
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
|
return val
|
||||||
|
|
||||||
@command_get("sampling_down_factor")
|
@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
|
return "/sys/devices/system/cpu/cpu%s/power/energy_perf_bias" % cpu_id
|
||||||
|
|
||||||
@command_set("energy_perf_bias", per_device=True)
|
@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):
|
if not self._is_cpu_online(device):
|
||||||
log.debug("%s is not online, skipping" % device)
|
log.debug("%s is not online, skipping" % device)
|
||||||
return None
|
return None
|
||||||
|
|
@ -613,10 +614,11 @@ class CPULatencyPlugin(hotplug.Plugin):
|
||||||
if not sim:
|
if not sim:
|
||||||
for val in vals:
|
for val in vals:
|
||||||
val = val.strip()
|
val = val.strip()
|
||||||
if self._cmd.write_to_file(energy_perf_bias_path, val):
|
if self._cmd.write_to_file(energy_perf_bias_path, val, \
|
||||||
log.info("energy_perf_bias successfully set to '%s' on cpu '%s'"
|
no_error = [errno.ENOENT] if remove else False):
|
||||||
% (val, device))
|
log.info("energy_perf_bias successfully set to '%s' on cpu '%s'"
|
||||||
break
|
% (val, device))
|
||||||
|
break
|
||||||
else:
|
else:
|
||||||
log.error("Failed to set energy_perf_bias on cpu '%s'. Is the value in the profile correct?"
|
log.error("Failed to set energy_perf_bias on cpu '%s'. Is the value in the profile correct?"
|
||||||
% device)
|
% device)
|
||||||
|
|
@ -711,7 +713,7 @@ class CPULatencyPlugin(hotplug.Plugin):
|
||||||
return self._has_pm_qos_resume_latency_us
|
return self._has_pm_qos_resume_latency_us
|
||||||
|
|
||||||
@command_set("pm_qos_resume_latency_us", per_device=True)
|
@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):
|
if not self._is_cpu_online(device):
|
||||||
log.debug("%s is not online, skipping" % device)
|
log.debug("%s is not online, skipping" % device)
|
||||||
return None
|
return None
|
||||||
|
|
@ -729,7 +731,8 @@ class CPULatencyPlugin(hotplug.Plugin):
|
||||||
if not self._check_pm_qos_resume_latency_us(device):
|
if not self._check_pm_qos_resume_latency_us(device):
|
||||||
return None
|
return None
|
||||||
if not sim:
|
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
|
return latency
|
||||||
|
|
||||||
@command_get("pm_qos_resume_latency_us")
|
@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()
|
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)
|
@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):
|
if not self._is_cpu_online(device):
|
||||||
log.debug("%s is not online, skipping" % device)
|
log.debug("%s is not online, skipping" % device)
|
||||||
return None
|
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())
|
avail_vals = set(self._cmd.read_file(self._pstate_preference_path(cpu_id, True)).split())
|
||||||
for val in vals:
|
for val in vals:
|
||||||
if val in avail_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))
|
log.info("Setting energy_performance_preference value '%s' for cpu '%s'" % (val, device))
|
||||||
break
|
break
|
||||||
else:
|
else:
|
||||||
|
|
|
||||||
|
|
@ -335,10 +335,11 @@ class DiskPlugin(hotplug.Plugin):
|
||||||
return self._sysfs_path(device, "queue/scheduler")
|
return self._sysfs_path(device, "queue/scheduler")
|
||||||
|
|
||||||
@command_set("elevator", per_device=True)
|
@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)
|
sys_file = self._elevator_file(device)
|
||||||
if not sim:
|
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
|
return value
|
||||||
|
|
||||||
@command_get("elevator")
|
@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))
|
return self._cmd.get_active_option(self._cmd.read_file(sys_file, no_error=ignore_missing))
|
||||||
|
|
||||||
@command_set("apm", per_device=True)
|
@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 device not in self._hdparm_apm_devices:
|
||||||
if not sim:
|
if not sim:
|
||||||
log.info("apm option is not supported for device '%s'" % device)
|
log.info("apm option is not supported for device '%s'" % device)
|
||||||
|
|
@ -389,7 +390,7 @@ class DiskPlugin(hotplug.Plugin):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@command_set("spindown", per_device=True)
|
@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 device not in self._hdparm_apm_devices:
|
||||||
if not sim:
|
if not sim:
|
||||||
log.info("spindown option is not supported for device '%s'" % device)
|
log.info("spindown option is not supported for device '%s'" % device)
|
||||||
|
|
@ -428,14 +429,15 @@ class DiskPlugin(hotplug.Plugin):
|
||||||
return v
|
return v
|
||||||
|
|
||||||
@command_set("readahead", per_device=True)
|
@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)
|
sys_file = self._readahead_file(device)
|
||||||
val = self._parse_ra(value)
|
val = self._parse_ra(value)
|
||||||
if val is None:
|
if val is None:
|
||||||
log.error("Invalid readahead value '%s' for device '%s'" % (value, device))
|
log.error("Invalid readahead value '%s' for device '%s'" % (value, device))
|
||||||
else:
|
else:
|
||||||
if not sim:
|
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
|
return val
|
||||||
|
|
||||||
@command_get("readahead")
|
@command_get("readahead")
|
||||||
|
|
@ -471,10 +473,11 @@ class DiskPlugin(hotplug.Plugin):
|
||||||
return self._sysfs_path(device, "queue/iosched/quantum")
|
return self._sysfs_path(device, "queue/iosched/quantum")
|
||||||
|
|
||||||
@command_set("scheduler_quantum", per_device=True)
|
@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)
|
sys_file = self._scheduler_quantum_file(device)
|
||||||
if not sim:
|
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
|
return value
|
||||||
|
|
||||||
@command_get("scheduler_quantum")
|
@command_get("scheduler_quantum")
|
||||||
|
|
|
||||||
|
|
@ -380,7 +380,7 @@ class NetTuningPlugin(hotplug.Plugin):
|
||||||
return "/sys/module/nf_conntrack/parameters/hashsize"
|
return "/sys/module/nf_conntrack/parameters/hashsize"
|
||||||
|
|
||||||
@command_set("wake_on_lan", per_device=True)
|
@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:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
|
|
@ -406,14 +406,15 @@ class NetTuningPlugin(hotplug.Plugin):
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@command_set("nf_conntrack_hashsize")
|
@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:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
hashsize = int(value)
|
hashsize = int(value)
|
||||||
if hashsize >= 0:
|
if hashsize >= 0:
|
||||||
if not sim:
|
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
|
return hashsize
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
@ -447,7 +448,7 @@ class NetTuningPlugin(hotplug.Plugin):
|
||||||
return self._call_ip_link(args)
|
return self._call_ip_link(args)
|
||||||
|
|
||||||
@command_set("txqueuelen", per_device=True)
|
@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:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
try:
|
try:
|
||||||
|
|
@ -487,7 +488,7 @@ class NetTuningPlugin(hotplug.Plugin):
|
||||||
return res.group(1)
|
return res.group(1)
|
||||||
|
|
||||||
@command_set("mtu", per_device=True)
|
@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:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
try:
|
try:
|
||||||
|
|
|
||||||
|
|
@ -1414,12 +1414,13 @@ class SchedulerPlugin(base.Plugin):
|
||||||
self._secure_boot_hint = False
|
self._secure_boot_hint = False
|
||||||
return data
|
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:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
if not sim:
|
if not sim:
|
||||||
if not self._cmd.write_to_file(self._get_sched_knob_path(prefix, namespace, knob), value):
|
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))
|
no_error = [errno.ENOENT] if remove else False):
|
||||||
|
log.error("Error writing value '%s' to '%s'" % (value, knob))
|
||||||
return value
|
return value
|
||||||
|
|
||||||
@command_get("sched_min_granularity_ns")
|
@command_get("sched_min_granularity_ns")
|
||||||
|
|
@ -1427,77 +1428,77 @@ class SchedulerPlugin(base.Plugin):
|
||||||
return self._get_sched_knob("", "sched", "min_granularity_ns")
|
return self._get_sched_knob("", "sched", "min_granularity_ns")
|
||||||
|
|
||||||
@command_set("sched_min_granularity_ns")
|
@command_set("sched_min_granularity_ns")
|
||||||
def _set_sched_min_granularity_ns(self, value, sim):
|
def _set_sched_min_granularity_ns(self, value, sim, remove):
|
||||||
return self._set_sched_knob("", "sched", "min_granularity_ns", value, sim)
|
return self._set_sched_knob("", "sched", "min_granularity_ns", value, sim, remove)
|
||||||
|
|
||||||
@command_get("sched_latency_ns")
|
@command_get("sched_latency_ns")
|
||||||
def _get_sched_latency_ns(self):
|
def _get_sched_latency_ns(self):
|
||||||
return self._get_sched_knob("", "sched", "latency_ns")
|
return self._get_sched_knob("", "sched", "latency_ns")
|
||||||
|
|
||||||
@command_set("sched_latency_ns")
|
@command_set("sched_latency_ns")
|
||||||
def _set_sched_latency_ns(self, value, sim):
|
def _set_sched_latency_ns(self, value, sim, remove):
|
||||||
return self._set_sched_knob("", "sched", "latency_ns", value, sim)
|
return self._set_sched_knob("", "sched", "latency_ns", value, sim, remove)
|
||||||
|
|
||||||
@command_get("sched_wakeup_granularity_ns")
|
@command_get("sched_wakeup_granularity_ns")
|
||||||
def _get_sched_wakeup_granularity_ns(self):
|
def _get_sched_wakeup_granularity_ns(self):
|
||||||
return self._get_sched_knob("", "sched", "wakeup_granularity_ns")
|
return self._get_sched_knob("", "sched", "wakeup_granularity_ns")
|
||||||
|
|
||||||
@command_set("sched_wakeup_granularity_ns")
|
@command_set("sched_wakeup_granularity_ns")
|
||||||
def _set_sched_wakeup_granularity_ns(self, value, sim):
|
def _set_sched_wakeup_granularity_ns(self, value, sim, remove):
|
||||||
return self._set_sched_knob("", "sched", "wakeup_granularity_ns", value, sim)
|
return self._set_sched_knob("", "sched", "wakeup_granularity_ns", value, sim, remove)
|
||||||
|
|
||||||
@command_get("sched_tunable_scaling")
|
@command_get("sched_tunable_scaling")
|
||||||
def _get_sched_tunable_scaling(self):
|
def _get_sched_tunable_scaling(self):
|
||||||
return self._get_sched_knob("", "sched", "tunable_scaling")
|
return self._get_sched_knob("", "sched", "tunable_scaling")
|
||||||
|
|
||||||
@command_set("sched_tunable_scaling")
|
@command_set("sched_tunable_scaling")
|
||||||
def _set_sched_tunable_scaling(self, value, sim):
|
def _set_sched_tunable_scaling(self, value, sim, remove):
|
||||||
return self._set_sched_knob("", "sched", "tunable_scaling", value, sim)
|
return self._set_sched_knob("", "sched", "tunable_scaling", value, sim, remove)
|
||||||
|
|
||||||
@command_get("sched_migration_cost_ns")
|
@command_get("sched_migration_cost_ns")
|
||||||
def _get_sched_migration_cost_ns(self):
|
def _get_sched_migration_cost_ns(self):
|
||||||
return self._get_sched_knob("", "sched", "migration_cost_ns")
|
return self._get_sched_knob("", "sched", "migration_cost_ns")
|
||||||
|
|
||||||
@command_set("sched_migration_cost_ns")
|
@command_set("sched_migration_cost_ns")
|
||||||
def _set_sched_migration_cost_ns(self, value, sim):
|
def _set_sched_migration_cost_ns(self, value, sim, remove):
|
||||||
return self._set_sched_knob("", "sched", "migration_cost_ns", value, sim)
|
return self._set_sched_knob("", "sched", "migration_cost_ns", value, sim, remove)
|
||||||
|
|
||||||
@command_get("sched_nr_migrate")
|
@command_get("sched_nr_migrate")
|
||||||
def _get_sched_nr_migrate(self):
|
def _get_sched_nr_migrate(self):
|
||||||
return self._get_sched_knob("", "sched", "nr_migrate")
|
return self._get_sched_knob("", "sched", "nr_migrate")
|
||||||
|
|
||||||
@command_set("sched_nr_migrate")
|
@command_set("sched_nr_migrate")
|
||||||
def _set_sched_nr_migrate(self, value, sim):
|
def _set_sched_nr_migrate(self, value, sim, remove):
|
||||||
return self._set_sched_knob("", "sched", "nr_migrate", value, sim)
|
return self._set_sched_knob("", "sched", "nr_migrate", value, sim, remove)
|
||||||
|
|
||||||
@command_get("numa_balancing_scan_delay_ms")
|
@command_get("numa_balancing_scan_delay_ms")
|
||||||
def _get_numa_balancing_scan_delay_ms(self):
|
def _get_numa_balancing_scan_delay_ms(self):
|
||||||
return self._get_sched_knob("sched", "numa_balancing", "scan_delay_ms")
|
return self._get_sched_knob("sched", "numa_balancing", "scan_delay_ms")
|
||||||
|
|
||||||
@command_set("numa_balancing_scan_delay_ms")
|
@command_set("numa_balancing_scan_delay_ms")
|
||||||
def _set_numa_balancing_scan_delay_ms(self, 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)
|
return self._set_sched_knob("sched", "numa_balancing", "scan_delay_ms", value, sim, remove)
|
||||||
|
|
||||||
@command_get("numa_balancing_scan_period_min_ms")
|
@command_get("numa_balancing_scan_period_min_ms")
|
||||||
def _get_numa_balancing_scan_period_min_ms(self):
|
def _get_numa_balancing_scan_period_min_ms(self):
|
||||||
return self._get_sched_knob("sched", "numa_balancing", "scan_period_min_ms")
|
return self._get_sched_knob("sched", "numa_balancing", "scan_period_min_ms")
|
||||||
|
|
||||||
@command_set("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):
|
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)
|
return self._set_sched_knob("sched", "numa_balancing", "scan_period_min_ms", value, sim, remove)
|
||||||
|
|
||||||
@command_get("numa_balancing_scan_period_max_ms")
|
@command_get("numa_balancing_scan_period_max_ms")
|
||||||
def _get_numa_balancing_scan_period_max_ms(self):
|
def _get_numa_balancing_scan_period_max_ms(self):
|
||||||
return self._get_sched_knob("sched", "numa_balancing", "scan_period_max_ms")
|
return self._get_sched_knob("sched", "numa_balancing", "scan_period_max_ms")
|
||||||
|
|
||||||
@command_set("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):
|
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)
|
return self._set_sched_knob("sched", "numa_balancing", "scan_period_max_ms", value, sim, remove)
|
||||||
|
|
||||||
@command_get("numa_balancing_scan_size_mb")
|
@command_get("numa_balancing_scan_size_mb")
|
||||||
def _get_numa_balancing_scan_size_mb(self):
|
def _get_numa_balancing_scan_size_mb(self):
|
||||||
return self._get_sched_knob("sched", "numa_balancing", "scan_size_mb")
|
return self._get_sched_knob("sched", "numa_balancing", "scan_size_mb")
|
||||||
|
|
||||||
@command_set("numa_balancing_scan_size_mb")
|
@command_set("numa_balancing_scan_size_mb")
|
||||||
def _set_numa_balancing_scan_size_mb(self, 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)
|
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")
|
return os.path.join("/sys/class/scsi_host/", str(device), "link_power_management_policy")
|
||||||
|
|
||||||
@command_set("alpm", per_device = True)
|
@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:
|
if policy is None:
|
||||||
return None
|
return None
|
||||||
policy_file = self._get_alpm_policy_file(device)
|
policy_file = self._get_alpm_policy_file(device)
|
||||||
if not sim:
|
if not sim:
|
||||||
if os.path.exists(policy_file):
|
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:
|
else:
|
||||||
log.info("ALPM control file ('%s') not found, skipping ALPM setting for '%s'" % (policy_file, str(device)))
|
log.info("ALPM control file ('%s') not found, skipping ALPM setting for '%s'" % (policy_file, str(device)))
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
|
|
@ -1,4 +1,5 @@
|
||||||
import os
|
import os
|
||||||
|
import errno
|
||||||
from . import base
|
from . import base
|
||||||
from .decorators import *
|
from .decorators import *
|
||||||
import tuned.logs
|
import tuned.logs
|
||||||
|
|
@ -63,13 +64,14 @@ class SelinuxPlugin(base.Plugin):
|
||||||
pass
|
pass
|
||||||
|
|
||||||
@command_set("avc_cache_threshold")
|
@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:
|
if value is None:
|
||||||
return None
|
return None
|
||||||
threshold = int(value)
|
threshold = int(value)
|
||||||
if threshold >= 0:
|
if threshold >= 0:
|
||||||
if not sim:
|
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
|
return threshold
|
||||||
else:
|
else:
|
||||||
return None
|
return None
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from .decorators import *
|
||||||
import tuned.logs
|
import tuned.logs
|
||||||
from tuned.utils.commands import commands
|
from tuned.utils.commands import commands
|
||||||
import glob
|
import glob
|
||||||
|
import errno
|
||||||
|
|
||||||
log = tuned.logs.get()
|
log = tuned.logs.get()
|
||||||
|
|
||||||
|
|
@ -57,7 +58,7 @@ class USBPlugin(base.Plugin):
|
||||||
return "/sys/bus/usb/devices/%s/power/autosuspend" % device
|
return "/sys/bus/usb/devices/%s/power/autosuspend" % device
|
||||||
|
|
||||||
@command_set("autosuspend", per_device=True)
|
@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)
|
enable = self._option_bool(value)
|
||||||
if enable is None:
|
if enable is None:
|
||||||
return None
|
return None
|
||||||
|
|
@ -65,7 +66,8 @@ class USBPlugin(base.Plugin):
|
||||||
val = "1" if enable else "0"
|
val = "1" if enable else "0"
|
||||||
if not sim:
|
if not sim:
|
||||||
sys_file = self._autosuspend_sysfile(device)
|
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
|
return val
|
||||||
|
|
||||||
@command_get("autosuspend")
|
@command_get("autosuspend")
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from .decorators import *
|
||||||
import tuned.logs
|
import tuned.logs
|
||||||
from tuned.utils.commands import commands
|
from tuned.utils.commands import commands
|
||||||
import os
|
import os
|
||||||
|
import errno
|
||||||
import re
|
import re
|
||||||
|
|
||||||
log = tuned.logs.get()
|
log = tuned.logs.get()
|
||||||
|
|
@ -76,7 +77,7 @@ class VideoPlugin(base.Plugin):
|
||||||
}
|
}
|
||||||
|
|
||||||
@command_set("radeon_powersave", per_device=True)
|
@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)
|
sys_files = self._radeon_powersave_files(device)
|
||||||
va = str(re.sub(r"(\s*:\s*)|(\s+)|(\s*;\s*)|(\s*,\s*)", " ", value)).split()
|
va = str(re.sub(r"(\s*:\s*)|(\s+)|(\s*;\s*)|(\s*,\s*)", " ", value)).split()
|
||||||
if not os.path.exists(sys_files["method"]):
|
if not os.path.exists(sys_files["method"]):
|
||||||
|
|
@ -86,20 +87,25 @@ class VideoPlugin(base.Plugin):
|
||||||
for v in va:
|
for v in va:
|
||||||
if v in ["default", "auto", "low", "mid", "high"]:
|
if v in ["default", "auto", "low", "mid", "high"]:
|
||||||
if not sim:
|
if not sim:
|
||||||
if (self._cmd.write_to_file(sys_files["method"], "profile") and
|
if (self._cmd.write_to_file(sys_files["method"], "profile", \
|
||||||
self._cmd.write_to_file(sys_files["profile"], v)):
|
no_error = [errno.ENOENT] if remove else False) and
|
||||||
return v
|
self._cmd.write_to_file(sys_files["profile"], v, \
|
||||||
|
no_error = [errno.ENOENT] if remove else False)):
|
||||||
|
return v
|
||||||
elif v == "dynpm":
|
elif v == "dynpm":
|
||||||
if not sim:
|
if not sim:
|
||||||
if (self._cmd.write_to_file(sys_files["method"], "dynpm")):
|
if (self._cmd.write_to_file(sys_files["method"], "dynpm", \
|
||||||
return "dynpm"
|
no_error = [errno.ENOENT] if remove else False)):
|
||||||
|
return "dynpm"
|
||||||
# new DPM profiles, recommended to use if supported
|
# new DPM profiles, recommended to use if supported
|
||||||
elif v in ["dpm-battery", "dpm-balanced", "dpm-performance"]:
|
elif v in ["dpm-battery", "dpm-balanced", "dpm-performance"]:
|
||||||
if not sim:
|
if not sim:
|
||||||
state = v[len("dpm-"):]
|
state = v[len("dpm-"):]
|
||||||
if (self._cmd.write_to_file(sys_files["method"], "dpm") and
|
if (self._cmd.write_to_file(sys_files["method"], "dpm", \
|
||||||
self._cmd.write_to_file(sys_files["dpm_state"], state)):
|
no_error = [errno.ENOENT] if remove else False) and
|
||||||
return v
|
self._cmd.write_to_file(sys_files["dpm_state"], state, \
|
||||||
|
no_error = [errno.ENOENT] if remove else False)):
|
||||||
|
return v
|
||||||
else:
|
else:
|
||||||
if not sim:
|
if not sim:
|
||||||
log.warn("Invalid option for radeon_powersave.")
|
log.warn("Invalid option for radeon_powersave.")
|
||||||
|
|
|
||||||
|
|
@ -3,6 +3,7 @@ from .decorators import *
|
||||||
import tuned.logs
|
import tuned.logs
|
||||||
|
|
||||||
import os
|
import os
|
||||||
|
import errno
|
||||||
import struct
|
import struct
|
||||||
import glob
|
import glob
|
||||||
from tuned.utils.commands import commands
|
from tuned.utils.commands import commands
|
||||||
|
|
@ -57,7 +58,7 @@ class VMPlugin(base.Plugin):
|
||||||
return path
|
return path
|
||||||
|
|
||||||
@command_set("transparent_hugepages")
|
@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 value not in ["always", "never", "madvise"]:
|
||||||
if not sim:
|
if not sim:
|
||||||
log.warn("Incorrect 'transparent_hugepages' value '%s'." % str(value))
|
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")
|
sys_file = os.path.join(self._thp_path(), "enabled")
|
||||||
if os.path.exists(sys_file):
|
if os.path.exists(sys_file):
|
||||||
if not sim:
|
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
|
return value
|
||||||
else:
|
else:
|
||||||
if not sim:
|
if not sim:
|
||||||
|
|
@ -81,8 +83,8 @@ class VMPlugin(base.Plugin):
|
||||||
|
|
||||||
# just an alias to transparent_hugepages
|
# just an alias to transparent_hugepages
|
||||||
@command_set("transparent_hugepage")
|
@command_set("transparent_hugepage")
|
||||||
def _set_transparent_hugepage(self, value, sim):
|
def _set_transparent_hugepage(self, value, sim, remove):
|
||||||
self._set_transparent_hugepages(value, sim)
|
self._set_transparent_hugepages(value, sim, remove)
|
||||||
|
|
||||||
@command_get("transparent_hugepages")
|
@command_get("transparent_hugepages")
|
||||||
def _get_transparent_hugepages(self):
|
def _get_transparent_hugepages(self):
|
||||||
|
|
@ -98,11 +100,12 @@ class VMPlugin(base.Plugin):
|
||||||
return self._get_transparent_hugepages()
|
return self._get_transparent_hugepages()
|
||||||
|
|
||||||
@command_set("transparent_hugepage.defrag")
|
@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")
|
sys_file = os.path.join(self._thp_path(), "defrag")
|
||||||
if os.path.exists(sys_file):
|
if os.path.exists(sys_file):
|
||||||
if not sim:
|
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
|
return value
|
||||||
else:
|
else:
|
||||||
if not sim:
|
if not sim:
|
||||||
|
|
|
||||||
|
|
@ -91,6 +91,17 @@ class commands:
|
||||||
return None
|
return None
|
||||||
|
|
||||||
def write_to_file(self, f, data, makedir = False, no_error = False):
|
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))
|
self._debug("Writing to file: '%s' < '%s'" % (f, data))
|
||||||
if makedir:
|
if makedir:
|
||||||
d = os.path.dirname(f)
|
d = os.path.dirname(f)
|
||||||
|
|
@ -103,10 +114,11 @@ class commands:
|
||||||
fd.write(str(data))
|
fd.write(str(data))
|
||||||
fd.close()
|
fd.close()
|
||||||
rc = True
|
rc = True
|
||||||
except (OSError,IOError) as e:
|
except (OSError, IOError) as e:
|
||||||
rc = False
|
rc = False
|
||||||
if not no_error:
|
if isinstance(no_error, bool) and not no_error or \
|
||||||
self._error("Writing to file '%s' error: '%s'" % (f, e))
|
isinstance(no_error, list) and e.errno not in no_error:
|
||||||
|
self._error("Writing to file '%s' error: '%s'" % (f, e))
|
||||||
return rc
|
return rc
|
||||||
|
|
||||||
def read_file(self, f, err_ret = "", no_error = False):
|
def read_file(self, f, err_ret = "", no_error = False):
|
||||||
|
|
|
||||||
Loading…
Reference in a new issue