Na čem aktuálně pracují vývojáři GNOME a KDE Plasma? Pravidelný přehled novinek v Týden v GNOME a Týden v KDE Plasma.
Před 25 lety zaplavil celý svět virus ILOVEYOU. Virus se šířil e-mailem, jenž nesl přílohu s názvem I Love You. Příjemci, zvědavému, kdo se do něj zamiloval, pak program spuštěný otevřením přílohy načetl z adresáře e-mailové adresy a na ně pak „milostný vzkaz“ poslal dál. Škody vznikaly jak zahlcením e-mailových serverů, tak i druhou činností viru, kterou bylo přemazání souborů uložených v napadeném počítači.
Byla vydána nová major verze 5.0.0 svobodného multiplatformního nástroje BleachBit (GitHub, Wikipedie) určeného především k efektivnímu čištění disku od nepotřebných souborů.
Na čem pracují vývojáři webového prohlížeče Ladybird (GitHub)? Byl publikován přehled vývoje za duben (YouTube).
Provozovatel čínské sociální sítě TikTok dostal v Evropské unii pokutu 530 milionů eur (13,2 miliardy Kč) za nedostatky při ochraně osobních údajů. Ve svém oznámení to dnes uvedla irská Komise pro ochranu údajů (DPC), která jedná jménem EU. Zároveň TikToku nařídila, že pokud správu dat neuvede do šesti měsíců do souladu s požadavky, musí přestat posílat data o unijních uživatelích do Číny. TikTok uvedl, že se proti rozhodnutí odvolá.
Společnost JetBrains uvolnila Mellum, tj. svůj velký jazykový model (LLM) pro vývojáře, jako open source. Mellum podporuje programovací jazyky Java, Kotlin, Python, Go, PHP, C, C++, C#, JavaScript, TypeScript, CSS, HTML, Rust a Ruby.
Vývojáři Kali Linuxu upozorňují na nový klíč pro podepisování balíčků. K původnímu klíči ztratili přístup.
V březnu loňského roku přestal být Redis svobodný. Společnost Redis Labs jej přelicencovala z licence BSD na nesvobodné licence Redis Source Available License (RSALv2) a Server Side Public License (SSPLv1). Hned o pár dní později vznikly svobodné forky Redisu s názvy Valkey a Redict. Dnes bylo oznámeno, že Redis je opět svobodný. S nejnovější verzí 8 je k dispozici také pod licencí AGPLv3.
Oficiální ceny Raspberry Pi Compute Modulů 4 klesly o 5 dolarů (4 GB varianty), respektive o 10 dolarů (8 GB varianty).
Byla vydána beta verze openSUSE Leap 16. Ve výchozím nastavení s novým instalátorem Agama.
Vývojové jádro 3.17-rc6 vyšlo dne 21. září (oznámení). Linus k tomu řekl:
Byl klid – natolik, že – s ohledem na mé nadcházející cestování – by to mohla být poslední verze -rc a finální verze 3.17 by mohla vyjít příští víkend.
Stabilní aktualizace: minulý týden nebyly vydány žádné stabilní aktualizace.
Problém je, že současný kód zařazuje stejnou strukturu do čtyř různých seznamů. Protože nemáme kvantový počítač, nemůže head.next odkazovat na čtyři různá místa.
– Paul McKenney (odkaz)
V poslední době používám printk zřídka. Má moc omezené použití. Za prvé, většina věcí, které se hodí ladit, se děje tisíckrát za sekundu a když použijete printk, všechno se hrozně zpomalí.
– Steven Rostedt (odkaz)
Je přirozené počítat s tím, že operace vstupu a výstupu pomocí vyrovnávací paměti v unixových systémech jsou asynchronní. V Linuxu existuje mezipaměť stránky, která na úrovni procesu odděluje vstupně-výstupní požadavky od fyzických požadavků odeslaných do paměťového média. Ale některé operace jsou ve skutečnosti synchronní; konkrétně operaci čtení nelze dokončit, dokud se data skutečně nenačtou do mezipaměti stránky. Takže volání read() na normální deskriptor souboru může vždy blokovat; tohle zablokování většinu nepůsobí žádné potíže, ale může být problematické pro programy, které musí stále reagovat. V současnosti probíhají práce na částečném řešení pro tento druh kódu, ale za cenu přidání až čtyř nových systémových volání.
Problém blokovaných čtení pomocí vyrovnávací paměti samozřejmě není nový, takže ho aplikace obcházejí mnoha způsoby. Jedním z častých řešení je vytvořit sadu vláken určených k provádění vstupně-výstupních operací pomocí vyrovnávací paměti. Tato vlákna lze blokovat, zatímco jiná vlákna v programu pokračují v práci. Toto řešení funguje a může být efektivní, ale nevyhnutelně přidává určitou režii komunikace mezi vlákny, zejména v případech, kdy požadovaná data již v mezipaměti stránky jsou a volání read() by mohlo být dokončeno ihned. Nedávná sada oprav od Milosze Tanského se snaží tenhle problém řešit jinak. Miloszův přístup umožňuje programu požádat o neblokovací chování na úrovni jednoho volání read(). Bohužel, současné read() a varianty nemají argument „flags“, takže tuto žádost o jejich použití nejde nijak vyjádřit. Proto Milosz přidává dvě nové verze každého read() a write():
int readv2(unsigned long fd, struct iovec *vec, unsigned long vlen, int flags); int writev2(unsigned long fd, struct iovec *vec, unsigned long vlen, int flags); int preadv2(unsigned long fd, struct iovec *vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h, int flags); int pwritev2(unsigned long fd, struct iovec *vec, unsigned long vlen, unsigned long pos_l, unsigned long pos_h, int flags);
Ve všech případech je systémové volání stejné jako dříve, s výjimkou přidání argumentu flags. Všimněte si, že se dva parametry odsazení (pos_l a pos_h) až preadv2() a pwritev2() na úrovni knihovny C zkombinují do jednoho parametru off_t.
V Miloszově sadě oprav je jediným podporovaným příznakem RWF_NONBLOCK, který požaduje neblokující operaci. Pokud žádost o čtení doprovází tento příznak, bude dokončena pouze v případě, kdy jsou požadovaná data (alespoň některá) již v mezipaměti stránky; v opačném případě vrátí EAGAIN. Současná oprava nespustí žádný druh operace readahead, pokud nedokáže uspokojit požadavek čtení bez blokování. Nové operace zápisu nepodporují neblokující činnost; argument flags musí být při jejich volání nulový. Do volání write() lze přidat neblokovacího chování; takový zápis bude dokončen pouze v případě, že je pro kopii dat v mezipaměti stránky okamžitě k dispozici paměť. Ale tato implementace byla odložena na později.
Vzhledem k tomu, že vstupně-výstupní chování bez blokování je volitelné a musí být výslovně vyžádáno, nezdá se, že by jeho podpora u běžných souborů způsobila potíže. Tím se dostáváme k faktu, že předání příznaku O_NONBLOCK do volání open() vlastně požaduje dvě různé věci: (1), že samotné volání open() neblokuje a (2), že následné vstupy a výstupy nebudou blokovací. Některé aplikace používají O_NONBLOCK z prvního důvodu; Samba ho například používá, aby bránila volání open() v blokování v případě zámků souboru. Protože čtení pomocí vyrovnávací paměti jsou vždy blokována bez ohledu na O_NONBLOCK, aplikace se před voláním read() nebude zabývat obnovení příznaku voláním fcntl(). Pokud tato volání read() začnou vracet EAGAIN, aplikace, která takové chování nečeká, selže.
Lze namítnout, že toto chování je nesprávné, ale fungovalo po celá desetiletí; narušení těchto aplikací změnou jádra není přijatelné. Samba není jedinou aplikaci, která by měla problémy; squid a GQview zjevně také selžou. Jde tedy opravdu o reálný problém.
Kromě toho, jak vysvětlil Volker Lendecke, chování zcela bez blokování nebude ladit s tím, jak tuto funkci chtějí používat aplikace, jako je Samba. Chtělo by to zkusit načíst veškerá potřebná data v režimu bez blokování; pokud data nebudou k dispozici, žádost bude předána fondu vláken k synchronnímu zpracování. Pokud fondu vláken používá stejný popisovač souboru, jeho pokusy o blokovací čtení se nezdaří. Pokud používá jiný popisovač souboru, mohou narazit na zvláštní problémy týkající se překvapující sémantiky uzamčení souborů POSIX (další informace viz tento článek). Takže je nutná možnost požádat o chování bez blokování na úrovni jednotlivých čtení.
Další možností by bylo přidat verzi systémového volání fincore(), která umožňuje procesu dotázat se jádra, zda je v mezipaměti stránky uložen konkrétní rozsah dat souboru. Opravy přidávající fincore() jsou k dispozici zhruba od roku 2010. Ale fincore() je vnímán trochu jako nepřímá trasa k reálnému cíli a vždy existuje možnost, že se mezi voláním fincore() a rozhodnutím aplikace na základě výsledku něco udělat může situace změnit. Pokud se volá read() bez blokace, k tomuto konkrétnímu rozporu nedojde.
V úvahu také připadá asynchronní vstupně-výstupní subsystém v jádru, který by umožňoval aplikaci využít přístupy bez blokací na úrovni požadavků. Ale asynchronní vstupně-výstupní operace nikdy nebyly pro vstup/výstup s vyrovnávací pamětí podporovány a pokusy přidat tuto funkcionalitu se utápějí v čiré složitosti tohoto problému. Přidat chování read() bez blokací – kde, na rozdíl od asynchronních vstupů/výstupů, může požadavek jednoduše selhat, pokud nemůže být splněn okamžitě – je mnohem jednodušší.
Takže v konečném důsledku můžeme mít novou sadu systémových volání specifických pro Linux, která umožní aplikacím volat na běžné soubory read() bez blokací. Rychlost změn na této sadě oprav se zpomaluje – ačkoli stojí za zmínku, že readv2() a writev2() byly z nejnovější verze sady oprav odebrány (v době vzniku tohoto textu). Už je pozdě připravit tento kód pro vývojový cyklus 3.18, ale měl by být skvěle připraven do verze 3.19.
Ve světě filtru paketů Berkeley (BPF) se všechno děje rychle. LWN se na tuto práci naposledy díval v červenci, kdy byla publikována verze 2 sady oprav přidávající systémové volání bpf(). O dva měsíce později postoupila tato práce do verze 14; docela dost se toho změnilo a byly odebrány některé funkce ve snaze zmenšit opravy natolik, aby se daly snadno revidovat. Teď ovšem systémové volání jádra možná dosáhlo bodu, kdy se blíží zařazení do hlavního stromu. Zdá se být vhodná chvíle pro další pohled na tento významný přírůstek do funkce jádra s nadějí, že se znovu nezmění.
Vývojář BPF Alexej Starovojtov se ze všech sil snažil dostat svou práci do stavu vhodného k začlenění – dokazuje to ostatně vydání dvanácti verzí za dva měsíce, často s velkými změnami. Vstřícně reagoval na žádosti o změny, ale, jak napovídá tato stížnost, podle některých vývojářů je trochu příliš ctižádostivý. To ale nezabránilo tomu, aby se některé z jeho prací dostaly do hlavního stromu. A nakonec by to ani nemělo být žádnou velkou překážkou pro případné začlenění zbytku.
Stejně jako u předchozích verzí jsou funkce BPF přístupné prostřednictvím jediného rozhraní systémové volání, ale toto volání se výrazně změnilo:
#includeint bpf(int cmd, union bpf_attr *attr, unsigned int size);
Klíčovou změnou, podle návrhu Inga Molnára, je vytvořit jeden velký union obsahující všechny možní typy parametrů pro různé operace podporované bpf(). Použití tohoto unionu závisí na konkrétním příkazu vydaném systémovému volání.
Většina operací v aktuální sadě oprav se týká správy map – polí dat, které lze sdílet mezi programem BPF a uživatelským prostorem. Tento proces začíná vytvořením mapy pomocí příkazu BPF_MAP_CREATE. Po tomto příkazu systémové volání očekává, že příslušné informace budou v tomto členu unionu bpf_attr:
struct { /* anonymní struktura použitá příkazem BPF_MAP_CREATE */ __u32 map_type; __u32 key_size; /* velikost klíče v bajtech */ __u32 key_size; /* velikost klíče v bajtech */ __u32 max_entries; /* max. počet položek v mapě */ };
Pole map_type popisuje typ mapy. V plánu je mít širokou škálu typů včetně polí hash, ordinálních polí, Bloomových filtrů a stromů radix. Současná implementace údajně podporuje pouze typ hash, ale i tato implementace v příslušném zveřejnění chybí. Parametry key_size a value_size kódu sdělí, jak velké budou klíče a přidružené hodnoty, zatímco max_entries nastaví horní mez počtu položek, které lze v mapě uložit.
Když se zavolá funkce bpf() k vytvoření mapy, vše v unionu bpf_attr mimo výše uvedenou strukturu musí být nastaveno na nulu, a size by měla být velikost unionu jako celku. Tato pravidla, která platí pro všechny operace bpf(), jsou vynucena v kódu; účelem je umožnit přidávat k tomuto unionu další informace, aby bylo možno funkčnost BPF dále rozšiřovat. Pokud jsou přidána nová pole, potřebné informace mohou poskytnout novější aplikace. Starší aplikace budou místo toho muset v těchto polích předávat samé nuly, aby všechno fungovalo správně.
Po úspěšném vytvoření mapy bude návratová hodnota bpf() obsahovat popisovač otevřeného souboru, kterým lze odkazovat na tuto mapu.
K dispozici je sada příkazů pro práci na jednotlivých položkách v mapě; všechny používají tuto strukturu v unionu bpf_attr:
struct { /* anonymní struktura použitá v příkazech BPF_MAP_*_ELEM */ __u32 map_fd; __aligned_u64 key; union { __aligned_u64 value; __aligned_u64 next_key; }; };
Pro všechny operace map_fd popisovač souboru odkazuje k mapě, která se má použít, a key je ukazatel na příslušný klíč. Chcete-li v mapě uložit položku, je třeba použít příkaz BPF_MAP_UPDATE_ELEM; v tomto případě by měl parametr value obsahovat ukazatel na data, která mají být uložena. Chcete-li vyhledat položku, použijte BPF_MAP_LOOKUP_ELEM; pokud se položka v mapě nachází, její hodnota bude uložena v umístění, na které odkazuje value. Položky lze odstranit pomocí BPF_MAP_DELETE_ELEM.
Iteraci mapou lze provést pomocí BPF_MAP_GET_NEXT_KEY; vrátí další klíč po poskytnutém parametru key. Význam „next“ závisí na typu mapy. Pokud není zadaný klíč key v mapě nalezen, hodnota next_key bude nastavena na první klíč v mapě; typickou iteraci je tedy nejvhodnější spustit voláním BPF_MAP_GET_NEXT_KEY s nesmyslným klíčem.
Všimněte si, že neexistuje žádný příkaz k odstranění mapy. Místo toho program, který vytvořil mapu, musí pouze zavřít přidružený popisovač souboru; když jsou všechny popisovače uzavřeny a na mapu neodkazuje žádný načtený program BPF, bude mapa odstraněna.
Program BPF se do jádra načte příkazem BPF_PROG_LOAD. Odpovídající struktura je v tomto případě:
struct { /* anonymní struktura použitá v příkazu BPF_PROG_LOAD */ __u32 prog_type; __u32 insn_cnt; __aligned_u64 insns; /* 'const struct bpf_insn *' */ __aligned_u64 license; /* 'const char *' */ __u32 log_level; /* úroveň podrobností ověřovatele eBPF */ __u32 log_size; /* velikost vyrovnávací paměti uživatele */ __aligned_u64 log_buf; /* vyrovnávací paměť 'char *' zadaná uživatelem */ };
Zde prog_type popisuje kontext, ve kterém se očekává použití programu; určuje, která data a podpůrné funkce budou při spuštění programu k dispozici. BPF_PROG_TYPE_SOCKET je používán pro programy, které budou připojeny k soketům, zatímco BPF_PROG_TYPE_TRACING je pro trasovací filtry. Velikost programu (v instrukcích) je k dispozici v insn_cnt, zatímco insns odkazuje na samotný program. Pole license odkazuje na popis licence programu; lze v budoucnu použít k omezení některých funkcí programů kompatibilních s GPL.
Všechny programy musí v rámci procesu načítání projít ověřovačem BPF. Tento ověřovač má zaručit, že program nepoškodí systém jako celek. Zabrání přístupu k libovolným datům, zakáže programy, které obsahují smyčky, a další. Pokud by chtěl vývojář vědět, proč ověřovač jeho program odmítá, může nastavit vyrovnávací paměť protokolování délky log_size, na kterou odkazuje log_buf. Protokolování se zapne nastavením log_level na nenulovou hodnotu.
Všimněte si, že pole „fixup“ v prvních verzích sady opravy již není k dispozici. Toto pole označovalo instrukce odkazující na popisovače souboru map BPF; uvedené instrukce byly nastaveny na používání vnitřních ukazatelů ověřovačem. Aktuální verze sady oprav místo toho definují nové instrukce BPF pro přístup k mapám. Ověřovač dokáže rozpoznat tyto pokyny přímo, takže uživatelský prostor na ně již nemusí odkazovat.
V sadě oprava verze 14 neexistuje žádný způsob, jak skutečně připojit programy BPF k zajímavým událostem po jejich načtení. Takové funkce mají být přidány, jakmile projdou základní funkce BPF revizemi a najdou si cestu do hlavního stromu. Tato chvíle se zdá být blízko; zdá se, že vývojáři, kteří se zapojili do API, jsou čím dál více spokojeni s tím, co mají. Začlenění do verze 3.18 se zdá být v tuto chvíli ambiciózní, ale 3.19 může být reálná možnost.
Aktualizace: Tato série byla 26. září přijata do stromu net-next, takže se téměř jistě objeví ve verzi 3.18.
Nástroje: Tisk bez diskuse
Tiskni
Sdílej: