Skip to main content
RunBook Academy

LinuxXIII · Disks and Block DevicesRescan and resize

Rescanning and growing block devices - when the kernel still sees the old size

Advanced⏱ ~15 minbashlsblkpartxsgdiskblockdev

What you'll learn

  • Name every layer between an array LUN and a mounted filesystem, and which command refreshes each
  • Rescan a SCSI device or host bus without disturbing running I/O
  • Choose between partprobe, partx -u and blockdev --rereadpt for re-reading a partition table
  • Move a GPT backup header after a disk grows
  • Recognise the resize operations that are irreversible and the dry runs that precede them

Prerequisites

Verified against Ubuntu 24.04 LTS · Debian 12 (Bookworm) · RHEL 9.x · Rocky Linux 9.x · AlmaLinux 9.x · Linux kernel 6.1 LTS / 6.6 LTS · systemd 255+ · OpenSSH 8.7p1 (RHEL 9) / 9.6p1 (Ubuntu 24.04) · nftables 1.0.x · chrony 4.x · Pacemaker 2.1.x · Corosync 3.1.x · 2026-08-11

Not yet marked complete on this device.

The storage team grew the LUN from 2 TB to 4 TB an hour ago and sent you the ticket. lsblk still says 2 TB. Nothing is broken and nothing needs a reboot - the kernel simply caches a device’s capacity and its partition table, and neither is re-read spontaneously.

The work is a chain of layers, each of which has to be told separately, and each of which will happily report success while the layer above it is still stale.

The chain

LayerRefreshed byRead back with
SCSI device capacityecho 1 > /sys/block/sdb/device/rescanblockdev --getsize64 /dev/sdb
Multipath mapsudo multipathd resize map mpathamultipath -ll
Partition tablesudo partx -u /dev/sdblsblk /dev/sdb
Partition sizesudo growpart /dev/sdb 1lsblk /dev/sdb1
LVM physical volumesudo pvresize /dev/sdb1sudo pvs -o pv_name,pv_size,pv_free
Logical volumesudo lvextend -L +1T vg0/datasudo lvs
Filesystemsudo xfs_growfs /srv/data or resize2fsdf -h /srv/data

Every step is additive and none of them destroys data - with two exceptions marked below, which is why the exceptions get the attention.

Step 1: make the kernel re-read the capacity

Read-only / Safethe two size views
$ blockdev --getsize64 /dev/sdb; cat /sys/block/sdb/size
2199023255552
4294967296

Illustrative output

Configuration changerescan one SCSI device
$ echo 1 | sudo tee /sys/block/sdb/device/rescan
1
Read-only / Safeconfirm the kernel agreed
$ sudo dmesg -T | tail -3
[Tue Aug 11 14:22:07 2026] sd 6:0:0:1: [sdb] 8589934592 512-byte logical blocks: (4.40 TB/4.00 TiB)
[Tue Aug 11 14:22:07 2026] sd 6:0:0:1: [sdb] 4096-byte physical blocks
[Tue Aug 11 14:22:07 2026] sdb: detected capacity change from 2199023255552 to 4398046511104

Illustrative output

For a new LUN that does not yet have a device node, the device-level rescan has nothing to act on. Scan the host bus instead, or use the sg3_utils wrapper that walks every host:

for h in /sys/class/scsi_host/host*/scan; do
  echo '- - -' | sudo tee "$h" > /dev/null
done

# the packaged equivalent, which also handles removals
sudo rescan-scsi-bus.sh

The three dashes are channel target lun, each wildcarded. Scanning a bus is safe but not free: on a large fabric it produces a burst of discovery I/O, so do it once rather than in a loop.

Step 2: re-read the partition table

Three commands do overlapping things, and choosing the wrong one is how a resize turns into an outage.

CommandMechanismWith partitions in use
blockdev --rereadptBLKRRPART ioctl - drops and re-adds every partitionFails with EBUSY
partprobeTries BLKRRPART, falls back to per-partition updatesUsually works, sometimes silently partial
partx -uBLKPG ioctl per partition - updates in placeWorks
Configuration changeupdate partitions in place
$ sudo partx -u /dev/sdb

Step 3: the GPT backup header is now in the middle of the disk

GPT stores a primary header at the start of the disk and a backup header in the last sector. Grow the disk and the backup is suddenly thousands of sectors short of the end, where nothing looks for it.

Read-only / Safediagnose the stale backup GPT
$ sudo sgdisk --verify /dev/sdb
Caution: invalid backup GPT header, but valid main header; regenerating
backup header from main header.

Warning! Main and backup partition tables differ! Use the 'c' and 'e' options
on the recovery & transformation menu to examine the two tables.

Problem: The secondary header's self-pointer indicates that it doesn't reside
at the end of the disk. If you've added a disk to a RAID array, use the 'e'
option on the experts' menu to adjust the secondary header's and partition
table's locations.

Identified 1 problems!

Illustrative output

Data-loss riskmove the backup GPT to the new end of disk
$ sudo sgdisk --move-second-header /dev/sdb
Warning: The kernel is still using the old partition table.
The new table will be used at the next reboot or after you
run partprobe(8) or partx(8)
The operation has completed successfully.

Step 4: grow the partition

Read-only / Safesee the change before making it
$ sudo growpart --dry-run /dev/sdb 1
CHANGE: partition=1 start=2048 old: size=4294965248 end=4294967296 new: size=8589932544 end=8589934592
# === old sfdisk -d ===
label: gpt
/dev/sdb1 : start=2048, size=4294965248, type=E6D6D379-F507-44C2-A23C-238F2A3DF928
# === new sfdisk -d ===
label: gpt
/dev/sdb1 : start=2048, size=8589932544, type=E6D6D379-F507-44C2-A23C-238F2A3DF928

Illustrative output

Drop --dry-run to apply it. growpart rewrites the partition entry in place, keeping the start sector, and then asks the kernel to update. The alternative - deleting the partition in fdisk and recreating it larger - works only if you recreate it at exactly the same start sector, and is how filesystems get orphaned by people who were sure they remembered the number.

Step 5 onwards: PV, LV, filesystem

  1. sudo pvresize /dev/sdb1 - the PV metadata records its own size and does not follow the partition automatically. Confirm with sudo pvs -o pv_name,pv_size,pv_free.
  2. sudo lvextend -r -L +2T vg0/data - the -r flag is equivalent to --fs resize and calls the filesystem-specific resize command in the same step, which removes the window where the LV is larger than the filesystem and nobody has noticed.
  3. df -h /srv/data - the only check that matters to the person who filed the ticket.

xfs_growfs /srv/data and resize2fs /dev/vg0/data are the manual forms if you prefer to do the two steps separately. Both grow online. Both are additive.

Knowledge check

Knowledge check · 4 questions

  1. Q1. A LUN was grown on the array. After echoing 1 to /sys/block/sdb/device/rescan, blockdev --getsize64 /dev/sdb shows the new size but /dev/mapper/mpatha still shows the old one. What is missing?

  2. Q2. When blockdev --rereadpt fails with EBUSY because a partition is mounted, the correct fix is to unmount the filesystem so the command can complete.

  3. Q3. Which of the following are safe, non-destructive steps in a device-growth procedure? Select all that apply.

  4. Q4. sgdisk --verify on a recently grown disk reports that the secondary header does not reside at the end of the disk. What is the actual risk?

Passing score: 75%. Answers are checked in this browser.