1
0
Fork 0
tuned/profiles/functions
Jaroslav Škarvada d4038a7e64 plugin_script: added support for verify
Added 'verify' shell function to the 'functions' API. This
function is optional, if defined in the script, it is called
during the verification. It's return code is checked. Function
return code '0' means verification passed, other value means
failure.

Signed-off-by: Jaroslav Škarvada <jskarvad@redhat.com>
2015-05-19 15:51:04 +02:00

523 lines
12 KiB
Text

#
# This is library of helper functions that can be used in scripts in tuned profiles.
#
# API provided by this library is under heavy development and could be changed anytime
#
#
# Config
#
STORAGE=/run/tuned
STORAGE_SUFFIX=".save"
#
# Helpers
#
# Save value
# $0 STORAGE_NAME VALUE
save_value() {
[ "$#" -ne 2 ] && return
[ "$2" -a -e "${STORAGE}" ] && echo "$2" > "${STORAGE}/${1}${STORAGE_SUFFIX}"
}
# Save sysfs value
# $0 STORAGE_NAME SYSFS_NAME
save_sys() {
[ "$#" -ne 2 ] && return
[ -r "$2" -a ! -e "${STORAGE}/${1}${STORAGE_SUFFIX}" ] && cat "$2" > "${STORAGE}/${1}${STORAGE_SUFFIX}"
}
# Set sysfs value
# $0 SYSFS_NAME VALUE
set_sys() {
[ "$#" -ne 2 ] && return
[ -w "$1" ] && echo "$2" > "$1"
}
# Save and set sysfs value
# $0 STORAGE_NAME SYSFS_NAME VALUE
save_set_sys() {
[ "$#" -ne 3 ] && return
save_sys "$1" "$2"
set_sys "$2" "$3"
}
# Get stored sysfs value from storage
# $0 STORAGE_NAME
get_stored_sys() {
[ "$#" -ne 1 ] && return
[ -r "${STORAGE}/${1}${STORAGE_SUFFIX}" ] && cat "${STORAGE}/${1}${STORAGE_SUFFIX}"
}
# Restore value from storage
# $0 STORAGE_NAME
restore_value() {
[ "$#" -ne 1 ] && return
_rs_value="`get_stored_sys \"$1\"`"
unlink "${STORAGE}/${1}${STORAGE_SUFFIX}" >/dev/null 2>&1
[ "$_rs_value" ] && echo "$_rs_value"
}
# Restore sysfs value from storage, if nothing is stored, use VALUE
# $0 STORAGE_NAME SYSFS_NAME [VALUE]
restore_sys() {
[ "$#" -lt 2 -o "$#" -gt 3 ] && return
_rs_value="`get_stored_sys \"$1\"`"
unlink "${STORAGE}/${1}${STORAGE_SUFFIX}" >/dev/null 2>&1
[ "$_rs_value" ] || _rs_value="$3"
[ "$_rs_value" ] && set_sys "$2" "$_rs_value"
}
#
# DISK tuning
#
DISKS_DEV="$(command ls -d1 /dev/[shv]d*[a-z] 2>/dev/null)"
DISKS_SYS="$(command ls -d1 /sys/block/{sd,cciss,dm-,vd,dasd,xvd}* 2>/dev/null)"
_check_elevator_override()
{
/bin/fgrep -q 'elevator=' /proc/cmdline
}
# $0 OPERATOR DEVICES ELEVATOR
_set_elevator_helper() {
_check_elevator_override && return
SYS_BLOCK_SDX=""
[ "$2" ] && SYS_BLOCK_SDX=$(eval LANG=C /bin/ls -1 "${2}" 2>/dev/null)
# if there is no kernel command line elevator settings, apply the elevator
if [ "$1" -a "$SYS_BLOCK_SDX" ]; then
for i in $SYS_BLOCK_SDX; do
se_dev="`echo \"$i\" | sed 's|/sys/block/\([^/]\+\)/queue/scheduler|\1|'`"
$1 "elevator_${se_dev}" "$i" "$3"
done
fi
}
# $0 DEVICES ELEVATOR
set_elevator() {
_set_elevator_helper save_set_sys "$1" "$2"
}
# $0 DEVICES [ELEVATOR]
restore_elevator() {
re_elevator="$2"
[ "$re_elevator" ] || re_elevator = cfq
_set_elevator_helper restore_sys "$1" "$re_elevator"
}
# SATA Aggressive Link Power Management
# usage: set_disk_alpm policy
set_disk_alpm() {
policy=$1
for host in /sys/class/scsi_host/*; do
if [ -f $host/ahci_port_cmd ]; then
port_cmd=`cat $host/ahci_port_cmd`;
if [ $((0x$port_cmd & 0x240000)) = 0 -a -f $host/link_power_management_policy ]; then
echo $policy >$host/link_power_management_policy;
else
echo "max_performance" >$host/link_power_management_policy;
fi
fi
done
}
# usage: set_disk_apm level
set_disk_apm() {
level=$1
for disk in $DISKS_DEV; do
hdparm -B $level $disk &>/dev/null
done
}
# usage: set_disk_spindown level
set_disk_spindown() {
level=$1
for disk in $DISKS_DEV; do
hdparm -S $level $disk &>/dev/null
done
}
# usage: multiply_disk_readahead by
multiply_disk_readahead() {
by=$1
# float multiplication not supported in bash
# bc might not be installed, python is available for sure
for disk in $DISKS_SYS; do
control="${disk}/queue/read_ahead_kb"
old=$(cat $control)
new=$(echo "print int($old*$by)" | python)
(echo $new > $control) &>/dev/null
done
}
# usage: remount_disk options partition1 partition2 ...
remount_partitions() {
options=$1
shift
for partition in $@; do
mount -o remount,$options $partition >/dev/null 2>&1
done
}
remount_all_no_rootboot_partitions() {
[ "$1" ] || return
# Find non-root and non-boot partitions, disable barriers on them
rootvol=$(df -h / | grep "^/dev" | awk '{print $1}')
bootvol=$(df -h /boot | grep "^/dev" | awk '{print $1}')
volumes=$(df -hl --exclude=tmpfs | grep "^/dev" | awk '{print $1}')
nobarriervols=$(echo "$volumes" | grep -v $rootvol | grep -v $bootvol)
remount_partitions "$1" $nobarriervols
}
DISK_QUANTUM_SAVE="${STORAGE}/disk_quantum${STORAGE_SUFFIX}"
set_disk_scheduler_quantum() {
value=$1
rm -f "$DISK_QUANTUM_SAVE"
for disk in $DISKS_SYS; do
control="${disk}/queue/iosched/quantum"
echo "echo $(cat $control) > $control" >> "$DISK_QUANTUM_SAVE" 2>/dev/null
(echo $value > $control) &2>/dev/null
done
}
restore_disk_scheduler_quantum() {
if [ -r "$DISK_QUANTUM_SAVE" ]; then
/bin/sh "$DISK_QUANTUM_SAVE" &>/dev/null
rm -f "$DISK_QUANTUM_SAVE"
fi
}
#
# CPU tuning
#
CPUSPEED_SAVE_FILE="${STORAGE}/cpuspeed${STORAGE_SUFFIX}"
CPUSPEED_ORIG_GOV="${STORAGE}/cpuspeed-governor-%s${STORAGE_SUFFIX}"
CPUSPEED_STARTED="${STORAGE}/cpuspeed-started"
CPUSPEED_CFG="/etc/sysconfig/cpuspeed"
CPUSPEED_INIT="/etc/init.d/cpuspeed"
CPUS="$(ls -d1 /sys/devices/system/cpu/cpu* | sed 's;^.*/;;' | grep "cpu[0-9]\+")"
# set CPU governor setting and store the old settings
# usage: set_cpu_governor governor
set_cpu_governor() {
governor=$1
# prefer governor setting using cpuspeed daemon
if [ -e $CPUSPEED_INIT ]; then
if [ ! -e $CPUSPEED_SAVE_FILE -a -e $CPUSPEED_CFG ]; then
cp -p $CPUSPEED_CFG $CPUSPEED_SAVE_FILE
sed -e 's/^GOVERNOR=.*/GOVERNOR='$governor'/g' $CPUSPEED_SAVE_FILE > $CPUSPEED_CFG
fi
service cpuspeed status &> /dev/null
[ $? -eq 3 ] && touch $CPUSPEED_STARTED || rm -f $CPUSPEED_STARTED
service cpuspeed restart &> /dev/null
# direct change using /sys fs
elif [ -e /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ]; then
echo >&2
echo "Suggestion: install 'cpuspeed' package to get best tuning results." >&2
echo "Falling back to '$governor' scaling governor for all CPUs." >&2
echo >&2
for cpu in $CPUS; do
gov_file=/sys/devices/system/cpu/$cpu/cpufreq/scaling_governor
save_file=$(printf $CPUSPEED_ORIG_GOV $cpu)
rm -f $save_file
if [ -e $gov_file ]; then
cat $gov_file > $save_file
echo $governor > $gov_file
fi
done
fi
}
# re-enable previous CPU governor settings
# usage: restore_cpu_governor
restore_cpu_governor() {
if [ -e $CPUSPEED_INIT ]; then
if [ -e $CPUSPEED_SAVE_FILE ]; then
cp -fp $CPUSPEED_SAVE_FILE $CPUSPEED_CFG
rm -f $CPUSPEED_SAVE_FILE
fi
if [ -e $CPUSPEED_STARTED ]; then
rm -f $CPUSPEED_STARTED
service cpuspeed stop &> /dev/null
else
service cpuspeed restart &> /dev/null
fi
elif [ -e /sys/devices/system/cpu/cpu0/cpufreq/scaling_governor ]; then
for cpu in $CPUS; do
cpufreq_dir=/sys/devices/system/cpu/$cpu/cpufreq
save_file=$(printf $CPUSPEED_ORIG_GOV $cpu)
if [ -e $cpufreq_dir/scaling_governor ]; then
if [ -e $save_file ]; then
cat $save_file > $cpufreq_dir/scaling_governor
rm -f $save_file
else
echo userspace > $cpufreq_dir/scaling_governor
cat $cpufreq_dir/cpuinfo_max_freq > $cpufreq_dir/scaling_setspeed
fi
fi
done
fi
}
_cpu_multicore_powersave() {
value=$1
[ -e /sys/devices/system/cpu/sched_mc_power_savings ] && echo $value > /sys/devices/system/cpu/sched_mc_power_savings
}
# enable multi core power savings for low wakeup systems
enable_cpu_multicore_powersave() {
_cpu_multicore_powersave 1
}
disable_cpu_multicore_powersave() {
_cpu_multicore_powersave 0
}
#
# MEMORY tuning
#
THP_ENABLE="/sys/kernel/mm/transparent_hugepage/enabled"
THP_SAVE="${STORAGE}/thp${STORAGE_SUFFIX}"
[ -e "$THP_ENABLE" ] || THP_ENABLE="/sys/kernel/mm/redhat_transparent_hugepage/enabled"
enable_transparent_hugepages() {
if [ -e $THP_ENABLE ]; then
cut -f2 -d'[' $THP_ENABLE | cut -f1 -d']' > $THP_SAVE
(echo always > $THP_ENABLE) &> /dev/null
fi
}
restore_transparent_hugepages() {
if [ -e $THP_SAVE ]; then
(echo $(cat $THP_SAVE) > $THP_ENABLE) &> /dev/null
rm -f $THP_SAVE
fi
}
#
# WIFI tuning
#
# usage: _wifi_set_power_level level
_wifi_set_power_level() {
# 0 auto, PM enabled
# 1-5 least savings and lowest latency - most savings and highest latency
# 6 disable power savings
level=$1
# apply the settings using iwpriv
ifaces=$(cat /proc/net/wireless | grep -v '|' | sed 's@^ *\([^:]*\):.*@\1@')
for iface in $ifaces; do
iwpriv $iface set_power $level
done
# some adapters may relay on sysfs
for i in /sys/bus/pci/devices/*/power_level; do
(echo $level > $i) &> /dev/null
done
}
enable_wifi_powersave() {
_wifi_set_power_level 5
}
disable_wifi_powersave() {
_wifi_set_power_level 0
}
#
# BLUETOOTH tuning
#
disable_bluetooth() {
hciconfig hci0 down >/dev/null 2>&1
lsmod | grep -q btusb && rmmod btusb
}
enable_bluetooth() {
modprobe btusb
hciconfig hci0 up >/dev/null 2>&1
}
#
# USB tuning
#
_usb_autosuspend() {
value=$1
for i in /sys/bus/usb/devices/*/power/autosuspend; do echo $value > $i; done &> /dev/null
}
enable_usb_autosuspend() {
_usb_autosuspend 1
}
disable_usb_autosuspend() {
_usb_autosuspend 0
}
#
# SOUND CARDS tuning
#
enable_snd_ac97_powersave() {
save_set_sys ac97 /sys/module/snd_ac97_codec/parameters/power_save Y
}
disable_snd_ac97_powersave() {
save_set_sys ac97 /sys/module/snd_ac97_codec/parameters/power_save N
}
restore_snd_ac97_powersave() {
restore_sys ac97 /sys/module/snd_ac97_codec/parameters/power_save $1
}
set_hda_intel_powersave() {
save_set_sys hda_intel /sys/module/snd_hda_intel/parameters/power_save $1
}
restore_hda_intel_powersave() {
restore_sys hda_intel /sys/module/snd_hda_intel/parameters/power_save $1
}
#
# VIDEO CARDS tuning
#
# Power savings settings for Radeon
# usage: set_radeon_powersave dynpm | default | low | mid | high
set_radeon_powersave () {
[ "$1" ] || return
[ -e /sys/class/drm/card0/device/power_method ] || return
if [ "$1" = default -o "$1" = auto -o "$1" = low -o "$1" = med -o "$1" = high ]; then
[ -w /sys/class/drm/card0/device/power_profile ] || return
save_sys radeon_profile /sys/class/drm/card0/device/power_profile
save_set_sys radeon_method /sys/class/drm/card0/device/power_method profile
set_sys /sys/class/drm/card0/device/power_profile "$1"
elif [ "$1" = dynpm ]; then
save_sys radeon_profile /sys/class/drm/card0/device/power_profile
save_set_sys radeon_method /sys/class/drm/card0/device/power_method dynpm
fi
}
restore_radeon_powersave () {
restore_sys radeon_method /sys/class/drm/card0/device/power_method profile
_rrp_method="`get_stored_sys radeon_method`"
[ -z "$_rrp_method" -o _rrp_method="profile" ] && restore_sys radeon_profile /sys/class/drm/card0/device/power_profile default
}
#
# SOFTWARE tuning
#
RSYSLOG_CFG="/etc/rsyslog.conf"
RSYSLOG_SAVE="${STORAGE}/cpuspeed${STORAGE_SUFFIX}"
disable_logs_syncing() {
cp -p $RSYSLOG_CFG $RSYSLOG_SAVE
sed -i 's/ \/var\/log/-\/var\/log/' $RSYSLOG_CFG
}
restore_logs_syncing() {
mv $RSYSLOG_SAVE $RSYSLOG_CFG
}
#
# HARDWARE SPECIFIC tuning
#
# Asus EEE with Intel Atom
_eee_fsb_control() {
value=$1
if [ -e /sys/devices/platform/eeepc/she ]; then
echo $value > /sys/devices/platform/eeepc/she
elif [ -e /sys/devices/platform/eeepc/cpufv ]; then
echo $value > /sys/devices/platform/eeepc/cpufv
elif [ -e /sys/devices/platform/eeepc-wmi/cpufv ]; then
echo $value > /sys/devices/platform/eeepc-wmi/cpufv
fi
}
eee_set_reduced_fsb() {
_eee_fsb_control 2
}
eee_set_normal_fsb() {
_eee_fsb_control 1
}
#
# ACTION PROCESSING
#
error_not_implemented() {
echo "tuned: script function '$1' is not implemented." >&2
}
# implicit actions, will be used if not provided by profile script:
#
# * start must be implemented
# * stop must be implemented
start() {
error_not_implemented start
return 16
}
stop() {
error_not_implemented stop
return 16
}
#
# main processing
#
process() {
case "$1" in
start)
start
RETVAL=$?
;;
stop)
stop
RETVAL=$?
;;
verify)
if declare -f verify &> /dev/null;
then
verify
else
:
fi
RETVAL=$?
;;
*)
echo $"Usage: $0 {start|stop|verify}"
RETVAL=2
;;
esac
exit $RETVAL
}