Содержание

Skip to end of metadata
Go to start of metadata

You are viewing an old version of this page. View the current version.

Compare with Current View Page History

Version 1 Next »

 В современных версиях Astra Linux для управления подключаемыми устройствами используется механизм udev




Данная статья применима к:

  • ОС ОН Орёл 2.12;
  • ОС СН Смоленск 1.6;
  • ОС СН Ленинград 8.1.

Перехват события udev

События udev возникают при изменении статуса подключенных устройств. Наиболее употребительные - подключение устройства (событие "add") и отключение устройства (событие "remove").

Файлы-обработчики событий udev располагаются в каталогах /etc/udev/rules.d/ и /lib/udev/rules.d/.

Стандартно имя каждого файла - сценария начинается с двух цифр, и имеет расширение .rules.

При обработке события файлы выполняются в порядке алфавитной сортировки независимо от каталога, к котором они размещены.

Пример файла перехвата события /etc/udev/rules.d/99-local.rules:

/etc/udev/rules.d/99-local.rules

KERNEL=="sd[a-z][0-9]", SUBSYSTEMS=="usb", ACTION=="add", RUN+="/bin/systemctl start usb-mount@%k.service"
KERNEL=="sd[a-z][0-9]", SUBSYSTEMS=="usb", ACTION=="remove", RUN+="/bin/systemctl stop usb-mount@%k.servic"

Этот перехватчик обрабатывает события подключения/отключения дисковых устройств, однако не выполняет при этом прямых действий, а вызывает для выполнения этих действия системную службу usb-mount@%k.service, то есть вызывает сценарий обработки события как системную службу.
Как организовать такую службу описано ниже.

Для того, чтобы новый файл начал работать, необходимо перезагрузить правила udev командой


udevadm control --reload-rules

Вызов сценария обработки события как системного сервиса

Для вызова сервисов используются так называемы "юниты", специальные сценарии запуска, расположенные в каталоге /etc/systemd/system/.

Пример сценария для вышеуказанного /etc/systemd/system/usb-mount@.service обработчика события:


/etc/systemd/system/usb-mount@.service

[Unit]
Description=Mount USB Drive on %i

[Service]

Type=oneshot

RemainAfterExit=true

ExecStart=/usr/local/bin/usb-mount.sh add %i

ExecStop=/usr/local/bin/usb-mount.sh remove %i

Этот сценарий умеет обрабатывать две команды - старт и стоп, но сам опять ничего не делает, а вызывает исполнимый файл сценария обработки события /usr/local/bin/usb-mount.sh.

Сценарий обработки события

Сценарий обработки события в принципе может размещаться где угодно, для примера используем файл /usr/local/bin/usb-mount.sh


/usr/local/bin/usb-mount.sh

#!/bin/bash
# Этот сценарий вызывается из системного юнита как сценарий обработки подключения/отключения накопителей.
usage() {
    echo "Использование: $0 {add|remove} device_name (e.g. sdb1)"
    exit 1
}

if [[ $# -ne 2 ]]; then
    usage
fi

ACTION=$1
DEVBASE=$2
DEVICE="/dev/${DEVBASE}"

# Проверяем, не примонтировано ли уже устройство
MOUNT_POINT=$(/bin/mount | /bin/grep ${DEVICE} | /usr/bin/awk '{ print $3 }')

do_mount() {
    if [[ -n ${MOUNT_POINT} ]]; then
        echo "Предупреждение: ${DEVICE} уже смонтировано в ${MOUNT_POINT}"
        exit 1
    fi

# Получаем информацию об устройстве : метка $ID_FS_LABEL, идентификатоп $ID_FS_UUID, и тип файловой системы $ID_FS_TYPE
    eval $(/sbin/blkid -o udev ${DEVICE})

# Создаём точку монтирования:
    LABEL=${ID_FS_LABEL}
    if [[ -z "${LABEL}" ]]; then
        LABEL=${DEVBASE}
    elif /bin/grep -q " /media/${LABEL} " /etc/mtab; then
# Если точка монтирования уже существует изменяем имя:
        LABEL+="-${DEVBASE}"
    fi
MOUNT_POINT="/media/${LABEL}"
     echo "Точка монтирования: ${MOUNT_POINT}"
    /bin/mkdir -p ${MOUNT_POINT}

# Глобальные опции монтирования
    OPTS="rw,relatime"

# Специфические опции монтирования:
    if [[ ${ID_FS_TYPE} == "vfat" ]]; then
        OPTS+=",users,gid=100,umask=000,shortname=mixed,utf8=1,flush"
    fi

    if ! /bin/mount -o ${OPTS} ${DEVICE} ${MOUNT_POINT}; then
        echo "Ошибка монтирования ${DEVICE} (статус = $?)"
        /bin/rmdir ${MOUNT_POINT}
        exit 1
    fi

    echo "**** Устроййство ${DEVICE} смонтировано в ${MOUNT_POINT} ****"
}

do_unmount() {
    if [[ -z ${MOUNT_POINT} ]]; then
        echo "Предупреждение: ${DEVICE} не смонтировано"
    else
        /bin/umount -l ${DEVICE}
        echo "**** Отмонтировано ${DEVICE}"
    fi

# Удаление пустых каталогов
    for f in /media/* ; do
        if [[ -n $(/usr/bin/find "$f" -maxdepth 0 -type d -empty) ]]; then
            if ! /bin/grep -q " $f " /etc/mtab; then
                echo "**** Удаление точки монтирования $f"
                /bin/rmdir "$f"
            fi
        fi
    done
}

case "${ACTION}" in
    add) do_mount ;;
    remove) do_unmount ;;
    *) usage ;;
esac

После создания файла сценария не забыть сделать его исполнимым:

chmod +x /usr/local/bin/usb-mount.sh

Приёмы отладки

Включение вывода отладочных сообщений в файл /var/log/syslog

udevadm control -l debug

Тестовая отработка правил udev без их загрузки:

udevadm test /dev/sdb1
Мониторинг событий udev:
udevadm monitor -k -u -p
Путь к устройству:
udevadm info -q path -n /dev/sdd1
Полная информация об устройстве:
udevadm info -a -p $(udevadm info -q path -n /dev/sdd1)


  • No labels