diff --git a/o2cb.ocf b/o2cb.ocf new file mode 100644 index 0000000..88f3e81 --- /dev/null +++ b/o2cb.ocf @@ -0,0 +1,456 @@ +#!/bin/bash +# 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. +# +# You should have received a copy of the GNU General Public License +# along with this program; if not, write the Free Software Foundation, +# Inc., 59 Temple Place - Suite 330, Boston MA 02111-1307, USA. +# +####################################################################### + +# OCF initialization +. ${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs + +# Parameter defaults +: ${OCF_RESKEY_stack:="pcmk"} +: ${OCF_RESKEY_sysfs:="/sys/fs"} +: ${OCF_RESKEY_daemon_timeout:="10"} +: ${OCF_RESKEY_configfs:="/sys/kernel/config"} +: ${OCF_RESKEY_CRM_meta_gloablly_unique:="false"} + +# Common variables +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=`pidofproc "$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 + + start_daemon "$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 + + # Dont unmount configfs - its 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 laoded" + 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() { + : TODO: check for gloablly_unique=true and return OCF_ERR_CONFIGURED + case ${OCF_RESKEY_CRM_meta_gloablly_unique} in + yes|Yes|true|True|1) + ocf_log err "$OCF_RESOURCE_INSTANCE must be configured with the gloablly_unique=false meta attribute" + exit $OCF_ERR_CONFIGURED + ;; + esac + + return $OCF_SUCCESS +} + +meta_data() { + cat < + + + 1.0 + pingd resource agent + +This is a pingd Resource Agent. +It records (in the CIB) the current number of ping nodes a node can connect to. + + + + + +Location where sysfs is mounted + + Sysfs location + + + + + +Location where configfs is mounted + + Configfs location + + + + + +Which userspace stack to use. Known values: pcmk, cman + + Userspace stack + + + + + +Number of seconds to allow the control daemon to come up + + Daemon Timeout + + + + + + + + + + + + +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 $? diff --git a/ocfs2-tools.changes b/ocfs2-tools.changes index 630b27a..224f1b7 100644 --- a/ocfs2-tools.changes +++ b/ocfs2-tools.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Wed Nov 12 11:25:01 CET 2008 - abeekhof@suse.de + +- Add an OCF-style script to allow Pacemaker to reliably manage the + ocfs2 modules. The existing LSB-style one is inadequate. + ------------------------------------------------------------------- Mon Oct 27 14:58:59 CET 2008 - abeekhof@suse.de diff --git a/ocfs2-tools.spec b/ocfs2-tools.spec index 806d855..a016950 100644 --- a/ocfs2-tools.spec +++ b/ocfs2-tools.spec @@ -22,10 +22,11 @@ Name: ocfs2-tools BuildRequires: e2fsprogs-devel glib2-devel libdlm-devel libopenais-devel libpacemaker-devel libxml2-devel libxslt-devel python-devel python-gtk-devel readline-devel update-desktop-files Summary: Oracle Cluster File System 2 Core Tools Version: 1.4.1 -Release: 4 +Release: 5 License: GPL v2 or later Group: System/Filesystems Source: ocfs2-tools.tar.bz2 +Source1: o2cb.ocf Patch5: ocfs2-tools-static-glib.diff Patch99: ocfs2-devel.diff Patch100: ocfs2-quota.diff @@ -103,17 +104,19 @@ make OPTS="$RPM_OPT_FLAGS" %install mkdir -p $RPM_BUILD_ROOT/sbin mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/init.d +mkdir -p ${RPM_BUILD_ROOT}/var/adm/fillup-templates mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/udev/rules.d/ +mkdir -p $RPM_BUILD_ROOT/usr/lib/ocf/resource.d/ocfs2 cp -f vendor/common/o2cb.init $RPM_BUILD_ROOT%{_sysconfdir}/init.d/o2cb cp -f vendor/common/ocfs2.init $RPM_BUILD_ROOT%{_sysconfdir}/init.d/ocfs2 -cp -f vendor/common/51-ocfs2.rules $RPM_BUILD_ROOT%{_sysconfdir}/udev/rules.d/ +cp -f vendor/common/51-ocfs2.rules $RPM_BUILD_ROOT%{_sysconfdir}/udev/rules.d +cp -f $RPM_SOURCE_DIR/o2cb.ocf $RPM_BUILD_ROOT/usr/lib/ocf/resource.d/ocfs2/o2cb +cp -f vendor/common/o2cb.sysconfig ${RPM_BUILD_ROOT}/var/adm/fillup-templates/sysconfig.o2cb ln -sf ..%{_sysconfdir}/init.d/o2cb $RPM_BUILD_ROOT/sbin/rco2cb ln -sf ..%{_sysconfdir}/init.d/ocfs2 $RPM_BUILD_ROOT/sbin/rcocfs2 -mkdir -p ${RPM_BUILD_ROOT}/var/adm/fillup-templates -cp -f vendor/common/o2cb.sysconfig ${RPM_BUILD_ROOT}/var/adm/fillup-templates/sysconfig.o2cb make DESTDIR="$RPM_BUILD_ROOT" install -mv $RPM_BUILD_ROOT/{,/usr}/sbin/debugfs.ocfs2 mv $RPM_BUILD_ROOT/{,/usr}/sbin/o2image +mv $RPM_BUILD_ROOT/{,/usr}/sbin/debugfs.ocfs2 mv $RPM_BUILD_ROOT/{,/usr}/sbin/ocfs2_controld.pcmk find $RPM_BUILD_ROOT -name '*.a' -type f -print0 | xargs -0 rm -f find $RPM_BUILD_ROOT -name '*.la' -type f -print0 | xargs -0 rm -f @@ -171,6 +174,10 @@ fi /var/adm/fillup-templates/sysconfig.o2cb %doc README.O2CB COPYING CREDITS MAINTAINERS %doc documentation/users_guide.txt +%dir /usr/lib/ocf +%dir /usr/lib/ocf/resource.d +%dir /usr/lib/ocf/resource.d/ocfs2 +/usr/lib/ocf/resource.d/ocfs2/o2cb %files -n ocfs2console %defattr(-,root,root) @@ -189,6 +196,9 @@ fi %{_libdir}/pkgconfig/ocfs2.pc %changelog +* Wed Nov 12 2008 abeekhof@suse.de +- Add an OCF-style script to allow Pacemaker to reliably manage the + ocfs2 modules. The existing LSB-style one is inadequate. * Mon Oct 27 2008 abeekhof@suse.de - Refresh package to upstream a93731c164d024e0016520a1f4cd8f9007d7c05e - Remove part of the static glib patch as tunefs.ocfs2 no longer uses glib @@ -265,7 +275,7 @@ fi - Should-Start: iscsi added (from SLES9) (#114733) * Wed Nov 02 2005 dmueller@suse.de - don't build as root -* Wed Nov 02 2005 jeffm@suse.com +* Tue Nov 01 2005 jeffm@suse.com - Update to version 1.1.3 - SVN 1105 * Mon Aug 22 2005 garloff@suse.de - Fix python defines.