From 2a11306aa51c34bd90fe331fae3077e412e65c50 Mon Sep 17 00:00:00 2001 From: "Fabio M. Di Nitto" Date: Tue, 15 Sep 2009 07:08:41 +0000 Subject: [PATCH] Add pacemaker resource agent for ocfs2 support --- o2cb_pcmk.diff | 460 +++++++++++++++++++++++++++++++++++++++++++++++ ocfs2-tools.spec | 13 +- 2 files changed, 472 insertions(+), 1 deletion(-) create mode 100644 o2cb_pcmk.diff diff --git a/o2cb_pcmk.diff b/o2cb_pcmk.diff new file mode 100644 index 0000000..58b5f99 --- /dev/null +++ b/o2cb_pcmk.diff @@ -0,0 +1,460 @@ +diff -Nuard ocfs2-tools-1.4.2.orig/vendor/common/o2cb.ocf ocfs2-tools-1.4.2/vendor/common/o2cb.ocf +--- ocfs2-tools-1.4.2.orig/vendor/common/o2cb.ocf 1970-01-01 01:00:00.000000000 +0100 ++++ ocfs2-tools-1.4.2/vendor/common/o2cb.ocf 2009-09-15 06:30:58.000000000 +0200 +@@ -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="/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" ++ ps axf | grep -C 3 $$ ++ 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 ++ o2cb resource agent ++ ++This is a o2cb Resource Agent. It runs o2cb daemon as a instance of anonymous clone. ++ ++ ++ ++ ++ ++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.spec b/ocfs2-tools.spec index a14933a..3974459 100644 --- a/ocfs2-tools.spec +++ b/ocfs2-tools.spec @@ -6,7 +6,7 @@ Summary: Tools for managing the Ocfs2 cluster file system Name: ocfs2-tools Version: 1.4.2 -Release: 3%{?alphatag:.%{alphatag}}%{?dist} +Release: 4%{?alphatag:.%{alphatag}}%{?dist} License: GPLv2 Group: System Environment/Base # The source for this package was pulled from upstream's git repo and manually @@ -20,6 +20,7 @@ Group: System Environment/Base # tar -czvf ocfs2-tools-1.3.9.tar.gz ocfs2-tools-1.3.9 Source0: %{name}-%{version}.tar.gz Patch0: minor_build_fixes.diff +Patch1: o2cb_pcmk.diff URL: http://oss.oracle.com/projects/ocfs2-tools/ Requires(post): chkconfig Requires(preun): chkconfig @@ -96,6 +97,7 @@ pacemaker cluster manager %prep %setup -q %patch0 -p1 +%patch1 -p1 %build %{configure} \ @@ -118,6 +120,10 @@ cp -f vendor/common/o2cb.sysconfig $RPM_BUILD_ROOT/etc/sysconfig/o2cb mkdir -p $RPM_BUILD_ROOT/etc/udev/rules.d cp -f vendor/common/51-ocfs2.rules \ $RPM_BUILD_ROOT/etc/udev/rules.d/51-ocfs2.rules +mkdir -p $RPM_BUILD_ROOT/usr/lib/ocf/resource.d/ocfs2 +cp -f vendor/common/o2cb.ocf \ + $RPM_BUILD_ROOT/usr/lib/ocf/resource.d/ocfs2/o2cb +chmod 0755 $RPM_BUILD_ROOT/usr/lib/ocf/resource.d/ocfs2/o2cb make DESTDIR="$RPM_BUILD_ROOT" install @@ -202,8 +208,13 @@ fi %files pcmk %defattr(-,root,root,-) /sbin/ocfs2_controld.pcmk +%dir /usr/lib/ocf/resource.d/ocfs2 +/usr/lib/ocf/resource.d/ocfs2 %changelog +* Tue Sep 15 2009 Fabio M. Di Nitto - 1.4.2-4 +- Add pcmk resource agent. + * Thu Sep 3 2009 Fabio M. Di Nitto - 1.4.2-3 - Fix pcmk and cman Requires.