Po po téměř roce vývoje od vydání verze 5.38 byla vydána nová stabilní verze 5.40 programovacího jazyka Perl (Wikipedie). Do vývoje se zapojilo 75 vývojářů. Změněno bylo přibližně 160 tisíc řádků v 1 500 souborech. Přehled novinek a změn v podrobném seznamu.
Uroš Popović popisuje, jak si nastavit Linux na desce jako Raspberry Pi Zero, aby je šlo používat jako USB „flešku“.
Andreas Kling oznámil, že jelikož už se nevěnuje nezávislému operačnímu systému SerenityOS, ale výhradně jeho webovému prohlížeči Ladybird, přičemž vyvíjí primárně na Linuxu, SerenityOS opustí a Ladybird bude nově samostatný projekt (nový web, repozitář na GitHubu).
Po dvou měsících vývoje byla vydána nová verze 0.13.0 programovacího jazyka Zig (GitHub, Wikipedie). Přispělo 73 vývojářů. Přehled novinek v poznámkách k vydání.
Na čem aktuálně pracují vývojáři GNOME a KDE? Pravidelný přehled novinek v Týden v GNOME a Týden v KDE.
Před 70 lety, 7. června 1954, ve věku 41 let, zemřel Alan Turing, britský matematik, logik, kryptoanalytik a zakladatel moderní informatiky.
NiceGUI umožňuje používat webový prohlížeč jako frontend pro kód v Pythonu. Zdrojové kódy jsou k dispozici na GitHubu pod licencí MIT.
Open source platforma Home Assistant (Demo, GitHub, Wikipedie) pro monitorování a řízení inteligentní domácnosti byla vydána ve verzi 2024.6. Z novinek lze vypíchnout lepší integraci LLM (OpenAI, Google AI, Ollama) nebo podporu Matter 1.3.
IKEA ve Spojeném království hledá zaměstnance do své nové pobočky. Do pobočky v počítačové hře Roblox. Nástupní mzda je 13,15 liber na hodinu.
Alyssa Rosenzweig se v příspěvku na svém blogu Vulkan 1.3 na M1 za 1 měsíc rozepsala o novém Vulkan 1.3 ovladači Honeykrisp pro Apple M1 splňujícím specifikaci Khronosu. Vychází z ovladače NVK pro GPU od Nvidie. V plánu je dále rozchodit DXVK a vkd3d-proton a tím pádem Direct3D, aby na Apple M1 s Asahi Linuxem běžely hry pro Microsoft Windows.
Aktuální vývojová verze jádra je 3.4-rc5 vydaná 29. dubna. A stejně jako v případě -rc5 docela dost změn dorazilo v pátek (a pár dalších ještě včera). A neuklidňuje se to, spíš naopak. -rc5 má o téměř 50 % commitů víc než -rc4. To není dobré. Tak jako tak přicházejí hlavně opravy, krátký přehled změn najdete v oznámení.
Stabilní aktualizace: verze 3.0.30 a 3.3.4 vyšly 27. dubna s obvyklou hromadou oprav.
Když vám teď povím, že jsem měl včera noční můru, ve které se mě r12 (IP registr na ARM) snažil zabít, tak věřte, že si nevymýšlím. Asi jsem to s hrabáním se v disassembly jádra o víkendu trochu přehnal.
-- Jon Masters
No zajisté, mým cílem bylo, aby to bylo „méně ujeté“, nikoliv „neujeté“. A „neujetý“ popis zůstává dlouhodobou snahou spíše než krátkodobým cílem.
-- přiměřeně ujetý Paul McKenney
Co to s těma Linusama lidé mají? Už i v Googlu jednoho mají. Jednoho dne si vezmu meč, začnu pobíhat okolo a křičet "Může tu být jen jediný Linus!"
Býval jsem něco _extra_. Fňuk.
Pro ty z vás, kteří by se rádi dozvěděli, jak používat subsystém perf, zveřejnil Google rozsáhlý tutorial napsaný Stephanem Eranianem. U zájemců si tento odkaz asi vyslouží zařazení do záložek.
Migrace běžícího kontejneru z jednoho fyzického hostitele na jiného je na mnoha úrovních docela záludnost. Je to ještě složitější, pokud má kontejner aktivní síťová spojení k procesům mimo kontejner. Je přirozené požadovat, aby tato spojení následovala kontejner na nového hostitele, nejlépe, kdyby si vzdálená strana ani nevšimla, že se něco změnilo, jenže síťový stack Linuxu nebyl k tomuto napsán. I tak to ale vypadá, že transparentní přesídlení síťových spojení bude podporováno od jádra 3.5, díky patchům pro opravu TCP spojení od Pavla Emelyanova.
Prvním krokem nezbytným pro přesun TCP spojení je shromáždění všech dostupných informací o aktuálním stavu. Většina těchto informací je už teď dostupná z uživatelského prostoru, z /proc a /sys lze vytáhnout adresu a port vzdálené strany, velikosti přijímacích a odesílacích front, sekvenční čísla TCP a řadu dalších parametrů vyjednaných mezi oběma stranami. Zbývá ještě ale pár věcí, které je nutné zjistit, než je možné provést úkon; k tomu je zapotřebí dodatečná pomoc od jádra.
S Pavlovým patchem je možné tuto pomoc získat, pokud jste dostatečně privilegovaným procesem. Aby bylo možné zkoumat vnitřnosti aktivního síťového spojení, tak musí uživatelský prostor nejprve přepnout soket do nového „opravářského režimu“. To se dá udělat pomocí volání setsockopt() s volbou TCP_REPAIR. Pro nastavení tohoto režimu je třeba mít capability CAP_NET_ADMIN, soket také musí být buď připojený (established) nebo uzavřený (closed). Jakmile je soket v tomto režimu, dá se s ním pracovat několika způsoby.
Jedním způsobem je číst odesílací a přijímací fronty. Odesílací fronta obsahuje data, která ještě nebyla úspěšně odeslána druhé straně; tato data je nutné přesunout spolu se spojením, aby došlo k jejich odeslání z nového místa. Přijímací fronta zase obsahuje data, která ještě nenačetla přesouvaná aplikace; tato data je rovněž nutné přesunout, aby na aplikaci čekala na novém hostiteli. Získání obsahu těchto front je možné pomocí dvou kroků: 1) zavolat setsockopt(TCP_REPAIR_QUEUE) s buď TCP_RECV_QUEUE nebo TCP_SEND_QUEUE a 2) zavolat recvmsg() pro přečtení obsahu zvolené fronty.
Ukázalo se, že je tu už jen jedna další informace, kterou nejde získat z uživatelského prostoru: maximální hodnota MSS (maximální velikost segmentu) vyjednaná mezi oběma konci při vytváření spojení. Aby bylo možné hodnotu získat, tak Pavlův patch mění sémantiku volby soketu TCP_MAXSEG (pro getsockopt()) – když je spojení v opravářském režimu, tak je vracena maximální MSS místo aktuální aktivní hodnoty.
Poslední věcí je to, že pokud je spojení ukončeno v tomto režimu, nejsou druhé straně zaslána žádná upozornění. Žádný RST nebo FIN, takže druhá strana nebude tušit, že se něco děje.
Pak je tu obnova spojení na novém hostiteli. Toho dosáhneme vytvořením nového socketu a okamžitým přepnutím do opravářského režimu. Pak je možné soket navázat na správný port, obvyklé kontroly portů jsou v tomto režimu vypnuty. Opět se použije setsockopt(TCP_REPAIR_QUEUE), ale tentokrát se obsah front obnoví pomocí sendmsg().
Dalším důležitým úkolem je obnovit sekvenční čísla. Tato čísla jsou při připojení obvykle generována náhodně, ale to při přesunu spojení nelze dělat. Tato čísla jde nastavit pomocí dalšího volání setsockopt(), tentokrát s volbou TCP_QUEUE_SEQ. Tato operace se dotýká té fronty, která byla předtím zvolena pomocí TCP_REPAIR_QUEUE, takže obnovu obsahu fronty a nastavení sekvenčního čísla jde udělat najednou.
Pak je třeba obnovit ještě několik dalších sjednaných hodnot – MSS clamp, aktivní maximální velikost segmentu, velikost okénka a používání selective ACK a časových otisků (timestamps). K tomu slouží volání setsockopt(TCP_REPAIR_OPTIONS).
V moment, kdy byl soket obnoven do stavu, v jakém původně byl, je čas jej uvést do běhu. Když je na socketu v opravářském režimu zavoláno connect(), tak je většina kódu kolem nastavování spojení přeskočena a spojení přejde rovnou do stavu připojeno (established). Poslední věcí je to, že při vypnutí údržbářského režimu je poslán paket pro nastavení okénka, aby se obnovil provoz mezi oběma stranami; od této chvíle může být soket používán na novém hostiteli.
Tyto patche v uplynulých měsících prošly několika revizemi; ve verzi 4 je pak správce síťování David Miller přijal do net-next. Z tohoto místa je pak krátká cesta do začleňovacího okna verze 3.5. Patche pro opravu TCP spojení nejsou kompletním řešením problému migrace kontejnerů, ale jsou významným krokem v tomto ohledu.
Jedním ze zásadních pravidel vývoje jádra je to, že rozbíjení ABI pro uživatelský prostor je nepřijatelné. Pokud nějaký kód v uživatelském prostoru závisí na konkrétním chování, tak je nutné toto chování zachovat, i když se to nemusí moc hodit do krámu. Ale co dělat, když dva různé programy závisí na vzájemně nekompatibilním chování, takže je na první pohled nemožné zachovat fungování obou z nich? Odpovědí může být porušení jiného pravidla, tedy dát do jádra ošklivý hack – nebo udělat něco ještě zákeřnějšího.
Protokol „autofs“ je používán pro komunikaci mezi jádrem a démonem pro automatické připojování. Umožňuje automounteru vytvořit speciální virtuální souborový systém, který při použití uživatelem může být nahrazen skutečným. Většina protokolu je implementována pomocí volání ioctl() na speciálním zařízení autofs, ale používají se i roury, a to když se konkrétní souborové systémy připojují.
Tento protokol je rozhodně součástí jaderného ABI, takže jeho komponenty byly navrhovány s určitou mírou péče. Jednou ze zásadních součástí protokolu autofs je struktura autofs_v5_packet, která je z jádra do uživatelského prostoru poslána rourou; mj. se používá k oznámení, že souborový systém už nebyl nějakou dobu používán, takže je možné jej odpojit. Takto struktura vypadá následovně:
struct autofs_v5_packet { struct autofs_packet_hdr hdr; autofs_wqt_t wait_queue_token; __u32 dev; __u64 ino; __u32 uid; __u32 gid; __u32 pid; __u32 tgid; __u32 len; char name[NAME_MAX+1]; };
Velikost každého pole je precizně definovaná, takže by struktura měla vypadat stejně na 32 i 64bitových systémech. A až na jeden malý problém to tak je. Velikost struktury je definovaná na 300 bajtů, což není dělitelné osmi. Takže pokud by se do paměti umístily dvě takové struktury, 64bitová hodnota ino by nemohla být správně zarovnaná. Aby se tomu kompilátor vyhnul, tak na 64bitových systémech zarovná velikost struktury na násobek osmi, takže přidá na konec čtyři extra bajty. sizeof(struct autofs_v5_packet) tedy na 32bitovém systému vrátí 300 a na 64bitovém 304.
Tento nesoulad až na jednu výjimku nepředstavuje problém. Automatické připojování je jedním z mnoha úkolů, které řeší démon systemd. Když systemd čte takovou strukturu z jádra, zkontroluje správnou velikost. Tato kontrola funguje správně do té doby, dokud se jádro a systemd na velikosti shodnou. Pokud je ale systemd 32bitovým procesem na 64bitovém jádře, tak to nedopadne dobře, systemd usoudí, že něco je špatně, a ukončí se.
V únoru začlenil Ian Kent patch, který má problém vyřešit. Je to docela hack: jaderný kód pro automount odečte 4 bajty z velikosti struktury, pokud (a jen pokud) 64bitové jádro komunikuje s 32bitovým procesem. Tento patch zajistí, že systemd funguje; byl začleněn v 3.3-rc5 a byl rychle začleněn do různých stabilních řad. Všichni žili šťastně až do smrti.
...jenže oni šťastně nežili. Ukázalo se, že program automount z balíčku autofs-tools, který se na spoustě systémů stále používá, na tento problém narazil už před léty. Tehdy se vývojáři autofs-tools rozhodli problém obejít v uživatelském prostoru. Takže když automount zjistí, že běží v 32bitovém režimu na 64bitovém jádře, opraví údaj o tom, jak velká by struktura měla být. Když začne jádro na tuto velikost sahat, oprava v automountu přestane fungovat, takže Ianův patch opravuje systemd s tím, že rozbíjí automount.
Takže jsme se dostali do situace, kdy dva různé programy mají jinou představu o tom, jak má protokol autofs vypadat. Je to dosti nešťastná situace. Zachování patche nepotěší jedny, jeho odstranění rozzlobí zase druhé.
Nešťastná, ale ne neřešitelná. Jedním způsobem, jak to opravit, je patch od Michaela Tokareva. Ve zkratce dělá to, že se dívá na název aktuálního příkazu (current->comm) a porovnává to s „automount“. Pokud se aktuální program jmenuje automount, oprava velikosti struktury se nekoná a všechno zase funguje. Takže všechno je opraveno, akorát že tu máme jaderné ABI, které závisí na názvu běžícího programu. To je přinejmenším ne zrovna elegantní. Přinejhorším tu může být jiný program s jiným jménem, který se porouchá stejně jako automount; takový program by ani pak nefungoval.
Linus přesto dospěl k tomu, že to asi budeme muset překousnout. Dával ale přednost robustnějšímu řešení. Jednou možností bylo to, že by se jádro podívalo na velikost operace read(), pomocí které se načítá struktura autofs_v5_packet; pokud by velikost byla 300 nebo 304, tak by jádro dalo volajícímu programu tu velikost, jakou očekává. Problém je v tom, že operace read() je tu ukryta za rourou, takže kód autofs nemá přístup k velikosti tohoto bufferu.
Linus tedy přišel s jiným řešením, jsou jím tzv. paketizované roury. Paketizovaná roura připomíná obyčejnou rouru s pár rozdíly: každé volání write() se uchovává v odděleném bufferu a read() spotřebuje celý buffer, i když je velikost v read menší objem dat v bufferu. S paketizovanou rourou může jádro vždy zapsat větší strukturu a pokud program čte jen 300 bajtů, tak dostane to, co očekává. Takto není potřeba speciálních hacků v jádře, jen se volí jiné chování roury. Na základě návrhu od Alana Coxe zpřístupnil Linus paketizované chování přes volbu O_DIRECT, takže uživatelský prostor může takové roury vytvářet podle potřeby.
Po několika neúspěších Linus patch rozchodil a začlenil jej těsně před vydáním verze 3.4-rc5. Takže jádro 3.4 by mělo dobře fungovat s automount i systemd.
Tentokrát z toho jaderná komunita vybruslila lacino; tentokrát bylo možné, aby chytrý vývojář našel způsob, jak všem programům dát to, co chtějí. Příště už to nemusí být tak snadné. Udržování stability ABI není vždycky sranda, ale je nutné udržovat systém dlouhodobě použitelným.
Nástroje: Tisk bez diskuse
Tiskni Sdílej:
Kdyby to byla aspoň oprava dvou programů, ale ona je to oprava jen jednoho (systemd). Protože jestli to chápu správně, vývojáři systemd rozbili ABI protože byli líní řešit na straně aplikace různé chování jádra. A místo toho, aby vývojáři zkroušeně připustili, že to někdo podělal a příslušnou změnu revertovali, tak vyrobí hnusný hack.Ne chápeš to zcela špatně - myslím, že zde to Linus vysvětluje.
if (pkt_len % 8) { if (strcmp(un.machine, "alpha") == 0 || strcmp(un.machine, "ia64") == 0 || strcmp(un.machine, "x86_64") == 0 || strcmp(un.machine, "ppc64") == 0) pkt_len += 4; }Až mi někdo řekne, že prasím v C tak mu pošlu tohle.