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