Virtualni datotečni sustavi u Linuxu: zašto su potrebni i kako rade? Drugi dio

Pozdrav svima, dijelimo s vama drugi dio objave „Virtualne datotečne sustave u Linuxu: zašto su potrebni i kako rade?“ Prvi dio možete pročitati ovdje. Podsjećamo, ova serija objava povezana je s pokretanjem novog tečaja „Administrator Linuxa“, koji počinje vrlo brzo.

Kako pratiti VFS pomoću alata eBPF i bcc

Najlakši način da shvatite kako jezgra upravlja datotekama sysfs – jest promatrati to u praksi, a najlakši način da pratite ARM64 jest koristiti eBPF. eBPF (skraćenica za Berkeley Packet Filter) sastoji se od virtualne mašine koja se pokreće u jezgru, koju privilegirani korisnici mogu zatražiti (query) iz naredbenog retka. Izvori jezgre govore čitatelju što može učiniti jezgra; pokretanje alata eBPF u opterećenom sustavu pokazuje što zapravo jezgra radi.

Virtualni datotečni sustavi u Linuxu: zašto su potrebni i kako rade? Drugi dio

Srećom, lako je početi koristiti eBPF s alatima bcc, koji su dostupni kao paketi iz opće distribucije Linux i detaljno dokumentirani Bernardom Greggom. Alati bcc – to su skripte u Pythonu s malim dijelovima koda u C, što znači da svatko tko poznaje oba jezika može ih lako modificirati. U bcc/tools ima 80 Python skripti, što znači da će programer ili sistemski administrator vjerojatno naći nešto prikladno za rješavanje problema.
Kako biste dobili barem površno razumijevanje koje poslove VFS obavljaju u pokrenutom sustavu, pokušajte vfscount ili vfsstat. To će pokazati, recimo, da se desetine poziva vfs_open() i „njegovih prijatelja“ događaju doslovno svake sekunde.

Virtualni datotečni sustavi u Linuxu: zašto su potrebni i kako rade? Drugi dio

vfsstat.py – to je skripta u Pythonu, s dijelovima C koda, koja jednostavno broji pozive funkcija VFS.

Uzmimo trivialniji primjer i pogledajmo što se događa kada umetnemo USB flash disk u računalo i kada ga sustav prepoznaje.

Virtualni datotečni sustavi u Linuxu: zašto su potrebni i kako rade? Drugi dio

Pomoću eBPF možete vidjeti što se događa u /sys, kada je umetnut USB flash disk. Ovdje je prikazan jednostavan i složen primjer.

U primjeru prikazanom gore, bcc alat trace.py isporučuje poruku kada se pokrene naredba sysfs_create_files(). Vidimo da sysfs_create_files() je pokrenut putem kworker niti u odgovoru na to što je USB umetnut, ali koji je se datoteka pritom stvorila? Drugi primjer pokazuje svu moć eBPF. Ovdje trace.py ispisuje obratnu traganje jezgre (kernel backtrace) (opciju -K) i ime datoteke koja je stvorena sysfs_create_files(). Umetanje u jednostavnim izjavama je C kod koji uključuje lako prepoznatljivu formatnu liniju osiguranu Python skriptom koja pokreće LLVM just-in-time kompajler. Ovu liniju on kompajlira i izvršava u virtualnom stroju unutar jezgre. Potpuna potpis funkcije sysfs_create_files () mora biti ponovljena u drugom naredbi kako bi formatna linija mogla referencirati jedan od parametara. Greške u ovom fragmentu C koda dovode do prepoznatljivih grešaka C kompajlera. Na primjer, ako je parametar -l propušten, vidjet ćete "Failed to compile BPF text." Programeri koji su dobro upoznati s C i Pythonom će smatrati alate bcc jednostavnim za proširenje i promjenu.

Kada je USB uređaj umetnut, obratno traganje jezgre će pokazati da je PID 7711 – to je nit kworker, koja je stvorila datoteku "events" u sysfs. Tako će poziv s sysfs_remove_files() pokazati da je uklanjanje uređaja dovelo do brisanja datoteke events, što odgovara općoj koncepciji brojanja referenci. U ovom kontekstu, pregled sysfs_create_link () s eBPF tijekom umetanja USB uređaja pokazat će da je stvoreno najmanje 48 simboličkih veza.

Dakle, koja je svrha datoteke events? Korištenje cscope za pretraživanje __device_add_disk(), pokazuje da poziva disk_add_events (), i ili "media_change", ili "eject_request" mogu biti zapisani u datoteku događaja. Ovdje sloj bloka jezgre obavještava userspace o pojavljivanju i uklanjanju "diska". Obratite pažnju koliko je informativna ova metoda istraživanja na primjeru umetanja USB uređaja u odnosu na pokušaje da se sazna kako sve funkcioniše isključivo iz izvora.

Korijenske datotečne sustave samo za čitanje omogućuju ugrađene uređaje

Naravno, nitko ne isključuje server ili svoje računalo izvlačeći utikač iz utičnice. Ali zašto? Sve zato što montirani datotečni sustavi na fizičkim uređajima za pohranu mogu imati odložene zapise, a strukture podataka koje bilježe njihovo stanje možda se neće sinkronizirati s zapisima u pohrani. Kada se to dogodi, vlasnici sustava moraju čekati sljedeće pokretanje da bi pokrenuli alat fsck filesystem-recovery i, u najgorem slučaju, izgubiti podatke.

Ipak, svi znamo da mnoga IoT uređaja, kao i ruterima, termostatima i automobilima, sada funkcioniraju na Linuxu. Mnogi od tih uređaja praktički nemaju korisničko sučelje i ne postoji način da se 'čisto' isključe. Zamislite da pokrećete automobil s praznom baterijom, dok napajanje upravljačkog uređaja Linux neprestano oscilira. Kako se događa da se sustav učitava bez dugog fsck, kada motor konačno počne raditi? Odgovor je jednostavan. Ugrađeni uređaji oslanjaju se na korijenski datotečni sustav samo za čitanje (skraćeno ro-rootfs (datotečni sustav samo za čitanje).

ro-rootfs nudе mnoge prednosti koje su manje očigledne od nemjenjivosti. Jedna od prednosti je ta da zlonamjerni softver ne može pisati u /usr ili /lib, ako nijedan proces Linuxa ne može pisati u njega. Druga je ta da u značajnoj mjeri nepromijenjen datotečni sustav ima ključnu ulogu u terenskoj podršci udaljenim uređajima, jer pomoćno osoblje koristi lokalne sustave koji su nominalno identični sustavima na terenu. Možda je najvažnija (ali i najobmanjujuća) prednost ta što ro-rootfs prisiljava programere da odluče koji će sustavski objekti biti nepromjenjivi već u fazi dizajniranja sustava. Rad s ro-rootfs može biti nezgodan i bolan, kao što to često biva s konstantama u programskim jezicima, ali su njihove prednosti lako isplative naspram dodatnih troškova.

Izrada rootfs samo za čitanje zahtijeva dodatni trud od programera ugrađenih sustava, a tu na scenu stupa VFS. Linux zahtijeva da datoteke u /var budu dostupne za zapisivanje, a osim toga, mnoge popularne aplikacije koje pokreću ugrađene sustave pokušat će stvoriti konfiguracijske dot-datoteke u $HOME. Jedno od rješenja za konfiguracijske datoteke u korisničkom direktoriju obično je njihova prethodna generacija i prikupljanje u rootfs. Za /var jedan od mogućih pristupa je montiranje u zasebnu particiju dostupnu za pisanje, dok je sama / montira se samo za čitanje. Druga popularna alternativa je korištenje povezanih ili preklapajućih montaža (bind or overlay mounts).

Povezane i preklapajuće montaže, njihovo korištenje u kontejnerima

Izvršavanje naredbe man mount je najbolji način da saznate o povezanim i preklapajućim montažama, koje omogućuju programerima i sistemskim administratorima da kreiraju datotečni sustav putem jednog puta, a zatim ga daju aplikacijama na drugom. Za ugrađene sustave to znači mogućnost pohranjivanja datoteka u /var na USB memoriji dostupnoj samo za čitanje, ali preklapajuće ili povezano montiranje puta iz tmpfs u /var pri pokretanju omogućit će aplikacijama da pišu bilješke (scrawl). Pri sljedećem uključivanju, promjene u /var bit će izgubljene. Preklapajuće montiranje stvara spoj između tmpfs i donjeg datotečnog sustava te omogućuje navodne izmjene postojećih datoteka u ro-tootf dok povezano montiranje može učiniti nove prazne tmpfs mapirajući ih kao dostupne za pisanje u ro-rootfs putanjama. Dok overlayfs je pravi (proper) tip datotečnog sustava, povezano montiranje je implementirano u VFS prostoru imena.

Bazirano na opisu preklapajućeg i povezanog montiranja, nije iznenađujuće što Linux kontejneri aktivno ih koriste. Pogledajmo što se događa kada koristimo systemd-nspawn za pokretanje kontejnera, koristeći alat mountsnoop od bcc.

Poziv system-nspawn pokreće kontejner tijekom rada mountsnoop.py.

Pogledajmo što smo dobili:

Pokretanje mountsnoop tijekom "učitavanja" kontejnera pokazuje da okruženje izvođenja kontejnera uvelike ovisi o povezanom montiranju (Prikazuje se samo početak dugog ispisa).

Ovdje systemd-nspawn osigurava odabrane datoteke u procfs i sysfs domaćina u kontejner kao putove u njegovom rootfs. Osim MS_BIND flaga, koji postavlja povezano montiranje, neke druge zastavice u montiranom sustavu određuju međusobne odnose između promjena u prostoru imena domaćina i kontejnera. Na primjer, povezano montiranje može ili propuštati promjene u /proc i /sys u kontejner, ili ih skrivati ovisno o pozivu.

Zaključak

Razumijevanje unutarnjeg funkcioniranja Linuxa može se činiti kao nemoguć zadatak, budući da samo jezgro sadrži ogroman broj kodova, dok su aplikacije korisničkog prostora Linuxa i sučelja sustavnih poziva u C knjižnicama poput glibc. Jedan od načina da se napreduje je čitanje izvornog koda jedne podsustava jezgre s naglaskom na razumijevanje sustavnih poziva i zaglavlja koji se obraćaju korisničkom prostoru, kao i osnovnih unutarnjih sučelja jezgre, na primjer, tablica file_operations. Operacije datoteka osiguravaju princip "sve je datoteka", pa je upravljanje njima posebno ugodno. Izvorne datoteke jezgre na C-u u glavnom direktoriju fs/ predstavljaju implementaciju virtualnih datotečnih sustava, koji su sloj omotača koji osigurava široku i relativno jednostavnu kompatibilnost popularnih datotečnih sustava i uređaja za pohranu. Montiranje putem povezivanja i preklapanja preko Linuxovih imenskih prostora je čarolija VFS-a, koja omogućava stvaranje kontejnera i korijenskih datotečnih sustava samo za čitanje. U kombinaciji s proučavanjem izvornog koda, sredstvo jezgre eBPF i njegovo sučelje bcc
čine istraživanje jezgre lakšim nego ikad.

Prijatelji, javite nam je li vam ovaj članak bio koristan? Imate li kakve komentare ili primjedbe? A one koji su zainteresirani za tečaj "Linux administrator" pozivamo na dan otvorenih vrata, koji će se održati 18. travnja.

Prvi dio.

Izvor: habr.com

Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere 🔥 Kupite pouzdan hosting za web stranice s DDoS zaštitom, VPS VDS servere | ProHoster