Portál AbcLinuxu, 5. května 2025 15:20
Aktuální verze jádra: 2.6.32-rc5. Citáty týdne: Dark Shikari, Ingo Molnár. Výsledky voleb LF TAB 2009. Jaderný summit 2009. Díry v souborech, souběhy a mmap().
Současné vývojové jádro je 2.6.32-rc5, vydané Linusem 15. října. 90 % z hlavní části změn od -rc4 je v ovladačích, většina z toho pochází ze dvou síťových ovladačů (stmmac a vmxnet3). Kromě nových ovladačů je zde téměř 300 commitů a většina z nich jsou poměrně rozprostřené jedno- nebo málořádky: Aktualizace v architekturách (arm, powerpc, x86), nějaké aktualizace v souborových systémech (hlavně btrfs) a nějaká dokumentace, síťování atd. Zkrácený changelog je v oznámení, detaily vizte v kompletním changelogu.
Vzhledem ke Kernel Summitu nebyly do hlavní řady od vydání 2.6.32-rc5 začleněny žádné změny.
Během minulého týdne nevyšly žádné stabilní aktualizace. V době psaní tohoto článku je revidováno 2.6.31-rc5; až toto budete číst, dost možná bude k dispozici.
-- Dark Shikari
-- Ingo Molnár
Jedna z často přehlížených událostí, která se každoročně odehrává na Jaderném summitu, je obsazování pěti z deseti míst ve Výboru technických poradců [Technical Advisory Board] Linux Foundation. Výbor je pověřen zprostředkováváním výměny informací mezi LF a vývojovou komunitou. Ve volbách roku 2009 se v Tokyu vybíralo z velké skupiny kandidátů. Zvoleni byli Greg Kroah-Hartman, Alan Cox, Thomas Gleixner, Ted Ts'o a redaktor LWN.net Jonathan Corbet. Druhou polovinu výboru (které končí mandát za rok) tvoří James Bottomley, Kristen Carlson Accardi, Chris Wright, Chris Mason a Dave Jones.
Jaderný summit, ročník 2009, se konal v Japonsku v Tokyu 19. a 20. října. Časovým posunem dezorientovaní vývojáři z celého světa diskutovali široký záběr témat. Jonathan Corbet, redaktor LWN, byl při tom a sepsal následující shrnutí:
Diskuze konající se první den summitu byly:
Výstupy z minisummitů; hlášení z různých minisummitů, které se konaly během minulých šesti měsíců.
Stav plánovače, subsystému, na který všichni rádi nadávají.
Diskuze s koncovými uživateli, kde uživatelé z podnikové a embedded sféry mluví o tom, jak by jim Linux mohl sloužit lépe.
Regrese. Nikdo je nemá rád; lepší se jaderní vývojáři v tom, aby se jim vyhýbali a opravovali je?
Budoucnost událostí výkonnosti [perf events]; diskuze o tom, kam tento nový subsystém bude pravděpodobně směřovat dále.
Objem LKML a záležitosti s tím spojené. Krátké prezentace, které se z větší části týkaly e-mailové konference linux-kernel a těch, kteří do ní přispívají.
Obecné stromy zařízení. Abstrakce v podobě stromu zařízení prokázala svou užitečnost při vytváření obecných jader pro embedded hardware. Tato diskuze se týkala toho, co strom zařízení je a proč je užitečný
Druhý den se diskutovalo následující:
Právní záležitosti; jaderný summit navštívil právník, který mluvil o hrozbě softwarových patentů a o tom, jak na ni reagovat.
Jak Google používá Linux: Problémy, kterým čelí jeden z největších a nejtajnůstkářštějších uživatelů.
Výkonnostní regrese: Zpomaluje se jádro? Jak to zjistit a jak zjistit, odkud se berou problémy?
Reálný čas: Záležitosti spojené se začleněním stromu realtime preempce do hlavní řady.
Podpora obecné architektury: Zjednodušování portování Linuxu na další architektury procesorů.
Záležitosti ohledně vývojového procesu, včetně linux-next, staging, pravidel začleňovacího okna a další.
Jaderný summit skončil s obecným pocitem, že diskuze probíhaly dobře. Také bylo poznamenáno, že japonští hostitelé odvedli v podpoře summitu výjimečný kus práce a tím umožnili, aby se všechno odehrálo; nebylo by překvapením, kdyby vývojáři navrhovali, aby se summit v blízké budoucnosti do Japonska vrátil.
Vizte také: Povinné skupinové foto z Jaderného summitu.
Originál tohoto článku pro LWN.net napsal Goldwyn Rodrigues.
Souborové operace používající truncate() vždy obsahovaly souběhy. Vývojáři vždy měli obavy z toho, že dojde k souběhu zápisu do souboru a změně jeho velikosti. Existují různé krajní případy, ve kterých mohou být ztracena nebo ignorována data nebo ve kterých se naopak mohou objevit data tam, kde jsou v dírách v souboru očekávány nuly. Patch Jana Káry se pokouší takové souběhy opravit a závisí přitom na nové sekvenci zkracování, která opravuje způsob, jakým je nastavována velikost inodu souboru.
Díra je v souboru oblast reprezentovaná nulami. Vznikne, když se zapíší data na pozici [offset] v souboru, která je za současnou velikostí, nebo když je soubor „zkrácen“ na délku větší, než je jeho současná velikost. Místo mezi původní velikostí souboru a pozicí (nebo novou velikostí) je vyplněno nulami. Většina souborových systémů je dostatečně chytrá a nuly vyznačí v inodu, neukládá je fyzicky na disk (takové soubory jsou také známy jako řídké [sparse]). Souborový systém označí bloky v inodu a poznamená v nich, že jsou součástí díry. Když uživatel požaduje data z pozice v díře, souborový systém vytvoří stránku vyplněnou nulami a předá ji do uživatelského prostoru.
Práce s dírami začne být trochu ošidná, když nejsou díry zarovnané podle hranic bloků v souborovém systému. V takovém případě je nutné část bloků reprezentující díry vynulovat. Například soubor o velikosti 12k na souborovém systému s velikostí bloku 4k a s dírou o velikosti 8192 od pozice 2500 bude vyžadovat, aby posledních 1596 (4096-2500) bytů prvního bloku a stejně tak prvních 2500 bytů třetího bloku bylo vynulováno. Druhý blok je v seznamu datových bloků inodu vynechán a nezabírá žádné místo na disku.
mmap() je systémové volání, které mapuje obsah souboru do paměti. Volání přebírá adresu, kam má být soubor namapován, popisovač souboru, pozici v souboru, odkud se má mapovat a délku dat od této pozice. Obvykle se jako adresa předává NULL, takže si adresu může vybrat jádro a procesu ji předat. Mmap lze provést dvěma způsoby:
Privátní mapování – definované pomocí MAP_PRIVATE, toto mapování je pro proces soukromé. Jakékoliv změny dat se v souboru neprojevují. Pokud proces data změní, zkopíruje se stránka a změny se projeví v kopii. To je běžně známo jako kopírování při zápisu [copy-on-write, COW].
Sdílené mapování – definované pomocí MAP_SHARED, toto mapování může být sdíleno mezi procesy a lze ho použít jako efektivní nástroj pro meziprocesovou komunikaci [Inter Process Communication, IPC]. Jakákoliv modifikace souboru je zapsána zpět na disk a ostatní procesy ji mohou číst. Není nicméně garantováno, že zápisy na disk budou okamžité, většinou se provádějí, když proces zavolá msync() nebo munmap().
Když proces zavolá mmap(), jádro nastaví oblast adres virtuální paměti (Virtual Memory Address – VMA – region), do které mapuje stránky souboru na disk. Do vma->vm_ops přiřadí struct vm_operations souboru. struct vm_operations obsahuje ukazatele na funkce, které pomáhají dostat na vyžádání stránky do paměti. vm_operations.fault() se volá, když uživatel přistoupí do oblasti virtuální paměti, která v hlavní paměti není přítomna. Je zodpovědná za načtení stránky z disku a její vložení do paměti. Pokud je vma sdílená, vm_operations.page_mkwrite() nastaví stránku jako sdílenou, v opačném případě je duplikována pomocí COW. page_mkwrite() zodpovídá za sledování informací, které potřebuje souborový systém, aby bylo možné data umístit zpátky na disk (například buffer_heads). To typicky znamená přípravu bloku na zápis, kontrolu, jestli je dostatek místa na disku (a vrácení ENOSPC, když není), a provedení zápisu.
U současné sekvence page_mkwrite() hrozí souběh se změnami velikosti souboru způsobenými truncate(). Zkracování souboru probíhající ve chvíli, kdy jsou data ze sdíleného mmap() zapisována zpět na disk, mohou vést k nepředvídatelným výsledkům, jako je ztráta dat nebo jejich objevení se na místě, kde čekáme nuly.
Ztráta dat může v programu nastat ve specifickém případě, kde program namapuje soubor do paměti větší, než je současná velikost. Jak může ke ztrátě dojít, ukazuje následující úryvek kódu na systému s velikostí bloku 1024 bytů a velikostí stránky 4096 bytů:
ftruncate(fd, 0); pwrite(fd, buf, 1024, 0); map = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED, fd, 0); map[0] = 'a'; /* pro index 0 se volá page_mkwrite() */
Všimněte si, že i když je velikost souboru nastavena na 1024 bytů, mapováno je jich 4096, což je více než současná velikost. To je přípustné, protože stránky souboru jsou mapovány se zarovnáním na velikost stránky. Vzhledem k tomu, že ve sdílené paměti dochází ke změně, záznam v tabulce stránek se nastaví na zapisovatelný.
pwrite(fd, buf, 1, 10000); map[3000] = 'b'; fsync(fd); /* pro index 0 se volá writepage() */
Když je poprvé voláno page_mkwrite(), je alokován pouze blok 0, protože velikost souboru se vejde do 1024 bytů. Když nicméně program zvětší velikost souboru a zavolá fsync(), writepage() potřebuje alokovat další 3 bloky, aby mohl provést zápis vyvolaný map[3000]. Pokud je v takové situaci vyčerpána kvóta uživatele nebo souborový systém již nemá volné místo, data modifikovaná zápisem do map[3000] jsou v tichosti ignorována.
Nenulový znak se v díře může objevit, pokud proces zemře po rozšíření souboru, ale před vynulováním stránky a zápisem do ní. K pochopení problému nám pomůže tento úryvek kódu:
ftruncate(fd, 1000); map = mmap(NULL, 4096, PROT_WRITE, MAP_SHARED, fd, 0); while (1) map[1020] = 'a';
Program nepřetržitě zapisuje na pozici 1020. Jádro před zápisem na disk vynuluje stránky od pozice 1000 do 4096. map[1020] může být nicméně nastaveno poté, co jádro stránku vynuluje. Stránka je odemčena a nastavena pro zpětný zápis. V takovém případě je na disk zapsán nenulový znak. To není problém, protože je mimo rozsah souboru. Když ale jiný proces soubor zvětší (a tím zvětší i díru) a je zabit předtím, než stránku znovuvynuluje a zapíše, bude v souboru při příštím čtení obsažen „špinavý znak“. Tento problém existuje bez ohledu na velikost bloku souborového systému. Kompletní program, který tento problém demonstruje, lze najít zde.
Janův patch zavádí pomocné funkce, které zajišťují vytváření děr: block_prepare_hole() a block_finish_hole(). Tyto funkce jsou volány v sekvencích write_begin() a write_end() operací s adresovým prostorem, pokud je zjištěno, že je současná pozice v souboru větší než současná velikost, tj. při vytváření děr. write_begin() a write_end() jsou obvykle volány v page_mkwrite(). Část stránky, která reprezentuje díru, je místo v block_write_full_page() nulována v block_prepare_hole(). Během celé sekvence page_mkwrite() je stránka uzamčena, takže je chráněna proti zápisům jinými procesy. Operace zkrácení může proběhnout, až když je zámek stránky uvolněn, což sekvenci řadí. To řeší problém zbloudilých dat, která mohou v díře přistát.
Na druhou stranu block_finish_hole() je zodpovědná za označení části stránky v díře jako pouze pro čtení. Pokud se proces pokusí cokoliv zapsat do té části díry, která patří stránce, zavolá se page_mkwrite(). Jádro tak dostane příležitost pro dodatečný zápis alokovat buffer_heads, pokud je to potřeba, nebo vrátit chybu v případě ENOSPC nebo EDQUOT. Pokud dojde k chybě, write_begin() ji vrátí, takže změna v oblasti mapované paměti vrátí chybu (SIGSEGV). Funkce zapisující data na disk – block_write_full_page() kontroluje buffery všech stránek, ne jenom ty, které jsou v současné velikosti souboru. Dokud to probíhá, zajišťuje nová sekvence zkracování, že soubor není zkrácen. To řeší problém ztráty dat.
Patch zavádí ve struct address_space_operations nové pole new_writepage, které obsahuje novou metodu používanou k provedení writepage(). Jako nová sekvence zkracování je i toto pole dočasný hack a zmizí, až se všechny souborové systémy přizpůsobí novému standardu zapisování stránek na disk. Souborové systémy implementující novou metodu writepage musí nastavit new_writepage a zvládat soubory s dírami tak, že připraví vytváření děr ve write_begin() a dokončí ho ve write_end(). Staré chování page_mkwrite() je obnoveno v noalloc_page_mkwrite(). To při výpadku stránky nealokuje žádné bloky a označí všechny nemapované buffery ve stránce jako zpožděné [delayed], takže je zapíše block_write_full_page().
Nová funkce simple_create_hole() je analogická k ostatním funkcím simple_*; je to jednoduchý způsob, jakým vytvořit díru v souboru. Tato funkce vynuluje ty části stránek, které jsou součástí díry. Funkce je volána, kdykoliv je velikost souboru zkracována na hodnotu vyšší, než je současná velikost.
Nyní je zasílána třetí verze patche a většina námitek z předchozích verzí byla vyklizena. Vzhledem k tomu, že tento patch řeší uzavření souběhu, je pravděpodobné, že bude nakonec začleněn. Tato série nicméně závisí na nové sérii zkracování, takže musí počkat, až se tyto patche dostanou do hlavní řady. A navíc bude muset zmizet hackovitá metoda rozpoznávání nového writepage. To vyžaduje, aby všechny souborové systémy začaly novou sekvenci writepage používat.
[Goldwyn by rád poděkoval Janu Károvi za revizi tohoto článku.]
V době psaní tohoto článku je revidováno 2.6.31-rc5; až toto budete číst, dost možná bude k dispozici.Tak nevim, jestli jsem autora dobre pochopil, ale v den vydani clanku je venku RC8. http://lkml.org/lkml/2009/11/19/395
Jaderné noviny – 21. 10. 2009 ... Současné vývojové jádro je 2.6.32-rc5, vydané Linusem 15. října. ...Jakým způsobem to tam má ještě být napsáno aby to i poslední jelito pochopilo, že tohle je překlad článku z 21. 10. 2009 a tedy, že uvedené časové údaje se vztahují k době, kdy byl článek psán.
...aby to i poslední jelito pochopilo...Místo celého ábíčka by se musela zobrazit jenom věta "Toto je překlad článku z 21.10.2009", následně by se musel prohlížeč, maximalizovat, dát nad všechna okna a na deset vteřin zaseknout.
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.