diff --git a/extra/resources/controld b/extra/resources/controld index e74dc49ae1..ed43326df9 100755 --- a/extra/resources/controld +++ b/extra/resources/controld @@ -1,292 +1,292 @@ #!/bin/sh # # ocf:pacemaker:controld resource agent # # Copyright 2008-2021 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # (GPLv2) WITHOUT ANY WARRANTY. # # Manages the DLM controld process # ####################################################################### # Initialization: : ${OCF_FUNCTIONS:="${OCF_ROOT}/resource.d/heartbeat/.ocf-shellfuncs"} . "${OCF_FUNCTIONS}" : ${__OCF_ACTION:="$1"} # Explicitly list all environment variables used, to make static analysis happy : ${OCF_RESKEY_CRM_meta_globally_unique:="false"} : ${OCF_RESKEY_allow_stonith_disabled:="false"} : ${OCF_RESKEY_sctp:="false"} : ${OCF_RESOURCE_INSTANCE:=""} case "$OCF_RESOURCE_INSTANCE" in *[gG][fF][sS]*) : ${OCF_RESKEY_args=-g 0} : ${OCF_RESKEY_daemon:=gfs_controld} ;; *[dD][lL][mM]*) : ${OCF_RESKEY_args=-s 0} : ${OCF_RESKEY_daemon:=dlm_controld} ;; *) : ${OCF_RESKEY_args=-s 0} : ${OCF_RESKEY_daemon:=dlm_controld} esac ####################################################################### if [ -e "$OCF_ROOT/resource.d/heartbeat/controld" ]; then ocf_log info "Using heartbeat controld agent" "$OCF_ROOT/resource.d/heartbeat/controld" "$1" exit $? fi meta_data() { cat < 1.0 This Resource Agent can control the dlm_controld services needed by cluster-aware file systems. It assumes that dlm_controld is in your default PATH. In most cases, it should be run as an anonymous clone. DLM Agent for cluster file systems Any additional options to start the dlm_controld service with DLM Options The daemon to start - supports gfs_controld and dlm_controld The daemon to start Allow DLM start-up even if STONITH/fencing is disabled in the cluster. Setting this option to true will cause cluster malfunction and hangs on fail-over for DLM clients that require fencing (such as GFS2, OCFS2, and cLVM2). This option is advanced use only. Allow start-up even without STONITH/fencing END } ####################################################################### CONFIGFS_DIR="/sys/kernel/config" DLM_CONFIGFS_DIR="${CONFIGFS_DIR}/dlm" DLM_SYSFS_DIR="/sys/kernel/dlm" controld_usage() { cat <&1) if [ $? -eq 0 ]; then if [ -n "$CUL_TMP" ]; then ocf_log err "Uncontrolled lockspace exists, system must reboot. Executing suicide fencing" stonith_admin --reboot="$(crm_node -n)" --tag controld exit $OCF_ERR_GENERIC fi fi } controld_start() { controld_monitor; rc=$? case $rc in - $OCF_SUCCESS) return $OCF_SUCCESS;; - $OCF_NOT_RUNNING) ;; + "$OCF_SUCCESS") return $OCF_SUCCESS;; + "$OCF_NOT_RUNNING") ;; *) return $OCF_ERR_GENERIC;; esac # Ensure configfs is mounted if [ ! -e "$CONFIGFS_DIR" ]; then modprobe configfs if [ ! -e "$CONFIGFS_DIR" ]; then ocf_log err "$CONFIGFS_DIR not available" return $OCF_ERR_INSTALLED fi fi mount -t configfs | grep " $CONFIGFS_DIR " >/dev/null 2>/dev/null if [ $? -ne 0 ]; then mount -t configfs none "$CONFIGFS_DIR" fi # Ensure DLM is available if [ ! -e "$DLM_CONFIGFS_DIR" ]; then modprobe dlm if [ ! -e "$DLM_CONFIGFS_DIR" ]; then ocf_log err "$DLM_CONFIGFS_DIR not available" return $OCF_ERR_INSTALLED fi fi if ! ocf_is_true "$OCF_RESKEY_allow_stonith_disabled" && \ ! ocf_is_true "$(crm_attribute --type=crm_config --name=stonith-enabled --query --quiet --default=true)"; then ocf_log err "The cluster property stonith-enabled may not be deactivated to use the DLM" return $OCF_ERR_CONFIGURED fi "${OCF_RESKEY_daemon}" $OCF_RESKEY_args while true do sleep 1 controld_monitor; rc=$? case $rc in - $OCF_SUCCESS) + "$OCF_SUCCESS") CS_ADDR_LIST="$(cat "${DLM_CONFIGFS_DIR}"/cluster/comms/*/addr_list 2>/dev/null)" if [ $? -eq 0 ] && [ -n "$CS_ADDR_LIST" ]; then return $OCF_SUCCESS fi ;; - $OCF_NOT_RUNNING) + "$OCF_NOT_RUNNING") return $OCF_NOT_RUNNING ;; *) return $OCF_ERR_GENERIC ;; esac ocf_log debug "Waiting for ${OCF_RESKEY_daemon} to be ready" done } controld_stop() { controld_monitor; rc=$? if [ $rc -eq $OCF_NOT_RUNNING ]; then return $OCF_SUCCESS fi killall -TERM "${OCF_RESKEY_daemon}"; rc=$? if [ $rc -ne 0 ]; then return $OCF_ERR_GENERIC fi rc=$OCF_SUCCESS while [ $rc -eq $OCF_SUCCESS ]; do controld_monitor; rc=$? sleep 1 done if [ $rc -eq $OCF_NOT_RUNNING ]; then rc=$OCF_SUCCESS fi return $rc } controld_monitor() { killall -0 ${OCF_RESKEY_daemon} >/dev/null 2>&1 ; CM_RC=$? case $CM_RC in 0) smw=$(dlm_tool status -v | grep "stateful_merge_wait=" | cut -d= -f2) if [ -n "$smw" ] && [ $smw -eq 1 ]; then ocf_log err "DLM status is: stateful_merge_wait" CM_RC=$OCF_ERR_GENERIC elif [ -z "$smw" ] && dlm_tool ls | grep -q "wait fencing" && \ ! stonith_admin -H '*' --output-as xml | grep -q "extended-status=\"pending\""; then ocf_log err "DLM status is: wait fencing" CM_RC=$OCF_ERR_GENERIC else CM_RC=$OCF_SUCCESS fi ;; 1) CM_RC=$OCF_NOT_RUNNING;; *) CM_RC=$OCF_ERR_GENERIC;; esac # if the dlm is not successfully running, but # dlm lockspace bits are left over, we self must fence. if [ $CM_RC -ne $OCF_SUCCESS ]; then check_uncontrolled_locks fi return $CM_RC } controld_validate() { check_binary killall check_binary "${OCF_RESKEY_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 [ -d /var/run/cluster ] || mkdir /var/run/cluster return $OCF_SUCCESS } case "$__OCF_ACTION" in meta-data) meta_data exit $OCF_SUCCESS ;; start) controld_validate; controld_start;; stop) controld_stop;; monitor) controld_validate; controld_monitor;; validate-all) controld_validate;; usage|help) controld_usage exit $OCF_SUCCESS ;; *) controld_usage exit $OCF_ERR_UNIMPLEMENTED ;; esac rc=$? exit $rc # vim: set filetype=sh expandtab tabstop=4 softtabstop=4 shiftwidth=4 textwidth=80: diff --git a/extra/resources/o2cb.in b/extra/resources/o2cb.in index c4edc3482a..c5a69dca22 100755 --- a/extra/resources/o2cb.in +++ b/extra/resources/o2cb.in @@ -1,441 +1,441 @@ #!@BASH_PATH@ # # ocf:pacemaker:o2cb resource agent # # Original copyright 2005-2008 Oracle # Later changes copyright 2008-2021 the Pacemaker project contributors # # The version control history for this file may have further details. # # This source code is licensed under the GNU General Public License version 2 # (GPLv2) WITHOUT ANY WARRANTY. # ####################################################################### : ${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 [ $# -ne 2 ] || [ -z "$1" ] || [ -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 [ $# -ne 1 ] || [ -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 0") ;; - $FSNAME\ *) + "$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 [ $? -ne 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 -ne 0 ]; then ocf_log err "Could not start $DAEMON" return $OCF_ERR_GENERIC fi sleep 1 COUNT=0 rc=$OCF_NOT_RUNNING while [ $rc -eq $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 -ne $OCF_SUCCESS ]; then return $rc fi ocf_log info "Stopping $(basename "$DAEMON")" killproc "$DAEMON" while [ $rc -eq $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 ] || [ -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 0") ;; - $MODNAME\ *) + "$MODNAME "*) return 2 ;; *) ocf_log err "Invalid module parsing!" return 1 ;; esac modprobe -rs "$MODNAME" if [ $? -ne 0 ]; then ocf_log err "Unable to unload module \"$MODNAME\"" return 1 fi return 0 } o2cb_start() { o2cb_monitor; rc=$? if [ $rc -ne $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 [ $? -ne 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 [ $? -ne 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 [ $? -ne 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 -ne 0 ]; then modprobe -s ocfs2 if [ $? -ne 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;; + "$OCF_NOT_RUNNING") return $OCF_SUCCESS;; esac ocf_log info "Stopping $OCF_RESOURCE_INSTANCE" kill_daemon if [ $? -ne 0 ]; then ocf_log err "Unable to unload modules: the cluster is still online" return $OCF_ERR_GENERIC fi unload_filesystem ocfs2 if [ $? -eq 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 [ $? -eq 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 [ $? -eq 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 -ne 0 ]; then ocf_log info "configfs not loaded" return $OCF_NOT_RUNNING fi check_filesystem configfs "${OCF_RESKEY_configfs}"; rc=$? if [ $rc -ne 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 -ne 0 ]; then ocf_log err "Wrong stack $(cat $LOADED_PLUGINS_FILE)" return $OCF_ERR_INSTALLED fi driver_filesystem ocfs2; rc=$? if [ $rc -ne 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 < 1.0 OCFS2 daemon resource agent This Resource Agent controls the userspace daemon needed by OCFS2. Location where sysfs is mounted Sysfs location Location where configfs is mounted Configfs location Which userspace stack to use. Known values: pcmk 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 $? # vim: set filetype=sh expandtab tabstop=4 softtabstop=4 shiftwidth=4 textwidth=80: