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!

Ogłoszenie

Prosimy o pomoc dla małej Julki — przekaż 1% podatku na Fundacji Dzieciom zdazyć z Pomocą.
Więcej informacji na dug.net.pl/pomagamy/.

#1  2013-05-05 02:32:20

  morfik - Cenzor wirtualnego świata

morfik
Cenzor wirtualnego świata
Skąd: ze WSI
Zarejestrowany: 2011-09-15
Serwis

Przeładowanie modułów jądra

Analizując skrypt alsy:

Kod:

#!/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:

Kod:

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

 

#2  2013-05-05 06:17:07

  Jacekalex - Podobno człowiek...;)

Jacekalex
Podobno człowiek...;)
Skąd: /dev/urandom
Zarejestrowany: 2008-01-07

Re: Przeładowanie modułów jądra

Kod:

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)


W demokracji każdy naród ma taką władzę, na jaką zasługuje ;)
Si vis pacem  para bellum  ;)       |       Pozdrawiam :)

Offline

 

#3  2013-05-05 15:55:32

  morfik - Cenzor wirtualnego świata

morfik
Cenzor wirtualnego świata
Skąd: ze WSI
Zarejestrowany: 2011-09-15
Serwis

Re: Przeładowanie modułów jądra

Ok, pulse jest tam widoczny:

Kod:

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ł:

Kod:

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

 

Stopka forum

Powered by PunBB
© Copyright 2002–2005 Rickard Andersson
Możesz wyłączyć AdBlock — tu nie ma reklam ;-)

[ Generated in 0.006 seconds, 9 queries executed ]

Informacje debugowania

Time (s) Query
0.00010 SET CHARSET latin2
0.00004 SET NAMES latin2
0.00120 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.220.97.161' WHERE u.id=1
0.00063 REPLACE INTO punbb_online (user_id, ident, logged) VALUES(1, '18.220.97.161', 1732364928)
0.00039 SELECT * FROM punbb_online WHERE logged<1732364628
0.00032 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.00021 SELECT search_for, replace_with FROM punbb_censoring
0.00121 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.00080 UPDATE punbb_topics SET num_views=num_views+1 WHERE id=23468
Total query time: 0.0049 s