#!/bin/sh MODE=$1 ARRAY=$2 DRIVE=$3 alias logger="logger -s -t mdadm_replace" function DISK_REMOVE { mdadm -D $ARRAY | grep -E "${DRIVE}$" > /dev/null MD_DEV_PRESENT="$?" if [ "$MD_DEV_PRESENT" == "0" ] ; then echo "// SETTING DRIVE($DRIVE) STATE TO FAULTY " echo mdadm $ARRAY -f $DRIVE mdadm $ARRAY -f $DRIVE sleep 5 echo "// REMOVING DRIVE($DRIVE) FROM ARRAY($ARRAY) " echo mdadm $ARRAY -r $DRIVE mdadm $ARRAY -r $DRIVE MD_DEV_REMOVE="$?" if [ "$MD_DEV_REMOVE" != "0" ] ; then echo "// DEVICE ($DRIVE) FAILED TO REMOVE, EXITING UNCLEANLY! " exit 1 fi else echo "// DEVICE ($DRIVE) NOT LISTED, EXITING (PERHAPS REMOVED ALREADY...) " return 1 fi } #/FUNCTION DISK_REMOVE function DISK_READMIT { echo "// ZEROING DRIVE BEFORE ADMITTING BACK TO ARRAY " # set 1MB blocksize for 'dd' BS="1048576" # get blockdev size in bytes: DISK_BYTES=`fdisk -l ${DRIVE} 2>/dev/null | grep bytes | head -1 | awk '{print $5}'` # calculate for DD, to write at offset 64MB from the end of device -> end of device (( DISK_BYTES_OFFSET=( $DISK_BYTES / $BS ) - 64 )) # zero 64MB at start of drive dd if=/dev/zero of=${DRIVE} bs=1M count=64 DD_ERR=$? # check and make sure we are writing to the drive, else exit with an error if [ "${DD_ERR}" != "0" ] ; then echo "COULD NOT ZERO DEVICE ${DRIVE}, EXITING WITH ERROR ${DD_ERR} " exit 1 fi # zero drive starting at offset 64MB from end until it hits the wall dd if=/dev/zero of=${DRIVE} bs=1M seek=$DISK_BYTES_OFFSET # hackey-like reload of device now that it's been b0rked: echo "// RE-LOADING DRIVE BY KERNEL " MASTER=`basename $DRIVE` for SLAVE in /sys/block/$MASTER/slaves/* ; do #echo "SLAVE is $SLAVE " RDEV=`basename $SLAVE` echo 1 > $SLAVE/device/rescan sleep 1 blockdev --rereadpt /dev/$RDEV >/dev/null 2>&1 done blockdev --rereadpt $DRIVE >/dev/null 2>&1 # sleep a few to let udev/kernel catch up sleep 10 # add device back to array now: echo "// mdadm $ARRAY -a $DRIVE" mdadm $ARRAY -a $DRIVE MD_ADD_ERR="$?" if [ "${MD_ADD_ERR}" != "0" ] ; then echo "COULD NOT ADD DEVICE($DRIVE) BACK TO ARRAY($ARRAY), EXITING WITH ERROR ${DD_ERR} " exit 1 fi # array now has the replacement drive. show status and exit: echo -e "\n#### ARRAY $ARRAY STATUS: " | logger cat /proc/mdstat | logger echo -e "\n#### DEVICE $DRIVE STATUS: " | logger mdadm --examine $DRIVE | logger exit 0 } #/FUNCTION DISK_READMIT ### END SETUP. ### START PROGRAM FLOW: if [[ (( x"${ARRAY}" == "x" )) && (( x"${DRIVE}" == "x" )) ]] ; then ### necessary input vals not defined, exit. echo "VALUES NOT SET " exit 1 else ### ALL CLEAR, run program # function $MODE fi