Page MenuHomeClusterLabs Projects

No OneTemporary

diff --git a/heartbeat/Filesystem b/heartbeat/Filesystem
index 0206be924..153bb8938 100644
--- a/heartbeat/Filesystem
+++ b/heartbeat/Filesystem
@@ -1,513 +1,514 @@
#!/bin/sh
#
# Support: linux-ha@lists.linux-ha.org
# License: GNU General Public License (GPL)
#
# Filesystem
# Description: Manages a Filesystem on a shared storage medium.
# Original Author: Eric Z. Ayers (eric.ayers@compgen.com)
# Original Release: 25 Oct 2000
#
# usage: ./Filesystem {start|stop|status|monitor|validate-all|meta-data}
#
# OCF parameters are as below:
# OCF_RESKEY_device
# OCF_RESKEY_directory
# OCF_RESKEY_fstype
# OCF_RESKEY_options
#
#OCF_RESKEY_device : name of block device for the filesystem. e.g. /dev/sda1, /dev/md0
# Or a -U or -L option for mount, or an NFS mount specification
#OCF_RESKEY_directory : the mount point for the filesystem
#OCF_RESKEY_fstype : optional name of the filesystem type. e.g. ext2
#OCF_RESKEY_options : options to be given to the mount command via -o
#
#
# An example usage in /etc/ha.d/haresources:
# node1 10.0.0.170 Filesystem::/dev/sda1::/data1::ext2
# or
# node1 10.0.0.170 Filesystem::-Ldata1::/data1::ext2
# or
# node1 10.0.0.170 Filesystem::server:/data1::/data1::nfs::ro
#
# This assumes you want to manage a filesystem on a shared (scsi) bus.
# Do not put this filesystem in /etc/fstab. This script manages all of
# that for you.
#
# If you are interested in High Availability, you will probably also want
# some sort of external hardware RAID controller in front of the actual
# disks. I don't mean a RAID controller embedded in the host controller -
# it has to be an external controller.
#
# It can also be an internal RAID controller if the controller supports
# failover. IBM's ServeRAID controller does this, and it automatically
# prohibits concurrent access too, so it's pretty cool in this application.
#
# There is a script for software RAID-1 included in this directory. Right
# now, I wouldn't recommend using software RAID (see notes in the Raid1 script)
#
# NOTE: There is no locking (such as a SCSI reservation) being done here.
# I would if the SCSI driver could properly maintain the reservation,
# which it cannot, even with the 'scsi reservation' patch submitted
# earlier this year by James Bottomley. The patch minimizes the
# bus resets caused by a RESERVATION_CONFLICT return, and helps the
# reservation stay when 2 nodes contend for a reservation,
# but it does not attempt to recover the reservation in the
# case of a bus reset.
#
# What all this means is that if 2 nodes mount the same file system
# read-write, the filesystem is going to become corrupted.
#
# As a result, you should use this together with the stonith option
# and redundant, independent communications paths.
#
# If you don't do this, don't blame us when you scramble your disk.
#
# Note: the ServeRAID controller does prohibit concurrent acess
# In this case, you don't actually need STONITH, but redundant comm is
# still an excellent idea.
#
#######################################################################
# Initialization:
. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs
#######################################################################
HOSTOS=`uname`
usage() {
cat <<-EOT
usage: $0 {start|stop|status|monitor|validate-all|meta-data}
EOT
}
meta_data() {
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="Filesystem">
<version>1.0</version>
<longdesc lang="en">
Resource script for Filesystem. It manages a Filesystem on a shared storage medium.
</longdesc>
<shortdesc lang="en">Filesystem resource agent</shortdesc>
<parameters>
<parameter name="device" required="1">
<longdesc lang="en">
The name of block device for the filesystem, or -U, -L options for mount, or NFS mount specification.
</longdesc>
<shortdesc lang="en">block device</shortdesc>
<content type="string" default="" />
</parameter>
<parameter name="directory" required="1">
<longdesc lang="en">
The mount point for the filesystem.
</longdesc>
<shortdesc lang="en">mount point</shortdesc>
<content type="string" default="" />
</parameter>
<parameter name="fstype" required="1">
<longdesc lang="en">
The optional type of filesystem to be mounted.
</longdesc>
<shortdesc lang="en">filesystem type</shortdesc>
<content type="string" default="" />
</parameter>
<parameter name="options">
<longdesc lang="en">
Any extra options to be given as -o options to mount.
</longdesc>
<shortdesc lang="en">options</shortdesc>
<content type="string" default="" />
</parameter>
+</parameters>
<actions>
<action name="start" timeout="60" />
<action name="stop" timeout="60" />
<action name="notify" timeout="60" />
<action name="monitor" depth="0" timeout="40" interval="20" start-delay="10" />
<action name="validate-all" timeout="5" />
<action name="meta-data" timeout="5" />
</actions>
</resource-agent>
END
}
#
# Make sure the kernel does the right thing with the FS buffers
# This function should be called after unmounting and before mounting
# It may not be necessary in 2.4 and later kernels, but it shouldn't hurt
# anything either...
#
# It's really a bug that you have to do this at all...
#
flushbufs() {
if have_binary $BLOCKDEV ; then
if [ "$blockdevice" = "yes" ] ; then
$BLOCKDEV --flushbufs $1
return $?
fi
fi
return 0
}
# Take advantage of /etc/mtab if present, use portable mount command
# otherwise. Normalize format to "dev mountpoint fstype".
list_mounts() {
if [ -f "/etc/mtab" -a -r "/etc/mtab" ]; then
cut -d' ' -f1,2,3 </etc/mtab
else
$MOUNT | cut -d' ' -f1,3,5
fi
}
determine_blockdevice() {
if [ $blockdevice = "yes" ]; then
return
fi
# Get the current real device name, if possible.
# (specified devname could be -L or -U...)
case "$FSTYPE" in
nfs|smbfs|cifs) ;;
*) DEVICE=`list_mounts | grep " $MOUNTPOINT " | cut -d' ' -f1`
if [ -b "$DEVICE" ]; then
blockdevice=yes
fi
;;
esac
}
# Lists all filesystems potentially mounted under a given path,
# excluding the path itself.
list_submounts() {
list_mounts | grep " $1/" | cut -d' ' -f2 | sort -r
}
#
# START: Start up the filesystem
#
Filesystem_start()
{
# See if the device is already mounted.
if Filesystem_status >/dev/null 2>&1 ; then
ocf_log info "Filesystem $MOUNTPOINT is already mounted."
return $OCF_SUCCESS
fi
if [ "X${HOSTOS}" != "XOpenBSD" ];then
# Insert SCSI module
# TODO: This probably should go away. Why should the filesystem
# RA magically load a kernel module?
$MODPROBE scsi_hostadapter >/dev/null 2>&1
if [ -z "$FSTYPE" ]; then
: No FSTYPE specified, rely on the system has the right file-system support already
else
# Insert Filesystem module
$MODPROBE $FSTYPE >/dev/null 2>&1
grep -e "$FSTYPE"'$' /proc/filesystems >/dev/null
if [ $? -ne 0 ] ; then
ocf_log err "Couldn't find filesystem $FSTYPE in /proc/filesystems"
return $OCF_ERR_ARGS
fi
fi
fi
# Check the filesystem & auto repair.
# NOTE: Some filesystem types don't need this step... Please modify
# accordingly
if [ $blockdevice = "yes" ]; then
if [ "$DEVICE" != "/dev/null" -a ! -b "$DEVICE" ] ; then
ocf_log err "Couldn't find device [$DEVICE]. Expected /dev/??? to exist"
exit $OCF_ERR_ARGS
fi
if
case $FSTYPE in
ext3|reiserfs|reiser4|nss|xfs|jfs|vfat|fat|nfs|cifs|smbfs|ocfs2|gfs2|lustre) false;;
*) true;;
esac
then
ocf_log info "Starting filesystem check on $DEVICE"
if [ -z "$FSTYPE" ]; then
$FSCK -p $DEVICE
else
$FSCK -t $FSTYPE -p $DEVICE
fi
# NOTE: if any errors at all are detected, it returns non-zero
# if the error is >= 4 then there is a big problem
if [ $? -ge 4 ]; then
ocf_log err "Couldn't sucessfully fsck filesystem for $DEVICE"
return $OCF_ERR_GENERIC
fi
fi
fi
if [ ! -d "$MOUNTPOINT" ] ; then
ocf_log err "Couldn't find directory [$MOUNTPOINT] to use as a mount point"
exit $OCF_ERR_ARGS
fi
flushbufs $DEVICE
# Mount the filesystem.
if [ -z "$FSTYPE" ]; then
$MOUNT $options $DEVICE $MOUNTPOINT
else
$MOUNT -t $FSTYPE $options $DEVICE $MOUNTPOINT
fi
if [ $? -ne 0 ]; then
ocf_log err "Couldn't mount filesystem $DEVICE on $MOUNTPOINT"
return $OCF_ERR_GENERIC
fi
return 0
}
#
# STOP: Unmount the filesystem
#
Filesystem_stop()
{
# See if the device is currently mounted
Filesystem_status >/dev/null 2>&1
if [ $? -eq $OCF_NOT_RUNNING ]; then
# Already unmounted, wonderful.
rc=$OCF_SUCCESS
else
# Determine the real blockdevice this is mounted on (if
# possible) prior to unmounting.
determine_blockdevice
# For networked filesystems, there's merit in trying -f:
case "$FSTYPE" in
nfs|cifs|smbfs) umount_force="-f" ;;
esac
# Umount all sub-filesystems mounted under $MOUNTPOINT/ too.
for SUB in `list_submounts $MOUNTPOINT` $MOUNTPOINT; do
ocf_log info "Trying to unmount $MOUNTPOINT"
for sig in SIGTERM SIGTERM SIGTERM SIGKILL SIGKILL SIGKILL; do
if $UMOUNT $umount_force $SUB ; then
rc=$OCF_SUCCESS
ocf_log info "unmounted $SUB successfully"
break
else
rc=$OCF_ERR_GENERIC
ocf_log err "Couldn't unmount $SUB; trying cleanup with $sig"
# fuser returns a non-zero return code if none of the
# specified files is accessed or in case of a fatal
# error.
if [ "X${HOSTOS}" = "XOpenBSD" ];then
PIDS=`fstat | grep ${SUB} | awk '{print $3}'`
for PID in ${PIDS};do
kill -s 9 ${PID}
ocf_log info "Sent kill -9 to ${PID}"
done
else
if $FUSER -$sig -m -k $SUB ; then
ocf_log info "Some processes on $SUB were signalled"
else
ocf_log info "No processes on $SUB were signalled"
fi
fi
sleep 1
fi
done
if [ $rc -ne $OCF_SUCCESS ]; then
ocf_log err "Couldn't unmount $SUB, giving up!"
fi
done
fi
flushbufs $DEVICE
return $rc
}
# end of Filesystem_stop
#
# STATUS: is the filesystem mounted or not?
#
Filesystem_status()
{
if list_mounts | grep -q " $MOUNTPOINT " >/dev/null 2>&1; then
rc=$OCF_SUCCESS
msg="$MOUNTPOINT is mounted (running)"
else
rc=$OCF_NOT_RUNNING
msg="$MOUNTPOINT is unmounted (stopped)"
fi
# TODO: For ocfs2, or other cluster filesystems, should we be
# checking connectivity to other nodes here, or the IO path to
# the storage?
# Special case "monitor" to check whether the UUID cached and
# on-disk still match?
case "$OP" in
status) ocf_log info "$msg";;
esac
return $rc
}
# end of Filesystem_status
#
# VALIDATE_ALL: Are the instance parameters valid?
# FIXME!! The only part that's useful is the return code.
# This code always returns $OCF_SUCCESS (!)
#
Filesystem_validate_all()
{
if [ -n $MOUNTPOINT -a ! -d $MOUNTPOINT ]; then
ocf_log warn "Mountpoint $MOUNTPOINT does not exist"
fi
# Check if the $FSTYPE is workable
# NOTE: Without inserting the $FSTYPE module, this step may be imprecise
# TODO: This is Linux specific crap.
if [ ! -z "$FSTYPE" ]; then
cut -f2 /proc/filesystems |grep -q ^$FSTYPE$
if [ $? -ne 0 ]; then
modpath=/lib/modules/`uname -r`
moddep=$modpath/modules.dep
# Do we have $FSTYPE in modules.dep?
cut -d' ' -f1 $moddep |grep -q "^$modpath.*$FSTYPE\.k\?o:$"
if [ $? -ne 0 ]; then
ocf_log info "It seems we do not have $FSTYPE support"
fi
fi
fi
#TODO: How to check the $options ?
return $OCF_SUCCESS
}
# Check the arguments passed to this script
if [ $# -ne 1 ]; then
usage
exit $OCF_ERR_ARGS
fi
# Check the OCF_RESKEY_ environment variables...
DEVICE=$OCF_RESKEY_device
FSTYPE=$OCF_RESKEY_fstype
if [ ! -z "$OCF_RESKEY_options" ]; then
options="-o $OCF_RESKEY_options"
fi
OP=$1
# These operations do not require instance parameters
case $OP in
meta-data) meta_data
exit $OCF_SUCCESS
;;
usage) usage
exit $OCF_SUCCESS
;;
esac
blockdevice=no
case $DEVICE in
"") ocf_log err "Please set OCF_RESKEY_device to the device to be managed"
exit $OCF_ERR_ARGS
;;
-*) # Oh... An option to mount instead... Typically -U or -L
;;
[!/]*:/*) # An NFS filesystem specification...
;;
//[!/]*/*) # An SMB filesystem specification...
;;
/dev/null) # Special case for BSC
blockdevice=yes
;;
*) if [ ! -b "$DEVICE" -a ! -d "$DEVICE" -a "X$OP" != Xstart ] ; then
ocf_log warn "Couldn't find device [$DEVICE]. Expected /dev/??? to exist"
fi
if [ ! -d "$DEVICE" ];then
blockdevice=yes
fi
;;
esac
# Normalize instance parameters:
# It is possible that OCF_RESKEY_directory has one or even multiple trailing "/".
# But the output of `mount` and /proc/mounts do not.
if [ -z "$OCF_RESKEY_directory" ]; then
if [ X$OP = "Xstart" -o $blockdevice = "no" ]; then
ocf_log err "Please specify the directory"
exit $OCF_ERR_ARGS
fi
else
MOUNTPOINT=$(echo $OCF_RESKEY_directory | sed 's/\/*$//')
: ${MOUNTPOINT:=/}
# At this stage, $MOUNTPOINT does not contain trailing "/" unless it is "/"
# TODO: / mounted via Filesystem sounds dangerous. On stop, we'll
# kill the whole system. Is that a good idea?
fi
# Check to make sure the utilites are found
if [ "X${HOSTOS}" != "XOpenBSD" ];then
check_binary $MODPROBE
check_binary $FUSER
fi
check_binary $FSCK
check_binary $MOUNT
check_binary $UMOUNT
if [ "$OP" != "monitor" ]; then
ocf_log info "Running $OP for $DEVICE on $MOUNTPOINT"
fi
# These operations do not require the clone checking
case $OP in
status|monitor) Filesystem_status
exit $?
;;
validate-all) Filesystem_validate_all
exit $?
;;
stop) Filesystem_stop
exit $?
;;
esac
case $FSTYPE in
bind|nfs|ocfs2|gfs2) : # this is kind of safe too
;;
*) if [ -n "$OCF_RESKEY_CRM_meta_clone" ]; then
ocf_log err "DANGER! $FSTYPE on $DEVICE is NOT cluster-aware!"
ocf_log err "DO NOT RUN IT AS A CLONE!"
ocf_log err "Politely refusing to proceed to avoid data corruption."
exit $OCF_ERR_CONFIGURED
fi
;;
esac
case $OP in
start) Filesystem_start
;;
notify) Filesystem_notify
;;
*) usage
exit $OCF_ERR_UNIMPLEMENTED
;;
esac
exit $?

File Metadata

Mime Type
text/x-diff
Expires
Mon, Feb 24, 11:23 AM (19 h, 1 m ago)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1464161
Default Alt Text
(14 KB)

Event Timeline