IvmanAutomount

Материал из ALT Linux Wiki
Freesource-logo.png Blue Glass Arrow.svg MediaWiki logo.png
Эта страница была перемещена с freesource.info.
Эта страница наверняка требует чистки и улучшения — смело правьте разметку и ссылки.
Просьба по окончанию убрать этот шаблон со страницы.


Новые веяния в области автомонтирования

NB: по состоянию на конец 2010 года hal признан устаревшим и вкладывать силы в его применение малоосмысленно. --mike 21:26, 21 декабря 2010 (UTC)

Hal+ivman+pmount

Проблема со сменными носителями существовала с момента появления первого носителя и разные операционные системы абсолютно по разному подходили к решению этого вопроса. На моей памяти в линуксе я использовал supermount/autofs/subfs и у каждого из этих вариантов было множество недостатков. Попробую их перечислить:

  1. Необходимость выяснить текущее имя устройства
  2. Наличие прав на запись в системные конфигурационные файлы
  3. Всевозможные проблемы с "залипанием" сменного устройства с последующей перезагрузкой для его извлечения

Решение первого пункта было возложено на сервис hotplug и многие ощутили на себе последствия этого шага, как-то затирания /etc/fstab. Сейчас ситуация стабилизировалась, но у многих мысль о допускании кого-то на автоматическую запись в /etc/fstab вызывает дрожь. Многие, в том числе и я, для спокойного сна воспользовались командой chattr +i /etc/fstab. Информацию же о имени устройства можно получить через сервис Hal.

Но это сделало еще более острым второй вопрос - если никто из сервисов, работающих под правами рута не вносит запись, то это вынужден делать пользователь. Самому себе можно дать права на редактирование чего угодно, но это не подходит для ситуации с несколькими пользователями или для корпоративной среды. rider@ по старой традиции возложил монтирование сменных устройств на информационную подсистему hal, и теперь уже к нему появляются претензии по поводу бредовых записей в /etc/fstab... Есть начинание по запрету записи в /etc/fstab и перенесение его изменяемой части в /etc/fstab.d

Что предлагает Ivman?

Отсутствие необходимости писать в /etc/fstab или куда-либо еще для автоматического монтирования. Теперь все сервисы у нас занимаются только своим делом:

  • hotplug - подгружает драйвера устройств
  • hal - формирует описание устройства
  • dbus - рассылает уведомления о появлении/исчезновении устройств всем заинтересованным
  • ivman - принимает решение о действиях, которые необходимо выполнить
  • pmount - монтирует сменное устройство, основываясь на его описании в hal

Как это все работает

  • Для начала необходимо установить ivman - apt-get install ivman pmount (Указывать принудительно pmount нужно только до версии alt4 - позже я исправил багу)
  • Затем выставить права на утилиту pmount - control pmount wheelonly, control pmount restricted или control pmount public. Предваряя желающих повесить багу на пакет pmount - пока группа xgrp не поставляется в систему пакетом setup это невозможно. (см. также altbug:7482

)

  • Осталось только запустить service ivman start и, если понравится, прописать автозапуск - chkconfig ivman on
  • Теперь все устройства, которые по базе hal являются монтируемыми будут автоматически монтироваться при подключении и отмонтироваться при извлечении

И это все?

Нет, это очень маленькая часть возможностей ivman! ivman стандартно работает в двух экземплярах:

  • Общесистемный демон, на который обычно возлагается только монтирование сменных носителей
  • Пользовательский демон, на который возлагаются все действия, которые только могут прийти в голову пользователю для работы с hotplug устройствами и сменными носителями.

Маленький пример:

  • для аудиодисков у меня автоматически запускается cdplay
  • для DVD-Video - mplayer
  • для цифрового фотоаппарата - digikam
  • для моего мобильного телефона - moto4lin
  • DVD диск Мастер 2.4 монтируется не в /media/cdrom, а в /var/ftp/pub/Master/2.4

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

Совместимость с другими системами автомонтирования

ivman запущенный под системным аккаунтом не мешает никому из них... Но и не работает сам - это связано в первую очередь с паузой которую он делает для отработки пользовательских правил. За это время hotplug(а в последних версия hal) успевает произвести запись в fstab и вызвать монтирование устройства. У копии запущенной от простого пользователя возникает состояние гонки и результат абсолютно непредсказуем. Поэтому рекомендуется избегать пересечения по устройствам у различных систем автомонтирования. UPDATE: последние версии hal ничем таким не занимаются Продолжение следует...


Добрые советы

Большой проблемой на данный момент является совместимость этой схемы с утилитами записи CD и DVD дисков. Для growisofs я рекомендую использовать такой workarround: Создать в каталоге ~/bin файл с именем growisofs и следующим содержанием:

#!/bin/sh
if [ `mount | grep /dev/hdd | wc -l ` -gt 0 ] ; then
pumount /dev/hdd
fi
/usr/bin/growisofs "$@"

by Nick S. Grechukh:

Поддержка iocharset в ivman

ivman версии 0.6.4 местами обрабатывал policy.mount_option (исключая iocharset). я изготовил патч на эту тему и отправил его в дедал: патченый ivman передает pmount -c $hal.volume.policy.mount_option.iocharset$, если он задан в hal policy.

в версии 0.6.6 все поменяли, теперь mount_command выбирается из mount/pmount/pmount-hal при инициализации, и в дальнейшем не меняется. Причем, общесистемный экземпляр всегда использует pmount, а пользовательский - pmount-hal. Соответственно, передать что-либо udi-зависимое невозможно :(

Единственным выходом остается определять кодировку в самом pmount, см. ниже. Для пользовательского ivman - таки можно ориентироваться на hal, для этого надо поправить pmount-hal.

Поддержка iocharset в pmount

pmount поддерживает явное задание кодировки iocharset - ключ -c. Если кодировка не задана, то поведение pmount мне представляется странным: он берет текущую локаль (пользователя, под которым запущен) и если она utf8 - выставляет iocharset=utf8, но игнорирует любую другую.

Можно было бы исправить pmount, чтобы он всегда монтировал с текущей локалью в iocharset, однако это не поможет при запуске из системного ivman (или просто от рута). Я предпочел заменить запрос локали вызовом libnatspec. Пакет можно взять тут: ftp://ftp.altlinux.ru/pub/distributions/ALTLinux/Daedalus/i586/RPMS.daedalus/pmount-0.9.3-alt1.gns1.i586.rpm или собрать: ftp://ftp.altlinux.ru/pub/distributions/ALTLinux/Daedalus/SRPMS.daedalus/pmount-0.9.3-alt1.gns1.src.rpm

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

Конфигурирование ivman

Запускать ivman можно с помощью chkconfig - для системного демона или любого файла автозапуска пользователя, вроде .xsession.d, .bash_profile или .profile. Пользователю не стоит опасаться, что при повторном в ходе в систему с другой консоли запустится новый экземпляр ivman, в последний встроена проверка на этот счет. Также, системный и пользовательский процессы могут нормально работать вместе, если у них не пересекаются "сферы влияния", например монтированием сменных дисков занимается системный демон, а монтированием цифрового фотоаппарата - пользовательский. Для этого достаточно разнести необходимые действия по разным конфигам. Основным используемым файлом конфигурации ivman является файл IvmConfigActions.xml, находящийся в /etc/ivman для системного демона и в /.ivman - для пользовательского приложения. Синтаксис его выглядит следующим образом:

<ivm:Match name="hal.device.name" value="device_properties">
	<ivm:Option name="exec" value="program_name" />
</ivm:Match>

где name является названием свойства устройства, а value - значением этого свойства, при совпадении которых выполняется необходимое действие.

Самым простым способом подобрать нужные значения будет использование программы hal-device, с помощью которых можно посмотреть свойства всех устройств, присутствующих в системе и подобрать нужную комбинацию свойств/значений.

Также, при запуске события на появление устройства можно использовать имена свойств hal как переменные, окружив их знаками "$" например:

<ivm:Option name="exec" value="pmount $hal.block.device$" />

Эта команда выполнит строку вида pmount /dev/hda1 при монтировании жесткого диска.

Условия можно вкладывать друг в друга:

<ivm:Match name="hal.device.name1" value="device_properties1">
    <ivm:Match name="hal.device.name2" value="device_properties2">
	<ivm:Option name="exec" value="program_name" />
    </ivm:Match>
</ivm:Match>

при этом сначала выполняется проверка внешних параметров, а затем внутренних.

Примеры конфигурации

В начале файла IvmConfigActions.xml находится глобальная команда команда включения/выключения монтирования сменных носителей:

<ivm:Match name="ivm.mountable" value="true">
        <ivm:Option name="mount" value="true" />
</ivm:Match>

По умолчанию устройства монтируются в каталог /media в подпапки, равные имени block device (для флэшек - в папку usbdisk). Если мы хотим монтировать определенные устройства в определенные папки, то можем поступить таким образом:

<ivm:Match name="hal.block.device" value="/dev/hdc">
	<ivm:Option name="mount" value="false" /> // Отключаем глобальное монтирование для этого устройства
	<ivm:Option name="exec" value="pmount $hal.block.device$ dvd" /> // монтируем DVD привод в папку dvd, используя pmount.
</ivm:Match>

Пример для автозапуска DVD-Video дисков:

<ivm:Match name="hal.volume.disc.is_videodvd" value="true">
	<ivm:Option name="execdvd" value="xine -p dvd:/$hal.volume.mount_point$" />
</ivm:Match>

Пример для монтирования любой цифровой фотокамеры, работающей по протоколу PTP:

<ivm:Match name="hal.info.bus" value="usb">
	<ivm:Match name="hal.info.category" value="camera">
		<ivm:Match name="hal.camera.access_method" value="ptp">
			<ivm:Option name="exec" value="digikam --detect-camera" />
		</ivm:Match>
	</ivm:Match>
</ivm:Match>

Таким образом, используя hal можно легко назначать практически любые действия событиям hal, от монтирования CD дисков с определенной меткой в определенную папку, до автоматического определения сканера или принтера. Помочь в этом разобраться должен следующие мануалы: ivman(8), IvmConfigActions.xml(5), pmount(1), а также коментарии в файлах конфигурации ivman.

Особенности использования pmount

По умолчанию pmount не считает сменными носителями жесткие диски, которые мы часто подключаем к компьютеру и не монтирует их. Для того, чтобы легко монтировать сменные диски из под пользователя, достаточно занести блочное устройство в белый список pmount, находящийся в /etc/pmount.allow

Также не стоит забывать, что hal/ivman образатывают события о появлении и исчезновении устройств, а не об их наличии. Таким образом я пока не вижу способа сделать конфиг для ivman, который монтировал бы жесткий диск, подключенный к выключенному компьютеру, поскольку устройство уже существует в момент запуска ivman. Флэшка, которая уже была воткнута в момент включения, тоже не смонтируется - здесь вам не Microsoft (r) Windows (tm).

UPDATE из changelog: 18 April 2006: Ivman 0.6.11 released. Changes since last ivman:

    • Fixed automounting for HAL 0.5.7 or greater.
    • Added option to process all rules in IvmConfigActions.xml when Ivman starts. This allows automounting to take place of devices already attached to the system when Ivman is started.

Пример конфигурации точек монтирования через FDI

/etc/hal/fdi/policy/00-gns-flash.fdi

<?xml version="1.0" encoding="UTF-8"?> <!-- -*- SGML -*- -->
<deviceinfo version="0.2">
        <device>
                <match key="volume.uuid" string="324F-24F4">
                        <merge key="volume.policy.desired_mount_point" type="string">jetflash</merge>
                </match>
        </device>
        <device>
                        <match key="@info.parent:storage.model" string="CN-USB20EFD0256A">
                                        <merge key="volume.policy.desired_mount_point" type="string">canyon</merge>
                        </match>
        </device>
        <device>
                <match key="@info.parent:info.product" string="Sansa e130">
                        <merge key="volume.policy.desired_mount_point" type="string">sansa_</merge>
                        <append key="volume.policy.desired_mount_point" type="string">sd</append>
                        <match key="volume.label" string="SANSA E1XX">
                                <merge key="volume.policy.desired_mount_point" type="string">sansa_</merge>
                                <append key="volume.policy.desired_mount_point" type="string">e130</append>
                        </match>
                </match>
        </device>
</deviceinfo>

фрагмент /etc/ivman/IvmConfigActions.xml

<ivm:Match name="ivm.mountable" value="true">
        <ivm:Option name="mount" value="false" />
        <ivm:Match name="hal.info.category" value="volume">
            <ivm:Option name="mount" value="true" />
        </ivm:Match>
    </ivm:Match>

фрагмент /etc/ivman/IvmConfigBase.xml

<ivm:Option name="mountcommand" value="pmount -c cp1251 -u 007 $hal.block.device$ $hal.volume.policy.desired_mount_point$" />
    <ivm:Option name="umountcommand" value="pumount $hal.block.device$" />

Как все это работает

При подгрузке (обнаружении) нового устройства в ядре возникает так называемое uevent (userspace event).

У этого события есть три типа обработки:

  1. Вызвать внешнюю программу (если есть). Путь задается в /proc/sys/kernel/hotplug
  2. Передать сообщение на unixdomain socket (не знаю где задается путь к сокету)
  3. Передать специальное сообщение socket NETLINK с типом NETLINK_KOBJECT_UEVENT

Первый способ остался для обратной совместимости со старой системой. В более новых дистрибутивах вместо hotplug'а запускается процесс udevd, который слушает socket NETLINK для получения информации о новых устройствах. В правилах (rules) udevd помимо создания устройства есть 1. вызов hotplug'а и 2. передача сообщения hald.