Il modo migliore per vedere come funziona LVM è metterlo in pratica, possibilmente su un computer di prova che può essere sacrificato per i nostri esperimenti.
Vediamo qui la procedura adottata per migrare su un sistema RedHat Linux 8 la directory /home da una normale partizione fisica ad una partizione basata su LVM.
Quanto riportato può essere utile, oltre che per avere un'idea dei pochi comandi necessari, per tutti i casi in cui non si è usato LVM durante l'installazione e si decide di implementarlo in tempi successivi.
[root@89 /]# cat /proc/partitions
Visualizziamo innanzitutto quali partizioni sono presenti sui dischi collegati al sistema. Si nota hda variamente partizionato e hdc e hdd senza partizioni
major minor #blocks name rio rmerge rsect ruse wio wmerge wsect wuse running use aveq
22 0 3528000 hdc 6 6 24 30 1 3 8 0 0 30 30
22 64 2481696 hdd 1 3 8 10 0 0 0 0 0 10 10
3 0 4224150 hda 14048 39349 183186 149870 4952 10187 82764 480080 0 119420 639100
3 1 104391 hda1 31 80 222 580 17 8 50 4460 0 3180 5040
3 2 2072385 hda2 6159 3376 75626 60190 1231 3020 34880 188820 0 69350 257130
3 3 522112 hda3 7193 32990 80366 46130 1525 5005 13210 220250 0 53150 267410
3 4 1 hda4 0 0 0 0 0 0 0 0 0 0 0
3 5 755023 hda5 23 97 306 290 11 5 104 2910 0 3200 3200
3 6 570276 hda6 629 2769 26530 42520 2168 2149 34520 63640 0 22540 106160
3 7 192748 hda7 9 25 104 100 0 0 0 0 0 100 100
[root@89 /]# mount
Di fatto tutto il sistema è montato su partizioni di hda
/dev/hda3 on / type ext3 (rw)
none on /proc type proc (rw)
/dev/hda1 on /boot type ext3 (rw)
none on /dev/pts type devpts (rw,gid=5,mode=620)
/dev/hda5 on /home type ext3 (rw)
none on /dev/shm type tmpfs (rw)
/dev/hda2 on /usr type ext3 (rw)
/dev/hda6 on /var type ext3 (rw)
A questo punto decidiamo di creare dei fisical device usando hdc e hdd
[root@89 /]# pvcreate /dev/hdc
pvcreate -- physical volume "/dev/hdc" successfully created
[root@89 /]# pvcreate /dev/hdd
pvcreate -- physical volume "/dev/hdd" successfully created
[root@89 /]# pvscan
Il comando pvscan è utile per visualizzare lo stato dei PV
pvscan -- reading all physical volumes (this may take a while...)
pvscan -- inactive PV "/dev/hdc" is in no VG [3.36 GB]
pvscan -- inactive PV "/dev/hdd" is in no VG [2.37 GB]
pvscan -- total: 2 [5.73 GB] / in use: 0 [0] / in no VG: 2 [5.73 GB]
Possiamo creare un Volume Group, utilizzando i PV appena creati. Notare che avremmo potuto usare un unico comando (vgcreate /dev/hdc /dev/hdd
) ma abbiamo preferito provare ad estendere il gruppo (chiamato "grumo") appena creato con il comando vgextend
[root@89 /]# vgcreate grumo /dev/hdc
vgcreate -- INFO: using default physical extent size 4 MB
vgcreate -- INFO: maximum logical volume size is 255.99 Gigabyte
vgcreate -- doing automatic backup of volume group "grumo"
vgcreate -- volume group "grumo" successfully created and activated
[root@89 /]# vgdisplay
Comando utile per visualizzare lo stato di un Volume Group, notare come cambia l'output dopo aver aggiunto il PD hdd
--- Volume group ---
VG Name grumo
VG Access read/write
VG Status available/resizable
VG # 0
MAX LV 256
Cur LV 0
Open LV 0
MAX LV Size 255.99 GB
Max PV 256
Cur PV 1
Act PV 1
VG Size 3.36 GB
PE Size 4 MB
Total PE 860
Alloc PE / Size 0 / 0
Free PE / Size 860 / 3.36 GB
VG UUID 49Urj3-lrwC-3S3k-pF7p-NZ71-1bGg-44QOeF
[root@89 /]# vgextend grumo /dev/hdd
vgextend -- INFO: maximum logical volume size is 255.99 Gigabyte
vgextend -- doing automatic backup of volume group "grumo"
vgextend -- volume group "grumo" successfully extended
[root@89 /]# vgdisplay
--- Volume group ---
VG Name grumo
VG Access read/write
VG Status available/resizable
VG # 0
MAX LV 256
Cur LV 0
Open LV 0
MAX LV Size 255.99 GB
Max PV 256
Cur PV 2
Act PV 2
VG Size 5.72 GB
PE Size 4 MB
Total PE 1464
Alloc PE / Size 0 / 0
Free PE / Size 1464 / 5.72 GB
VG UUID 49Urj3-lrwC-3S3k-pF7p-NZ71-1bGg-44QOeF
A questo punto possiamo creare un Logical Volume. Decidiamo di farlo grande 1 Gigabyte (-L 1G) e di chiamarlo "casa". Con il comando lvdisplay se ne visualizzano le informazioni di base.
Notare che con il comando lvcreate è obbligatorio speficicare il Volume Group in cui crearlo e la dimensione del Logcial Volume (tramite i flag -l o -L).
[root@89 /]# lvcreate -L 1G -n casa grumo
[root@89 /]# lvdisplay /dev/grumo/casa
--- Logical volume ---
LV Name /dev/grumo/casa
VG Name grumo
LV Write Access read/write
LV Status available
LV # 1
# open 0
LV Size 1 GB
Current LE 256
Allocated LE 256
Allocation next free
Read ahead sectors 1024
Block device 58:0
Il nostro Logical Volume /dev/grumo/casa è a tutti gli effetti un device a blocchi che possiamo formattare e montare su una directory del nostro filesystem
[root@89 /]# mkfs.ext3 /dev/grumo/casa
[...]
[root@89 /]# mkdir /mnt/casa
[root@89 /]# mount -t ext3 /dev/grumo/casa /mnt/casa/
[root@89 /]# mount
[...]
/dev/hda6 on /var type ext3 (rw)
/dev/grumo/casa on /mnt/casa type ext3 (rw)
Ne approfittiamo per vedere come appare il modulo LVM
[root@89 /]# lsmod
Module Size Used by Not tainted
loop 11224 0 (autoclean)
lvm-mod 61792 3
autofs 12228 0 (autoclean) (unused)
ne2k-pci 6752 1
8390 7884 0 [ne2k-pci]
ipt_REJECT 3448 6 (autoclean)
iptable_filter 2316 1 (autoclean)
ip_tables 14456 2 [ipt_REJECT iptable_filter]
ext3 64160 6
jbd 48180 6 [ext3]
A questo punto copiamo tutto il contenuto della /home attuale sul LV appena creato e montato temporaneamente su /mnt/casa
[root@89 /]# cp -Ra /home/* /mnt/casa/
Per montare stabilmente la nostra home sul LV dobbiamo modificare /etc/fstab
[root@89 /]# cat /etc/fstab
LABEL=/ / ext3 defaults 1 1
LABEL=/boot /boot ext3 defaults 1 2
none /dev/pts devpts gid=5,mode=620 0 0
LABEL=/home /home ext3 defaults 1 2
none /proc proc defaults 0 0
none /dev/shm tmpfs defaults 0 0
LABEL=/usr /usr ext3 defaults 1 2
LABEL=/var /var ext3 defaults 1 2
/dev/hda7 swap swap defaults 0 0
/dev/cdrom /mnt/cdrom iso9660 noauto,owner,kudzu,ro 0 0
/dev/fd0 /mnt/floppy auto noauto,owner,kudzu 0 0
In particolare modifichiamo il device da montare su /home:
/dev/grumo/casa /home ext3 defaults 1 2
A questo punto possiamo smontare la vecchia home, la directory temporanea /mnt/casa e rimontare home con il nuovo /etc/fstab modificato
[root@89 /]# umount /mnt/casa/
[root@89 /]# umount /home/
[root@89 /]# mount /home/
Tutto fin'ora è filato liscio, le operazione di creazione e gestione di LVM sono state piuttosto facili, la migrazione della home è stata rapida perchè coinvolgeva pochi file, in produzione, con maggiori quantità di dati da spostare, ci sarebbero stati sicuramente tempi e complicazioni maggiori (avremmo fatto una prima copia di tutti i file e poi una rapida sincronizzazione con rsync appena prima di smontare e rimontare il tutto. L'operazione sarebbe stata comunque resa più difficoltosa se ci fossero stati vari utenti locali a lavorare su /home e avrebbe potuto comportare un disservizio forzato di alcuni minuti)
Tutto a posto?
Non esattamente. Abbiamo eseguito il reboot del sistema (sempre consigliabile farlo subito, quando si fanno simili cambiamenti radicali, per essere sicuri che tutto si ripristini senza problemi) e inesorabilmente si è tutto bloccato lasciandoci in mantenance mode:
- Il kernel ha dato un messaggio di errore tipo "kmod: failed to exec /sbin/modprobe -s -k block-major-8, errno = 2
- Al momento di eseguito il mount dei file system, il sistema si è bloccato, non riuscendo a trovare il mount point per /home (di fatto non trovando il nostro Logical Volume /dev/grumo/casa)
L'HowTo e la logica ci hanno fatto capire che il problema stava nel mancato caricamento automatico del modulo LVM (non ci sarebbero stati problemi se avessimo avuto un kernel con il supporto LVM direttamente compilato nel core). Abbiamo provato inizialmente a modificare /etc/modules.conf
aggiungendo la riga:
alias block-major 8 lvm-mod
ma senza risultati.
Allora senza ulteriori indugi, e in modo non particolarmente elegante, ma comunque efficace, abbiamo aggiunto all'INIZIO di /etc/rc.d/rc.sysinit
(il primo script che viene eseguito da init sui sistemi Redhat) il caricamente manuale del modulo:
/sbin/insmod lvm-mod
e il tutto ha finalmente funzionato.
Notare che se non ci fossimo presi la briga di provare subito un reboot, avremmo avuto maggiori problemi al prossimo avvio, senza magari ricordare gli interventi fatti o avere la possibilità di intervenire immediatamente.