repair-ssd.sh
· 4.9 KiB · Bash
Исходник
#!/bin/bash
# =============================================================
# SSD Repair Script (ext4/auto) - Proxmox Edition (Final)
# =============================================================
# 🔙 Обратно към статията:
# https://itpraktika.com/proxmox-ssd-read-only-fix/
MOUNT_POINT="/mnt/backup"
DEVICE="/dev/sda1"
LOG_FILE="repair.log"
# Цветове
RED="\e[31m"
GREEN="\e[32m"
YELLOW="\e[33m"
CYAN="\e[36m"
RESET="\e[0m"
# Проверка за root
if [ "$EUID" -ne 0 ]; then
echo -e "${RED}❌ Стартирай скрипта като root (sudo)!${RESET}"
exit 1
fi
# Подобрена лог функция (с разделител за по-добра четимост)
log_message() {
echo -e "$1"
# Записваме в лога без цветови кодове (за чист текст)
local clean_msg=$(echo -e "$2" | sed 's/\x1b\[[0-9;]*m//g')
echo "$(date '+%Y-%m-%d %H:%M:%S') - $clean_msg" >> "$LOG_FILE"
}
clear
echo -e "${CYAN}==========================================${RESET}"
echo -e "${CYAN} SSD REPAIR TOOL - СИСТЕМА ЗА БЕКЪПИ ${RESET}"
echo -e "${CYAN}==========================================${RESET}"
echo -e "Лог файл: ${YELLOW}$LOG_FILE${RESET}"
echo ""
# Потвърждение
echo -e "${YELLOW}ВНИМАНИЕ: Скриптът ще извърши fsck върху $DEVICE.${RESET}"
read -p "Сигурен ли си? (y/n): " confirm
if [[ $confirm != [yY] ]]; then
echo -e "${RED}❌ Операцията е отменена.${RESET}"
exit 0
fi
# Добавяме празен ред в лога за разделител между отделните пускания
echo "----------------------------------------------------------" >> "$LOG_FILE"
log_message "${CYAN}===> Старт на операция за $DEVICE${RESET}" "STARTING NEW SESSION"
# 1. Проверка mount point
if [ ! -d "$MOUNT_POINT" ]; then
log_message "${RED}❌ Липсва mount point: $MOUNT_POINT${RESET}" "ERROR: Missing mount point directory"
exit 1
fi
# 2. Проверка дали е монтиран и unmount
if mountpoint -q "$MOUNT_POINT"; then
log_message "${YELLOW}⚠️ Дискът е монтиран.${RESET}" "Status: Mounted"
# Показваме кои процеси пречат
BUSY_PIDS=$(fuser -m "$MOUNT_POINT" 2>/dev/null)
if [ -n "$BUSY_PIDS" ]; then
echo -e "${CYAN}Процеси използващи диска (PIDs):${RESET} $BUSY_PIDS"
read -p "Да бъдат ли спрени процесите автоматично? (y/n): " kill_confirm
if [[ $kill_confirm == [yY] ]]; then
log_message "${YELLOW}⚠️ Спиране на процеси...${RESET}" "Action: Killing processes $BUSY_PIDS"
fuser -km "$MOUNT_POINT" 2>/dev/null
sleep 2
fi
fi
echo -e "${CYAN}Опит за unmount...${RESET}"
umount -l "$MOUNT_POINT" # Добавено -l за по-сигурен unmount
if mountpoint -q "$MOUNT_POINT"; then
log_message "${RED}❌ Unmount неуспешен!${RESET}" "ERROR: Umount failed"
exit 1
else
log_message "${GREEN}✅ Успешен unmount${RESET}" "Status: Unmount OK"
fi
else
log_message "${GREEN}✅ Вече е unmounted${RESET}" "Status: Already unmounted"
fi
# 3. fsck (Най-важната част)
log_message "${CYAN}===> Стартиране на fsck...${RESET}" "Action: Running fsck"
fsck -fvy "$DEVICE"
FSCK_RET=$?
if [ $FSCK_RET -lt 4 ]; then
log_message "${GREEN}✅ fsck OK (код: $FSCK_RET)${RESET}" "Result: fsck Success"
else
log_message "${RED}❌ fsck проблем (код: $FSCK_RET)${RESET}" "Result: fsck Critical Failure"
exit 1
fi
# 4. mount обратно
log_message "${CYAN}===> Монтиране...${RESET}" "Action: Remounting"
mount "$DEVICE" "$MOUNT_POINT"
if [ $? -ne 0 ]; then
log_message "${RED}❌ mount грешка${RESET}" "Result: Mount Failed"
exit 1
else
log_message "${GREEN}✅ mount OK${RESET}" "Result: Mount Success"
fi
# 5. Тест за запис
TEST_FILE="$MOUNT_POINT/repair_test_$(date +%s).tmp"
if touch "$TEST_FILE" 2>/dev/null; then
rm "$TEST_FILE"
log_message "${GREEN}✅ WRITE TEST OK${RESET}" "Write Test: PASSED"
else
log_message "${RED}❌ WRITE TEST FAIL (Read-Only?)${RESET}" "Write Test: FAILED"
fi
# 6. SMART и Kernel logs (само на екрана, за да не пълним лог файла с излишно инфо)
echo -e "\n${CYAN}===> Последни kernel съобщения:${RESET}"
dmesg | tail -n 15
PARENT_DISK=$(lsblk -no PKNAME "$DEVICE")
if [ -n "$PARENT_DISK" ] && command -v smartctl >/dev/null 2>&1; then
echo -e "\n${CYAN}===> SMART статус (/dev/$PARENT_DISK):${RESET}"
smartctl -H "/dev/$PARENT_DISK" | grep -iE "result|status|health"
fi
log_message "${GREEN}===> ВСИЧКО ЗАВЪРШИ УСПЕШНО${RESET}" "SESSION FINISHED SUCCESSFULLY"
| 1 | #!/bin/bash |
| 2 | |
| 3 | # ============================================================= |
| 4 | # SSD Repair Script (ext4/auto) - Proxmox Edition (Final) |
| 5 | # ============================================================= |
| 6 | # 🔙 Обратно към статията: |
| 7 | # https://itpraktika.com/proxmox-ssd-read-only-fix/ |
| 8 | |
| 9 | MOUNT_POINT="/mnt/backup" |
| 10 | DEVICE="/dev/sda1" |
| 11 | LOG_FILE="repair.log" |
| 12 | |
| 13 | # Цветове |
| 14 | RED="\e[31m" |
| 15 | GREEN="\e[32m" |
| 16 | YELLOW="\e[33m" |
| 17 | CYAN="\e[36m" |
| 18 | RESET="\e[0m" |
| 19 | |
| 20 | # Проверка за root |
| 21 | if [ "$EUID" -ne 0 ]; then |
| 22 | echo -e "${RED}❌ Стартирай скрипта като root (sudo)!${RESET}" |
| 23 | exit 1 |
| 24 | fi |
| 25 | |
| 26 | # Подобрена лог функция (с разделител за по-добра четимост) |
| 27 | log_message() { |
| 28 | echo -e "$1" |
| 29 | # Записваме в лога без цветови кодове (за чист текст) |
| 30 | local clean_msg=$(echo -e "$2" | sed 's/\x1b\[[0-9;]*m//g') |
| 31 | echo "$(date '+%Y-%m-%d %H:%M:%S') - $clean_msg" >> "$LOG_FILE" |
| 32 | } |
| 33 | |
| 34 | clear |
| 35 | echo -e "${CYAN}==========================================${RESET}" |
| 36 | echo -e "${CYAN} SSD REPAIR TOOL - СИСТЕМА ЗА БЕКЪПИ ${RESET}" |
| 37 | echo -e "${CYAN}==========================================${RESET}" |
| 38 | echo -e "Лог файл: ${YELLOW}$LOG_FILE${RESET}" |
| 39 | echo "" |
| 40 | |
| 41 | # Потвърждение |
| 42 | echo -e "${YELLOW}ВНИМАНИЕ: Скриптът ще извърши fsck върху $DEVICE.${RESET}" |
| 43 | read -p "Сигурен ли си? (y/n): " confirm |
| 44 | |
| 45 | if [[ $confirm != [yY] ]]; then |
| 46 | echo -e "${RED}❌ Операцията е отменена.${RESET}" |
| 47 | exit 0 |
| 48 | fi |
| 49 | |
| 50 | # Добавяме празен ред в лога за разделител между отделните пускания |
| 51 | echo "----------------------------------------------------------" >> "$LOG_FILE" |
| 52 | log_message "${CYAN}===> Старт на операция за $DEVICE${RESET}" "STARTING NEW SESSION" |
| 53 | |
| 54 | # 1. Проверка mount point |
| 55 | if [ ! -d "$MOUNT_POINT" ]; then |
| 56 | log_message "${RED}❌ Липсва mount point: $MOUNT_POINT${RESET}" "ERROR: Missing mount point directory" |
| 57 | exit 1 |
| 58 | fi |
| 59 | |
| 60 | # 2. Проверка дали е монтиран и unmount |
| 61 | if mountpoint -q "$MOUNT_POINT"; then |
| 62 | log_message "${YELLOW}⚠️ Дискът е монтиран.${RESET}" "Status: Mounted" |
| 63 | |
| 64 | # Показваме кои процеси пречат |
| 65 | BUSY_PIDS=$(fuser -m "$MOUNT_POINT" 2>/dev/null) |
| 66 | if [ -n "$BUSY_PIDS" ]; then |
| 67 | echo -e "${CYAN}Процеси използващи диска (PIDs):${RESET} $BUSY_PIDS" |
| 68 | read -p "Да бъдат ли спрени процесите автоматично? (y/n): " kill_confirm |
| 69 | if [[ $kill_confirm == [yY] ]]; then |
| 70 | log_message "${YELLOW}⚠️ Спиране на процеси...${RESET}" "Action: Killing processes $BUSY_PIDS" |
| 71 | fuser -km "$MOUNT_POINT" 2>/dev/null |
| 72 | sleep 2 |
| 73 | fi |
| 74 | fi |
| 75 | |
| 76 | echo -e "${CYAN}Опит за unmount...${RESET}" |
| 77 | umount -l "$MOUNT_POINT" # Добавено -l за по-сигурен unmount |
| 78 | |
| 79 | if mountpoint -q "$MOUNT_POINT"; then |
| 80 | log_message "${RED}❌ Unmount неуспешен!${RESET}" "ERROR: Umount failed" |
| 81 | exit 1 |
| 82 | else |
| 83 | log_message "${GREEN}✅ Успешен unmount${RESET}" "Status: Unmount OK" |
| 84 | fi |
| 85 | else |
| 86 | log_message "${GREEN}✅ Вече е unmounted${RESET}" "Status: Already unmounted" |
| 87 | fi |
| 88 | |
| 89 | # 3. fsck (Най-важната част) |
| 90 | log_message "${CYAN}===> Стартиране на fsck...${RESET}" "Action: Running fsck" |
| 91 | fsck -fvy "$DEVICE" |
| 92 | FSCK_RET=$? |
| 93 | |
| 94 | if [ $FSCK_RET -lt 4 ]; then |
| 95 | log_message "${GREEN}✅ fsck OK (код: $FSCK_RET)${RESET}" "Result: fsck Success" |
| 96 | else |
| 97 | log_message "${RED}❌ fsck проблем (код: $FSCK_RET)${RESET}" "Result: fsck Critical Failure" |
| 98 | exit 1 |
| 99 | fi |
| 100 | |
| 101 | # 4. mount обратно |
| 102 | log_message "${CYAN}===> Монтиране...${RESET}" "Action: Remounting" |
| 103 | mount "$DEVICE" "$MOUNT_POINT" |
| 104 | |
| 105 | if [ $? -ne 0 ]; then |
| 106 | log_message "${RED}❌ mount грешка${RESET}" "Result: Mount Failed" |
| 107 | exit 1 |
| 108 | else |
| 109 | log_message "${GREEN}✅ mount OK${RESET}" "Result: Mount Success" |
| 110 | fi |
| 111 | |
| 112 | # 5. Тест за запис |
| 113 | TEST_FILE="$MOUNT_POINT/repair_test_$(date +%s).tmp" |
| 114 | if touch "$TEST_FILE" 2>/dev/null; then |
| 115 | rm "$TEST_FILE" |
| 116 | log_message "${GREEN}✅ WRITE TEST OK${RESET}" "Write Test: PASSED" |
| 117 | else |
| 118 | log_message "${RED}❌ WRITE TEST FAIL (Read-Only?)${RESET}" "Write Test: FAILED" |
| 119 | fi |
| 120 | |
| 121 | # 6. SMART и Kernel logs (само на екрана, за да не пълним лог файла с излишно инфо) |
| 122 | echo -e "\n${CYAN}===> Последни kernel съобщения:${RESET}" |
| 123 | dmesg | tail -n 15 |
| 124 | |
| 125 | PARENT_DISK=$(lsblk -no PKNAME "$DEVICE") |
| 126 | if [ -n "$PARENT_DISK" ] && command -v smartctl >/dev/null 2>&1; then |
| 127 | echo -e "\n${CYAN}===> SMART статус (/dev/$PARENT_DISK):${RESET}" |
| 128 | smartctl -H "/dev/$PARENT_DISK" | grep -iE "result|status|health" |
| 129 | fi |
| 130 | |
| 131 | log_message "${GREEN}===> ВСИЧКО ЗАВЪРШИ УСПЕШНО${RESET}" "SESSION FINISHED SUCCESSFULLY" |