UMGUM.COM (лучше) 

MHDDFS ( Сбор нескольких файловых систем в единой точке монтирования. )

1 августа 2010  (обновлено 2 ноября 2014)

OS: Debian Linux.

И так, мы уже имеем "куски" в виде полноценных блочных устройств с размещёнными на них файловыми системами. Последний серьёзный шаг на нашем пути - объединение всего этого в единой точке монтирования. Воспользуемся для этого разработкой российского программиста Дмитрия Обухова MHDDFS (Multi HDD File System); подробнее с ней можно ознакомится по адресу http://mhddfs.uvw.ru/.

Инсталлируем пакет (в репозитории стабильной версии Debian номер - 0.1.12, на июнь 2010 года доступна уже 0.1.34; можно бы и собрать из исходных кодов):

# aptitude install mhddfs

Если каким-то чудом в системе ещё нигде не было использовано FUSE, то инсталлятор предложит её установить (fuse-utils и libfuse - невелика цена за решение задачи).

На самом деле MHDDFS сводит в одной точке не блочные устройства, а уже смонтированные файловые системы в единой точке монтирования. То есть, предварительно нужно будет смонтировать все доступные файловые системы на блочных устройствах, а уже к ним применять MHDDFS.


Применим отработанную методику составления статичного листа объектов:

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

Наименования объектов вносим с разделителем в виде пробельного символа. К имени объекта-устройства добавляем через разделитель в виде "слэша" обозначение точки монтирования. Например:

# cat /etc/custom/hdd/mnt/list

drbd0/mnt0.0 drbd1/mnt0.1 ... drbdX/mnt0.X e2.0/mnt2.0 e2.1/mnt2.1 ... e2.X/mnt2.X

Именование точек монтирования универсальное, взято от принципа именования AoE. Первый индекс в имени - условный номер компьютера в схеме, второй индекс - условный номер дискового устройства.

Пишем скрипт, отрабатывающий список объектов монтирования:

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

#!/bin/bash

PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
HOSTNAME=`cat /etc/hostname`
OBJECTS=`cat /etc/custom/hdd/mnt/list`
DATE=`date +"%Y-%m-%d %H:%M:%S"`
EMAIL=`cat /etc/custom/hdd/email`
MHDDFS=""
mkdir -p /tmp/custom/mnt
# Поднимаем флаг обнаружения ошибок при отработке скрипта
FLAG="1"

# Устанавливаем флаг блокировки на время работы скрипта
echo "0" > /tmp/custom/mnt/flag

# Проверяем, не установлен ли флаг блокировки от более низкого уровня схемы
if [ "`cat /tmp/custom/drbd/flag`" != "1" ]
then
  exit 0
fi

function send-report() {
  local LOCAL_OBJECT=$1
  local LOCAL_REPORT=$2
  # Посылаем электронное письмо с уведомлением о проблеме
  echo -e "Content-Type: text/plain; charset="utf-8"\nSubject: Warning MHDDFS: $HOSTNAME: /dev/$LOCAL_OBJECT\n$DATE.\nHost: $HOSTNAME.\nDevice: /dev/$LOCAL_OBJECT.\n$LOCAL_REPORT" | sendmail -F$HOSTNAME $EMAIL
}

# Перебираем в цикле объекты для монтирования
for OBJECTIVE in $OBJECTS
do
  # Получаем в переменные имя устройства и назначенный ему индекс
  OBJECT=`echo $OBJECTIVE | awk -F / '{print $1}'`
  POINT=`echo $OBJECTIVE | awk -F / '{print $2}'`
  # Проверяем наличие объекта как блочного устройства
  if [ "`ls -l /dev/ | grep -i brw | grep -i $OBJECT`" != "" ] || [ "`ls -l /dev/etherd/ | grep -i brw | grep -i $OBJECT`" != "" ]
  then
    # Проверяем, не смонтировано ли устройство в положенной ему точке
    if [ "`mount | grep -i $OBJECT | grep -i $POINT | grep -i xfs`" = "" ]
    then
      # Монтируем объект
      mkdir -p /mnt/$POINT
      if [ "`ls -l /dev/ | grep -i brw | grep -i $OBJECT`" != "" ]
      then
        # mount -t xfs -o noatime,nodiratime,osyncisdsync /dev/$OBJECT /mnt/$POINT
        mount -t xfs -o noatime,nodiratime,sync,nodev,nosuid,noexec /dev/$OBJECT /mnt/$POINT
      fi
      if [ "`ls -l /dev/etherd/ | grep -i brw | grep -i $OBJECT`" != "" ]
      then
        # mount -t xfs -o noatime,nodiratime,osyncisdsync /dev/etherd/$OBJECT /mnt/$POINT
        mount -t xfs -o noatime,nodiratime,sync,nodev,nosuid,noexec /dev/etherd/$OBJECT /mnt/$POINT
      fi
      echo "Выжидаем десять секунд для корректного прохождения операции монтирования тома в точке /mnt/$POINT..."
      sleep 10
      # Проверяем, не было ли ошибок при монтировании устройства в положенной ему точке
      if [ "`mount | grep -i $OBJECT | grep -i $POINT | grep -i xfs`" = "" ]
      then
        # Устанавливаем флаг обнаружения ошибки
        FLAG="0"
        # Паникуем по поводу некорректного монтирования объекта-устройства
        send-report $OBJECT "Panic! Некорреткно смонтировано блочное устройство."
        echo >&2 "Panic! Некорректно смонтировано блочное устройство $OBJECT."
      fi
    fi
    # Добавляем точку монтирования в список
    MHDDFS=$MHDDFS",/mnt/$POINT"
  else
    # Устанавливаем флаг обнаружения ошибки
    FLAG="0"
    # Паникуем по поводу отсутствия объекта-устройства подлежащего монтированию
    send-report $OBJECT "Panic! Отсутствует блочное устройство подлежащее монтированию."
    echo >&2 "Panic! Отсутствует блочное устройство $OBJECT подлежащее монтированию."
  fi
done

# Если все объекты успешно смонтированы, то сводим их в единую точку с помощью MHDDFS
if [ "$FLAG" = "1" ] && [ "$MHDDFS" != "" ]
then
  # Проверяем, не отработан ли уже сбор
  if [ "`mount | grep -i /mnt/storage`" = "" ]
  then
    mkdir -p /mnt/storage
    # Отрезаем лишнюю запятую впереди строки
    MHDDFS=`echo "$MHDDFS" | cut -c 2-`
    mhddfs -o mlimit=100G,noatime,allow_other $MHDDFS /mnt/storage
  fi
fi

# Снимаем флаг блокировки если не было обнаружено ни одной ошибки
if [ "$FLAG" = "1" ]
then
  echo "1" > /tmp/custom/mnt/flag
else
  # В связи с обнаруженной ошибкой завершаем работу приложений, использующих эти устройства
  /etc/init.d/application stop
  # Для пущей уверенности в том, что ресурсы работающие с ошибкой не будут использованы, отмонтируем их
  umount -f /mnt/storage
fi

exit 0

Смотрим, что же у нас получилось:

# df -h

....
/mnt/drbd0;/mnt/drbd1;/mnt/drbd2;/mnt/drbd3;/mnt/drbd4;/mnt/drbd5
                      5.5T   73M  5.5T   1% /mnt/storage

# mount

....
/mnt/drbd0;/mnt/drbd1;/mnt/drbd2;/mnt/drbd3;/mnt/drbd4;/mnt/drbd5 on /mnt/storage type fuse.mhddfs (rw,nosuid,nodev,noatime)

Демонтируем, если в этом будет необходимость:

# fusermount -u /mnt/storage

В каком режиме запускать скрипт сборки точек монтирования - толком не понятно; с одной стороны - контролировать состояние особо и нечего, а, с другой стороны - определённого момента для запуска у него нет, только после отработки предыдущих этапов. Даже после успешного завершения какого либо из этапов не обязательно будут готовы все точки монтирования, они могут как подготавливаться локально, так и доставляться по сети. Ничего не остаётся, как запускать его через каждые пять минут, в ожидании, пока отработают предыдущие скрипты:

# cat /etc/crontab

....
*/5  * * * *   root    /etc/custom/hdd/mnt/check-mnt.sh &
....

В ряде случаев в процессе работы MHDDFS может сложится впечатление о её зависании. Всякое бывает, конечно, но нужно помнить о том, что если одно из дисковых устройств переполняется в процессе увеличения размера открытого файла, то "драйвер" MHDDFS автоматически переместит этот самый файл (не закрывая соединения с ним, а лишь "заморозив" очередь обращения к нему) на другую точку монтирования, более свободную. Понятно, что в случае файла ста гигабайтного объёма задержка может быть весьма длительной и, в связи со спецификой работы драйвера, директории, в которых располагается обрабатываемый файл в этот момент практически не доступны; при том, что файловая система в целом работает.


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


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