LVM
Cos’è LVM
LVM sta per Logical Volume Manager e consente di gestire lo storage in modo più flessibile introducendo uno strato intermedio tra i dischi (fisici) e i file system.
Senza LVM avremmo:
- dischi;
- partizioni: ogni partizione può occupare al massimo un disco;
- file system: ogni file system può occupare al massimo una partizione.
Con LVM abbiamo:
- dischi fisici, quelli veri ;-);
- dischi fisici (PV);
- volume group (VG): associa i PV ai volumi logici;
- volumi logici (LV);
- file system.
I PV corrispondono alle partizioni così come le conosciamo nel mondo Mac ed è al di sopra di questi che LVM aggiunge quel livello d’indirezione che consente ai LV di essere definiti in termini di “somma” di PV.
Una limitazione di LVM è data dal fatto che una partizione LVM non può essere usata per il boot. Inoltre, il fatto che sia necessario smontare il file system per ridimensionarlo, complica leggermente la pianificazione delle partizioni: è meglio prevedere almeno due partizioni non LVM, una di boot e una di root. In questo modo le operazioni di manutenzione non richiederanno il riavvio da un boot alternativo.
Attenzione, non è obbligatorio che la partizione di root non usi LVM; è solo che diventa una complicazione inutile se tanto il file system non verrà mai allargato. Il problema diventerà evidente più avanti.
Un case study
Questo case study è lo scenario in cui mi sono realmente trovato e che mi ha portato ad approfondire questo software. Si trattava di una macchina con Fedora Core, nella quale si voleva riutilizzare il secondo dei due dischi interni per altri scopi.
Quello che segue è una replica abbastanza fedele di quello che è stato fatto.
Scopo del case study
Lo scenario di partenza è il seguente:
- due dischi fisici, l’uno grande il doppio dell’altro;
- un solo VG;
- due PV;
- due LV, uno di root e l’altro di swap.
Quello di arrivo è:
- un LV di root composto da un solo PV;
- un LV di root composto dal secondo PV a scopo di backup.
Ambiente di test
Useremo Debian 4, sotto Parallels, per illustrare i passi e il contesto delle decisioni prese. Alcune operazioni saranno dettate dalla situazione particolare dell’ambiente di test e terranno conto di elementi non strettamente collegati a LVM; tuttavia penso che questi elementi di contorno rendano il case study più realistico. I tutorial sono necessati per capire l’uso di un dato strumento ma, sul campo, bisogna saper incrociare elementi diversi per arrivare all’obbiettivo.
La virtual machine è configurata in questo modo:
- il disco di boot, da 32GB (il default) sul bus IDE 0:0 e mappato sotto
/dev/hda; - il secondo disco, da 16GB sul bus IDE 1:0 e mappato sotto
/dev/hdc; - un disco di backup, da 32GB sul bus IDE 1:1 e mappato sotto
/dev/hdd;
Sistema operativo
Debian 4 propone 4 tipi di partizioni:
- un disco intero;
- un disco intero, con LVM;
- un disco intero, con LVM criptato;
- manuale.
Sceglieremo la seconda opzione, con una sola partizione, aggiungendo manualmente il secondo disco in un secondo momento. Il nome di default per il VG è uguale al nome dell’host, in questo caso debian4lvm e il bootloader usato è GRUB. Ad installazione terminata abbiamo:
# vgdisplay --- Volume group --- VG Name debian4lvm System ID Format lvm2 Metadata Areas 1 Metadata Sequence No 3 VG Access read/write VG Status resizable MAX LV 0 Cur LV 2 Open LV 2 Max PV 0 Cur PV 1 Act PV 1 VG Size 31.01 GB PE Size 4.00 MB Total PE 7938 Alloc PE / Size 7938 / 31.01 GB Free PE / Size 0 / 0 VG UUID K1SsHH-eJv3-cDir-j0HQ-JXaz-qPvn-zRCytB
# pvdisplay --- Physical volume --- PV Name /dev/hda5 VG Name debian4lvm PV Size 31.01 GB / not usable 0 Allocatable yes (but full) PE Size (KByte) 4096 Total PE 7938 Free PE 0 Allocated PE 7938 PV UUID fOw6Im-tcAV-oBbH-9yt3-gMfQ-zW2I-sME5bq
# lvdisplay --- Logical volume --- LV Name /dev/debian4lvm/root VG Name debian4lvm LV UUID SylknN-CQxH-2mv6-32Dc-FLDg-frIG-zdQ3gA LV Write Access read/write LV Status available # open 1 LV Size 30.27 GB Current LE 7750 Segments 1 Allocation inherit Read ahead sectors 0 Block device 254:0 --- Logical volume --- LV Name /dev/debian4lvm/swap_1 VG Name debian4lvm LV UUID PXaaOb-yl4Y-J9NR-6q73-2cqw-8zjd-3JlfiP LV Write Access read/write LV Status available # open 2 LV Size 752.00 MB Current LE 188 Segments 1 Allocation inherit Read ahead sectors 0 Block device 254:1
Secondo disco
Aggiungiamo il secondo disco, dopo averlo formattato con fdisk:
# fdisk /dev/hdc Command (m for help): n Command action e extended p primary partition (1-4) p Partition number (1-4): 1 First cylinder (1-2039, default 1):<RETURN> Using default value 1 Last cylinder or +size or +sizeM or +sizeK (1-2039, default 2039): <RETURN> Command (m for help): t Partition number (1-4): 1 Hex code (type L to list codes): 8e Changed system type of partition 2 to 8e (Linux LVM) Command (m for help): w
per poi aggiungerlo al VG creata all’inizio:
# pvcreate /dev/hdc1 # vgextend debian4lvm /dev/hdc1
Adesso avremo:
# pvdisplay --- Physical volume --- PV Name /dev/hda5 VG Name debian4lvm PV Size 31.01 GB / not usable 0 Allocatable yes (but full) PE Size (KByte) 4096 Total PE 7938 Free PE 0 Allocated PE 7938 PV UUID fOw6Im-tcAV-oBbH-9yt3-gMfQ-zW2I-sME5bq --- Physical volume --- PV Name /dev/hdc1 VG Name debian4lvm PV Size 15.62 GB / not usable 0 Allocatable yes PE Size (KByte) 4096 Total PE 3998 Free PE 3998 Allocated PE 0 PV UUID 2dWjqG-Z9nS-t56H-4PZo-ubwg-psId-BnKpVj
# vgdisplay --- Volume group --- VG Name debian4lvm System ID Format lvm2 Metadata Areas 2 Metadata Sequence No 4 VG Access read/write VG Status resizable MAX LV 0 Cur LV 2 Open LV 2 Max PV 0 Cur PV 2 Act PV 2 VG Size 46.62 GB PE Size 4.00 MB Total PE 11936 Alloc PE / Size 7938 / 31.01 GB Free PE / Size 3998 / 15.62 GB VG UUID K1SsHH-eJv3-cDir-j0HQ-JXaz-qPvn-zRCytB
# lvdisplay --- Logical volume --- LV Name /dev/debian4lvm/root VG Name debian4lvm LV UUID SylknN-CQxH-2mv6-32Dc-FLDg-frIG-zdQ3gA LV Write Access read/write LV Status available # open 1 LV Size 30.27 GB Current LE 7750 Segments 1 Allocation inherit Read ahead sectors 0 Block device 254:0 --- Logical volume --- LV Name /dev/debian4lvm/swap_1 VG Name debian4lvm LV UUID PXaaOb-yl4Y-J9NR-6q73-2cqw-8zjd-3JlfiP LV Write Access read/write LV Status available # open 2 LV Size 752.00 MB Current LE 188 Segments 1 Allocation inherit Read ahead sectors 0 Block device 254:1
Ovvero, vediamo il nuovo PV e la capacità massima del VG è diventata di circa 46GB mentre i LV sono rimasti invariati.
Adesso possiamo allargare il LV: il nuovo PV è grande 15.62GB ma dobbiamo ridurre di 0.01GB per errori di arrotondamento (almeno credo… se usassimo i blocchi potremmo essere più precisi):
# lvextend -L+15.61G /dev/debian4lvm/root
adesso abbiamo:
--- Logical volume --- LV Name /dev/debian4lvm/root VG Name debian4lvm LV UUID SylknN-CQxH-2mv6-32Dc-FLDg-frIG-zdQ3gA LV Write Access read/write LV Status available # open 1 LV Size 45.89 GB Current LE 11747 Segments 2 Allocation inherit Read ahead sectors 0 Block device 254:0 --- Logical volume --- LV Name /dev/debian4lvm/swap_1 VG Name debian4lvm LV UUID PXaaOb-yl4Y-J9NR-6q73-2cqw-8zjd-3JlfiP LV Write Access read/write LV Status available # open 2 LV Size 752.00 MB Current LE 188 Segments 1 Allocation inherit Read ahead sectors 0 Block device 254:1
Estensione del file system
Per poter allargare il file system, dobbiamo smontarlo. Tuttavia, dato che la partizione di root è una sola dobbiamo fare il boot da un altra unità. Abbiamo due possibilità: a) usare un CD di recupero; b) aggiungere un secondo disco di dimensioni adeguate e usarlo come boot alternativo e, nello stesso tempo, come backup per il disco principale.
Seguiamo la seconda soluzione, ispirata a questo HOWTO, usando il disco sotto /dev/hdd. Esso dovrà essere formattato in modo da poter essere usato come disco di boot alternativo (senza usare LVM).
Dobbiamo creare tre partizioni: una di boot da 247MB, una di swap da 752MB e il resto lo dedichiamo alla partizione di root. Le dimensioni delle prime due partizioni sono desunte da quelle in uso. Dato che usiamo sempre fdisk, rimando ancora a questo HOWTO per i dettagli.
Formattiamo le partizioni:
# mkfs.ext3 /dev/hdd1 # mkfs.ext3 /dev/hdd3 # mkswap /dev/hdd2
Creiamo una directory di mount per il nuovo disco e montiamolo:
# mkdir /new-hd # mount -t ext3 /dev/hdd3 /new-hd # mkdir /new-hd/boot # mount -t ext3 /dev/hdd1 /new-hd/boot
Prima di copiare i dati, mettiamoci in single user mode:
# /sbin/telinit 1
Per copiare i dati ci sono diverse possibilità. Le più semplice consiste nell’usare cp:
# cp -ax / /new-hd
Il flag -a cerca di preservare ogni carattertistica dei file, mentre il flag -x evita che la copia “attraversi” i file system, in modo che new-hd non venga copiato.
Un’altra possibilità è quella di usare rsync (che può non essere installato, dipende dalle opzioni scelte all’inizio):
# rsync -ax --delete --force --exclude /new-hd / /new-hd # rsync -ax --delete --force --exclude /new-hd /boot /new-hd/boot
in questo caso useremo quest’ultima.
Il disco di backup non sarebbe disponibile per il boot, a causa della sua posizione sul bus IDE, per cui scambiamo la sua posizione con quella occupata dal CD.
Questo ha due implicazioni: 1) /dev/hdb, prima usato per il CD, adesso fa riferimento al nuovo disco; 2) l’fstab è disallineato, dato che indica /dev/hdb come device per il mount dei CD.
Quindi modifichiamo l’/etc/fstab sotto /new-hd. Il disco hdd diventa hdb e il CD-ROM diventa hdd:
… /dev/hdb3 / ext3 … /dev/hdb1 /boot ext3 … /dev/hdb2 none swap … /dev/hdd /media/cdrom udf,iso9660 … …
Per eseguire il boot dal disco di backup, dopo averne scambiato la posizione con il lettore, usiamo GRUB, passandogli questi parametri:
root(hd1,0) kernel /vmlinux-2.6.18-4-686 root=/dev/hdb3 ro single initrd /initrd.img-2.6.18-4-686
A boot avvenuto, espandiamo la partizione di root:
fsck.ext3 -f /dev/debian4lvm/root resize2fs /dev/debian4lvm/root
da notare che senza nessuna indicazione l’espansione del volume occuperà tutto il LV.
Distacco del secondo hd
A questo punto abbiamo replicato lo scenario di partenza: un disco di boot composto da due volumi logici. Adesso, per poter sganciare il secondo disco dovremo semplicemente fare queste operazioni:
- Ridurre le dimensioni del file system montato sul LV:
# fsck.ext3 -f /dev/debian4lvm/root # resize2fs /dev/debian4lvm/root 25G - Ridurre le dimensioni del LV:
# lvreduce -L26G /dev/debian4lvm/root - Rimuovere il disco fisico dal VG:
# vgreduce debian4lvm /dev/hdc1 - Rimuovere il PV:
# pvremove /dev/hdc1
Forse prima avete notato che ho usato una dimensione molto inferiore a quella massima disponibile. Questo è stato fatto per assicurarsi che il secondo PV fosse libero. Ovviamente, un approccio del genere è possibile solo se si ha spazio a sufficienza sul primo PV.
Per riutilizzare di nuovo tutto il PV usiamo lvextend specificando un numero di LE ricavato da pvdisplay:
# lvextend -l +1094 /dev/debian4lvm/root
È tutto!
Appendice 1. Link utili
Questi sono i link agli articoli che ho usato come riferimento nell’intervento e nella stesura del case study.
- Managing Disk Space with LVM;
- Learning Linux LVM(parti 1 e 2);
- LVM HowTo;
- Operazioni comuni. Vengono riportati – molto sinteticamente – i comandi per diverse operazioni di routine. Da tenere come reference quando le idee sono già chiare.
- Ricette. In particolare:
- uso delle istantanee per fare il backup: l’idea è quella di fare il backup dell’istantanea, in modo da essere isolati dalle modifiche al LV in uso;
- rimozione di un disco: lo scenario tipico è quello della sostituzione di un disco con un altro oppure della redistribuzione del contenuto di un disco su gli altri dischi di un VG;
- spostare un VG su un altro sistema: con la coppia
vgexportevgimportè possibile spostare in modo sicuro (impedendo
accessi durante le operazioni di manutenzione) i VG da un sistema ad un altro; - suddivisione di un VG: creazione di un nuovo VG riallocando risorse da VG esistente;
- A beginner’s guide to LVM;
- A simple introduction to working with LVM. Data la criticità delle operazioni è bene sapere che LVM conserva una serie di file di backup sotto /etc/lvm/backup e un log delle operazioni sotto /etc/lvm/archive;
- Back Up (And Restore) LVM Partitions With LVM Snapshots. Le snapshot sono copie consistenti di un file system e una delle possibilità più interessanti offerte da LVM2 è quelli creare delle snapshot modificabili;
- Recover Data From RAID1 LVM Partitions With Knoppix Linux LiveCD. Descrizione di un ipotetico recupero dati a partire da
un singolo disco su cui era construito un RAID1 (conmadm), a sua volta usato da LVM. Per tutte le operazioni viene usato un Knoppx LiveCD; - Altri link su del.icio.us (comprendono anche quelli elencati qui sopra…).
Appendice 2. ZFS
Dato che ZFS è un file system che probabilmente verrà usato anche sotto Mac OS X ed è implementato, in forma ancora sperimentale, su FreeBSD 7, pensavo sarebbe stato utile qualche accenno a ZFS.
I link che seguono dovrebbero dare un’idea più precisa delle sue peculiarità:
- What is ZFS? se andate di fretta e volete avere un’idea di quello che offre ZFS, questo link da per voi;
- ZFS Overview and Guide una veloce carrellata sui principali comandi,
zpoole zfs; - ZFS vs. Linux Raid vs. Linux LVM vs. Linux LVM + Raid tabelle riassuntive per mettere a confronto le architetture di storage.
- Altri link su del.icio.us (comprendono anche quelli elencati qui sopra…).

Commenti su LVM
4 risposta
Linux Volume Manager (LVM) - ReFactor.it (24/11/07)
[…] aggiunto un articolo sull’LVM (chiamiamolo così…). Prego usare il form dei commenti ;-) Scritto il 24÷11÷07 da giorgio_v. […]
Aggiornamento pagina su LVM - ReFactor.it (06/03/08)
[…] LVM […]
Note operative sull’LVM « Diavoletto76’s Weblog (27/05/08)
[…] volentieri il post dell’amico/collega Giorgio, da cui ho tratto parecchi spunti per la compilazione di questo […]
Ork (10/07/09)
2 piccole correzioni:
1) Non è vero che non si può fare boot da LVM, basta usare lilo, grub2 o grub patchato.
2) Non è vero che bisogna smontare il filsystem per ridimensionarlo, dipende solo dal filesystem e non lvm: reiserfs può essere ridimensionato senza essere smontato, e sperimentalmente anche ext3.