Archivio per la categoria Sotto il cofano

NFS server su Linux + client NFS su SGI IRIX = cose strane

Ho ancora per le mani un paio di server Silicon Graphics Origin 200 (roba del 2000, che va ancora senza il minimo problema).
Nell’impianto dove sono impiegati, questi due server montano via NFS uno spazio disco condiviso da un server SUNFire 6800.

Arrivato il momento della pensione per il SunFire (le macchine SGI ci andranno a fine anno), è stato sostituito da un server DL380 di HP, con 5Tb di disco, con installato CentOS.

A metà della procedura di sostituzione, controllando che i servizi che girano sul Origin 200 operassero regolarmente, è saltato fuori un problema veramente curioso. Supponiamo che la macchina CentOS esporti una directory chiamata alfa, con dentro due directory beta e gamma. La macchina SGI avrà nel file /etc/fstab una riga tipo questa:

centos:/alfa  /puntodimount   nfs  defaults 0 0

Fin qui nulla di strano. L’anomalia salta fuori se si entra nella directory /puntodimount, e di usa il comando pwd:

# cd /puntodimount
# pwd
/
#

la risposta dovrebbe essere invece /puntodimount, ossia viene “eliminato” percorso di mount dalla directory corrente. Naturalmente in questo frangente tutti i servizi che controllano dove si trovano prima di operare non funzionano più, perché se vogliono andare dentro /puntodimount/beta, al controllo di “dove sono” (pwd), si vedono dentro /beta.

Dopo un paio di passaggi con Google ne sono venuto a capo: è un bug noto di IRIX 6.5.12 e precedenti, il numero 815265, la cui criptica definizione è: IRIX not liking file handles of less than 32 bytes. Il bug è risolto nella versione 6.5.13, ma, naturalmente, non è possibile fare alcun aggiornamento della macchina IRIX, meno che mai un aggiornamento di sistema operativo, che porterebbe ben altri problemi.

La soluzione è di usare l’opzione vers=2 nel file /etc/fstab del client IRIX, in questo modo:

centos:/alfa  /puntodimount   nfs  defaults,vers=2  0 0

Risolto questo problema, naturalmente, è uscito fuori quello che stava sotto, più grande: le prestazioni pietose. Per capirci, creando un file da 100M dalla macchina SGI sul server NFS Linux, questo è stato il risultato:

# time dd if=/dev/zero of=/LGCACHE/provamario bs=1024000 count=100
100+0 records in
100+0 records out
0.0u 2.0s 5:56 0% 0+0k 3+6250io 0pf+0w

Tradotto, 5 minuti e 56 secondi per creare il file, ossia 280kb/sec, roba che neanche con una rete a 10 mbit.

Facendo il solito giro, stavolta sui newsgroup, ho trovato un paio di messaggi che spiegano perché e come risolvere. In breve: mentre l’implementazione di SUN del server NFS lavora bene con l’impostazione synchronous writes, ossia il server risponde “ho scritto” ad ogni richiesta solo dopo che ha effettivamente scritto sul disco i dati, lasciando in attesa il client, l’implementazione in Linux lavora meglio con l’impostazione asynchronous writes, dove il server risponde immediatamente “ho scritto” alla corretta ricezione dei dati. L’effetto è che le scritture su disco, in Linux, vengono accumulate ed eseguite a gruppi, eliminando di fatto l’attesa per il client.
Aggiungendo nel server Linux alla riga di definizione della share NFS nel file /etc/exports il parametro async si ottiene questo risultato, con lo stesso test di scrittura:

# time dd if=/dev/zero of=/LGCACHE/provamario1  bs=1024000 count=100
100+0 records in
100+0 records out
0.0u 1.7s 0:11 15% 0+0k 1+6255io 0pf+0w

solo 11 secondi, pari a 9,3Mb/sec, un risultato ben diverso da prima.

Riferimenti

Tape drive LTO-3, controller HP Smart Array, Linux e problemi di velocità

Ho per le mani un server nuovo di zecca, con una discreta dotazione hardware. In particolare il pezzo degno di nota è un drive per nastri di tipo LTO-3.

Il server è un HP DL380 di sesta generazione, e monta un controller dedicato per il drive a nastro, uno SmartArray P212 con interfaccia di tipo SAS.

Il primo problema è stato che il drive non è rilevato all’avvio del sistema operativo, ma questo è facile da risolvere: i controller di tipo Smart Array sono in grado di accettare e controllare dispositivi a nastro, naturalmente a patto che l’interfaccia sia corretta, ossia SAS o SCSI. Il supporto per i dispositivi SCSI che non siano dischi è normalmente disabilitato nel modulo kernel corrispondente, che per la cronaca si chiama cciss, e può essere abilitato senza problemi e senza riavviare niente. Basta usare l’interfaccia /proc di accesso ai parametri del kernel.
Occorre prima individuare a quale controller sia connesso il drive a nastro, se ce ne sono più di uno. Basta andare a guardare nella directory /proc/driver/cciss: in questa directory vi sono tanti file quanti sono i controller, con il nome ccissX dove X è il numero “logico” del controller. Guardando dentro i singoli file con un cat si individua il controller giusto, nel mio caso è cciss1, il cui contenuto è:

cciss1: HP Smart Array P212 Controller
Board ID: 0x3241103c
Firmware Version: 1.66
IRQ: 178
Logical drives: 0
Sector size: 2048
Current Q depth: 0
Current # commands on controller: 0
Max Q depth since init: 0
Max # commands on controller since init: 1
Max SG entries since init: 0
Sequential access devices: 1

Per individuarlo, nel mio caso, ho cercato il modello di controller, ma si può usare ad esempio la presenza o meno di dischi, se il controller è condiviso fra dischi e nastro, cosa sconsigliata a priori.
Trovato il controller giusto, basta dare questo comando, da utente root:

# echo "engage scsi" > /proc/driver/cciss/cciss1

sostituendo a cciss1 il file giusto, e magicamente appare il drive a nastro, come si può verificare dai messaggi del kernel, visibili col comando dmesg:

scsi0 : cciss
  Vendor: HP        Model: Ultrium 3-SCSI    Rev: Q24D
  Type:   Sequential-Access                  ANSI SCSI revision: 05
scsi 0:0:0:0: Attached scsi generic sg0 type 1

Per trovare il device, occorre prima caricare a mano il modulo kernel st, oppure riavviare, ed a quel punto avremo disponibile il device /dev/st0 ed il device /dev/nst0 per accedere al nastro: il primo riavvolge il nastro automaticamente all’inizio quando si termina una operazione di scrittura (alla chiusura del device, ossia quando ad esempio il comando tar termina), mentre il secondo lascia il nastro dov’è.
Per rendere permanenti le modifiche ed avere il drive disponibile fin dall’avvio, ho inserito il comando nel file /etc/rc.local, che nelle distribuzioni RedHat e derivate (Fedora, CentOS), come pure in Debian, è destinato appunto questo scopo. Come effetto collaterale avremo che il modulo kernel st sarà caricato automaticamente all’avvio.

La velocità

Il primo test è a dir poco deludente: meno di 3 megabyte al secondo. Ma l’effetto peggiore è un altro, a lungo termine: il drive, non avendo dati alla velocità giusta, è costretto a fermarsi, aspettare dati a sufficienza, tornare indietro e ripartire. Questo ciclo di start-stop-rewind è in grado di distruggere un drive in pochi mesi. Se invece i dati arrivano costantemente e in quantità adeguata, il drive scrive a velocità costante per tutto il tempo senza fermarsi mai, se non alla fine del lavoro.
Ebbene, il problema è a vari livelli. La facciamo breve:

  • disattivare la compressione del drive, ed usare quella del software
  • impostare la dimensione del blocco sul nastro a 64k (65536 bytes)
  • assegnare al modulo kernel st almeno 2 megabyte di buffer

dopo questi interventi la velocità in scrittura è passata a 30 megabyte/sec, ben dieci volte, e soprattutto niente più start-stop.

Ecco i comandi da impartire, partiamo dalla compressione:

# mt -f /dev/st0 compression off

dove mt è una utility per la gestione dei drive a nastro, disponibile nel pacchetto mt-st.

Per la dimensione del blocco, si può utilizzare sia il comando:

# mt -f /dev/st0 setblk 65536

che con le opzioni proprie del programma usato per scrivere su nastro. Ad esempio tar ha l’opzione -b a cui devono essere indicati quanti blocchi da 512 byte per impostare la lunghezza del segmento dati da leggere o scrivere. Per 64k l’opzione è -b 128.

Per il buffer del modulo kernel st invece occorre aggiungere questa riga al file /etc/modprobe.conf (o l’equivalente della distribuzione in uso):

options st buffer_kbs=4096

e per attivare le modifiche basta scaricare il modulo, eseguire un depmod -a e ricaricare il modulo st. Se la configurazione è corretta, nel log del kernel deve apparire qualcosa del genere:

st: Version 20070203, fixed bufsize 4194304, s/g segs 256
st 0:0:0:0: Attached scsi tape st0
st0: try direct i/o: yes (alignment 512 B)
st0: Block limits 1 - 16777215 bytes.

Notare il messaggio: “fixed bufsize 4194304″.

La cura è piuttosto efficace, questo è il risultato di un test eseguito dopo le impostazioni mostrate:

# time dd if=/dev/zero of=/dev/st0 bs=64k count=100000
100000+0 records in
100000+0 records out
6553600000 bytes (6,6 GB) copied, 212,13 seconds, 30,9 MB/s

real	3m32.133s
user	0m0.040s
sys	0m1.049s

Riferimenti

  • Il manuale del modulo st, contenuto nel pacchetto kernel-doc, o nei sorgenti del kernel, in Documentation/scsi/st.txt.
  • Il manuale del modulo cciss, sempre nel pacchetto della documentazione del kernel, in Documentation/cciss.txt.
  • Un vecchio articolo della knowledge base di RedHat sui controller Smart Array.

Tags: , , , ,