|
| 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