Дерево страниц

Сравнение версий

Ключ

  • Эта строка добавлена.
  • Эта строка удалена.
  • Изменено форматирование.

Оглавление

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

Источник: https://serverfault.com/questions/766506/automount-usb-drives-with-systemd





Информация

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

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


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

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

  • подключение устройства (событие "add");
  • отключение устройства (событие "remove").

Перехват событий осуществлятся с помощью сценариев обработки. Файлы со сценариями - обработчиками событий udev располагаются в каталогах:

  • /lib/udev/rules.d/
  • /run/udev/rules.d/
  • /etc/udev/rules.d/

Каталоги обрабатываются в том порядке, в котором они перечислены. Перед выполнением файлы упорядочиваются по алфавиту. Файлы с одинаковыми именами - переписываются последним найденным файлом, т.е. файл, найденный в последнем каталоге (/etc и /lib/udev/rules.d/) заменит собой ранее найденный файл.

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

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

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

Информация
title/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.servicservice"

Этот перехватчик обрабатывает события подключения/отключения дисковых устройств , однако с именами начинающимися с букв "sd", после которых следует одна любая строчная буква ([a-z]), после которой следует одна цифра ([0-9]).
Однако сам перехватчик не выполняет при этом прямых действий, а вызывает для выполнения этих действия системную службу usb-mount@%k.service, то есть вызывает сценарий обработки события как системную службу.

Обратите внимание, на имя службы usb-mount@%k , которое имеет особый смысл:

  • при выполнении правила обработки события служба udev вместо переменной %k автоматически подставит имя устройства (полный список переменных имеется в документации).
    Т.е. при подключении устройства, например, /dev/sdb1  будет выполняться команда  /bin/systemctl start usb-mount@sdb1.service;

  • при вызове службы, в имени которой содержится  симовол "@" системная служба вызова служб разберёт это имя на части, и передаст часть, находящуюся после символ а"@" как параметр вызываемой службе.
    Т.е. вызов systemctl start usb-mount@sdb1.service превратится в вызов службы usb-mount с параметрами start и sdb1.

Как организовать обработку этого вызова и саму Как организовать такую службу описано ниже.

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

Command

udevadm control --reload-rules

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

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

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

Информация
title/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

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

Обратите внимание на параметр %i - вместо него будет автоматически подставлена часть имени вызова службы, находящаяся после символа "@".

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

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

Информация
title/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

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

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

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

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

Информация
udevadm control -l debug

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

Command
udevadm test /dev/sdb1

Мониторинг событий udev:

Command
udevadm monitor -k -u -p

Путь к устройству:

Command
udevadm info -q path -n /dev/sdd1

Полная информация об устройстве:

Command
udevadm info -a -p $(udevadm info -q path -n /dev/sdd1)