Recentemente mi sono trovato a discutere - in un qualche forum - della necessità di eseguire un
# no auto-summary
per una configurazione Cisco in merito al riepilogo di rete del protocollo EIGRP. All'utente non risultava chiaro il significato di questo comando.
Si tratta, al solito, di risolvere problematiche di retrocompatibilità utili più al mass marketing che non al servizio in sè, ma questo si sa, è una vecchia storia....
EIGRP protocollo di routing proprietario Cisco è il successore dell'ormai obsoleto IGRP.
Tra le disgrazie, EIGRP eredita dal progenitore il protocollo classful in fase di riepilogo di rete (summarization).
Con il metodo classful, gli aggiornamenti di routing inviati tra i router non contengono informazioni sulle subnet mask, in quanto implicitamente riconosciute come reti di classe A, B, C a seconda dei casi. Ne consegue che se ci troviamo a gestire due sottoreti, come ad esempio 172.16.1.0/24 e 172.16.2.0/24 connesse da un'ulteriore rete, ad esempio 192.168.0.0/24, con EIGRP e l'auto summary abilitato, il risultato sarà quello illustrato in questa figura:
Le reti 172.16.1.0/24 e 172.16.2.0/24, saranno pubblicizzate al Router_A come reti di classe B: 172.16.0.0/16.
Questo implica conseguenze facilmente immaginabili; il Router_A avrà seri problemi di raggiungibilità per le reti suddette....
Per sopperire a questa "imprevista circostanza" bisogna evitare la procedura di auto summarization da parte del router.
Tale impostazione viene abilitata tramite il comando no auto-summary.
Router(config) # router eigrp as_num
Router(config-router) # no auto-summary
A seguito di questa modifica, il Router_A riceverà le route corrette per raggiungere le due reti 172.16.1.0/24 e 172.16.2.0/24; il contesto di quanto detto è chiarito da questa figura:
venerdì 26 luglio 2013
giovedì 27 giugno 2013
Oracle database in backup mode
Durante la mia consulenza su database Oracle, mi è capitato di diagnosticare database in backup mode; ovvia conseguenza di un backup terminato in modo non corretto...
Se ci troviamo a gestire una versione uguale/superiore alla 10g, un semplice
SQL> ALTER DATABASE END BACKUP;
risolverà il problema (vedi con select * from v$backup), ma per le versioni precedenti, il lavoro diventa più operoso: dovremo tablespace per tablespace eseguire un END BACKUP.
Vediamo di facilitare il compito con uno script che chiamo end_backup.sql.
rem -----------------------------------------------------------------------
rem Filename: end_backup.sql
rem Purpose: This script will create a file called end_backup_script.sql
rem - run it to take all tablespaces out of backup mode.
rem -----------------------------------------------------------------------
column cmd format a80 heading "Text"
set feedback off
set heading off
set pagesize 0
spool end_backup_script.sql
select 'alter tablespace '||a.tablespace_name||' end backup;' cmd
from sys.dba_data_files a, sys.v_$backup b
where b.status = 'ACTIVE'
and b.file# = a.file_id
group by a.tablespace_name
/
spool off
set feedback on
set heading on
set pagesize 24
set termout on
start end_backup_script.sql
Salviamo lo script in un file, diciamo $ORACLE_HOME/end_backup.sql ed eseguiamo l'accesso nel database con sqlplus utente sys as sysdba.
Una volta entrati nella shell sql lanciamo
SQL> @?/end_backup.sql
Verifichiamo lo stato del database con
SQL> SELECT * FROM V$BACKUP;
NOT ACTIVE = non in backup mode.
Se ci troviamo a gestire una versione uguale/superiore alla 10g, un semplice
SQL> ALTER DATABASE END BACKUP;
risolverà il problema (vedi con select * from v$backup), ma per le versioni precedenti, il lavoro diventa più operoso: dovremo tablespace per tablespace eseguire un END BACKUP.
Vediamo di facilitare il compito con uno script che chiamo end_backup.sql.
rem -----------------------------------------------------------------------
rem Filename: end_backup.sql
rem Purpose: This script will create a file called end_backup_script.sql
rem - run it to take all tablespaces out of backup mode.
rem -----------------------------------------------------------------------
column cmd format a80 heading "Text"
set feedback off
set heading off
set pagesize 0
spool end_backup_script.sql
select 'alter tablespace '||a.tablespace_name||' end backup;' cmd
from sys.dba_data_files a, sys.v_$backup b
where b.status = 'ACTIVE'
and b.file# = a.file_id
group by a.tablespace_name
/
spool off
set feedback on
set heading on
set pagesize 24
set termout on
start end_backup_script.sql
Salviamo lo script in un file, diciamo $ORACLE_HOME/end_backup.sql ed eseguiamo l'accesso nel database con sqlplus utente sys as sysdba.
Una volta entrati nella shell sql lanciamo
SQL> @?/end_backup.sql
Verifichiamo lo stato del database con
SQL> SELECT * FROM V$BACKUP;
NOT ACTIVE = non in backup mode.
venerdì 7 giugno 2013
Debian GNU/Hurd, la rivincita del micro?
Il 23 Maggio è stata rilasciata la distribuzione Debian con kernel GNU/Hurd: un travaglio!
Ormai da più di vent'anni la comunità della Free Software Foundation stava lavorando a questo kernel, che nelle intenzioni di Richard Stallman doveva essere il nucleo pulsante di GNU.
L'architettura del kernel negli anni è stata implementata in diverse versioni; inizialmente basata su kernel Mach, poi L4 ed infine Coyotos (successore di EROS).
Dalle note di rilascio, si evince la scelta iniziale: il kernel Mach; ma cos'è questo GNU/Hurd e perché non è poi così significativo il suo rilascio?
Kernel Monolitico
Un sistema operativo dovrebbe, come prima funzionalità, essere affidabile e funzionare senza problemi, ma, sfortunatamente, i sistemi operativi di oggi disattendono queste prospettive (il riferimento è al mercato mainstream/enterprise).
Le maggiori problematiche, derivano in primis proprio dall'architettura monolitica dei più comuni sistemi oggi in produzione.
In un sistema monolitico (come il kernel Linux, seppur modulare), il sistema operativo è un unico blocco di codice eseguito in modalità privilegiata che implementa tutte le funzionalità tipiche di un sistema operativo.
Ergo, tutte queste funzioni in kernel-mode non garantiscono un isolamento al fault del codice, perciò ogni bug può potenzialmente compromettere l'intero sistema. Molti ricercatori hanno evidenziato come il 70-80% dei casi di panic del kernel, derivino dai driver eseguiti in kernel-mode.
Kernel Single-Server
Il Single-Server è un kernel ridotto che esegue un sistema monolitico in user-mode. Sfortunatamente, l'affidabilità del sistema non si discosta di molto da un sistema monolitico in quanto anche in questa architettura è presente un 'single point of failure'.
Esempi di kernel Single-Server sono considerati il Mach-UX e il L4Linux.
Per la cronaca, uno dei primi sistemi Single-Server fu il Mach-UX che eseguiva un BSD sopra ad un Mach 3 a microkernel, noto ai più per le sue basse performance: circa 50% più lento della versione normale del BSD.
Kernel Multiserver
L'architettura dominante nelle installazioni mission critical real time (RTOS) è data da sistemi Multiserver System a microkernel (QNX, LynxOS, per citarne un paio), dove un qualsivoglia software di terze parti è destinato a lavorare isolato in user-mode.
Un kernel di questo tipo non dovrebbe superare le 50000 linee di codice (per i monolitici siamo oltre i 7 milioni), cosa che rende il sistema agevolmente comprensibile e di facile manutenzione.
Come esempio, prendo in esame il microkernel di Minix 3 un sistema operativo UNIX-like in grado di perdurare al crash di componenti critici, come ad esempio un device driver.
Il kernel di Minix è costituito solo dal gestore IRQ, IPC e da uno scheduler più due kernel task: SYS e CLOCK. Tutto il resto (Networking, File system, Drivers, ecc.) gira al difuori del kernel in user-mode, incapsulato in uno spazio di indirizzi privato che viene protetto dall'hardware attraverso l'MMU. In questo modo, è garantita un'alta affidabilità del sistema.
I detrattori del microkernel hanno sempre sostenuto che questo modo di agire penalizzava fortemente le performance. Se ciò poteva essere vero negli anni '80, ad oggi è solo uno sproposito, basti pensare al utilizzo di QNX per alcuni apparati Cisco (IOS XR): ...possiamo credere che Cisco è certamente interessata alle performance!
Affidabilità dunque è il tema dominante e GNU/Hurd è un microkernel multiserver rilasciato sotto licenza GPL con l'aspirazione di scalzare il dominio del kernel Linux sul software GNU.
Il progetto però è in costante ritardo e si deve misurare con altri progetti simili e ben più blasonati, già consolidati nel mercato embedded. Rimane da conquistare il mercato mainstream ed enterprise. Omnia cum tempora...
Ormai da più di vent'anni la comunità della Free Software Foundation stava lavorando a questo kernel, che nelle intenzioni di Richard Stallman doveva essere il nucleo pulsante di GNU.
L'architettura del kernel negli anni è stata implementata in diverse versioni; inizialmente basata su kernel Mach, poi L4 ed infine Coyotos (successore di EROS).
Dalle note di rilascio, si evince la scelta iniziale: il kernel Mach; ma cos'è questo GNU/Hurd e perché non è poi così significativo il suo rilascio?
Kernel Monolitico
Un sistema operativo dovrebbe, come prima funzionalità, essere affidabile e funzionare senza problemi, ma, sfortunatamente, i sistemi operativi di oggi disattendono queste prospettive (il riferimento è al mercato mainstream/enterprise).
Le maggiori problematiche, derivano in primis proprio dall'architettura monolitica dei più comuni sistemi oggi in produzione.
In un sistema monolitico (come il kernel Linux, seppur modulare), il sistema operativo è un unico blocco di codice eseguito in modalità privilegiata che implementa tutte le funzionalità tipiche di un sistema operativo.
Ergo, tutte queste funzioni in kernel-mode non garantiscono un isolamento al fault del codice, perciò ogni bug può potenzialmente compromettere l'intero sistema. Molti ricercatori hanno evidenziato come il 70-80% dei casi di panic del kernel, derivino dai driver eseguiti in kernel-mode.
Kernel Single-Server
Il Single-Server è un kernel ridotto che esegue un sistema monolitico in user-mode. Sfortunatamente, l'affidabilità del sistema non si discosta di molto da un sistema monolitico in quanto anche in questa architettura è presente un 'single point of failure'.
Esempi di kernel Single-Server sono considerati il Mach-UX e il L4Linux.
Per la cronaca, uno dei primi sistemi Single-Server fu il Mach-UX che eseguiva un BSD sopra ad un Mach 3 a microkernel, noto ai più per le sue basse performance: circa 50% più lento della versione normale del BSD.
Kernel Multiserver
L'architettura dominante nelle installazioni mission critical real time (RTOS) è data da sistemi Multiserver System a microkernel (QNX, LynxOS, per citarne un paio), dove un qualsivoglia software di terze parti è destinato a lavorare isolato in user-mode.
Un kernel di questo tipo non dovrebbe superare le 50000 linee di codice (per i monolitici siamo oltre i 7 milioni), cosa che rende il sistema agevolmente comprensibile e di facile manutenzione.
Come esempio, prendo in esame il microkernel di Minix 3 un sistema operativo UNIX-like in grado di perdurare al crash di componenti critici, come ad esempio un device driver.
Il kernel di Minix è costituito solo dal gestore IRQ, IPC e da uno scheduler più due kernel task: SYS e CLOCK. Tutto il resto (Networking, File system, Drivers, ecc.) gira al difuori del kernel in user-mode, incapsulato in uno spazio di indirizzi privato che viene protetto dall'hardware attraverso l'MMU. In questo modo, è garantita un'alta affidabilità del sistema.
I detrattori del microkernel hanno sempre sostenuto che questo modo di agire penalizzava fortemente le performance. Se ciò poteva essere vero negli anni '80, ad oggi è solo uno sproposito, basti pensare al utilizzo di QNX per alcuni apparati Cisco (IOS XR): ...possiamo credere che Cisco è certamente interessata alle performance!
Affidabilità dunque è il tema dominante e GNU/Hurd è un microkernel multiserver rilasciato sotto licenza GPL con l'aspirazione di scalzare il dominio del kernel Linux sul software GNU.
Il progetto però è in costante ritardo e si deve misurare con altri progetti simili e ben più blasonati, già consolidati nel mercato embedded. Rimane da conquistare il mercato mainstream ed enterprise. Omnia cum tempora...
sabato 20 aprile 2013
Port Address Translation? No, Puoi Anche Trascurarlo
Viste le tante definizioni di PAT che ho sentito nelle mie attività di consulente, faccio fede a quanto dichiara Cisco:
Argomento certo nobile.
Supponiamo di avere due device con ip 10.0.0.1 e 10.0.0.2 che accedono ad Internet attraverso un router NAT con un ip pubblico 88.88.88.1.
Quando l'ip 10.0.0.1 vuole accedere ad un web server, come ad esempio www.google.it, il datagramma viene inviato al router NAT che sostituisce l'ip sorgente con il suo ip pubblico (88.88.88.1) e come porta sorgente mantiene quella del device, supponiamo 5000, così rappresentata nella tabella di NAT:
10.0.0.1:5000 to 88.88.88.1:5000 ---> IPgoogle:80
Diciamo che nello stesso momento il device 10.0.0.2 invia una richiesta a www.google.it; come detto in precedenza, il router sostituisce l'ip sorgente con 88.88.88.1 e mantiene la porta sorgente del device, supponiamo 5001, così rappresentata nella tabella di NAT:
10.0.0.2:5001 to 88.88.88.1:5001 ---> IPgoogle:80
Quando il pacchetto ritorna al router, avrà come ip di destinazione 88.88.88.1 e come porta di destinazione 5000 o 5001. In questo modo il router riesce a decidere se il datagramma va inoltrato al device 10.0.0.1 o 10.0.0.2 basando cioè la sua decisione sulla porta di destinazione (demultiplexing).
Ma cosa succede se entrambi i device usano la porta 5000 come porta sorgente?
A questo punto il router non sarà più in grado di distinguere le due connessioni.
La soluzione è implementare nel router la funzione di sostituzione della porta sorgente; in questo contesto, se il device 10.0.0.1 invia una richiesta web a www.google.it, il router sostituirà la porta sorgente con una presa tra un intervallo compreso tra 1024:65535. Ad esempio:
10.0.0.1:5000 -> 88.88.88.1:5550
Se nello stesso momento il secondo device inviasse una richiesta a www.google.it, il router andrà a generare una tabella di NAT tipo:
10.0.0.2:5000 -> 88.88.88.1:5551
Con questa definizione, quando il pacchetto ritorna dal web server avrà come destinazione 88.88.88.1:5550 oppure 88.88.88.1:5551. è chiaro che in questo modo il router sarà in grado di inoltrare il pacchetto al device corretto.
Tutto ciò è stato affrontato e risolto dalle specifiche NAT - vedi RFC 5135 e RFC 1918 -.
Non si capisce dunque il motivo per cui si persiste a chiamare una tecnologia implementata nel NAT con un nome diverso quale PAT, come se fosse un nuovo servizio di rete destinato ad essere implementato da quei pochi netadmin "che loro sì, conoscono la tecnologia"...
Per quanto detto, il netadmin quadratico medio, si dovrebbe solo preoccupare del fatto che il suo sistema che implementa funzionalità di NAT abbia adottato le RFC sopra citate, mentre ogni altra allusione a PAT o affini va quanto prima eliminata perché inutile e fuorviante.
Port Address Translation (PAT) is a feature of a network device that translates TCP or UDP communications made between hosts on a private network and hosts on a public network. It allows a single public IP address to be used by many hosts on the private network, which is usually called a Local Area Network or LAN. ...
Argomento certo nobile.
Supponiamo di avere due device con ip 10.0.0.1 e 10.0.0.2 che accedono ad Internet attraverso un router NAT con un ip pubblico 88.88.88.1.
Quando l'ip 10.0.0.1 vuole accedere ad un web server, come ad esempio www.google.it, il datagramma viene inviato al router NAT che sostituisce l'ip sorgente con il suo ip pubblico (88.88.88.1) e come porta sorgente mantiene quella del device, supponiamo 5000, così rappresentata nella tabella di NAT:
10.0.0.1:5000 to 88.88.88.1:5000 ---> IPgoogle:80
Diciamo che nello stesso momento il device 10.0.0.2 invia una richiesta a www.google.it; come detto in precedenza, il router sostituisce l'ip sorgente con 88.88.88.1 e mantiene la porta sorgente del device, supponiamo 5001, così rappresentata nella tabella di NAT:
10.0.0.2:5001 to 88.88.88.1:5001 ---> IPgoogle:80
Quando il pacchetto ritorna al router, avrà come ip di destinazione 88.88.88.1 e come porta di destinazione 5000 o 5001. In questo modo il router riesce a decidere se il datagramma va inoltrato al device 10.0.0.1 o 10.0.0.2 basando cioè la sua decisione sulla porta di destinazione (demultiplexing).
Ma cosa succede se entrambi i device usano la porta 5000 come porta sorgente?
A questo punto il router non sarà più in grado di distinguere le due connessioni.
La soluzione è implementare nel router la funzione di sostituzione della porta sorgente; in questo contesto, se il device 10.0.0.1 invia una richiesta web a www.google.it, il router sostituirà la porta sorgente con una presa tra un intervallo compreso tra 1024:65535. Ad esempio:
10.0.0.1:5000 -> 88.88.88.1:5550
Se nello stesso momento il secondo device inviasse una richiesta a www.google.it, il router andrà a generare una tabella di NAT tipo:
10.0.0.2:5000 -> 88.88.88.1:5551
Con questa definizione, quando il pacchetto ritorna dal web server avrà come destinazione 88.88.88.1:5550 oppure 88.88.88.1:5551. è chiaro che in questo modo il router sarà in grado di inoltrare il pacchetto al device corretto.
Tutto ciò è stato affrontato e risolto dalle specifiche NAT - vedi RFC 5135 e RFC 1918 -.
Non si capisce dunque il motivo per cui si persiste a chiamare una tecnologia implementata nel NAT con un nome diverso quale PAT, come se fosse un nuovo servizio di rete destinato ad essere implementato da quei pochi netadmin "che loro sì, conoscono la tecnologia"...
Per quanto detto, il netadmin quadratico medio, si dovrebbe solo preoccupare del fatto che il suo sistema che implementa funzionalità di NAT abbia adottato le RFC sopra citate, mentre ogni altra allusione a PAT o affini va quanto prima eliminata perché inutile e fuorviante.
martedì 26 marzo 2013
simulatore MIPS
Per chi volesse iniziare un percorso formativo sulla programmazione MIPS, consiglio vivamente questo ambiente di simulazione: SPIM
meglio che mai in accoppiata con MIPSter
Una volta installato, eseguiamo un test di verifica con il seguente codice:
.data
hello_str: .asciiz "Test MIPSTer\nHello World!!!"
.text
main:
la $a0, hello_str
li $v0, 4
syscall
li $v0, 10
syscall
# Fine programma
Questa la bibliografia riguardo ai MIPS tradizionali:
meglio che mai in accoppiata con MIPSter
Una volta installato, eseguiamo un test di verifica con il seguente codice:
.data
hello_str: .asciiz "Test MIPSTer\nHello World!!!"
.text
main:
la $a0, hello_str
li $v0, 4
syscall
li $v0, 10
syscall
# Fine programma
Questa la bibliografia riguardo ai MIPS tradizionali:
- D. Sweetman, "See MIPS run ! 2nd"
- R. Britton, "MIPS Assembly Language Programming"
- Farquhar & Bunce, "The Mips Programmer's Handbook"
sabato 9 marzo 2013
VT questo sconosciuto
La comprensione della tecnologia Wintel VT-x o AMD-V introdotta nel 2005,
resta ancora abbastanza fumosa ai più, se non per la sua implementazione a più
alto livello.
Queste righe hanno lo scopo di chiarire l'idiosincrasia verso questo tipo di architettura.
La virtualizzazione non è certo invenzione dei giorni nostri, visto che già negli anni 70 l'IBM pionieristicamente introdusse questa tecnologia sui suoi sistemi denominati IBM/370.
Semplificando, diremo che il trucco sta nel servirsi della partizione del tempo d'uso della cpu (con opportuni algoritmi di scheduling), e delle tecniche della memoria virtuale. Un sistema operativo può creare così l'illusione che un processo disponga della propria CPU con la propria memoria (virtuale).
Ciò detto, dobbiamo precisare che gli approcci alla virtualizzazione sono di due tipi, detti di hypervisor di tipo 1, ove l’hypervisor è eseguito sul nudo hardware. La macchina virtuale è eseguita come un processo utente in modalità utente e come tale non gli è consentita l’esecuzione di istruzioni privilegiate. La macchina virtuale esegue un sistema operativo guest che pensa di essere in modalità kernel, sebbene sia in modalità utente. Diversamente, un hypervisor di tipo 2 non è altro che un programma utente (che gira su un sistema tipo Windows, Unix, ecc.) dove l’hypervisor viene eseguito come un qualsiasi programma applicativo e ne segue le regole ancorchè applicate al contesto della virtualizzazione.
Sebbene ci si possa aspettare che la tecnica adottata dal hypervisor di tipo 1 dia prestazioni maggiori di quella di tipo 2, in realtà non è così.
Semmai l’hypervisor di tipo 1 può sfruttare le caratteristiche peculiari del tipo 2 per migliorare le proprie performante, dando vita ad una sorta di sistema ibrido dove vengono prese in prestito le migliori caratteristiche dei due tipi di architetture.
Per completezza dobbiamo dire che esiste una terza tecnica (migliorativa) di virtualizzazione detta paravirtualizzazione, le cui specifiche esulano dallo scopo di questo post.
Il motivo dell’esistenza dei due tipi di hypervisor ha a che fare con i difetti dell’architettura del processore Wintel 386, portati avanti servilmente nelle nuove CPU per vent’anni, in nome di una retrocompatibilità.
In parole povere, ogni CPU con la modalità kernel e la modalità utente ha un insieme di istruzioni eseguibile solo in modalità kernel, come le istruzioni che fanno l’I/O, il cambio delle impostazioni dell’MMU e così via.
Ci sono anche delle istruzioni che, se eseguite in modalità utente, provocano un trap.
Nelle architetture I386 se si prova a fare qualcosa in modalità utente che non dovrebbe essere eseguito in modalità utente, l’hardware dovrebbe eseguire un trap. Diversamente dall'IBM/370, che possedeva questa proprietà, non era così per il 386. Un discreto numero di istruzioni significative, se eseguite in modalità utente, erano ignorate. Per esempio, l’istruzione POPF sostituisce il registro dei flag, cambiando il bit che abilita/disabilita gli interrupt. In modalità utente questo bit semplicemente non cambia. Conseguentemente, il 386 e i suoi sucessori non potrebbero supportare un hypervisor di tipo 1.
In realtà, la situazione è leggermente peggiore di quanto delineato. Oltre ai problemi relativi alle istruzioni che non riescono ad eseguire il trap in modalità utente, ci sono istruzioni che possono leggere lo stato sensibile in modalità utente senza provocare un trap.
Questi problemi furono risolti dal Intel (una ventina d'anni dopo questo documento) introducendo o meglio migliorando la virtualizzazione sui loro processori, quelli che oggi tutti conosciamo come VT.
La soluzione intrapresa è quella di far girare le machine virtuali in una sorta di container, una zona del processore che, detta in modo semplicistico ma lapalissiano, emula un IBM/370.
Ogni considerazione sulla (in)voluzione della tecnologia è lasciata come esercizio al lettore...
Queste righe hanno lo scopo di chiarire l'idiosincrasia verso questo tipo di architettura.
La virtualizzazione non è certo invenzione dei giorni nostri, visto che già negli anni 70 l'IBM pionieristicamente introdusse questa tecnologia sui suoi sistemi denominati IBM/370.
Semplificando, diremo che il trucco sta nel servirsi della partizione del tempo d'uso della cpu (con opportuni algoritmi di scheduling), e delle tecniche della memoria virtuale. Un sistema operativo può creare così l'illusione che un processo disponga della propria CPU con la propria memoria (virtuale).
Ciò detto, dobbiamo precisare che gli approcci alla virtualizzazione sono di due tipi, detti di hypervisor di tipo 1, ove l’hypervisor è eseguito sul nudo hardware. La macchina virtuale è eseguita come un processo utente in modalità utente e come tale non gli è consentita l’esecuzione di istruzioni privilegiate. La macchina virtuale esegue un sistema operativo guest che pensa di essere in modalità kernel, sebbene sia in modalità utente. Diversamente, un hypervisor di tipo 2 non è altro che un programma utente (che gira su un sistema tipo Windows, Unix, ecc.) dove l’hypervisor viene eseguito come un qualsiasi programma applicativo e ne segue le regole ancorchè applicate al contesto della virtualizzazione.
Sebbene ci si possa aspettare che la tecnica adottata dal hypervisor di tipo 1 dia prestazioni maggiori di quella di tipo 2, in realtà non è così.
Semmai l’hypervisor di tipo 1 può sfruttare le caratteristiche peculiari del tipo 2 per migliorare le proprie performante, dando vita ad una sorta di sistema ibrido dove vengono prese in prestito le migliori caratteristiche dei due tipi di architetture.
Per completezza dobbiamo dire che esiste una terza tecnica (migliorativa) di virtualizzazione detta paravirtualizzazione, le cui specifiche esulano dallo scopo di questo post.
Il motivo dell’esistenza dei due tipi di hypervisor ha a che fare con i difetti dell’architettura del processore Wintel 386, portati avanti servilmente nelle nuove CPU per vent’anni, in nome di una retrocompatibilità.
In parole povere, ogni CPU con la modalità kernel e la modalità utente ha un insieme di istruzioni eseguibile solo in modalità kernel, come le istruzioni che fanno l’I/O, il cambio delle impostazioni dell’MMU e così via.
Ci sono anche delle istruzioni che, se eseguite in modalità utente, provocano un trap.
Nelle architetture I386 se si prova a fare qualcosa in modalità utente che non dovrebbe essere eseguito in modalità utente, l’hardware dovrebbe eseguire un trap. Diversamente dall'IBM/370, che possedeva questa proprietà, non era così per il 386. Un discreto numero di istruzioni significative, se eseguite in modalità utente, erano ignorate. Per esempio, l’istruzione POPF sostituisce il registro dei flag, cambiando il bit che abilita/disabilita gli interrupt. In modalità utente questo bit semplicemente non cambia. Conseguentemente, il 386 e i suoi sucessori non potrebbero supportare un hypervisor di tipo 1.
In realtà, la situazione è leggermente peggiore di quanto delineato. Oltre ai problemi relativi alle istruzioni che non riescono ad eseguire il trap in modalità utente, ci sono istruzioni che possono leggere lo stato sensibile in modalità utente senza provocare un trap.
Questi problemi furono risolti dal Intel (una ventina d'anni dopo questo documento) introducendo o meglio migliorando la virtualizzazione sui loro processori, quelli che oggi tutti conosciamo come VT.
La soluzione intrapresa è quella di far girare le machine virtuali in una sorta di container, una zona del processore che, detta in modo semplicistico ma lapalissiano, emula un IBM/370.
Ogni considerazione sulla (in)voluzione della tecnologia è lasciata come esercizio al lettore...
giovedì 21 febbraio 2013
HP DataProtector CLI omni tools
Un piccolo prontuario (non completo) di comandi utili alla gestione di HP DataProtector:
riferimento alla versione A.06.00
omnicc [ -version | -help | -redistribute | ... ]
gestisce le licenze, visualizza la versione di HP DataProtector, esempio:
omnicc -ver
visualizza la versione di DataProtector
omniabort [ -version | -session SessionID | -help]
esegue l'abort di una sessione attiva (omnistat), esempio:
omniabort -session 2013/02/9-14
esegue l'abort della sessione
omnistat [ -version | -help | -session SessionID | -previous ]
visualizza lo stato delle sessioni attive, esempio:
omnistat -detail -session 2013/02/9-14
visualizza lo stato della sessione
omnisv [ -version | -help | -start | -stop | -status ]
esegue lo start, stop e visualizza lo stato del demone/servizio di DataProtector, esempio:
omnisv -status
visualizza lo stato del demone/servizio
omnirpt [ -version | -help | -report ]
genera backup report, esempio:
omnirpt -report -html list_sessions -timeframe 24 24 -email IND_MAIL
genera un media report
omnimm [ -version | -help | -create_pool | -modify_pool | ... ]
visualizza i media report disponibili, esempio:
omnimm -list_pool
visualizza lo stato, il nome pool, i media type ecc..
omnib [ -version | -help | -filesystem | -datalist | ... ]
esegue il backup, esempio:
omnib -datalist POLICY_NAME -mode full -load high
esegue il backup
omnidbutil [ -help | -version | -list_dcdirs | ... ]
gestisce diversi task di DataProtector, esempio:
omnidbutil -clean
esegue il clean delle sessioni attive
Per maggiori dettagli, si faccia riferimento a questa documentazione.
riferimento alla versione A.06.00
omnicc [ -version | -help | -redistribute | ... ]
gestisce le licenze, visualizza la versione di HP DataProtector, esempio:
omnicc -ver
visualizza la versione di DataProtector
omniabort [ -version | -session SessionID | -help]
esegue l'abort di una sessione attiva (omnistat), esempio:
omniabort -session 2013/02/9-14
esegue l'abort della sessione
omnistat [ -version | -help | -session SessionID | -previous ]
visualizza lo stato delle sessioni attive, esempio:
omnistat -detail -session 2013/02/9-14
visualizza lo stato della sessione
omnisv [ -version | -help | -start | -stop | -status ]
esegue lo start, stop e visualizza lo stato del demone/servizio di DataProtector, esempio:
omnisv -status
visualizza lo stato del demone/servizio
omnirpt [ -version | -help | -report ]
genera backup report, esempio:
omnirpt -report -html list_sessions -timeframe 24 24 -email IND_MAIL
genera un media report
omnimm [ -version | -help | -create_pool | -modify_pool | ... ]
visualizza i media report disponibili, esempio:
omnimm -list_pool
visualizza lo stato, il nome pool, i media type ecc..
omnib [ -version | -help | -filesystem | -datalist | ... ]
esegue il backup, esempio:
omnib -datalist POLICY_NAME -mode full -load high
esegue il backup
omnidbutil [ -help | -version | -list_dcdirs | ... ]
gestisce diversi task di DataProtector, esempio:
omnidbutil -clean
esegue il clean delle sessioni attive
Per maggiori dettagli, si faccia riferimento a questa documentazione.
sabato 9 febbraio 2013
giovedì 31 gennaio 2013
The book's corner
Ho studiato su questo parziale elenco di libri che ritengo indispensabile per chiunque voglia iniziare a parlare seriamente di architettura, progettazione, programmazione e amministrazione di sistemi operativi.
Come detto, ben lungi dall'essere completo, ma essenziale...
Testi su linguaggio assembly
- Blum "Professional Assembly Language"
- Britton "MIPS Assembly Language Programming"
- Paul "SPARC Architecture, Assembly Language Programming, and C"
Testi sui linguaggi di programmazione e oltre
- Alfred V. Aho "Compilers: Principles, Techniques, and Tools"
- Mogensen "Basics of Compiler Design"
- Peter van der Linden "Expert C Programming: Deep C Secrets"
- Kelley & Pohl "C didattica e progrmammazione"
- Kernighan & Ritchie "Il Linguaggio C"
- Malatesta "Linguaggio C in ambiente linux"
- Robert Love "Linux kernel developer"
- Corbet, Alessandro Rubini, Kroah-Hartman "Linux Device Drivers"
Testi sull'architettura dei calcolatori e sistemi operativi
- Hennessy & Patterson "Computer architecture - a quantitative approach"
- Hamacher "Introduzione all'archittettura dei calcolatori"
- Tanenbaum "Structured computer organization"
- Winn L. Rosch "Hardware Bible"
- Tanenbaum "I moderni sistemi operativi"
- Silberschatz "Sistemi operativi, Concetti ed esempi"
- Stallings "Operating Systems: Internals and Design Principles"
- Tanenbaum "Operating Systems: Design and Implementation"
- Tanenbaum "Sistemi distribuiti"
Testi sulle reti di calcolatori
- Tanenbaum "Reti di calcolatori"
- Kurose & Ross "Reti di calcolatori e Internet"
- Stallings "Data and Computer Communications"
- Lorenzi, Pizzigalli, Rizzi "Reti Internet & tecnologie web"
Solo in seguito, una full immersion su specifiche tecnologie: Oracle, MySql, Solaris, Linux, Windows, Cisco e vari linguaggi di p-scripting: Perl, Python.
Personalmente, nello studio dei Sistemi Operativi ho trovato di eccellente aiuto: Minix, SolOS e RTEMS
Come detto, ben lungi dall'essere completo, ma essenziale...
Testi su linguaggio assembly
- Blum "Professional Assembly Language"
- Britton "MIPS Assembly Language Programming"
- Paul "SPARC Architecture, Assembly Language Programming, and C"
Testi sui linguaggi di programmazione e oltre
- Alfred V. Aho "Compilers: Principles, Techniques, and Tools"
- Mogensen "Basics of Compiler Design"
- Peter van der Linden "Expert C Programming: Deep C Secrets"
- Kelley & Pohl "C didattica e progrmammazione"
- Kernighan & Ritchie "Il Linguaggio C"
- Malatesta "Linguaggio C in ambiente linux"
- Robert Love "Linux kernel developer"
- Corbet, Alessandro Rubini, Kroah-Hartman "Linux Device Drivers"
Testi sull'architettura dei calcolatori e sistemi operativi
- Hennessy & Patterson "Computer architecture - a quantitative approach"
- Hamacher "Introduzione all'archittettura dei calcolatori"
- Tanenbaum "Structured computer organization"
- Winn L. Rosch "Hardware Bible"
- Tanenbaum "I moderni sistemi operativi"
- Silberschatz "Sistemi operativi, Concetti ed esempi"
- Stallings "Operating Systems: Internals and Design Principles"
- Tanenbaum "Operating Systems: Design and Implementation"
- Tanenbaum "Sistemi distribuiti"
Testi sulle reti di calcolatori
- Tanenbaum "Reti di calcolatori"
- Kurose & Ross "Reti di calcolatori e Internet"
- Stallings "Data and Computer Communications"
- Lorenzi, Pizzigalli, Rizzi "Reti Internet & tecnologie web"
Solo in seguito, una full immersion su specifiche tecnologie: Oracle, MySql, Solaris, Linux, Windows, Cisco e vari linguaggi di p-scripting: Perl, Python.
Personalmente, nello studio dei Sistemi Operativi ho trovato di eccellente aiuto: Minix, SolOS e RTEMS
mercoledì 23 gennaio 2013
NetApp non solo snapshot
Mi sono spinto a scrivere questo
articolo che step by step spiega la tecnologia adottata da NetApp per
gestire le snapshot, perché considero questo metodo un modo elegante
e alternativo al più comune copy-on-write.
In the beginning was...
All'inizio le snapshot erano gestite in
modo molto semplice: un backup solo più veloce. Si leggeva tutto il
contenuto del disco e quindi lo ricopiava su un secondo disco.
Simple. Effective. Expensive.
Immagina questo tipo di snapshot come una fotocopiatrice: prendi un foglio, scrivi qualcosa su di esso, quando esegui una snapshot, semplicemente, fermati di scrivere e metti il foglio nella fotocopiatrice e fanne una copia.... In questo modo avrai 2 copie del foglio.
Un database potrebbe essere rappresentato come 100 fogli. Fare una snapshot potrebbe essere un procedimento lungo dal momento che dovresti copiare ogni pagina...
Certo, è un procedimento più veloce che copiare tutto a mano!
ok, l'analogia non è proprio perfetta, ma ci si avvicina.
Copy-on-Write Snapshots
Copiare tutti i dati ogni volta, può essere un operazione lunga che richiede molto spazio disco con costi tempo-denaro a volte eccessivi.
Inoltre, dovremo aggiungere il tempo di restore di tutti i dati del backup (snapshot)....
E se potessimo copiare solo i byte modificati?
A questo punto entra in gioco la snapshot copy-on-write. La prima snapshot registrerà una sorta di baseline prima che qualsiasi byte possa cambiare.
Dal momento che nulla è ancora stato modificato, non si avrà spazio utilizzato nella snapshot appena creata.
Ci si aspetta comunque che, prima o poi, qualcosa verrà modificato; si dovranno allora “registrare” queste modifiche. Il sistema copy-on-write andrà perciò a copiare il “vecchio” dato – prima che sia modificato – in un'area di snapshot, quindi sovrascriverà il dato.
Semplice ed efficace!
Ora il nostro backup non occuperà molto spazio dal momento che la snapshot registrerà solo i cambiamenti (delta).
Ma... ci sono dei lati negativi,
Ogniqualvolta che si andrà a modificare i blocchi dati, il sistema dovrà prima leggere il vecchio dato, poi scriverlo nell'area di snapshot, e quindi scrivere il dato aggiornato nella sua posizione.
Nota come il sistema, per ogni aggiornamento, dovrà eseguire due scritture e una lettura.
Questo modo di agire rallenta le cose.
In definitiva, si tratta di un compromesso; perdi in scrittura, ma in compenso non hai bisogno di grandi volumi per gestire la tua snapshot.
Oggi, questo problema viene gestito usando particolari algoritmi di cacheing, i quali possono ridurre la menzionata perdita di performance.
Ok, ma...cosa succede se non hai i dati originali?
NetApp Snapshots
NetApp con il suo filesystem WALF, gestisce il problema in modo differente. Invece di copiare i vecchi dati prima che essi siano modificati, NetApp (ok.. Ontap...) andrà a scrivere queste nuove informazioni in una zona speciale del disco chiamata SnapReserve; successivamente, il puntatore che identifica nel sistema quel dato verrà aggiornato per puntare al nuovo dato scritto nella SnapReserve.
Questo è il motivo per cui ogni volta che viene cambiato un dato (e la cancellazione è intesa come modifica) quest'area si andrà a riempire.
Questo metodo porta con sé indubbi vantaggi; si dovranno registrare solo i delta dei dati – è già un miglioramento rispetto alle performance del copy-on-write - . Dal momento che le snapshot sono solo dei puntatori, quando vorrai fare il restore dei dati (usando il SnapRestore) tutto ciò che il sistema dovrà fare è aggiornare i puntatori ai dati originali, il che è molto più veloce che copiare tutti i dati dell'area di snapshot nella posizione originale, come farebbe il copy-on-write.
Bene, ma c'è dell'altro...
Snapshots Are Views
Sarebbe bello pensare alla snapshot come ad una sorta di vista dei tuoi dati al momento della snapshot... ed essendo dei puntatori ciò è possibile! Se, per esempio, incorri in una delete accidentale di un dato, ti sarà possibile accedere ad una sotto cartella (.snapshot), la quale sarà difatto la tua vista (in read only) verso il passato....
A questo devo aggiungere che anche ZFS è in grado di offrire questa vista tramite la directory .zfs, ma ad eccezione di questa, non conosco altre tecnologie che posseggano questo splendido servizio.
JumpStart installation
Ammetto che l'installazione di Solaris
tramite JumpStart, è un'attività abbastanza tediosa...per questo
propongo questa guida.
Rispetto al sistema di esempio che ho
utilizzato, il lettore, eventualmente, dovrà personalizzare la
configurazione in relazione al proprio sistema.
La procedura è stata testata con una
macchina Solaris 10 x86 virtualizzata su Vmware (server jumpstart) d'ora in poi SRV-SOL_VM e un SunFire V240 (client jumpstart) d'ora in
poi SRV-SOLV240.
STEP #1
Creiamo una directory per salvare
l'immagine di Solaris OS.
# mkdir /export/install
Inseriamo il primo CD di Solaris 10
(uno di due) oppure se si ha il DVD inserire questo disco nella
macchina SRV-SOL_VM.
Posizionarsi nella directory del CD/DVD
dove è anche presente il file setup_install_server.
# cd
/cdrom/sol_10_811_sparc/Solaris_10/Tools
Lanciamo lo script
setup_install_server per salvare l'immagine del sistema nella
directory appena creata.
# ./setup_install_server
(se si sta installando con CD, inserire
il CD2 e dalla stessa directory lanciare:
# ./add_to_install_server
/export/install).
Queste procedure salveranno dentro la
directory install l'immagine del sistema operativo che si andrà ad
installare.
STEP #2
[operazione opzionale]: se non vengono
inseriti nel file sysidcfg, questi dati verranno richiesti durante
l'installazione.
Il file sysidcfg contiene informazioni di sistema come: security, time zone, ecc...
Creiamo una directory per queste
informazioni.
# mkdir -m 775 /export/jumpstart
Quindi spostarsi nella directory appena
creata, e creare il file sysidcfg, poi inseriamo questi dati di
esempio:
# touch sysidcfg
# vi sysidcfg
network_interface=primary
{protocol-ipv6=no
netmask=255.255.255.0}
security_policy=none
name_service=none
time_zone=Rome/Europe
system_locale=en
… salva il file..
STEP #3
Se non fatto in precedenza (step#2),
creare una directory jumpstart.
# mkdir -m 775 /export/jumpstart
Spostiamoci nella directory appena
creata e creiamo il file rules
# touch rules
# vi rules
any - - profile -
..salva il file.
Nella stessa directory creare un nuovo
file chiamato profile
# touch profile
# vi profile
install_type initial_install
pool rpool auto auto mirror c0t0d0s0
c0t1d0s0
bootenv installbe bename sxce-xx
Da un terminale facciamo partire il
servizio RARP:
# /usr/sbin/in.rarpd -d -a
STEP #4
Prima che un client JumpStart possa
iniziare l'installazione, bisogna creare il file rules.ok. Per creare
questo file, eseguire check; un run file che si trova nel CD/DVD di
Solaris.
# cd
/cdrom/sol_10_811_sparc/Solaris_10/Misc/JumpStart_sample
Copiamo il file check nella directory
jumpstart.
# cp check /export/jumpstart
Cambiamo directory ed eseguiamo il file
# cd /export/jumpstart
# ./check
Produrrà un'output simile a questo:
Vlidating rules...
Validating profile profile...
The custom JumpStart configuration is
ok
Bene, ora verifichiamo se nella
directory è stata creato il file rules.ok
STEP #5
Aggiungiamo al file /etc/ethers il
MAC-ADDRESS del client ed il suo nome host
# vi /etc/ethers
00-C1-AA-98-C3-B5 SRV-SOLV240
Salva il file..
Modifichiamo il file /etc/inet/hosts
con i dati del client
# vi /etc/inet/hosts
SRV-SOLV240 192.168.0.111
..Salva il file
Posizioniamoci nella directory dove si
trova il file add_install_client
# cd /export/install/Solaris_10/Tools
Eseguire il file add_install_client con
i parametri desiderati
# ./add_install_client -c
SRV-SOL_VM:/export/jumpstart SRV-SOLV240 sun4u
Modifichiamo il file /etc/dfs/dfstab
# vi /etc/dfs/dfstab
share -F nfs -o ro, anon=0
/export/install
share -F nfs -o ro, anon=0
/expoer/jumpstart
Lanciamo il comando shareall per
esportare i mountpoint di /export/install e /expoer/jumpstart.
# sahreall
Verifichiamo che siano correttamente
esportati:
# share
STEP #6
Avviamo la macchina JumpStart client
(SRV-SOLV240)
# init 6
Dall'OpenBoot PROM eseguiamo il boot:
ok> boot net – install
FINE!
giovedì 17 gennaio 2013
Solaris 10 from DHCP to Static IP
Questo esempio mostra come passare dalla configurazione DHCP ad un ip statico:
modifica il file /etc/hosts
# Internet host table
::1 localhost
127.0.0.1 localhost
192.168.0.161 quorum-srv loghost
quindi questi files:
/etc/hostname.INTERFACE
quorum-srv
/etc/defaultrouter
192.168.0.1
/etc/nodename
quorum-srv
rm /etc/dhcp.INTERFACE
cp /etc/nsswitch.files /etc/nsswitch.conf
That' all...
modifica il file /etc/hosts
# Internet host table
::1 localhost
127.0.0.1 localhost
192.168.0.161 quorum-srv loghost
quindi questi files:
/etc/hostname.INTERFACE
quorum-srv
/etc/defaultrouter
192.168.0.1
/etc/nodename
quorum-srv
rm /etc/dhcp.INTERFACE
cp /etc/nsswitch.files /etc/nsswitch.conf
That' all...
Iscriviti a:
Commenti (Atom)




