Není nutné být průkopníkem
Následující přehled obsahuje technologické novinky, jejichž výhod si díky Linuxu můžeme užívat. Nemusí jít nutně o věci, které se objevily v Linuxu jako v prvním systému – důležitější je, že to byl právě Linux, který stál za jejich podstatným využitím v praxi. Ne všechny z nich přežily v plném nasazení do dnešních dnů, ale i tak se podílely významnou měrou na úspěchu Linuxu v oblastech, kde si vydobyl svoji pozici.
Plánovač úloh s konstantní složitostí
Když Linus Torvalds tvořil základy Linuxu, použil pro plánování úloh (procesů) pro procesor jednoduchou implementaci, která sice spolehlivě fungovala, měla ale několik nevýhod. Především byla špatně škálovatelná (přepočet dynamických priorit závisel na počtu běžících úloh a při velkém počtu procesů byla celková režie značná), pracovala s příliš hrubou granularitou časových kvant, nedokázala zajistit dostatečnou interaktivitu a nehodila se pro real-time aplikace.
Tato implementace byla postupem času vylepšována (byla přidána podpora SMP a různá výkonnostní vylepšení a optimalizace), nicméně bránila efektivně nasadit Linux na některé systémy, například vysoce výkonné superpočítače nebo terminálové servery s velkým počtem uživatelů. Proto byl pro řadu jader 2.6 vytvořen nový plánovač, který přetrval až do verze 2.6.22.
Nový plánovač měl konstantní operační složitost, tedy jeho režie nezávisela na počtu běžících úloh. Byl založen na dvou sadách front; jedna byla vždy aktivní, z ní se odebíraly úlohy pro běh na procesoru, do druhé sady front se vkládaly úlohy, kterým vypršelo časové kvantum. Po vyprázdnění front z jedné sady se stala aktivní sada druhá (k přepnutí sad docházelo také při „vyhladovění“ neaktivní sady).
Jednotlivé fronty příslušely úrovním priority. U real-time plánování (úrovně priority 0–99) to fungovalo tak, že – podle typu plánování – každá úloha běžela tak dlouho, než se vzdala procesoru, anebo do vypršení kvanta (v takovém případě se ale jen přesunula na konec stejné fronty). U běžného plánování se úloze přidělovalo časové kvantum podle statické priority a úloha se umísťovala do příslušné fronty (100–139) podle dynamické priority. Časové kvantum se čerpalo po částech (jemná granularita). Po vyčerpání části kvanta se úloha přesunula na konec téže fronty, teprve až po vyčerpání kvanta celého (nebo při vzdání se procesoru) úloha putovala do druhé sady front.
Pokud byly úlohy ve frontě s vyšší prioritou, měly vždy přednost před úlohami z front s nižší prioritou. Interaktivita byla podporována tím, že úlohy dříve se vzdávající procesoru (které měly delší průměrnou dobu spánku – z ní a ze statické priority se počítala dynamická priorita) měly vyšší dynamickou prioritu a mohly tedy běžet přednostně před úlohami, které si usurpovaly procesor na dlouhou dobu.
Výhodou tohoto plánovače bylo i to, že se jednotlivé procesory plánovaly nezávisle a tedy bez nutnosti zamykat s velkými dopady na výkon. Vyvažování zátěže mezi procesory bylo řešeno samostatně. Tento plánovač, ač jinak velmi kvalitní, byl od počátku podrobován kritice kvůli nevhodnému chování v některých specifických situacích. Proto byl nakonec ve verzi jádra 2.6.23 nahrazen plánovačem CFS (Completely Fair Scheduler), který i přes horší operační složitost (logaritmickou) lépe zvládá extrémní situace a lépe čelí útokům, které by mohly být na plánovač podnikány.
Ne jedna, ne dvě, ale hned tři konference se konají na konci října v Praze
Netfilter
Mechanismus netfilter pro práci se síťovou komunikací, lidově známý pod názvem „iptables“ (což je struktura tabulek pro definici pravidel protokolů IP, je součástí stejného projektu jako netfilter), je jednou z nejsilnějších zbraní Linuxu. Zajišťuje širokou škálu operací se síťovými daty, a to standardně bez nutnosti předávat tato data do uživatelského prostoru (přestože i tato možnost samozřejmě existuje). Netfilter je v jádře od řady 2.4, nahradil dvě starší implementace podobných funkcí a zatím nic nenasvědčuje tomu, že by se „chystal do důchodu“.
Netfilter obsahuje bezestavový i stavový firewall pro IPv4 a IPv6, NAT/NAPT pro IPv4 (verze pro IPv6 se do netfilteru možná dostane v budoucnu, i přes velký odpor puristů, protože je o tuto funkcionalitu zájem) včetně podpory pro specifické protokoly, široké možnosti ohledně počítání/měření a logování dat, v neposlední řadě možnost rozšiřování pomocí modulů pracujících na různých úrovních.
Implementace těchto funkcionalit v jádře zajišťuje vysoký výkon (velkou propustnost a nízkou latenci) a minimální zátěž procesoru i při velkých datových tocích. Současně je ale možnost předávat data i do uživatelského prostoru (přes komunikační rozhraní netlink, které vzniklo původně právě pro takové účely, byť se dnes využívá i k řadě jiných věcí). K netfilteru přísluší také logovací démon ulogd, který běží v uživatelském prostoru a může zaznamenávat do logu (do souboru, databáze atd.) události a data podle definovaných pravidel.
K ovládání netfilteru slouží jednoduché řádkové utility, kterými lze při znalosti práce s tabulkami nastavovat chování různých subsystémů. Existují ovšem i grafické programy, které generují už přímo výstup pro netfilter (tedy primárně tabulky iptables, případně zavádění modulů apod.).
FUSE
Unixová filozofie říká, že „všechno je soubor“. V praxi to ale není tak docela pravda, přes soubory se lze ve skutečných operačních systémech dostat k lecčemu, rozhodně ale ne ke všemu. Nicméně existuje technologie, která umožňuje posunout praxi mnohem blíže k teoretické představě: je to Filesystem in Userspace čili FUSE (česky souborový systém v uživatelském prostoru).
FUSE je technologie, která umožňuje naroubovat souborové rozhraní prakticky na cokoliv. To by sice šlo i přímo v jádře, ale implementace v uživatelském prostoru jsou mnohem snazší (není potřeba se přizpůsobovat specifikům vývoje pro jádro) a bezpečnější (např. chybný přístup do paměti nijak neohrozí systém jako celek). Nevýhodou je však nižší výkon, daný tím, že se musí mnohem častěji přecházet do jádra a zpět, se všemi důsledky.
FUSE se skládá ze dvou částí. Jednou je implementace přímo v jádře, která umožňuje využívat prostředky VFS (virtuálního souborového systému) prostřednictvím systémových volání z obslužného programu. Druhá část je knihovna, která výrazně usnadňuje vývoj takového obslužného programu. FUSE umožňuje napsat tento program velmi snadno, bez nutnosti řešit cokoli jiného než souborové cesty. Na druhou stranu, pokud je žádoucí operace optimalizovat, prostředky k tomu jsou k dispozici také.
Pokud chce nějaký proces využívající soubor ze souborového systému přes FUSE například číst data, zavolá normální volání read()
jako obvykle. Implementace VFS v jádře deleguje toto volání do FUSE a odtamtud se předá obslužnému procesu, který čeká na příkazy. Zde se zavolá callback, přečtou se data a proces předá řízení zpět jádru. To poskytne přečtená data volajícímu procesu.
Pomocí FUSE bylo již vytvořeno velké množství různých ovladačů souborových systémů. Tím asi nejznámějším je NTFS-3G (první linuxový ovladač plnohodnotně podporující zápis na NTFS), dále existuje např. ZFS, archivemount (přístup k souborům v archivech), TrueCrypt (šifrované souborové systémy), SSHFS (vzdálené soubory dostupné přes SSH) a mnoho dalších.
sysfs
Sysfs je speciální paměťový souborový systém určený ke komunikaci mezi jádrem (konkrétně subsystémy a ovladači) a uživatelským prostorem. V dobách jader řady 2.4 probíhala taková komunikace jednak přes procfs (který k tomu však nikdy nebyl určen), využíval se i sysctl (realizován jako wrapper k části procfs) a případně též speciální příkazy ioctl()
. Proto vznikl nový souborový systém sysfs, který se ve stabilních jádrech objevil od řady 2.6 a měl za cíl nahradit nevhodné způsoby komunikace.
Podoba sysfs v zásadě odráží objektový model jádra – jednotlivé objekty jsou reprezentovány adresáři, atributy objektů pak soubory v těchto adresářích. Soubory mohou být ke čtení, k zápisu či k obojímu. Příslušná operace z uživatelského prostoru způsobí zavolání příslušné metody daného objektu, tato metoda musí přijmout nebo předat správná data (například u síťových adaptérů lze číst různé čítače, jiné ovladače podporují třeba přepínání režimu zařízení apod.).
Výhodou sysfs je jednotný přístup na obou stranách (v jádře i uživatelském prostoru), usnadňující vývoj ovladačů i řídicích utilit. Snadno se spravují přístupová práva (jako u jiných souborů), ve vhodných případech existují symbolické odkazy (provazující mezi sebou například zařízení a sběrnice), celé řešení je velmi robustní (na rozdíl třeba od ioctl()
, kde může i při malé nedůslednosti dojít k zavlečení záludných chyb).
Informace ze sysfs čerpají nástroje pro práci se zařízeními, jako je udev, udisks nebo UPower. Významně se vlastnosti sysfs projevují při připojování a odpojování zařízení za provozu, protože sysfs reprezentuje vždy aktuální stav systému – když pak udev dostane (přes netlink) od jádra notifikaci o změně, prostě si přečte vše potřebné ze sysfs. Platí to i pro případy, kdy je potřeba načíst do zařízení firmware z nějakého souboru. V sysfs je připraven mechanismus, který umožňuje snadné a bezpečné předání firmwaru z uživatelského prostoru do jádra.
Spouštěcí handlery, binfmt_misc
Velkou, i když možná nepříliš doceněnou výhodou Linuxu je možnost snadno spouštět širokou škálu různých programů – aniž by uživatel řešil, zda jde o nativní programy, či třeba skripty (vyžadující interpretaci) nebo programy pro jiný systém (které potřebují emulátor či wrapper).
Linuxové jádro využívá tzv. spouštěcí handlery, což jsou kusy kódu, které analyzují spustitelný soubor, a pokud vědí jak, zajistí spuštění tohoto souboru. Základním handlerem je v Linuxu ten, který umožňuje spouštět klasické binární spustitelné soubory ve formátu ELF. Bez něj se nelze obejít, protože jde o formát používaný prakticky pro veškeré nativní programy. Dalším základním handlerem je skriptový, který podle hlavičky skriptu (známé #!
následované cestou k interpretu) spustí správný interpret a předá mu cestu ke skriptu jako parametr. Proto lze jak binární programy, tak skripty spouštět přímo (pouhým uvedením cesty ve volání execve()
).
V Linuxu lze ale používat i další handlery. Jednak existují handlery pro zastaralé a exotické formáty binárních souborů, mnohem zajímavější je ale handler binfmt_misc, umožňující spouštět skoro cokoliv. Pod tím „cokoliv“ si lze představit třeba program určený pro Microsoft Windows (spustí se přes Wine) nebo soubor s javovou třídou (spustí se na virtuálním stroji Javy).
binfmt_misc se ovládá přes speciální souborový systém, často se o to ale uživatel nemusí nijak starat, protože to za něj vyřešil tvůrce distribuce (kdy se například s instalací balíčku pro Wine hned nastaví i handler pro spouštění programů pro Windows). Ovládání spočívá v zaregistrování typů souborů se všemi potřebnými informacemi (jak formát poznat, co spustit atd.).
Video4Linux
Pro abstraktní přístup k různým audiovizuálním zařízením vznikla technologie Video For Linux (Video4Linux, V4L). Existovala ve dvou verzích, starší Video4Linux 1 (začleněna do řady 2.2, odstraněna ve verzi 2.6.38) a novější, stále používané verzi V4L2.
V4L zajišťuje zachytávání videa, jeho výstup, překryvné video (přímý přenos z jednoho zařízení do druhého, s případným klíčováním), práci s daty ze zatemňovacího intervalu (VBI; jedná se například o teletext) a rozhlasová zařízení. V4L je vrstvou, která na jedné straně komunikuje s audiovizuálními aplikacemi (v uživatelském prostoru) a na straně druhé s ovladači jednotlivých zařízení.
Z pohledu aplikací je práce s V4L velmi jednoduchá. Používají se totiž úplně obyčejná souborová systémová volání, tedy např. read()
, write()
, select()
/poll()
/epoll()
a podobně. Zvláštní postavení má volání ioctl()
, které se využívá k ovládání komunikace. Pokud ovladač zařízení podporuje proudovou komunikaci přes sdílenou paměť, přes příkazy ve volání ioctl()
aplikace manipuluje s buffery (vyzvedává si je k přečtení/zápisu a zase odevzdává jádru). Jiné příkazy tohoto volání slouží ke zjišťování funkcí zařízení, k nastavování videonormy apod.
Video4Linux je typickým reprezentantem maximální abstrakce, která je v Linuxu poměrně rozšířená. Přestože to v některých případech neplatí, je obecně snaha řešit věci pokud možno co nejabstraktněji, aby bylo co nejvíce kódu společného a aby byl přístup k různým zařízením a jejich ovladačům co nejjednotnější.
I takhle to jde
Uvedený přehled je sice jen malou ukázkou toho, co Linux z technologického pohledu přinesl, je na něm ale vidět, že o zajímavá řešení není v jádře nouze. Právě taková řešení stojí za tím, že při připojení například USB disku nevyskočí hlášení „instaluji ovladač“ (přičemž by uživatel čekal desítky sekund), nýbrž je disk prakticky okamžitě připraven k použití. Nebo za tím, že lze i na vskutku muzejním hardwaru bez problémů provozovat firewall, skrz nějž tečou data stahovaná stovkami uživatelů, aniž by s tím měl obstarožní procesor nějaké potíže.
Přemýšliví lidé s chutí do práce, skvělé technologické novinky... to všechno ale ještě nestačí k vítěznému tažení světem. Ač se to někomu nemusí líbit, faktem je, že bez účasti firem a dalších organizací by Linux rozhodně nebyl tam, kde dnes je. A proto se příště podíváme právě na tuto oblast, přestože ne všechny subjekty hrály jen ryze pozitivní roli.