#!/bin/bash

# 硬件健康检测脚本
# 检查机械硬盘SMART状态和内存错误修复情况

echo "开始系统硬件健康检测..."
echo "----------------------------------------"

# 获取所有机械硬盘设备列表
DISKS=$(lsblk -d -o NAME,ROTA | awk '$2==1 {print $1}')

# 硬盘检测结果存储文件
HDD_LOG="/tmp/hdd_health_$(date +%s).log"
# 内存检测结果存储文件
MEM_LOG="/tmp/mem_health_$(date +%s).log"

# 检查smartctl是否安装
if ! command -v smartctl &> /dev/null; then
    echo "错误：smartctl工具未安装，请先安装smartmontools包"
    echo "在CentOS/RHEL上可以使用: yum install smartmontools -y"
    echo "在Ubuntu/Debian上可以使用: apt-get install smartmontools -y"
    exit 1
fi

# 存储有问题的磁盘
bad_disks=()

# 定义硬盘检查函数
check_disk_health() {
    local disk=$1
    local device="/dev/$disk"
    local output=$(smartctl -a "$device" 2>&1)
    
    echo "----------------------------------------" | tee -a "$HDD_LOG"
    echo "检测硬盘: $device" | tee -a "$HDD_LOG"
    
    # 检查SMART整体健康状态
    local health_status=$(echo "$output" | grep -i "SMART overall-health self-assessment test result")
    if [ -n "$health_status" ]; then
        echo "SMART健康状态: $health_status" | tee -a "$HDD_LOG"
    else
        echo "警告: 无法获取SMART健康状态" | tee -a "$HDD_LOG"
    fi
    
    # 检查错误日志
    local errors=$(echo "$output" | grep -iE "Error [0-9]+ occurred at disk power-on lifetime")
    if [ -n "$errors" ]; then
        echo ">>> 发现硬盘错误日志:" | tee -a "$HDD_LOG"
        echo "$errors" | head -n 3 | tee -a "$HDD_LOG"
        echo "!!! 该硬盘存在故障或坏道 !!!" | tee -a "$HDD_LOG"
        bad_disks+=("$disk")  # 添加到有问题的磁盘列表
        return 1
    fi
    
    # 检查重分配扇区
    local reallocated=$(echo "$output" | grep -i "Reallocated_Sector_Ct")
    if [ -n "$reallocated" ]; then
        reallocated_count=$(echo "$reallocated" | awk '{print $10}')
        if [ "$reallocated_count" -gt 0 ]; then
            echo ">>> 发现重分配扇区: $reallocated_count" | tee -a "$HDD_LOG"
            echo "!!! 该硬盘存在坏道已被替换 !!!" | tee -a "$HDD_LOG"
            bad_disks+=("$disk")  # 添加到有问题的磁盘列表
            return 1
        fi
    fi
    
    # 检查待处理扇区
    local pending=$(echo "$output" | grep -i "Current_Pending_Sector")
    if [ -n "$pending" ]; then
        pending_count=$(echo "$pending" | awk '{print $10}')
        if [ "$pending_count" -gt 0 ]; then
            echo ">>> 发现待处理扇区: $pending_count" | tee -a "$HDD_LOG"
            echo "!!! 该硬盘存在不稳定扇区 !!!" | tee -a "$HDD_LOG"
            bad_disks+=("$disk")  # 添加到有问题的磁盘列表
            return 1
        fi
    fi
    
    echo "硬盘状态正常" | tee -a "$HDD_LOG"
    return 0
}

# 定义内存检查函数
check_memory_errors() {
    echo "----------------------------------------" | tee -a "$MEM_LOG"
    echo "开始内存错误检查..." | tee -a "$MEM_LOG"
    
    # 检查内存读取错误
    local mem_errors=$(dmesg | grep -i 'memory read error')
    if [ -n "$mem_errors" ]; then
        echo ">>> 发现内存读取错误:" | tee -a "$MEM_LOG"
        echo "$mem_errors" | head -n 5 | tee -a "$MEM_LOG"
        
        # 检查是否有已修复的错误
        local corrected_errors=$(dmesg | grep -i 'It has been corrected')
        if [ -n "$corrected_errors" ]; then
            echo ">>> 发现已修复的内存错误:" | tee -a "$MEM_LOG"
            echo "$corrected_errors" | head -n 5 | tee -a "$MEM_LOG"
            echo "!!! 系统已自动修复部分内存错误，请关注内存健康状况 !!!" | tee -a "$MEM_LOG"
            return 1
        else
            echo "!!! 发现未修复的内存错误，请立即检查内存 !!!" | tee -a "$MEM_LOG"
            return 2
        fi
    else
        echo "未发现内存读取错误" | tee -a "$MEM_LOG"
        return 0
    fi
}

# 执行硬盘检查
echo "========== 硬盘健康检查 =========="
hdd_issues=0  # 初始化硬盘问题标志
if [ -z "$DISKS" ]; then
    echo "未检测到机械硬盘！"
    hdd_status="未检测到机械硬盘"
else
    for disk in $DISKS; do
        check_disk_health "$disk"
        if [ $? -ne 0 ]; then
            hdd_issues=1
        fi
        echo ""
    done
    
    if [ $hdd_issues -eq 1 ]; then
        echo "警告：检测到硬盘存在问题，请查看详细日志：$HDD_LOG"
        hdd_status="存在问题"
    else
        echo "所有硬盘状态正常"
        hdd_status="状态良好"
    fi
fi

echo ""
echo "========== 内存健康检查 =========="
check_memory_errors
mem_status=$?

case $mem_status in
    0) echo "内存状态正常"
       mem_result="状态良好" ;;
    1) echo "警告：检测到已修复的内存错误，请查看详细日志：$MEM_LOG"
       mem_result="存在已修复错误" ;;
    2) echo "严重：检测到未修复的内存错误，请立即检查内存！查看日志：$MEM_LOG"
       mem_result="存在未修复错误" ;;
esac

echo ""
echo "========== 检测总结 =========="
echo "硬盘状态: $hdd_status"
if [ ${#bad_disks[@]} -gt 0 ]; then
    echo "有问题的磁盘: /dev/${bad_disks[*]// /, /dev/}"
fi
echo "内存状态: $mem_result"

if [ -n "$DISKS" ]; then
    echo "硬盘数量: $(echo "$DISKS" | wc -w)"
fi

echo ""
echo "检测完成"
echo "详细日志已保存至: $HDD_LOG 和 $MEM_LOG"

# 返回整体检测状态码
if [ "$hdd_issues" -eq 1 ] || [ "$mem_status" -ne 0 ]; then
    exit 1
else
    exit 0
fi    