#!/bin/sh # # ocf:pacemaker:controld resource agent # # Copyright 2008-2023 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.1 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") ;; *) return $OCF_ERR_GENERIC;; esac # Ensure @runstatedir@/cluster exists [ -d "@runstatedir@/cluster" ] || mkdir "@runstatedir@/cluster" # 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 # If no-quorum-policy not set, or not set as freeze, give a warning crm_attribute --type=crm_config --name=no-quorum-policy --query|grep value=freeze >/dev/null 2>/dev/null if [ $? -ne 0 ]; then ocf_log warn "The DLM cluster best practice suggests to set the cluster property \"no-quorum-policy=freeze\"" fi "${OCF_RESKEY_daemon}" $OCF_RESKEY_args while true do sleep 1 controld_monitor; rc=$? case $rc in "$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") 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() { case "${OCF_RESKEY_CRM_meta_globally_unique}" in [Tt][Rr][Uu][Ee] | [Oo][Nn] | [Yy][Ee][Ss] | [Yy] | 1) msg="The globally-unique meta attribute must not be enabled for" msg="$msg $OCF_RESOURCE_INSTANCE" ocf_log err "$msg" exit $OCF_ERR_CONFIGURED ;; esac # Host-specific checks if [ "$OCF_CHECK_LEVEL" = "10" ]; then check_binary killall check_binary "${OCF_RESKEY_daemon}" fi 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: