Portál AbcLinuxu, 24. dubna 2024 17:08

Jaderné noviny - 5. 5. 2015: Konverze systémových volání pro rok 2038

30. 7. 2015 | Redakce
Články - Jaderné noviny - 5. 5. 2015: Konverze systémových volání pro rok 2038  

Stav vydání jádra. Citáty týdne. Konverze systémových volání pro rok 2038.

Stav vydání jádra

Současný vývojový cyklus nese označení 4.1-rc2, a byl vydán 3. května. "Jako vždy se jedná o směsku ovladačů, aktualizací architektur (z nichž s390 vynikala kvůli prng poznámce), souborového systému a sítí."

Stabilní aktualizace: Žádné nebyly tento týden vydány. Aktualizace 4.0.2, 3.19.7, 3.14.41 a 3.10.77 byly v době psaní tohoto článku v procesu revidování. Původně měly vyjít 4. května, ale zdržely se shrnutím několika neuvážených patchů.

Citáty týdne

Za posledních 10 let se x86 FPU (matematický koprocesor) rozrostly do rozměrů jakéhosi špagetového monstra, kterému jen velmi málo (pokud vůbec nějací) vývojářů kernelu rozumí, a které jen málokoho baví hackovat.

Za ta léta mnoho lidí upozorňovalo na to, že by nebyl od věci pořádný úklid, takže jsem si před nějakou dobou řekl "a proč by ne", a krok za krokem jsem s ním začal, abych viděl, kam až to vede. Jak těžké to může být?!

O tři týdny a 200+ patchů později musím přiznat, že jsem velmi hrubě podcenil rozsah tohoto projektu ;-)

-Ingo Molnar se vydává na menší čistící quest

PROSÍM VÁS. Neprogramujeme v Pascalu (a díky Bohu za to), takže můžeme ponechat návěští se smysluplnými názvy. Taky se nestydíme používat goto, kde to dává smysl, takže není třeba zmenšovat návěští do velikosti smítek na monitoru.

-Linus Torvalds

Konverze systémového volání roku 2038

Do onoho osudného dne v lednu roku 2038, kdy dojdou volné bity a přetečou 32bitové hodnoty time_t, které v unixových systémech zastupují zobrazování času, nám už zbývá jen 23 let. S přibližováním onoho data se můžeme těšit na všelijaká zábavná selhání 32bitových systémů a současní čtenáři LWN se mohou těšit na povolání z důchodu v hrdinné (a lukrativní) snaze zabránit blížící se apokalypse. Tak nějak by to mohlo vypadat, nebýt skupiny vývojářů (morousů), kteří se snaží problém roku 2038 vyřešit a celou zábavu pokazit. Konkrétnější obrysy této snahy se dostaly do hledáčku díky novým (později aktualizovaným) patchům Arnda Bergmanna, ukazujícím migrační cestu pro časová systémová volání.

Současná linuxová systémová volání využívají pro zobrazování času několik různých datových typů od times_t, timeval po timespec a další. Všechny však mají jedno společné: Celočíselnou hodnotu, která počítá vteřiny od roku 1970 (nebo z aktuálního času v případech, kdy je zapotřebí relativní hodnota času). Na 32bitových systémech je počet dán 32bitovým celým číslem se znaménkem, takže je zapotřebí dalších volných bitů, jinak dojde k přetečení a po roce 2038 se čas nebude zobrazovat správně.

Reprezentace času

Jednou z možností je použití nově vytvořených 64bitových verzí těchto časových struktur. Ale pokud má dojít k nekompatibilním změnám, bylo by možná vhodné se nejprve šířeji zamyslet. Proto nedávno Thomas Gleixner navrhoval vytvoření nové sady systémových volání (linuxových), které by pracovaly s 64bitovým nanosekundovým čítačem se znaménkem. Ten by zrcadlil ktime_t type (definovaný v include/linux/ktime.h), který se používá pro reprezentaci času v kernelu:

    union ktime {
	s64	tv64;
    };
    typedef union ktime ktime_t;		/* Kill this */

Komentář "kill this" přidal Andrew Morton v roce 2007, ale nikdo tak ještě neučinil)

Používat zrcadlené časové hodnoty kernelu také v uživatelském prostoru má něco do sebe, předešlo by se mnoha přepočtům času. Avšak Arnd Bergmann poukázal na několik těžkostí, spojených s tímto přístupem, jednou z nich je ještě složitější přechod. Zásadní chyba se objevuje v tomto seznamu časových systémových volání, který Andy zveřejnil krátce na to: Systémová volání, která pracují s časovými značkami souborů, musí být schopna vyjádřit čas ještě před rokem 1970. Také musí umět vyjádřit širší rozsah časů, než kolik zvládá 64bitový ktime_t. Je tedy nutné použít některou z variant time_t. (Potřeba zobrazovat čas před rokem 1970 vylučuje použití hodnoty bez znaménka pro rozšíření 32bitové hodnoty time_t).

Z toho vyplývá, že univezální použití časových hodnot v nanosekundách se znaménkem zde není reálné. Rozhodně ne jako prevence nadcházející katastrofy roku 2038. Stále je zde prostor pro zjednodušení. Aktuálně je v plánu využití 64bitové verze struct timespec (nazývané v kernelu jednoduše struct timespec64 - uživatelský prostor uvidí pouze jako struct timespec) pro téměř všechny časové údaje přicházející do nebo z jádra. Různá systémová volání, která používají jiné (starší) časové formáty, mohou být jednoduše emulována v uživatelském prostoru. Takže například volání gettimeofday() (které využívá struct timeval) se změní na volání clock_gettime() předtím, než vstoupí do kernelu. Takto je možné snížit počet různých volání, jejichž kompatibilitu je třeba v kernelu zajistit.

Takže všechny 32bitové systémy připravené na rok 2038, budou využívat struct timespec64 pro všechny časové hodnoty, které vstupují do jádra. Prozatím zůstává menší problém s dosažením tohoto cíle za co nejmenších škod. Aktuální Arndovo řešení je možné vidět v patch setu, který zahrnuje velký počet kroků, které pomohou bezpečně přiblížit kernel k roku 2038.

Cesta k bezpečnému systému roku 2038

Prvním krokem je připravit podporu 32bitových aplikací a přesunout kód kernelu pro řízení času na 64bitový čas. Tyto "vnitřní" práce již nějaký čas probíhají, pozornost vyžaduje interface uživatelského rozhraní, počínaje sadou pravidel, která by převáděla mezi 32bitovým a 64bitovým časem v rozhraní systémového volání. Dobrou zprávou je, že tato pravidla (routines) již existují ve formě "kompatibilních" systémových volání, které využívají 32bitové aplikace běžící na 64bitovém kernelu. Pokud jde o manipulaci s časem, budou v budoucnu 64bitová všechna jádra, takže tyto funkce jsou zapotřebí (až na několik případů jiných typů dat, kdy je zapotřebí rozdílného převedení). Patch tedy zajistí kompatibilitu systémových volání jak pro 32bitové, tak pro 64bitové kernely. Kompatibilní funkce jsou připraveny k použití, ovšem budou dostupné teprve na konci série patchů.

Dalším krokem je přeměna nativních systémových volání kernelu pro manipulaci s časem na výhradně 64bitové hodnoty. Toho lze docílit pomocí dvou dílčích kroků. Prvním je definování nové sady typů popisujících formát nativních časových hodnot v uživatelském prostoru. Kupříkladu systémová volání, která v současné době akceptují jako parametr struct timespec, budou po změně pracovat s struct__kernel_timespec. Obě struktury jsou téměř totožné, takže jejich záměna nebude mít na kernel žádný vliv. Jestliže bude nastavena konfigurace CONFIG_COMPACT_TIME, bude struct__kernel_timespec vypadat jako timespec64.

Různé typy __kernel_ se objevují na hranici (boundary) systémových volání, méně za touto hranicí. Místo toho dojde na všech zařízeních k jejich okamžitému převedení na 64bitové. Na 64bitových zařízeních není samozřejmě moc co převádět. Jakmile jsou všechna časová systémová volání převedena, používají interně 64bitové časové hodnoty, a to i v případě, že uživatelský prostor nadále pracuje s 32bitovými časovými hodnotami.

Posledním krokem je povolení 64bitových časových hodnot na 32bitových systémech bez toho, aby došlo k poškození existujících 32bitových binárek.

To je tak nejvíc, co se dá v kernelu (s tímto problémem) dělat. Existující 32bitové binárky zavolají kompatibilní verze časových systémových volání a budou i nadále fungovat, až do roku 2038.

Zbývá tedy slušné množství práce, kterou je třeba udělat v uživatelském prostoru. Zjednodušeně lze říct, že C knihovny mohou používat 64bitové datové struktury a vyvolat nové verze příslušných systémových volání. Potom mohou být rekompilovány aplikace pro nové knihovny, možná bude zapotřebí oprav v uživatelském prostoru, poté se nebudou podílet na debaklu roku 2038. V praxi by mohlo být nutné přestavět všechny knihovny a aplikace systému, aby se zajistila ucelená myšlenka o reprezentaci času. C GNU knihovny užívají pro určení verzí symboly, takže je možné je nastavit pro oba časové formáty zároveň. Některé knihovny takovou schopnost nemají. Konverze kompletních distribucí by mohla být zajímavou výzvou v okamžiku, kdy bude v jádře vše hotovo.

Ukončovací práce

I v kernelu je stále několik záležitostí, kterým se dosud nikdo nevěnoval. Významným problémem je volání ioctl(), z tisíců podporovaných jádrem jich několik pracuje s hodnotami time_t. Bude třeba je lokalizovat, jedno po druhém opravit, což bude trvat. Souborový systém ext4 ukládá časové značky jako 32bitové hodnoty time_t, i když některé verze formátování je rozšiřují na 34 bitů. Ext3 34bitové časové značky nepodporuje, takže řešením by byl přechod k ext4. NFSv3 má podobný problém a možná, že ho čeká podobný osud. I XFS má problémy, které je třeba řešit. Potíže se souborovým systémem se nevyhýbají ani 64bitovým systémům. V kernelu a uživatelském prostoru navíc zcela jistě číhá ještě celá řada dalších (nepříjemných) překvapení, takže připravit systém na rok 2038 jde ještě daleko za přechod k 64bitovým časovým hodnotám systémových volání. I když začít s nimi je rozhodně dobrý začátek.

Jakmile se vyřeší zbývající problémy, bude možné aplikovat poslední patch. Volitelným se stane CONFIG_COMPAT_TIME, ponechá 64bitové cesty beze změny a odstraní kompatibilní 32bitová volání. Bude-li tato volba vypnuta, nepodaří se spustit binárky se staršími systémovými voláními. Jde o dobrou metodu, jak otestovat konverze pro rok 2038 nebo nasazení starších systémů, které musí fungovat i po tomto datu. Arnd k tomu dodává:

V současné době jde o nástroj pro ladění, který by měl pomoci vytvořit distribuci odolnou na rok 2038, ale někdy ve třicátých letech bychom měli tuhle možnost a veškeré řízení kompatibility odstranit docela.

Doufejme, že bude v budoucnu někdo dávat pozor a nezapomene za dvacet let tento krok provést (v případě velké inspirace by prostě mohli zabít ktime_t). Potom budou určitě vděčni těm vývojářům, kteří obětovali svůj čas problému mnohem dříve, než začal být akutní. My ostatní si prostě budeme muset najít jiný způsob, jak si vydělat na důchod.

(Díky patří Arndovi Bergmannovi za cenné rady a návrhy k rané verzi článku.)

Odkazy a zdroje

LWN.net

Další články z této rubriky

Jaderné noviny – přehled za březen 2024
Jaderné noviny – přehled za únor 2024
Jaderné noviny – přehled za leden 2024
Jaderné noviny – přehled za prosinec 2023
Jaderné noviny – přehled za listopad 2023

ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.