Page Menu
Home
ClusterLabs Projects
Search
Configure Global Search
Log In
Files
F4511690
o2cb
No One
Temporary
Actions
Download File
Edit File
Delete File
View Transforms
Subscribe
Mute Notifications
Flag For Later
Award Token
Size
10 KB
Referenced Files
None
Subscribers
None
o2cb
View Options
#!/bin/bash
# Copyright (c) 2005,2008 Oracle
# Copyright (c) 2008 Andrew Beekhof
# All Rights Reserved.
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of version 2 of the GNU General Public License as
# published by the Free Software Foundation.
#
# This program is distributed in the hope that it would be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
#
# Further, this software is distributed without any warranty that it is
# free of the rightful claim of any third person regarding infringement
# or the like. Any license provided herein, whether implied or
# otherwise, applies only to this software file. Patent licenses, if
# any, provided herein do not apply to combinations of this program with
# other software, or any other product whatsoever.
#
#######################################################################
: ${OCF_FUNCTIONS=${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs}
. ${OCF_FUNCTIONS}
: ${__OCF_ACTION=$1}
: ${OCF_RESKEY_stack:="pcmk"}
: ${OCF_RESKEY_sysfs:="/sys/fs"}
: ${OCF_RESKEY_configfs:="/sys/kernel/config"}
: ${OCF_RESKEY_daemon_timeout:="10"} # How long to wait for things to start
: ${OCF_RESKEY_CRM_meta_globally_unique:="false"}
DAEMON="/usr/sbin/ocfs2_controld.${OCF_RESKEY_stack}"
CLUSTER_STACK_FILE="${OCF_RESKEY_sysfs}/ocfs2/cluster_stack"
LOADED_PLUGINS_FILE="${OCF_RESKEY_sysfs}/ocfs2/loaded_cluster_plugins"
#
# Check to see if a filesystem driver is loaded.
# 0 is loaded, 1 is not.
#
driver_filesystem() {
if [ -z "$1" ]
then
ocf_log err "driver_filesystem(): Missing an argument"
exit 1
fi
FSNAME="$1"
FSOUT="$(awk '(NF == 1 && $1 ~ /^'$FSNAME'$/) || $2 ~ /^'$FSNAME'$/{
print $1;exit
}' /proc/filesystems 2>/dev/null)"
test -n "$FSOUT"
return $?
}
#
# Check to see if a filesystem of type $1 is mounted at $2.
#
# 0 is mounted, 1 is not.
#
check_filesystem()
{
if [ "$#" != "2" -o -z "$1" -o -z "$2" ]
then
ocf_log err "check_filesystem(): Missing arguments"
exit 4
fi
FSNAME="$1"
MOUNTPOINT="$2"
FULL_MOUNTSEARCH="`echo "$MOUNTPOINT" | sed -e 's/\//\\\\\//g'`"
MOUNTOUT="`awk '$2 ~ /^'$FULL_MOUNTSEARCH'$/ && $3 ~ /^'$FSNAME'$/{print $2; exit}' < /proc/mounts 2>/dev/null`"
test -n "$MOUNTOUT"
return $?
}
#
# Unload a filesystem driver.
# Be careful to notice if the driver is built-in and do nothing.
#
# 0 is success, 1 is error, 2 is already unloaded.
#
unload_filesystem()
{
if [ "$#" != "1" -o -z "$1" ]
then
ocf_log err "unload_filesystem(): Missing an argument"
return 1
fi
FSNAME="$1"
driver_filesystem "$FSNAME" || return 2
MODOUT="`awk '$1 ~ /^'$FSNAME'$/{print $1,$3;exit}' < /proc/modules 2>/dev/null`"
if [ -z "$MODOUT" ]; then
# The driver is built in, we can't unload it.
return 0
fi
case "$MODOUT" in
$FSNAME\ 0)
;;
$FSNAME\ *)
# The driver is busy, leave it alone
ocf_log err "Module $FSNAME is still in use"
return 1
;;
*)
ocf_log err "Invalid module parsing! "
return 1
;;
esac
modprobe -rs "$FSNAME"
if [ "$?" != 0 ]; then
ocf_log err "Unable to unload module: $FSNAME"
return 1
fi
return 0
}
status_daemon()
{
PID=`pidof "$DAEMON"`
if [ -n "$PID" ]; then
return $OCF_SUCCESS
fi
return $OCF_NOT_RUNNING
}
bringup_daemon()
{
if [ ! -e "$DAEMON" ]; then
ocf_log err "Required binary not found: $DAEMON"
return $OCF_ERR_INSTALLED
fi
"$DAEMON"; rc=$?
if [ $rc != 0 ]; then
ocf_log err "Could not start $DAEMON"
return $OCF_ERR_GENERIC
fi
sleep 1
COUNT=0
rc=$OCF_NOT_RUNNING
while [ $rc = $OCF_NOT_RUNNING ]; do
COUNT=`expr $COUNT + 1`
if [ $COUNT -gt $OCF_RESKEY_daemon_timeout ]; then
ocf_log err "`basename $DAEMON` did not come up"
return $OCF_ERR_GENERIC
fi
status_daemon; rc=$?
sleep 1
done
return $rc
}
kill_daemon()
{
status_daemon; rc=$?
if [ $rc != $OCF_SUCCESS ]; then
return $rc
fi
ocf_log info "Stopping `basename "$DAEMON"`"
killproc "$DAEMON"
while [ $rc = $OCF_NOT_RUNNING ]; do
sleep 1
status_daemon; rc=$?
done
return $OCF_SUCCESS
}
#
# Unload a module
# 0 is success, 1 is error, 2 is not loaded
#
unload_module()
{
if [ "$#" -lt "1" -o -z "$1" ]
then
ocf_log err "unload_module(): Requires an argument"
return 1
fi
MODNAME="$1"
MODOUT="`awk '$1 ~ /^'$MODNAME'$/{print $1,$3;exit}' < /proc/modules 2>/dev/null`"
if [ -z "$MODOUT" ]
then
return 2
fi
case "$MODOUT" in
$MODNAME\ 0)
;;
$MODNAME\ *)
return 2
;;
*)
ocf_log err "Invalid module parsing!"
return 1
;;
esac
modprobe -rs "$MODNAME"
if [ "$?" != 0 ]; then
ocf_log err "Unable to unload module \"$MODNAME\""
return 1
fi
return 0
}
o2cb_start() {
o2cb_monitor; rc=$?
if [ $rc != $OCF_NOT_RUNNING ]; then
return $rc
fi
ocf_log info "Starting $OCF_RESOURCE_INSTANCE"
if [ ! -e "$CLUSTER_STACK_FILE" ]; then
modprobe -s ocfs2_stackglue
if [ $? != 0 ]; then
ocf_log err "Could not load ocfs2_stackglue"
return $OCF_ERR_INSTALLED
fi
fi
SP_OUT="$(awk '/^'user'$/{print; exit}' "$LOADED_PLUGINS_FILE" 2>/dev/null)"
if [ -z "$SP_OUT" ]
then
modprobe -s ocfs2_stack_user
if [ $? != 0 ]; then
ocf_log err "Could not load ocfs2_stack_user"
return $OCF_ERR_INSTALLED
fi
fi
SP_OUT="$(awk '/^'user'$/{print; exit}' "$LOADED_PLUGINS_FILE" 2>/dev/null)"
if [ -z "$SP_OUT" ]; then
ocf_log err "Switch to userspace stack unsuccessful"
return $OCF_ERR_INSTALLED
fi
if [ -f "$CLUSTER_STACK_FILE" ]; then
echo "$OCF_RESKEY_stack" >"$CLUSTER_STACK_FILE"
if [ $? != 0 ]; then
ocf_log err "Userspace stack '$OCF_RESKEY_stack' not supported"
return $OCF_ERR_INSTALLED
fi
else
ocf_log err "Switch to userspace stack not supported"
return $OCF_ERR_INSTALLED
fi
driver_filesystem ocfs2; rc=$?
if [ $rc != 0 ]; then
modprobe -s ocfs2
if [ "$?" != 0 ]; then
ocf_log err "Unable to load ocfs2 module"
return $OCF_ERR_INSTALLED
fi
fi
bringup_daemon
return $?
}
o2cb_stop() {
o2cb_monitor; rc=$?
case $rc in
$OCF_NOT_RUNNING) return $OCF_SUCCESS;;
esac
ocf_log info "Stopping $OCF_RESOURCE_INSTANCE"
kill_daemon
if [ $? != 0 ]; then
ocf_log err "Unable to unload modules: the cluster is still online"
return $OCF_ERR_GENERIC
fi
unload_filesystem ocfs2
if [ $? = 1 ]; then
ocf_log err "Unable to unload ocfs2 module"
return $OCF_ERR_GENERIC
fi
# If we can't find the stack glue, we have nothing to do.
[ ! -e "$LOADED_PLUGINS_FILE" ] && return $OCF_SUCCESS
while read plugin
do
unload_module "ocfs2_stack_${plugin}"
if [ $? = 1 ]; then
ocf_log err "Unable to unload ocfs2_stack_${plugin}"
return $OCF_ERR_GENERIC
fi
done <"$LOADED_PLUGINS_FILE"
unload_module "ocfs2_stackglue"
if [ $? = 1 ]; then
ocf_log err "Unable to unload ocfs2_stackglue"
return $OCF_ERR_GENERIC
fi
# Don't unmount configfs - it's always in use by libdlm
}
o2cb_monitor() {
o2cb_validate
# Assume that ocfs2_controld will terminate if any of the conditions below are met
driver_filesystem configfs; rc=$?
if [ $rc != 0 ]; then
ocf_log info "configfs not loaded"
return $OCF_NOT_RUNNING
fi
check_filesystem configfs "${OCF_RESKEY_configfs}"; rc=$?
if [ $rc != 0 ]; then
ocf_log info "configfs not mounted"
return $OCF_NOT_RUNNING
fi
if [ ! -e "$LOADED_PLUGINS_FILE" ]; then
ocf_log info "Stack glue driver not loaded"
return $OCF_NOT_RUNNING
fi
grep user "$LOADED_PLUGINS_FILE" >/dev/null 2>&1; rc=$?
if [ $rc != 0 ]; then
ocf_log err "Wrong stack `cat $LOADED_PLUGINS_FILE`"
return $OCF_ERR_INSTALLED
fi
driver_filesystem ocfs2; rc=$?
if [ $rc != 0 ]; then
ocf_log info "ocfs2 not loaded"
return $OCF_NOT_RUNNING
fi
status_daemon
return $?
}
o2cb_usage() {
echo "usage: $0 {start|stop|monitor|validate-all|meta-data}"
echo " Expects to have a fully populated OCF RA-compliant environment set."
echo " In particualr, a value for OCF_ROOT"
}
o2cb_validate() {
check_binary ${DAEMON}
case ${OCF_RESKEY_CRM_meta_globally_unique} in
yes|Yes|true|True|1)
ocf_log err "$OCF_RESOURCE_INSTANCE must be configured with the globally_unique=false meta attribute"
exit $OCF_ERR_CONFIGURED
;;
esac
return $OCF_SUCCESS
}
meta_data() {
cat <<END
<?xml version="1.0"?>
<!DOCTYPE resource-agent SYSTEM "ra-api-1.dtd">
<resource-agent name="o2cb" version="1.0">
<version>1.0</version>
<shortdesc lang="en">OCFS2 daemon resource agent</shortdesc>
<longdesc lang="en">
This Resource Agent controls the userspace daemon needed by OCFS2.
</longdesc>
<parameters>
<parameter name="sysfs" unique="0">
<longdesc lang="en">
Location where sysfs is mounted
</longdesc>
<shortdesc lang="en">Sysfs location</shortdesc>
<content type="string" default="/sys/fs"/>
</parameter>
<parameter name="configfs" unique="0">
<longdesc lang="en">
Location where configfs is mounted
</longdesc>
<shortdesc lang="en">Configfs location</shortdesc>
<content type="string" default="/sys/kernel/config"/>
</parameter>
<parameter name="stack" unique="0">
<longdesc lang="en">
Which userspace stack to use. Known values: pcmk
</longdesc>
<shortdesc lang="en">Userspace stack</shortdesc>
<content type="string" default="pcmk"/>
</parameter>
<parameter name="daemon_timeout" unique="0">
<longdesc lang="en">
Number of seconds to allow the control daemon to come up
</longdesc>
<shortdesc lang="en">Daemon Timeout</shortdesc>
<content type="string" default="10"/>
</parameter>
</parameters>
<actions>
<action name="start" timeout="90" />
<action name="stop" timeout="100" />
<action name="monitor" timeout="20" depth="0"/>
<action name="meta-data" timeout="5" />
<action name="validate-all" timeout="30" />
</actions>
</resource-agent>
END
}
case $__OCF_ACTION in
meta-data) meta_data
exit $OCF_SUCCESS
;;
start) o2cb_start
;;
stop) o2cb_stop
;;
monitor) o2cb_monitor
;;
validate-all) o2cb_validate
;;
usage|help) o2cb_usage
exit $OCF_SUCCESS
;;
*) o2cb_usage
exit $OCF_ERR_UNIMPLEMENTED
;;
esac
exit $?
File Metadata
Details
Attached
Mime Type
text/x-shellscript
Expires
Wed, Jun 25, 2:12 AM (9 h, 35 m)
Storage Engine
blob
Storage Format
Raw Data
Storage Handle
1951828
Default Alt Text
o2cb (10 KB)
Attached To
Mode
rP Pacemaker
Attached
Detach File
Event Timeline
Log In to Comment