14.04.2016Автоматическое монтирование папки NFS
Источник вдохновения
Кроме рабочих процессов и случайного вдохновения, самым надёжным источником программерских задач является повторение. Одно из самых ярких чувств удовлетворения наступает от того, что не нужно делать то, что вынужден был делать до этого сто раз.
В работе мы используем сетевые хранилища данных. Они не так гибки в настройке, как обычные компьютеры, но работать можно. Для монтирования дисков на рабочие машины мы используем протокол NFS. И он, вместе с этими устройствами, доставляет множество мелких проблем.
Одну из таких проблем решает быстрый пинг из предыдущей статьи. Потому что хуже того, чтобы пытаться монтировать выключенное хранилище может быть только выключение замонтированного хранилища.
Но сегодня мы будем бороться с тем, что каждое хранилище требует по-разному к нему обращаться с рабочей машины.
Имя, сестра!
После выполнения одинаковых инструкций — настройка адреса, создание папки c именем, например, storage, предоставление к ней доступа по NFS — на хранилищах разных марок оказываются доступны разные папки. Тут нам на помощь приходит showmount:
$ showmount -e 192.168.4.50
Exports list on 192.168.4.50:
/storage
/homes
/Web
/Usb
/Recordings
/Public
/Network Recycle Bin 1
/Multimedia
/Download
$ showmount -e 192.168.4.60
Exports list on 192.168.4.60:
/volume1/storage *
Мы бы могли на первом хранилище создать руками папки /volume1/storage, но всегда может появиться устройство с другим названием корневого раздела. Вот и первый кусок кода, где мы определяем имя удалённой папки:
NFSPOINT=`showmount -e $HOST | grep storage | awk '{print $1}'`
autofs
В случае с постоянными включениями-выключениями и переносами хранилищ одним из хороших решений является autofs. В таком случае нам нужно только автоматически конфигурировать его по запросу. Если в нашем /etc/auto.master написано:
/mnt/autofspts /etc/auto.myrules
То по запросу можно писать нужную конфигурацию в /etc/auto.myrules таким образом:
#!/bin/bash
address=192.168.4.50
folder=somefolder
if ping -A -s16 -i0.5 -c3 -q $address > /dev/null 2>&1; then
set -o pipefail
mount_point=`showmount -e $address | grep storage | awk '{print $1}'`
if [[ $? == 0 ]]; then
entry="$folder -fstype=nfs,rsize=8192,wsize=8192,noatime,nodiratime,intr,async $address:$mount_point"
case "$mount_point" in
/storage)
model="QNAP"
;;
/volume1/storage)
model="Synology"
;;
*)
model="unkonwn"
;;
esac
output="$address:$mount_point $model"
if [ "x$(cat /etc/auto.myrules)" = "x$entry" ]; then
echo $output
else
echo $entry > /etc/auto.myrules && echo $output configured
fi
else
exit 101
fi
else
exit 102
fi
Тут мы делаем сразу несколько волшебных вещей:
- Пингуем перед тем, как смотреть на папки;
- Определяем марку из уже известных хранилищ;
- Сверяем, что уже написано в конфиге и не пишем, если там всё ок;
- Возвращаем разные статусы для разных ошибок.
Тут, однако, нужны права суперпользователя, чтобы писать в конфиг. О том, как я поступаю с суперпользователями на некоторых рабочих машинах я расскажу дальше.
sudo mount
Всем хорош autofs, кроме того, что не проверяет, опять таки, включена ли машина, прежде чем лезть на неё. Что приводит, например, к зависанию процедур листинга папок со ссылками внутрь внешних хранилищ. Вполне возможно обойтись просто командой mount. Но в случае, когда тома не прописаны в /etc/fstab, для монтирования нужны права суперпользователя. А автоматически править /etc/fstab очень не хочется.
На машинах, где все знают пароль для sudo я пользуюсь совершенно беззастенчиво совершенно опасной возможностью sudo получать пароль из стандартного ввода:
#!/bin/bash
NAME=$1
POINT=$2
HOST=$3
if mount | grep $POINT -c > /dev/null; then
./ping.sh $HOST && echo -e "[\e[0;32mOK\e[0m] Already mounted $NAME" || ( echo -e "[\e[0;31mFAIL\e[0m] $NAME is mounted but unreachable. Check if it's powered and connected" && exit 1 )
else
if ./ping.sh $HOST; then
NFSPOINT=`showmount -e $HOST | grep storage | awk '{print $1}'`
echo "password" | sudo -S -p "" mount -tnfs -o"rw,rsize=8192,wsize=8192,noatime,nodiratime,intr,async" $HOST:$NFSPOINT $POINT && echo -e "[\e[0;32mOK\e[0m] Successfully mounted $NAME" || ( echo -e "[\e[0;31mFAIL\e[0m] Unable to mount $NAME" && exit 1 )
else
echo -e "[\e[0;31mFAIL\e[0m] $NAME is unreachable."
exit 1
fi
fi
Конечно, кусочек echo "password" | sudo -S -p "" mount вызывает резонный вопрос: «А почему бы тогда не сделать sudo без пароля для данного пользователя?» Ответ тут такой, что за этой машиной работают не только роботы, но и люди, а человека ввод пароля, пусть даже и такого, который все знают, вводит в более сосредоточенное и серьёзное состояние.
Вопрос для самостоятельного изучения
Если вдруг вы знаете, как справляться ситуацией, когда замонтированное (любым способом) хранилище NFS выключили, то напишите мне.
sudo umount -f -l /mnt/point
Особенно для случаев, когда такая команда не работает.