Build an LVM stack from scratch (PV → VG → LV) on a
blank disk (/dev/vdb), format the LV with XFS, mount
it at /mnt/logs, make the mount persistent with a
UUID-based /etc/fstab entry, extend the LV, grow XFS
online, then revert the system back to a clean state.
A VM gets a new blank disk for application logs. You want
flexibility to resize later, so you choose LVM. You will create
PV → VG → LV, format XFS, mount at
/mnt/logs, make it persistent via
/etc/fstab, extend the LV, grow XFS online, then
clean up.
LVM operations write metadata to disks and can destroy data if you target the wrong device. Confirm the target disk and verify each layer (PV/VG/LV) before formatting or mounting.
/dev/vdb exists, is unused, and has no
mountpoints.
lvm2) if required.
/dev/vdb.
logs_vg and a logical
volume (LV) logs_lv.
/mnt/logs.
/etc/fstab
entry and validate with mount -a.
PV → VG → LV and what each layer
represents.
/dev/<vg>/<lv>)
vs mapper paths (/dev/mapper/*).
/etc/fstab.
mount -a after fstab
edits to avoid boot failures.
LV → VG → PV to avoid “in use” errors.
lsblk -o NAME,SIZE,TYPE,FSTYPE,MOUNTPOINTS
Verify the target disk is present, the size matches expectation, and it has no filesystem or mountpoint.
NAME MAJ:MIN RM SIZE RO TYPE FSTYPE MOUNTPOINTS
vda 253:0 0 11G 0 disk
└─vda1 253:1 0 10G 0 part xfs /
vdb 253:16 0 1G 0 disk
sudo dnf -y install lvm2
If the system already has LVM tooling, the package manager should report nothing to do.
sudo pvcreate /dev/vdb
This writes LVM metadata to the disk and makes it available for a volume group.
sudo pvs -o pv_name,vg_name,pv_size,pv_free
PV VG PSize PFree
/dev/vdb 1.00g 1.00g
sudo vgcreate logs_vg /dev/vdb
A VG pools PV capacity into something you can slice into logical volumes.
sudo lvcreate -L 500M -n logs_lv logs_vg
This creates the block device you will format and mount.
sudo lvs -o lv_name,vg_name,lv_size,lv_path
The canonical device path is /dev/logs_vg/logs_lv
(and the mapper path is also valid).
sudo mkfs.xfs /dev/logs_vg/logs_lv
This is a destructive write. Only run it after you have verified the LV path.
sudo mkdir -p /mnt/logs
sudo mount /dev/logs_vg/logs_lv /mnt/logs
Mounting is your first end-to-end validation that the storage stack is usable.
df -h /mnt/logs
This confirms the filesystem is mounted and reports its size.
sudo blkid /dev/logs_vg/logs_lv
Use the filesystem UUID rather than device paths for persistence.
# Replace UUID below with your actual value from blkid
echo 'UUID=REPLACE_UUID /mnt/logs xfs defaults 0 0' | sudo tee -a /etc/fstab
# Ops-safe validation (should return no output on success)
sudo mount -a
After any change to /etc/fstab, run
mount -a immediately. If you broke the file,
you want to find out now, not at the next reboot.
sudo lvextend -L +200M /dev/logs_vg/logs_lv
sudo xfs_growfs /mnt/logs
df -h /mnt/logs
The LV grows first (block device). Then XFS expands online while
mounted. Finish by verifying the new size with df.
In real work you may use lvextend -r to resize
the filesystem automatically. This lab keeps the two steps
explicit so you build the habit of verifying each layer.
You targeted a disk that already has signatures, partitions,
or is mounted. Re-check lsblk -f and confirm you
are operating on the correct device.
The LV already has a filesystem signature. On real systems,
you would investigate why, and only use
mkfs.xfs -f if you are intentionally overwriting
it.
This usually means a typo in the UUID, mountpoint, or
filesystem type. Fix the line immediately. Do not leave a
broken /etc/fstab behind.
The filesystem can only grow if the LV grew. Re-check
lvs after lvextend and confirm the
mountpoint is correct.
Unmount first. If a process is holding the mount busy, you
would locate it (for example with lsof or
fuser) before retrying.
The goal is to leave the system in a clean, boot-safe state with no leftover mounts and no LVM metadata on the test disk.
# 1) Remove the mount entry
sudo sed -i '/\/mnt\/logs/d' /etc/fstab
# 2) Unmount (only after confirming /mnt/logs is mounted)
sudo umount /mnt/logs
# 3) Remove LVM objects (LV -> VG -> PV)
sudo lvremove -y /dev/logs_vg/logs_lv
sudo vgremove -y logs_vg
sudo pvremove -y /dev/vdb
# 4) Final verification (should show vdb as a raw disk with no PV/VG/LV)
lsblk -f
sudo pvs
sudo vgs
sudo lvs
pvs/vgs/lvs should not show your test objects,
and lsblk -f should show /dev/vdb
without an LVM signature.
lsblk: List block devices and their layers.dnf: Install packages on RHEL-based systems.
-y: Automatically answer "yes" to prompts.pvcreate: Initialize a block device as an LVM Physical Volume (PV).
pvs: Display PVs and free space.
-o pv_name,vg_name,pv_size,pv_free: Show PV name, VG membership, total size, and free space.
vgcreate: Create a Volume Group (VG) from one or more PVs.
vgs: Display VGs and free space.
lvcreate: Create a Logical Volume (LV) from a VG.
-L: Set size.-n: Set LV name.lvs: Display LVs and their paths.
-o lv_name,vg_name,lv_size,lv_path: Show key LV fields including canonical path.mkfs.xfs: Create an XFS filesystem on a block device.
mount: Mount filesystems.
-a: Mount all entries in /etc/fstab (except noauto).df: Report filesystem space usage.
-h: Human-readable units.blkid: Display UUID and filesystem metadata.tee: Write stdin to a file (works well with sudo).
-a: Append instead of overwrite.lvextend: Extend an LV (block device) before filesystem growth.
-L +SIZE: Increase size by the specified amount.xfs_growfs: Grow an XFS filesystem online.sed: Edit text non-interactively.
-i: Edit file in place.umount: Unmount a filesystem.lvremove: Remove an LV.
-y: Auto-confirm prompts.vgremove: Remove a VG.
-y: Auto-confirm prompts.pvremove: Remove LVM metadata from a PV device.
-y: Auto-confirm prompts.lsblk -f: Show filesystem signatures and UUIDs (useful for cleanup verification).