This post was originally published in 2019 and has been refreshed with more modern content and best practices. It combines the earlier posts on “Adding a New Hard Drive“ and “Extending an Existing Hard Drive“.
Managing storage on Linux follows the same process whether you are working with a physical machine, a VMware virtual machine, or a cloud instance such as AWS EC2. In each case the operating system sees a block device and the steps to make it available are identical: scan for the device, configure it with LVM, format it, and mount it. This post covers both scenarios: adding a new disk from scratch and extending an existing one.
Adding a new disk
Adding the disk itself is outside the scope of this article. On a physical machine, install the drive; on VMware, add a virtual disk via the hypervisor GUI; on EC2, create and attach an EBS volume in the console. Once attached, follow the steps below.
Scan for the new device
After attaching the disk, the operating system may not see it immediately without a reboot. To avoid rebooting, scan all SCSI host buses:
for i in $(ls /sys/class/scsi_host/*/scan); do echo "- - -" > ${i}; done
Confirm the new device is visible with lsblk. In this example sdb has appeared with no partitions defined:
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sda 8:0 0 10G 0 disk
├─sda1 8:1 0 1M 0 part
├─sda2 8:2 0 1G 0 part /boot
└─sda3 8:3 0 9G 0 part
└─ubuntu--vg-ubuntu--lv 253:0 0 4G 0 lvm /
sdb 8:16 0 10G 0 disk
AWS EC2 note: EBS volumes are usually visible immediately after attachment without a bus scan. Run lsblk first — if the device appears, skip the scan step.
Set up LVM
The most flexible approach is to allocate the entire disk to LVM. This allows the volume to be extended later without repartitioning. Create a physical volume, a volume group, then a logical volume:
# pvcreate /dev/sdb
Physical volume "/dev/sdb" successfully created.
# vgcreate data-vg /dev/sdb
Volume group "data-vg" successfully created
# lvcreate -l 100%FREE -n data data-vg
Logical volume "data" created.
If you want to add this disk to an existing volume group rather than creating a new one, use vgextend instead:
# vgextend existing-vg /dev/sdb
Format and mount
Format the logical volume, create the mount point, and add it to /etc/fstab for persistence across reboots:
# mkfs.ext4 /dev/data-vg/data
# mkdir /data
# echo "/dev/data-vg/data /data ext4 defaults 0 0" >> /etc/fstab
# mount /data
# df -h /data
Filesystem Size Used Avail Use% Mounted on
/dev/mapper/data--vg-data 9.8G 37M 9.2G 1% /data
Filesystem choice: ext4 is the default on Ubuntu and Debian. Amazon Linux 2023 and RHEL-based distributions use xfs by default — substitute mkfs.xfs accordingly. The resize commands differ between the two; see below.
Extending an existing disk
This scenario applies when you have increased the capacity of an existing disk — extended an EBS volume in the EC2 console, or grown a VMware virtual disk — and need the operating system to recognise and use the additional space.
Rescan for additional capacity
Unlike adding a new device, extending an existing one requires rescanning the device itself rather than the host bus:
for i in $(ls /sys/class/scsi_device/*/device/rescan); do echo 1 > ${i}; done
Confirm the additional capacity is now visible. In this example sdb has grown from 10G to 20G but the logical volume still reports the original size:
# lsblk
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
sdb 8:16 0 20G 0 disk
└─data--vg-data 253:0 0 10G 0 lvm /data
Extend the LVM stack
Resize the physical volume to consume the additional space, then extend the logical volume:
# pvresize /dev/sdb
Physical volume "/dev/sdb" changed
1 physical volume(s) resized / 0 physical volume(s) not resized
# lvextend -l +100%free /dev/data-vg/data
Size of logical volume data-vg/data changed from <10.00 GiB to <20.00 GiB.
Logical volume data-vg/data successfully resized.
Resize the filesystem
The logical volume is now larger, but the filesystem on top of it still reports the original size. Both ext4 and xfs support online resizing — no unmounting required.
ext4:
# resize2fs /dev/data-vg/data
The filesystem on /dev/data-vg/data is now 5241856 (4k) blocks long.
xfs (Amazon Linux 2023, RHEL, Rocky Linux) — note that xfs_growfs takes the mount point, not the device path:
# xfs_growfs /data
Command reference
Device discovery
| Command | Purpose |
|---|---|
lsblk | List block devices, sizes, types and mount points |
for i in $(ls /sys/class/scsi_host/*/scan); do echo "- - -" > ${i}; done | Scan SCSI host buses for newly attached devices |
for i in $(ls /sys/class/scsi_device/*/device/rescan); do echo 1 > ${i}; done | Rescan existing SCSI devices for capacity changes |
LVM
| Command | Purpose |
|---|---|
pvcreate /dev/sdb | Initialise a disk as an LVM physical volume |
pvresize /dev/sdb | Resize a physical volume to consume available disk space |
pvdisplay | Show details of all physical volumes |
vgcreate data-vg /dev/sdb | Create a new volume group from a physical volume |
vgextend existing-vg /dev/sdb | Add a physical volume to an existing volume group |
vgdisplay | Show details of all volume groups |
lvcreate -l 100%FREE -n data data-vg | Create a logical volume using all free space in a volume group |
lvextend -l +100%free /dev/data-vg/data | Extend a logical volume to consume all free space in its volume group |
lvdisplay /dev/data-vg/data | Show details of a specific logical volume |
Filesystems
| Command | Purpose |
|---|---|
mkfs.ext4 /dev/data-vg/data | Format a logical volume with ext4 |
mkfs.xfs /dev/data-vg/data | Format a logical volume with xfs |
resize2fs /dev/data-vg/data | Grow an ext4 filesystem online to fill its logical volume |
xfs_growfs /data | Grow an xfs filesystem online (takes mount point, not device path) |
df -h /data | Show available and used space at a mount point |
mount /data | Mount a filesystem using its /etc/fstab entry |