mount не выполняется при вызове udev

17

Я попытался создать некоторые правила udev для монтирования и размонтирования моих флешек; правила на данный момент очень просты:

ACTION=="add",KERNEL=="sd[b-z]",RUN+="/root/scripts/plug_flash_drive.sh %k"
ACTION=="remove",KERNEL=="sd[b-z]",RUN+="/root/scripts/unplug_flash_drive.sh %k"

plug_flash_drive.sh также очень прост:

device_name=$1
mount_options="umask=000,utf8"
if [ ! -e "/media/$device_name" ]; then
    mkdir "/media/$device_name"
fi
sleep 1
/usr/bin/mount "/dev/$device_name" "/media/$device_name" -o "$mount_options"

unplug_flash_drive.sh:

device_name=$1

umount "/dev/$device_name"
rmdir "/media/$device_name"

Я провел несколько тестов, чтобы убедиться, что:

  • При подключении моя флешка обнаружена; файл создается в / dev
  • plug_flash_drive.sh вызывается udev
  • часть скрипта mkdir работает
  • однако кажется, что часть «mount» сценария не выполнена, поэтому мой диск не смонтирован
  • когда я вызываю мои скрипты в командной строке, они отлично работают

Кто-нибудь знает, почему mount не выполняется при вызове udev?

РЕДАКТИРОВАТЬ 28/08/14: я добавил «grep -q / proc / mounts && echo success || echo fail» в конце моего скрипта, чтобы проверить в моем журнале отладки, действительно ли устройство смонтировано до его завершения. Оказывается , что устройство будет установлен в тот момент , даже если сценарий вызывается Udev. Таким образом, настоящая проблема в том, что «мое блочное устройство, по-видимому, размонтировано после завершения сценария монтирования при вызове через udev»: s

magva
источник
Это может быть неважно, но почему вы, mkdir "$mount_dir"но rmdir "/media/$device_name"? Где $mount_dirустановлен?
G-Man говорит: «Восстановите Монику»
извините, это опечатка, я использовал некоторые совершенно бесполезные псевдонимы переменных в исходных кодах и удалил их здесь для ясности
magva
Вы пробовали отладку старой школы; например, положив set -xvи exec >> "$HOME"/mount.log 2>&1в .shфайлы?
G-Man говорит: «Восстановите Монику»
1
Я сделал это, но согласно журналу, который я получаю, mount выполняется, когда скрипт вызывается udev. В журнале нет разницы между звонком из udev и из командной строки ... это на самом деле довольно
сложно
1
в этом случае сценарий также завершится ошибкой при запуске из командной строки
magva

Ответы:

22

systemd-udevd работает в своем собственном пространстве имен файловой системы, и по умолчанию монтирование, выполняемое в udev .rules, не распространяется на хост. Для того, чтобы ваши старые сценарии работы вы можете установить MountFlags=sharedв /usr/lib/systemd/system/systemd-udevd.serviceили (лучше) создание и редактирование его копию в/etc/systemd/system/

Смотрите man 5 systemd.execдля получения дополнительной информации, MountFlagsвариант.

user83388
источник
Что вы подразумеваете под "не распространять на хост"?
Себельк
2
@sebelk Я полагаю, что user83388 означает, что они не распространяются в «корневое» пространство имен
Марк
2

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

Вы не должны запускаться mountиз службы Systemd. Даже после комментирования строк MountFlagsи , ваше правило не будет работать для файловых систем FUSE, таких как NTFS или exFAT, потому что процесс FUSE будет убит системой Systemd.PrivateMountssystemd-udevd.service

Посмотрите эту страницу ArchWiki, которая перечисляет несколько лучших вариантов. Я предпочитаю крошечный проект на GitHub под названием udev-media-automount , который просто перезапускает службу Systemd из правила Udev. Это удобный способ обойти различные громоздкие ограничения Udev для пространств имен и дочерних процессов.

Смотрите также этот anwser , который показывает, как использовать SYSTEMD_WANTSпеременную Udev для запуска модуля Systemd.

Метаморфические
источник
-1

Вы можете попробовать использовать :=вместо +=правил RUN назначения.

:=Оператор устанавливает значение списка и запрещает дальнейшие изменения.

XAE
источник
спасибо, но крепление все еще не работает :(
magva
1
Может быть, не в вашем случае, но в моей системе монтирование находится в / bin / mount. Попробуйте "команду -v mount".
xae
1
В моей системе путь, возвращаемый командой -v mount, - это / usr / bin / mount. Я заметил, что у меня также есть исполняемый файл / bin / mount, но он не работает ни при вызове udev
magva