Mondi su mondi, sistemi di sistemi.

LVM

Cos’è LVM

LVM sta per Logical Volume Manager e con­sente di gestire lo sto­rage in modo più fles­si­bile intro­du­cendo uno strato inter­me­dio tra i dischi (fisici) e i file system.

Senza LVM avremmo:

  1. dischi;
  2. par­ti­zioni: ogni par­ti­zione può occu­pare al mas­simo un disco;
  3. file system: ogni file system può occu­pare al mas­simo una partizione.

Con LVM abbiamo:

  1. dischi fisici, quelli veri ;-);
  2. dischi fisici (PV);
  3. volume group (VG): asso­cia i PV ai volumi logici;
  4. volumi logici (LV);
  5. file system.

I PV cor­ri­spon­dono alle par­ti­zioni così come le cono­sciamo nel mondo Mac ed è al di sopra di que­sti che LVM aggiunge quel livello d’indirezione che con­sente ai LV di essere defi­niti in ter­mini di “somma” di PV.

Una limi­ta­zione di LVM è data dal fatto che una par­ti­zione LVM non può essere usata per il boot. Inoltre, il fatto che sia neces­sa­rio smon­tare il file system per ridi­men­sio­narlo, com­plica leg­ger­mente la pia­ni­fi­ca­zione delle par­ti­zioni: è meglio pre­ve­dere almeno due par­ti­zioni non LVM, una di boot e una di root. In que­sto modo le ope­ra­zioni di manu­ten­zione non richie­de­ranno il riav­vio da un boot alternativo.

Attenzione, non è obbli­ga­to­rio che la par­ti­zione di root non usi LVM; è solo che diventa una com­pli­ca­zione inu­tile se tanto il file system non verrà mai allar­gato. Il pro­blema diven­terà evi­dente più avanti.

Un case study

Questo case study è lo sce­na­rio in cui mi sono real­mente tro­vato e che mi ha por­tato ad appro­fon­dire que­sto soft­ware. Si trat­tava di una mac­china con Fedora Core, nella quale si voleva riu­ti­liz­zare il secondo dei due dischi interni per altri scopi.

Quello che segue è una replica abba­stanza fedele di quello che è stato fatto.

Scopo del case study

Lo sce­na­rio di par­tenza è il seguente:

  • due dischi fisici, l’uno grande il dop­pio dell’altro;
  • un solo VG;
  • due PV;
  • due LV, uno di root e l’altro di swap.

Quello di arrivo è:

  • un LV di root com­po­sto da un solo PV;
  • un LV di root com­po­sto dal secondo PV a scopo di backup.

Ambiente di test

Useremo Debian 4, sotto Parallels, per illu­strare i passi e il con­te­sto delle deci­sioni prese. Alcune ope­ra­zioni saranno det­tate dalla situa­zione par­ti­co­lare dell’ambiente di test e ter­ranno conto di ele­menti non stret­ta­mente col­le­gati a LVM; tut­ta­via penso che que­sti ele­menti di con­torno ren­dano il case study più rea­li­stico. I tuto­rial sono neces­sati per capire l’uso di un dato stru­mento ma, sul campo, biso­gna saper incro­ciare ele­menti diversi per arri­vare all’obbiettivo.

La vir­tual machine è con­fi­gu­rata in que­sto modo:

  • il disco di boot, da 32GB (il default) sul bus IDE 0:0 e map­pato sotto /dev/hda;
  • il secondo disco, da 16GB sul bus IDE 1:0 e map­pato sotto /dev/hdc;
  • un disco di bac­kup, da 32GB sul bus IDE 1:1 e map­pato sotto /dev/hdd;

Sistema ope­ra­tivo

Debian 4 pro­pone 4 tipi di partizioni:

  1. un disco intero;
  2. un disco intero, con LVM;
  3. un disco intero, con LVM criptato;
  4. manuale.

Sceglieremo la seconda opzione, con una sola par­ti­zione, aggiun­gendo manual­mente il secondo disco in un secondo momento. Il nome di default per il VG è uguale al nome dell’host, in que­sto caso debian4lvm e il boo­tloa­der usato è GRUB. Ad instal­la­zione ter­mi­nata 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 for­mat­tato 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 aggiun­gerlo 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 capa­cità mas­sima del VG è diven­tata di circa 46GB men­tre i LV sono rima­sti invariati.

Adesso pos­siamo allar­gare il LV: il nuovo PV è grande 15.62GB ma dob­biamo ridurre di 0.01GB per errori di arro­ton­da­mento (almeno credo… se usas­simo i bloc­chi 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 allar­gare il file system, dob­biamo smon­tarlo. Tuttavia, dato che la par­ti­zione di root è una sola dob­biamo fare il boot da un altra unità. Abbiamo due pos­si­bi­lità: a) usare un CD di recu­pero; b) aggiun­gere un secondo disco di dimen­sioni ade­guate e usarlo come boot alter­na­tivo e, nello stesso tempo, come bac­kup per il disco principale.

Seguiamo la seconda solu­zione, ispi­rata a que­sto HOWTO, usando il disco sotto /dev/hdd. Esso dovrà essere for­mat­tato in modo da poter essere usato come disco di boot alter­na­tivo (senza usare LVM).

Dobbiamo creare tre par­ti­zioni: una di boot da 247MB, una di swap da 752MB e il resto lo dedi­chiamo alla par­ti­zione di root. Le dimen­sioni delle prime due par­ti­zioni sono desunte da quelle in uso. Dato che usiamo sem­pre fdisk, rimando ancora a que­sto HOWTO per i dettagli.

Formattiamo le partizioni:


# mkfs.ext3 /dev/hdd1
# mkfs.ext3 /dev/hdd3
# mkswap /dev/hdd2

Creiamo una direc­tory 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, met­tia­moci in sin­gle user mode:


# /sbin/telinit 1

Per copiare i dati ci sono diverse pos­si­bi­lità. Le più sem­plice con­si­ste nell’usare cp:


# cp -ax / /new-hd

Il flag -a cerca di pre­ser­vare ogni carat­ter­ti­stica dei file, men­tre il flag -x evita che la copia “attra­versi” i file system, in modo che new-hd non venga copiato.
Un’altra pos­si­bi­lità è quella di usare rsync (che può non essere instal­lato, 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 que­sto caso use­remo quest’ultima.

Il disco di bac­kup non sarebbe dispo­ni­bile per il boot, a causa della sua posi­zione sul bus IDE, per cui scam­biamo la sua posi­zione con quella occu­pata dal CD.
Questo ha due impli­ca­zioni: 1) /dev/hdb, prima usato per il CD, adesso fa rife­ri­mento al nuovo disco; 2) l’fstab è disal­li­neato, dato che indica /dev/hdb come device per il mount dei CD.
Quindi modi­fi­chiamo 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 ese­guire il boot dal disco di bac­kup, dopo averne scam­biato la posi­zione con il let­tore, usiamo GRUB, pas­san­do­gli que­sti 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 avve­nuto, espan­diamo la par­ti­zione di root:


fsck.ext3 -f /dev/debian4lvm/root
resize2fs /dev/debian4lvm/root

da notare che senza nes­suna indi­ca­zione l’espansione del volume occu­perà tutto il LV.

Distacco del secondo hd

A que­sto punto abbiamo repli­cato lo sce­na­rio di par­tenza: un disco di boot com­po­sto da due volumi logici. Adesso, per poter sgan­ciare il secondo disco dovremo sem­pli­ce­mente fare que­ste operazioni:

  1. Ridurre le dimen­sioni del file system mon­tato sul LV:
    
    # fsck.ext3 -f /dev/debian4lvm/root
    # resize2fs /dev/debian4lvm/root 25G
    
  2. Ridurre le dimen­sioni del LV:
    
    # lvreduce -L26G /dev/debian4lvm/root
    
  3. Rimuovere il disco fisico dal VG:
    
    # vgreduce debian4lvm /dev/hdc1
    
  4. Rimuovere il PV:
    
    # pvremove /dev/hdc1
    

Forse prima avete notato che ho usato una dimen­sione molto infe­riore a quella mas­sima dispo­ni­bile. Questo è stato fatto per assi­cu­rarsi che il secondo PV fosse libero. Ovviamente, un approc­cio del genere è pos­si­bile solo se si ha spa­zio a suf­fi­cienza sul primo PV.

Per riu­ti­liz­zare di nuovo tutto il PV usiamo lvextend spe­ci­fi­cando un numero di LE rica­vato da pvdisplay:


# lvextend -l +1094 /dev/debian4lvm/root

È tutto!

Appendice 1. Link utili

Questi sono i link agli arti­coli che ho usato come rife­ri­mento nell’intervento e nella ste­sura del case study.

Appendice 2. ZFS

Dato che ZFS è un file system che pro­ba­bil­mente verrà usato anche sotto Mac OS X ed è imple­men­tato, in forma ancora spe­ri­men­tale, su FreeBSD 7, pen­savo sarebbe stato utile qual­che accenno a ZFS.

I link che seguono dovreb­bero dare un’idea più pre­cisa delle sue peculiarità: