Здесь размещено описание одного из функциональных блоков инструкций управления самодельным сетевым хранилищем на сочетании технологий "MDADM + LVM + XFS + NFS + MHDDFS" через простейшие BASH-скрипты. Отдельно неприменимо.
Заранее готовим корневую точку монтирования для импортируемых NFS-ресурсов:
# mkdir -p /mnt/import
# chown -R storage:storage /mnt/import
# chmod -R ug+rw /mnt/import
# chown -R storage:storage /mnt/import
# chmod -R ug+rw /mnt/import
Создадим конфигурационный файл перечнем и описанием характеристик ресурсов, готовых к инициализации и использованию:
# vi /usr/local/etc/storage/cnf.d/nfs.import.cnf
....
nfs.import=node0
nfs.import.node0.address=10.10.12.195
nfs.import.node0.root=/mnt/export
nfs.import.node0.from=/storage0
nfs.import.node0.to=/mnt/import/node0
nfs.import=node1
nfs.import.node1.address=10.10.12.196
nfs.import.node1.root=/mnt/export
nfs.import.node1.from=/storage0
nfs.import.node1.to=/mnt/import/node1
nfs.import=node2
nfs.import.node2.address=10.10.12.197
nfs.import.node2.root=/mnt/export
nfs.import.node2.from=/storage0
nfs.import.node2.to=/mnt/import/node2
nfs.import=node3
nfs.import.node3.address=10.10.12.198
nfs.import.node3.root=/mnt/export
nfs.import.node3.from=/storage0
nfs.import.node3.to=/mnt/import/node3
....
nfs.import=node0
nfs.import.node0.address=10.10.12.195
nfs.import.node0.root=/mnt/export
nfs.import.node0.from=/storage0
nfs.import.node0.to=/mnt/import/node0
nfs.import=node1
nfs.import.node1.address=10.10.12.196
nfs.import.node1.root=/mnt/export
nfs.import.node1.from=/storage0
nfs.import.node1.to=/mnt/import/node1
nfs.import=node2
nfs.import.node2.address=10.10.12.197
nfs.import.node2.root=/mnt/export
nfs.import.node2.from=/storage0
nfs.import.node2.to=/mnt/import/node2
nfs.import=node3
nfs.import.node3.address=10.10.12.198
nfs.import.node3.root=/mnt/export
nfs.import.node3.from=/storage0
nfs.import.node3.to=/mnt/import/node3
....
Фрагмент кода автоматизации функционала импорта NFS-ресурсов подсистемы хранения:
# vi /usr/local/etc/storage/fnc.d/nfs.import.fnc
#!/bin/bash
# This file contains the code snippet for the shell Bash v.4 (Bourne again shell)
# Файл содержит фрагмент кода для командного интерпретатора Bash v.4 (Bourne again shell)
# Функция импорта файловых систем хранилища посредством NFS
function start-nfs-import() {
# Перебираем все строки именований импортируемых ресурсов
for INFSS in `grep --ignore-case "^nfs.import=" "${CNF}" | uniq`; do
INFS=`echo ${INFSS} | awk -F = '{print $2}'`
# Перебираем все строки параметров импортируемых ресурсов
for PARAMS in `grep --ignore-case "^nfs.import.${INFS}." "${CNF}" | uniq` ; do
BUFFER=`echo ${PARAMS} | grep --ignore-case ".address=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && IADDRESS="${BUFFER}"
BUFFER=`echo ${PARAMS} | grep --ignore-case ".root=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && IROOT="${BUFFER}"
BUFFER=`echo ${PARAMS} | grep --ignore-case ".from=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && IFROM="${BUFFER}"
BUFFER=`echo ${PARAMS} | grep --ignore-case ".to=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && ITO="${BUFFER}"
done
# Проверяем наличие субьектов файловой системы
if [ ! -d "${ITO}" ] ; then
echo "${DATE}: The mount point ${ITO} intended to import the resource is not available. Aborting." | tee -a "${LOGT}"
return 1
fi
# Проверяем корректность параметров
if [ "${IROOT}" == "" ] || [ "${IADDRESS}" == "" ] ; then
echo "${DATE}: Not all resource settings are in full. Aborting." | tee -a "${LOGT}"
return 1
fi
# Проверяем, не импортированы ли уже ресурсы
STATE=`mount | grep --count --ignore-case "^${IADDRESS}:${IFROM}[ ]*on[ ]*${ITO}"`
if [ "${STATE}" -eq "0" ] ; then
# Проверяем доступность импортируемого ресурса
STATE=`showmount --exports --no-headers ${IADDRESS} | grep --count --ignore-case "^${IROOT}${IFROM}"`
if [ "${STATE}" -ne "0" ] ; then
# # IOPT="hard,tcp,sync,noatime,nodiratime,nodev,noexec,nosuid"
IOPT="soft, intr, retrans=5, timeo=600, rsize=4096, wsize=4096, tcp, async, noatime, nodiratime, nodev, noexec, nosuid"
mount.nfs4 ${IADDRESS}:${IFROM} ${ITO} -o ${IOPT}
# Проверяем успешность завершения операции
if [ "${?}" != "0" ] ; then
echo "${DATE}: Importing resource NFS ${IADDRESS}:${IFROM} completed with error. Aborting." | tee -a "${LOGT}"
return 1
fi
# Даём системе пару секунд на завершение импортирования
sleep 2
# Проверяем успешность импортирования
STATE=`mount | grep --count --ignore-case "^${IADDRESS}:${IFROM}[ ]*on[ ]*${ITO}"`
if [ "${STATE}" -ne "0" ] ; then
echo "${DATE}: Importing resource NFS ${IADDRESS}:${IFROM} completed successfully." | tee -a "${LOGT}"
else
echo "${DATE}: Importing resource NFS ${IADDRESS}:${IFROM} completed with error. Aborting." | tee -a "${LOGT}"
return 1
fi
else
echo "${DATE}: Imported resource NFS ${IADDRESS}:${IROOT}${IFROM} is not available. Aborting." | tee -a "${LOGT}"
return 1
fi
else
echo "${DATE}: Resource NFS ${IADDRESS}:${IFROM} has already been imported." | tee -a "${LOGT}"
fi
done
# Создаём файл блокировки, показывающий на состояние работы подсистемы
touch "${LOCK}/nfs-import.lck"
return $?
}
# Функция прекращения импорта файловых систем хранилища посредством NFS
function stop-nfs-import() {
# Перебираем все строки именований импортируемых ресурсов
for INFSS in `grep --ignore-case "^nfs.import=" "${CNF}" | uniq`; do
INFS=`echo ${INFSS} | awk -F = '{print $2}'`
# Перебираем все строки параметров импортируемых ресурсов
for PARAMS in `grep --ignore-case "^nfs.import.${INFS}." "${CNF}" | uniq` ; do
BUFFER=`echo ${PARAMS} | grep --ignore-case ".address=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && IADDRESS="${BUFFER}"
BUFFER=`echo ${PARAMS} | grep --ignore-case ".from=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && IFROM="${BUFFER}"
BUFFER=`echo ${PARAMS} | grep --ignore-case ".to=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && ITO="${BUFFER}"
done
# Проверяем, импортированы ли ресурсы
STATE=`mount | grep --count --ignore-case "^${IADDRESS}:${IFROM}[ ]*on[ ]*${ITO}"`
if [ "${STATE}" -ne "0" ] ; then
# Демонтируем ресурс NFS (сочетание ключей "force" и "lazy" позволяет отцепить даже задействованный ресурс)
umount.nfs4 "${ITO}" -fl
fi
done
# Удаляем файл блокировки, показывающий на состояние работы подсистемы
rm --force "${LOCK}/nfs-import.lck"
return $?
}
# Функция проверки состояния импортированных файловых систем хранилища посредством NFS
function check-nfs-import() {
# Удостоверимся в том, что публикация ресурсов прошла успешно (в противном случае проверку не запускаем - бессмысленно)
if [ -f "${LOCK}/nfs-import.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)
# Функция импорта файловых систем хранилища посредством NFS
function start-nfs-import() {
# Перебираем все строки именований импортируемых ресурсов
for INFSS in `grep --ignore-case "^nfs.import=" "${CNF}" | uniq`; do
INFS=`echo ${INFSS} | awk -F = '{print $2}'`
# Перебираем все строки параметров импортируемых ресурсов
for PARAMS in `grep --ignore-case "^nfs.import.${INFS}." "${CNF}" | uniq` ; do
BUFFER=`echo ${PARAMS} | grep --ignore-case ".address=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && IADDRESS="${BUFFER}"
BUFFER=`echo ${PARAMS} | grep --ignore-case ".root=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && IROOT="${BUFFER}"
BUFFER=`echo ${PARAMS} | grep --ignore-case ".from=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && IFROM="${BUFFER}"
BUFFER=`echo ${PARAMS} | grep --ignore-case ".to=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && ITO="${BUFFER}"
done
# Проверяем наличие субьектов файловой системы
if [ ! -d "${ITO}" ] ; then
echo "${DATE}: The mount point ${ITO} intended to import the resource is not available. Aborting." | tee -a "${LOGT}"
return 1
fi
# Проверяем корректность параметров
if [ "${IROOT}" == "" ] || [ "${IADDRESS}" == "" ] ; then
echo "${DATE}: Not all resource settings are in full. Aborting." | tee -a "${LOGT}"
return 1
fi
# Проверяем, не импортированы ли уже ресурсы
STATE=`mount | grep --count --ignore-case "^${IADDRESS}:${IFROM}[ ]*on[ ]*${ITO}"`
if [ "${STATE}" -eq "0" ] ; then
# Проверяем доступность импортируемого ресурса
STATE=`showmount --exports --no-headers ${IADDRESS} | grep --count --ignore-case "^${IROOT}${IFROM}"`
if [ "${STATE}" -ne "0" ] ; then
# # IOPT="hard,tcp,sync,noatime,nodiratime,nodev,noexec,nosuid"
IOPT="soft, intr, retrans=5, timeo=600, rsize=4096, wsize=4096, tcp, async, noatime, nodiratime, nodev, noexec, nosuid"
mount.nfs4 ${IADDRESS}:${IFROM} ${ITO} -o ${IOPT}
# Проверяем успешность завершения операции
if [ "${?}" != "0" ] ; then
echo "${DATE}: Importing resource NFS ${IADDRESS}:${IFROM} completed with error. Aborting." | tee -a "${LOGT}"
return 1
fi
# Даём системе пару секунд на завершение импортирования
sleep 2
# Проверяем успешность импортирования
STATE=`mount | grep --count --ignore-case "^${IADDRESS}:${IFROM}[ ]*on[ ]*${ITO}"`
if [ "${STATE}" -ne "0" ] ; then
echo "${DATE}: Importing resource NFS ${IADDRESS}:${IFROM} completed successfully." | tee -a "${LOGT}"
else
echo "${DATE}: Importing resource NFS ${IADDRESS}:${IFROM} completed with error. Aborting." | tee -a "${LOGT}"
return 1
fi
else
echo "${DATE}: Imported resource NFS ${IADDRESS}:${IROOT}${IFROM} is not available. Aborting." | tee -a "${LOGT}"
return 1
fi
else
echo "${DATE}: Resource NFS ${IADDRESS}:${IFROM} has already been imported." | tee -a "${LOGT}"
fi
done
# Создаём файл блокировки, показывающий на состояние работы подсистемы
touch "${LOCK}/nfs-import.lck"
return $?
}
# Функция прекращения импорта файловых систем хранилища посредством NFS
function stop-nfs-import() {
# Перебираем все строки именований импортируемых ресурсов
for INFSS in `grep --ignore-case "^nfs.import=" "${CNF}" | uniq`; do
INFS=`echo ${INFSS} | awk -F = '{print $2}'`
# Перебираем все строки параметров импортируемых ресурсов
for PARAMS in `grep --ignore-case "^nfs.import.${INFS}." "${CNF}" | uniq` ; do
BUFFER=`echo ${PARAMS} | grep --ignore-case ".address=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && IADDRESS="${BUFFER}"
BUFFER=`echo ${PARAMS} | grep --ignore-case ".from=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && IFROM="${BUFFER}"
BUFFER=`echo ${PARAMS} | grep --ignore-case ".to=" | awk -F = '{print $2}'`
[ "${BUFFER}" != "" ] && ITO="${BUFFER}"
done
# Проверяем, импортированы ли ресурсы
STATE=`mount | grep --count --ignore-case "^${IADDRESS}:${IFROM}[ ]*on[ ]*${ITO}"`
if [ "${STATE}" -ne "0" ] ; then
# Демонтируем ресурс NFS (сочетание ключей "force" и "lazy" позволяет отцепить даже задействованный ресурс)
umount.nfs4 "${ITO}" -fl
fi
done
# Удаляем файл блокировки, показывающий на состояние работы подсистемы
rm --force "${LOCK}/nfs-import.lck"
return $?
}
# Функция проверки состояния импортированных файловых систем хранилища посредством NFS
function check-nfs-import() {
# Удостоверимся в том, что публикация ресурсов прошла успешно (в противном случае проверку не запускаем - бессмысленно)
if [ -f "${LOCK}/nfs-import.lck" ]; then
echo "check"
fi
return $?
}
Переход к настройке автоматизации сборки файловых систем в единую точку посредством MHDDFS.