Замена традиционному automount'у.
В одном (а может и не одном) большом датацентре одной большой транснациональной компании инженеры считли тысячи и десятки тысяч небольших и средних задачек. Делали они это налаженным путем, изо дня в день отправляя заявки в систему распределенных вычислений (коммерческую, с платной поддержкой), которая распределяла их задачи по нескольким сотням узлов (никакого самосбора - брендовое железо с платной поддержкой от вендора) с лицензионной операционной системой (разумеется тоже с платной поддержкой). И обнаружили инженеры, что определенный процент задач вдруг повисает в так называемом "D-state", как vmware-vmx и kjournald на следующей картинке, только виснет намертво.
В руководстве к команде top по поводу состояния задач сказано следующее
S -- Process Status
The status of the task which can be one of:
’D’ = uninterruptible sleep
’R’ = running
’S’ = sleeping
’T’ = traced or stopped
’Z’ = zombie
А коллеги со stackoverflow.com уточняют, что обычно так выглядит ожидание ввода-вывода, особенно к дисковым устройствам.
Поскольку часть расчетов являлась регрессионными тестами для квалификации ПО, то просто так перезапустить "рухнувшие" задачи было нельзя, и в итоге расследованием инцидента занялась техподдержка разработчика операционной системы. И выяснила что во всем виноват automount. В итоговом отчете было что-то про "chase conditions" и предлагался патч.
"Chase conditions" или, выражаясь по-русски, "гонки" - это ситуация, когда результат выполнения кода недетерминирован и зависит от случайных процессов.
Автомонтировщик монтирует файловую систему при обращении процесса к файлу, расположенному на этой файловой системе. В случае, если в течение определенного времени к файловой системе не было ни одного обращения - она демонтируется. Очевидно, в данном случае запрос на доступ к файлу конкурировал с операцией размонтирования по тайм-ауту и в худшем случае автомонтировщик выдергивал файл из-под ног у процесса.
При огромном количестве монтируемых файловых систем использование automount дает удобство и некоторую экономию памяти. Если количество файловых систем невелико, то экономия будет несущественной, а получить удобство в централизованном управлении монтировками можно с помощью скрипта.
LABEL=/ / ext3 defaults 1 1
tmpfs /dev/shm tmpfs defaults 0 0
devpts /dev/pts devpts gid=5,mode=620 0 0
sysfs /sys sysfs defaults 0 0
proc /proc proc defaults 0 0
LABEL=SWAP-sda2 swap swap defaults 0 0
main-nfs:/site/Moscow-1 /site/Moscow-1 nfs ro,rsize=8192,timeo=1,intr,soft
Новая версия скрипта
MYNAME=`uname -n`
if [ -e /etc/site/Moscow-1/mounts-$MYNAME ];
then
cp /etc/site/Moscow-1/mounts-$MYNAME /etc/mounts
else
cp /etc/site/Moscow-1/mounts /etc/mounts
fi
mount | awk '/type nfs/ {print $1" "$2" "$3}' > /tmp/current_mounts
cat /etc/mounts > /tmp/new_mounts
/etc/diff_mounts /tmp/current_mounts /tmp/new_mounts /tmp/delmounts /tmp/addmounts
#diff -b -B /tmp/current_mounts /tmp/new_mounts | grep ">" > /tmp/addmounts
#diff -b -B /tmp/current_mounts /tmp/new_mounts | grep "<" > /tmp/delmounts
echo "" > /tmp/mount.sh
for mountpoint in `cat /tmp/delmounts | cut -d" " -f1`; do
#echo "Unmounting $mountpoint resource..."
echo "umount -f -l $mountpoint" >> /tmp/mount.sh;
#echo "Deleting $mountpoint mountpoint..."
# rm $dir;
done;
cat /tmp/addmounts | awk '{print "mount -t nfs -o hard,intr,retrans=16,timeo=64,rsize=32768,wsize=32768 "$1" "$3}' >> /tmp/mount.sh
chmod 755 /tmp/mount.sh
if [[ `cat /tmp/addmounts | wc -l`>0 ]];
then
mkdir -p `awk '{print $3}' /tmp/addmounts`
fi
/tmp/mount.sh
d=`date +%y%m%d%H%M%S`
echo "$d mounts updated"
Старая версия скрипта
(использует только команды UNIX, поэтому должна работать на любой платформе)
cp /site/Moscow-1/mounts /etc
mount | awk '/type nfs/ {print $1" "$2" "$3}' | sort > /tmp/current_mounts
sort /etc/mounts > /tmp/new_mounts
join -v 1 -t"!" /tmp/new_mounts /tmp/current_mounts > /tmp/addmounts
join -v 1 -t"!" /tmp/current_mounts /tmp/new_mounts > /tmp/delmounts
for mountpoint in `cat /tmp/delmounts | cut -d" " -f3`; do
echo "Unmounting $mountpoint resource..."
umount -l $mountpoint;
#echo "Deleting $mountpoint mountpoint..."
# rm $dir;
done;
mkdir -p `awk '{print $3}' /tmp/addmounts`
cat /tmp/addmounts | awk '{print "mount -t nfs -o hard,intr,retrans=16,timeo=64,
chmod 755 /tmp/mount.sh
/tmp/mount.sh
d=`date +%y%m%d%H%M%S`
echo "$d mounts updated" >> /var/log/messages