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

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

Ключ

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

Оглавление

Введение

 В

современных версиях

обновлениях Astra Linux до обновления x.7.2 для управления подключаемыми устройствами

используется механизм udevИсточник: https://serverfault.com/questions/766506/automount-usb-drives-with-systemd

совместно используются механизмы udev и mount. См. Съемные носители в Astra Linux. В данной статье рассматривается пример сценария, использующего механизм udev для автоматического монтирования съемных носителей. Сценарий имеет следующие особенности:

  • монтирование выполняется в предопределенную точку монтирования (/media/<имя_устройства>);
  • монтирование выполняется для всех пользователей (примонтированное устройство доступно для чтения и записи всем пользователям;
  • размонтирование устройства доступно всем пользователям.


Информация

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

  • ОС ОН Орёл 2.12;
  • ОС СН Смоленск 1.6;
    • Astra Linux Special Edition РУСБ.10015-01 и РУСБ.10015-10 (очередное обновление 1.7)
    • Astra Linux Special Edition РУСБ.10052-02 (очередное обновление 4.7)
    • Astra Linux Special Edition РУСБ.10015-01 (очередное обновление 1.6)

    • Astra Linux Special Edition РУСБ.10015-16 исп. 1 и исп. 2

    • Astra Linux Special Edition РУСБ.10265-01 (очередное обновление 8.1)

    • Astra Linux Common Edition 2.12



    Предупреждение

    Предлагаемый в настоящей статье сценарий монтирования предназначен исключительно для демонстрации приемов работы. Для практического применения предлагаемый сценарий должен быть доработан в соответствии с поставленными задачами. В частности, автоматически примонтированные сценарием носители с файловой системой NTFS не могут быть размонтированы через службу fly-reflex (графическое приложение). Однако при этом пользователи могут использовать для размонтирования команду umount из командной строки.

    Применение собственных сценариев обработки событий udev одновременно с использованием учтенных носителей (см. Съемные носители в Astra Linux) допустимо только в рамках действующих правил безопасности..

    ОС СН Ленинград 8.1.


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

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

    • физическое подключение устройства (событие "add");
    • физическое отключение (извлечение) устройства (событие "remove");
    • смена носителя в устройстве (событие "change"). Используется для устройств типа компакт-диск (CD- и DVD-приводы).

    Перехват событий осуществлятся осуществляется с помощью сценариев обработки. Файлы со сценариями - обработчиками событий 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:

    Информацияcode
    title/etc/udev/rules.d/99-local.rules
    KERNEL=="sd[a-z]|sd[a-z][
    0
    1-9]", SUBSYSTEMS=="usb", ACTION=="add", RUN+="/bin/systemctl start usb-mount@%k.service
    "
    ", RUN+="/usr/bin/logger -s -t Astra StepAdd"
    KERNEL=="sd[a-z]
    [0
    |sd[a-z][1-9]", SUBSYSTEMS=="usb", ACTION=="remove", RUN+="/bin/systemctl stop usb-mount@%k.
    servic
    service", RUN+="/usr/bin/logger -s -t Astra StepRemove"
    KERNEL=="sd[a-z]|sd[a-z][1-9]", SUBSYSTEMS=="usb", ACTION=="change", RUN+="/bin/systemctl reload usb-mount@%k.service", RUN+="/usr/bin/logger -s -t Astra StepReload"

    Этот перехватчик обрабатывает события подключения/отключения дисковых разделов с именами:

    • начинающимися с букв "sd", после которых следует одна любая строчная буква ([a-z]) — такие имена используются для дисковых разделов с файловой системой vfat и, иногда, NTFS;
    • начинающимися с букв "sd", , после которых следует одна любая строчная буква ([a-z]), после которой следует одна цифра ([0-9]) — такие имена используются для дисковых разделов ext2/ext3/ext4 и NTFS.

    Для отладки в сценарий вставлены команды трассировки выполняемых вызовов:

    Блок кода
    RUN+="/usr/bin/logger -s -t Astra_USB ...

    Отладочные сообщения отмеченные тегом Astra_USB записываются в системный журнал /var/log/syslog.

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

    При выполнении правила обработки события служба udev вместо специальной переменной %k автоматически подставит имя подключаемого объекта (полный список специальных переменных имеется в документации). Т.е. при подключении дискового раздела, например, /dev/sdb1, будет выполняться команда:

    Command
     /bin/systemctl start usb-mount@sdb1.service

    Имя вызываемой службы usb-mount@%k помимо переменной %k содержит символ "коммерческое at" ("собака", "@"), имеющий специальный смысл: при вызове службы в имени которой содержится  символ "@" системная служба вызова служб разберет это имя на части, и передаст часть, находящуюся после символа "@" вызываемой службе как параметр. Т.е. вызов:

    Блок кода
    systemctl start usb-mount@sdb1.service

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

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

    Command

    udevadm control --reload-rules

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

    Итак, сценарий обработки вызывается как системный сервиссистемная служба. Для вызова сервисов системных служб используются так называемы называемые "юниты" (units), специальные сценарии запуска сервисовслужб, расположенные в каталоге каталогах /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
    ExecReload=/usr/local/bin/usb-mount.sh reload %i
    ExecStop=/usr/local/bin/usb-mount.sh remove %i

    Этот сценарий умеет обрабатывать две команды - старт и стопstart (параметр ExecStart) и stop (параметр ExecStop), но сам опять ничего не делает, а вызывает исполнимый файл сценария обработки события (для примера - файл /usr/local/bin/usb-mount.sh). При вызове файлу передается параметр, определяющий действие (в примере выше - add или remove) и  специальный параметр %i, вместо которого автоматически подставляется часть имени вызова службы, находящаяся после символа "@", т.е. в используемом примере - sdb1.

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

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

    • монтирование устройств vfat:
      • выполняется от имени пользователя nobody ("никто") и группы nogroup ("никакая группа");
      • на устройство устанавливается маска доступа (umask) 000, разрешающая доступ на чтение и запись к файловым объектам на устройстве всем пользователям;
    • при монтировании для повышения безопасности используется опция users, которая при выполнении монтировании интерпретируется как опции "noexecnosuid, nodev":
      • noexec — запрет исполнения двоичных файлов, расположенных на носителе;
      • nosuid — запрет применения битов установки идентификатора пользователя и идентификатора группы, используемых для изменения (повышения) привилегий;
      • nodev — запрет применения файлов, расположенных на устройстве, как файлов символьных или блочных устройств;
    • в файл /etc/fstab добавляется строка вида:

      Блок кода
      <имя_устройства> <точка_монтирования> auto <опции_монтирования>

      Наличие такой строки позволяет выполнять операцию монтирования с помощью команды mount указанного устройства в указанную точку любому пользователю. Дополнительно сценарий в опциях монтирования указывает:

      • Опция монтирования users. Наличие этой опции, когда она указана в файле /etc/fstab, помимо задания опций "noexecnosuid, nodev" при монтировании, имеет дополнительную функцию: наличие этой опции разрешает размонтировать устройство любому пользователю;

      • Опция монтирования noauto. Наличие этой опции исключает автоматическое монтирование носителя при загрузке ОС (или при выполнении команды mount -a). 

    Текст сценария:

    Информация
    title/usr/local/bin/usb-mount.sh

    #!/bin/bash
    set -xue
    # Определяется команда для трассировки (отладки) выполнения сценария. Отладочные записи записываются в системный журнал /var/log/syslog и помечается тегом "Astra_USB"
    log='/usr/bin/logger -s -t "Astra_USB"'

    # Этот сценарий вызывается из системного юнита как сценарий обработки подключения/отключения накопителей .и должен получать два параметра
    usage() {
        echo "Использование    $log "Применение: $0 {add|remove|reload} device_name (e.g. например, sdb1)."
            exit 1
    }if [[ $# -ne 2 ]]; then
        usage
    fi

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

    # Проверяем, не примонтировано ли уже устройство
    do_mount() {
        MOUNT_POINT=$(/bin/mount | /bin/grep ${DEVICE} | /usr/bin/awk '{ print $3 }')
    do_mount() {
            if [[ -n ${MOUNT_POINT} ]]; then
            echo         $log "Предупреждение: ${DEVICE} уже смонтировано в ${MOUNT_POINT}"
                    exit 1
            fi

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

        # Глобальные опции монтирования
        OPTS="rw,relatime,users" # Создаём точку монтирования:
        LABEL=

        # Специфические для файловых систем опции монтирования:
        case ${ID_FS_TYPE:-} in
            vfat)       $log "Файловая система ${ID_FS_TYPE} на устройстве ${DEVICE}"
                        OPTS+=",uid=nobody,gid=nogroup,umask=000,shortname=mixed,utf8=1,flush"
                        ;;
             ext4|ext3|xfs|btrfs)
                        $log "Файловая система ${ID_FS_TYPE} на устройстве ${DEVICE}"
                        ;;
             ntfs)
                        OPTS+=",group,uid=nobody,gid=nogroup"
                        $log "Файловая система ${ID_FS_TYPE} на устройстве ${DEVICE}"
                        ;;
            "")         $log "На устройстве ${DEVICE} отсутствует файловая система"
                        exit 0
                        ;;
            *)  $log "Неподдерживаемая файловая система ${ID_FS_TYPE:-} на устройстве ${DEVICE}"
                exit 1
        esac

        UUID=`lsblk $DEVICE -no UUID`
    #    MOUNT_POINT="/run/user/0/media/by-uuid-${UUID}"
        LABEL}
        if [[ -z "${LABEL}" ]]; then
            LABEL=${DEVBASE}
        elif /bin/grep -q " /media/${LABEL} " /etc/mtab; then
    # Если точка монтирования уже существует изменяем имя:
            LABEL+="-${DEVBASE}"
        fi
    MOUNT_POINT="/media/by-uuid-${LABELUUID}"
         echo     $log "Точка монтирования: ${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

        chmod 777 ${MOUNT_POINT}

            if ! /bin/mount -o ${OPTS} ${DEVICE} ${MOUNT_POINT}; then
            echo         $log "Ошибка монтирования ${DEVICE} (статус = $?)"
                    /bin/rmdir ${MOUNT_POINT}
                exit 1
        fi  exit 1
        else
            sed -i "/^${DEVICE//\//\\/}\s\+/d" /etc/fstab
            echo "${DEVICE} ${MOUNT_POINT} auto ${OPTS} 0 0" | tee -a /etc/fstab > /dev/null
        fi

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

    do_unmount() {
        $log "Removing: ${DEVICE}-${ID_FS_LABEL:-}-${DEVBASE}"
        MOUNT_POINT=$(/bin/mount | /bin/egrep "^${DEVICE}" | /usr/bin/awk '{ print $3 }')
        if [[ -z ${MOUNT_POINT} ]]; then
                echo $log "Предупреждение: ${DEVICE} не смонтированопримонтировано"
            else
                    /bin/umount -l ${DEVICE}
            echo         $log "**** Отмонтировано ${DEVICE} **** Удаление точки монтирования ${MOUNT_POINT} и записи в /etc/fstab"
        fi    fi
        [ -d "$MOUNT_POINT" ] && /bin/rmdir "$MOUNT_POINT"
        sed -i "/^${DEVICE//\//\\/}\s\+${MOUNT_POINT//\//\\/}/d" /etc/fstab
    }

    do_reload() {
        $log "Reload: ${DEVICE}-${ID_FS_LABEL:-}-${DEVBASE}"
        MOUNT_POINT=$(/bin/mount | /bin/egrep "^${DEVICE}" | /usr/bin/awk '{ print $3 }')
        if [[ -z ${MOUNT_POINT} ]]; then
            for d in `egrep "^${DEVICE}\s+" /etc/fstab | awk '{print $2}'` ; do
                $log "Reload: ${DEVICE} не примонтировано. Удаление точки монтирования $d"
                [ -d "$d" ] && rm "$d"
            done
        else
            $log "Reload: ${DEVICE} примонтировано"
        fi
        sed -i "/^${DEVICE//\//\\/}\s\+/d" /etc/fstab # Удаление пустых каталогов
        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 ;;
            reload) do_reload ;;
        *) usage ;;
    esac

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

    Command
    sudo chmod +x /usr/local/bin/usb-mount.sh
    Приёмы

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

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

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