需求:
考慮一種場景,譬如hdfs中的存儲節點(datanode)所需的磁盤,當集羣規模變大,假設每個節點有20塊盤,集羣有200個節點,那麼實際物理磁盤爲4000塊;假設磁盤年故障率爲1%,那麼,我們是不是可以認爲每天都有1塊盤出現故障需要更換或修復?
現在,爲了解放生產力,具體需求是:當發現磁盤故障後,僅需更換物理磁盤,系統級別的操作全部自動化。
一些問題思考:
1):刪除其信息寫入fstab的故障盤信息
2):新磁盤是不需要分區的,直接格式化
3):故障盤如果修復後,又放回來,如果磁盤數據還保留,不得對其格式化
4):不能對有分區的盤進行操作
5):不能對已掛載的盤操作(考慮故障盤熱插拔的情況)
6):假設磁盤總數是不確定的,因此掛載點的數量,應當和磁盤數量對應
7):不能對有數據的可用進行格式化操作
8):對磁盤操作的前提必須是該磁盤是沒有分區的,沒有數據的
9):對已格式化但未掛載,並符合的磁盤做掛載操作
10):在爲了數據的安全的情況下,歡迎補充…
系統環境:CentOS 6.3 x86_64
shell代碼如下:
#!/bin/bash # Script name: check_disk.sh # Date & Time: 2013-07-08/21:06:08 # Description: # Author: MOS Mlog=${Mlog:-/var/log/check_disk.log} Date="/bin/date +%k:%M:%S/%Y-%m-%d" NUL=/dev/null # 掛載點的父目錄,會自動創建 SDIR=/mpoint # Umt函數:卸載無效磁盤 Umt(){ Ut=(`grep "$SDIR" /etc/fstab|awk '{print $2}'`) Ud=(`grep "$SDIR" /etc/fstab|awk -F\" '{print $2}'`) for d in ${Ut[@]};do if [ -d $d ];then #Dk=`df $d|awk '{print $1}'|/usr/bin/tail -1` Dk=`mount|grep "$d\>"|awk '{print $1}'` Ud=`/sbin/blkid $Dk|awk -F\" '{print $2}'` Td=`grep $d /etc/fstab|awk -F\" '{print $2}'` [ -b "$Dk" ] && Uft=`/sbin/parted $Dk print|/usr/bin/tail -2|/usr/bin/head -1|awk '{print $5}'` Tft=`grep $d /etc/fstab|awk '{print $3}'` if [[ $Ud != $Td || $Uft != $Tft ]];then /bin/umount $d &> $NUL /bin/sed -i "/$d/d" /etc/fstab &> $NUL fi fi done for d in ${Ud[@]};do Unull=`/sbin/blkid|grep $d` if [[ -z $Unull ]];then Mpit=`grep $d /etc/fstab|awk '{print $2}'` /bin/umount $Mpit &> $NUL /bin/sed -i "/$d/d" /etc/fstab &> $NUL fi done } # Mmu函數:掛載有效磁盤 Mmu(){ declare -i P=1 Tb=/etc/fstab Ftb(){ Sft=`/sbin/blkid $Fph|awk -F\" '{print $2}'` Ft=`grep "\<disk$P\>" $Tb` Gud=`grep "\<$Sft\>" $Tb` [[ -n $Ft ]] && /bin/sed -i "/\<disk$P\>/"d $Tb [[ -n $Gud ]] && /bin/sed -i "/\<$Sft\>/"d $Tb } Add(){ Ef=`/sbin/blkid $Fph` [[ -z $Ef ]] && /bin/echo y|/sbin/mkfs.ext4 $Fph &> $NUL Uuid=`/sbin/blkid -s UUID $Fph|awk '{print $2}'` Fs=`/sbin/blkid -s TYPE $Fph|awk -F\" '{print $2}'` Fr="defaults,noatime" echo -en "$Uuid\t"$SDIR"/disk$P\t$Fs\t$Fr\t0 0\n" >> $Tb /bin/mount -a &> $NUL break } Fe(){ Mtp=`mount|grep ""$SDIR"/disk$P\>"` if [[ -n "$Mtp" ]];then echo "`$Date` $Mp is used." >> $Mlog else Ftb Add fi } while : ;do if [[ -d "$SDIR"/disk$P ]];then Fe else /bin/mkdir -p "$SDIR"/disk$P && Ftb Add fi P=P+1 done } # Chech_disk函數:區分磁盤的有效性並調用對應的函數處理 Check_disk(){ [ -x /sbin/partprobe ] && /sbin/partprobe &> $NUL Umt /bin/mount -a &> $NUL for b in ${Exist[@]};do Fph="$Dph$b" [[ ! -b "$Fph" ]] && echo "`$Date` $Fph is not block device !!!" >> $Mlog && continue CTE=`ls "$Fph"*|/usr/bin/wc -l` [[ "$CTE" -ne 1 ]] && echo "`$Date` $Fph mismatches." >> $Mlog && continue DFM=`mount|awk '{print $1}'|grep "^$Fph$" 2>$NUL` [[ -n "$DFM" ]] && echo "`$Date` $Fph is used." >> $Mlog && continue Ugd=`/sbin/parted $Fph print|/usr/bin/wc -l` [[ "$Ugd" -ge 8 && -n "$DFM" ]] && echo "`$Date` parted $Fph >= 8 ." >> $Mlog && continue Lvm=`/sbin/blkid $Fph|grep -E "LVM2_member|swap"` [[ -n "$Lvm" ]] && echo "`$Date` $Fph is LVM or swap." >> $Mlog && continue Fgd=`/sbin/fdisk -l $Fph|/usr/bin/wc -l` [[ "$Fgd" -ge 10 ]] && echo "`$Date` fdisk -l $Fph >=10 ." >> $Mlog && continue Mmu done } if [[ "$1" == "-s" && -z "$2" ]];then if [[ -b /dev/cciss/c0d0 ]];then Ah=hp Dph=/dev/cciss/ Exist=(`ls /dev/cciss/|grep "^\<c0d[0-9][0-9]\{0,1\}\>"`) Check_disk else Exist=(`ls /dev/|grep -E "^\<sd[a-z]{0,1}\>|^\<hd[a-z]{0,1}\>|^\<vd[a-z]{0,1}\>"`) Dph=/dev/ Check_disk fi fi
使用時記得加-s,格式: ./check_disk.sh -s,腳本可直接附件下載。
寫東西不易,覺得湊合就給個贊吧,謝啦