udev, автомонтирование средствами hal

Это как-бы в догонку к теме блога http://archlinux.org.ru/node/150.
Вобщем понадобилось (попросили) сделать автомонтирование. Сделал тогда товарищу по принципу как в вышеупомянутой статье. Но. Через некоторое время он поинтересовался, почему допустим файловый менеджер или программа не может отмонтировать его съемный диск. Мелочь, жить не мешающая но всё-же…
Решил я сделать это методами hal. И наступил на граблю. Несколько часов переписывал скрипт то с прямыми вызовами свойств через dbus-send, то с обёртками типа hal-get-property… От пользователя пожалуйста - монтирует-размонтирует, монтирует и дает размонтировать другим программам, но при вызове из dbus конфигов напрочь отказывается это делать.
Вобшем наконец (после вдумчивого чтения) нашел строчку, в которой было написано, что при обработке правила, (допустим при вставке флешки) , RUN+=“program” udev ждёт от “program” кода завершения. А в это время блокирует любые попытки достучаться до устройства через шину. А хал в это время не может получить свойств устройства, а я не могу их обработать, а udev ждёт. И сделать RUN+=“program %k &” не прокатило.
Короче в лучших традициях сделал подпорку. program теперь просто отдельный скрипт в три строки, вызывает сам монтировщик в бэкграунде и передает ему аргументы от удава. Удев спокойно завершает свои дела, освобождая доступ к устройству. А сам скрипт в фоне делает своё дело.
Вот интересно, что-б не плодить сущностей может скрипт просто форкнуть себя. Но что-то быстрый поиск bash fork не впечатлил. На питоне реализовать подобное интересней и удобней, но задача была bash+hal+udev. Да и на питоне полно реализаций автомаунта как демона, а на “просто скриптик” “многа букаф”… Вобщем пусть подпорка пока у сарая постоит. Решил её покрасить - у человека фотик, плеер… Потом всё ему через подпорку (жопу?) на свои скрипты заведём ;D
Да, чуть не забыл. Может кому пригодится. Сам скриптик монтирования.
#!/bin/sh
PATH=/bin:/sbin:/usr/bin:usr/sbin:$PATH
OPT_NTFS='locale=ru_RU.utf8,dmask=000,fmask=111,exec'
OPT_VFAT='uid=%s,iocharset=utf8,codepage=1251,showexec,umask=0,flush'
OPT_EXT='noatime,nodiratime,sync,dirsync,defaults'
#########################
USERID=`id -u`
ACTION=$1
DEVICE=$2
if [ -z "$DEVICE" ] || [ -z "$ACTION" ] ; then
    logger "$0: Wrong option!"
    exit 2
fi
DEVICE='/dev/'$(echo $1 | sed -n '/^sd[a-z][1-9]\?/p')
sleep 4
function find_by_property {
    UDI=$(hal-find-by-property --key block.device --string $DEVICE)
    if [ -z $UDI ]; then
        logger "$0: Wrong storage udi, device=${DEVICE}"
        exit 2
    fi
}
function get_hal_label {
    LO_UDI=$1
    COUNTER=0;
    LABEL=$(hal-get-property --key volume.label --udi $LO_UDI 2>/dev/null)
    while [ -z "$LABEL" -a $COUNTER -lt 4 ]; do
        LO_UDI=$(hal-get-property --key info.parent --udi $LO_UDI 2>/dev/null)
        LABEL=$(hal-get-property --key storage.model --udi $LO_UDI 2>/dev/null)
        COUNTER=$(expr $COUNTER + 1)
    done
    LABEL=$(echo $LABEL | sed 's/[ ]/_/g'| sed 's/[^_a-zA-Z0-9\.]//g' \
    | sed 's/[^a-zA-Z0-9]$//g')
    if [ -z $LABEL ]; then
        LABEL=${DEVICE##/dev/}
    fi
}
function get_hal_fsoption {
    LO_UDI=$1
    FSTYPE=$(hal-get-property --key volume.policy.mount_filesystem --udi $LO_UDI 2>/dev/null)
    if [ -z $FSTYPE ]; then
        FSTYPE=$(hal-get-property --key volume.fstype --udi $LO_UDI 2>/dev/null)
    fi
    case $FSTYPE in
     'ntfs'|'ntfs-3g') OPTIONS=$OPT_NTFS;;
     'vfat'|'fat'|'mvfat') OPTIONS=$(printf $OPT_VFAT $USERID);;
     'ext2'|'ext3') OPTIONS=$OPT_EXT;;
          *) OPTIONS='';;
    esac
}
case $ACTION in
 'a'|'add')
    find_by_property "$DEVICE"
    get_hal_label $UDI
    get_hal_fsoption $UDI
    dbus-send --system --print-reply --dest=org.freedesktop.Hal $UDI \
    org.freedesktop.Hal.Device.Volume.Mount string:$LABEL \
    string: array:string:"$OPTIONS" 2>/dev/null
    logger "$0: device=${DEVICE} , mount point=${LABEL}"
    logger "$0: fs=${FSTYPE} , mount option=${OPTIONS}"
    ;;
 'r'|'remove')
    find_by_property "$DEVICE"
    /usr/bin/dbus-send --system --print-reply --dest=org.freedesktop.Hal $UDI \
    org.freedesktop.Hal.Device.Volume.Unmount array:string:'' 2>/dev/null
    logger "$0: ${DEVICE} remove."
    ;;
    *)  logger "$0: Wrong action ${ACTION}"
        exit 2
        ;;
esac
exit 0
Решал точно такую же проблему (через udev также не работало отмонтирование), но без всяких скриптов.
Для Gnome достаточно запущенного HAL и gnome-volume-manager, который прописан в Сессиях и стартует при запуске Gnome.
Затем поправим опции монтирования (чтобы не было проблем с файлами названными по-русски):

/system/storage/default_options/vfat/mount_options =

Вуаля! Все работает, как нужно.
Gnom не нужен ;D
Шутка. Ни гнома, ни gnome-volume-manager, ни gconf. Работать должно что в init3, голой консоли, что в иксах *box.
Не нужно пользователям DE. Не нужно пользователям *box сверху гнома-кед.
 
Зарегистрироваться или войдите чтобы оставить сообщение.