Можем ли мы автоматически ждать необходимое время для smartmontools/smartctl?

Вопрос или проблема

Можем ли мы сделать что-то подобное в скрипте (предпочтительно zsh):

smartctl -t long /dev/sda
smartctl -t long /dev/sdb
smartctl -t long /dev/sdc

[Подождите столько, сколько нужно smartctl]

smartctl -H /dev/sda
smartctl -H /dev/sdb
smartctl -H /dev/sdc

Как видно, я просто пытаюсь автоматизировать это.

Существует 2 возможности. smartctl -c выведет список возможностей устройства, которые включают строки вроде

Рутина короткого самопроверки 
рекомендуемое время опроса:      (   1) минут.
Расширенная рутина самопроверки
рекомендуемое время опроса:      (  48) минут.

Таким образом, вы можете просто прочитать их и сделать паузу на необходимое короткое или длинное время.

Во-вторых, пока тест выполняется, тот же параметр -c выведет текущий статус любого теста, например:

Статус сбора данных в оффлайне:  (0x03) Активность сбора данных в оффлайне
  выполняется.
Статус выполнения самопроверки:      ( 247) Рутины самопроверки в процессе...
  70% от теста осталось.
Общее время для завершения 
сбора данных в оффлайне:    (   44) секунд.

Таким образом, вы можете опрашивать каждые несколько минут и ждать, пока оставшееся время не вернется к 0, а другие поля не примут свои окончательные значения:

Статус сбора данных в оффлайне:  (0x02) Активность сбора данных в оффлайне
  была выполнена без ошибок.
Статус выполнения самопроверки:      (   0) Предыдущая рутина самопроверки завершена
  без ошибок или самопроверка никогда не 
  выполнялась.
Общее время для завершения 
сбора данных в оффлайне:    (    0) секунд.

Это не выглядит красиво, но, похоже, это работает. Легко может быть изменено, чтобы обрабатывать произвольное количество дисков. Модификации приветствуются.

#!/usr/bin/zsh
#set -x

outputmsg () { echo -e "\e[35;1m$@\e[0m"; }
infomsg ()   { echo -e "\e[36;1m$@\e[0m"; }

smartctl -X /dev/sda &> /dev/null
wait_time_greatest=$( smartctl -t short /dev/sda | grep 'Please wait' | sed 's,^\(Please wait \)\([[:digit:]]*\)\(.*\),\2,' )

smartctl -X /dev/sdb &> /dev/null
wait_time_new=$( smartctl -t short /dev/sdb | grep 'Please wait' | sed 's,^\(Please wait \)\([[:digit:]]*\)\(.*\),\2,' )

[ "$wait_time_new" -gt "$wait_time_greatest" ] && wait_time_greatest="$wait_time_new"

wait_time_greatest=$((wait_time_greatest + 1)) #На всякий случай?

infomsg "\nМы закончим через $wait_time_greatest минут ...\n"
sleep "$[wait_time_greatest]m"

outputmsg "Диск sda:"   # Странно, что в отчете не указано ID диска.
echo -e \e[0m       # Необходимо сбросить цвет!
smartctl -H /dev/sda

outputmsg "Диск sdb:"
echo -e \e[0m       # Необходимо сбросить цвет!
smartctl -H /dev/sdb

# Поскольку smartctl, похоже, это портит, нужно выполнить снова:
hdparm -S60y /dev/sda
hdparm -S60y /dev/sdb

В оболочке xonsh вы можете использовать это, чтобы дождаться завершения всех дисков их тестов smart:

while not all(
        $(sudo smartctl -c @(drive) | egrep r"Статус выполнения самопроверки:\s+\(\s*0\)")
        for drive in g`/dev/sd?`):
    sleep 20s

Этот цикл выполняется до тех пор, пока вывод smartctl для всех дисков, совпадающих с глобом /dev/sd?, не соответствует регулярному выражению, переданному в egrep.

Регулярное выражение ищет следующий вывод:

Статус выполнения самопроверки:      (   0)

Пока хотя бы один тест выполняется, соответствующий egrep ничего не находит, возвращая пустую строку. Это заставляет вызов all() возвращать False, что инвертируется в True с помощью not, поддерживая цикл в работе. Как только все диски совпадают, т.е. завершены, цикл while прерывается.

Примечание о sudo

Это требует, чтобы команда sudo smartctl -c /dev/sdX выполнялась без запроса пароля. Либо настройте sudo так, чтобы он не требовал паролей для этой команды, либо настройте его так, чтобы он не требовал пароля в течение времени, превышающего период ожидания с момента последнего использования sudo. Опрос будет держать аутентификацию активной и не требовать пароль до завершения.

Или уберите sudo и выполните оболочку (скрипт) от имени root.

Ответ или решение

Автоматическое ожидание завершения тестов с помощью smartmontools

Вопрос автоматизации ожидания завершения тестов на дисках с использованием инструмента smartctl из пакета smartmontools является распространенной задачей для системных администраторов и техников. В этой статье мы рассмотрим, как можно реализовать автоматическое ожидание, используя язык сценариев zsh.

Возможные подходы

Существует два основных подхода, которые можно использовать для достижения автоматизации вашего сценария:

  1. Изучение временных интервалов тестирования
    Инструмент smartctl предоставляет информацию о времени, необходимом для завершения теста, при помощи команды smartctl -c /dev/sdX. Это позволит нам извлечь ожидаемое время выполнения тестов, затем использовать sleep для ожидания.

  2. Проверка статуса выполнения теста
    Во время выполнения теста можно периодически проверять статус с помощью той же команды smartctl -c /dev/sdX, чтобы видеть, когда тест завершится, и только после этого продолжать выполнение следующего шага.

Рекомендуемый сценарий на языке zsh

Далее приведен пример скрипта, который реализует оба подхода:

#!/usr/bin/zsh

# Функция вывода сообщения
outputmsg () { echo -e "\e[35;1m$@\e[0m"; }
infomsg ()   { echo -e "\e[36;1m$@\e[0m"; }

# Запускаем тесты на всех целевых дисках
for disk in /dev/sda /dev/sdb /dev/sdc; do
    smartctl -t long "$disk" &> /dev/null
done

# Получаем максимальное время ожидания для всех запущенных тестов
wait_time=0
for disk in /dev/sda /dev/sdb /dev/sdc; do
    time_required=$(smartctl -c "$disk" | grep 'recommended polling time:' | awk '{print $NF}')
    wait_time=$(($wait_time > $time_required ? $wait_time : $time_required))
done

infomsg "\nОжидание завершения тестов займет примерно $wait_time минут(ы)...\n"
sleep "${wait_time}m"

# Проверка статуса завершения теста для каждого диска
while true; do
    all_done=true
    for disk in /dev/sda /dev/sdb /dev/sdc; do
        status=$(smartctl -c "$disk" | grep 'Self-test execution status' | awk '{print $NF}')
        if [[ "$status" != "(0)" ]]; then
            all_done=false
            break
        fi
    done
    if $all_done; then
        break
    fi
    sleep 20s
done

# Вывод результатов тестирования
for disk in /dev/sda /dev/sdb /dev/sdc; do
    outputmsg "Результаты теста для $disk:"
    smartctl -H "$disk"
done

Как работает скрипт

  1. Запуск тестов: Скрипт запускает длинные тесты для всех заданных дисков.
  2. Извлечение времени ожидания: Для каждого диска извлекается рекомендованное время ожидания, и выбирается максимальное время для использования в sleep.
  3. Ожидание завершения: После ожидания указанного времени выполняется цикл проверки состояния теста. Скрипт продолжает опрашивать состояние до тех пор, пока все тесты не будут завершены.
  4. Вывод результатов: Напоследок выводятся результаты тестов для каждого диска.

Заключение

Использование приведенного скрипта на zsh позволяет автоматизировать процесс ожидания завершения тестов на дисках, делая вашу работу более эффективной и освобождая время для более важных задач. Обратите внимание на возможность конфигурации sudo, если она необходима для выполнения команд без необходимости ввода пароля.

Этот подход значительно упрощает наблюдение за состоянием дисков и гарантирует, что ваша система останется в исправном состоянии, благодаря регулярной проверке состояния SMART.

Оцените материал
Добавить комментарий

Капча загружается...