Neprovede se reboot stroje
Dan Lukes
dan at obluda.cz
Wed Sep 23 16:22:31 CEST 2009
Milan Cizek napsal/wrote, On 09/21/09 19:31:
>> napise syncing disks... A vyplivne uptime.
>> Nic dalšího tam není.
> Tak to zatuhne na DEVICE 'ad2'
> Pokud ad2 fyzicky odpojim (bootuji z ad0, takze bez problemu), pak se reboot
> opravdu uskutecni tak jak ma.
Jelikoz je tu nejmene jeden, ktereho zajimaji dalsi dily serialu "kdo
zabil shutdown" tak sepisu kratke shrnuti.
Preci jen jsme nakonec presli k privatni komunikaci - prilis mnoho
napadu nikam nevede a posilat sem rozsahlejsi vypisy taky neni vhodne.
Desitku dopisu lze shrnout do par odstavcu aniz bych vas pripravil o
podstatnou zapletku.
Skoncili jsme u toho, ze shutdown pocitace se nenavratne zadre behem
shutdownu ovladace disku ad2.
Ta rutina (sys/dev/ata/ata-disk.c::ad_shutdown()) je primitovni - dela
jen tohle: "pokud disk podporuje prikaz FLUSH tak udelej FLUSH".
Konkretne zavola:
ata_controlcmd(dev, ATA_FLUSHCACHE, 0, 0, 0);
Tahle funkce (viz sys/dev/ata/ata-queue.c) pouze vyplni predane
parametry do jednoduche struktury vcetne jednoho parametru nepredaneho -
timeoutu - a zavola
ata_queue_request() (stejny soubor). Tahle funkce uz je slozitejsi,
jenze, vetsina z ni resi veci, tkere se naseho jednoducheho pozadavku
netykaji. Nas se tyka jen to, ze je pozadavek zarazen na konec fronty
(TAILQ_INSERT_TAIL) a je zavolan dispatcher (ata_start()).
Pro nas je klicovy dalsi krok:
sema_timedwait(&request->done, request->timeout * hz * 4)
To je funkce, ktera ceka az bude request vyrizen NEBO az vyprsi timeout,
ktery je nastaven na 4 sekundy (mimochodem dost malo - ATA specifikace
umoznuje prikazu FLUSH trvat az 30s). Pokud by funkce skoncial timeoutem
tak se na consoli vypise hlaska. Ta se nam nevypisuje.
Takze vime, ze tato funkce nejenze nikdy nekonstatuje, ze pozadavek byl
vyrizen, ale navic neskonci ani po ubehnuti pozadovaneho timeoutu.
Zatim jsme se nijak nevenovali prvni polovine problemu - proc neni
pozadavek vyrizen (nebo prinejmensim, proc to neni rozpoznano) - je to
fuk, v nejhorsim to preci ma skoncit timeoutem.
sema_timedwait() je je cekani na semafor s timeoutem.
Semafor je softwarova obdoba samoobsluhy kam se smi jen s vozikem.
Prichazeji zakaznici a dokud voziky nedojdou mohou hned dovnitr. Kdyz
dojdou cekaji frontu na voziky. Vime tak, ze uvnitr neni nikdy vic nez
maximalni dovoleny pocet nakupujicich. Obcas nekdo zaplati a vozik vrati
a prvni z fronty na voziky tak muze dovnitr. V nasem pripade je
prujezdem pokladnou dokonceni zadaneho ATA pozadavku a pocatecni pocet
voziku byl nastaven na nulu. sema_timedwait tak efektivne ceka na
vyrizeni pozadavku. Nebo timeout, protoze toto cekani je s timeoutem.
Zjistime, ze v nasem pripade funkce nikdy neskonci. Podle ni nedoslo ani
k vyrizeni pozadavku ani k timeoutu. Takze se musime podivat do ni (viz
sys/kern/kern_sema.c)
Je trivialni - vsechno tam vlastne dela "nekonecna" smycka ktera vola
cv_timedwait().
cv je "cekani na udalost". To je do znacne miry velice podobne semaforum
s tim rozdilem, ze cekat nelze na minule udalosti - jen budouci. Zatimco
u semaforu muzu prijit a pokud jsou "kosiky volne" tak ihned jit, v
pripade cekani na udalost minule udalosti nehraji roli. Cekame udalost
ktera nastane od ted dal. V nasem pripade je udalosti "nekdo vratil
kosik" - teda chtel jsem rict - byla zvysena hodnota semaforu. Zvyseni
hodnoty semaforu (a tim prehozeni na zelenou) by zajistila rutina
ata_complete pote, co je dokonceno vyrizeni ATA requestu.
Cekani navic muze byt ukonceno prerusenim a v pripade timedwait take
uplynutim timeoutu.
Takze - cv_timedwait() (viz sys/kern/kern_cond.c) muze skoncit ve trech
pripadech - zvysila se hodnota semaforu (hodnoty > 0 se povazuji za
"zelene svetlo", =0 za "cervene") nebo tak, ze vyprsel timeout nebo bylo
cekani preruseno. Kvuli te treti moznosti je cekani ve smycce - zavola
cekani znovu.
Skutecna implementace je ale ve skutecnosti nedokonala a komentar
spravne upozornuje, ze pri prilis castem prerusovani cekani k timeoutu
nikdy nedojde (po preruseni se totiz pocita "od pocatku"). Vypadalo to,
jako by to mohl byt nas pripad - vypadalo to moc nadejne.
Bohuzel, testem se ukazalo, ze preruseni nedochazi vubec. Ke zmene
promenne semaforu take ne (jak uz jsem psal k te by doslo, kdyby byl
pozadavek vyrizen) - a nedojde ani k timeoutu.
Takze jak vlastne cekani na udalost funguje ? Thread se uspi. Vzbudit ho
muze krome "vseobecnych budiku" coz je prichod signalu/preruseni take
to, ze nastane ocekavana udalost. Ta svoje "nastani" oznami zavolanim
cv_signal(), ktere zajisti "od-uspani". My ale cekame s timeoutem -
takze k uspani threadu se pouzije funkce "uspani s nastavenym budickem"
- sleepq_timedwait()
Vypada to monotonne ?
Uz jedeme treti kolo zavodu
"funkce X_timedwait() je implementovana pomoci Y_timedwait()"
Jo, je to ponekud nudne. Ale uz to konci.
Timeout "uspani" je zavisi na funkci callout_reset() - to je funkce,
ktera patri ke CRONu kernelove urovne. V podstate rika kernelu "za
urceny cas zavolej funkci F s parametry P" - v nasem konkretnim pripade
je funkce F takova, ze provede "odespani".
No a tady (nejmene dneska) skoncime. Vime, ze sleepq_timedwait() nikdy
neskonci - ale nevime, jestli je to proto, ze nas thread zustal navzdy
uspan (selhal kernelovy CRON a thread tudiz nebyl odespan). Nebo je to
proto, ze thread sice byl odespan, ale z nejakeho duvodu nebyl uznan
hodna behu.
Jedna z teorii je, ze system si predcasne zastavi "hodiny" - tim by
prestal fungovat in-kernel CRON a nedoslo by k odespani. Navic by to
vysvetlovalo proc neni vyrizen ATA pozadavek - i obsluha fronty je
rizena casem. Ale prepnuti kernelu na jiny casovac problem nevyresilo.
Dalsi mozna teorie je vada scheduleru - tohle cele je slozite kvuli
tomu, ze veci se deji, nebo prinejmensim dit mohou, soucasne (cekame az
nekdo z fronty vezme a vyridi pozadavek a da nam to vedet, pritom ale
samocekani je zavisle na tom, ze nekde tikaji hodiny a provadeji nejake
ukony). Pokud by byl problem se schedulerem je mozne, ze ty "soucasne"
veci ve skutecnosti nebezi. Nebo bezi a jsme to my, kdo od urciteho
okamziku uz nebezi ac bychom podle vseho mohli.
A tohle bude zanalyzovat komplikovany. Uvidime ...
Dan
More information about the Users-l
mailing list