Nie jesteś zalogowany.
Jeśli nie posiadasz konta, zarejestruj je już teraz! Pozwoli Ci ono w pełni korzystać z naszego serwisu. Spamerom dziękujemy!
Prosimy o pomoc dla małej Julki — przekaż 1% podatku na Fundacji Dzieciom zdazyć z Pomocą.
Więcej informacji na dug.net.pl/pomagamy/.





Cenzor wirtualnego świata
Analizując skrypt alsy:
#!/bin/sh
#
# alsa-base control script
#
# Description: Used to load and unload ALSA modules and
# restore and store mixer levels. There is no
# longer any need to run this script on bootup
# or shutdown. It is now moved to /usr/sbin.
set -e
# Exit if alsa-base package is not installed
[ -f /etc/modprobe.d/alsa-base.conf ] || exit 0
MYNAME=/usr/bin/alsa.sh
PATH=/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin
# Default values of variables in /etc/default/alsa
force_unload_modules_before_suspend=""
[ -f /etc/default/alsa ] && . /etc/default/alsa
# $* MESSAGE
warn() { echo "${MYNAME}: Warning: $* " >&2 ; }
#
# Attempt to create /var/run/alsa if it is absent.
# Return true if /var/run/alsa exists after this attempt,
# otherwise false.
#
check_run_dir()
{
[ -d /var/run/alsa ] && return 0
# We have no business creating /var/run if it doesn't exist
if ! [ -d /var/run ] ; then
warn "Could not create /var/run/alsa/ because /var/run/ is not present."
return 1
fi
if ! mkdir --mode=755 /var/run/alsa ; then
warn "Failed to create /var/run/alsa/."
return 1
fi
[ -d /var/run/alsa ] && return 0
return 1
}
echo_procs_using_sound()
{
for i in /proc/[0-9]*/fd/* ; do
var="$(readlink $i)"
if test x"$var" != x"${var#/dev/snd/pcm}" ; then
IFS=/; set -- $i; unset IFS; echo $3
fi
done
}
# $* [PID]...
echo_with_command_names()
{
[ "$1" ] || return 0
echo $( \
ps --no-headers -o "%p %c" "$@" \
| sed -e 's/\([0-9][0-9]*\) \(.*\)/\1(\2)/' \
)
}
kill_procs_using_sound()
{
procs_using_sound="$(echo_procs_using_sound)"
if [ "$procs_using_sound" ] ; then
echo -n "Terminating processes:"
for attempt in 1 2 3 4 ; do
echo -n " ${procs_using_sound}"
kill $procs_using_sound || :
sleep 1
procs_using_sound="$(echo_procs_using_sound)"
[ "$procs_using_sound" ] || break
done
# Either no more procs using sound or attempts ran out
if [ "$procs_using_sound" ] ; then
echo -n " (with SIGKILL:) ${procs_using_sound}"
kill -9 $procs_using_sound || :
sleep 1
fi
procs_using_sound="$(echo_procs_using_sound)"
if [ "$procs_using_sound" ] ; then
echo " (failed: processes still using sound devices: $(echo_with_command_names $procs_using_sound))."
return 1
fi
echo "."
fi
return 0
}
# $* MODULE-NAME [MODULE-NAME]... | "all"
unload_modules()
{
procs_using_sound="$(echo_procs_using_sound)"
if [ "$procs_using_sound" ] ; then
warn "Processes using sound devices: $(echo_with_command_names $procs_using_sound)."
fi
if check_run_dir ; then
:> /var/run/alsa/modules-removed
else
warn "Not keeping list of removed modules because /var/run/alsa is absent.
It will not be possible automatically to reload these modules."
fi
echo -n "Unloading ALSA sound driver modules:"
[ -d /proc/asound ] || { echo " (none loaded)." ; return 0 ; }
echo_snd_modules_loaded()
{
lsmod \
| sed -n -e 's/^\(snd[-_][^[:space:]]*\)[[:space:]].*/\1/p' \
| sed -e 's/_/-/g'
}
for FSMBS in $* ; do
MODULES_TO_REMOVE=""
SND_MODULES_LOADED="$(echo_snd_modules_loaded)"
case "$FSMBS" in
all)
MODULES_TO_REMOVE="$SND_MODULES_LOADED"
;;
snd_*|snd-*)
FSMBS="$(echo "$FSMBS" | sed -e 's/_/-/g')"
for M in $SND_MODULES_LOADED ; do
if [ "$FSMBS" = "$M" ] ; then
MODULES_TO_REMOVE="$FSMBS"
break
fi
done
;;
esac
[ "$MODULES_TO_REMOVE" ] || continue
if [ -d /var/run/alsa ] ; then
echo "$MODULES_TO_REMOVE" >> /var/run/alsa/modules-removed
fi
for M in $MODULES_TO_REMOVE ; do
echo -n " ${M}"
modprobe -r "$M" >/dev/null 2>&1 || :
done
done
if [ -f /var/run/alsa/modules-removed ] ; then
MODULES_STILL_LOADED="$(echo_snd_modules_loaded | grep -F -f /var/run/alsa/modules-removed)"
MODULES_STILL_LOADED="$(echo $MODULES_STILL_LOADED)"
else
MODULES_STILL_LOADED=""
fi
if [ "$MODULES_STILL_LOADED" ] ; then
echo " (failed: modules still loaded: ${MODULES_STILL_LOADED})."
return 1
else
echo "."
return 0
fi
}
# $* MODULE-NAME [MODULE-NAME]... | "all"
force_unload_modules()
{
kill_procs_using_sound || :
unload_modules "$@" || return 1
return 0
}
load_unloaded_modules()
{
LUM_RETURNSTATUS=0
MODULES_TO_LOAD=""
[ -d /var/run/alsa ] || warn "Directory /var/run/alsa is absent."
echo -n "Loading ALSA sound driver modules:"
[ -f /var/run/alsa/modules-removed ] && MODULES_TO_LOAD="$(echo $(cat /var/run/alsa/modules-removed))"
[ "$MODULES_TO_LOAD" ] || { echo " (none to reload)." ; return $LUM_RETURNSTATUS ; }
echo -n " $MODULES_TO_LOAD"
for MDL in $MODULES_TO_LOAD ; do
modprobe $MDL || LUM_RETURNSTATUS=1
done
case "$LUM_RETURNSTATUS" in
0) echo "." ;;
*) echo " (failed)." ;;
esac
return $LUM_RETURNSTATUS
}
case "$1" in
unload)
unload_modules all || exit $?
;;
reload)
EXITSTATUS=0
unload_modules all || EXITSTATUS=1
load_unloaded_modules || EXITSTATUS=1
exit $EXITSTATUS
;;
force-unload)
force_unload_modules all || exit $?
;;
force-reload)
EXITSTATUS=0
force_unload_modules all || EXITSTATUS=1
load_unloaded_modules || EXITSTATUS=1
exit $EXITSTATUS
;;
suspend)
case "$force_unload_modules_before_suspend" in
""|false) : ;;
all|true) force_unload_modules all || exit $? ;;
*) force_unload_modules $force_unload_modules_before_suspend || exit $? ;;
esac
;;
resume)
case "$force_unload_modules_before_suspend" in
""|false) : ;;
*) load_unloaded_modules || exit $? ;;
esac
;;
*)
echo "Usage: $MYNAME {unload|reload|force-unload|force-reload|suspend|resume}" >&2
exit 3
;;
esacna myśl mi przyszły dwa pytania:
1. jak uzyskać informacje, jaki proces lub coś innego korzysta z modułu?
2. czy da się jakoś siłowo usunąć moduł z jądra?
Chodzi o to, że ten powyższy skrypt rozwiązuje problemu z dźwiękiem przez przeładowanie modułów dźwiękowych. Nie było go co prawda na archu ale go pożyczyłem z debiana i po niezbyt głębokiej analizie rzuciły mi się w oczy następujące kroki: Pobranie numeru procesu używającego dźwięk, ubicie procesów, wylistowanie modułów snd* i usinięcie ich z jądra.
Problem się zaczyna w momencie gdy próbowałem to ręcznie zrobić -- konkretnie przez zamykanie aplikacji odtwarzające dźwięk. Jednak przy próbie usunięcia modułu, dostałem poniższy komunikat:
root:/home/morfik# modprobe -r snd-ca0106 modprobe: FATAL: Module snd_ca0106 is in use.
Sprawdziłem zatem funkcją ze skryptu czy może jakiś proces używa modułu ale nic nie wskazało. Jednak coś używało tego modułu, był to oczywiście pulse. xD Po wydaniu pulseaudio -k moduł się dał usunąć.
Offline







Podobno człowiek...;)








lsof /dev/dsp* /dev/audio* /dev/mixer* /dev/snd/*
Każda karta dźwiękowa, graficzna, czy inny sprzęt jest reprezentowana przez urządzenie w /dev.
Korzystanie z danego sterownika polega na komunikacji programu z urządzeniem przypisanym do danego sterownika.
To by było na tyle
;-)
Ostatnio edytowany przez Jacekalex (2013-05-05 06:20:00)
Offline





Cenzor wirtualnego świata
Ok, pulse jest tam widoczny:
root:~# lsof /dev/dsp* /dev/audio* /dev/mixer* /dev/snd/* lsof: status error on /dev/dsp*: No such file or directory lsof: status error on /dev/audio*: No such file or directory lsof: status error on /dev/mixer*: No such file or directory COMMAND PID USER FD TYPE DEVICE SIZE/OFF NODE NAME pulseaudi 6900 morfik mem CHR 116,7 26304 /dev/snd/pcmC0D1p pulseaudi 6900 morfik mem CHR 116,9 26306 /dev/snd/pcmC0D0p pulseaudi 6900 morfik 21u CHR 116,11 0t0 26308 /dev/snd/controlC0 pulseaudi 6900 morfik 22r CHR 116,33 0t0 2720 /dev/snd/timer pulseaudi 6900 morfik 23u CHR 116,9 0t0 26306 /dev/snd/pcmC0D0p pulseaudi 6900 morfik 24u CHR 116,7 0t0 26304 /dev/snd/pcmC0D1p pulseaudi 6900 morfik 25r CHR 116,33 0t0 2720 /dev/snd/timer pulseaudi 6900 morfik 30u CHR 116,11 0t0 26308 /dev/snd/controlC0
Polecenie było troszkę obcięte. Dodałem mu tam parametr +c ale przy lsof +c 16 nic nie jest pokazywane. Da radę ustawić więcej niż +c 15?
W każdym razie, da radę ubić tam procesy używające karty i uwolnić moduł:
kill -9 `lsof -t /dev/dsp* /dev/audio* /dev/mixer* /dev/snd/*`
Czyli jedno pytanie z głowy. A co w przypadku drugiego? Da radę usunąć siłowo moduł z jądra bez ubijania procesów? Czy jest to niewykonalne i trzeba pierw ubić procesy wykorzystujące moduł?
Offline