#!/bin/sh # ctdb event script for checking local file system utilization [ -n "$CTDB_BASE" ] || \ export CTDB_BASE=$(cd -P $(dirname "$0") ; dirname "$PWD") . $CTDB_BASE/functions loadconfig validate_percentage () { case "$1" in "") return 1 ;; # A failure that doesn't need a warning [0-9]|[0-9][0-9]|100) return 0 ;; *) echo "WARNING: ${1} is an invalid percentage${2:+ in \"}${2}${2:+\"} check" return 1 esac } check_thresholds () { _thing="$1" _thresholds="$2" _usage="$3" case "$_thresholds" in *:*) _warn_threshold="${_thresholds%:*}" _unhealthy_threshold="${_thresholds#*:}" ;; *) _warn_threshold="$_thresholds" _unhealthy_threshold="" esac if validate_percentage "$_unhealthy_threshold" "$_thing" ; then if [ "$_usage" -ge "$_unhealthy_threshold" ] ; then die "ERROR: ${_thing} utilization ${_usage}% >= threshold ${_unhealthy_threshold}%" fi fi if validate_percentage "$_warn_threshold" "$_what" ; then if [ "$_usage" -ge "$_warn_threshold" ] ; then echo "WARNING: ${_thing} utilization ${_usage}% >= threshold ${_warn_threshold}%" fi fi } monitor_filesystem_usage () { # Check each specified filesystem, specified in format # :[:fs_unhealthy_threshold] for _fs in $CTDB_MONITOR_FILESYSTEM_USAGE ; do _fs_mount="${_fs%%:*}" _fs_thresholds="${_fs#*:}" if [ ! -d "$_fs_mount" ]; then echo "WARNING: Directory ${_fs_mount} does not exist" continue fi # Get current utilization _fs_usage=$(df -kP "$_fs_mount" | \ sed -n -e 's@.*[[:space:]]\([[:digit:]]*\)%.*@\1@p') if [ -z "$_fs_usage" ] ; then echo "WARNING: Unable to get FS utilization for ${_fs_mount}" continue fi check_thresholds "Filesystem ${_fs_mount}" \ "$_fs_thresholds" \ "$_fs_usage" done } monitor_memory_usage () { if [ -z "$CTDB_MONITOR_FREE_MEMORY_WARN" -a \ -z "$CTDB_MONITOR_FREE_MEMORY" -a \ "$CTDB_CHECK_SWAP_IS_NOT_USED" != "yes" ] ; then return fi _meminfo=$(get_proc "meminfo") set -- $(echo "$_meminfo" | awk ' $1 == "MemAvailable:" { memavail += $2 } $1 == "MemFree:" { memfree += $2 } $1 == "Cached:" { memfree += $2 } $1 == "Buffers:" { memfree += $2 } $1 == "MemTotal:" { memtotal = $2 } $1 == "SwapFree:" { swapfree = $2 } $1 == "SwapTotal:" { swaptotal = $2 } END { if (memavail != 0) { memfree = memavail ; } print int((memtotal - memfree) / memtotal * 100), int((swaptotal - swapfree) / swaptotal * 100) }') _mem_usage="$1" _swap_usage="$2" # Shutdown CTDB when memory is below the configured limit if [ -n "$CTDB_MONITOR_FREE_MEMORY" ] ; then if [ $_mem_usage -ge $CTDB_MONITOR_FREE_MEMORY ] ; then echo "CRITICAL: OOM - ${_mem_usage}% usage >= ${CTDB_MONITOR_FREE_MEMORY}% (CTDB threshold)" echo "CRITICAL: Shutting down CTDB!!!" echo "$_meminfo" ps auxfww set_proc "sysrq-trigger" "m" ctdb disable sleep 3 ctdb shutdown fi fi # Warn when low on memory if [ -n "$CTDB_MONITOR_FREE_MEMORY_WARN" ] ; then if [ $_mem_usage -ge $CTDB_MONITOR_FREE_MEMORY_WARN ] ; then echo "WARNING: memory usage is excessive - ${_mem_usage}% >= ${CTDB_MONITOR_FREE_MEMORY_WARN}% (CTDB threshold)" fi fi # We should never enter swap, so SwapTotal == SwapFree. if [ "$CTDB_CHECK_SWAP_IS_NOT_USED" = "yes" ] ; then if [ $_swap_usage -gt 0 ] ; then echo We are swapping: echo "$_meminfo" ps auxfww fi fi } case "$1" in monitor) monitor_filesystem_usage monitor_memory_usage ;; *) ctdb_standard_event_handler "$@" ;; esac exit 0