UMGUM.COM (лучше) 

UDEV ( Прослойка абстракции в области именования устройств файловой системы. )

1 августа 2010  (обновлено 15 августа 2016)

OS: Debian Linux.

Небольшое, но важное, отступление. Этап работ, описываемый здесь можно пропустить, но я счёл необходимым для себя реализовать прослойку абстракции от уровня системных утилит, хотя бы и в области именования устройств.

В нашей операционной системе именованием устройств занимается пакет приложений UDEV. Очень удобная и красивая штука, особенно для управления устройствами "горячего" типа подключения, вроде USB носителей. Каждый раз, когда ядро обнаруживает обновление структуры устройств, оно вызывает утилиты UDEV для именования обнаруженных устройств. Казалось бы, какое к нам это имеет отношение, мы работаем не с "флешками" и не USB "веб"-камерами? А вот и имеет, SATA ACHI считаются "сменными" устройствами, да ещё и эмулируются как устройства группы "scsi". То есть, именование одного устройства может смениться в зависимости от того, появилось ли перед ним на "шине" или пропало однотипное устройство. Иначе говоря, в какой то из не прекрасных моментов, после смены конфигурации компьютера, можно обнаружить то, что дисковое устройство "sdb" вдруг стало называться "sdf", или наоборот.


Чтобы избежать вышеописанной ситуации, можно привязать статическими правилами для UDEV уникальные для нашей схемы символические имена блочных устройств, с которыми мы работаем, к их физическим признакам, например к серийному номеру устройства (все помнят, что ранее мы договорились о методе идентификации дисковых устройств и привязки их к физическому месторасположению с помощью простейшей таблицы?). Можно и нужно, но меня, в силу моей особой тупости (временной - сильно надеюсь), не вышло в правилах UDEV воспользоваться возможностью запуска сторонних приложений. Решать задачу необходимо, проблема с UDEV ввергнула меня в печаль и сомнение; пришлось решать задачу с помощью скриптов.

Устанавливаем утилиту получения информации о дисковых устройствах, если её ещё нет в системе:

# aptitude install hdparm

Пишем скрипт, помогающий нам получать серийные номера дисковых устройств SATA:

# touch /etc/custom/hdd/get-sd-serial.sh
# chmod ugo+x /etc/custom/hdd/get-sd-serial.sh

#!/bin/sh
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
INDEX=$1

if [ ! $INDEX ]
then
  exit 0
fi

hdparm -i /dev/$INDEX | grep SerialNo | awk '{print $6}'

exit 0

Создадим список, через пробел, серийных номеров наших дисковых устройств и условных имён, сопоставляемых с этими устройствами, с разделителем между номером и именем в виде символа "слэш". К имени публикуемого устройства добавляем через разделитель в виде "слеша" присвоенный ему нами индекс (условные "номер шасси или компьютера"."номер слота или интерфейса диска") для однозначной идентификации его прослойкой LVM на дальнейших этапах:

# mkdir -p /etc/custom/hdd/dev
# touch /etc/custom/hdd/dev/list

# cat /etc/custom/hdd/dev/list

odsk0.0/serial0 odsk0.1/serial1 ... odsk0.X/serialX

Замечу, к вышеприведённому списку, о том, что обращаться с помощью "жёсткой" ссылки в дальнейшем мы будем не к блочному устройству вроде "sda", например, а к разделу на указанном устройстве, например: "sda1". То есть, сопоставление будет вида: "sda1 => odsk0". С учётом того, что мы используем всё дисковое пространство, можно было бы обращаться и по имени блочного устройства диска, а не создавать ещё одну сущность в виде раздела на весь диск, но, в ряде случаев, обращение к разделу более предпочтительно из соображений совместимости с разнообразным программным обеспечением.

Пишем скрипт сканирования имеющихся дисковых устройств SATA, поиска среди них наших, проверяющий корректность их применения и создающий для них "жёсткие" ссылки, если в этом есть необходимость:

# touch /etc/custom/hdd/dev/check-dev.sh
# chmod ugo+x /etc/custom/hdd/dev/check-dev.sh

#!/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
OBJECTS=`ls /dev | grep -i "^sd[a-z]$"`
NAMES=`cat /etc/custom/hdd/dev/list`

# Перебираем в цикле все обнаруженные дисковые устройства по наименованию
for OBJECT in ${OBJECTS}; do
  # Выясняем серийный номер
  SERIAL=`/etc/custom/hdd/get-sd-serial.sh $OBJECT`
  if [ "$SERIAL" != "" ]
  then
    # Сопоставляем серийный номер и символическое имя
    for NAME in ${NAMES}; do
      if [ "`echo $NAME | awk -F / '{print $2}'`" == "$SERIAL" ]
      then
        ODSK=`echo $NAME | awk -F / '{print $1}'`
      fi
    done
    if [ "$ODSK" != "" ]
    then
      # Ищем первый подраздел
      if [ "`ls /dev | grep -i ${OBJECT}1`" != "" ]
      then
        # Проверяем наличие корректной ссылки
        # CHECK=`ls -l /dev | grep -i "^lrwx.*${ODSK}.*${OBJECT}1$"`
        if [ "`ls -l /dev | grep -i lrwx | grep -i ${ODSK} | grep -i ${OBJECT}1`" == "" ]
        then
          # Если нет, то создаем "жёсткую" ссылку
          ln -f /dev/${OBJECT}1 /dev/${ODSK}
        fi
      fi
    fi
  fi
done

exit 0

Скриптик простенький, утилитарный. Вызывать его будем во всех случаях, когда нужно будет осуществить первичный запуск или перезапуск сервиса, обращающегося к дисковым устройствам.

Учитывая то, что содержимое директории "/dev" с загрузкой операционной системы полностью обновляется, можно не опасаться загромождения её устаревшими ссылками; в связи с указанной особенностью директории очевидным является необходимость вызывать скрипт создания "жёстких" ссылок на устройства после каждой загрузки системы перед началом работы.


Заметки и комментарии к публикации:


Оставьте свой комментарий ( выразите мнение относительно публикации, поделитесь дополнительными сведениями или укажите на ошибку )