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.
Aktuální předverze je (20. 11. 2007) 2.6.24-rc3, vydaná 16. listopadu. Kromě spousty oprav obsahuje podporu nových zařízení I/OAT a patch označující funkci jmenných prostorů PID jako "experimentální". Vizte krátký changelog se seznamem patchů nebo dlouhý se všemi podrobnostmi.
Od vydání -rc3 bylo zatím do hlavního git repozitáře začleněno jen několik oprav.
Aktuální vydání stabilní řady 2.6 je 2.6.23.8 ze 16. listopadu. Pár dní předtím Greg Kroah-Hartman poznamenal:
Ok, trochu jsem se v poslední době se -stable loudal a neuvědomil jsem si, jak moc pozadu už jsem. Všichni posílali patche, což je skvělé, ale máme teď před sebou obrovské vydání, kde by jich bylo 114.
Aby usnadnil kontrolu kódu, rozdělil patche do několika částí, z nichž každá vyšla jako samostatná stabilní verze. Takže máme:
2.6.23.9, které obsahuje 29 patchů, je teď připravováno.
Starší jádra: 2.6.22.13 vyšlo také 16. listopadu a obsahovalo pouze bezpečnostní opravy. 2.6.22.14, ve kterém je dalších pár desítek oprav, se teď připravuje.
Ještě starší jádra: 2.4.35.4 vyšlo 17. listopadu s několika opravami. 2.4.36-pre2 vyšlo s převážně těmi samými opravami.
A co se týče 802.11n, tak už jsem _takhle_ blízko k získání specifikací důležitého čipsetu, takže snad pro vás budeme mít zanedlouho práci. Teď kdyby si jen pospíšili ti právníci...
>-- Greg Kroah-Hartman stupňuje napětí.
Vždycky jsem si o HIGHMEM myslel, že je to prostě nepoužitelné. Je to OK pro rozšíření 2 - 4 GB (tj. HIGHMEM4G, ne 64G) a asi je to i na hraně použitelnosti při 4 -8 G, když si dáváte pozor.
Ale upřímně řečeno se odmítám starat o to, co se děje nad to. Pokud máte ve svém stroji 12 G (nebo, bůh chraň, ještě více) a neráčíte se obtěžovat upgradovat na 64bitový procesor, tak *mně* nestojí za to si kvůli tomu dělat vrásky.
Příprava uživatelských API je těžká. I když se rozhraní v době vytvoření zdá kompletní a dobře navržené, v budoucnu se často objeví nové požadavky, které může staré API jen těžko uspokojit. Unix například začal se systémovým voláním wait(). Přišly však komplexnější aplikace a začalo být potřeba čekat na konkrétní procesy, získat o končícím procesu více informací, čekat tak, aby nedošlo k bloku, atd. Takže kromě wait() teď máme ještě waitid(), waitpid() a wait4(). Protože staré verze systémových volání nemohou být (téměř) nikdy odstraněny, proměnlivé potřeby mají tendenci časem způsobovat přibývání nových volání.
Nedávno Ulrich Drepper požadoval, aby bylo možné přidávat příznaky k systémovým voláním, která vytvářejí popisovače souborů, ale nemají parametr pro příznaky. Příkladem mohou být třeba socket() a accept(). Chování popisovačů souborů, které byly vytvořeny pomocí těchto systémových volání, je možné upravit zpětně (pomocí fcntl()), ale vždycky tam bude chvilka, během které bude popisovač existovat, aniž by bylo nastaveno požadované chování. Jedná-li se například o "close on exec" [zavřít při spuštění] a zároveň běží vícevláknový program, mohlo by jedno vlákno spustit nový program pomocí exec() ještě předtím, než by jiné stihlo nastavit příznak "close on exec". Výsledkem takového souběhu by byl děravý popisovač souborů, který by mohl znamenat bezpečnostní problém. Jediný způsob, jak tomuto konkrétnímu souběhu zabránit, je přinutit jádro, aby popisovače souborů vytvářelo už s nastavenými požadovanými příznaky.
Tradičně by tento problém řešilo přidání nového systémového volání; mohlo by se například přidat 4parametrové volání socket4(), které by mělo požadovaný parametr flags. Takové řešení však není optimální; jak bylo řečeno, vede to k neustále narůstajícímu počtu systémových volání. Bylo by tedy fajn najít jiné řešení. Ulrich si myslí, že se mu povedlo právě to, když přidal jediné systémové volání (indirect()), které funguje tak, že přidává dodatečné parametry k existujícím voláním.
První implementaci sys_indirect() vytvořil Davide Libenzi v červenci. S tím kódem však Ulrich nebyl moc spokojen:
Davideova předchozí implementace je podle mého názoru mnohem komplikovanější, než by bylo potřeba. Tento kód je, jak se můžete přesvědčit, triviální. Minulý týden jsem o tomto přístupu mluvil s Linusem a na chvilku jsme spolu dokonce v něčem souhlasili.
Prototyp nového systémového volání vypadá takto:
int indirect(struct indirect_registers *regs, void *userparams, size_t paramslen, int flags);
Struktura regs obsahuje registry procesu, které se obyčejně používají v systémových voláních; jinými slovy číslo systémového volání a jeho (normální) parametry. Dodatečné parametry, které mají být systémovému volání předány, jsou v userparams a jejich délka je paramslen. Parametr flags není v současné době využit; je tam kvůli případnému budoucímu rozšíření, protože není možné rozšířit indirect() sebou samým.
Struktura task_struct byla rozšířena o nové pole:
union indirect_params indirect_params;
Tato union má obsahovat pole pro každý druh parametru, který by mohl být k systémovému volání přidáván; v Ulrichově kódu vypadá takto:
union indirect_params { struct { int flags; } file_flags; };
Může být tedy použita k předání parametru flags systémovým voláním, které se zabývají popisovači souborů.
Když je zavoláno indirect(), zkontroluje si, jestli je číslo požadovaného systémového volání na interním seznamu povolených. Pokud nebylo dané systémové volání označeno jako rozšiřitelné tímto způsobem, volání selže s EINVAL. V opačném případě jsou parametry překopírovány do struktury task_struct aktuálního procesu a volání je spuštěno běžným způsobem. Po dokončení volání je oblast indirect_params ve struktuře úlohy vynulována.
Jádro systémovému volání nedává nijak najevo, že bylo spuštěno prostřednictvím indirect(); jediným rozdílem v takovém případě je, že v indirect_params mohou být nenulové hodnoty. Takže mechanismus lze také chápat jako způsob, jak k systémovým voláním přidat parametry s výchozí hodnotou nula. Bez dalších úprav tedy není možné přidat systémovému volání parametr, u kterého by předání nuly mělo jiný význam než úplné vynechání parametru.
Pokud by se v budoucnu objevila potřeba přidat další parametr, může být velikost struktury indirect_params zvětšena. Za předpokladu, že si jádro udrží staré chování, když má nový parametr hodnotu nula, starší aplikace a knihovny budou fungovat jako dříve. Rozšířené systémové volání nepotřebuje (a nemůže) vědět, jestli je zvětšená struktura indirect_params používána, nebo ne.
Nabízí se také možnost využití tohoto mechanismu nad rámec rozšiřování systémových volání: vývojáři sysletů v tom vidí způsob, jak specifikovat asynchronní chování. Aktuální patche implementující syslety jsou v podstatě jen obalová vrstva kolem systémových voláních, která říká, že jde o asynchronní volání (a co dělat s výsledky). Přidávat systémovým voláním dvě nepřímé vrstvy se nezdá jako optimální řešení, takže někteří vývojáři projevili zájem přidat místo toho informace o sysletech do indirect(). To je jeden ze zamýšlených účelů zatím nepoužívaného parametru flags.
Samozřejmě se nečeká, že by aplikace volaly indirect() přímo. Daleko pravděpodobnější se zdá, že by indirect() bylo zavrtáno hluboko v C knihovně, která by pro aplikace exportovala přímočařejší rozhraní.
Zatímco některým vývojářům (včetně Linuse, zjevně) se patch líbí, jiní moc nadšení nejsou. David Miller si nebral servítky: Řekl bych, že tohle nepřímé systémové volání je nejošklivější rozhraní, které jsem kdy viděl navrhované pro jádro. Na H. Peter Anvina to také dojem neudělalo:
Myslím, že je to děsná berlička. Zase další multiplexor, kterým se v jádře tolik snažíme vyhýbat. A aby to bylo ještě horší, tak je to multiplexor, který vytváří zase další jednoúčelovou konvenci pro volání, zatímco bychom se měli snažit jaderné volací konvence co nejvíce sjednotit.
Nebylo by tedy nijak překvapivé, kdyby se před začleněním do jádra toto rozhraní ještě vyvíjelo - je to nové a trochu zrádné API, kterému by diskuze jen prospěla. Protože však za touto prací stojí reálná potřeba, je pravděpodobné, že se indirect() nakonec v nějaké podobě v hlavním jádře objeví.
Autoři: Pavel Emeljanov a Kir Kolyškin [Pavel Emelyanov a Kir Kolyshkin].
Jednou z nových vlastností v jádře 2.6.24 je podpora jmenných prostorů PID, kterou vyvinul tým OpenVZ s pomocí IBM. Jmenný prostor PID umožňuje vytvářet sady úloh, z nichž každá vypadá - z pohledu ID procesů - jako samostatný systém. Jinými slovy, v různých jmenných prostorech můžete mít stejná ID.
Tato funkce je základním předpokladem pro migraci kontejnerů mezi hostiteli; když máme jmenný prostor, můžeme jej přesunout na jiného hostitele, ale ponechat hodnoty PID -- a to je nutné, protože úloze by se nemělo měnit PID. Bez této funkce by migrace s největší pravděpodobností selhala, jelikož na cílovém uzlu by mohly existovat procesy se stejnými ID, což by způsobilo konflikty při adresování úloh prostřednictvím jejich ID.
Jmenné prostory PID jsou hierarchické; při vytvoření nového jmenného prostoru PID uvidí všechny procesy v aktuálním jmenném prostoru úlohy v tom novém (tj. budou schopné je adresovat pomocí PID). Nicméně, úlohy v novém jmenném prostoru neuvidí ty v aktuálním. To znamená, že od té chvíle má každý proces více než jedno PID -- jedno pro každý jmenný prostor.
Nový jmenný prostor lze vytvořit zavoláním systémového volání clone(2)
s nastaveným příznakem CLONE_NEWPID
. Pak bývá vhodné změnit kořenový adresář a připojit novou instanci /proc
, aby fungovaly běžné utility, např. ps
. Vzhledem k tomu, že předek zná PID svého potomka, je pro čekání na ukončení možné použít běžným způsobem wait()
.
První úloha v novém jmenném prostoru bude mít PID 1
. Bude to tedy jeho init a všechny osiřelé úlohy se stanou jejími potomky. Na rozdíl od samostatných strojů může tento init skončit, což znamená ukončení celého jmenného prostoru.
Protože teď máme izolované skupiny úloh, měli bychom zařídit, aby proc
ukazoval pouze ty PID, které jsou pro danou úlohu viditelné. Abychom toho dosáhli, musí být procfs
připojen vícekrát -- jednou pro každý jmenný prostor. Pak budou PID zobrazené v připojené instanci právě z toho jmenného prostoru, kde proběhlo připojení.
Například pokud uživatel vytvoří nový adresář proc_2
, založí nový jmenný prostor PID a připojí tam procfs
, uvidí PID, jak vypadají v rámci nového jmenného prostoru. Bude tam PID číslo 1
, což je init daného jmenného prostoru, a všechny další PID, které mohou být stejné jako PID v aktuálním jmenném prostoru, ale přitom mohou odkazovat na jinou úlohu.
Žádné další změny v uživatelském API nejsou potřeba. Úlohy mohou i nadále získávat své PID, PGID atd. s pomocí známých systémových volání. Mohou také pracovat se sezeními a skupinami. Úlohy mohou vytvářet vlákna a pracovat s futexy.
Všechna PID, které může úloha mít, jsou popsána v struct pid
. Tato struktura obsahuje hodnotu ID, seznam úloh, které mají toto ID, referenční čítač a hashovanou položku seznamu, která je uložena v hashované tabulce pro rychlejší vyhledávání.
Pár slov o seznamech úloh. Každá úloha má v podstatě tři PID: ID procesu (PID), ID skupiny procesů (PGID) a ID sezení (SID). PGID a SID mohou být úlohami sdílené. Pokud například dvě nebo více úloh náleží do stejné skupiny, pak ID skupiny odkazuje na více než jednu úlohu.
Se jmennými prostory PID je tato struktura pružná. Každé PID může mít několik hodnot, přičemž každá bude platit v jiném jmenném prostoru. Takže úloha může mít PID 1024 v jednom jmenném prostoru a 256 v jiném. Struktura struct pid
je tedy změněna.
Takhle vypadala struct pid
před zavedením jmenných prostorů PID:
struct pid { atomic_t count; /* referenční čítač */ int nr; /* hodnota pid */ struct hlist_node pid_chain; /* hash */ struct hlist_head tasks[PIDTYPE_MAX]; /* seznam úloh */ struct rcu_head rcu; /* RCU pomocník */ };
A takhle vypadá teď:
struct upid { int nr; /* přesunuto ze struct pid */ struct pid_namespace *ns; /* jmenný prostor, ve kterém je tato hodnota vidět */ struct hlist_node pid_chain; /* přesunuto ze struct pid */ }; struct pid { atomic_t count; struct hlist_head tasks[PIDTYPE_MAX]; struct rcu_head rcu; int level; /* počet upid */ struct upid numbers[0]; };
Jak vidíte, struct upid
teď reprezentuje hodnotu PID. Pro převod struct pid
na PID a naopak můžete použít sadu pomocníků, např. task_pid_nr()
, pid_nr_ns()
,
find_task_by_vpid()
atd.
Všechna tato volání mají v názvech informaci:
..._nr()
pid_nr(pid)
vám řekne globální PID dané struct pid
. Hodí se pouze v případě, že hodnota PID neopustí jádro. Například pokud nějaký kód potřebuje uložit PID a pak podle něj úlohu najít. V tomto případě je však lepší uložit přímý ukazatel na struct pid
, protože globální PID budou používány pouze v jaderném logu...._vnr()
task_pid_vnr(tsk)
vám řekne PID úlohy, jak jej daná úloha vidí (s sys_getpid()
). Nezapomeňte, že pokud pracujete v jiném jmenném prostoru, bude vám to nejspíš k ničemu. Proto se používají při práci s aktuální úlohou, protože všechny úlohy vždy vidí své virtuální PID...._nr_ns()
task_pid_nr_ns(tsk, current->nsproxy->pid_ns)
, což vrátí číslo, a pak úlohu najdete pomocí find_task_by_pid_ns(pid, current->nsproxy->pid_ns)
. Používají se v systémových voláních, když je zdrojem PID uživatelský prostor. V takovém případě může jedna úloha odkazovat na jinou v jiném jmenném prostoru.Popisované rozhraní bylo začleněno do jádra 2.6.24. Je však označeno jako "experimentální", aby jej distributoři nenasazovali, dokud se nevyřeší zbývající problémy. V období do odstranění označení "experimentální" se však v tomto API neočekávají žádné velké změny.
Nástroje: Tisk bez diskuse
Tiskni
Sdílej: