Итак, мы уже имеем "куски" в виде полноценных блочных устройств с размещёнными на них файловыми системами. Последний серьёзный шаг на нашем пути - объединение всего этого в единой точке монтирования. Воспользуемся для этого разработкой российского программиста Дмитрия Обухова 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.
Пишем скрипт, собирающий файловую систему из всех доступных объектов монтирования, расположенных в /dev/etherd/:
# vi /etc/custom/hdd/mnt/assembly-mnt.sh && chmod ugo+x /etc/custom/hdd/mnt/assembly-mnt.sh
#!/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
HOSTNAME=`cat /etc/hostname`
DATE=`date +"%Y-%m-%d %H:%M:%S"`
EMAIL=`cat /etc/custom/hdd/email`
MHDDFS=""
# Определяем функцию уведомления администратора о нештатном развитии ситуации
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}
}
# Проверяем, не установлены ли флаги блокировки от текущего или более низкого уровня схемы
if [ -e /tmp/custom/mnt/lock ]
then
exit 0
fi
# Устанавливаем флаг блокировки на время работы скрипта
mkdir -p /tmp/custom/mnt
touch /tmp/custom/mnt/lock
# Переходим в директорию объектов для монтирования
cd /dev/etherd/
# Перебираем в цикле объекты для монтирования
for OBJECT in *
do
# Проверяем, является ли файл блочным устройством
if [ -b "./${OBJECT}" ]
then
# Монтируем объект
mkdir -p /mnt/${OBJECT}
mount -t xfs -o noatime,nodiratime,osyncisdsync /dev/etherd/${OBJECT} /mnt/${OBJECT}
# Выжидаем десять секунд для корректного прохождения операции монтирования тома
echo "Wait 10 seconds for correct mount /dev/${OBJECT} as resource /mnt/${OBJECT}..."
sleep 10
# Проверяем, не было ли ошибок при монтировании устройства в положенной ему точке
if [ "`mount | grep -i ${OBJECT} | grep -i ${OBJECT} | grep -i xfs`" != "" ]
then
# Добавляем точку монтирования в список
MHDDFS=${MHDDFS}",/mnt/${OBJECT}"
else
# Паникуем по поводу некорректного монтирования объекта-устройства
send-report ${OBJECT} "Panic! Некорректно смонтировано блочное устройство."
echo >&2 "Panic! Некорректно смонтировано блочное устройство ${OBJECT}."
fi
fi
done
# После того, как все доступные объекты успешно смонтированы, сводим их в единую точку с помощью MHDDFS
mkdir -p /mnt/storage
# Отрезаем лишнюю запятую впереди строки
MHDDFS=`echo "${MHDDFS}" | cut -c 2-`
mhddfs -o mlimit=100G,noatime,allow_other ${MHDDFS} /mnt/storage
# Удаляем флаг блокировки во время исполнения
rm --force /tmp/custom/mnt/lock
exit 0
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
HOSTNAME=`cat /etc/hostname`
DATE=`date +"%Y-%m-%d %H:%M:%S"`
EMAIL=`cat /etc/custom/hdd/email`
MHDDFS=""
# Определяем функцию уведомления администратора о нештатном развитии ситуации
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}
}
# Проверяем, не установлены ли флаги блокировки от текущего или более низкого уровня схемы
if [ -e /tmp/custom/mnt/lock ]
then
exit 0
fi
# Устанавливаем флаг блокировки на время работы скрипта
mkdir -p /tmp/custom/mnt
touch /tmp/custom/mnt/lock
# Переходим в директорию объектов для монтирования
cd /dev/etherd/
# Перебираем в цикле объекты для монтирования
for OBJECT in *
do
# Проверяем, является ли файл блочным устройством
if [ -b "./${OBJECT}" ]
then
# Монтируем объект
mkdir -p /mnt/${OBJECT}
mount -t xfs -o noatime,nodiratime,osyncisdsync /dev/etherd/${OBJECT} /mnt/${OBJECT}
# Выжидаем десять секунд для корректного прохождения операции монтирования тома
echo "Wait 10 seconds for correct mount /dev/${OBJECT} as resource /mnt/${OBJECT}..."
sleep 10
# Проверяем, не было ли ошибок при монтировании устройства в положенной ему точке
if [ "`mount | grep -i ${OBJECT} | grep -i ${OBJECT} | grep -i xfs`" != "" ]
then
# Добавляем точку монтирования в список
MHDDFS=${MHDDFS}",/mnt/${OBJECT}"
else
# Паникуем по поводу некорректного монтирования объекта-устройства
send-report ${OBJECT} "Panic! Некорректно смонтировано блочное устройство."
echo >&2 "Panic! Некорректно смонтировано блочное устройство ${OBJECT}."
fi
fi
done
# После того, как все доступные объекты успешно смонтированы, сводим их в единую точку с помощью MHDDFS
mkdir -p /mnt/storage
# Отрезаем лишнюю запятую впереди строки
MHDDFS=`echo "${MHDDFS}" | cut -c 2-`
mhddfs -o mlimit=100G,noatime,allow_other ${MHDDFS} /mnt/storage
# Удаляем флаг блокировки во время исполнения
rm --force /tmp/custom/mnt/lock
exit 0
Пишем скрипт, разбирающий файловую систему, собранную из всех доступных объектов монтирования, расположенных в /dev/etherd/:
# vi /etc/custom/hdd/mnt/disassembly-mnt.sh && chmod ugo+x /etc/custom/hdd/mnt/disassembly-mnt.sh
#!/bin/bash
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
HOSTNAME=`cat /etc/hostname`
DATE=`date +"%Y-%m-%d %H:%M:%S"`
EMAIL=`cat /etc/custom/hdd/email`
# Определяем функцию уведомления администратора о нештатном развитии ситуации
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}
}
# Проверяем, не установлены ли флаги блокировки от текущего или более низкого уровня схемы
if [ -e /tmp/custom/mnt/lock ]
then
exit 0
fi
# Устанавливаем флаг блокировки на время работы скрипта
mkdir -p /tmp/custom/mnt
touch /tmp/custom/mnt/lock
# Разбираем систему MHDDFS
if [ "`mount | grep -i '/mnt/storage'`" != "" ]
then
umount -f /mnt/storage
fi
# Получаем список смонтированных из /dev/etherd/ файловых систем
mount | grep '^/dev/etherd/' | awk '{print $1}' | while read OBJECT
do
# Размонтируем полученные точки
umount -f ${OBJECT}
done
# Проверяем результат тотального размонтирования
if [ "`mount | grep '^/dev/etherd/'`" != "" ] || [ "`mount | grep -i '/mnt/storage'`" != "" ]
then
# Паникуем по поводу неполного размонтирования точек
send-report "MHDDFS" "Panic! Неполностью размонтированы точки."
echo >&2 "Panic! Неполностью размонтированы точки MHDDFS."
fi
# Удаляем флаг блокировки во время исполнения
rm --force /tmp/custom/mnt/lock
exit 0
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/sbin:/usr/local/bin
HOSTNAME=`cat /etc/hostname`
DATE=`date +"%Y-%m-%d %H:%M:%S"`
EMAIL=`cat /etc/custom/hdd/email`
# Определяем функцию уведомления администратора о нештатном развитии ситуации
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}
}
# Проверяем, не установлены ли флаги блокировки от текущего или более низкого уровня схемы
if [ -e /tmp/custom/mnt/lock ]
then
exit 0
fi
# Устанавливаем флаг блокировки на время работы скрипта
mkdir -p /tmp/custom/mnt
touch /tmp/custom/mnt/lock
# Разбираем систему MHDDFS
if [ "`mount | grep -i '/mnt/storage'`" != "" ]
then
umount -f /mnt/storage
fi
# Получаем список смонтированных из /dev/etherd/ файловых систем
mount | grep '^/dev/etherd/' | awk '{print $1}' | while read OBJECT
do
# Размонтируем полученные точки
umount -f ${OBJECT}
done
# Проверяем результат тотального размонтирования
if [ "`mount | grep '^/dev/etherd/'`" != "" ] || [ "`mount | grep -i '/mnt/storage'`" != "" ]
then
# Паникуем по поводу неполного размонтирования точек
send-report "MHDDFS" "Panic! Неполностью размонтированы точки."
echo >&2 "Panic! Неполностью размонтированы точки MHDDFS."
fi
# Удаляем флаг блокировки во время исполнения
rm --force /tmp/custom/mnt/lock
exit 0
Посмотрим, что должно получаться у нас после сборки распределённой файловой системы:
# df -h
....
/mnt/e0.0;/mnt/e0.1;.../mnt/e2.5
12T 11T 1.4T 89% /mnt/storage
/mnt/e0.0;/mnt/e0.1;.../mnt/e2.5
12T 11T 1.4T 89% /mnt/storage
# mount
....
/dev/etherd/e0.0 on /mnt/e0.0 type xfs (rw,noatime,nodiratime,osyncisdsync)
/dev/etherd/e0.1 on /mnt/e0.1 type xfs (rw,noatime,nodiratime,osyncisdsync)
....
/dev/etherd/e2.5 on /mnt/e2.5 type xfs (rw,noatime,nodiratime,osyncisdsync)
/mnt/e0.0;/mnt/e0.1;.../mnt/e2.5 on /mnt/storage type fuse.mhddfs (rw,nosuid,nodev,noatime,allow_other)
/dev/etherd/e0.0 on /mnt/e0.0 type xfs (rw,noatime,nodiratime,osyncisdsync)
/dev/etherd/e0.1 on /mnt/e0.1 type xfs (rw,noatime,nodiratime,osyncisdsync)
....
/dev/etherd/e2.5 on /mnt/e2.5 type xfs (rw,noatime,nodiratime,osyncisdsync)
/mnt/e0.0;/mnt/e0.1;.../mnt/e2.5 on /mnt/storage type fuse.mhddfs (rw,nosuid,nodev,noatime,allow_other)
В ряде случаев в процессе работы MHDDFS может сложится впечатление о её зависании. Всякое бывает, конечно, но нужно помнить о том, что если одно из дисковых устройств переполняется в процессе увеличения размера открытого файла, то "драйвер" MHDDFS автоматически переместит этот самый файл (не закрывая соединения с ним, а лишь "заморозив" очередь обращения к нему) на другую точку монтирования, более свободную. Понятно, что в случае файла ста гигабайтного объёма задержка может быть весьма длительной и, в связи со спецификой работы драйвера, директории, в которых располагается обрабатываемый файл в этот момент практически не доступны; при том, что файловая система в целом работает.