Estendere una partizione LVM su una VM CentOS

centos

Pochi giorni fa ho avuto la necessità di aumentare la dimensione di un HD virtuale sulla quale era presente un'installazione di CentOS 6.4. La piattaforma di virtualizzazione era l'immancabile VMware vSphere mentre la distro Linux era installata su una partizione LVM. Aumentare le dimensioni del disco virtuale è una baggianata; basta infatti loggarsi tramite vSphere Client oppure vSphere Web Client e incrementare la dimensione del disco al valore desiderato. Non è invece altrettanto banale estendere la partizione LVM sul quale è installato CentOS per trarre vantaggio di quei GB disponibili in più che sono visti dal sistema operativo come spazio non partizionato.

NOTA BENE: dato che la procedura richiederà di effettuare la modifica della tabella delle partizioni suggerisco caldamente di effettuare un backup di tutti i dati. Se invece l'operazione va fatta su un ambiente di produzione è meglio tenere su le antenne e prepararsi ad ogni eventualità in modo che nel peggiore dei casi il fermo macchina sia il più limitato possibile. La virtualizzazione ci può aiutare parecchio in quando non dobbiamo più fare l'immagine dell'intero sistema e poi doverla ripristinare in caso di disastro. Ci basterà prendere uno snapshot o effettuare un backup con i numerosi software messi a disposizione VDP, Veeam, vmProtect, ecc. Per effettuare un testing possiamo sempre clonare la VM, effettuare le modifiche e vedere come il sistema risponde per poi replicare le stesse operazioni sulla VM di produzione una volta soddisfatti del risultato. Nel mio caso la VM era un semplice webserver e non era un sistema critico quindi mi sono limitato ad effettuare un backup.
Il consiglio che vi posso dare è prendete tutto il tempo che vi serve, leggete tutto prima di mettervi all'opera.

La prima cosa da fare è incrementare la dimensione dell'HD della macchina virtuale. In vSphere possiamo fare questo tramite vSphere Client o Web Client mentre la macchina è in funzione. Le immagini seguenti fanno fede al Web Client di vSphere, la procedura è tuttavia la medesima anche con l'applicazione legacy.
Entrate nel menù di configurazione della vm che volete modificare ed editate il parametro relativo alla capienza dell'HD.

esxi-edit-hd-size

Come detto all'inizio qui non c'è nulla di complicato. Ora dobbiamo dire all'OS di utilizzare tutto lo spazio messo a disposizione dal disco. Il primo problema che ci ritroviamo ad affrontare è che la macchina virtuale non si "accorge" al volo che l'HD sulla quale risiede è stato esteso e quindi ci riporta come capacità totale quella precedente all'incremento. Il modo più semplice per risolvere è quello di riavviare la macchina, al successivo reboot il sistema operativo si accorgerà che il disco ha una dimensione maggiore. Ovviamente non estenderà automaticamente la partizione fino a ricoprire l'intera dimensione del disco. Per fare questo dovrete continuare nella lettura.

C'è anche la possibilità di "dire" al sistema operativo che la dimensione del disco è cambiata senza riavviare forzando un rescan dei dischi (non la ho testata personalmente), per fare questo basta dare il comando:

echo "- - -" > /sys/class/scsi_host/host#/scan

Dove host# può essere reperito dando il comando:

ls /sys/class/scsi_host

Per verificare che l'OS abbia effettivamente recepito le nuove dimensioni del disco potete usare il comando:

fdisk -l

Dovreste ottenere qualcosa di questo tipo: (sì già... c'è un motivo se i server vanno tenuti in lingua inglese >.>) ((In questo e in tutti gli output d'esempio successivi ho mascherato il nome del server con myserver. Al posto di segnaposto troverete il nome che avete scelto per la macchina.))

Disco /dev/sda: 53.7 GB, 53687091200 byte

255 testine, 63 settori/tracce, 6527 cilindri
Unità = cilindri di 16065 * 512 = 8225280 byte
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Identificativo disco: 0x000002f4

Dispositivo Boot      Start         End      Blocks   Id  System
/dev/sda1   *           1          64      512000   83  Linux
La partizione 1 non termina al limite del cilindro.
/dev/sda2              64        6528    51915776   8e  Linux LVM

Disco /dev/mapper/vg_myserver-lv_root: 51.0 GB, 51044679680 byte

255 testine, 63 settori/tracce, 6205 cilindri
Unità = cilindri di 16065 * 512 = 8225280 byte
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Identificativo disco: 0x00000000

Disco /dev/mapper/vg_myserver-lv_swap: 2113 MB, 2113929216 byte
255 testine, 63 settori/tracce, 257 cilindri
Unità = cilindri di 16065 * 512 = 8225280 byte
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Identificativo disco: 0x00000000

Se cercate su Google "grow/extend lvm partions" vi compariranno diversi howto e tutorial, nella maggior parte di questi il comando che viene usato per modificare la tabella delle partizioni è fdisk /dev/sda. La cosa non è sbagliata ma è parecchio rischiosa. Di default questa utility usa come unità di misura i cilindri. Se per caso la partizione sulla quale si vuole effettuare l'estensione non inizia alla fine del cilindro della partizione precedente l'operazione potrebbe portare alla perdita di dati. Vediamo un esempio:

cylinder start cylinder end
/dev/sda1 1 15
/dev/sda2 15 300

La cosa funzionerebbe invece in questo caso:

cylinder start cylinder end
/dev/sda1 1 14
/dev/sda2 15 300

Per andare sul sicuro quindi è meglio usare l'unità più piccola a disposizione, il settore. In questo modo se siamo nel primo caso non incorreremo in perdite di dati. Per fare questo usiamo il comando fdisk -u /dev/sda.

[myserver@myserver ~]$ sudo fdisk -u /dev/sda

WARNING: DOS-compatible mode is deprecated. It's strongly recommended to
         switch off the mode (command 'c').

Comando (m per richiamare la guida): p

Disco /dev/sda: 53.7 GB, 53687091200 byte

255 testine, 63 settori/tracce, 6527 cilindri, totale 104857600 settori
Unità = settori di 1 * 512 = 512 byte
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
Identificativo disco: 0x000002f4

Dispositivo Boot      Start         End      Blocks   Id  System
/dev/sda1   *        2048     1026047      512000   83  Linux
La partizione 1 non termina al limite del cilindro.
/dev/sda2         1026048   104857599    51915776   8e  Linux LVM

Comando (m per richiamare la guida):

Come potete notare utilizzando il parametro -u l'utility ci riporta 104857600 settori e non più 6527 cilindri.
Per qualsiasi informazione potete scrivere m e vi verrà visualizzata una veloce guida ad fdisk.

Comando (m per richiamare la guida): m
Azione comando
   a  Cambia bootable flag
   b   modifica di bsd disklabel
   c   cambia il flag compatibile con il dos
   d   cancellazione di una partizione
   l   elenco dei tipi di partizione conosciuti
   m   stampa di questo menu
   n   aggiunta di una nuova partizione
   o   creazione di una nuova tabella delle partizioni DOS vuota
   p   stampa della tabella delle partizioni
   q   uscita senza salvataggio delle modifiche
   s   creazione di una nuova disklabel Sun vuota
   t   modifica l'id di sistema di una partizione
   u   modifica delle unità di visualizzazione/di immissione
   v   verifica la tabella delle partizioni
   w   scrivi la tabella su disco ed esci
   x   ulteriori funzioni (solo per esperti)

Memorizziamo (o scriviamoci da qualche parte) due numeri, il numero di settori totali del disco fisso. Dato che ovviamente non corrisponderà con la fine della partizione /dev/sda2, in quanto il disco è stato espanso. Nel mio caso il totale dei settori è praticamente uguale al settore finale della partizione 2 (la differenza è di un settore), questo perchè la mia partizione /dev/sda2 in LVM è già stata estesa per sfruttare al massimo la capienza messa a disposizione del disco. Tutto questo perchè semplicemente non avevo voglia di tornare indietro e rifare tutto da capo e catturare l'output corretto. 😀
L'altro dato da memorizzare è il settore in cui inizia la partizione da ridimensionare.

Se facciamo fede all'esempio sopra i dati che devono essere trascritti sono 104857600 (settori totali del disco) e 1026048 (settore iniziale di /dev/sda2). Armati di questi valori possiamo cominciare a modificare le partizione. Questi sono i passaggi nella quale bisogna fare molta attenzione!

Rimuoviamo la partizione 2 (quella appunto che devo estendere) dando il comando:

d

E poi il numero dalla partizione:

2

Ora ricreiamo la partizione con:

n

E impostiamola come primaria con:

p

Ci verrà chiesto da che settore la partizione dovrà iniziale. Dobbiamo ASSOLUTAMENTE inserire nel modo corretto il valore del settore iniziale di /dev/sda2 che ci siamo segnati prima. Seguendo gli esempi fatti io dovrei inserire 1026048. Sbagliare questo significa dire "bye bye" alla cara sda2. 😀

1026048

Scriviamo anche il valore del settore finale. Di default fdisk assegna tutto lo spazio rimanente, quindi ci basterà premere invio. Se così non fosse potete scrivere l'altro valore che vi siete annotati, ossia il numero massimo di settori disponibili sul disco. Magari sottraete un settore da tutti quelli disponibili. Quindi facendo fede al mio esempio invece di scrivete 104857600 io scriverei 104857599.

Ora settiamo che tale partizione è di tipo lvm con:

t

Scriviamo il valore della partizione a cui vogliamo assegnare l'attributo lvm (/dev/sda2 è corrispondete alla partizione 2 del disco /dev/sda)

2

Ed infine diciamo ad fdisk che la partizione sarà ti tipo lvm assegnando l'attributo:

8e

Concludiamo con la scrittura delle modifiche sulla tabella delle partizioni.

w

Ed infine riavviamo il PC. Se tutto è stato fatto in modo corretto non dovreste perdere nulla e il PC si riavvierà in maniera corretta.

Non è finita, a questo appunto abbiamo una tabella consistente con la situazione che vorremmo ottenere. Dobbiamo però mettere ancora mano al gestore LVM per poter utilizzare lo spazio aggiunto.

Usate uno di questi tre comandi per visualizzare lo stato del volume volume logico

lvdisplay
vgdisplay
pvdisplay

Dovreste ottenere qualcosa di questo tipo:

[myserver@myserver ~]$ lvdisplay
  --- Logical volume ---
  LV Path                /dev/vg_myserver/lv_root
  LV Name                lv_root
  VG Name                vg_myserver
  LV UUID                jmlmyU-14HQ-1xTa-JALE-zf71-8ryT-j83jGc
  LV Write Access        read/write
  LV Creation host, time myserver.localdomain.local, 2012-09-11 19:01:14 +0200
  LV Status              available
  # open                 1
  LV Size                47,54 GiB
  Current LE             12170
  Segments               2
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:0

  --- Logical volume ---
  LV Path                /dev/vg_myserver/lv_swap
  LV Name                lv_swap
  VG Name                vg_myserver
  LV UUID                NzY5Du-p32O-wRgx-wPco-Z9k4-HaEd-EwOwrW
  LV Write Access        read/write
  LV Creation host, time myserver.localdomain.local, 2012-09-11 19:01:19 +0200
  LV Status              available
  # open                 1
  LV Size                1,97 GiB
  Current LE             504
  Segments               1
  Allocation             inherit
  Read ahead sectors     auto
  - currently set to     256
  Block device           253:1

Ora date questo comando per espandere il PV in modo che si mangi tutto lo spazio disponibile messo a disposizione da /dev/sda2.

pvresize /dev/sda2

Diamo il comando vgdisplay e soffermiamoci sul valore di Free PV / Size. Il comando genererà un output di questo tipo:

myserver@myserver~]$vgdisplay

 --- Volume group ---
  VG Name               vg_myserver
  System ID
  Format                lvm2
  Metadata Areas        1
  Metadata Sequence No  5
  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               49,51 GiB
  PE Size               4,00 MiB
  Total PE              12674
  Alloc PE / Size       12674 / 49,51 GiB
  Free  PE / Size       0 / 0
  VG UUID               pcw3Re-htRU-COXz-jMCo-fmcu-jTPM-VFdOoD

Il mio Free PE / Size è di 0 perchè, come detto sopra, il mio volume è già stato esteso. Nel vostro caso alla voce Free PE / Size ci sarà la differenza tra la dimensione attuale del disco e quella precedente alla sua estensione. Quindi se partiamo con 10GB e portiamo il disco a 40GB il valore di PE Size sarà approssimativamente di 30GB. Annotatevi il primo valore.

Diamo nuovamente il comando lvdisplay e scopriamo qual'è il nome (e relativo path) del nostro volume logico. Tale informazione si trova sotto la voce di LV Path. Ad esempio, dal mio lvdisplay postato sopra si evince che il mio volume logico root è questo: /dev/vg_myserver/lv_root

Siamo quasi alla fine. 🙂

Ora finalmente estendiamo il volume logico con:

lvextend -l +X /dev/vg_myserver/lv_root

Dove X è il primo valore che trovate sotto la voce Free PE / Size.

Effettuiamo ora l'estensione del filesystem con il comando:

resize2fs /dev/vg_myserver/lv_root

Ora con:

lvdisplay /dev/vg_myserver/lv_root

ammiriamo i frutti del nostro lavoro.

Come ultimo comando diamo:

e2fsck -f /dev/vg_myserver/lv_root

Ovviamente in questi ultimi due comandi dovrete sostituire "/dev/vg_myserver/lv_root" con il vostro LV Path. 😉

Come avete visto la procedura in se non è per niente difficile, basta porre un attimo di attenzione e degnarsi di leggere tutti i passi da intraprendere prima di mettersi a smanettare. Sfortunatamente non sono a conoscenza di un'applicazione GUI che permetta di fare ciò in modo più veloce e sicuro. Editor di partizionamento come gParted non supportano l'estensione di di dischi gestiti da un software LVM. =(