When automating disk preparation in Linux systems, traditional methods like dd if=/dev/zero
leave the kernel's partition table cache out of sync. Here's what actually happens under the hood:
# Typical MBR wipe command
dd if=/dev/zero of=/dev/sdX bs=512 count=1 conv=notrunc
The kernel maintains an in-memory copy of partition tables. Any active handles (mounts, LVM, mdadm, swap) will block partition table updates:
# Common error patterns
sudo blockdev --rereadpt /dev/sda
# BLKRRPART: Device or resource busy
partprobe
# Error: Partition(s) on /dev/sda are in use
This bash function handles all common disk usage scenarios:
#!/bin/bash
function disk_reset() {
local disk=$1
[[ -b "$disk" ]] || { echo "Invalid block device"; return 1; }
# Unmount all partitions
grep "^$disk" /proc/mounts | awk '{print $2}' | sort -r | xargs -r umount
# Deactivate LVM
if command -v vgchange &>/dev/null; then
vgchange -an 2>/dev/null
for vg in $(vgs --noheadings -o vg_name 2>/dev/null); do
vgremove -f "$vg" 2>/dev/null
done
fi
# Stop MD arrays
if command -v mdadm &>/dev/null; then
mdadm --stop --scan
mdadm --remove --scan
fi
# Clear swap
swapoff -a
# Wipe MBR and partition table
dd if=/dev/zero of="$disk" bs=1M count=10 conv=fsync
# Force kernel to reload
partx -d "$disk" 2>/dev/null
partprobe "$disk"
blockdev --rereadpt "$disk" 2>/dev/null
}
# Usage: disk_reset /dev/sda
For systems with sg3_utils package:
# Physical disk reset (like power cycle)
sg_reset /dev/sda
# Combined with wipe:
sg_format --format /dev/sda
For advanced cases where device handlers persist:
# List all open handles
lsof /dev/sda*
# Force-close file descriptors
for fd in $(ls /proc/*/fd/* 2>/dev/null | grep -P '/dev/sda'); do
kill -9 $(echo $fd | cut -d'/' -f3)
done
Remember that some operations (like filesystem journal replays) may require a full reboot for complete cleanup.
When working with storage devices in Linux, you often need to completely wipe a disk's partition table and MBR (Master Boot Record) to start fresh. While tools like dd
can overwrite these structures, the kernel often keeps old partition information cached, leading to "device busy" errors when trying to repartition.
The fundamental issue is that Linux maintains device mappings in memory even after you've destroyed the partition table. This is particularly problematic when dealing with:
- Mounted filesystems
- LVM volumes
- MD RAID arrays
- Swap partitions
Here's a comprehensive bash script that handles all these cases:
#!/bin/bash
# Check root privileges
if [ "$(id -u)" != "0" ]; then
echo "This script must be run as root" 1>&2
exit 1
fi
# Validate input
if [ -z "$1" ]; then
echo "Usage: $0 /dev/sdX"
exit 1
fi
DEVICE="$1"
# Verify device exists
if [ ! -b "$DEVICE" ]; then
echo "Error: $DEVICE is not a block device"
exit 1
fi
# Unmount all partitions
echo "Unmounting any mounted partitions..."
umount -l ${DEVICE}* 2>/dev/null
# Stop any LVM activity
echo "Stopping LVM volumes..."
vgchange -an 2>/dev/null
for vg in $(vgs --noheadings -o vg_name 2>/dev/null); do
vgremove -f "$vg" 2>/dev/null
done
pvremove -ff "$DEVICE"* 2>/dev/null
# Stop MD RAID arrays
echo "Stopping MD RAID devices..."
for md in $(ls /dev/md/* 2>/dev/null); do
mdadm --stop "$md" 2>/dev/null
mdadm --remove "$md" 2>/dev/null
done
# Clear swap
echo "Deactivating swap..."
swapoff -a
# Wipe partition table
echo "Wiping partition table..."
dd if=/dev/zero of="$DEVICE" bs=512 count=1 conv=notrunc 2>/dev/null
# Force kernel to reread partition table
echo "Reloading partition table..."
blockdev --rereadpt "$DEVICE" 2>/dev/null || partprobe "$DEVICE" 2>/dev/null
echo "Disk $DEVICE has been completely reset"
For different scenarios, consider these alternatives:
Using sgdisk (GPT disks)
sgdisk -Z /dev/sdX
sgdisk -o /dev/sdX
partprobe /dev/sdX
Using wipefs
wipefs -a /dev/sdX
partprobe /dev/sdX
If you still encounter "device busy" errors, try removing device mapper references:
dmsetup remove_all
partprobe
For data center environments, you might want to reset all non-system disks:
for disk in $(lsblk -dn -o NAME | grep -v $(lsblk -no PKNAME $(findmnt -n / -o SOURCE)))
do
/path/to/reset_script.sh "/dev/$disk"
done
- Always double-check the device path before running destructive commands
- This process doesn't securely erase data - use proper wiping tools for that
- Some hardware RAID controllers may require additional steps
- NVMe devices might need
nvme format
instead