Problema generale: questa versione aggiornata dell'articolo propone due soluzioni per un unico problema, ovvero allargare lo spazio su un disco LVM (ovvero ripartizionarlo), accessibile soltanto tramite SSH, su cui gira Linux e alla seguenti condizioni: la partizione logica LVM non può essere smontata (perché su di essa gira il server), né può essere smontata alcuna delle partizioni fisiche che fanno parte dell'LVM.
Caso d'uso specifico: Sebbene Aruba Cloud, nel pannello di amministrazione dei Cloud Server Smart, permetta di fare un upgrade del server, passando ad esempio da Aruba Cloud Server Smart SMALL (20GB) ad Aruba Cloud Server Smart MEDIUM (40GB) o tagli più grandi come LARGE (80GB) o EXTRA LARGE (160GB), non fornisce però alcuna modalità automatica per ridimensionare il disco in modo sicuro. Più precisamente, facendo un upgrade del server, viene aumentato lo spazio disponibile su disco ma non vengono modificate le partizioni preesistenti.
Può Aruba ripartizionare il disco LVM in modo da usare tutto lo spazio disponibile, evitando di obbligare noi sviluppatori o sistemisti a fare a mano tale operazione, con tutti i rischi conseguenti? Ho fatto esplicitamente ad Aruba questa domanda. Ecco la poco incoraggiante risposta: «Possiamo procedere all'espansione del disco (LVM) qualora le condizioni del server lo consentano. Non possiamo garantire che l'intervento sia risolutivo. Verranno calcolate Euro 100,00 che includono le prime 2 ore. Nel caso in cui l'intervento dovesse protrarsi oltre verranno calcolate ulteriori Euro 50,00 per ogni ora aggiuntiva.»
Stando così le cose, e dopo aver dedicato ore e ore a leggermi documentazione disponibile in Rete, ho trovato due strade per affrontare e risolvere il problema di allargare il disco LVM al massimo spazio disponibile su disco.
Disclaimer: Ho provato le due soluzioni seguenti, a mio rischio e pericolo, su un mio server Aruba VPS su cui gira Ubuntu Linux 14.04. Tali passaggi, nel mio caso, hanno funzionato alla grande senza alcun problema. Presumo che gli stessi passaggi funzionino anche con altre distribuzioni Linux, ad ogni modo è tua responsabilità avere un backup integrale del tuo server, nel caso in cui qualcosa vada storto (magari, per ulteriore prudenza, fatti anche uno snapshot del server dal pannello di Aruba e un backup della tabella delle partizioni). Considera che è sufficiente un solo comando sbagliato per perdere tutti i dati. Io non posso garantire in alcun modo che ciò che ha funzionato a me possa funzionare anche a te, quindi stai attento e prima di impartire ogni comando assicurati di aver capito cosa stai facendo.
Le due strade percorribili per allargare il disco LVM senza smontare alcuna delle partizioni esistenti:
- la più sicura è aggiungere una nuova partizione fisica primaria (se il numero massimo di partizioni primarie non è già stato raggiunto);
- la più rischiosa (ma necessaria se non è possibile aggiungere ulteriori partizioni) è "sostituire" con fdisk l'ultima partizione fisica con un'altra che ha le stesse caratteristiche e lo stesso punto di inizio, ma dimensione diversa (ovviamente senza toccare i dati).
Vediamo in dettaglio queste due soluzioni.
CASO 1: ISTRUZIONI PER AGGIUNGERE UNA NUOVA PARTIZIONE FISICA PRIMARIA AL LVM, IN MODO DA OCCUPARE TUTTO IL DISCO
Qui riporto il caso di un allargamento da 20GB a 40GB aggiungendo una nuova partizione.
1. Login tramite SSH
ssh root@nomedominio
2. Controllo dello spazio disponibile
df -h
Prima e dopo l'upgrade del VPS su Aruba, non dovrebbero risultare variazioni di spazio disponibile su /dev/dm-1, che corrisponde alla partizione montata come directory radice
Nel mio caso, ad es., dopo l'upgrade di 20GB, /dev/dm-1 risulta ancora occupata al 99%:
Filesystem Size Used Avail Use% Mounted on udev 990M 4.0K 990M 1% /dev tmpfs 201M 540K 200M 1% /run /dev/dm-1 19G 18G 304M 99% / none 4.0K 0 4.0K 0% /sys/fs/cgroup none 5.0M 0 5.0M 0% /run/lock none 1002M 0 1002M 0% /run/shm none 100M 0 100M 0% /run/user /dev/sda1 236M 40M 185M 18% /boot
3. Do uno sguardo alle partizioni del disco SSD attaccato al VPS:
ls -al /dev/sda* brw-rw---- 1 root disk 8, 0 Mar 8 12:26 /dev/sda brw-rw---- 1 root disk 8, 1 Mar 8 12:26 /dev/sda1 brw-rw---- 1 root disk 8, 2 Mar 8 12:26 /dev/sda2 brw-rw---- 1 root disk 8, 3 Mar 8 12:26 /dev/sda3 brw-rw---- 1 root disk 8, 5 Mar 8 12:26 /dev/sda5
Ho quindi tre partizioni primarie e una logica. Ne segue che almeno una delle partizioni primarie è una partizione estesa. C'è quindi posto per un'altra partizione primaria (ricordo che ogni disco può avere fino a quattro partizioni primarie, numerate da 1 a 4, di cui una può essere una partizione estesa contenente partizioni logiche, che a loro volta sono numerate da 5 in poi).
Sicuramente c'è posto anche un'altra partizione logica, però non posso crearla senza prima estendere la partizione estesa, cosa impossibile perché tutte le partizioni sono montate (e ovviamente non posso smontarle perché l'unica possibilità di accesso al VPS è tramite SSH). Riferimenti per quanto ho appena scritto: https://askubuntu.com/questions/591213/how-to-expand-resize-extended-partition
Da queste poche informazioni, ne segue che, senza smontare nessuna delle partizioni presenti, posso aggiungere una partizione primaria /dev/sda4
4. Creazione di /dev/sda4
cfdisk
Tramite cfdisk, che è un semplice tool grafico di partizionamento, mi posiziono nello spazio libero e credo la partizione primaria /dev/sda4. Da notare che devo manualmente specificare il tipo di file system diverso da quello di default: devo scegliere "Linux LVM".
L'uso di cfdisk è abbastanza intuitivo, se così non fosse rimando alle guide presenti in rete.
Alla fine, salvo il nuovo partizionamento (nel quale non ho toccato minimamente le partizioni preesistenti), e riavvio tramite:
reboot
6. Attendo un minuto, per dare tempo al VPS di riavviarsi, ed eseguo nuovamente il login tramite ssh
7. Inizializzo la nuova partizione per l'uso con LVM
pvcreate /dev/sda4
Il messaggio che ottengo è:
Physical volume "/dev/sda4" successfully created
Nel caso in cui invece si verificasse un messaggio di errore in questo passaggio, rimando a quanto scritto in questa guida:
http://www.joomlaworks.net/blog/item/168-resizing-the-disk-space-on-ubuntu-server-vms-running-on-vmware-esxi-5
8. Controllo qual è il nome del "volume group"
vgdisplay --- Volume group --- VG Name vg System ID Format lvm2 Metadata Areas 2 Metadata Sequence No 9 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 19.76 GiB PE Size 4.00 MiB Total PE 5058 Alloc PE / Size 5058 / 19.76 GiB Free PE / Size 0 / 0 VG UUID yMofmX-iYvO-cOtK-nTf5-cD7d-oc7o-GECO0q
Il "VG Name" è "vg".
9. Aggiungo la partizione precedentemente creata al volume group
vgextend vg /dev/sda4 Volume group "vg" successfully extended
10. Controllo qual è il path del logical volume:
lvdisplay --- Logical volume --- LV Path /dev/vg/lv_swap LV Name lv_swap VG Name vg LV UUID CohmrO-3wcX-zLMV-exxT-gUDu-dAxo-vJhfD4 LV Write Access read/write LV Creation host, time ubuntu, 2014-07-18 10:33:32 +0200 LV Status available # open 2 LV Size 952.00 MiB Current LE 238 Segments 1 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 252:0 --- Logical volume --- LV Path /dev/vg/lv_root LV Name lv_root VG Name vg LV UUID VxYaWt-nPDZ-zTos-Bhbk-0dyz-vlX4-5P06Qc LV Write Access read/write LV Creation host, time ubuntu, 2014-07-18 10:33:44 +0200 LV Status available # open 1 LV Size 18.83 GiB Current LE 4820 Segments 2 Allocation inherit Read ahead sectors auto - currently set to 256 Block device 252:1
In questo caso, l'informazione che mi serve per lo step successivo è: /dev/vg/lv_root
11. Estendo la dimensione del volume logico
lvextend /dev/vg/lv_root /dev/sda4 Extending logical volume lv_root to 38.82 GiB Logical volume lv_root successfully resized
12. Step finale
resize2fs /dev/vg/lv_root resize2fs 1.42.9 (4-Feb-2014) Filesystem at /dev/vg/lv_root is mounted on /; on-line resizing required old_desc_blocks = 2, new_desc_blocks = 3 The filesystem on /dev/vg/lv_root is now 10177536 blocks long.
13. Ho finito: controllo la nuova dimensione del disco e noto che lo spazio occupato non è più 99% (come nello step 2) ma 48%, perché ci sono 20GB in più:
df -h Filesystem Size Used Avail Use% Mounted on udev 990M 4.0K 990M 1% /dev tmpfs 201M 544K 200M 1% /run /dev/dm-1 39G 18G 20G 48% / none 4.0K 0 4.0K 0% /sys/fs/cgroup none 5.0M 0 5.0M 0% /run/lock none 1002M 0 1002M 0% /run/shm none 100M 0 100M 0% /run/user /dev/sda1 236M 40M 185M 18% /boot
Concludo il tutto con un:
reboot
Note finali:
Poiché a questo punto le partizioni primarie sono finite, un eventuale ulteriore incremento dello spazio su disco ripetendo questi passaggi non sarà possibile con questo metodo e sarà necessario il metodo seguente (caso 2).
CASO 2: ISTRUZIONI PER ALLARGARE LO SPAZIO SU DISCO LVM QUANDO NON È POSSIBILE NÉ SMONTARE LE PARTIZIONI ESISTENTI, NÉ AGGIUNGERE ULTERIORI PARTIZIONI
Questo caso si verifica se le partizioni primarie sono esaurite (max 4, compresa la partizione estesa che viene conteggiata come primaria) e se la partizione estesa non può essere allargata (in quanto montata). Qui le cose si fanno difficili, questa situazione può accadere ad es. allargando più volte lo spazio disponibile con il metodo precedente. Ma una soluzione c'è.
Qui riporto il caso di un allargamento dell'LVM da 40GB a 160GB senza aggiungere una nuova partizione, senza smontare le partizioni esistenti e persino senza riavviare il server!!!
Per prima cosa, controlliamo se il nuovo disco viene visto correttamente:
#lshw -C disk *-disk description: SCSI Disk physical id: 0.0.0 bus info: scsi@2:0.0.0 logical name: /dev/sda size: 160GiB (171GB) capabilities: partitioned partitioned:dos configuration: sectorsize=512 signature=000bc621
Ok, viene visto. Ripartiamo da dove eravamo arrivati nel caso 1 precedentemente descritto, ovvero in quello dell'allargamento da 20GB a 40GB. Questo è lo stato delle partizioni:
# parted GNU Parted 2.3 Using /dev/sda Welcome to GNU Parted! Type 'help' to view a list of commands. (parted) print free Model: VMware Virtual disk (scsi) Disk /dev/sda: 172GB Sector size (logical/physical): 512B/512B Partition Table: msdos Number Start End Size Type File system Flags 32.3kB 1049kB 1016kB Free Space 1 1049kB 256MB 255MB primary ext2 boot 256MB 257MB 1048kB Free Space 2 257MB 10.7GB 10.5GB extended 5 257MB 10.7GB 10.5GB logical lvm 3 10.7GB 21.5GB 10.7GB primary lvm 4 21.5GB 42.9GB 21.5GB primary lvm 42.9GB 172GB 129GB Free Space
Ci sono 129GB liberi, ma non è possibile aggiungere un'altra partizione primaria, il massimo che possiamo fare è allargare la partizione primaria 4.
Vediamo meglio i dettagli di questa partizione, in particolare mi interessa il punto di inizio:
# sudo fdisk /dev/sda Command (m for help): p Disk /dev/sda: 171.8 GB, 171798691840 bytes 255 heads, 63 sectors/track, 20886 cylinders, total 335544320 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000bc621 Device Boot Start End Blocks Id System /dev/sda1 * 2048 499711 248832 83 Linux /dev/sda2 501758 20969471 10233857 5 Extended /dev/sda3 20969472 41943039 10486784 8e Linux LVM /dev/sda4 41943040 83886079 20971520 8e Linux LVM /dev/sda5 501760 20969471 10233856 8e Linux LVM
Controlliamo anche così:
# pvdisplay /dev/sda4 --- Physical volume --- PV Name /dev/sda4 VG Name vg PV Size 20.00 GiB / not usable 4.00 MiB Allocatable yes (but full) PE Size 4.00 MiB Total PE 5119 Free PE 0 Allocated PE 5119 PV UUID DfKppj-lpj0-4HS7-MScL-ubVU-7JRh-sgMp03
Ricontrolliamo l'attuale setup di LVM:
#lvscan ACTIVE '/dev/vg/lv_swap' [952.00 MiB] inherit ACTIVE '/dev/vg/lv_root' [38.82 GiB] inherit
Prima di andare avanti, nel caso in cui qualcosa vada storto, facciamo un bel backup della tabella delle partizioni:
sfdisk -d /dev/sda > part_table
Qualora fosse necessario ripristinare le partizioni appena salvate, questo è il comando:
sfdisk /dev/sda < part_table
Adesso cancelliamo e ricreiamo con fdisk la partizione /dev/sda4. Attenzione: fdisk modifica soltanto la tabella delle partizioni e non tocca in alcun modo i dati, i quali non saranno persi se e soltanto se la nuova partizione inizierà esattamente nello stesso punto di quella attuale (in questo caso "41943040"), se avrà lo stesso id (in questo caso "8e") e se avrà lo stesso flag (in questo caso "lvm"):
# fdisk /dev/sda Command (m for help): p Disk /dev/sda: 171.8 GB, 171798691840 bytes 255 heads, 63 sectors/track, 20886 cylinders, total 335544320 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000bc621 Device Boot Start End Blocks Id System /dev/sda1 * 2048 499711 248832 83 Linux /dev/sda2 501758 20969471 10233857 5 Extended /dev/sda3 20969472 41943039 10486784 8e Linux LVM /dev/sda4 41943040 83886079 20971520 8e Linux LVM /dev/sda5 501760 20969471 10233856 8e Linux LVM Command (m for help): d Partition number (1-5): 4 Command (m for help): n Partition type: p primary (2 primary, 1 extended, 1 free) l logical (numbered from 5) Select (default p): p Selected partition 4 First sector (499712-335544319, default 499712): 41943040 Last sector, +sectors or +size{K,M,G} (41943040-335544319, default 335544319): 335544319 Command (m for help): p Disk /dev/sda: 171.8 GB, 171798691840 bytes 255 heads, 63 sectors/track, 20886 cylinders, total 335544320 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000bc621 Device Boot Start End Blocks Id System /dev/sda1 * 2048 499711 248832 83 Linux /dev/sda2 501758 20969471 10233857 5 Extended /dev/sda3 20969472 41943039 10486784 8e Linux LVM /dev/sda4 41943040 335544319 146800640 83 Linux /dev/sda5 501760 20969471 10233856 8e Linux LVM Command (m for help): t Partition number (1-5): 4 Hex code (type L to list codes): 8e Changed system type of partition 4 to 8e (Linux LVM) Command (m for help): p Disk /dev/sda: 171.8 GB, 171798691840 bytes 255 heads, 63 sectors/track, 20886 cylinders, total 335544320 sectors Units = sectors of 1 * 512 = 512 bytes Sector size (logical/physical): 512 bytes / 512 bytes I/O size (minimum/optimal): 512 bytes / 512 bytes Disk identifier: 0x000bc621 Device Boot Start End Blocks Id System /dev/sda1 * 2048 499711 248832 83 Linux /dev/sda2 501758 20969471 10233857 5 Extended /dev/sda3 20969472 41943039 10486784 8e Linux LVM /dev/sda4 41943040 335544319 146800640 8e Linux LVM /dev/sda5 501760 20969471 10233856 8e Linux LVM Command (m for help): w The partition table has been altered! Calling ioctl() to re-read partition table. WARNING: Re-reading the partition table failed with error 16: Device or resource busy. The kernel still uses the old table. The new table will be used at the next reboot or after you run partprobe(8) or kpartx(8) Syncing disks.
Adesso informiamo il kernel del nuovo partizionamento...
partprobe
... dopodiché informiamo LVM dell'avvenuto cambiamento:
pvresize /dev/sda4 Physical volume "/dev/sda4" changed 1 physical volume(s) resized / 0 physical volume(s) not resized
Controlliamo la nuova dimensione della partizione, che da 20GB deve essere passata a 140GB:
pvdisplay /dev/sda4 --- Physical volume --- PV Name /dev/sda4 VG Name vg PV Size 140.00 GiB / not usable 3.00 MiB Allocatable yes PE Size 4.00 MiB Total PE 35839 Free PE 30720 Allocated PE 5119 PV UUID DfKppj-lpj0-4HS7-MScL-ubVU-7JRh-sgMp03
Infine, allarghiamo lo spazio effettivamente disponibile su LVM con:
lvresize -L +120G /dev/vg/lv_root Extending logical volume lv_root to 158.82 GiB Logical volume lv_root successfully resized
e poi:
resize2fs /dev/vg/lv_root resize2fs 1.42.9 (4-Feb-2014) Filesystem at /dev/vg/lv_root is mounted on /; on-line resizing required old_desc_blocks = 3, new_desc_blocks = 10 The filesystem on /dev/vg/lv_root is now 41634816 blocks long.
Un paio di controlli finali:
lvscan ACTIVE '/dev/vg/lv_swap' [952.00 MiB] inherit ACTIVE '/dev/vg/lv_root' [158.82 GiB] inherit #df -h Filesystem Size Used Avail Use% Mounted on udev 3.9G 4.0K 3.9G 1% /dev tmpfs 799M 544K 798M 1% /run /dev/dm-1 157G 22G 128G 15% / none 4.0K 0 4.0K 0% /sys/fs/cgroup none 5.0M 0 5.0M 0% /run/lock none 3.9G 0 3.9G 0% /run/shm none 100M 0 100M 0% /run/user /dev/sda1 236M 70M 154M 32% /boot
Fine. Ce l'abbiamo fatta! ;-)
Happy GNU/Linux a tutti,
Francesco Galgani,
16 settembre 2018