#!/bin/bash # # Copyright (c) 2013-2022 Wind River Systems, Inc. # # SPDX-License-Identifier: Apache-2.0 # usage () { echo "Usage: `basename $0` [-h|--force|--include-backup]" echo "Erases the master boot record on the hard drive." echo "WARNING: All data on this hard drive will be lost." echo "" echo "Options:" echo " -h display this help" echo " --force do not ask for confirmation" echo " --include-backup removes data from platform backup directory" exit 1 } # Systemd automatically remounts all the mounted filesystems at shutdown # When we are deleting a partition, we have to unmount its corresponding filesystem # because remounting deleted filesystems at shutdown will throw errors unmount_fs() { local fs=$1 local ret_code=0 echo "Trying to unmount $fs" if findmnt $fs > /dev/null 2>&1 ; then if umount -f $fs ; then echo "$fs has been successfully unmounted" else echo "Error! Failed to unmount $fs" ret_code=1 fi else echo "Warning! $fs is not mounted" ret_code=2 fi return $ret_code } OPTS=`getopt -o h -l force,include-backup -- "$@"` if [ $? != 0 ] ; then exit 1 fi eval set -- "$OPTS" while true ; do case "$1" in -h) usage; shift;; --force) FORCE=1; shift;; --include-backup) INCLUDE_BACKUP=1; shift;; --) shift; break;; esac done if [ $# != 0 ] ; then echo "Invalid argument. Use -h for help." exit 1 fi declare WIPE_HDD= # Only wipe the boot device disks boot_disk_part=$(df --output=source /boot | tail -1) boot_disk_path=$(find -L /dev/disk/by-path/ -samefile ${boot_disk_part} | sed 's/-part[0-9]*'//) if [ -z "${boot_disk_path}" ] ; then boot_disk_path=$(find -L /dev/disk/by-id/ -samefile ${boot_disk_part} | grep wwn | sed 's/-part[0-9]*'//) fi boot_disk=$(readlink -f ${boot_disk_path}) if [ -z "$boot_disk" ] ; then echo "Boot disk not found. Failed to wipe disk." exit 1 else WIPE_HDD="$boot_disk" fi # Due to dynamic partitioning, volume groups can have PVs across multiple disks. # When deleting the boot disk volume groups, we should also delete all PVs # (across all disks) that are part of volume groups that are also present on the # boot disk. boot_disk_vgs=$(pvdisplay -C --separator ' | ' -o pv_name,vg_name | grep $boot_disk | awk '{print $3}' | sort -u) pvs_to_delete="" for vg in $boot_disk_vgs ; do pv=$(pvdisplay --select "vg_name=$vg" | awk '/PV Name/{print $3}') pvs_to_delete="$pvs_to_delete $pv" done WIPE_HDD="$pvs_to_delete $WIPE_HDD" if [ ! $FORCE ] ; then echo "This will result in the loss of all data on the hard drives and" echo "will require this node to be re-installed." echo "The following disks will be wiped:" for dev in $WIPE_HDD ; do echo " $dev" done | sort echo read -p "Are you absolutely sure? [y/n] " -r if [[ ! $REPLY =~ ^[Yy]$ ]] ; then echo "Aborted" exit 1 fi read -p "Type 'wipediskscompletely' to confirm: " -r if [[ ! $REPLY = "wipediskscompletely" ]] ; then echo "Aborted" exit 1 fi fi # Note that the BA5EBA11-0000-1111-2222- is the prefix used by STX and it's defined in sysinv constants.py. # Since the 000000000001 suffix is used by custom stx LVM partitions, # the next suffix is used for the persistent backup partition (000000000002) BACKUP_PART_GUID="BA5EBA11-0000-1111-2222-000000000002" part_type_guid_str="Partition GUID code" # get the nodetype variable to check later if this node is a controller . /etc/platform/platform.conf for dev in $WIPE_HDD ; do if [[ -e $dev ]] ; then if [[ "$dev" == "$boot_disk" && "${nodetype}" == "controller" ]] ; then part_numbers=( $(parted -s $dev print | awk '$1 == "Number" {i=1; next}; i {print $1}') ) for part_number in "${part_numbers[@]}" ; do part=$dev$part_number case $part in *"nvme"*) part=${dev}p${part_number} ;; *"dm-"*) for p in /dev/disk/by-id/wwn-*; do if [ "${dev}" = "$(readlink -f ${p})" ]; then part=${p}-part${part_number} break fi done ;; esac sgdisk_part_info=$(flock $dev sgdisk -i $part_number $dev) part_type_guid=$(echo "$sgdisk_part_info" | grep "$part_type_guid_str" | awk '{print $4;}') if [[ "$part_type_guid" == $BACKUP_PART_GUID && ! $INCLUDE_BACKUP ]] ; then echo "Skipping wipe backup partition $part..." continue fi echo "Wiping partition $part..." wipefs -f -a $part # Delete the first few bytes at the start and end of the partition. This is required with # GPT partitions, they save partition info at the start and the end of the block. # Skip / or we will lose access to the tools on the system. if [[ $part != $boot_disk_part ]] ; then unmount_fs $part dd if=/dev/zero of=$part bs=512 count=34 dd if=/dev/zero of=$part bs=512 count=34 seek=$((`blockdev --getsz $part` - 34)) fi echo "Removing partition $part..." sgdisk $dev --delete $part_number done # Wipe bootloader signature to allow reboot from secondary boot devices (e.g. PXE) dd if=/dev/zero of=$dev bs=440 count=1 else echo "Wiping $dev..." wipefs -f -a $dev unmount_fs $dev # Clearing previous GPT tables or LVM data # Delete the first few bytes at the start and end of the partition. This is required with # GPT partitions, they save partition info at the start and the end of the block. dd if=/dev/zero of=$dev bs=512 count=34 dd if=/dev/zero of=$dev bs=512 count=34 seek=$((`blockdev --getsz $dev` - 34)) fi fi done if [[ -z $WIPE_HDD ]] ; then echo "No disks were detected." else sync echo "The disk(s) have been wiped." fi