Вопрос или проблема
Этот вопрос уже неоднократно задавался относительно реализации /dev/random
в Linux, но я не могу найти ответ, специфичный для FreeBSD.
Из страницы мануала FreeBSD random(4)
:
Генератор начнет работу в состоянии без семени и будет блокировать чтения до тех пор, пока не будет посеян в первый раз. Это может вызвать проблемы при загрузке системы, когда ключи и подобные данные генерируются из случайных, поэтому необходимо предпринять шаги, чтобы обеспечить посев как можно скорее.
Я задаю этот вопрос, потому что предпочел бы, чтобы мои скрипты завершались с ошибкой, вместо того чтобы зависать из-за того, что /dev/random
ещё не был посеян.
- На момент, когда вы задали свой вопрос, последней версией FreeBSD была 12.0.
На тот момент страница мануала для устройстваrandom
не делала никаких упоминаний о службеsave-entropy
(хотя она уже существовала).
Если вы ее не отключали, эта служба кэширует некоторую энтропию и считывает ее при загрузке. -
# REQUIRE: random
Учитывая, что
/etc/rc.d/random
удаляет файлы энтропии после использования (предотвращая случайное повторное использование), эвристика может заключаться в проверке наличия файлов кэша энтропии.
Тем не менее, записьcrontab
может просто снова заполнить его в следующий миг, или файлы вообще могут не существовать (например, из-за нехватки места на диске). - Если у вас установлены GNU coreutils, вы можете использовать флаг ввода
gdd
nonblock
и продолжить или выйти в зависимости от того, сколько данных было выдачи. - Если вас не беспокоит небольшая задержка, используйте
timeout
, либо для командного запроса, который просто считывает и отбрасывает/dev/random
, либо для той команды, которая вам важна, при условии, что её безопасно остановить.read -t 1s -r dummy < /dev/random || { info 'Пропускаем, потому что /dev/random пока не готов.' exit 0 }
Ответ или решение
Для проверки блокировки /dev/random
в FreeBSD есть несколько эффективных методов, которые помогут вам избежать зависания скриптов и гарантировать их корректное завершение с ошибкой, если ресурс не готов к чтению.
1. Понимание работы /dev/random
Согласно документации FreeBSD, генератор случайных чисел в /dev/random
начинает свою работу в неинициализированном состоянии и блокируется при чтении до тех пор, пока он не будет инициализирован. Это может вызвать проблемы при загрузке системы, если используются ключи или подобные данные, зависящие от случайных чисел. Таким образом, важно убедиться, что генератор семенен перед использованием.
2. Проверка наличия файлов кэша энтропии
Служба save-entropy
может кэшировать некоторую энтропию при загрузке. Вы можете проверить наличие файлов кэша энтропии, чтобы понять, был ли процесс инициализации завершен успешно. Обычно файлы кэша находятся в /var/db/entropy/
или другом конфигурируемом месте. Например, вы можете воспользоваться следующим скриптом для проверки существования файлов кэша:
if ls /var/db/entropy/* 1> /dev/null 2>&1; then
echo "Энтропия загружена."
else
echo "Энтропия не загружена."
exit 1
fi
Однако, кэш может обновляться, что делает этот метод не совсем надежным.
3. Использование gdd
с флагом nonblock
Если в вашей системе установлены утилиты GNU, можно воспользоваться командой gdd
с флагом nonblock
. Этот подход позволяет вам попробовать прочитать данные из /dev/random
без блокировки:
gdd if=/dev/random bs=1 count=1 status=none || {
echo "/dev/random блокирует чтение. Завершение."
exit 1
}
Если чтение прошло успешно, то генератор случайных чисел готов к использованию.
4. Применение команды timeout
Для более традиционного подхода, вы можете использовать команду timeout
для ограничения времени ожидания чтения из /dev/random
. Например, следующий скрипт использует read
с таймаутом:
read -t 1s -r dummy < /dev/random || {
echo 'Пропускаем, так как /dev/random еще не готов.'
exit 0
}
Этот способ позволяет задать максимальное время ожидания. Если в течение этого времени данные не готовы, скрипт завершится без блокировки.
Заключение
Таким образом, для вывода состояния /dev/random
и предотвращения блокировки в FreeBSD вы можете воспользоваться различными методами: проверкой наличия файлов кэша энтропии, использованием gdd
с флагом nonblock
, или применением утилиты timeout
. Каждый из этих подходов обладает своими достоинствами и может быть использован в зависимости от ваших конкретных требований. Выбор подхода будет зависеть от связанной с вашим скриптом критичности времени выполнения и доступности системных утилит.