Сценарий BASH не монтирует мое устройство, когда вызывается UDEV.

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

Я пытаюсь создать правило udev, которое монтирует мое устройство по его uuid, чтобы я мог затем прочитать его содержимое.

Мой файл udev находится в /etc/udev/rules.d/99-local.rules, и вот его содержимое:

ACTION=="add", ENV{ID_FS_UUID}=="12CB-F616", SYMLINK+="masterkey", RUN+="/usr/bin/mountkey.sh"

Скрипт, запускаемый правилом udev, состоит из следующего:

LOG_FILE="/tmp/mount-key.log"

mount /dev/masterkey /mnt/masterkey >  "$LOG_FILE"

MOUNT_POINT="$(findmnt -n -o TARGET --source '/dev/masterkey')"

echo "Device mounted at $MOUNT_POINT" >> "$LOG_FILE"


Проблема в том, что когда udev вызывает команду mount, она, похоже, не работает, и команда не производит никакого вывода, как и переменная окружения MOUNT_POINT в файле лога. Даже несмотря на то, что udev действительно создает символьную ссылку masterkey.

Файл лога выглядит так:


Device mounted at 

Я подтвердил, что раздел действительно не смонтирован после выполнения lsblk:

NAME        MAJ:MIN RM   SIZE RO TYPE MOUNTPOINTS
sda           8:0    1   3.8G  0 disk 
└─sda1        8:1    1   3.8G  0 part 
...

Я изменил скрипт и вместо этого запустил его с sudo, но получил тот же вывод, что и выше. Затем я решил запустить команду mount от имени root без ввода пароля (думая, что в этом была проблема), я отредактировал файл /etc/sudoers с помощью visudo и добавил строку с полем NOPASSWD для mount для пользователя root, вот так:

root ALL=(ALL:ALL) ALL
root ALL=NOPASSWD:/usr/bin/mount 

Также я попробовал запустить это различными способами:

ACTION=="add", ENV{ID_FS_UUID}=="12CB-F616", SYMLINK+="masterkey", RUN+="/bin/bash -c '/usr/bin/mountkey.sh'"

ACTION=="add", ENV{ID_FS_UUID}=="12CB-F616", SYMLINK+="masterkey", RUN+="/bin/bash -c 'sudo /usr/bin/mount /dev/masterkey /mnt/masterkey'"

ACTION=="add", ENV{ID_FS_UUID}=="12CB-F616", SYMLINK+="masterkey", RUN+="/bin/bash -c '/usr/bin/mount /dev/masterkey /mnt/masterkey'"

Я пробовал делать все это с sh (с #!/bin/sh) и никакой из этих способов не сработал. Похоже, нет проблемы с вызовом скрипта и созданием символьной ссылки, но проблема возникает при запуске бинарного файла mount любым методом.

И дело не в моем бинарном файле mount, потому что когда я запускаю:

sudo mount /dev/sdnx /mnt/masterkey

он работает корректно.

После многих попыток без намека на то, в чем может быть проблема, я изменил правило udev следующим образом:

ACTION=="add", ENV{ID_FS_UUID}=="12CB-F616", RUN+="/bin/bash -c '/usr/local/bin/mountkey.sh $ID_FS_UUID'"

И мой bash-скрипт:

#!/bin/bash
UUID="$1"
DEVICE=$(blkid -o device -t UUID="$UUID")
echo "$UUID\n$DEVICE" > "/tmp/mountkey.log"

mount $DEVICE /media/masterkey

Но о, сюрприз, ничего не изменилось.


ВИРТУАЛЬНАЯ МАШИНА

Vagrant (archlinux/archlinux)

Ядро 6.10.10-arch1-1

РЕАЛЬНАЯ СИСТЕМА

Я попытался запустить правило udev на своей реальной машине, которая:

Arch linux / 6.13.2-arch1-1

Но я все равно получил тот же результат (раздел в системе не смонтирован).

Таким образом, сделав это, я подтвердил, что проблема заключается в одном из файлов (правило udev или bash-скрипт).

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

Теория

Для понимания проблем, связанных с монтированием устройств с помощью udev и BASH-скриптов, необходимо учитывать особенности работы udev, ограничения контекста, в котором он работает, и потенциоальные ошибки конфигурации. Udev, как система управления устройствами, запускается в фоновом режиме и является частью init system; в большинстве современных систем это systemd. Приложения и скрипты, запускаемые через udev, работают в строго ограниченном окружении без доступа к пользовательским правам или переменным окружения.

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

  1. Ограниченное окружение: Udev не наследует окружение пользователя, поэтому решения на основе переменных окружения, таких как $PATH, могут не работать.
  2. Поток вывода: Udev ожидает, что скрипты завершат работу за определенное время, и в случае задержек или ожидания вывода могут возникать проблемы.
  3. Операции с диском: Операции с файлами и подсистемами ввода-вывода могут быть затруднены из-за недостаточного времени выполнения или доступа.

Пример

Рассмотрим, как можно протестировать и исправить проблемы с udev на примере предоставленных udev-правил и BASH-скрипта.

Вы определили правило udev следующим образом:

ACTION=="add", ENV{ID_FS_UUID}=="12CB-F616", SYMLINK+="masterkey", RUN+="/usr/bin/mountkey.sh"

И соответствующий BASH-скрипт:

#!/bin/bash
LOG_FILE="/tmp/mount-key.log"
mount /dev/masterkey /mnt/masterkey > "$LOG_FILE"
MOUNT_POINT="$(findmnt -n -o TARGET --source '/dev/masterkey')"
echo "Device mounted at $MOUNT_POINT" >> "$LOG_FILE"

Применение

1. Устройства и права доступа

Убедитесь, что устройство правильно идентифицируется с помощью lsblk и подтверждено, что оно действительно имеет UUID 12CB-F616. Например:

lsblk -f | grep '12CB-F616'

Если есть несоответствия, udev не сможет вызвать скрипт корректно.

2. Пересечение требований прав

Запуск mount требует root-прав. В udev важно использовать прямое указание нужных параметров. Пропишите в скрипте:

sudo mount /dev/sda1 /mnt/masterkey

Убедитесь, что sudoers правильно настроены для выполнения команды без пароля:

root ALL=(ALL:ALL) NOPASSWD: /usr/bin/mount /dev/sda1 /mnt/masterkey

3. Тестирование в терминале

Перед тестированием через udev, отладьте скрипт в терминале:

sudo /usr/bin/mountkey.sh

Если ошибки отсутствуют, переходите к отладке через udev.

4. Проверка прав доступа и лога

Логирование—ключевой момент в анализе ошибок. Добавьте отладочную информацию в лог, например, вывод ошибки от mount:

mount /dev/masterkey /mnt/masterkey 2>> "$LOG_FILE"

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

5. Обновление правил udev

После изменений нужно освежить правила:

udevadm control --reload-rules
udevadm trigger

6. Тестирование в изолированном окружении

Создайте виртуальное окружение или VM для проверки готовности правил:
Используйте те же команды и проверьте, работает ли все в свежем окружении.

Исправив указанные несоответствия и внедрив практики тестирования, вы сможете больше влиять на управление устройствами через udev. Проблемы с udev часто связаны с разрешениями и ограниченной средой, но подробное логгирование и тесты помогают быстро их диагностировать и решать.

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

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