Why
When you connect a new disk, you need answers:
- Which
/dev/sdXor/dev/nvmeXnYis it? - How is it partitioned? Are there existing partitions?
- What filesystems are on it (if any)?
- What UUID or LABEL do the partitions have, to put in [[mount-and-fstab|fstab]]?
- Where is it currently mounted?
lsblk answers 1, 2, and 5. blkid answers 3 and 4. They are often used together.
lsblk: the tree
$ lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINTS
sda 8:0 0 931.5G 0 disk
├─sda1 8:1 0 512M 0 part /boot/efi
├─sda2 8:2 0 1G 0 part /boot
└─sda3 8:3 0 930G 0 part
└─cryptroot 252:0 0 930G 0 crypt
├─vg-root 252:1 0 50G 0 lvm /
├─vg-swap 252:2 0 8G 0 lvm [SWAP]
└─vg-data 252:3 0 872G 0 lvm /data
nvme0n1 259:0 0 476.9G 0 disk
└─nvme0n1p1 259:1 0 476.9G 0 part /home
Columns:
- NAME: device name
- MAJ:MIN: major:minor numbers (for
mknod) - RM: removable (flash drive, USB)
- SIZE: size
- RO: read-only
- TYPE:
disk,part,lvm,crypt,raid1/5/...,loop,rom - MOUNTPOINTS: where it is mounted (multiple entries for bind mounts)
The tree shows the stack: disk -> partition -> LUKS-crypt -> LVM volume -> mount.
lsblk -f: with filesystem and UUID
$ lsblk -f
NAME FSTYPE LABEL UUID MOUNTPOINTS
sda
├─sda1 vfat EFI 1234-ABCD /boot/efi
├─sda2 ext4 boot a1b2c3... /boot
└─sda3 crypto_LUKS d4e5f6...
└─cryptroot LVM2_member 7890ab...
├─vg-root ext4 root 3344cc... /
├─vg-swap swap swap 5566dd... [SWAP]
└─vg-data xfs data 7788ee... /data
One call gives everything you need for fstab. Useful options:
lsblk -f # FSTYPE/LABEL/UUID
lsblk -p # full paths (/dev/sda1, not sda1)
lsblk -P # KEY="value" (for scripts)
lsblk -J # JSON
lsblk -O # all columns
lsblk -d # disks only, no partitions
lsblk -e7 # exclude loop devices (major 7)
lsblk /dev/sda # tree for this disk only
lsblk -o: custom column set
lsblk -o NAME,SIZE,FSTYPE,UUID,MOUNTPOINTS,MODEL
lsblk -o NAME,ROTA,DISC-MAX,SCHED,FSTYPE
Useful non-default columns:
| Field | Description |
|---|---|
MODEL, SERIAL | vendor, model, and serial number |
ROTA | 1 = HDD, 0 = SSD |
TRAN | sata/nvme/usb |
WWN | World-Wide Name (for multipath) |
MIN-IO, OPT-IO, PHY-SEC, LOG-SEC | I/O and sector sizes |
DISC-MAX, DISC-GRAN | trim/discard support |
SCHED | I/O scheduler (mq-deadline, none, bfq, kyber) |
RQ-SIZE | I/O queue depth |
# All SSDs on the host
lsblk -d -o NAME,ROTA,MODEL | awk '$2==0'
blkid: filesystem details
$ blkid
/dev/sda1: UUID="1234-ABCD" TYPE="vfat" PARTUUID="aabbccdd-01"
/dev/sda2: LABEL="boot" UUID="a1b2c3..." TYPE="ext4" PARTUUID="aabbccdd-02"
/dev/sda3: UUID="d4e5f6..." TYPE="crypto_LUKS" PARTUUID="aabbccdd-03"
/dev/mapper/vg-root: LABEL="root" UUID="3344cc..." TYPE="ext4"
Fields:
- UUID: filesystem UUID (assigned by mkfs); changes when you run
mkfsagain - PARTUUID: GPT partition UUID (assigned by parted/sgdisk); stable for the partition's lifetime
- LABEL: user label set with
mkfs -Lortune2fs -L - PARTLABEL: GPT partition label (set with gdisk, not a filesystem label)
- TYPE: filesystem type:
ext4,xfs,vfat,swap,crypto_LUKS,LVM2_member,linux_raid_member
Querying a specific device:
blkid /dev/sda2
blkid -U <uuid> # find device by UUID
blkid -L boot # find by LABEL
blkid -o value -s UUID /dev/sda2 # UUID only, no extra output
blkid -o export /dev/sda2 # UUID=...\nTYPE=... format, suitable for eval
UUID vs PARTUUID vs LABEL: what to use in fstab
| Identifier | When to use |
|---|---|
| UUID | most cases; stable and unique |
| PARTUUID | for a swap partition without a filesystem, or raw partitions |
| LABEL | human-readable, but can conflict across disks |
/dev/sdaX | do not use; changes when you add or remove disks |
Generating an fstab entry:
echo "UUID=$(blkid -o value -s UUID /dev/sda2) /boot ext4 defaults 0 2"
When to use /dev/disk/by-*/
An alternative to blkid is to look at the udev symlinks directly:
ls -l /dev/disk/by-uuid/
ls -l /dev/disk/by-label/
ls -l /dev/disk/by-partuuid/
ls -l /dev/disk/by-id/ # serial numbers, multipath
ls -l /dev/disk/by-path/ # PCI/USB path
You can write /dev/disk/by-uuid/abcd-1234 directly in fstab. It is equivalent to
UUID=abcd-1234, but more explicit.
After creating a new partition
# 1. Create the partition (parted/sgdisk/cfdisk)
sudo parted /dev/sdb mklabel gpt mkpart data ext4 1MiB 100%
# 2. Tell the kernel to re-read the partition table
sudo partprobe /dev/sdb # or: blockdev --rereadpt /dev/sdb
# 3. Create the filesystem
sudo mkfs.ext4 -L data /dev/sdb1
# 4. Get the UUID
blkid /dev/sdb1
# 5. Add to fstab
echo "UUID=$(blkid -o value -s UUID /dev/sdb1) /mnt/data ext4 defaults 0 2" \
| sudo tee -a /etc/fstab
# 6. Create the mountpoint and verify
sudo mkdir /mnt/data
sudo mount -a
lsblk -f /dev/sdb
Troubleshooting
- lsblk does not show a new disk. You may need to run
partprobeor reboot after partitioning. On a hotswap bay, the controller may not have notified the kernel. Checkdmesg | tail. Device or resource busy. The disk is in use (mounted, in LVM, in RAID, or in crypt). Uselsof /dev/sdXorfuserto find what holds it.- Two devices with the same UUID. You cloned the disk with
ddand the UUID is no longer unique. Fix withtune2fs -U random /dev/sdX1(ext) or recreate the filesystem. /dev/sdbsuddenly became/dev/sda. This is exactly why fstab uses UUID or PARTUUID instead of sdX. A reboot changed the probing order.- blkid shows nothing after mkfs. The udev cache may be stale.
blkid -p /dev/sdX1reads directly, bypassing the cache. Alternatively, runudevadm trigger.
Alternatives and related tools
fdisk -l: the classic option; shows the partition table as a flat listparted -l: similar to fdisk, but GPT-awareudevadm info /dev/sdX: everything udev knows about the devicesmartctl -a /dev/sdX: SMART data for the disk (separate package)