Portál AbcLinuxu, 1. května 2025 06:59
Všem uživatelům Ubuntu 9.04 gratulujeme
Dekuji. Na Ext3 si nemuzu stezovat.
Ext4 si můžeš v 9.04 při instalaci zvolit, nikoliv musíš...
Na rozdíl od jiných pofidérních distribucí bude v Ubuntu jako defaultní volba ext3 ještě víc, než půl roku... takže kde je problém? :)
Pomineme-li různé hard-core distra typu Gentoo nebo Arch, vsadíme se, že Ubuntu bude (hned po Fedoře, u které se to dá tradičně čekat) první, které Ext4 nasadí jako default?
S tim FF je to chyba FF, taky se mi to stalo a to bez rebootu.
Ve zpravicce se rika, ze dojde ke ztrate dat, ktere se prave upravuji - myslis, ze pri bootu jadra se taky pousti firefox? :D
Jak si to vůbec můžou dovolit nechat být a neopravit to v 2.6.29.
Vis, ani opravy nemusi byt vzdy trivialni a je nutne je poradne otestovat (u FS obzvlast) - neni pak nic horsiho nez oprava, ktera problem resi jen z casti nebo jej transformuje do jine chyby.
obsahuje bug, kvůli kterému můžete přijít o důležitá data.Pravda za predpokladu ze nejake dolezite data tam mate
Ano, ale priznajme si: ma sa to stat v Microsofte, aj ked len par dni po uvedeni, ci pred uvedenim a mat od nich odpoved, ze to zafixuju az v SP1, tak to by sa vzniesla kritika typu "MS ako vzdy: nekvalitny softver a ani opravit chybu nedokazu..."
Ale v Ubuntu není jako hlavní FS EXT 4, ne?? Ubunu jse, naposled používal asi ped půl rokem a myslim si, že když se objeví oprava tak to zahrnou do aktualizací!! ;)
Samozrejme. Len clovek by teraz cakal, ze aj na linux sa znesie vlna kritiky. Zatial som si tu vsak precital komentare v zmysle "fajn, ja ubuntu nepouzivam!", "ja aj tak pouzivam ext3" atd. To len kvoli objektivite, ako dokazeme Microsoft pospinit kde sa len da ("nikdy nerobil kvalitny kod", "nie su schopni vyriesit problem" atd), pricom ak ide o linux tak sa vyhybame podobnemu konstatovaniu ako mozeme. Fakt si neviem predstavit, co by sa pisalo, keby sa zistilo, ze produkt Microsoftu moze vymazat dolezite data na disku.
Pozrite sa na to inak. Ak by to takto Microsoft komentoval problem, tiez ho budete ospravedlnovat? Este raz: je tu problem, ktory treba vyriesit, nevyriesi ho uzivatel (BFU), chyba je na strane programatorov/vyvojarov. Nikoho nezaujima, tak ako v pripade podobnych kauz s Microsoftom, ze ta chyba vobec nie je v EXT4, ale v zlom spravani sa aplikacii. Preco jedno ospravedlnujete a druheho by ste nakopali do zadku (poprosim, nevztahovat na seba)?
Tak pokud nikoho nezaujima, tak ako v pripade podobnych kauz s Microsoftom, ze ta chyba vobec nie je v EXT4, tak to stejně můžeme hodit na Microsoft ne? Prostě buďto jste schopen rozlišit v čem je problém a kdo by měl být zodpovědný za jeho řešení a nebo nejste a pak můžeme házet špínu na MS že to je jeho vina
tak ono to ext4 neni zatim vydavano za uplne stable a krom toho je v linuxu jaksi vetsi vyber z moznych filesystemu, nez jen z ntfs, jak tomu je u windows, ze
No lenze ten problem sa neprejavuje len pri ext4, vsakze... Naviac ext4 sa uz ma dodavat s najnovsim kernelom, takze Vasa poznamka nie je celkom na mieste. Inak teraz ste predviedli dalsi priklad, ako sa da vyhnut kritike. Casto sa stava, ze niekto pise, ze ma problem. Diskusia skonci tym, aby nepouzival distribuciu A, lebo v distribucii B to funguje. Ked ma niekto iny problem s distribuciou B, staci mu poradit distribuciu A.
zkus si napred najit duvody, proc se tam ext4 dostalo
Ked si ich najdem, vysvetli to, preco mate nerovnaky pristup k chybam od MS a od linuxu?
Ano, tyhle linky jsem chtěl taky citovat.
A především: tohle není jednoznačně bug v kernelu. Jedná se spíš o bug v aplikacích, které nevhodným způsobem pracují se svými konfiguračními soubory (neustále je mažou a znovu vytvářejí), a díky tomu jsou choulostivé na opožděný zápis - což je jinak velice bohulibá vlastnost VM a FS, kvůli průchodnosti diskového subsystému a třeba kvůli spotřebě notebooků. Označovat toto za chybu v kernelu je podle mého poněkud přehnané. Jedná se o nové chování, které odhalilo, že starý císař (aplikace) je nahý. Ostatně i zmiňované "patche" do kernelu jsou ve skutečnosti spíš kernel-space workaroundy, které se na bázi jakési heuristiky snaží odhalit provinilé aplikace (problematické chování) a provést jakási protiopatření (dané soubory flushovat častěji, než by podle POSIXu bylo potřeba).
Je docela nešťastné, že provinilými aplikacemi jsou zrovna desktopová prostředí. Takže kvůli ztrátě pár souborů při softwarovém zatuhnutí systému se člověku rozsype desktop...
No, já osobně o tom vím kulový, ale z mého pohledu nevidím nic špatného na mazání a vytváření souborů. Podle mě je tento přístup mnohem efektivnější, než v aplikacích řešit nějaké mergeování dat pomocí nějakých šílených seeků. To, že se žurnál nedokáže vyrovnat se smazaným a znovu vytvořeným souborem, je podle mého názoru chyba žurnálu — nikoli chyba aplikace. Navíc, v životě jsem neslyšel o nějakých limitech na počet přepsání souborů za jednotku času.
Samozřejmě netvrdím, že když si pustím textový editor na pozadí a stokrát ve vteřině mi bude přepisovat nějaký soubory na disku stejným obsahem, že je to v pořádku.
Dokud nebude file systém transakční, pak mají uživatelé linků smůlu.
Jen podotýkám, že sám jsem tohoto chování zneužil při integraci systémů v jedné z největších Českých bank, a dosud si nikdo neztěžoval. (To jen pro úplnost).
Takové aplikace mám nejraději.
Já vím.
Programátor se nechce obtěžovat s tím, aby napsal pořádně zápis konfiguračního souboru, tak rozhodne, že uživatel nepotřebuje rozšířené atributy, linky, přístupová práva k souborům, vrstvené souborové systémy -- prostě cokoli, co jde připojit k node souboru a co daná aplikace nezná a nedokáže to zduplikovat do nového souboru.
Já o žádném konfiguračním souboru nemluvil. Tak mi necpi něco do huby. Stačil mi oběd.
Tímhle stylem se programuje ve Windows, a pokud se má tenhle styl zanést do OSS, pak děkuji, nechci.
Však já ti nic nenutím.
Jen podotýkám, že sám jsem tohoto chování zneužil při integraci systémů v jedné z největších Českých bank, ...Které banky mají slovo Česká v názvu?
Příště vám nic neřeknu. Když máte možnost se dozvédět něco, co vám pomůže, tak se smějete. Příště se smějte se své hlouposti a možná hlavně neznalosti.
Nic nepsat proti pravopisným chybám pomáhá dokonale, to je pravda.
Víš, co je nejdokonalejší? Že tenhle portál je ze zahraničí stráááááášněééééé pomaléééj. A když to chci mahlásit jako bugu, tak mi to píše, že něco není košér s mým heslem. Tak já teda nevim…
Nicmene prepisovani souboru na miste je operace mnohem rizikovejsi. Zatimco vytvoreni souboru vedle a nasledne prejmenovani jde snadno udelat tak, aby system byl stale konzistentni jak pro pouzivani tak pri vypadku, u prepsani dat na miste bys kvuli tomu musel delat znacnou magii (implementovat vlastni jurnal?).
vim
soubory přepisuje, a přesto obnovu po pádu zvládá velice dobře. Takže přepsání souboru na místě udělat bezpečně jde. Dokonce tím získáte ochranu nejen proti tvrdému pádu systému, ale můžete konfiguraci obnovit i při chybě uživatele (což je daleko častější případ) -- pokud tedy záložní soubor nemažete.
Na vytvareni a mazani souboru neni nic spatne. Spatne je, pokud aplikace pouziva POSIX rozhrani a pritom spoleha na to, ze se soubor zapise na disk pri volani close()
.
"Vsechny nove filesystemy" (a to vcetne ext3) data, ktera maji byt zapsana na disk, interne cachuji. Pokud by se tak nechovaly, dostanete z beznych disku maximalne 100 operaci za sekundu. Shodou okolnosti ext3 takova data na disk zapisuje v defaultnim nastaveni kazdych 5 sekund, a proto je riziko "ztraty dat" pomerne male.
POSIX rika, ze pokud je potreba mit data opravdu dostupna na disku, je nutne zavolat fsync()
ci jeho alternativy. Pokud si aplikace mysli, ze staci close()
, je to problem jeji a nikoli kernelu. Prece kdyz pouzivam nejake API, tak si ho musim precit a posoudit, jak se chova v okrajovych pripadech.
Znovu upozorňuji, že daný problém se mě netýká a nezajímá mě.
POSIX rika, ze pokud je potreba mit data opravdu dostupna na disku, je nutne zavolat
fsync()
ci jeho alternativy. Pokud si aplikace mysli, ze staciclose()
, je to problem jeji a nikoli kernelu.
Když vezmu vpotaz situaci, že korektně používám POSIX… Korektně uložím (konfigurační) soubor a zavolám close()
. Pak systém lehne. Nevím, ale měl jsem doteď za to, že žurnál tu je právě od toho, aby zajistil konzistentní file systém. Takže: buď ať je na disku původní verze, nebo nová.
Toto nemá nic společného s tím, zda někdo dokumentaci čte nebo ne. Toto je prostě závažná chyba, když se po zavolání close()
(nebo před ním) filesystem rozsype.
Prece kdyz pouzivam nejake API, tak si ho musim precit a posoudit, jak se chova v okrajovych pripadech.
A je někde v dokumentaci napsáno, že když nezavolám sync()
byť jsem korektně zavolal close()
, že se má filesystem s žurnálem rozesrat?
A je někde v dokumentaci napsáno, že když nezavolám sync()
byť jsem korektně zavolal close()
, že se má filesystem s žurnálem rozesrat?
A kde berete tu informaci, že se fs rozsype? Pokud tomu dobře rozumím, tak pouze přijdete o data souboru. Ale jejich korektnost vám žádný (trochu zevšeobecňuju) současný žurnálovací fs nezajišťuje, ty zajišťují pouze konzistenci metadat.
Měli by to zrychlit
Žurnál je z hlediska POSIXu irelevantní. POSIX říká, že po close(2) data na disku uložena být nemusí. Tohle je vlastnost, ne chyba.
Jiná věc je, že žurnál v běžném nastavení je kompromis mezi výkonem a spolehlivostí a neřeší spolehlivost dat – řeší jen metadata.
No já jsem z toho jelen. Už jsem se v tom ztratil. Takže — všichni máte pravdu a já jsem letadlo.
A je někde v dokumentaci napsáno, že když nezavolámTo jste tak liny precist si man 2 close? Tam je uplne jasne napsano, ze zavolani close neznamena, ze se zapsala vsechna data a ze pokud tu jistotu chcete, mate volat fsync().sync()
byť jsem korektně zavolalclose()
, že se má filesystem s žurnálem rozesrat?
To jste tak liny precist si man 2 close?
Líný nejsem. Jen šetřím svůj čas. Informace z odkazované manuálové stránky jsou mi úplně k ničemu.
Jedná se spíš o bug v aplikacích, které nevhodným způsobem pracují se svými konfiguračními soubory (neustále je mažou a znovu vytvářejí)To je naprosto standardní feature (nikoli bug). Pokud se to dělá přímým zápisem do souboru, nelze zajistit konzistenci. Zamkne-li se soubor (advisory locking; s mandatory nelze počítat), je po dobu úprav blokován. Kdežto rename() je atomická operace, takže když se vytvoří nový soubor a po dokončení zápisu se přejmenuje na standardní název, je to bezpečné a nezdržuje to v práci. Neškodilo by samozřejmě flushnout ten soubor na disk, je-li důležitý, aby netrčel dlouho jen v paměti.
3.a) open and read file ~/.kde/foo/bar/baz 3.b) fd = open("~/.kde/foo/bar/baz.new", O_WRONLY|O_TRUNC|O_CREAT) 3.c) write(fd, buf-of-new-contents-of-file, size-of-new-contents-of-file) 3.d) fsync(fd) --- and check the error return from the fsync 3.e) close(fd) 3.f) rename("~/.kde/foo/bar/baz", "~/.kde/foo/bar/baz~") --- this is optional 3.g) rename("~/.kde/foo/bar/baz.new", "~/.kde/foo/bar/baz")...celkem sabotuje hardlinky. Stejně všude dělám symlinky.
zpráva by měla mít název "BRFS, EXT4 a XFS obsahují chybu..."alebo vrstva pre komunikaciu s FS v linuxovom kerneli ma chybu...
no a ona ta chyba ani neni v souborovych systemech. Nadpis tehle zpravy je strasny a tendencne napsany. Podle zpravy se to tyka pouze nekterych aplikaci, a je to spise problem jejich nez souborovych systemu, ale prislo se na to az ted, kdyz FS pouzivaji zpozdenou alokaci.
Za moderni system povazuji ZFS nebo HAMMER a tam tohle opravdu nehrozi.
no kdyz myslite ;)
Jů, tenhle bug mě trápil od minulého roku čím dál tím víc... Jsem rád, že se o tom ví, i když ten čas opravy by teda mohl být rychlejší...
A hlásil jste to?
Problem neni ani tak v close(), jako spis v negarantovani relativniho usporadani ruznych operaci provedenych jednim procesem. Garantovani zapisu na disk po close() by znacne zpomalilo napr. kopirovani mnoha malych souboru. Stejne tak fsync() mezi jednotlivymi operacemi je znacny overkill, ale POSIX asi nejakou jemnejsi barierovou funkci (ktera by rikala, ze operace to teto bariere se neprovedou pred dokoncenim operaci pred tou barierou) nema.
close()
chova prave takto by programator vedet mel. Ale na druhou stranu je tady videt, jak jednoduche je „ustrelit si nohu“. Az to neni hezke :)
A successful close does not guarantee that the data has been successfully saved to disk, as the kernel defers writes. It is not common for a file system to flush the buffers when the stream is closed. If you need to be sure that the data is physically stored use fsync(2).
Integrita dat je téměř vždy důležitější než výkon a "ustřelit si nohu" by mělo stát vývojáře větší úsilí než bezpečné chování. Situace, kdy vám záleží na výkonu a ne na datech, jsou speciální případy a mělo by pro ně tedy být speciální volání.Tento předpoklad má řadu úskalí. Zaprvé ta výkonová penalizace je v praxi tak brutální, že na výkonu záleží u drtivé většiny dat. Kromě toho, funkce close() je součástí POSIXu a změnit její chování by znamenalo ztrátu kompatibility.
Dále evidentně chybí funkce typu "bezpečně ulož všechny uzavřené soubory tohoto procesu", např. po kopírování.To by znamenalo udržovat si po libovolně dlouhou dobu seznam všech zavřených souborů procesu a navíc hlídat, co se s každým takovým souborem děje dále. Tedy jestli s ním například nepracují jiné procesy, co s ním dělají atd. Pokud může do téhož souboru zapisovat více procesů současně, jsou jakékoli požadavky na bezpečné uložení bezpředmětné, pokud se týkají určitého procesu. Celé je to nesmysl - buď se bezpečně ukládá jeden konkrétní soubor (ve stavu, v jakém aktuálně je), anebo se bezpečně uloží úplně všechno (sync()).
Aplikační programátoři jsou většinou nezkušení amatéři, kteří nečtou dokumentaci, snaží se věci udělat jednoduše.Ano, tak jednoduše, že například vůbec netestují návratovou hodnotu tohoto volání (i mnohých jiných - ale u close() je úplný mor). Přitom close() má vždy nejméně 4 chybové kódy. Může se například stát, že dojde místo na disku - uživatel se pak vůbec nedozví, že funkce close() selhala a on přišel o data.
Tvrzení: "A to ze se funkce close() chova prave takto by programator vedet mel." je hloupá výmluva programátora, který funkci close() špatně navrhl (nebo si na to špatné chování zvykl) a teď se výsledný průšvih snaží hodit na nezkušené kolegy.Funkce close() v současné podobě existuje desítky let, je součástí řady standardů a programátoři jsou zvyklí ji používat. Není důvod ji měnit (a tím zásadním způsobem nabourat kompatibilitu) jen proto, že si někdo nepřečte, jak funkce pracuje.
> Kromě toho, funkce close() je součástí POSIXu a změnit její chování by znamenalo ztrátu kompatibility.
Zrovna zmenit chovani close() tak, ze by uspal dokud se data nezapisou, by ztratu kompatibility neznamenalo, nebot POSIX rika, ze to negarantuje, nikoliv, ze se tak chovat nesmi. I tak by to ale nebyla rozumna zmena.
Takze by to znamenalo ztratu kompatibility aplikaci, nikoliv ztratu kompatibility Linuxu.
A programatori i tak casto nepisou kompatibilni aplikace a pouzivaji ruzna GNU ci Linux specifika.
Zaprvé ta výkonová penalizace je v praxi tak brutální, že na výkonu záleží u drtivé většiny dat.Výkonová penalizace je snadno odhalitelná a napravitelná - pokud na to API poskytne prostředky.
Kromě toho, funkce close() je součástí POSIXu a změnit její chování by znamenalo ztrátu kompatibility.Neznamenalo. Funkce close() nezaručuje uložení dat, ale není nikde psáno, že to dělat nesmí.
Ne. To by znamenalo přidat do seznamu všech neuložených souborů (který už beztak existuje) navíc čísla procesů (nebo spíš proccess group), které ho měly otevřený a to pouze do doby, kdy dojde k uložení těch dat.Dále evidentně chybí funkce typu "bezpečně ulož všechny uzavřené soubory tohoto procesu", např. po kopírování.
To by znamenalo udržovat si po libovolně dlouhou dobu seznam všech zavřených souborů procesu a navíc hlídat, co se s každým takovým souborem děje dále. Tedy jestli s ním například nepracují jiné procesy, co s ním dělají atd.
Pokud může do téhož souboru zapisovat více procesů současně, jsou jakékoli požadavky na bezpečné uložení bezpředmětné, pokud se týkají určitého procesu.Otevření souboru někým jiným přece přeci z principu nijak neovlivňuje bezpečnost dat, která zapíšete vy.
Celé je to nesmysl - buď se bezpečně ukládá jeden konkrétní soubor (ve stavu, v jakém aktuálně je), anebo se bezpečně uloží úplně všechno (sync()).Naopak, nesmysl je, že aplikace s právy uživatele nobody by měla při syncování svých dat vyvolat sync cizích procesů. Funkce sync() podle normy POSIX signalizuje operačnímu systému, že má data uložit. Na na jejich skutečné uložení nemusí čekat, úspěšné uložení negarantuje a případnou chybu nijak neoznamuje. Dokumentaci k sync() jste evidentně nečetl, což je podle vaší logiky pouze a jen vaše chyba. Já tvrdím, že je to je nedostatek API, na který jste právě naletěl.
Ano, netestování návratových kódů je chyba programátora, o tom není pochyb. Když jste to nakousl - položím záludnou otázku: Pokud close() vrátí chybu, zůstane deskriptor souboru otevřený, nebo ne?Aplikační programátoři jsou většinou nezkušení amatéři, kteří nečtou dokumentaci, snaží se věci udělat jednoduše.
Ano, tak jednoduše, že například vůbec netestují návratovou hodnotu tohoto volání (i mnohých jiných - ale u close() je úplný mor). Přitom close() má vždy nejméně 4 chybové kódy. Může se například stát, že dojde místo na disku - uživatel se pak vůbec nedozví, že funkce close() selhala a on přišel o data.
Ano, funkci close() kdysi kdosi špatně navrhl, nějakým nedopatřením se stala součástí řady standardů a prudí neopatrné programátory už desítky let. To bohužel platí i o spoustě jiných funkcí. Trvám na tom, že je to vada prapůvodního návrhu, který neměl být nikdy standardizován. Dále tvrdím, že popis v dokumentaci není dostatečným řešením tohoto problému, což potvrzují praktické zkušenosti. A stojím si za tím, že přes standardizaci měly být tyto vadné funkce prohlášeny za zastaralé a nahrazeny novými a protože se to zatím nestalo, mělo by se to udělat co nejdřív.Tvrzení: "A to ze se funkce close() chova prave takto by programator vedet mel." je hloupá výmluva programátora, který funkci close() špatně navrhl (nebo si na to špatné chování zvykl) a teď se výsledný průšvih snaží hodit na nezkušené kolegy.
Funkce close() v současné podobě existuje desítky let, je součástí řady standardů a programátoři jsou zvyklí ji používat. Není důvod ji měnit (a tím zásadním způsobem nabourat kompatibilitu) jen proto, že si někdo nepřečte, jak funkce pracuje.
Výkonová penalizace je snadno odhalitelná a napravitelná - pokud na to API poskytne prostředky.Nicméně při tvorbě aplikace je těžko predikovatelná, protože to programátor nemůže otestovat na všech možných systémech, kde to poběží (různé síťové filesystémy, pomalé SSD apod.).
Ne. To by znamenalo přidat do seznamu všech neuložených souborů (který už beztak existuje) navíc čísla procesů (nebo spíš proccess group), které ho měly otevřený a to pouze do doby, kdy dojde k uložení těch dat.Problém je v tom, že ten seznam může být velice dlouhý, protože nikde není řečeno, jaká bude perioda automatického uložení (standardně 30 s, ale u notebooku si to někdo může dát třeba na 10 minut). Pokud se v něm bude vyhledávat, pak to znamená ještě nad nimi vytvořit nějaký strom apod., protože v systému mohou být mraky neuložených souborů a procházet je sekvenčně by bylo hodně zdlouhavé.
Naopak, nesmysl je, že aplikace s právy uživatele nobody by měla při syncování svých dat vyvolat sync cizích procesů. Funkce sync() podle normy POSIX signalizuje operačnímu systému, že má data uložit. Na na jejich skutečné uložení nemusí čekat, úspěšné uložení negarantuje a případnou chybu nijak neoznamuje. Dokumentaci k sync() jste evidentně nečetl, což je podle vaší logiky pouze a jen vaše chyba. Já tvrdím, že je to je nedostatek API, na který jste právě naletěl.Ohledně těch práv je otázka, zda současný stav vadí. Jinak dokumentaci k sync() jsem opravdu nečetl (až teď), protože jsem toto volání nikdy nepotřeboval. Když už jsem měl potřebu vynucovat uložení na médium (které stejně není úplně zaručené - to by ho museli zaručovat i všichni výrobci úložného HW), používal jsem fsync().
Když jste to nakousl - položím záludnou otázku: Pokud close() vrátí chybu, zůstane deskriptor souboru otevřený, nebo ne?Záleží na tom, jakou chybu vrátí. Pokud je to EBADF (tj. neplatný deskriptor), pak deskriptor zcela logicky zůstává otevřený. Je-li to jiná chyba, pak není stav deskriptoru specifikován - ani v POSIXu, ani v dokumentaci Linuxu. Faktem je, že aktuální implementace deskriptor zneplatní (odstraní ho z tabulky deskriptorů a příslušnému otevřenému souboru dekrementuje počitadlo referencí). Na to se ale pochopitelně nelze ohlížet, rozhodující je to, co je napsáno v dokumentaci.
Ano, funkci close() kdysi kdosi špatně navrhl, nějakým nedopatřením se stala součástí řady standardů a prudí neopatrné programátory už desítky let. To bohužel platí i o spoustě jiných funkcí. Trvám na tom, že je to vada prapůvodního návrhu, který neměl být nikdy standardizován. Dále tvrdím, že popis v dokumentaci není dostatečným řešením tohoto problému, což potvrzují praktické zkušenosti. A stojím si za tím, že přes standardizaci měly být tyto vadné funkce prohlášeny za zastaralé a nahrazeny novými a protože se to zatím nestalo, mělo by se to udělat co nejdřív.Ve standardech je toho špatného spousta a zasloužilo by to udělat lépe. Ale vždy je lepší postupovat tak, že se vytvoří něco nového, na to se u nové tvorby přechází a to staré se nechává dožívat v současné podobě dožít (jen se to označí "deprecated" apod.). U close() zatím nebyly žádné velké snahy ho nahradit, jiné věci jsou mnohem palčivější.
Programátor přeci může říci, jestli mu na daných datech záleží, nebo ne. Jak se s tím OS popere je jeho věc. V nejhorším případě program poběží pomalu, ale bude dělat to, co autor očekával a data nebudou mizet.Výkonová penalizace je snadno odhalitelná a napravitelná - pokud na to API poskytne prostředky.
Nicméně při tvorbě aplikace je těžko predikovatelná, protože to programátor nemůže otestovat na všech možných systémech, kde to poběží (různé síťové filesystémy, pomalé SSD apod.).
Přístup typu "aby se to dobře implementovalo" je zdrojem právě takových potíží, které od začátku řešíme. API je potřeba navrhovat tak, aby se co nejlépe používalo a interní implementaci tomu podřídit. Je to těžší, ale jde to a výsledek stojí za to. (Mluvím z osobní zkušenosti.)Ne. To by znamenalo přidat do seznamu všech neuložených souborů ... a to pouze do doby, kdy dojde k uložení těch dat.
Problém je v tom, že ... v systému mohou být mraky neuložených souborů a procházet je sekvenčně by bylo hodně zdlouhavé.
Když už jsem měl potřebu vynucovat uložení na médium (které stejně není úplně zaručené - to by ho museli zaručovat i všichni výrobci úložného HW), používal jsem fsync().Autoři postižených aplikací zřejmě tuto potřebu neměli. Jednoduše nepočítali s tím, že se systém může podělat a data z cache neuložit. Na výsledných potížích tak mají podíl všichni - autor původního návrhu close(), autoři filesystémů i programátoři problémových aplikací. Každý v této řadě dal přednost výkonu před bezpečností uložení. Svádět celou vinu jen na jednoho z nich je nefér.
Přístup typu "aby se to dobře implementovalo" je zdrojem právě takových potíží, které od začátku řešíme. API je potřeba navrhovat tak, aby se co nejlépe používalo a interní implementaci tomu podřídit. Je to těžší, ale jde to a výsledek stojí za to. (Mluvím z osobní zkušenosti.)Jenže v okamžiku, kdy se navrhuje API operačního systému, je potřeba uvažovat také to, jak často bude určité volání potřeba a zda stejný účel neplní jiné volání nebo kombinace volání. Po takovém volání, o kterém se tu bavíme, zjevně nebyla příliš velká poptávka, protože zatím nikdo vážně nenavrhl jeho přidání do jádra. Teprve v tomto okamžiku by se začalo analyzovat, co by znamenala jeho implementace - zatím jsme se ale do této fáze ještě vůbec nedostali. Pokud by se volání přidalo "jen pro jistotu" a implementoval se k němu složitý aparát, jen by v jádře přibyla hromada zbytečného kód, který by zabíral místo a požíral výkon. Proto zmiňuji tu implementaci - ne proto, že by bylo složité to implementovat.
Autoři postižených aplikací zřejmě tuto potřebu neměli. Jednoduše nepočítali s tím, že se systém může podělat a data z cache neuložit.Já jsem měl tuto potřebu také jen velmi zřídka. Také v aplikacích nepočítám s tím, že se něco podělá tak, že to bude nad rámec běžných chyb detekovaných systémem. Jinak bych totiž musel uvažovat nejen možnost ztráty nezapsaných dat, ale i poškození disku, poškození dat přenášených po síti (nad rámec toho, co dokáže transparentně řešit TCP) a mnoho dalšího.
Jenže v okamžiku, kdy se navrhuje API operačního systému, je potřeba uvažovat také to, jak často bude určité volání potřeba a zda stejný účel neplní jiné volání nebo kombinace volání. Po takovém volání, o kterém se tu bavíme, zjevně nebyla příliš velká poptávka, protože zatím nikdo vážně nenavrhl jeho přidání do jádra.Bezpečné uložení souboru je potřeba vždy. Poptávka nebyla, protože potíže nastávaly jen vyjímečně a nikomu nestálo za námahu to řešit.
No vidíte, uvažujete stejně jako já a i zřejmě jako autoři těch "špatně napsaných" aplikací. Všichni používáme funkci close() ne-úplně-správně, přestože víme, jak pracuje. Občas se to nějakému nešťastníkovi vymstí. Ukazovat na něj prstem a křičet: "on si nepřečetl dokumentaci a může si za to sám" je trošku nefér, nemyslíte?Autoři postižených aplikací zřejmě tuto potřebu neměli. Jednoduše nepočítali s tím, že se systém může podělat a data z cache neuložit.
Já jsem měl tuto potřebu také jen velmi zřídka. Také v aplikacích nepočítám s tím, že se něco podělá tak, že to bude nad rámec běžných chyb detekovaných systémem. Jinak bych totiž musel uvažovat nejen možnost ztráty nezapsaných dat, ale i poškození disku, poškození dat přenášených po síti (nad rámec toho, co dokáže transparentně řešit TCP) a mnoho dalšího.
Bezpečné uložení souboru je potřeba vždy. Poptávka nebyla, protože potíže nastávaly jen vyjímečně a nikomu nestálo za námahu to řešit."Bezpečné" (absolutně) to nebude nikdy. Vždycky to bude jen bezpečnější nebo méně bezpečné.
No vidíte, uvažujete stejně jako já a i zřejmě jako autoři těch "špatně napsaných" aplikací. Všichni používáme funkci close() ne-úplně-správně, přestože víme, jak pracuje. Občas se to nějakému nešťastníkovi vymstí. Ukazovat na něj prstem a křičet: "on si nepřečetl dokumentaci a může si za to sám" je trošku nefér, nemyslíte?Jde vždy o to, s jakou úrovní bezpečnosti je potřeba počítat. Tomu se přizpůsobuje implementace. Ale k tomu je pochopitelně potřeba vědět, jakou úroveň bezpečnosti použité mechanismy zajišťují. Když už se totiž rýpeme v tomto, pak musím připomenout například memory overcommitting. Je-li zapnutý (což ve většině linuxových distribucí je), pak úspěšná alokace nějaké paměti nezaručuje, že ta paměť bude v případě potřeby skutečně k dispozici. Pokud k dispozici nebude, jádro natvrdo sestřelí téměř libovolný proces (na základě skóre), aby paměť zajistilo. Tuto situaci jsem zažil rozhodně vícekrát, než že se ztratila důležitá data proto, že nebyla ještě uložena z paměti na disk a došlo např. k výpadku proudu.
fsync
zavolali. Rozhodně kvůli těmto speciálním případům nedává smysl zpomalovat běžnou práci s FS.
Ostatně, systém prostě padat nemá. Pokud padá, je něco fatálně špatně. Řešte proto raději příčinu, místo abyste se snažil záplatovat následky. Dokonale bezpečně se systém při pádu nemůže chovat nikdy.
Může se například stát, že dojde místo na disku - uživatel se pak vůbec nedozví, že funkce close() selhala a on přišel o data.
Nechci do toho kecat, ale nenáleží starost(+ upozornění správce systému, alokace rezerv aby vůbec mohl být upozorněn a něco s tím udělat) o systémové prostředky právě systému? Je sice fajn, že o tom aplikace ví, ale co s tím asi tak aplikace může udělat?
Dát to najevo uživateli. Přece jenom si neumím představit, ze bych např. zapisoval data někam na flash disk a ono mi to zamlčelo, že se zápis nepodařil celý.
Vážený uživateli aplikace Mega Super Enterprise, s politováním Vám oznamujeme, že Vaše data byla nenávratně ztracena, poněvadž se nepodařilo uzavřít soubor. Za vzniklé potíže se Vám omlouváme a věříme, že v budoucnosti se již nastalá situace nebude opakovat.
a nebo:
Chyba při uzavírání souborového deskriptoru 0x43. Navrhnout řešení -> Zkontrolujte si dosažení hranice kvóty určené správcem systému a zkuste uvolnit nějaká data na vzdáleném systému. OK -> close_window()
.
Ale souhlasím, že někdo by o tom někdo informován být měl. (Jen by close()
mělo zmrznout a dostat se do smyčky. Pokud jsou data v paměti, tak ještě existuje nějaká naděje - a paměť umírá poslední).
Jádro se sice stará o zdroje, ale přímo s uživatelem komunikovat nebude.
A to je chyba. Už teď se dozvídám, když mi dochází baterie a jiné výjimečné stavy, tak bych se klidně mohl na stejném místě dozvídat, že dochází paměť, místo na disku, kvóta či jiné systémové stavy(resp. že už se vyskytla aplikace, která narazila na problém s alokací systémových prostředků). A u ne-desktopových distribucí by se to mohlo signalizovat správci, popř. uživatelům.
Ale souhlasím, že někdo by o tom někdo informován být měl. (Jen by close() mělo zmrznout a dostat se do smyčky. Pokud jsou data v paměti, tak ještě existuje nějaká naděje - a paměť umírá poslední).Jak přesně to bude vypadat, je už záležitostí implementace filesystému. Jádro vrátí chybový kód až poté, co proces vyběhne ven z ovladače filesystému (příp. zařízení). Ovladač může být implementován tak, že když zápis selže, zkusí to ještě několikrát s nějakou prodlevou. Nelze čekat donekonečna, paměť patří ke vzácným zdrojům, navíc i ten visící proces by byl problém.
Už teď se dozvídám, když mi dochází baterie a jiné výjimečné stavy, tak bych se klidně mohl na stejném místě dozvídat, že dochází paměť, místo na disku, kvóta či jiné systémové stavy(resp. že už se vyskytla aplikace, která narazila na problém s alokací systémových prostředků). A u ne-desktopových distribucí by se to mohlo signalizovat správci, popř. uživatelům.Jenže jakým způsobem to hlásit? Obecně například není problém posílat zprávy přes D-BUS, ale i to má jednak svá úskalí (např. problematické použití při vzdálené práci), ale hlavně ty chyby pak nejdou dát do kontextu s konkrétním stavem aplikace. Jen aplikace ví, co přesně selhalo a může to dát uživateli náležitě najevo. Od systému se uživatel nedozví, jestli kvůli selhání třeba jen nemůže provést operaci Undo, anebo zda přišel o nějaká důležitá data.
Jak přesně to bude vypadat, je už záležitostí implementace filesystému. Jádro vrátí chybový kód až poté, co proces vyběhne ven z ovladače filesystému (příp. zařízení). Ovladač může být implementován tak, že když zápis selže, zkusí to ještě několikrát s nějakou prodlevou. Nelze čekat donekonečna, paměť patří ke vzácným zdrojům, navíc i ten visící proces by byl problém.
Asi jo. Jak tak čtu dál, tak chyba uzavření deskriptoru nutně nemusí znamenat ztracená data. No na druhou stranu opustit alokované, neuložené data a oznámit to s politováním uživateli? To bude ještě pěkný oříšek: It is quite possible that errors on a previous write(2) operation are first reported at the final close().
Jenže jakým způsobem to hlásit? Obecně například není problém posílat zprávy přes D-BUS, ale i to má jednak svá úskalí (např. problematické použití při vzdálené práci), ale hlavně ty chyby pak nejdou dát do kontextu s konkrétním stavem aplikace.
Samozřejmě jsem neměl na mysli přímý kontext, ale když např. bude uživatel vědět, že dochází místo a najednou se nebude dat ukládat a nebo bude vědět, že dochází paměť a nebude se dát alokovat paměť…přece jen už to budou nějaké indicie pro správce počítače či vzdálenou pomoc(a nebo dokonce technicky schopnějšího uživatele). A jak to hlásit? Pro nějaký enterprise systém či embeded zařízení mě napadá syslog (nevím jestli by se už nedal nedostatek systémových prostředků klasifikovat trochu vážněji a odeslat zprávu všem uživatelům systému jako při restartu:"Prosím uložte si všechna svá data. Brzo se něco semele a pěkné to nebude.") a pro desktop by to šlo kupř. přes nějakého notify démona do stejných míst kde se zobrazuje nedostatek energie v baterii u laptopů.
Jen aplikace ví, co přesně selhalo a může to dát uživateli náležitě najevo. Od systému se uživatel nedozví, jestli kvůli selhání třeba jen nemůže provést operaci Undo, anebo zda přišel o nějaká důležitá data.
Já zase zastávám názor, že pokud se to týká systémových prostředků, tak by to měl řešit systém. Když nastane chyba u close() z toho důvodu, že uživatel vyčerpal kvótu a data se drží jen v keších, tak s tím aplikace už stejně nic neudělá (write vracelo úspěch, takže už mohou být data dealokována a pointery ztraceny).
Nevím jestli by se už nedal nedostatek systémových prostředků klasifikovat trochu vážněji a odeslat zprávu všem uživatelům systému jako při restartu:"Prosím uložte si všechna svá data. Brzo se něco semele a pěkné to nebude."Takže když si nějaký uživatel připojí foťák, zkusí do něj něco zapisovat a už tam nebude místo, tak systém ztropí takový povyk? Vždyť stačí právě jen to, že to oznámí příslušná aplikace.
Myslel jsem to tak, že jádro nekomunikuje s uživatelem přímo, ale přes nejakého prostředníka, většinou několik. A v tomto případě mi prostě přijde nejlepší řešení, aby se o oznámení postarala přímo aplikace, která toJádro se sice stará o zdroje, ale přímo s uživatelem komunikovat nebude.A to je chyba. Už teď se dozvídám, když mi dochází baterie a jiné výjimečné stavy …
close()
volala, i když nebude moct říct nic lepšího, že uzavření selhalo.
To ze programator nevi, jak neco funguje, je pouze a jedine jeho chyba a zodpovednost. Protoze programatori nectou dokumentaci, tak ma nekdo pro ne neco navrhovat tak, aby to i pres jejich neschopnost vzdy fungovalo? Jednak to ani neni mozne, jednak proc hazet perly svinim?
Uložení dat na disk tak, aby nezmizela, není běžný případ? Na tom se, pane kolego, neshodneme.Uložení dat na disk tak, aby nezmizela v případě, když vzápětí dojde k pádu systému, není běžný případ. Jak už jsem psal, pokud by to běžný případ byl, nepoužívá se pro zápis na disk cache.
Tak teď ještě nějaké na pečivo a máme sbírku kompletní (teda, až na Hitlera, samozřejmě).
teda, až na Hitlera, samozřejměA profesora. Netrpělivě čekám, kdy se tu objeví dad a svalí veškenou vinu na svého oblíbence
Přesně. Ale všímáte si, že to je národní sport pouze na tomto portále?
Ne, protože není. Děje se to všude.
No, nevím. Na jiných portálech jsem moc ještě nebyl nucen konfrontace přirovnávání k autu. Teda co si pamatuju - a že si to pamatuju docela dobře, protože jediné co mě s auty spojuje je taková blbá kartička a většinou počátek přirovnávání v diskusi je pro mě roven zaslání TCP rámce s RST flagem.
mount -o flush
, což skutečně způsobí, že návrat z close()
bude čekat na uložení na médium (používá se pro výměnná média).
Jen jestli to správně chápu: Vytvoří/změní se soubor, zavře se, na disku se to promítne v metadatech souborového systému ale fyzická data se drží v keši a pokud se nestačí sesynchronizovat tak vnikne Sodoma a Gomora. A teď tu hoří flame o tom jestli má close()
zaručovat fyzické zapsání na médium a pokud ne, tak má alespoň existovat varianta open
volání, která zaručí, že se nebude kešovat(pominu, že něco takového už existuje) a o vině a nevině programátora, kernel hackera a uživatele. Potřebuje můj výrok nějakou korekci?
fsync()
), takže pokud se systém v tomhle stavu sesype, o data dost možná přijde. Pokud by se system nezhroutil, tak afaik defaultně nastavený ext3 nejdřív zapíše data a pak teprv matadata. Dělá se to takto kvůli bezpečnosti: pokud by se nejprve zapsala metadata jak popisujete, pak při prodlužování souboru by se mohly jeho součástí stát nějaká náhodná už dříve smazaná data.
Mimochodem, jestli jsem spravne pochopil ty bugreporty, tak k problemum doslo po prihlaseni do desktopoveho prostredi a naslednem padu. K tomu me napada otazka, ktera se tu jeste neobjevila - proc sakra desktopove prostredi cokoliv zapisuje do konfigurace hned pri prihlaseni, a ne jenom kdyz uzivatel explicitne meni konfiguraci?
Tiskni
Sdílej:
ISSN 1214-1267, (c) 1999-2007 Stickfish s.r.o.