Ponorte sa do SDCardFS: Ako výmena FUSE od spoločnosti Google zníži réžiu I/O

click fraud protection

Hĺbkový prieskum SDCardFS, ktorý Google nahradil FUSE, a ako jeho implementácia zníži réžiu I/O.

Pred niekoľkými mesiacmi Google pridal niečo s názvom „SDCardFS” na oficiálne pobočky AOSP pre jadro Linuxu. V tom čase si tento krok všimol iba niektorí vývojári jadra, ale inak preletel pod radarom väčšiny používateľov. Nie je prekvapením, že väčšina používateľov, vrátane mňa, v skutočnosti nevie, čo sa deje pod kapotou operačného systému Android a jeho jadra.

Najnovšia epizóda seriálu Zákulisie vývojárov Androidu podcast obnovil záujem o túto tému. Podcast, ktorý hostil Chet Haase (starší softvérový inžinier v spoločnosti Google), preskúmal nedávne a nadchádzajúce zmeny v jadre. Na výstave bol vývojár linuxového jadra pracujúci v tíme Android - Rom Lemarchand. Dvojica diskutovala predovšetkým o tom, aké zmeny boli urobené na prispôsobenie sa aktualizáciám A/B, ale v posledných 5 minútach epizódy pán Lemarchand hovoril o „ďalšej veľkej veci“, na ktorej jeho tím pracoval – SDCardFS.

Musím sa priznať, že o existencii SDCardFS som sa dozvedel až po vypočutí tohto podcastu. Samozrejme, nebol som jediný, koho táto téma zaujala, keďže a

nedávne vlákno Reddit ukázal. Nebol som však spokojný so základným vysvetlením, ktoré podcast ponúkal, a v snahe rozptýliť niektoré Keď sa šíria dezinformácie, urobil som si vlastný prieskum a porozprával som sa s niekoľkými odborníkmi s relevantnými znalosťami o tejto problematike záležitosť.

Veľké poďakovanie patrí vývojárovi softvéru Michalovi Kowalczykovi za to, že prispel svojimi poznatkami do tohto článku a že si našiel čas na zodpovedanie mojich otázok.


„Externé“ je skutočne vnútorné

Hneď na začiatku sa určite vyskytnú nejaké mylné predstavy, ktoré musíme objasniť – inak bude zvyšok článku veľmi mätúci. Je užitočné diskutovať o histórii kariet SD a telefónov s Androidom.

V prvých dňoch telefónov s Androidom sa takmer každé zariadenie spoliehalo na používanie kariet microSD na ukladanie. Dôvodom bola skutočnosť, že telefóny sa v tom čase dodávali s minimálnou kapacitou vnútornej pamäte. SD karty používané na ukladanie aplikácií však často neposkytujú hviezdny používateľský zážitok, aspoň v porovnaní s rýchlosťou, s akou dokáže interná flash pamäť čítať/zapisovať dáta. Rastúce používanie kariet SD na externé ukladanie údajov sa preto pre spoločnosť Google stalo problémom používateľskej skúsenosti.

V dôsledku skorého šírenia kariet SD ako externých úložných zariadení boli konvencie pomenovávania úložísk systému Android založené na skutočnosti, že každé zariadenie malo skutočný fyzický slot na kartu microSD. Ale aj na zariadeniach, ktoré neobsahovali slot na SD kartu, sa štítok /sdcard stále používal na ukazovanie na skutočný interný úložný čip. Ešte mätúcejšia je skutočnosť, že zariadenia, ktoré na ukladanie využívali fyzickú SD kartu aj vysokokapacitný úložný čip, často pomenovali svoje oddiely podľa SD karty. Napríklad v týchto zariadeniach by bod pripojenia /sdcard odkazoval na skutočný interný úložný čip, zatiaľ čo niečo ako /storage/sdcard1 by odkazovalo na fyzickú externú kartu.

Aj keď sa karta microSD prakticky považuje za externé úložisko, konvencia názvov viedla k tomu, že „SDCard“ zostala dlho po akomkoľvek skutočnom použití fyzickej karty. Tento zmätok s ukladacím priestorom tiež spôsobil určité bolesti hlavy vývojárom aplikácií v dôsledku skutočnosti, že aplikačné dáta a ich médiá boli oddelené medzi dvoma oddielmi.

Nízky úložný priestor skorých interných úložných čipov viedol k tomu, že používatelia frustrujúco zistili, že už nemôžu inštalovať aplikácie (kvôli plnému oddielu /data). Medzitým boli ich karty microSD s väčšou kapacitou odkázané na uchovávanie iba médií (ako sú fotografie, hudba a filmy). Používatelia, ktorí si v minulosti prehliadali naše fóra, si možno pamätajú tieto názvy: Link2SD a Apps2SD. Išlo o (root) riešenia, ktoré používateľom umožňovali inštalovať svoje aplikácie a ich dáta na fyzickú SD kartu. K dokonalým riešeniam to však malo ďaleko, a tak musel zakročiť Google.

Je známe, že Google vytiahol SD karty veľmi skoro. Nexus One zostáva jediným zariadením Nexus so slotom na kartu microSD (a to bude navždy, pretože značka Nexus je v skutočnosti mŕtva). V zariadení Nexus S bol teraz k dispozícii iba jeden jednotný oddiel na ukladanie všetkých údajov aplikácií a médií – oddiel /data. To, čo bolo kedysi známe ako bod pripojenia /sdcard, teraz jednoducho odkazovalo na virtuálny súborový systém (implementovaný pod FUSE protokol, ako je uvedené nižšie), ktorý sa nachádza v dátovom oddiele - /data/media/0.

Aby sa zachovala kompatibilita a znížil sa zmätok, spoločnosť Google stále používala tento teraz virtuálny oddiel „sdcard“ na uchovávanie médií. Ale teraz, keď sa tento virtuálny oddiel „sdcard“ skutočne nachádzal v /data, všetko, čo je v ňom uložené, sa započítava do úložného priestoru interného úložného čipu. Bolo teda na OEM, aby zvážili, koľko priestoru pridelia aplikáciám (/data) verzus médiám (/data/media).

Dve veľmi odlišné „SD karty“

Google dúfal, že výrobcovia budú nasledovať ich príklad a zbavia sa SD kariet. Našťastie časom výrobcovia telefónov dokázali získať tieto komponenty pri vyšších kapacitách, pričom zostali nákladovo efektívne, takže potreba SD kariet začínala byť slabá. Konvencie pomenovania však pretrvávajú, aby sa znížilo množstvo úsilia, ktoré by vývojári a OEM museli vynaložiť na prispôsobenie. V súčasnosti, keď hovoríme o „externom úložisku“, máme na mysli buď jedna z dvoch vecí: skutočná vymeniteľná karta microSD alebo virtuálny oddiel „SDCard“ umiestnený v /data/media. Posledný z nich, prakticky povedané, je vlastne interné úložisko, ale konvencia názvov spoločnosti Google ich odlišuje v dôsledku skutočnosti, že tieto údaje sú prístupné používateľovi (napríklad pri pripojení k počítaču).

V súčasnosti, keď hovoríme o „externom úložisku“, máme na mysli buď jedna z dvoch vecí: skutočná vymeniteľná karta microSD alebo virtuálny oddiel „SDCard“ umiestnený v /data/media.


História virtuálnych súborových systémov Androidu

Teraz, keď sa s „sdcard“ zaobchádza ako s virtuálnym súborovým systémom, znamená to, že môže byť naformátovaný ako akýkoľvek súborový systém, ktorý Google chcel. Počnúc zariadeniami Nexus S a Androidom 2.3 sa spoločnosť Google rozhodla naformátovať „sdcard“ ako VFAT (virtuálny FAT). Tento krok mal v tom čase zmysel, pretože inštalácia VFAT by umožnila takmer akémukoľvek počítaču prístup k údajom uloženým vo vašom telefóne. Táto počiatočná implementácia však mala dva hlavné problémy.

Prvý sa týka predovšetkým koncového užívateľa (vás). Na pripojenie zariadenia k počítaču by ste na prenos údajov používali režim veľkokapacitného úložného zariadenia USB. To však vyžadovalo, aby zariadenie so systémom Android odpojilo virtuálny oddiel predtým, ako počítač mohol získať prístup k údajom. Ak by používateľ chcel používať svoje zariadenie pripojené k elektrickej sieti, veľa vecí by sa zobrazilo ako nedostupných.

The zavedenie protokolu prenosu médií (MTP) vyriešil tento prvý problém. Keď je počítač zapojený, vidí vaše zariadenie ako „úložisko médií“. Vyžaduje zoznam súborov z telefónu a MTP vráti zoznam súborov, ktoré môže počítač stiahnuť zo zariadenia. Keď sa požaduje odstránenie súboru, MTP odošle príkaz na odstránenie požadovaného súboru z úložiska. Na rozdiel od režimu veľkokapacitného úložiska USB, ktorý v skutočnosti pripája „sdcard“, MTP umožňuje používateľovi pokračovať v používaní zariadenia, keď je zapojený. Okrem toho na systéme súborov prítomných v telefóne s Androidom už nezáleží na tom, aby počítač rozpoznal súbory v zariadení.

Po druhé, bola tu skutočnosť, že VFAT neposkytoval druh robustnej správy povolení, ktorú Google potreboval. Na začiatku by mnohí vývojári aplikácií považovali „sdcard“ za skládku údajov svojej aplikácie bez jednotného zmyslu pre ukladanie svojich súborov. Mnoho aplikácií by jednoducho vytvorilo priečinok s názvom aplikácie a uložilo tam svoje súbory.

Takmer každá aplikácia tam v tom čase vyžadovala WRITE_EXTERNAL_STORAGE povolenie zapisovať ich aplikačné súbory do externého úložiska. Čo však bolo znepokojujúcejšie, bola skutočnosť, že takmer každá aplikácia tiež vyžadovala READ_EXTERNAL_STORAGE povolenie - len na čítanie vlastných dátových súborov! To znamenalo, že aplikácie mohli mať jednoduchý prístup k údajom uloženým kdekoľvek na externom úložisku, a takéto povolenie často udeľoval používateľ, pretože sa to vyžadovalo pre mnohé aplikácie funkciu.

Google to jasne videl ako problematické. Celá myšlienka správy povolení je oddeliť to, k čomu aplikácie môžu a nemôžu mať prístup. Ak je takmer každej aplikácii udelený prístup na čítanie potenciálne citlivých údajov používateľa, potom povolenie nemá zmysel. Google sa preto rozhodol, že potrebuje nový prístup. To je miesto, kde prichádza FUSE.


Súborový systém v používateľskom priestore (FUSE)

Počnúc Androidom 4.4 sa Google rozhodol už nepripájať virtuálny oddiel „sdcard“ ako VFAT. Namiesto toho Google začal používať FUSE na emuláciu FAT32 na virtuálnom oddiele „sdcard“. S volaním programu sdcard FUSE na emuláciu povolení adresára v štýle FAT-on-sdcard, aplikácie môžu začať pristupovať k údajom uloženým na externom úložisku bez vyžadovania akýchkoľvek povolení. Skutočne, počnúc úrovňou API 19, READ_EXTERNAL_STORAGE už nebolo potrebné na prístup k súborom umiestneným na externom úložisku – za predpokladu, že priečinok s údajmi vytvorený démonom FUSE sa zhoduje s názvom balíka aplikácie. FUSE by to zvládla syntetizuje vlastníka, skupinu a režimy súborov na externom úložisku keď je nainštalovaná aplikácia.

FUSE sa líši od modulov v jadre, pretože umožňuje neprivilegovaným používateľom písať virtuálne súborové systémy. Dôvod, prečo Google implementoval FUSE, je pomerne jednoduchý - robil to, čo chceli a už to bolo dobre pochopené a zdokumentované vo svete Linuxu. Aby som citoval a Vývojár Google v tejto veci:

„Keďže FUSE je pekné stabilné API, pri prechode medzi verziami jadra nie je potrebná v podstate žiadna údržba. Ak by sme prešli na riešenie v jadre, prihlásili by sme sa na udržiavanie sady záplat pre každú stabilnú verziu jadra." -Jeff Sharkey, softvérový inžinier v spoločnosti Google

Bolo však celkom jasné, že režijné náklady FUSE okrem iných problémov predstavovali aj zásah do výkonu. Developer, s ktorým som v tejto veci hovoril, Michal Kowalczyk, napísal skvelý blogový príspevok pred viac ako rokom podrobne popisuje aktuálne problémy s FUSE. Viac technických detailov sa dočítate na jeho blogu, no jeho zistenia (s jeho dovolením) popíšem skôr laicky.


Problém s FUSE

V systéme Android démon používateľského priestoru „sdcard“ využíva FUSE na pripojenie /dev/fuse do emulovaného adresára externého úložiska pri zavádzaní. Potom démon sdcard požiada zariadenie FUSE o akékoľvek čakajúce správy z jadra. Ak ste počúvali podcast, možno ste počuli, že pán Lemarchand hovorí o FUSE o zavedení réžie počas I/O operácií – tu je v podstate to, čo sa deje.

V reálnom svete tento výkon ovplyvňuje akýkoľvek súbor uložený na externom úložisku.

Problém č. 1 - I/O réžia

Povedzme, že vytvoríme jednoduchý textový súbor s názvom „test.txt“ a uložíme ho do /sdcard/test.txt (čo pripomínam vám, je to v skutočnosti /data/media/0/test.txt za predpokladu, že aktuálny používateľ je primárnym používateľom na zariadenie). Ak by sme chceli čítať (príkaz cat) tento súbor, očakávali by sme, že systém vydá 3 príkazy: otvoriť, prečítať, potom zavrieť. Vskutku, ako ukazuje pán Kowalczyk pomocou strace, to sa stane:

Ale pretože sa súbor nachádza na externom úložisku, ktoré spravuje démon sdcard, je potrebné vykonať mnoho ďalších operácií. Podľa pána Kowalczyka je na to potrebných v podstate 8 dodatočných krokov každý z týchto 3 samostatných príkazov:

  1. Aplikácia používateľského priestoru vydáva systémové volanie, ktoré bude spracovať ovládač FUSE v jadre (vidíme to v prvom výstupe strace)
  2. Ovládač FUSE v jadre upozorní démona používateľského priestoru (sdcard) na novú požiadavku
  3. Démon používateľského priestoru číta /dev/fuse
  4. Démon používateľského priestoru analyzuje príkaz a rozpoznáva operácie so súbormi (napr. OTVORENÉ)
  5. Démon používateľského priestoru vydáva systémové volanie na skutočný súborový systém (EXT4)
  6. Kernel sa stará o fyzický prístup k dátam a posiela dáta späť do užívateľského priestoru
  7. Používateľský priestor upravuje (alebo nie) údaje a znova ich odovzdáva cez /dev/fuse do jadra
  8. Kernel dokončí pôvodné systémové volanie a presunie údaje do skutočnej aplikácie používateľského priestoru (v našom príklade cat)

Vyzerá to tak veľa réžie len na jeden I/O príkaz, ktorý sa má spustiť. A mali by ste pravdu. Aby to dokázal, pán Kowalczyk sa pokúsil o dva rôzne I/O testy: jeden zahŕňal kopírovanie veľkého súboru a druhý kopírovanie množstva malých súborov. Porovnal rýchlosť FUSE (na virtuálnom oddiele pripojenom ako FAT32) obsluhujúceho tieto operácie oproti rýchlosti jadro (na dátovom oddiele naformátovanom ako EXT4) a zistil, že FUSE skutočne významne prispieva nad hlavou.

V prvom teste skopíroval súbor s veľkosťou 725 MB za oboch testovacích podmienok. Zistil, že implementácia FUSE prenáša veľké súbory o 17 % pomalšie.

V druhom teste skopíroval 10 000 súborov – každý z nich má veľkosť 5 kB. V tomto scenári sa implementácia FUSE skončila 40 sekúnd pomalšie skopírovať v podstate 50 MB dát.

V reálnom svete tento výkon ovplyvňuje akýkoľvek súbor uložený na externom úložisku. To znamená aplikácie ako Mapy ukladajúce veľké súbory na /sdcard, Hudobné aplikácie ukladajúce veľa hudobných súborov, aplikácie Fotoaparát a fotografie atď. Akákoľvek I/O operácia, ktorá sa týka externého úložiska, je ovplyvnená réžiou FUSE. Réžia I/O však nie je jediným problémom FUSE.

Problém č. 2 - Dvojité ukladanie do vyrovnávacej pamäte

Ukladanie údajov do vyrovnávacej pamäte je dôležité pri zlepšovaní výkonu prístupu k údajom. Uložením základných údajov do pamäte je jadro Linuxu schopné tieto údaje v prípade potreby rýchlo vyvolať. Ale vzhľadom na spôsob implementácie FUSE Android ukladá dvojnásobné množstvo vyrovnávacej pamäte, ktoré je potrebné.

Ako ukazuje pán Kowalczyk, očakáva sa, že súbor s veľkosťou 10 MB bude uložený vo vyrovnávacej pamäti presne 10 MB, ale namiesto toho sa veľkosť vyrovnávacej pamäte zvýši približne o 20 MB. To je problematické na zariadeniach s menšou pamäťou RAM, pretože linuxové jadro používa na ukladanie údajov vyrovnávaciu pamäť stránok Pamäť. Pán Kowalczyk testoval tento problém s dvojitou vyrovnávacou pamäťou pomocou tohto prístupu:

  1. Vytvorte súbor so známou veľkosťou (na testovanie 10 MB)
  2. Skopírujte ho do /sdcard
  3. Zrušte vyrovnávaciu pamäť stránky
  4. Urobte si snímku používania vyrovnávacej pamäte stránky
  5. Prečítajte si testovací súbor
  6. Urobte ďalšiu snímku používania vyrovnávacej pamäte stránky

Zistil, že pred jeho testom jadro využívalo 241 MB na vyrovnávaciu pamäť stránok. Keď si prečítal svoj testovací súbor, očakával, že pre vyrovnávaciu pamäť stránky sa použije 251 MB. Namiesto toho zistil, že toto jadro používa 263 MB pre cache stránky - o dvojnásobok toho, čo sa očakávalo. Dôvodom je to, že údaje sú najprv uložené do vyrovnávacej pamäte používateľskou aplikáciou, ktorá pôvodne vydala I/O volanie (FUSE), a potom démonom sdcard (EXT4 FS).

Problém č. 3 - Neúplná implementácia FAT32

Existujú dva ďalšie problémy vyplývajúce z používania FUSE emulujúceho FAT32, ktoré sú v komunite Android menej známe.

Prvý zahŕňa nesprávne časové pečiatky. Ak ste niekedy preniesli súbor (napríklad fotografiu) a všimli ste si, že časová pečiatka je nesprávna, je to kvôli implementácii FUSE v systéme Android. Tento problém má existoval pre rokov. Aby sme boli konkrétnejší, problém sa týka utime() systémové volanie, ktoré vám umožňuje zmeniť prístup a čas úpravy súboru. Žiaľ, volania uskutočnené na démona sdcard ako štandardný používateľ nemajú správne povolenie na vykonanie tohto systémového volania. Existujú na to riešenia, ale vyžadujú si to od vás mať root prístup.

Ak ste niekedy preniesli súbor (napríklad fotografiu) a všimli ste si, že časová pečiatka je nesprávna, je to kvôli implementácii FUSE v systéme Android.

Ďalší problém sa týka skôr podnikov, ktoré používajú niečo ako a karta smartSD. Pred FUSE mohli tvorcovia aplikácií monitorovať príznak O_DIRECT na komunikáciu s mikrokontrolérom zabudovaným v karte. Pomocou FUSE môžu vývojári pristupovať iba k verzii súboru vo vyrovnávacej pamäti a nemôžu vidieť žiadne príkazy odoslané mikrokontrolérom. To je problematické pre niektoré podnikové/vládne/bankové aplikácie, ktoré komunikujú s kartami microSD s pridanou hodnotou.


Dumping FUSE pre SDCardFS

Niektorí OEMS rozpoznali tieto problémy skoro a začali hľadať riešenie v jadre, ktoré by nahradilo FUSE. Vyvíjal sa napríklad Samsung SDCardFS ktorý je založený na WrapFS. Toto riešenie v jadre emuluje FAT32 rovnako ako FUSE, ale zbavuje sa réžie I/O, dvojitého ukladania do vyrovnávacej pamäte a ďalších problémov, ktoré som spomenul vyššie. (Áno, dovoľte mi zopakovať tento bod, toto riešenie, ktoré Google teraz implementuje, je založené na práci Samsungu).

Samotný Google konečne uznal nevýhody spojené s FUSE, a preto sa začal pohybovať smerom k emulačnej vrstve FAT32 vyvinutej spoločnosťou Samsung. Spoločnosť, ako je uvedené v Zákulisie vývojárov Androidu podcast, pracuje na sprístupnení SDCardFS pre všetky zariadenia v pripravovanej verzii jadra. Aktuálne si môžete pozrieť ich priebeh práca v AOSP.

Ako Vývojár Google vysvetlil vyššie, najväčšou výzvou pri implementácii riešenia v jadre je, ako namapovať názov balíka ID aplikácie potrebné na to, aby balík mohol pristupovať k vlastným údajom v externom úložisku bez toho, aby ho vyžadoval povolenia. Ale toto vyhlásenie bolo urobené pred rokom a dosiahli sme bod, kedy tím nazýva SDCardFS ich „ďalšou veľkou vecou“. Už potvrdili, že obávaná chyba časovej pečiatky bol opravený vďaka odklonu od FUSE, takže sa môžeme tešiť na všetky zmeny, ktoré prinieslo opustenie FUSE.


Mylné predstavy na overovanie faktov

Ak ste sa dostali až sem do článku, ďakujeme vám, že ste zatiaľ držali krok so všetkým! Chcel som objasniť niekoľko otázok, ktoré som mal pri písaní tohto článku:

  • SDCardFS má nemá nič spoločné so skutočnými SD kartami. Je len tak pomenovaný, pretože spracováva I/O prístup pre /sdcard. A ako si možno pamätáte, /sdcard je zastaraný štítok odkazujúci na „externé“ úložisko vášho zariadenia (kam aplikácie ukladajú svoje médiá).
  • SDCardFS je nie tradičný súborový systém ako FAT32, EXT4 alebo F2FS. Je to stohovateľný obalový súborový systém, ktorý odovzdáva príkazy nižším, emulovaným súborovým systémom (v tomto prípade by to bol FAT32 na /sdcard).
  • V súvislosti s MTP sa nič nezmení. Na prenos súborov do/z počítača budete naďalej používať protokol MTP (kým sa Google nerozhodne pre lepší protokol). Ale aspoň sa opraví chyba časovej pečiatky!
  • Ako už bolo spomenuté, keď Google hovorí o „externom úložisku“, hovorí buď o (pre všetky účely a účely) interný /sdcard virtuálny oddiel FAT32 ALEBO hovoria o skutočnej fyzickej, vymeniteľnej microSD kartu. Terminológia je mätúca, ale práve to nás zaráža.

Záver

Odchodom od FUSE a implementáciou emulačnej vrstvy FAT32 v jadre (SDCardFS) spoločnosť Google zníži značná I/O réžia, eliminácia dvojitého ukladania do vyrovnávacej pamäte a vyriešenie niektorých nejasných problémov súvisiacich s emuláciou jeho FUSE FAT32.

Keďže sa tieto zmeny vykonajú v jadre, možno ich zaviesť bez toho, aby sa popri ňom objavila hlavná nová verzia systému Android. Niektorí používatelia očakávajú, že tieto zmeny budú oficiálne implementované v systéme Android 8, ale je to možné pre akékoľvek budúce OTA na zariadení Pixel, ktoré prinesie linuxové jadro verzie 4.1, na ktorom Google pracuje na.

Pre niektorých z vás nie je SDCardFS novým konceptom. Zariadenia Samsung ho v skutočnosti využívajú už roky (koniec koncov to boli oni, kto ho vyvinul). Odkedy bol SDCardFS minulý rok predstavený v AOSP, niektorí vývojári vlastných ROM a jadra sa rozhodli implementovať ho do svojej práce. CyanogenMOD v istom bode uvažoval o jeho implementácii, ale vrátil ho späť, keď používatelia narazili na problémy s ich fotografiami. Ale dúfajme, že keď Google prevezme vládu nad týmto projektom, používatelia Androidu na všetkých budúcich zariadeniach budú môcť využiť vylepšenia predstavené zrušením FUSE.