Skip to content
This repository was archived by the owner on Sep 2, 2021. It is now read-only.

Commit d1e9d28

Browse files
authored
Merge pull request #121 from digitalrebar/erase-disk-set
Add erase a subset of disks specified by an optional parameter.
2 parents ba427e2 + d926e80 commit d1e9d28

File tree

3 files changed

+148
-0
lines changed

3 files changed

+148
-0
lines changed
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
---
2+
Name: "erase-hard-disk-set"
3+
Description: "Defines the set of disks to erase"
4+
Documentation: |
5+
This string defines the set of disks to erase. Space separated dev names.
6+
7+
e.g. "/dev/sda /dev/sdb"
8+
9+
Schema:
10+
type: "string"
11+
12+
Meta:
13+
icon: "disk outline"
14+
color: "blue"
15+
title: "Digital Rebar Community Content"
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
---
2+
Name: "erase-hard-disk-set"
3+
Description: |
4+
Erases a set of disks.
5+
BootEnv: "sledgehammer"
6+
RunnerWait: true
7+
Tasks:
8+
- "erase-hard-disk-set"
9+
Meta:
10+
icon: "disk outline"
11+
color: "yellow"
12+
title: "Digital Rebar Community Content"
Lines changed: 121 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
---
2+
Name: "erase-hard-disk-set"
3+
Description: |
4+
Erases any data on the specified hard disk that might confuse the OS install
5+
process. This includes LVM metadata, partition tables, software RAID signatures,
6+
and the first and last megabyte of any partitions and disks.
7+
Meta:
8+
feature-flags: "sane-exit-codes"
9+
icon: "erase"
10+
color: "blue"
11+
title: "Digital Rebar Community Content"
12+
RequiredParams:
13+
- zero-hard-disks-for-os-install
14+
OptionalParams:
15+
- erase-hard-disk-set
16+
Templates:
17+
- Name: "erase-disk"
18+
Contents: |
19+
#!/bin/bash
20+
. helper
21+
22+
# Clear functional data - assumes /dev/sda or the like
23+
function clear_disk() {
24+
local disk
25+
disk=$1
26+
diskbase=${disk/\/dev\/}
27+
28+
# Deactivate all known lvm and dm devices first, unmounting filesystems as needed.
29+
echo "Deactivating all known volume groups on $disk"
30+
blkdeactivate -u -d force,retry -l retry,wholevg $disk || :
31+
# Nuke it all.
32+
declare vg pv maj min blocks name
33+
# Make sure that the kernel knows about all the partitions
34+
echo "Probing for all partitions on $disk. Failures are OK."
35+
partprobe "$disk" || :
36+
37+
# Zap any volume groups that may be lying around.
38+
vgscan --ignorelockingfailure -P
39+
while read vg; do
40+
echo "Forcibly removing volume group $vg"
41+
vgremove -ff -y "$vg" || :
42+
done < <(vgs --noheadings -o vg_name,pv_name | grep $disk | awk '{ print $1 }' | sort -u)
43+
44+
# Wipe out any LVM metadata that the kernel may have detected.
45+
pvscan --ignorelockingfailure
46+
while read pv; do
47+
echo "Forcibly removing physical volume $pv"
48+
pvremove -ff -y "$pv" || :
49+
done < <(pvs --noheadings -o pv_name | grep $disk)
50+
51+
# Now zap any partitions along with any RAID metadata that may exist.
52+
while read maj min blocks name; do
53+
[[ -b /dev/$name && -w /dev/$name && $name != name ]] || continue
54+
echo "Forcibly removing any RAID metadata on /dev/$name. Failures are OK if readonly"
55+
mdadm --misc --zero-superblock --force /dev/$name || :
56+
if (( blocks >= 4096)); then
57+
echo "Zeroing the first and last 2 megs of /dev/$name. Failures are OK if readonly"
58+
dd "if=/dev/zero" "of=/dev/$name" "bs=512" "count=4096" || :
59+
dd "if=/dev/zero" "of=/dev/$name" "bs=512" "count=4096" "seek=$(($blocks - 4096))" || :
60+
else
61+
echo "Zeroing small device /dev/$name. Failures are OK if readonly"
62+
dd "if=/dev/zero" "of=/dev/$name" "bs=512" "count=$blocks" || :
63+
fi
64+
done < <(tac /proc/partitions | grep $diskbase)
65+
}
66+
67+
# Wipe disk assumes /dev/sda or the like
68+
function wipe_disk() {
69+
local disk bd dev spinner want_zero skip_zero
70+
disk=$1
71+
bd=/sys/block/${disk/\/dev\/}
72+
dev="/dev/${bd##*/}"
73+
74+
[[ -b $dev ]] || continue
75+
grep -q 'devices/virtual' < <(readlink "$bd") && continue
76+
spinner=$(cat "$bd/queue/rotational")
77+
want_zero="{{.Param "zero-hard-disks-for-os-install"}}"
78+
skip_zero=$(cat "$bd/queue/discard_zeroes_data")
79+
if [[ $want_zero = true && $skip_zero != 1 && $spinner = 1 ]]; then
80+
# blkdiscard -z does the same job as dd if=/dev/zero,
81+
# except the kernel does all the work and it uses
82+
# the SCSI command WRITE_SAME if the device supports
83+
# it, which can greatly speed up the zeroing process.
84+
echo "Zeroing $dev"
85+
blkdiscard -z "$dev" || :
86+
fi
87+
# if discard_max_bytes is zero, then blkdiscard will not work anyways.
88+
if [[ $(cat "$bd/queue/discard_max_bytes") != 0 ]]; then
89+
# Try secure erase first, then regular discard.
90+
echo "Attempting to secure discard $dev."
91+
echo "This may fail if the device does not support secure discard."
92+
if blkdiscard -s "$dev"; then
93+
echo "Secure discard of $dev finished"
94+
else
95+
echo "Sercure discard of $dev failed, attempting normal discard"
96+
if blkdiscard "$dev"; then
97+
echo "Normal discard of $dev finished"
98+
else
99+
echo "Normal discard of $dev failed"
100+
fi
101+
fi
102+
fi
103+
}
104+
105+
{{if .ParamExists "erase-hard-disk-set" }}
106+
disks="{{.Param "erase-hard-disk-set"}}"
107+
# fill out disks
108+
for bd in $disks; do
109+
clear_disk $bd
110+
done
111+
# For paranoia's sake, try to discard all blocks on the remaining
112+
# top-level block devices in parallel.
113+
for bd in $disks; do
114+
( wipe_disk $bd ) &
115+
done
116+
wait
117+
partprobe
118+
{{else}}
119+
echo "No disks to erase. Skipping..."
120+
{{end}}
121+
exit 0

0 commit comments

Comments
 (0)