суббота, 5 сентября 2009 г.

FreeBSD: Automount

Известная проблема непривелегированного использования съёмных носителей с неродными файловыми системами с использованиеванием таблиц перекодирования символов (mount_msdosfs: msdosfs_iconv: Operation not permitted) под FreeBSD может быть решена, собственно, самой системой.

Как это есть


Обычный сценарий использования съёмного носителя под операционными системами класса Unix заключается в следующем:
  1. Подсоединить устройство с носителем к внешнему интерфейсу (USB, SAS, FireWire).
  2. Создать каталог-точку монтирования (если каталог не создан заранее).
  3. Смонтировать сменный носитель в каталог-точку монтирования с опциями по перекодированию символов неродной файловой системы в родную файловую систему и обратно.
  4. Поработать с файловой системой носителя.
  5. Демонтировать сменный носитель.
  6. Отсоединить устройство.

Все эти действия пользователь выполняет без какой-либо автоматизации, вручную!

В отличие от вездесущего Linux-демона HAL, работающего в связке с PolicyKit и демоном информационной шины D-Bus, встроенные системные средства FreeBSD позволяют обойтись без нагромождений стороннего софта. Естественно, модуль конвертации кодировок msdosfs_iconv из одной системы в другую и обратно всё же должен быть прописан в автозагрузке в файле /boot/loader.conf (msdosfs_iconv_enable="YES"), либо вкомпилирован в ядро системы (options MSDOSFS_ICONV).

"Всё должно быть просто, но не так чтобы сильно." © кто-то из великих

Преамбула


Только хозяин (owner, создатель) каталога может производить в него монтирование устройств, работать с файловой системой смонтированого устройства как ему вздумается. Демон devd(8) (device state change daemon) работает с системной (root) учётной записью и у него нет понятия "текущий пользователь" (строго говоря, FreeBSD — это многопользовательская ОС, в которой одновременно работают различные процессы под разными учётными записями). В общем, демон devd(8) имеет понятие только об устройствах (классах устройств) виртуальной файловой системы devfs(8), файловой системе вообще и событиях, случающихся в системе, но не имеет понятия, какой пользователь подсоединил или отсоединил девайс.

Фокус-покус


Хорошая новость: FreeBSD больше не падает при отсоединении неотмонтированной флэшки. А именно это будет происходить всякий раз, при использовании следующего описания. Хотя и не страшно.

Пишем в /etc/devd.conf следующие строчки:

# Automount
attach 10 {
match "device-name" "umass[0-9]+";
action "sleep 4 && mkdir -p /media/$device-name && chown -R username /media/$device-name && \
(/sbin/mount_msdosfs -o sync -L ru_RU.UTF-8 -D CP1251 /dev/da0s1 /media/$device-name || \
/sbin/mount_msdosfs -o sync -L ru_RU.UTF-8 -D CP1251 /dev/da0 /media/$device-name)";
};
detach 10 {
match "device-name" "umass[0-9]+";
action "/sbin/umount -f /media/$device-name && rm -r /media/$device-name";
};

Запускаем демон состояния виртуальной файловой системы устройств:
% echo 'devd_enable="YES"' >> /etc/rc.conf
% /etc/rc.d/devd start

Или рестартуем его, если он работает (чтобы он перечитал свой конфиг):
% /etc/rc.d/devd restart
Stopping devd.
Starting devd.

На события attach/detach демон devd(8) реагирует следующим образом: определяет, какой тип устройства подключается/отключается (здесь: umassНомерустройства) и совершает соответствующее действие (action). Из описанных действий нетрудно понять, каким образом ведётся работа с флэшкой.

При подсоединении съёмного носителя (флэшки) будет создан каталог /media/umass0, носитель будет подвергнут проверке fsck и, если никаких ошибок не найдено, созданный каталог изменит владельца на username, и в этот каталог смонтируется устройство /dev/da0s1 (первый слайс накопителя с файловой системой FAT). После этого пользователь, имеющий учётную запись username, сможет работать с устройством как с собственным файловым хранилищем.

Так как устройство работает в синхронном режиме, то есть данные на носитель пишутся и читаются последовательно, без отложенных операций, то ручное отмонтирование не требуется — по завершении всех операций достаточно просто отсоединить устройство — это событие заставит демон devd(8) выполнить действия по очистке точки монтирования, как в виртуальной файловой системе devfs (демонтирует каталог /dev/da0s1), так и в реальной файловой системе (удалит временный каталог /media/umass0).

Три ложечки дёгтя


  1. Необходимость в использовании имени учётной записи пользователя (username), к которому привязывается точка монтирования;
  2. Фиксированное название раздела носителя (da0s1) не позволит смонтировать в автоматическом режиме другие носители;
  3. Фиксированный тип файловой системы (msdosfs) на монтируемом носителе не позволяет правилом attach смонтировать носитель, с тем же названием раздела, но с отличной от FAT ФС.


P.S.


Я имею представление о портах, позволяющих обходить проблему автомонтирования флэшек с разных сторон: sysutils/kiconvtool и sysutils/automounter. Но лично у меня первый порт не заработал (ошибка осталась), а второй несколько избыточен по функциональности (надстройка над amd(8)).

4 комментария:

Pavel комментирует...

Странно, у меня kiconvtool работает без каких-либо проблем на нескольких машинах.
Можно узнать, что именно для него прописывалось в rc.conf и что в fstab?
Можем пообщаться через джаббер: pavel(точка)greenberg(собака)gmail(точка)com.

morbo комментирует...

>В отличие от вездесущего Linux-демона HAL, работающего в связке с PolicyKit и демоном информационной шины D-Bus, встроенные системные средства FreeBSD позволяют обойтись без нагромождений стороннего софта.

Вообще-то в Linux можно сделать абсолютно всё то же самое, средствами udev. Есть даже пакет usbmount, который устанавливает в каталоги udev необходимые скрипты.

Так что в Linux всю эту статью можно ужать до одной фразы:

Установите пакет usbmount.

Александр Чуранов комментирует...

Вместо username можно использовать who | awk '{print $1;}' | head -n1 , предполагая, что на десктопе работает только один пользователь.

morbo комментирует...

Александр Чуранов, теперь я знаю почему банкоматы иногда показывают синий экран смерти. Это просто какой-то быдлокодер решил выпендриться и заменить простой и всегда работающий быстрый код на сложный, медленный и работающий не гарантировано.