Heartbeatで共有ディスクのDiskQuotaを有効化する方法

通常Linuxは起動シーケンスでファイルシステムをマウントし、そのマウントしたファイルシステムに対してDiskQuotaを有効化します。
DRBDなどの共有ディスクは起動シーケンス後にマウントされるため、手動でコマンドを実行(quotaon)しなければDiskQuotaは有効になりません。
Heartbeatの標準リソースにはDiskQuotaに対する制御が無いので、自力でなんとかする必要があります。
以下はHeartbeat v2で共有ディスクのDiskQuotaを有効化する方法です。


1. /etc/ha.d/resource.d/Quotaを作成、実行権限を付与します。

#!/bin/sh
#
# Quota
# Description: Manages the quota(s) on a shared storage medium.
# Original Author: Marc Schmitt (mschmitt@xxxxxxxxxxx)
# Original Release: 18 April 2003
# Support: linux-ha@xxxxxx
# Based on: Linux-HA Filesystem resource script
#
# usage: ./Quota {start|stop|status}
#
# : use user quota
#: use group quota
#: run quota check
# : the mount point of the filesystem
#
#
# An example usage in /etc/ha.d/haresources:
# node1 10.0.0.170 Filesystem::/dev/sda1::/data1::ext3::usrquota Quota::y::n::n::/data1
#
unset LC_ALL; export LC_ALL
unset LANGUAGE; export LANGUAGE
prefix=/usr
exec_prefix=/usr
#. /etc/ha.d/shellfuncs
. /etc/ha.d/shellfuncs
# Utilities used by this script
QUOTAON=/sbin/quotaon
QUOTAOFF=/sbin/quotaoff
QUOTACHECK=/sbin/quotacheck
MOUNT=/bin/mount
check_util () {
if [ ! -x "$1" ] ; then
ha_log "ERROR: setup problem: Couldn't find utility $1"
exit 1
fi
}
usage() {
cat < usage: $0 {start|stop|status}
: use user quota
: use group quota
: run quota check
: the mount point of the filesystem
EOT
}
if [ $# -ne 5 ] ; then
usage
exit 1
fi
# Check the arguments passed to this script
DOUSERQUOTA=$1
DOGROUPQUOTA=$2
DOQUOTACHECK=$3
MOUNTPOINT=$4
operation=$5
options="-"
if [ ! -d "$MOUNTPOINT" ] ; then
ha_log "ERROR: Couldn't find directory $MOUNTPOINT to manage quotas on"
usage
exit 1
fi
[ "$DOUSERQUOTA" = "y" ] && options="${options}u"
[ "$DOGROUPQUOTA" = "y" ] && options="${options}g"
if [ "$options" = "-" ] ; then
ha_log "ERROR: Bad arguments"
usage
exit 1
fi
# Check to make sure the utilites are found
check_util $QUOTAON
check_util $QUOTAOFF
check_util $QUOTACHECK
# Look for the 'start', 'stop' or status argument
case "$operation" in
#
# START: Turn on quota(s)
#
start)
# See if the device is already mounted.
$MOUNT | cut -d' ' -f3 | grep -e "^$MOUNTPOINT$" >/dev/null
if [ $? -eq 1 ] ; then
ha_log "ERROR: Filesystem $MOUNTPOINT is not mounted!"
exit 1
fi
if
[ "$DOQUOTACHECK" = "y" ]
then
ha_log "info: Starting quota check on $MOUNTPOINT"
$QUOTACHECK $options $MOUNTPOINT
# NOTE: if any errors at all are detected, it returns non-zero
if
[ $? -ge 1 ]
then
ha_log "ERROR: Couldn't sucessfully check the quota for $MOUNTPOINT"
exit 1
fi
fi
# Turn on quota(s) on the filesystem.
if
$QUOTAON $options $MOUNTPOINT
then
: # Turning on quota(s) worked!
else
ha_log "ERROR: Couldn't turn on quota(s) on $MOUNTPOINT"
exit 1
fi
# end of start)
;;
#
# STOP: Turn off quota(s)
#
stop)
# See if the filesystem is currently mounted
if
$MOUNT | grep -e " on $MOUNTPOINT " >/dev/null
then
# Turn quota(s) off
$QUOTAOFF $options $MOUNTPOINT
if [ $? -ne 0 ] ; then
ha_log "ERROR: Couldn't turn off quota(s) on $MOUNTPOINT"
exit 1
fi
else
ha_log "WARNING: Filesystem $MOUNTPOINT not mounted?"
fi
# end of stop)
;;
#
# STATUS: are quota(s) turned on or not?
#
status)
$QUOTAON -p $options $MOUNTPOINT
# end of status)
;;
*)
echo "This script should be run with a fifth argument of 'start', 'stop', or 'status'"
usage
exit 1
;;
esac
# If you got to this point, chances are everything is O.K.
exit 0;

2. 以下の内容を記述したファイル/tmp/add.xmlを作成します。

<primitive class="heartbeat" id="Quota" provider="heartbeat" type="Quota">
<instance_attributes id="Quota_inst_attr">
<attributes>
<nvpair id="Quota_attr_1" name="1" value="y"/>
<nvpair id="Quota_attr_2" name="2" value="y"/>
<nvpair id="Quota_attr_3" name="3" value="n"/>
<nvpair id="Quota_attr_4" name="4" value="/home"/>
</attributes>
</instance_attributes>
</primitive>

3. 現在のcib.xmlに2.で作成したリソースを追加します。

# cibadmin -C -o resources -x /tmp/add.xml

リソースグループを定義している場合は上の方法ではなく、以下の方法になります。
3-1. /var/lib/heartbeat/crm/cib.xml を /tmp/cib.xmlにコピーして編集(2.の内容を組み込みます)
3-2. 以下のコマンドを実行します。

# cibadmin -U -x /tmp/cib.xml

当方の環境では問題無く動きましたが、設定は自己責任にてお願いします。