Un disco nuovo non serve a niente finché non lo si divide in partizioni: una per il sistema, una per i dati, magari una di swap. Un disco già in uso può avere bisogno di una partizione in più, o di capire come è fatto prima di intervenire. Lo strumento classico per tutto questo è fdisk: si usa a riga di comando, in modo interattivo, ed è presente praticamente ovunque.
Cos'è
fdisk (fixed disk) fa parte del pacchetto util-linux, lo stesso di lsblk, mount e lscpu (su Ubuntu recente il programma sta nel pacchetto separato fdisk, che comprende anche sfdisk e cfdisk; se manca, sudo apt install fdisk: vedi l'articolo su apt). Lavora sulla tabella delle partizioni, cioè l'elenco, scritto all'inizio del disco, che dice dove comincia e dove finisce ogni partizione e di che tipo è. Conosce i due formati più diffusi: MBR (chiamato anche DOS, il vecchio formato) e GPT (il formato moderno, richiesto dall'UEFI e necessario per i dischi sopra i 2 TiB).
Cosa fa
Mostra le partizioni di un disco, ne crea di nuove, le elimina, ne cambia il tipo e scrive la tabella sul disco. Non crea il file system: una partizione appena creata è uno spazio vuoto, che si prepara poi con mkfs (vedi mount e lsblk per la parte successiva). Le modifiche restano in memoria finché non si dà il comando di scrittura: è una rete di sicurezza importante.
Come si usa
$ sudo fdisk -l [disco]
$ sudo fdisk discoCome ho fatto le prove. Nella macchina virtuale di prova il sistema non permette di toccare i dischi (anche come amministratore dà Permission denied o Operation not permitted), ma fdisk funziona benissimo anche su un file immagine: un normale file che si comporta come un disco. Ho quindi creato un file da 2 GiB (truncate -s 2G disco.img, che non occupa spazio finché non si scrive) e ci ho lavorato come su un disco vero. Gli output che vedi con disco.img sono perciò reali (fdisk 2.39.3), con gli identificativi generati lì; i nomi come /dev/sda sono quelli che vedresti su web01, il server degli articoli precedenti. È anche un ottimo modo per fare pratica senza rischi: prova tutto su un file immagine, prima di toccare un disco vero.
Esempio 1: elencare le partizioni
$ sudo fdisk -l /dev/sda
$ sudo fdisk -l
$ fdisk -l disco.img
Disk disco.img: 2 GiB, 2147483648 bytes, 4194304 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
Disklabel type: gpt
Disk identifier: 07876C22-41D1-471D-8D64-CDBBA506E00E
Device Start End Sectors Size Type
disco.img1 2048 1050623 1048576 512M EFI System
disco.img2 1050624 3147775 2097152 1G Linux swap
disco.img3 3147776 4192255 1044480 510M Linux filesystemfdisk -l (list) mostra le partizioni e esce: non modifica niente, ed è la prima cosa da fare. Senza il nome del disco elenca tutti i dischi del sistema (nel sandbox non mostra niente, perché non può accedere ai dischi). Prima c'è l'intestazione del disco: la dimensione, la dimensione dei settori (512 bytes, o 4096 sui dischi più recenti), il Disklabel type (gpt o dos) e l'identificativo. Poi la tabella: Start e End sono il primo e l'ultimo settore, Sectors quanti sono, Size la dimensione e Type il tipo. Nota che la prima partizione comincia al settore 2048, cioè a 1 MiB dall'inizio: è l'allineamento che fdisk sceglie da solo, giusto anche per i dischi con settori da 4 KiB e per gli SSD. Per riconoscere a colpo d'occhio dischi e partizioni, anche già montate, c'è lsblk (vedi l'articolo relativo).
Esempio 2: più dettagli e altre unità
$ fdisk -x disco.img | sed -n 7,12p
First usable LBA: 2048
Last usable LBA: 4194270
Alternative LBA: 4194303
Partition entries starting LBA: 2
Allocated partition entries: 128
Partition entries ending LBA: 33
$ fdisk -l -o Device,Start,Size,Type disco.img | tail -n 3
disco.img1 2048 512M EFI System
disco.img2 1050624 1G Linux swap
disco.img3 3147776 510M Linux filesystem
$ fdisk -l --bytes disco.img | tail -n 3
disco.img1 2048 1050623 1048576 536870912 EFI System
disco.img2 1050624 3147775 2097152 1073741824 Linux swap
disco.img3 3147776 4192255 1044480 534773760 Linux filesystemCon -x (details) si vedono i dettagli della tabella (nell'esempio, i dati interni della tabella GPT, e per ogni partizione l'identificativo del tipo e quello unico della partizione, utile per i file /etc/fstab con UUID=: vedi l'articolo su mount). Con -o si scelgono le colonne (l'elenco è nell'aiuto: fdisk -h), e con --bytes le dimensioni escono in byte esatti, comodi negli script. Una nota: sull'output di un MBR le colonne sono diverse (compaiono Boot e Id: vedi l'esempio 4).
Esempio 3: creare una tabella GPT e tre partizioni
$ sudo fdisk /dev/sdb
Command (m for help): g
Created a new GPT disklabel (GUID: 07876C22-41D1-471D-8D64-CDBBA506E00E).
Command (m for help): n
Partition number (1-128, default 1):
First sector (2048-4194270, default 2048):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (2048-4194270, default 4192255): +512M
Created a new partition 1 of type 'Linux filesystem' and of size 512 MiB.
Command (m for help): t
Selected partition 1
Partition type or alias (type L to list all): uefi
Changed type of partition 'Linux filesystem' to 'EFI System'.
Command (m for help): n
Partition number (2-128, default 2):
First sector (1050624-4194270, default 1050624):
Last sector, +/-sectors or +/-size{K,M,G,T,P} (1050624-4194270, default 4192255): +1G
Created a new partition 2 of type 'Linux filesystem' and of size 1 GiB.
Command (m for help): t
Partition number (1,2, default 2):
Partition type or alias (type L to list all): swap
Changed type of partition 'Linux filesystem' to 'Linux swap'.
Command (m for help): n
(Invio a tutte le domande: la terza partizione occupa lo spazio rimasto)
Created a new partition 3 of type 'Linux filesystem' and of size 510 MiB.
Command (m for help): p
Command (m for help): v
No errors detected.
Command (m for help): w
The partition table has been altered.
Syncing disks.Il programma si guida con comandi di una lettera, che si scrivono dopo il prompt Command (m for help): (m mostra il menù). Il blocco è la sessione reale su disco.img, riassunta: ho tolto qualche riga vuota, e dove il programma propone un valore predefinito l'utente preme Invio (le risposte vuote dopo default). I comandi usati: g crea una nuova tabella GPT vuota (o per una MBR); n (new) crea una partizione, chiedendo numero, primo settore e ultimo; l'ultimo si può dare come dimensione (+512M, +1G) e se si preme Invio prende tutto lo spazio rimasto. t (type) cambia il tipo, e si può dare con un alias (uefi, swap, linux, lvm, raid: li ho provati) o con il numero della lista che mostra l; p stampa la tabella (come nell'esempio 1), v la verifica, w la scrive ed esce, q esce senza salvare. Prima della w il disco non è stato toccato: all'apertura fdisk dice Changes will remain in memory only. Se il disco è vuoto, all'avvio crea in memoria una tabella MBR predefinita (Created a new DOS (MBR) disklabel): se vuoi una GPT, il primo comando è g.
Esempio 4: la tabella MBR, con partizioni estese e logiche
Command (m for help): o
Command (m for help): n
Partition type
p primary (0 primary, 0 extended, 4 free)
e extended (container for logical partitions)
Select (default p): p
...
Command (m for help): a
Selected partition 1
The bootable flag on partition 1 is enabled now.
...
Command (m for help): n
All space for primary partitions is in use.
Adding logical partition 5
$ fdisk -l mbr.img | tail -n 6
Device Boot Start End Sectors Size Id Type
mbr.img1 * 2048 1050623 1048576 512M 83 Linux
mbr.img2 1050624 3147775 2097152 1G 82 Linux swap / Solaris
mbr.img3 3147776 4194303 1046528 511M 5 Extended
mbr.img5 3149824 3764223 614400 300M 83 Linux
mbr.img6 3766272 4194303 428032 209M 83 LinuxIl formato MBR ha un limite storico: al massimo quattro partizioni primarie. Per averne di più, una delle quattro diventa estesa (il tipo 5 Extended dell'esempio) e fa da contenitore per un numero qualsiasi di partizioni logiche, che hanno numeri da 5 in su (mbr.img5, mbr.img6): quando le primarie sono finite fdisk lo dice (All space for primary partitions is in use. Adding logical partition 5) e prosegue da solo. Con a si attiva il flag boot (* nella colonna Boot), che i vecchi BIOS usano per sapere da quale partizione avviarsi. Nel tipo, con MBR si usano codici in esadecimale (83 Linux, 82 swap, 8e LVM, fd RAID, ef EFI), e fdisk accetta in alternativa gli alias. Il MBR non gestisce dischi oltre i 2 TiB (gli indirizzi sono a 32 bit): per i dischi grandi serve la GPT.
Esempio 5: eliminare, spazio libero, informazioni
Command (m for help): F
Unpartitioned space disco.img: 0 B, 0 bytes, 0 sectors
Command (m for help): d
Partition number (1-3, default 3): 3
Partition 3 has been deleted.
Command (m for help): F
Unpartitioned space disco.img: 510.98 MiB, 535805440 bytes, 1046495 sectors
Start End Sectors Size
3147776 4194270 1046495 511M
Command (m for help): i
Partition number (1-3, default 3): 2
Device: disco.img2
Start: 1050624
End: 3147775
Sectors: 2097152
Size: 1G
Type: Linux swap
Type-UUID: 0657FD6D-A4AB-43C4-84E5-0933C84B4F4F
UUID: 789EF033-3062-4AC4-880C-648F0897714C
Command (m for help): qF mostra lo spazio libero non partizionato (come nell'esempio: prima della cancellazione 0, dopo circa 511 MiB); d (delete) elimina una partizione, i (info) mostra i dettagli di una (compreso l'identificativo unico, quello che si usa in fstab). Nell'esempio ho chiuso con q, per non salvare: la cancellazione c'è stata solo in memoria. Importante: d toglie la partizione dalla tabella, non cancella i dati contenuti. Ma senza la tabella il sistema non sa più dove sono, e il recupero non è garantito (vedi "Attenzione a"). Vale la regola: prima della w si può sempre tornare indietro con q; dopo la w no.
Esempio 6: gli errori più frequenti
$ fdisk -l /dev/nonesiste
fdisk: cannot open /dev/nonesiste: No such file or directory
$ fdisk -l /dev/sda
fdisk: cannot open /dev/sda: Permission denied
Command (m for help): n
Partition number (4-128, default 4): 1
Value out of range.
Partition number (4-128, default 4): 99999999
Value out of range.
Partition number (4-128, default 4):
No enough free sectors available.
Command (m for help): L
L: unknown commandI messaggi da riconoscere. cannot open ...: No such file or directory: il disco non esiste (controlla il nome con lsblk). Permission denied: servono i privilegi, quindi sudo (il secondo l'ho visto con un utente senza privilegi sul disco del sandbox). Value out of range: il numero o il settore indicato non è tra quelli ammessi (nell'esempio, il numero 1 è già usato), e il programma lo richiede. No enough free sectors available (il testo ha davvero questo errore di grammatica): non c'è più spazio libero per una nuova partizione. L'ultimo mostra una confusione frequente: al prompt principale l'elenco dei tipi si chiede con l (minuscola); la L maiuscola funziona solo dentro il comando t.
Esempio 7: salvare e ripetere una tabella con sfdisk
$ sfdisk -d disco.img > tabella.txt
$ cat tabella.txt
label: gpt
label-id: 07876C22-41D1-471D-8D64-CDBBA506E00E
device: disco.img
unit: sectors
first-lba: 2048
last-lba: 4194270
sector-size: 512
disco.img1 : start= 2048, size= 1048576, type=C12A7328-..., uuid=BC77F0D1-...
disco.img2 : start= 1050624, size= 2097152, type=0657FD6D-..., uuid=789EF033-...
disco.img3 : start= 3147776, size= 1044480, type=0FC63DAF-..., uuid=94FF9AAC-...
$ sfdisk nuovo.img < tabella.txt
$ printf 'label: gpt\n,512M,U\n,1G,S\n,,L\n' | sfdisk nuovo.img
nuovo.img1: Created a new partition 1 of type 'EFI System' and of size 512 MiB.
nuovo.img2: Created a new partition 2 of type 'Linux swap' and of size 1 GiB.
nuovo.img3: Created a new partition 3 of type 'Linux filesystem' and of size 510 MiB.
nuovo.img4: Done.sfdisk (stesso pacchetto) è il fratello non interattivo di fdisk: legge la tabella da un testo, perciò è adatto agli script. Con -d (dump) salva la tabella di un disco in un file, che si può conservare come copia di sicurezza prima di un intervento (è anche l'unica copia leggibile da una persona) e poi riapplicare con sfdisk disco < file. L'ultimo comando crea una tabella nuova da una descrizione scritta a mano: una riga per partizione, con dimensione e tipo abbreviato (U = EFI, S = swap, L = Linux; senza dimensione, la partizione prende tutto lo spazio che resta). Nell'esempio le tre righe uuid le ho accorciate. Attenzione: sfdisk con un dump riapplicato su un altro disco gli assegna gli stessi identificativi del disco originale (l'ho verificato: il disco copiato ha lo stesso GUID): se i due dischi stanno nello stesso computer il sistema può confondersi. Per cambiare l'identificativo del disco si usa il menù degli esperti (x, poi i) o sfdisk --disk-id.
Esempio 8: uso negli script
#!/bin/bash
# Mostra il tipo di tabella e il numero di partizioni di un disco
DISCO=${1:?indicare il disco, per esempio /dev/sda}
TIPO=$(fdisk -l "$DISCO" 2>/dev/null | awk -F': ' '/^Disklabel type/ {print $2}')
if [ -z "$TIPO" ]; then
echo "$DISCO: nessuna tabella delle partizioni (o disco non leggibile)" >&2
exit 1
fi
N=$(fdisk -l "$DISCO" | grep -c "^$DISCO")
echo "$DISCO: tabella $TIPO, $N partizioni"Lo script prende il nome di un disco come argomento (${1:?...} si ferma con un messaggio se manca), legge dal listato di fdisk -l il tipo di tabella e conta le righe che cominciano con il nome del disco (le partizioni). L'ho provato sui miei file immagine: disco.img risponde tabella gpt, 3 partizioni e mbr.img tabella dos, 5 partizioni; su un disco vuoto o inesistente dà l'errore e il codice 1; senza argomento si ferma subito con il messaggio. Il conteggio funziona per /dev/sda (partizioni /dev/sda1...) e anche per i dischi NVMe (/dev/nvme0n1p1), perché in entrambi i casi il nome delle partizioni comincia con quello del disco. Si lancia con sudo. Una riga come fdisk -l disco è sicura da usare in uno script; i comandi che scrivono, invece, vanno inseriti con molta più cautela, e di norma conviene sfdisk (esempio 7).
Opzioni utili
fdisk -l [disco]: elenco delle partizioni;-x: più dettagli;-o colonne: scelta delle colonne;--bytes: dimensioni in byte.- Nel programma:
mmenù;pstampa;nnuova;delimina;ttipo;Fspazio libero;iinformazioni;vverifica;lelenco dei tipi;aflag di avvio (MBR);wscrive;qesce senza salvare. g,o: crea una tabella nuova vuota (GPT, MBR);I,O: carica o salva un file di descrizione come quelli disfdisk.-w auto|always|never: cancella o no le firme di vecchi file system;-b dimensione: forza la dimensione dei settori.sfdisk -d disco: salva la tabella;sfdisk disco < file: la ripristina;cfdisk: la stessa cosa con un menù a tutto schermo.lsblk,blkid,mount,df: dispositivi, identificativi, montaggi, spazio.mkfs.ext4,mkswap: preparano la partizione dopofdisk.partprobe: avvisa il sistema di una nuova tabella.
Attenzione a
- Il disco sbagliato è l'errore più grave:
fdisk /dev/sdainvece di/dev/sdbpuò cancellare il sistema. Controlla sempre conlsblk(modello, dimensione, punti di montaggio) e confdisk -lprima di scrivere; i nomisdaesdbpossono scambiarsi da un avvio all'altro, perciò verifica anche la dimensione e il modello. - Dopo la
wnon si torna indietro: prima di scrivere ricontrolla conpev, e se sei in dubbio premiq. Su un disco con dati salva prima la tabella (sfdisk -d disco > copia.txt) e i dati stessi (vedirsyncetar). - Non toccare partizioni montate: smonta prima i file system (vedi
mount). Se il disco è in uso, dopo la scrittura il sistema può non rileggere la tabella (Re-reading the partition table failed): in quel casosudo partprobeo un riavvio. Non ho potuto provarlo nel sandbox, che non lo permette sui dischi. - Eliminare e ricreare una partizione non cancella i dati, ma è rischioso: se la nuova partizione comincia esattamente allo stesso settore, il file system sopra è di solito ancora leggibile; se no, i dati sono persi di fatto. Per questo i dischi con dati importanti si ridimensionano con strumenti dedicati (
growpart,parted,resize2fs), che aggiornano insieme tabella e file system.fdisknon ridimensiona. - Creare la partizione non basta: serve poi il file system (
mkfs.ext4 /dev/sdb1,mkswapper lo swap), il montaggio e, per renderlo permanente, la riga in/etc/fstab. Unmkfssulla partizione sbagliata cancella davvero i dati. - MBR o GPT: per macchine nuove con UEFI si usa la GPT, con una partizione
EFI System(di solito 100-512 MiB) per l'avvio; la MBR serve ai vecchi BIOS e non gestisce i dischi oltre i 2 TiB. Scegliere male rende il sistema non avviabile. - Dischi ingranditi nel cloud o in una macchina virtuale: se il disco è stato ingrandito dal fornitore, la partizione va allargata con
growpart(o con la procedura del fornitore), e poi il file system conresize2fs(ext4) oxfs_growfs(XFS). Questi passaggi li ho solo citati, non provati. - I nomi dei tipi e gli alias dipendono dalla versione: gli alias
uefi,swap,lvm,raidli ho provati con la 2.39.3; su versioni più vecchie può servire il numero o il codice esadecimale (lmostra l'elenco della tua).
Riepilogo
| Comando | Cosa fa |
|---|---|
sudo fdisk -l | Elenca le partizioni di tutti i dischi |
sudo fdisk -l /dev/sda | Elenca quelle di un solo disco |
sudo fdisk -x /dev/sda | Elenco con più dettagli |
sudo fdisk /dev/sdb | Apre il disco per modificare la tabella (in memoria) |
g / o | Nuova tabella vuota GPT / MBR |
n, d, t | Nuova partizione, elimina, cambia il tipo |
p, F, i, v | Stampa, spazio libero, informazioni, verifica |
w / q | Scrive ed esce / esce senza salvare |
sfdisk -d /dev/sda > tabella.txt | Salva la tabella in un file |
sudo sfdisk /dev/sdb < tabella.txt | Applica una tabella salvata |
truncate -s 2G disco.img | Crea un file immagine con cui esercitarsi |