problem s Apache22 na FreeBSD 6.1 a Accept Filter

Dan Lukes dan at obluda.cz
Tue Jul 25 11:45:24 CEST 2006


Miroslav Lachman wrote:
> Ten problem neni jen pri signalu USR1, ale i pri HUP, tedy klasickem 
> reloadu (vim, ze uz jsi tu minimalne jednou psal, ze jsi mel s USR1 
> problemy, kdy apache pak uz nenabehnul a ze s HUP je to jistejsi)

	No, to uz se do jiste miry vysvetlilo, to byla chyba v kodu OpenSSL a 
od te doby, co jsem na vsech 4.x instaloval novejsi OpenSSL z portu tak 
to prestalo. Ale je pravda, ze stejne gracefull restart nepouzivam ...

> Bohuzel nevim, jak overit, jestli ten filtr funguje, nebo ne.

	Hm, pripoustim, ze to bez debuggeru neumim zjistit take - a s 
debuggerem je to, s ohledem na komplikovany kod Apache take netrivialni 
zalezitost.

	Mozna by to slo zjistit s necim, co by monitorovalo, jake systemove 
volani aplikace pouzila, jake predala parametry a co dostala zpatky - 
potrebujeme videt co vrati prvni 'read' po akceptaci noveho spojeni.

	Mozna existuje nejaky jednoduchy zpusob, jak zjistit, co je na socketu 
aktivni za filtry, ale ja ho neznam.

> jako takovy bezi, to mam vyzkousene, ale krome trochy teorie z manualu o 
> ACCEPT FILTERu nevim jak presne to funguje a tudiz co zjistovat a hlavne 
> jak to zjistovat.

	To muzu vysvetlit - aplikace cekajici na spojeni vola 'listen()'. Tim 
zada TCP stack, aby pro ni prijimal prichozi TCP spojeni. Kdyz takove 
spojeni prichazi, probehne standardni TCP hanshaking 
(SYN->;SYN+ACK<-;ACK->), ktery probiha pod kontrolou jadra a TCP stacku 
- bez ucasti aplikace. Jakmile je takto TCP spojeni ustaveno, je 
zarazeno do fronty novych prichozich spojeni - odkud si tuto informaci 
muze aplikace vyzvednout volanim accept(). Pak uz, pod rizenim aplikace, 
probiha cteni "uzivatelskych" dat (obvykle volanim read() ).

	Filtr umoznuje rict, ze ten handshaking probihajici v rezii jadra je 
delsi a komplikovanejsi a odsunout tak okamzik, kdy spojeni a cteni dat 
prechazi od jadra pod kontrolu aplikace. HTTP filtr napriklad zpusobuje, 
ze jadro povazuje spojeni za "predatelne navazane" teprve v okamziku, 
kdy z protejsi strany dorazil kompletni HTTP request (nebo kdyz filtr 
dojde k zaveru, ze se o HTTP request vubec nejedna). Teprve v te chvili 
zaradi spojeni do fronty a teprve v teto chvili si jej aplikace muze 
accept()em vyzvednout. Prvni read() pak uz muze precist rovnou cely 
pozadavek. Bez filtru by mohlo byt treba mnoho readu - v zavislosti na 
tom, jak klient data pozadavku posila.

	Cele to ma pouze vykonovy duvod - systemova volani maji relativne 
velkou rezii. Kazdy usetreny read() se na zatizenem stroji pocita. A je 
to pritom v aplikaci snadno pouzitelne, protoze krome zadosti o aktivaci 
filtru neni treba delat v aplikaci zadnou zmenu.

> Je klidne mozne, ze je to jen hlaska v logu a o zadny skutecny problem, 
> ktery by jakkoliv omezoval funkcnost Apache nejde.

	Z vyse uvedeneho plyne, ze dokonce i kdyby ten filtr aktivni nebyl, tak 
nejde o funkcni omezeni - jen vykonove. Aplikace, s vyjimkou tech tri 
radek, ktere filtr aktivuji, je napsana uplne stejne, jako by zadny 
filtr neexistoval - jinymi slovy - aplikace nepocita (a slusna aplikace 
nikdy pocitat nebude) s tim, ze urcita data dostane "v kuse" - i tak ma 
a musi mit implementovany kod, ktery pocita s tim, ze cokoliv co cte 
muze prijit ve vice nez jednom readu (i kdyby to byly jen dva byte). Je 
prijemne plus (vykonostni) pokud to prijde najednou, ale nic se nedeje, 
pokud filtr "nezabere" a aplikace si data musi slozit sama.

					Dan



P.S. Ten druhy "hotovy" filtr v systemu (accf_data) povazuje spojeni za 
predatelne dokoncene ve chvili, kdy prijde prvni byte uzivatelskych dat.



More information about the Users-l mailing list