Здесь размещено описание одного из функциональных блоков инструкций управления самодельным сетевым хранилищем на сочетании технологий "MDADM + LVM + XFS + NFS + MHDDFS" через простейшие BASH-скрипты. Отдельно неприменимо.
Обновим конфигурационный файл с перечнем и описанием характеристик ресурсов, готовых к инициализации и использованию.
Содержимое конфигурационного файла сформируем из вывода команды сканирования текущего состояния подсистемы, сразу после первичной сборки или изменения таковой. Примерный вывод:
# mdadm --detail --scan
ARRAY /dev/md0 metadata=1.2 bitmap=/mnt/journal/mdadm/md0-bitmap name=node1:0 UUID=0b03c852:5d850f6e:7635830d:1f8e0e8d
ARRAY /dev/md1 metadata=1.2 bitmap=/mnt/journal/mdadm/md1-bitmap name=node1:1 UUID=3786fb6e:b5746f9e:3bb90781:59bdd3a8
ARRAY /dev/md2 metadata=1.2 bitmap=/mnt/journal/mdadm/md2-bitmap name=node1:2 UUID=067b70c7:c9fa66b7:7fbb9927:39f4a423
ARRAY /dev/md1 metadata=1.2 bitmap=/mnt/journal/mdadm/md1-bitmap name=node1:1 UUID=3786fb6e:b5746f9e:3bb90781:59bdd3a8
ARRAY /dev/md2 metadata=1.2 bitmap=/mnt/journal/mdadm/md2-bitmap name=node1:2 UUID=067b70c7:c9fa66b7:7fbb9927:39f4a423
Также все необходимые данные можно вычленить из вывода утилиты "blkid":
# blkid
/dev/sdb1: UUID="ed0c7d76-5d03-a1c1-6bda-02e4ae6a6d0c" TYPE="linux_raid_member"
/dev/sdc1: UUID="ed0c7d76-5d03-a1c1-6bda-02e4ae6a6d0c" TYPE="linux_raid_member"
/dev/sdd1: UUID="29e32e2d-07b5-a4a0-f0dd-b4d123eb9099" TYPE="linux_raid_member"
/dev/sde1: UUID="29e32e2d-07b5-a4a0-f0dd-b4d123eb9099" TYPE="linux_raid_member"
/dev/sdf1: UUID="1d7b49bc-163f-96f5-c68d-f65279db4da0" TYPE="linux_raid_member"
/dev/sdg1: UUID="1d7b49bc-163f-96f5-c68d-f65279db4da0" TYPE="linux_raid_member"
/dev/sdc1: UUID="ed0c7d76-5d03-a1c1-6bda-02e4ae6a6d0c" TYPE="linux_raid_member"
/dev/sdd1: UUID="29e32e2d-07b5-a4a0-f0dd-b4d123eb9099" TYPE="linux_raid_member"
/dev/sde1: UUID="29e32e2d-07b5-a4a0-f0dd-b4d123eb9099" TYPE="linux_raid_member"
/dev/sdf1: UUID="1d7b49bc-163f-96f5-c68d-f65279db4da0" TYPE="linux_raid_member"
/dev/sdg1: UUID="1d7b49bc-163f-96f5-c68d-f65279db4da0" TYPE="linux_raid_member"
Неудобство лишь в том, что неясно, какой массив должен быть создан из соответствующих дисков. Собственно, для того, что бы зафиксировать эти отношения мы и напишем нижеследующий конфигурационный файл. Обратите внимание на отличие в форматах отображения UUID, где то символ ":", а где то символ "-". Думаю, лучше остановится на символе "-".
Берём из вывода только необходимое и формируем строки, которыми удобно манипулировать в скрипте. Для работы с уже существующим массивом нам не нужно ничего, кроме его символического имени, UUID-а и адреса файла содержащего "битовую таблицу". Например:
# vi /usr/local/etc/storage/cnf.d/mdadm.cnf
....
mdadm.module=raid1
mdadm.array=md0
mdadm.array.md0.uuid=ed0c7d76-5d03-a1c1-6bda-02e4ae6a6d0c
mdadm.array.md0.journal=/mnt/journal/mdadm/md0-bitmap
mdadm.array=md1
mdadm.array.md1.uuid=1d7b49bc-163f-96f5-c68d-f65279db4da0
mdadm.array.md1.journal=/mnt/journal/mdadm/md1-bitmap
mdadm.array=md2
mdadm.array.md2.uuid=29e32e2d-07b5-a4a0-f0dd-b4d123eb9099
mdadm.array.md2.journal=/mnt/journal/mdadm/md2-bitmap
....
mdadm.module=raid1
mdadm.array=md0
mdadm.array.md0.uuid=ed0c7d76-5d03-a1c1-6bda-02e4ae6a6d0c
mdadm.array.md0.journal=/mnt/journal/mdadm/md0-bitmap
mdadm.array=md1
mdadm.array.md1.uuid=1d7b49bc-163f-96f5-c68d-f65279db4da0
mdadm.array.md1.journal=/mnt/journal/mdadm/md1-bitmap
mdadm.array=md2
mdadm.array.md2.uuid=29e32e2d-07b5-a4a0-f0dd-b4d123eb9099
mdadm.array.md2.journal=/mnt/journal/mdadm/md2-bitmap
....
Фрагмент кода автоматизации функционала MDADM подсистемы хранения:
# vi /usr/local/etc/storage/fnc.d/mdmdm.fnc
#!/bin/bash
# This file contains the code snippet for the shell Bash v.4 (Bourne again shell)
# Файл содержит фрагмент кода для командного интерпретатора Bash v.4 (Bourne again shell)
# Функция запуска (сборки) вручную подготовленных массивов
function start-mdadm() {
# Перебираем все строки именований необходимых модулей
for MODULES in `grep --ignore-case "^mdadm.module=" "${CONF}" | uniq`; do
MODULE=`echo ${MODULES} | awk -F = '{print $2}'`
# Проверяем, загружен ли необходимый для работы с массивами модуль
if [ "`lsmod | grep --count --ignore-case ${MODULE}`" -eq "0" ] ; then
echo "${DATE}: Probe module ${MODULE} load..." >> ${LOG}
modprobe ${MODULE}
# Проверяем успешность завершения операции
if [ "${?}" != "0" ] ; then
send-report "MDADM" "Error load module ${MODULE}. Aborting."
echo "${DATE}: Error load module ${MODULE}. Aborting." >> ${LOG}
return 1
fi
fi
done
# Перебираем все строки именований массивов
for ARRAYS in `grep --ignore-case "^mdadm.array=" "${CONF}" | uniq`; do
ARRAY=`echo ${ARRAYS} | awk -F = '{print $2}'`
# Проверяем, не собран ли уже целевой массив
STATE=`cat /proc/mdstat | grep --count --ignore-case "^${ARRAY}[ ]*:[ ]*"`
if [ "${STATE}" -eq "0" ] ; then
# Перебираем все строки параметров массивов
for PARAMS in `grep --ignore-case "^mdadm.array.${ARRAY}." "${CONF}" | uniq` ; do
BUFFER=`echo ${PARAMS} | grep --ignore-case ".uuid=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && UUID="${BUFFER}"
BUFFER=`echo ${PARAMS} | grep --ignore-case ".journal=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && JOURNAL="${BUFFER}"
done
if [ "${UUID}" == "" ] || [ "${JOURNAL}" == "" ] ; then
send-report "MDADM" "Parameters of the target array are not in full. Aborting."
echo "${DATE}: Parameters of the target array are not in full. Aborting." >> "${LOG}"
return 1
fi
# Собираем массив
mdadm --assemble --bitmap="${JOURNAL}" --uuid="${UUID}" "/dev/${ARRAY}" >/dev/null 2>&1
# Проверяем успешность завершения операции
if [ "${?}" != "0" ] ; then
send-report "MDADM" "Error assemble array ${ARRAY}. Aborting."
echo "${DATE}: Error assemble array ${ARRAY}. Aborting." >> "${LOG}"
return 1
fi
# Даём системе пару секунд на осознание места нового устройства
sleep 2
# Проверяем успешность отрабатывания операции сборки массива
if [ -b "/dev/${ARRAY}" ] ; then
echo "${DATE}: Array ${ARRAY} successfully built." >> "${LOG}"
else
send-report "MDADM" "Assembling the array ${ARRAY} failed. Aborting."
echo "${DATE}: Assembling the array ${ARRAY} failed. Aborting." >> "${LOG}"
return 1
fi
else
# Проверяем состояние массива на базовом уровне
STATE=`cat /proc/mdstat | grep --count --ignore-case "^${ARRAY}[ ]*:[ ]*active[ ]*"`
if [ "${STATE}" -eq "0" ] ; then
send-report "MDADM" "Array ${ARRAY} collected in error and is not active. Aborting."
echo "${DATE}: Array ${ARRAY} collected in error and is not active. Aborting." >> "${LOG}"
return 1
else
echo "${DATE}: Array ${ARRAY} is already assembled." >> "${LOG}"
fi
fi
done
# Создаём файл блокировки, показывающий на состояние работы подсистемы
touch "${LOCK}/mdadm.lck"
return $?
}
# Функция остановки вручную подготовленных массивов
function stop-mdadm() {
# Перебираем все строки именований массивов
for ARRAYS in `grep --ignore-case "^mdadm.array=" "${CONF}" | uniq` ; do
ARRAY=`echo ${ARRAYS} | awk -F = '{print $2}'`
# Если массив доступен, то останавливаем его
[ -b "/dev/${ARRAY}" ] && mdadm --stop "/dev/${ARRAY}" >/dev/null 2>&1
done
# Удаляем файл блокировки, показывающий на состояние работы подсистемы
rm --force "${LOCK}/mdadm.lck"
return $?
}
# Функция проверки состояния вручную подготовленных массивов
function check-mdadm() {
# Удостоверимся в том, что сборка массивов прошла успешно (в противном случае проверку не запускаем - бессмысленно)
if [ -f "${LOCK}/mdadm.lck" ]; then
echo "check"
fi
return $?
}
# This file contains the code snippet for the shell Bash v.4 (Bourne again shell)
# Файл содержит фрагмент кода для командного интерпретатора Bash v.4 (Bourne again shell)
# Функция запуска (сборки) вручную подготовленных массивов
function start-mdadm() {
# Перебираем все строки именований необходимых модулей
for MODULES in `grep --ignore-case "^mdadm.module=" "${CONF}" | uniq`; do
MODULE=`echo ${MODULES} | awk -F = '{print $2}'`
# Проверяем, загружен ли необходимый для работы с массивами модуль
if [ "`lsmod | grep --count --ignore-case ${MODULE}`" -eq "0" ] ; then
echo "${DATE}: Probe module ${MODULE} load..." >> ${LOG}
modprobe ${MODULE}
# Проверяем успешность завершения операции
if [ "${?}" != "0" ] ; then
send-report "MDADM" "Error load module ${MODULE}. Aborting."
echo "${DATE}: Error load module ${MODULE}. Aborting." >> ${LOG}
return 1
fi
fi
done
# Перебираем все строки именований массивов
for ARRAYS in `grep --ignore-case "^mdadm.array=" "${CONF}" | uniq`; do
ARRAY=`echo ${ARRAYS} | awk -F = '{print $2}'`
# Проверяем, не собран ли уже целевой массив
STATE=`cat /proc/mdstat | grep --count --ignore-case "^${ARRAY}[ ]*:[ ]*"`
if [ "${STATE}" -eq "0" ] ; then
# Перебираем все строки параметров массивов
for PARAMS in `grep --ignore-case "^mdadm.array.${ARRAY}." "${CONF}" | uniq` ; do
BUFFER=`echo ${PARAMS} | grep --ignore-case ".uuid=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && UUID="${BUFFER}"
BUFFER=`echo ${PARAMS} | grep --ignore-case ".journal=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && JOURNAL="${BUFFER}"
done
if [ "${UUID}" == "" ] || [ "${JOURNAL}" == "" ] ; then
send-report "MDADM" "Parameters of the target array are not in full. Aborting."
echo "${DATE}: Parameters of the target array are not in full. Aborting." >> "${LOG}"
return 1
fi
# Собираем массив
mdadm --assemble --bitmap="${JOURNAL}" --uuid="${UUID}" "/dev/${ARRAY}" >/dev/null 2>&1
# Проверяем успешность завершения операции
if [ "${?}" != "0" ] ; then
send-report "MDADM" "Error assemble array ${ARRAY}. Aborting."
echo "${DATE}: Error assemble array ${ARRAY}. Aborting." >> "${LOG}"
return 1
fi
# Даём системе пару секунд на осознание места нового устройства
sleep 2
# Проверяем успешность отрабатывания операции сборки массива
if [ -b "/dev/${ARRAY}" ] ; then
echo "${DATE}: Array ${ARRAY} successfully built." >> "${LOG}"
else
send-report "MDADM" "Assembling the array ${ARRAY} failed. Aborting."
echo "${DATE}: Assembling the array ${ARRAY} failed. Aborting." >> "${LOG}"
return 1
fi
else
# Проверяем состояние массива на базовом уровне
STATE=`cat /proc/mdstat | grep --count --ignore-case "^${ARRAY}[ ]*:[ ]*active[ ]*"`
if [ "${STATE}" -eq "0" ] ; then
send-report "MDADM" "Array ${ARRAY} collected in error and is not active. Aborting."
echo "${DATE}: Array ${ARRAY} collected in error and is not active. Aborting." >> "${LOG}"
return 1
else
echo "${DATE}: Array ${ARRAY} is already assembled." >> "${LOG}"
fi
fi
done
# Создаём файл блокировки, показывающий на состояние работы подсистемы
touch "${LOCK}/mdadm.lck"
return $?
}
# Функция остановки вручную подготовленных массивов
function stop-mdadm() {
# Перебираем все строки именований массивов
for ARRAYS in `grep --ignore-case "^mdadm.array=" "${CONF}" | uniq` ; do
ARRAY=`echo ${ARRAYS} | awk -F = '{print $2}'`
# Если массив доступен, то останавливаем его
[ -b "/dev/${ARRAY}" ] && mdadm --stop "/dev/${ARRAY}" >/dev/null 2>&1
done
# Удаляем файл блокировки, показывающий на состояние работы подсистемы
rm --force "${LOCK}/mdadm.lck"
return $?
}
# Функция проверки состояния вручную подготовленных массивов
function check-mdadm() {
# Удостоверимся в том, что сборка массивов прошла успешно (в противном случае проверку не запускаем - бессмысленно)
if [ -f "${LOCK}/mdadm.lck" ]; then
echo "check"
fi
return $?
}
Переход к настройке сведения блочных устройств в единое в рамках локальной системы.