Sistemi di file virtuali in Linux: perché sono utili e come funzionano? Parte 2

Ciao a tutti, condividiamo con voi la seconda parte della pubblicazione "Sistemi di file virtuali in Linux: perché sono utili e come funzionano?" È possibile leggere la prima parte qui. Ricordiamo che questa serie di pubblicazioni è dedicata al lancio di un nuovo ciclo del corso «Amministratore Linux», che inizierà molto presto.

Come monitorare le VFS utilizzando strumenti eBPF e bcc

Il modo più semplice per capire come il kernel gestisce i file sysfs è osservarlo in pratica, e il modo più semplice per osservare ARM64 è utilizzare eBPF. eBPF (abbreviazione di Berkeley Packet Filter) consiste in una macchina virtuale eseguita nel kernel, che gli utenti privilegiati possono interrogare (query) dalla riga di comando. I sorgenti del kernel informano il lettore su ciò che può fare il kernel; l'esecuzione degli strumenti eBPF in un sistema carico mostra cosa fa realmente il kernel.

Sistemi di file virtuali in Linux: perché sono utili e come funzionano? Parte 2

Fortunatamente, iniziare a utilizzare eBPF è abbastanza semplice con gli strumenti bcc, disponibili come pacchetti dalla distribuzione generale Linux e documentati in dettaglio da Bernard Gregg. Strumenti bcc – sono script in Python con piccole sezioni di codice in C, il che significa che chiunque abbia familiarità con entrambe le lingue può modificarli facilmente. In bcc/tools ci sono 80 script Python, il che implica che probabilmente uno sviluppatore o un amministratore di sistema riuscirà a trovare qualcosa di adatto per risolvere il problema.
Per avere almeno una visione superficiale del lavoro che svolgono i VFS in un sistema attivo, prova a vfscount o vfsstat. Questo mostrerà, ad esempio, che decine di chiamate vfs_open() e dei suoi «amici» si verificano letteralmente ogni secondo.

Sistemi di file virtuali in Linux: perché sono utili e come funzionano? Parte 2

vfsstat.py è uno script in Python, con sezioni di codice in C, che conta semplicemente le chiamate delle funzioni VFS.

Facciamo un esempio più triviale e vediamo cosa succede quando inseriamo una chiavetta USB nel computer e il sistema la riconosce.

Sistemi di file virtuali in Linux: perché sono utili e come funzionano? Parte 2

Con eBPF, possiamo vedere cosa accade in /sys, quando una chiavetta USB è inserita. Qui viene mostrato un esempio semplice e complesso.

Nell'esempio mostrato sopra, bcc strumento trace.py emette un messaggio quando viene eseguita la funzione sysfs_create_files(). Vediamo che sysfs_create_files() è stato avviato con kworker flusso in risposta al fatto che la chiavetta USB è stata inserita, ma quale file è stato creato? Il secondo esempio mostra tutta la potenza di eBPF. Qui trace.py viene visualizzato il backtrace del kernel (opzione -K) e il nome del file che è stato creato. sysfs_create_files()L'inserimento in frasi singole è un codice in C che include una stringa di formato facilmente riconoscibile, fornita da uno script Python che esegue LLVM. compilatore just-in-time. Questa stringa viene compilata ed eseguita in una macchina virtuale all'interno del kernel. La firma completa della funzione sysfs_create_files() deve essere riprodotta nel secondo comando, affinché la stringa di formato possa fare riferimento a uno dei parametri. Gli errori in questo frammento di codice C portano a errori riconoscibili del compilatore C. Ad esempio, se si omette il parametro -l, vedrete «Failed to compile BPF text». Gli sviluppatori che conoscono bene C e Python troveranno gli strumenti bcc facili da estendere e modificare.

Quando la chiavetta USB è inserita, il backtrace del kernel mostrerà che il PID 7711 è il flusso kworker, che ha creato il file «events» in sysfs. Di conseguenza, la chiamata a sysfs_remove_files() mostrerà che la rimozione del dispositivo ha portato alla cancellazione del file events, che corrisponde al concetto generale del conteggio dei collegamenti. In questo caso, la visualizzazione sysfs_create_link () con eBPF durante l'inserimento di una chiavetta USB mostrerà che sono state create almeno 48 symlink.

Qual è quindi il significato del file events? L'uso di cscope per trovare __device_add_disk(), dimostra che chiama disk_add_events (), e o "media_change", oppure "eject_request" possono essere registrati nel file eventi. Qui, il livello di blocco del kernel informa l'userspace dell'inserimento e dell'estrazione di un 'disco'. Nota quanto sia informativo questo metodo di indagine tramite l'inserimento di una chiavetta USB rispetto ai tentativi di capire come funziona tutto esclusivamente dai sorgenti.

I filesystem radice di sola lettura rendono possibili i dispositivi incorporati

Certo, nessuno spegne un server o il proprio computer staccando la spina dalla presa. Ma perché? È tutto perché i file system montati sui dispositivi di memorizzazione fisica possono avere registrazioni in sospeso e le strutture dati che registrano il loro stato potrebbero non sincronizzarsi con le registrazioni nell'archiviazione. Quando accade, ai proprietari del sistema tocca aspettare il prossimo avvio per eseguire l'utilità. fsck recupero filesystem e, nel peggiore dei casi, perdere dati.

Tuttavia, sappiamo tutti che molti dispositivi IoT, così come router, termostati e automobili, ora funzionano con Linux. Molti di questi dispositivi non hanno praticamente interfaccia utente e non c'è modo di spegnerli «pulitamente». Immagina di avviare un'auto con la batteria scarica, mentre l'alimentazione dell'unità di controllo Linux oscilla continuamente. Com'è possibile che il sistema si avvii senza un lungo fsck, quando finalmente il motore inizia a funzionare? La risposta è semplice. I dispositivi embedded si affidano al file system radice soltanto in lettura (abbreviato ro-rootfs (filesystem di root in sola lettura)).

ro-rootfs offrono numerosi vantaggi, che sono meno ovvi rispetto all'autenticità. Uno dei vantaggi è che il malware non può scrivere in /usr o /lib, se nessun processo Linux può scrivere lì. Un altro è che un filesystem sostanzialmente immutabile è fondamentale per il supporto sul campo dei dispositivi remoti, poiché il personale di supporto utilizza sistemi locali che sono nominalmente identici ai sistemi sul posto. Probabilmente, il vantaggio più importante (ma anche il più insidioso) è che ro-rootfs costringe gli sviluppatori a decidere quali oggetti di sistema saranno immutabili già nella fase di progettazione del sistema. Lavorare con ro-rootfs può essere scomodo e doloroso, come spesso accade con le variabili const nei linguaggi di programmazione, ma i loro vantaggi compensano facilmente i costi aggiuntivi.

Creazione rootfs la modalità sola lettura richiede alcuni sforzi aggiuntivi per gli sviluppatori di sistemi embedded, ed è qui che entra in gioco il VFS. Linux richiede che i file in /var erano disponibili per la registrazione e, inoltre, molti applicativi popolari che eseguono sistemi embedded cercheranno di creare file di configurazione dot-files in $HOME. Una delle soluzioni per i file di configurazione nella home directory è solitamente la loro generazione anticipata e assemblaggio in rootfs. Per /var uno dei possibili approcci è montarlo in una partizione separata, accessibile in scrittura, mentre il filesystem stesso / è montato solo in lettura. Un'altra alternativa popolare è l'uso di mount bind o overlay.

I mount bind e overlay, utilizzati dai contenitori

Esecuzione del comando man mount è il modo migliore per conoscere i mount bind e overlay, che consentono a sviluppatori e amministratori di sistema di creare un filesystem in un percorso e poi fornirlo alle applicazioni in un altro. Per i sistemi embedded, questo significa la possibilità di conservare file in /var su una flash drive accessibile solo in lettura, ma il montaggio overlay o bind di un percorso da tmpfs in /var il caricamento permetterà alle applicazioni di registrare note lì (scrawl). Al successivo avvio, le modifiche a /var saranno perse. Il montaggio sovrapposto crea un'unione tra tmpfs e il filesystem sottostante e consente di apportare modifiche apparenti ai file esistenti in ro-tootf mentre il montaggio collegato può rendere nuove cartelle vuote tmpfs visibili come accessibili per la scrittura in ro-rootfs percorsi. Mentre overlayfs è il tipo corretto (proper) di filesystem, il montaggio collegato è implementato nello spazio dei nomi VFS.

Basandosi sulla descrizione del montaggio sovrapposto e collegato, nessuno si sorprende che i container Linux li utilizzano attivamente. Osserviamo cosa succede quando usiamo systemd-nspawn per avviare un container, utilizzando lo strumento mountsnoop da bcc.

La chiamata system-nspawn avvia un container durante il funzionamento mountsnoop.py.

Vediamo cosa è uscito:

Avvio mountsnoop durante il 'caricamento' del container dimostra che l'ambiente di esecuzione del container dipende fortemente dal montaggio collegato (viene mostrato solo l'inizio di un lungo output).

Qui systemd-nspawn fornisce i file selezionati nel procfs e sysfs host nel container come percorsi nel suo rootfs. Oltre a MS_BIND Il flag che stabilisce il montaggio bind, così come altri flag nel sistema di montaggio, definiscono la relazione tra le modifiche nello spazio dei nomi dell'host e del container. Ad esempio, il montaggio bind può sia ignorare le modifiche nel /proc e /sys container, sia nasconderle a seconda della chiamata.

Conclusione

Capire il funzionamento interno di Linux può sembrare un compito impossibile, dato che il kernel stesso contiene una quantità enorme di codice, trascurando le applicazioni dello spazio utente di Linux e le interfacce delle syscall nelle librerie in C, come glibc. Un modo per progredire è leggere il codice sorgente di un sottosistema del kernel con l'accento sulla comprensione delle syscall e delle intestazioni rivolte allo spazio utente, così come delle principali interfacce interne del kernel, per esempio, la tabella file_operations. Le operazioni sui file seguono il principio "tutto è un file", quindi gestirle è particolarmente gratificante. I file sorgenti del kernel in C si trovano nella directory di alto livello. fs/ rappresentano l'implementazione dei file system virtuali, che costituiscono uno strato di interfaccia garantendo una compatibilità ampia e relativamente semplice tra i file system e i dispositivi di archiviazione più diffusi. Il montaggio con binding e overlay attraverso i namespace Linux è la magia del VFS, che rende possibile la creazione di contenitori e file system root soltanto in lettura. Combinato con lo studio del codice sorgente, lo strumento kernel eBPF e la sua interfaccia. bcc
rendono l'esplorazione del kernel più semplice che mai.

Amici, fateci sapere se questo articolo è stato utile per voi! Potreste avere commenti o osservazioni? E a coloro a cui interessa il corso "Amministratore Linux", invitiamo a giorno delle porte aperte, che si terrà il 18 aprile.

Prima parte.

Fonte: habr.com

Acquista un hosting affidabile per siti web con protezione DDoS, VPS VDS server 🔥 Acquista un hosting affidabile per siti web con protezione DDoS, VPS VDS server | ProHoster