[proaudio] OpenRC compatible rtirq init script |
[ Thread Index |
Date Index
| More lists.tuxfamily.org/proaudio Archives
]
ahoy all,
with the migration to the new OpenRC init system, the init.d script for rtirq no longer works, as it is not started with #!/sbin/runscript, as well as not having the correct functions implemented (i.e. at least start()). i made an attempt to make an OpenRC rtirq init.d, attached. please take a look and let me know if it indeed works for you.
i would be happy to update the rtirq ebuild, though i would need some hand holding, as well as overlay access obviously. but i am willing to learn.
thanks, w
#!/sbin/runscript
#
#
# Copyright (c) 2004-2009 rncbc aka Rui Nuno Capela.
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License
# as published by the Free Software Foundation; either version 2
# of the License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License along
# with this program; if not, write to the Free Software Foundation, Inc.,
# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
#
# /etc/init.d/rtirq
#
# Startup script for realtime-preempt enabled kernels.
#
# This program is free software; you can redistribute it and/or modify it
# under the terms of the GNU General Public License version 2 or later.
#
#
# 2011.05.17 Wayne DePrince http://wayne.in-giro.org
#
# * modified to work with OpenRC on Gentoo
# Colon delimited trail list of already assigned IRQ numbers,
# preventind lower priority override due to shared IRQs.
RTIRQ_TRAIL=":"
#
# Reset policy of all IRQ threads out there.
#
function rtirq_reset ()
{
# Reset all softirq-timer/s from highest priority.
rtirq_exec_high reset
# PIDS=`ps -eo pid,class | egrep '(FF|RR)' | awk '{print $1}'`
PIDS=`ps -eo pid,comm | grep -i IRQ | awk '{print $1}'`
for PID in ${PIDS}
do
${RTIRQ_CHRT} --pid --other 0 ${PID}
done
}
#
# IRQ thread handler policy prioritizer, by IRQ number.
#
function rtirq_exec_num ()
{
ACTION=$1
NAME1=$2
NAME2=$3
PRI2=$4
IRQ=$5
# Check the services that are to be (un)threaded.
if [ -n "`echo :${RTIRQ_NON_THREADED}: | sed 's/ /:/g' | grep :${NAME1}:`" ]
then
PREPEND="Setting IRQ priorities: ${ACTION} [${NAME2}] irq=${IRQ}"
for THREADED in /proc/irq/${IRQ}/*/threaded
do
if [ -f "${THREADED}" ]
then
case ${ACTION} in
*start)
einfo "${PREPEND}: ${THREADED}: OFF."
einfo -n 0 > "${THREADED}"
;;
stop)
einfo "${PREPEND}: ${THREADED}: ON."
einfo -n 1 > "${THREADED}"
;;
esac
fi
done
fi
# And now do the proper threading prioritization...
if [ -z "`echo ${RTIRQ_TRAIL} | grep :${IRQ}:`" ]
then
# Special for kernel-rt >= 2.6.31, where one can
# prioritize shared IRQs by device driver (NAME2)...
for NAME in ${NAME2}
do
PIDS=`ps -eo pid,comm | egrep -i "IRQ.${IRQ}.${NAME:0:8}" | awk '{print $1}'`
if [ -n "${PIDS}" ]; then break; fi
done
if [ -z "${PIDS}" ]
then
# Backward compability for older kernel-rt < 2.6.31...
PIDS=`ps -eo pid,comm | egrep -i "IRQ.${IRQ}" | awk '{print $1}'`
RTIRQ_TRAIL=":${IRQ}${RTIRQ_TRAIL}"
fi
for PID in ${PIDS}
do
PREPEND="Setting IRQ priorities: ${ACTION} [${NAME2}] irq=${IRQ} pid=${PID}"
case ${ACTION} in
*start)
PREPEND="${PREPEND} prio=${PRI2}"
if ${RTIRQ_CHRT} --pid --fifo ${PRI2} ${PID}
then
einfo "${PREPEND}: OK."
else
eerror "${PREPEND}: FAILED."
fi
;;
stop)
if ${RTIRQ_CHRT} --pid --other 0 ${PID}
then
einfo "${PREPEND}: OK."
else
eerror "${PREPEND}: FAILED."
fi
;;
status)
einfo "${PREPEND}: " && ${RTIRQ_CHRT} --pid --verbose ${PID}
;;
*)
eerror "${PREPEND}: ERROR."
;;
esac
PRI2=$((${PRI2} - 1))
done
fi
}
#
# IRQ thread handler policy prioritizer, by service name.
#
function rtirq_exec_name ()
{
ACTION=$1
NAME1=$2
NAME2=$3
PRI1=$4
IRQS=`grep "${NAME2}" /proc/interrupts | awk -F: '{print $1}'`
for IRQ in ${IRQS}
do
rtirq_exec_num ${ACTION} "${NAME1}" "${NAME2}" ${PRI1} ${IRQ}
PRI1=$((${PRI1} - 1))
done
}
#
# Generic process top prioritizer
#
function rtirq_exec_high ()
{
ACTION=$1
case ${ACTION} in
*start)
PRI1=99
;;
*)
PRI1=1
;;
esac
# Process all configured process names...
for NAME in ${RTIRQ_HIGH_LIST}
do
PREPEND="`basename $0`: ${ACTION} [${NAME}]"
PIDS=`ps -eo pid,comm | grep "${NAME}" | awk '{print $1}'`
for PID in ${PIDS}
do
if ${RTIRQ_CHRT} --pid --fifo ${PRI1} ${PID}
then
einfo "${PREPEND} pid=${PID} prio=${PRI1}: OK."
else
einfo "${PREPEND} pid=${PID} prio=${PRI1}: FAILED."
fi
done
[ ${PRI1} -gt ${RTIRQ_PRIO_HIGH} ] && PRI1=$((${PRI1} - 1))
done
}
#
# Main executive.
#
function rtirq_exec ()
{
ACTION=$1
# Check configured base priority.
PRI0=${RTIRQ_PRIO_HIGH:-90}
[ $((${PRI0})) -gt 95 ] && PRI0=95
[ $((${PRI0})) -lt 55 ] && PRI0=55
# Check configured priority decrease step.
DECR=${RTIRQ_PRIO_DECR:-5}
[ $((${DECR})) -gt 10 ] && DECR=10
[ $((${DECR})) -lt 1 ] && DECR=1
# (Re)set all softirq-timer/s to highest priority.
rtirq_exec_high ${ACTION}
# Process all configured service names...
for NAME in ${RTIRQ_NAME_LIST}
do
case ${NAME} in
snd)
PRI1=${PRI0}
grep irq /proc/asound/cards | tac | \
sed 's/\(.*\) at .* irq \(.*\)/\2 \1/' | \
while read IRQ NAME2
do
rtirq_exec_num ${ACTION} "${NAME}" "${NAME2}" ${PRI1} ${IRQ}
PRI1=$((${PRI1} - 1))
done
;;
usb)
rtirq_exec_name ${ACTION} "${NAME}" "ohci_hcd" ${PRI0}
rtirq_exec_name ${ACTION} "${NAME}" "uhci_hcd" ${PRI0}
rtirq_exec_name ${ACTION} "${NAME}" "ehci_hcd" ${PRI0}
;;
*)
rtirq_exec_name ${ACTION} "${NAME}" "${NAME}" ${PRI0}
;;
esac
[ ${PRI0} -gt ${DECR} ] && PRI0=$((${PRI0} - ${DECR}))
done
}
### OpenRC delcarations
name="rtirq"
description="Change the realtime scheduling policy and priority of relevant system driver IRQ handlers."
depend()
{
need localmount alsasound
provide rtirq
keyword -shutdown
}
start()
{
ebegin "Starting ${RC_SVCNAME}"
checkconfig || return 1
if [ "${RTIRQ_RESET_ALL}" = "yes" -o "${RTIRQ_RESET_ALL}" = "1" ]
then
rtirq_reset
fi
rtirq_exec start
eend $?
}
stop()
{
ebegin "Stopping ${RC_SVCNAME}"
if [ "${RTIRQ_RESET_ALL}" = "yes" -o "${RTIRQ_RESET_ALL}" = "1" ]
then
rtirq_reset
#else
# rtirq_exec stop
fi
eend $?
}
# restart()
#{
# ebegin "Restarting ${RC_SVCNAME}"
# #$SCRIPTNAME restart >/dev/null
# svc_stop; svc_start;
# eend $?
#}
checkconfig()
{
# Won't work without those binaries.
for DIR in /sbin /usr/sbin /bin /usr/bin /usr/local/bin; do
[ -z "${RTIRQ_CHRT}" -a -x ${DIR}/chrt ] && RTIRQ_CHRT=${DIR}/chrt
done
# Check for missing binaries (stale symlinks should not happen)
[ -n "${RTIRQ_CHRT}" -a -x ${RTIRQ_CHRT} ] || {
eerror "`basename $0`: chrt: not installed."
[ "$1" = "stop" ] && exit 0 || exit 5
}
# Check for existence of needed config file and read it.
RTIRQ_CONFIG=/etc/conf.d/rtirq
[ -r ${RTIRQ_CONFIG} ] || RTIRQ_CONFIG=/etc/default/rtirq
[ -r ${RTIRQ_CONFIG} ] || RTIRQ_CONFIG=/etc/rtirq.conf
[ -r ${RTIRQ_CONFIG} ] ||
{
eerror "`basename $0`: ${RTIRQ_CONFIG}: not found."
#[ "${RTIRQ_ACTION}" = "stop" ] && exit 0 || exit 6
return 1
}
# Read configuration.
source ${RTIRQ_CONFIG}
return 0
}
status()
{
ebegin "obtaining status of ${RC_SVCNAME}"
if ! service_started; then
eerror "service is not started, thus can get no status"
return 1
fi
# invoke runscript's status() function too???
#rtirq_exec status
ps -eo pid,class,rtprio,ni,pri,pcpu,stat,comm --sort -rtprio \
| egrep '(^[ |\t]*PID|IRQ|s(oft)?irq|sirq|irq\/)' \
| awk 'BEGIN {
while (getline IRQLine < "/proc/interrupts") {
split(IRQLine, IRQSplit, ":[ |\t|0-9]+");
if (match(IRQSplit[1], "^[ |\t]*[0-9]+$")) {
gsub("[^ |\t]+(PIC|MSI)[^ |\t]*[ |\t]+" \
"|\\[[^\\]]+\\][^ |\t]*[ |\t]+",
"", IRQSplit[2]);
IRQTable[IRQSplit[1] + 0] = IRQSplit[2];
}
}
} { if ($9 == "")
{ print $0"\t"IRQTable[substr($8,5)]; }
else
{ print $0"\t"IRQTable[$9]; } }'
eend $?
}
# reset()
# {
# if [ "${RTIRQ_RESET_ALL}" = "yes" -o "${RTIRQ_RESET_ALL}" = "1" ]
# then
# rtirq_reset
# else
# rtirq_exec stop
# fi
# }