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

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

Ключ

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

Оглавление

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

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





Информация

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

  • ОС ОН Орёл 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:

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

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

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


Command

udevadm control --reload-rules

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

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

Пример сценария для вышеуказанного /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

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

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

Сценарий обработки события в принципе может размещаться где угодно, для примера используем файл /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)