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/.
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 ;; esac
na 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
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
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
Time (s) | Query |
---|---|
0.00016 | SET CHARSET latin2 |
0.00004 | SET NAMES latin2 |
0.00142 | SELECT u.*, g.*, o.logged FROM punbb_users AS u INNER JOIN punbb_groups AS g ON u.group_id=g.g_id LEFT JOIN punbb_online AS o ON o.ident='18.216.250.143' WHERE u.id=1 |
0.00116 | UPDATE punbb_online SET logged=1732375202 WHERE ident='18.216.250.143' |
0.00061 | SELECT * FROM punbb_online WHERE logged<1732374902 |
0.00102 | DELETE FROM punbb_online WHERE ident='3.142.54.136' |
0.00103 | DELETE FROM punbb_online WHERE ident='85.208.96.197' |
0.00064 | SELECT topic_id FROM punbb_posts WHERE id=231777 |
0.00112 | SELECT id FROM punbb_posts WHERE topic_id=23468 ORDER BY posted |
0.00080 | SELECT t.subject, t.closed, t.num_replies, t.sticky, f.id AS forum_id, f.forum_name, f.moderators, fp.post_replies, 0 FROM punbb_topics AS t INNER JOIN punbb_forums AS f ON f.id=t.forum_id LEFT JOIN punbb_forum_perms AS fp ON (fp.forum_id=f.id AND fp.group_id=3) WHERE (fp.read_forum IS NULL OR fp.read_forum=1) AND t.id=23468 AND t.moved_to IS NULL |
0.00007 | SELECT search_for, replace_with FROM punbb_censoring |
0.00084 | SELECT u.email, u.title, u.url, u.location, u.use_avatar, u.signature, u.email_setting, u.num_posts, u.registered, u.admin_note, p.id, p.poster AS username, p.poster_id, p.poster_ip, p.poster_email, p.message, p.hide_smilies, p.posted, p.edited, p.edited_by, g.g_id, g.g_user_title, o.user_id AS is_online FROM punbb_posts AS p INNER JOIN punbb_users AS u ON u.id=p.poster_id INNER JOIN punbb_groups AS g ON g.g_id=u.group_id LEFT JOIN punbb_online AS o ON (o.user_id=u.id AND o.user_id!=1 AND o.idle=0) WHERE p.topic_id=23468 ORDER BY p.id LIMIT 0,25 |
0.00126 | UPDATE punbb_topics SET num_views=num_views+1 WHERE id=23468 |
Total query time: 0.01017 s |