(Gen 2003 e queste pagine non sono ancora tutto, ma ci sto lavorando)
L'ENBD è il risultato di un progetto industriale di ricerca accademica
fondato dalla Realm Software di Atalanta, GA, per consolidare l'NBD nel
kernel.
Partri' in due tempi, quando io realizzai un port indietro dal nascente NBD di Pavel Machek allo sviluppo del kernel 2.1.
Un NBD è una coppia di fili molto lunga. Fa in modo che dischi di macchine differenti appaiano come dischi locali nella vostra macchina. Si comporta come un block device della macchina locale che appare come /dev/nda.
Non occorre che la risorsa remota sia un intero disco o una partizione. Potrebbe essere anche un file.
In particolare lo scopo di ENBD e' realizzare un RAID attraverso la rete. Si puo' fare in modo che ogni risorsa NBD sia parte di un mirror RAID e dunque di avere un distante ma sicuro backup di rete.
Per chiarire: viene attivata una connessione NBD verso un server NBD distante, esattamente come se usaste una partizione locale in un ambiente RAID.
Il kernel originale è stato profondamente modificato per generare l'ENBD dal kernel NBD : l'ENBD usa comunicazioni multicanale e block-journaled; è dotato di un failover incorporato e di bilanciamento automatico fra i canali; i demoni del server e del client ripartono, si autenticano e riconnettono dopo essersi bloccati o dopo una perdita di collegamento; il codice può essere compilato per realizzare connessioni trasparenti su canali SSL (vedere le opzioni di compilazione del Makefile).
In sintesi, i cambiamenti fondamentali di ENBD rispetto un driver standard del kernel sono
Io non ho curato molto una precisa conformità al driver di Pavel, ma io e lui siamo in contatto amichevole e ci scambiamo i bug fixing; naturalmente nella misura in cui la differenza fra le due architetture lo permette.
Versioni di kernel dalla 2.2.10 alla .15, e dalla 2.4.0 in poi. Versioni "proprietarie" ENBD dalla 2.2.25 in poi, funzionano anche, almeno, con le prime del kernel 2.4. La versione "attuale" enbd 2.4.x funziona su entrambe le releases di kernel e probabilmente pure sul 2.0.x (così come fa la ENBD 2.2.x). Il driver per il kernel è approssimativamente uguale in tutti i casi; differiscono solo i demoni lato utente – gli strati di compatibilità nel driver servono per emulare le interfacce del kernel più recente per permettere il funzionamento sulle vecchie architetture di kernel.
La versione attuale dell'ottobre 2002.
Il codice proprietario finale per il kernel 2.2 si trova nel 2.2-current (attualmente è la versione ENBD 2.2.29). Vedere nell'ftp area l'intero elenco delle releases. L'ultima release stabile è la ENBD 2.4.30 (che in teoria, come si diceva, supporta sia il kernel 2.4.x che il vecchio 2.2.x). E’ disponibile qui.
Si ribadisce: potete usare sia il Linux kernel 2.2 che il 2.4, ma il codice ENBD 2.4.x è l'unico che viene sviluppato, mentre l'ENBD 2.2.x è stato abbandonato.
Per un orientamento generale vi rimando all'articolo sul Linux Journal (numero 73 del maggio 2000). Esso è accurato solamente in riferimento al codice della serie 2.2. Ne metto a disposizione una copia qui.
Per un breve giudizio riporto qui di seguito alcune misure di performance:
Queste sono attualmente vecchie valutazioni prese, se ricordo bene, con la versione 2.0.26, e con una versione di NBD molto precedente all'attuale, ma potrebbero essere ancora utili. La piattaforma di test era una coppia di Pentium 200 con 64 Mb di ram, con delle interfacce di rete 3COM 3c905 e collegata tramite uno switch a 100 BT.
Naturalmente anche l’implementazione di NFS è stata ad oggi migliorata.
Eseguire la compilazione nella macchina client. Essa ha la configurazione di kernel di cui abbiamo bisogno durante la compilazione - infatti l'ENBD server non interagisce mai con il proprio kernel.
Occorre anche impostare nella variabile LINUXDIR la directory in cui ci sono i sorgenti del kernel desiderato, poiché oggigiorno la classica locazione /usr/src/linux sembra essere sostituita da un qualche punto nel quale furono compilate le glibc, e non la reale sorgente del kernel che si sta utilizzando. Tale directory del kernel deve contenere anche il .config file del kernel utilizzato, così come si legge durante il make.
Eseguire dal prompt:
e da lì in poi riporto le direttive d'installazione:
dovrebbe essere sufficiente digitare "make" da questa directory (punto2). Questo genererà enbd.o, enbd-server ed enbd-client nella directory /tmp. Modificare BUILD nel Makefile per cambiare la directory di build. Eseguire "make config all" per essere totalmente sicuri che tutto è stato impostato, ma il solo "make" dovrebbe funzionare. Esaminare il file Makefile per capire cosa ed il perché.
Editare il Makefile e sostituire SERVER e CLIENT con il nome della vostra macchina e di quella desiderata. Quest’'ultima deve avere il kernel in cui il modulo deve essere caricato. Dovrebbe essere sufficiente utilizzare lo stesso kernel usato nella build machine. Quest'ultima potrebbe anche fare da target machine. Impostare entrambi i SERVER e CLENT a “localhost” è un scelta sicura.
Accertarsi che sudo e ssh siano installati sia nel SERVER che nel CLIENT, che voi siete un sudoer e che avete effettuato un'appropriata generazione delle chiavi ssh ed export in entrambi i lati, in modo da potervi loggare indifferentemente alle due macchine. Se non avete sentito parlare di queste due utility ... beh, siete un pivello di amministratore e non dovreste impicciarvi di queste cose. Dò 5 a 1 che non ci riuscireste.
Infine eseguite un "make test". Il suo funzionamento dipende dalla presenza sia di sudo che di ssh. Accertatevi che il modulo enbd.o sia caricato (controllatelo con il comando /sbin/lsmod). Accertatevi anche che l' enbd-server ed il client abbiano generato slave servers e clients per gestire le connessioni (visualizzate la situazione con il comando pstree). Accertatevi del corretto stato dell'apparato dando il comando "cat /proc/nbdinfo". Dovreste vedere l'indicazione che /dev/nda è attivo, e che parecchie sottopartizioni - che corrispondono alle connessioni - sono anch'esse attive. Se ci fosse qualcosa di errato esaminate i vostri system logs e mandatemi i messaggi di errore insieme allo stato che vi restituisce il comando /proc/nbdinfo.
Cosa è successo nel test appena eseguito?
Ebbene, "make test" dovrebbe generare un piccolo file nella directory /tmp della macchina server e fornirlo alla macchina client con l'nebd client. Questo dovrebbe essere il /dev/nda. Su di esso il makefile potrebbe anche compilare ed eseguire l' "nbd test". Se tutto è andato bene dovreste poter impostare un file system con "mke2fs /dev/nda" e giocarci. Vi suggerisco:
Affinché tutto funzioni deve esistere il device ndxN nella macchina client. Ho fornito uno script di nome MAKEDEV per generarlo. Sulla macchina client dare il comando " cd /dev; sh <path_al_MAKEDEV> ".
Fare attenzione però ... nella directory /dev esiste già uno script chiamato MAKEDEV . Il vostro nominatelo in un altro modo oppure editatelo, vedete cosa fa e impostate il device a mano. Occorrono i block devices /dev/nda, /dev/nda1, /dev/nda2, /dev/nda3 etc, fino al 43 (o comunque fino al valore impostato per NBD_MAJOR nel kernel) e a partire dai 0, 1, 2 etc.=. Il trucco sarebbe dare il comando "mknod /dev/nda b 43 0; mknod /dev/nda1 b 43 1; ...... " etc. etc. =.
Per fermare il test potete provare ad eseguire "make stop" oppure "make rescue" . Non vi garantisco il funzionamento della modalità rescue in alcune circostanze; potreste provare ed elaborare il Makefile per adattarlo al vostro caso.
La difficoltà sta nel fermare il codice auto-riparante! Mandare un kil-USR1 ai demoni dovrebbe abbatterli e dare un errore dipendente dalla coda di richieste che ha il device. Un kill-USR2 tenterà di fare altrettanto, ed un kill -TERM dovrebbe eliminare con sicurezza i demoni permettendovi di scaricare il modulo del kernel.
Osservate l"output del file /proc/nbdinfo per ottenere lo stato del device. In particolare dovreste vedere il numero dei socket attivi, ed il numero delle istanze attive dei client.
Device a:
Open
[a] State: initialized, verify, rw, last
error 0
[a] Queued: +0 curr reqs/+0 real reqs/+10 max
reqs
[a] Buffersize: 86016 (sectors=168)
[a] Blocksize: 1024 (log=10)
[a] Size: 2097152
[a] Blocks: 2048
[a] Sockets: 4 (+)
(+) (*) (+)
[a] Requested: 2048+0 (602) (462)
(431) (553)
[a] Dispatched: 2048 (602) (462)
(431) (553)
[a] Errored: 0 (0)
(0) (0) (0)
[a] Pending: 0+0 (0)
(0) (0) (0)
[a] Kthreads: 0 (0 waiting/0
running/1 max)
[a] Cthreads: 4 (+)
(+) (+) (+)
[a] Cpids: 4
(9489) (9490) (9491) (9492)
Device b-p: Closed
Qui sopra potete vedere 4 instanze di client (Cthreads) tutte attualmente nel kernel (+). Probabilmente stanno aspettando di attivarsi. Si vedono altrettanti sockets di rete aperti e funnzionanti (+) con tre di loro che sono stati attivi di recente (+ e non *). Il primo sembra che abbia svolto più lavoro degli altri (602), ma con una differenza non molto significativa. Non ci sono errori rilevati e nemmeno richieste in corso sulle code interne. Se mi riportate un bug, assicuratevi di includere l’output del /proc/nbdinfo.
Parecchie persone si sono messe nei guai quando, fatta un po' di esperienza, hanno voluto tentare di impostare le cose per conto proprio. Hanno avuto successo nell'implementazione ma quando hanno fermato server e client per un po'e poi hanno tentato di farli ripartire, essi non si sono connessi! Cos'e' successo?
Il server genera una firma che viene installata nell'nbd device del client alla prima connessione. Ogni tentativo successivo di connessioni al server con una differente firma è rifiutato. Questo per evitare lo spoofing. Ora il client non conosce quella firma, che è mascherata nel kernel, e può solo chiedere se è quella giusta o no.
Qualcuno ha però scoperto che si può rimuovere il kernel module e poi farlo ripartire con successo. Per forza! Questa operazione scavalca la firma incorporata, ma non è la soluzione corretta. La cosa giusta da fare è:
La maggior parte della gente viene beccata da questo BECCATO!#1, ma alcuni incappano nel #2, che vi descrivo qui di seguito.
Il segnale con SIGPWR è normalmente preso in cairco dai demoni supplementari, nbd-sstatd e nbd-cstatd, ma scommetto dieci a uno che non sono stati ancora installati. Lo spiegherò in breve ... la sequenza di handshake risulta troppo lunga per il primo collegamento, e senza SIGPWR i client proveranno la sequenza breve invece di quella lunga.
Approfondirò un po' piu' in dettaglio che cosa fa il "make test" in modo che possiate duplicarvelo. Il primo gruppo di istruzioni è per il codice enbd-2.2.* , e troverete immediatamente dopo quelle per l' enbd-2.4.*=. Fate attenzione alle differenze della command line:
Questo vale per il modulo enbd-2.2.*. Per il modulo enbd-2.4.* invece la sequenza è la seguente:
E A PROPOSITO DELLE RISORSE > 2Gb?
Dipende realmente dal server, e dunque è una questione di userspace. Cosiderate questo: se il sistema del server può usare il comando lseek() per superare il limite dei 2 Gb, allora il protocollo di rete dell'NBD lo supporterà, poiché infatti supererà l'offset a 64 bit. E dal lato del client, anche il demone interagirà sicuramente con il kernel usando l'offset a 64 bit (infatti è ancora una cosa che riguarda lo userspace se accedere o no a files maggiori di 2 Gb).
Se non avete un sistema server in grado di gestire i 64 bit , per quello che posso comprendere nell'attualmente confuso mondo di Linux ... sotto le glibc2 ed i kernel 2.2.* e 2.4.* dovete compilare il codice dell' nbd-server con l'opzione _LARGEFILE64_SOURCE abilitata. Per semplificarvi la cosa lo farò fare automaticamente agli script a partire dalle revisioni nbd-2.2.26 e 2.4.5 in avanti.
Se invece non avete il supporto Large File nel vostro sistema, ENBD supporterà ugualmente l'aggregazione delle risorse, attraverso il RAID lineare o con quello striping, di qualunque grandezza e dunque non limitato a 2 Gb massimi, solamente curando che i singoli componenti delle risorse aggregate siano inferiori a 2 Gb di grandezza. Controllate le opzioni della command line del server. E' già sufficiente che siano elencate una serie di risorse nella command line per fare in modo che avvenga l'aggregazione!
Sottotitolo: come fare in modo che ENBD lavori con l'earthbit, la più conosciuta infrastruttura per il failover. Matthew Sackman ha scritto un ottimo HOWTO sull'argomento. Potete trovarlo qui. Io ho aggiunto gli scripts necessari all'archivio di distribuzione (nbd-2.4.30) nella directory nbd/etc/ha.d =.
Sorry per i links, ma odio la documentazione non inline. In compenso, descrivero cosa si cerca di ottenere con il failover; l'heartbit è solo un mezzo e in molte circostanze un semplice script di shell va bene o forse anche meglio, e la seguente descrizione potrà aiutarvi a costruirvelo.
Il concetto è di fare in modo che il server ed il client siano capaci di usare un singolo "IP address fluttuante". Questo IP fluttuante è normalmente quello del client, ma viene spostato sul server quando il client "muore". Per contro viene rispostato sul client quando questo resuscita e si rimette a funzionare. L' IP fluttuante è normalmente quello gestito dal DNS per alcuni servizi vitali quali samba o http.
L' heartbit è semplicemente un meccanismo per rilevare quando un client o un server si guastano, e per attivare in risposta un appropriato script.
Breve descrizione del funzionamento: il client avrà normalmente impostata una funzione raid1 (mirror) composta da una risorsa locale e dall'NBD device. Quando il client muore, l' IP fluttuante miene preso in carico dal server che quindi inizia a rendere disponibile la sua risorsa fisica di cui l' NBD device è o era l'immagine virtuale. Quando il client torna attivo, il suo componente locale deve essere risincronizzato dal componente NBD, ma il client si riappropria immediatamente dell' IP e diunque il mirror si risincronizza in background, mentre il tutto continua a funzionare.
Dissertazione: ci sono 4 possibili stati in cui la coppia di macchine può essere: (1) server attivo, client attivo - (2) server attivo, client inattivo - (3) server inattivo, client attivo - (4) server e client entrambi inattivi. Di questi l' 1 è lo stato di funzionamento "normale" mentre il 4 per i nostri scopi non può/deve accadere - il failover sarebbe infatti impossibile. La transizione dall 1 al 2 e viceversa, e dall' 1 al 3 e viceversa, sono quelli che ci interessano. A seguito di ognuna di queste transizioni l' heartbit produce azioni nella macchina che sopravvive.
Maggiori dettagli:consideriamo la transizione dall' 1 al 2 (server attivo-client attivo => server attivo-client inattivo). Il server è quello che sopravvive. Esso eseguirà il suo 'endbd-client start' script perché in quel momento dovrà assumere il ruolo di client. Lasciamo da parte per un momento cosa facciano gli scripts e concentriamoci sulla convenzione del nome. Nella transizione del 2 all' 1 (server attivo-client inattivo => server attivo-client attivo), cioè quando il client ritorna attivo, quest'ultimo esegue lo script 'enbd-client start' ed il server invece il proprio 'enbd-client stop' (perché esso stesso faceva le funzioni del client).
Ugualmente, nella transizione dall' 1 al 3 (server attivo-client attivo => server inattivo-client attivo) è il client a sopravvivere, e dunque deve assumere il ruolo di server; per far ciò esegue lo script 'enbd-server start'. Il server, se ce la fa prima di morire, potrebbe eseguire lo script 'enbd-server stop'. Durante la transizione inversa (server inattivo-client attivo => server attivo-client attivo) il client esegueil proprio script 'enbd-server stop' ed il server il proprio 'enbd-server start'.
Cosa fanno questi script?
Consideriamo ancora la transizione dall' 1 al 2, dove è il client a morire mentre il server sopravvive assumendosi il ruolo di client. Il server deve terminare il suo demone enbd-server, eseguire un fsck di tipo raw della prtizione e montarla nel percorso in cui i suoi apache e samba si aspettano di trovarlo. Questo è proprio quello che fa lo script 'enbd-client start'.
Il compito di spostare l' IP è normalmente gestito dall'heartbit, ma si può fare anche manualmente semplicemente mettendo nel nostro script il comando ifconfig eth0:0 foobar. Ugualmente si può fare per far partire o fermare i servizi apache e samba - anche questo è normalmente gestito dall'heartbit.
Se il client, prima di morire, avesse la possibilità di eseguire il proprio 'enbd-client stop', avrebbe ottenuto lo smontaggio del raid mirror, poi lo stop del mirror e del demone enbd-client che era attivo. Questo è proprio quello che fà lo script 'enbd-client stop'.
La transizione dal 2 all' 1 (server attivo-client inattivo => server attivo-client attivo) è quella che riporta il client al suo ruolo originario. Normalmente il server vive fino a che vede questa transizione accadere, e il suo script 'enbd-client stop' smonterà la partizione raw, farà partire il demone enbd-server, ed sarà finita. Dall'altro lato il client, con lo script 'enbd-client start', deve far partire il demone ebnd con attenzione, deve aspettare che l' NBD device divenga attivo, e poi faccia partire il mirror con l'NBD device come componente primario. Ah sì, deve anche recuperare l'indirizzo IP fluttuante - beh, come del resto fa normalmente l'heartbit stesso..
La transizione dall' 1 al 3 (server attivo-client attivo => server inattivo-client attivo) deve essere pensata alla stessa maniera, ma è collegata ad una serie di script più semplice di quella 1=>2, poiché i servizi apache e samba non abbisognano di essere rilocati - essi risiedono infatti sul client.
Il client è il sopravvissuto. Prende il ruolo di server attraverso lo script 'enbd-server start' e quindi quest'ultimo deve solo terminare il demone enbd-client (la componente di mirror del client è già comunque morta). Non ha bisogno di fare altro perché il mirror stesso è già sopravvissuto. Potrebbe anche estrarre il componente NBD dal mirror con il comando raidhotremove, ma non ha alcun bisogno di farlo. Se il server riesce ad eseguire lo script 'enbd-server stop' prima di morire, dovrebbe solamente terminare il proprio demone enbd-server e basta.
La transizione inversa, dal 3 all' 1 (server inattivo-client attivo => server attivo-client attivo) è più difficoltosa. E' il caso in cui il server deve essere reintegrato nella coppia. Esso esegue lo script 'enbd-server start' che fa partire il demone enbd-server. E' il client ad operare la reintegrazione del server : esso esegue lo script 'enbd-server start' il quale fa partire il demone enbd-server, aspetta che l' NBD device divenga attivo e poi lo reintegra nel mirror come componente secodnario mediante il comando "raidhotadd".
Gli script sono nell’HOWTO, e nell'archivio di distribuzione.
Notizia dell'ultim'ora - il mirroring intelligente
Con la versione enbd 2.4.31 si può eseguire sotto la fr1 invece che un raid1 del kernel, ed ottenere così una soluzione completamente integrata di RAID1 di rete. Scaricate la patch, applicatela al sorgente del kernel, impostate nella configurazione del kernel l' FR1 come modulo (con il comando make menuconfig, etc.), e ricompilate (comando make modules) per ottenere il modulo. Caricate il nuovo modulo md.o ed il lfr1.o sopra di esso. Tutto ciò fornisce il RAID1 intelligente ma tuttavia completamente retrocompatibile con l'originario RAID1.
L'intelligenza consiste in ciò che accade quando uno degli enbd-servers fallisce, e in quello che accade per tornare indietro. Nel comune mirroring di tipo RAID1, l'hard disk che si è guastato viene usualmente sostituito dall'operatore in breve tempo e qundi il controller RAID ci mette poco a risincronizzare il nuovo disco con operazioni in background, mentre invece il RAID device richiede al sistema operativo che entrambi i sistemi siano funzionanti come al solito. Sfortunatamente in ambiente di rete:
Il mirroring re-ingegnerizzato di fr1 tiene conto esattamente di quali blocchi si sono persi ed in quali server, e quando questi ultimi ritornano in collegamento, aggiorna solamente quegli stessi blocchi.
Questa funzionalità permette una velocizzazione molto spinta e un consistente risparmio di tempo. Infatti può ridurre il periodo in cui i server non hanno la ridondanza, da una grandezza di ore ad una questione di secondi. E la risincronizzazione è automatica quando un enbd server si ristabilisce. Non richiede l'intervento umano poiché è l' enbd client che fa eseguire l'istruzione hotadd.
Per impostarlo, eseguire il device enbd come un componente di un mirror fr1 ("raid"). Questo è tutto.
Sebbene non ci sia (ancora) un driver fr5, potete ottenere almeno la risincronizzazione o la riconnessione patchando il kernel per l' fr1 e poi usando il modulo patchato md.o sotto il solito raid5 kernel. L' enbd client manda un comando hotadd ioctl ad ogni raid device attivo quando il server si riconnette. Infatti, naturalmente, è compito del driver md patchato informare l' enbd che è un raid device.
Ché? Ah sì, ci sono dei bugs.
Notizie recenti
Tummy.com ha molto gentilmente fornito una mailing list per nbd. Mandate una mail contenente la parola "help" oppure "subscribe nbd" a enbd-request@lists.community.tummy.com. Potete trovare esaustive istruzioni sulla loro pagina web per la lista. La lista in se' stessa e' all’indirizzo enbd@lists.community.tummy.com.
Cosi' come il principale sito in ftp://oboe.it.uc3m.es/pub/Programs/ . Tummy.com ha anche messo un mirror all'indirizzo ftp://mirrors.tummy.com/pub/mirrors/linux-ha/enbd/ftp://mirrors.tummy.com/pub/mirrors/linux-ha/enbd/ .
Contattatemi - non solo per incoraggiarmi a fare una mailing list (hey, è già stata fatta da SuSE e da tummy.com!) e migliorare questa pagina. L'elenco dei cambiamenti del sorgente del driver è veramente impressionante.
Peter T. Breuer ptb@it.uc3m.es
Translated by Mauro Domizioli.