Add LVM volume-grow guide; publish iPhone Mirroring + Claude Code login fixes
This commit is contained in:
parent
cf5e35da1d
commit
96db073b78
3 changed files with 166 additions and 0 deletions
|
|
@ -23,6 +23,12 @@ A collection of guides covering Linux administration, shell scripting, networkin
|
||||||
- [Ansible Getting Started](shell-scripting/ansible-getting-started.md)
|
- [Ansible Getting Started](shell-scripting/ansible-getting-started.md)
|
||||||
- [Bash Scripting Patterns](shell-scripting/bash-scripting-patterns.md)
|
- [Bash Scripting Patterns](shell-scripting/bash-scripting-patterns.md)
|
||||||
|
|
||||||
|
## Storage
|
||||||
|
|
||||||
|
- [SnapRAID & MergerFS Storage Setup](storage/snapraid-mergerfs-setup.md)
|
||||||
|
- [mdadm — Rebuilding a RAID Array After Reinstall](storage/mdadm-raid-rebuild.md)
|
||||||
|
- [Growing an LVM Volume by Absorbing Another Disk](storage/lvm-grow-volume-absorb-disk.md)
|
||||||
|
|
||||||
## Distro-Specific
|
## Distro-Specific
|
||||||
|
|
||||||
- [Linux Distro Guide for Beginners](distro-specific/linux-distro-guide-beginners.md)
|
- [Linux Distro Guide for Beginners](distro-specific/linux-distro-guide-beginners.md)
|
||||||
|
|
|
||||||
159
01-linux/storage/lvm-grow-volume-absorb-disk.md
Normal file
159
01-linux/storage/lvm-grow-volume-absorb-disk.md
Normal file
|
|
@ -0,0 +1,159 @@
|
||||||
|
---
|
||||||
|
title: "Growing an LVM Volume by Absorbing Another Disk"
|
||||||
|
domain: linux
|
||||||
|
category: storage
|
||||||
|
tags: [lvm, lvextend, vgextend, pvcreate, resize2fs, ext4, storage, disk, homelab]
|
||||||
|
status: published
|
||||||
|
created: 2026-06-17
|
||||||
|
updated: 2026-06-17
|
||||||
|
---
|
||||||
|
|
||||||
|
# Growing an LVM Volume by Absorbing Another Disk
|
||||||
|
|
||||||
|
When an LVM-backed filesystem fills up and its volume group (VG) has no free
|
||||||
|
extents, you can grow it by adding a second physical disk as a new physical
|
||||||
|
volume (PV), extending the VG onto it, then extending the logical volume (LV)
|
||||||
|
and its filesystem. With ext4 this can be done **online** — no unmount, no
|
||||||
|
downtime for the volume being grown.
|
||||||
|
|
||||||
|
This guide covers the common case where the disk you want to absorb is currently
|
||||||
|
in use by its own LVM volume (you must evacuate and tear that down first), and
|
||||||
|
the precautions that keep it safe.
|
||||||
|
|
||||||
|
> [!warning] This enlarges your failure domain
|
||||||
|
> A single LV spanning two disks linearly (the default — no RAID/mirror) means
|
||||||
|
> **losing either disk loses the entire volume.** ext4 has no parity. Only do
|
||||||
|
> this for data you can rebuild, or layer redundancy (mdadm/LVM RAID) underneath.
|
||||||
|
> Back up anything irreplaceable first.
|
||||||
|
|
||||||
|
## The Short Answer
|
||||||
|
|
||||||
|
If the target disk (`/dev/sdX`) is already empty and unused:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo pvcreate /dev/sdX
|
||||||
|
sudo vgextend myvg /dev/sdX
|
||||||
|
sudo lvextend -l +100%FREE /dev/myvg/mylv
|
||||||
|
sudo resize2fs /dev/mapper/myvg-mylv # ext4, online; use xfs_growfs for XFS
|
||||||
|
```
|
||||||
|
|
||||||
|
The rest of this article handles the harder case: the target disk is currently
|
||||||
|
holding its own LVM volume with data on it.
|
||||||
|
|
||||||
|
## Step-by-Step
|
||||||
|
|
||||||
|
### 1. Survey the current layout
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo pvs # physical volumes → which VG each belongs to
|
||||||
|
sudo vgs # volume groups, free extents (VFree)
|
||||||
|
sudo lvs # logical volumes and sizes
|
||||||
|
lsblk -o NAME,SIZE,TYPE,MOUNTPOINT
|
||||||
|
df -h
|
||||||
|
```
|
||||||
|
|
||||||
|
Confirm:
|
||||||
|
|
||||||
|
- The VG you want to grow (`myvg`) has `0` `VFree` (that's why you're here).
|
||||||
|
- The disk you want to absorb (`/dev/sdX`) is a **standalone** PV — not a member
|
||||||
|
of an mdadm array, a mergerfs branch, or a SnapRAID parity disk. Repurposing a
|
||||||
|
disk that something else depends on will break that thing silently.
|
||||||
|
|
||||||
|
### 2. Evacuate the disk you're about to absorb
|
||||||
|
|
||||||
|
Anything on the target disk will be **destroyed**. Move it somewhere with room to
|
||||||
|
spare, then prove the copy is intact before you trust it.
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Copy preserving permissions/timestamps
|
||||||
|
sudo rsync -a /mnt/olddisk/important /destination/with/space/
|
||||||
|
|
||||||
|
# Verify byte-for-byte — empty output + exit code 0 means identical
|
||||||
|
sudo diff -rq /mnt/olddisk/important /destination/with/space/important && echo OK
|
||||||
|
```
|
||||||
|
|
||||||
|
For large trees the `diff -rq` (full byte comparison) is slow but is the
|
||||||
|
authoritative check — don't skip it before the destructive phase. If an
|
||||||
|
application tracks files by path (databases, media servers), update its path
|
||||||
|
references to the new location *now*, while the old copy still exists as a
|
||||||
|
fallback.
|
||||||
|
|
||||||
|
### 3. Unmount and remove the old disk from fstab
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo fuser -m /mnt/olddisk # confirm nothing holds it open
|
||||||
|
sudo umount /mnt/olddisk
|
||||||
|
mountpoint -q /mnt/olddisk && echo "STILL MOUNTED" || echo "unmounted"
|
||||||
|
|
||||||
|
sudo cp /etc/fstab /etc/fstab.bak-$(date +%Y%m%d) # always back up fstab
|
||||||
|
sudo sed -i '/olddisk/d' /etc/fstab # remove the stale entry
|
||||||
|
grep olddisk /etc/fstab || echo "fstab line gone"
|
||||||
|
```
|
||||||
|
|
||||||
|
> [!tip] Verify your `sed` pattern only matches the line you mean
|
||||||
|
> A too-broad pattern can delete the wrong fstab entry. Check the file before and
|
||||||
|
> after, and keep the backup until you've confirmed the system still boots.
|
||||||
|
|
||||||
|
### 4. Tear down the old disk's LVM
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo lvremove -y /dev/oldvg/oldlv
|
||||||
|
sudo vgremove -y oldvg
|
||||||
|
sudo pvremove -y /dev/sdX # wipes the LVM label off the disk
|
||||||
|
```
|
||||||
|
|
||||||
|
This is the point of no return for the old disk's data — which is why steps 2–3
|
||||||
|
verified the copy first.
|
||||||
|
|
||||||
|
### 5. Add the disk to the target VG and extend
|
||||||
|
|
||||||
|
```bash
|
||||||
|
sudo pvcreate -y /dev/sdX
|
||||||
|
sudo vgextend myvg /dev/sdX
|
||||||
|
sudo lvextend -l +100%FREE /dev/myvg/mylv
|
||||||
|
```
|
||||||
|
|
||||||
|
`lvs`/`vgs` should now show the LV grown to span both disks and `0` free extents.
|
||||||
|
|
||||||
|
### 6. Grow the filesystem (online)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# ext4 — works while mounted
|
||||||
|
sudo resize2fs /dev/mapper/myvg-mylv
|
||||||
|
|
||||||
|
# XFS — grows online too, but takes the mountpoint, not the device
|
||||||
|
sudo xfs_growfs /mountpoint
|
||||||
|
```
|
||||||
|
|
||||||
|
`resize2fs` is idempotent — if it gets interrupted, just run it again; it reports
|
||||||
|
"Nothing to do!" once the filesystem already fills the LV.
|
||||||
|
|
||||||
|
### 7. Verify
|
||||||
|
|
||||||
|
```bash
|
||||||
|
df -h /mountpoint # should reflect the new larger size
|
||||||
|
sudo pvs # /dev/sdX now listed under myvg
|
||||||
|
sudo vgs myvg # two PVs, larger VSize
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes & Gotchas
|
||||||
|
|
||||||
|
- **Online resize works for the volume being grown, not the one being removed.**
|
||||||
|
The disk you absorb must be unmounted and torn down; the destination LV stays
|
||||||
|
mounted throughout.
|
||||||
|
- **`resize2fs` interruption is safe.** ext4 online resize is journaled; re-run it.
|
||||||
|
- **macOS cruft on evacuated disks.** Trees touched by macOS often carry
|
||||||
|
`._*` AppleDouble files and `.DS_Store` — harmless to drop, but they inflate
|
||||||
|
file counts in `diff`/`rsync` output. Don't mistake them for real data.
|
||||||
|
- **Check SMART on a disk you're promoting into a bigger role.** A disk with a
|
||||||
|
pending-sector history is riskier once it's in the critical path for a whole
|
||||||
|
multi-disk volume than it was holding a small isolated one.
|
||||||
|
- **Mountpoint cleanup.** After the old disk is gone, its former mountpoint
|
||||||
|
directory may reappear (it was shadowed by the mount). `rmdir` it if empty.
|
||||||
|
Note `ls -A` exits `0` on an empty directory, so don't gate cleanup on its exit
|
||||||
|
status — test contents explicitly.
|
||||||
|
|
||||||
|
## Related
|
||||||
|
|
||||||
|
- [SnapRAID & MergerFS Storage Setup](snapraid-mergerfs-setup.md) — add redundancy/parity instead of a linear span
|
||||||
|
- [mdadm — Rebuilding a RAID Array After Reinstall](mdadm-raid-rebuild.md)
|
||||||
|
|
@ -12,6 +12,7 @@ updated: 2026-06-19T10:05
|
||||||
* [Bash Scripting Patterns](01-linux/shell-scripting/bash-scripting-patterns.md)
|
* [Bash Scripting Patterns](01-linux/shell-scripting/bash-scripting-patterns.md)
|
||||||
* [SnapRAID & MergerFS Storage Setup](01-linux/storage/snapraid-mergerfs-setup.md)
|
* [SnapRAID & MergerFS Storage Setup](01-linux/storage/snapraid-mergerfs-setup.md)
|
||||||
* [mdadm — Rebuilding a RAID Array After Reinstall](01-linux/storage/mdadm-raid-rebuild.md)
|
* [mdadm — Rebuilding a RAID Array After Reinstall](01-linux/storage/mdadm-raid-rebuild.md)
|
||||||
|
* [Growing an LVM Volume by Absorbing Another Disk](01-linux/storage/lvm-grow-volume-absorb-disk.md)
|
||||||
* [Linux Distro Guide for Beginners](01-linux/distro-specific/linux-distro-guide-beginners.md)
|
* [Linux Distro Guide for Beginners](01-linux/distro-specific/linux-distro-guide-beginners.md)
|
||||||
* [WSL2 Instance Migration to Fedora 43](01-linux/distro-specific/wsl2-instance-migration-fedora43.md)
|
* [WSL2 Instance Migration to Fedora 43](01-linux/distro-specific/wsl2-instance-migration-fedora43.md)
|
||||||
* [WSL2 Training Environment Rebuild](01-linux/distro-specific/wsl2-rebuild-fedora43-training-env.md)
|
* [WSL2 Training Environment Rebuild](01-linux/distro-specific/wsl2-rebuild-fedora43-training-env.md)
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue