File: //proc/thread-self/root/lib/check_mk_agent/plugins/mk_informix
#!/bin/bash
# Copyright (C) 2019 Checkmk GmbH - License: GNU General Public License v2
# This file is part of Checkmk (https://checkmk.com). It is subject to the terms and
# conditions defined in the file COPYING, which is part of this source code package.
# Reason for this no-op: shellcheck disable=... before the first command disables the error for the
# entire script.
:
# Disable unused variable error (needed to keep track of version)
# shellcheck disable=SC2034
CMK_VERSION="2.3.0p38"
# Informix
# Make ENV-VARs avail for subshells
set -a
# .--helper--------------------------------------------------------------.
# | _ _ |
# | | |__ ___| |_ __ ___ _ __ |
# | | '_ \ / _ \ | '_ \ / _ \ '__| |
# | | | | | __/ | |_) | __/ | |
# | |_| |_|\___|_| .__/ \___|_| |
# | |_| |
# '----------------------------------------------------------------------'
# BEGIN COMMON PLUGIN CODE
# check that no users other than root can change the file
only_root_can_modify() {
permissions=$1
owner=$2
group=$3
group_write_perm=$(echo "$permissions" | cut -c 6)
other_write_perm=$(echo "$permissions" | cut -c 9)
if [ "$owner" != "root" ] || [ "$other_write_perm" != "-" ]; then
return 1
fi
[ "$group" = "root" ] || [ "$group_write_perm" = "-" ]
}
get_binary_owner() {
BINARY_PATH=$1
stat -c '%U' "${BINARY_PATH}"
}
get_binary_execution_mode() {
BINARY_PATH=$1
BINARY_USER=$2
# if the executable belongs to someone besides root, do not execute it as root
if needs_user_switch_before_executing "$BINARY_PATH"; then
echo "su ${BINARY_USER} -c"
return
fi
echo "bash -c"
}
needs_user_switch_before_executing() {
BINARY_PATH=$1
[ "$(whoami)" = "root" ] && ! only_root_can_modify "$(stat -c '%A' "$BINARY_PATH")" "$(stat -c '%U' "$BINARY_PATH")" "$(stat -c '%G' "$BINARY_PATH")"
}
# END COMMON PLUGIN CODE
set_env() {
# set environment variables given in the form VARNAME1=value1;VARNAME2=value2;...
while IFS=';' read -ra parts; do
for part in "${parts[@]}"; do
var_name="${part%%=*}"
var_value="${part#*=}"
export "$var_name"="$var_value"
done
done <<<"$1"
}
do_check() {
# $1:section, $2:excludelist
if echo "$2" | grep -qe "${1}"; then
return 1
else
return 0
fi
}
sql() {
sqltxt="$1"
export DBDELIMITER="|"
echo "$sqltxt" | $EXECUTION_MODE "$INFORMIXDIR/bin/dbaccess sysmaster"
}
set_excludes() {
exclude=""
if [ "$EXCLUDES" = "ALL" ]; then
exclude="$all_sections"
global_exclude=true
elif [ -n "$EXCLUDES" ]; then
exclude=$EXCLUDES
global_exclude=true
else
global_exclude=false
fi
if [ "$global_exclude" = "false" ]; then
excludes_i="EXCLUDES_${1}"
if [ "${!excludes_i}" = "ALL" ]; then
exclude="$all_sections"
elif [ -n "${!excludes_i}" ]; then
exclude=${!excludes_i}
fi
fi
}
#.
# .--sqls----------------------------------------------------------------.
# | _ |
# | ___ __ _| |___ |
# | / __|/ _` | / __| |
# | \__ \ (_| | \__ \ |
# | |___/\__, |_|___/ |
# | |_| |
# '----------------------------------------------------------------------'
all_sections="sessions locks tabextents dbspaces logusage"
informix_status() {
echo "<<<informix_status:sep(58)>>>"
echo "[[[$INFORMIXSERVER/$SERVERNUM]]]"
$EXECUTION_MODE "\"$INFORMIXDIR\"/bin/onstat -" >/dev/null 2>&1
state=$?
echo "Status:"$state
$EXECUTION_MODE "\"$INFORMIXDIR\"/bin/onstat -g dis"
port=$(grep "$INFORMIXSERVER" /etc/services)
echo "PORT:$port"
}
informix_sessions() {
echo "<<<informix_sessions>>>"
echo "[[[$INFORMIXSERVER/$SERVERNUM]]]"
# don't count our own session
sql "select 'SESSIONS', (count(*)-1)::int from syssessions"
}
informix_locks() {
echo "<<<informix_locks>>>"
echo "[[[$INFORMIXSERVER/$SERVERNUM]]]"
# don't count our own session
sql "select 'LOCKS', (count(*)-1)::int, type from syslocks group by type"
}
informix_tabextents() {
echo "<<<informix_tabextents>>>"
echo "[[[$INFORMIXSERVER/$SERVERNUM]]]"
sql "select first 10
'TABEXTENTS',
trim(n.dbsname) db,
trim(n.tabname) tab,
h.nextns extents,
nrows
from sysptnhdr h, systabnames n
where h.partnum = n.partnum
and nrows > 0
and n.dbsname not in ( 'sysadmin', 'sysuser', 'sysutils', 'sysmaster' )
and n.tabname not like 'sys%'
order by extents desc"
}
informix_dbspaces() {
# the default dbspace pagesize must be taken to calculate the used and free space
echo "<<<informix_dbspaces>>>"
echo "[[[$INFORMIXSERVER/$SERVERNUM]]]"
sql "select
trim(sd.name) || ' DBSPACE',
sd.dbsnum,
sd.is_temp,
sd.flags sd_flags,
'CHUNK',
sc.fname,
(select sh_pagesize from sysmaster:sysshmvals) system_pagesize,
sc.pagesize,
sc.chksize,
sc.nfree,
sc.flags chunk_flags,
trim(sc.mfname),
sc.mflags
from sysdbspaces sd, syschunks sc
where sd.dbsnum = sc.dbsnum
-- NO SBSPACE CURRENTLY
and sd.is_sbspace = 0
order by sd.name"
}
informix_logusage() {
echo "<<<informix_logusage>>>"
echo "[[[$INFORMIXSERVER/$SERVERNUM]]]"
sql "select 'LOGUSAGE',
number,
sh_pagesize,
size,
used,
flags,
'is_used:'||is_used,
'is_current:'||is_current,
'is_backed_up:'||is_backed_up,
'is_new:'||is_new,
'is_archived:'||is_archived,
'is_temp:'||is_temp,
'is_pre_dropped:'||is_pre_dropped
from syslogs, sysshmvals
order by number"
}
#.
# .--config--------------------------------------------------------------.
# | __ _ |
# | ___ ___ _ __ / _(_) __ _ |
# | / __/ _ \| '_ \| |_| |/ _` | |
# | | (_| (_) | | | | _| | (_| | |
# | \___\___/|_| |_|_| |_|\__, | |
# | |___/ |
# '----------------------------------------------------------------------'
# Config opts:
# - oninit-path; Default is empty, which means autodetection:
# ONINIT_PATH=<path to oninit-binary>
# - Excluding sections ("status sessions locks tabextents dbspaces logusage"):
# EXCLUDES_INFORMIX_INSTANCE="SECTION SECTION ..."
# EXCLUDES_INFORMIX_INSTANCE=ALL
# EXCLUDES="SECTION SECTION ..."
# EXCLUDES=ALL
# shellcheck disable=SC1091 # TODO: add a configuration example and remove this suppression
# shellcheck source=agents/cfg_examples/informix.cfg
. "$MK_CONFDIR/informix.cfg" 2>/dev/null
if [ -z "$ONINIT_PATH" ] || [ ! -x "$ONINIT_PATH" ]; then
ONINIT=$(UNIX95=true ps ax | grep oninit | grep -v grep | head -1 | awk '{print $1 " " $5}')
if [ -z "$ONINIT" ]; then
exit 0
fi
ONINIT_PATH=${ONINIT#* }
ONINIT_PID=${ONINIT% *}
case "$ONINIT_PATH" in
/*) ;;
*) # BUG not platform independent!
ONINIT_PATH=$(readlink "/proc/$ONINIT_PID/exe")
;;
esac
# If not set in config or not found we end up here
if [ -z "$ONINIT_PATH" ] || [ ! -f "$ONINIT_PATH" ]; then
exit 1
fi
fi
#.
# .--main----------------------------------------------------------------.
# | _ |
# | _ __ ___ __ _(_)_ __ |
# | | '_ ` _ \ / _` | | '_ \ |
# | | | | | | | (_| | | | | | |
# | |_| |_| |_|\__,_|_|_| |_| |
# | |
# '----------------------------------------------------------------------'
INFORMIXDIR=${ONINIT_PATH%/bin*}
if [ ! -f "$INFORMIXDIR/bin/onstat" ]; then
exit 1
fi
EXECUTION_MODE="$(get_binary_execution_mode "$INFORMIXDIR/bin/onstat" "$(get_binary_owner "$INFORMIXDIR/bin/onstat")")"
for IDSENV in $(
$EXECUTION_MODE "$INFORMIXDIR/bin/onstat -g dis" |
grep -E '^Server[ ]*:|^Server Number[ ]*:|^INFORMIX|^SQLHOSTS|^ONCONFIG' |
sed -e 's/Server Number/SERVERNUM/' \
-e 's/Server/INFORMIXSERVER/' \
-e 's/SQLHOSTS/INFORMIXSQLHOSTS/' \
-e 's/[ ]*:[ ]*/=/' |
tr '\n' ';' |
sed -e 's/;$/\n/' -e 's/;\(INFORMIXSERVER=[^;]*;\)/\n\1/g'
); do
(
set_env "$IDSENV"
# try to set them via 'onstat -g env' otherwise
# DB HAS TO BE RUNNING
if [ -z "$INFORMIXSQLHOSTS" ] || [ -z "$ONCONFIG" ]; then
$EXECUTION_MODE "$INFORMIXDIR/bin/onstat -g env" | grep -E -e '^INFORMIXSQLHOSTS' \
-e '^ONCONFIG' |
sed -e 's/[ ][ ]*/=/'
fi
informix_status
set_excludes "$INFORMIXSERVER"
if do_check "sessions" "$exclude"; then
informix_sessions
fi
if do_check "locks" "$exclude"; then
informix_locks
fi
if do_check "tabextents" "$exclude"; then
informix_tabextents
fi
if do_check "dbspaces" "$exclude"; then
informix_dbspaces
fi
if do_check "logusage" "$exclude"; then
informix_logusage
fi
)
done