SHARE
TWEET

Untitled

a guest Sep 11th, 2019 82 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
  1. #!/bin/bash
  2. # Check_MK Agent for Linux
  3. # +------------------------------------------------------------------+
  4. # |             ____ _               _        __  __ _  __           |
  5. # |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
  6. # |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
  7. # |           | |___| | | |  __/ (__|   <    | |  | | . \            |
  8. # |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
  9. # |                                                                  |
  10. # | Copyright Mathias Kettner 2014             mk@mathias-kettner.de |
  11. # +------------------------------------------------------------------+
  12. #
  13. # This file is part of Check_MK.
  14. # The official homepage is at http://mathias-kettner.de/check_mk.
  15. #
  16. # check_mk is free software;  you can redistribute it and/or modify it
  17. # under the  terms of the  GNU General Public License  as published by
  18. # the Free Software Foundation in version 2.  check_mk is  distributed
  19. # in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
  20. # out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
  21. # PARTICULAR PURPOSE. See the  GNU General Public License for more de-
  22. # tails. You should have  received  a copy of the  GNU  General Public
  23. # License along with GNU Make; see the file  COPYING.  If  not,  write
  24. # to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
  25. # Boston, MA 02110-1301 USA.
  26.  
  27. # Remove locale settings to eliminate localized outputs where possible
  28. export LC_ALL=C
  29. unset LANG
  30.  
  31. export MK_LIBDIR=${MK_LIBDIR:-/usr/lib/check_mk_agent}
  32. export MK_CONFDIR=${MK_CONFDIR:-/etc/check_mk}
  33. export MK_VARDIR=${MK_VARDIR:-/var/lib/check_mk_agent}
  34.  
  35. # Optionally set a tempdir for all subsequent calls
  36. #export TMPDIR=
  37.  
  38. # Provide information about the remote host. That helps when data
  39. # is being sent only once to each remote host.
  40. if [ "$REMOTE_HOST" ] ; then
  41.     export REMOTE=$REMOTE_HOST
  42. elif [ "$SSH_CLIENT" ] ; then
  43.     export REMOTE=${SSH_CLIENT%% *}
  44. fi
  45.  
  46. # The package name gets patched for baked agents to either
  47. # "check-mk-agent" or the name set by the "name of agent packages" rule
  48. XINETD_SERVICE_NAME=check_mk
  49.  
  50. # Make sure, locally installed binaries are found
  51. PATH=$PATH:/usr/local/bin
  52.  
  53. # All executables in PLUGINSDIR will simply be executed and their
  54. # ouput appended to the output of the agent. Plugins define their own
  55. # sections and must output headers with '<<<' and '>>>'
  56. PLUGINSDIR=$MK_LIBDIR/plugins
  57.  
  58. # All executables in LOCALDIR will by executabled and their
  59. # output inserted into the section <<<local>>>. Please
  60. # refer to online documentation for details about local checks.
  61. LOCALDIR=$MK_LIBDIR/local
  62.  
  63. # All files in SPOOLDIR will simply appended to the agent
  64. # output if they are not outdated (see below)
  65. SPOOLDIR=$MK_VARDIR/spool
  66.  
  67. # close standard input (for security reasons) and stderr when not
  68. # explicitly in debug mode.
  69. # When the nodes agent is executed by a e.g. docker node in a container,
  70. # then don't close stdin, because the agent is piped through it in this
  71. # case.
  72. if [ "$1" = -d ]
  73. then
  74.     set -xv
  75. elif [ -z "$MK_FROM_NODE" ]; then
  76.     exec </dev/null 2>/dev/null
  77. fi
  78.  
  79. # Detect whether or not the agent is being executed in a container
  80. # environment.
  81. if [ -f /.dockerenv ]; then
  82.     MK_IN_CONTAINER=1
  83. else
  84.     unset MK_IN_CONTAINER
  85. fi
  86.  
  87. # Prefer (relatively) new /usr/bin/timeout from coreutils against
  88. # our shipped waitmax. waitmax is statically linked and crashes on
  89. # some Ubuntu versions recently.
  90. if type timeout >/dev/null 2>&1 ; then
  91.     function waitmax () {
  92.         timeout "$@"
  93.     }
  94.     export -f waitmax
  95. fi
  96.  
  97. if [ -f "$MK_CONFDIR/encryption.cfg" ] ; then
  98.     source "$MK_CONFDIR/encryption.cfg"
  99. fi
  100.  
  101. if [ "$ENCRYPTED" == "yes" ] ; then
  102.     echo -n "00" # protocol version
  103.     exec > >(openssl enc -aes-256-cbc -md md5 -k "$PASSPHRASE" -nosalt)
  104. fi
  105.  
  106.  
  107. RTC_PLUGINS=""
  108. if [ -e "$MK_CONFDIR/real_time_checks.cfg" ]; then
  109.     . "$MK_CONFDIR/real_time_checks.cfg"
  110. fi
  111.  
  112.  
  113. #
  114. # CHECK SECTIONS
  115. #
  116.  
  117. function section_mem()
  118. {
  119.     if [ -z "$MK_IN_CONTAINER" ]; then
  120.         echo '<<<mem>>>'
  121.         grep -E -v '^Swap:|^Mem:|total:' < /proc/meminfo
  122.     else
  123.         echo '<<<docker_container_mem>>>'
  124.         cat /sys/fs/cgroup/memory/memory.stat
  125.         echo -n "usage_in_bytes "
  126.         cat /sys/fs/cgroup/memory/memory.usage_in_bytes
  127.         echo -n "limit_in_bytes "
  128.         cat /sys/fs/cgroup/memory/memory.limit_in_bytes
  129.         grep -F 'MemTotal:' /proc/meminfo
  130.     fi
  131. }
  132.  
  133. function section_cpu()
  134. {
  135.     if [ "$(uname -m)" = "armv7l" ]; then
  136.         CPU_REGEX='^processor'
  137.     else
  138.         CPU_REGEX='^CPU|^processor'
  139.     fi
  140.     NUM_CPUS=$(grep -c -E $CPU_REGEX < /proc/cpuinfo)
  141.  
  142.     if [ -z "$MK_IN_CONTAINER" ]; then
  143.         echo '<<<cpu>>>'
  144.         echo "$(cat /proc/loadavg) $NUM_CPUS"
  145.     else
  146.         echo '<<<docker_container_cpu>>>'
  147.         grep "^cpu " /proc/stat
  148.         echo "num_cpus $NUM_CPUS"
  149.         cat /sys/fs/cgroup/cpuacct/cpuacct.stat
  150.     fi
  151. }
  152.  
  153. function section_uptime()
  154. {
  155.     echo '<<<uptime>>>'
  156.     if [ -z "$MK_IN_CONTAINER" ]; then
  157.         cat /proc/uptime
  158.     else
  159.         echo "$(($(date +%s) - $(stat -c %Z /dev/pts)))"
  160.     fi
  161. }
  162.  
  163. # Print out Partitions / Filesystems. (-P gives non-wrapped POSIXed output)
  164. # Heads up: NFS-mounts are generally supressed to avoid agent hangs.
  165. # If hard NFS mounts are configured or you have too large nfs retry/timeout
  166. # settings, accessing those mounts from the agent would leave you with
  167. # thousands of agent processes and, ultimately, a dead monitored system.
  168. # These should generally be monitored on the NFS server, not on the clients.
  169. function section_df()
  170. {
  171.     if [ -n "$MK_IN_CONTAINER" ]; then
  172.         return
  173.     fi
  174.  
  175.     echo '<<<df>>>'
  176.     # The exclusion list is getting a bit of a problem. -l should hide any remote FS but seems
  177.     # to be all but working.
  178.     local excludefs="-x smbfs -x cifs -x iso9660 -x udf -x nfsv4 -x nfs -x mvfs -x zfs -x prl_fs"
  179.     df -PTlk $excludefs | sed 1d
  180.  
  181.     # df inodes information
  182.     echo '<<<df>>>'
  183.     echo '[df_inodes_start]'
  184.     df -PTli $excludefs | sed 1d
  185.     echo '[df_inodes_end]'
  186. }
  187.  
  188. function run_mrpe() {
  189.     local descr=$1
  190.     shift
  191.     local cmdline=$*
  192.  
  193.     echo '<<<mrpe>>>'
  194.  
  195.     PLUGIN=${cmdline%% *}
  196.     OUTPUT=$(eval "$cmdline")
  197.  
  198.     echo -n "(${PLUGIN##*/}) $descr $? $OUTPUT" | tr \\n \\1
  199.     echo
  200. }
  201.  
  202. export -f run_mrpe
  203.  
  204. # Runs a command asynchronous by use of a cache file. Usage:
  205. # run_cached [-s] NAME MAXAGE
  206. #   -s creates the section header <<<$NAME>>>
  207. #   -m mrpe-mode: stores exit code with the cache
  208. #   -ma mrpe-mode with age: stores exit code with the cache and adds the cache age
  209. #   NAME is the name of the section (also used as cache file name)
  210. #   MAXAGE is the maximum cache livetime in seconds
  211. function run_cached () {
  212.     local NOW
  213.     NOW=$(date +%s)
  214.     local section=
  215.     local mrpe=0
  216.     local append_age=0
  217.     # TODO: this function is unable to handle mulitple args at once
  218.     #       for example: -s -m won't work, it is read as single token "-s -m"
  219.     if [ "$1" = -s ] ; then local section="echo '<<<$2:cached($NOW,$3)>>>' ; " ; shift ; fi
  220.     if [ "$1" = -m ] ; then local mrpe=1 ; shift ; fi
  221.     if [ "$1" = "-ma" ] ; then local mrpe=1 ; local append_age=1 ; shift ; fi
  222.     local NAME=$1
  223.     local MAXAGE=$2
  224.     shift 2
  225.     local CMDLINE=$section$*
  226.  
  227.     if [ ! -d "$MK_VARDIR/cache" ]; then mkdir -p "$MK_VARDIR/cache" ; fi
  228.     if [ "$mrpe" = 1 ] ; then
  229.         CACHEFILE="$MK_VARDIR/cache/mrpe_$NAME.cache"
  230.     else
  231.         CACHEFILE="$MK_VARDIR/cache/$NAME.cache"
  232.     fi
  233.  
  234.     # Check if the creation of the cache takes suspiciously long and kill the
  235.     # process if the age (access time) of $CACHEFILE.new is twice the MAXAGE.
  236.     # Output the evantually already cached section anyways and start the cache
  237.     # update again.
  238.     if [ -e "$CACHEFILE.new" ] ; then
  239.         local CF_ATIME
  240.         CF_ATIME=$(stat -c %X "$CACHEFILE.new")
  241.         if [ $((NOW - CF_ATIME)) -ge $((MAXAGE * 2)) ] ; then
  242.             # Kill the process still accessing that file in case
  243.             # it is still running. This avoids overlapping processes!
  244.             fuser -k -9 "$CACHEFILE.new" >/dev/null 2>&1
  245.             rm -f "$CACHEFILE.new"
  246.         fi
  247.     fi
  248.  
  249.  
  250.     # Check if cache file exists and is recent enough
  251.     if [ -s "$CACHEFILE" ] ; then
  252.         local MTIME
  253.         MTIME=$(stat -c %Y "$CACHEFILE")
  254.         local AGE
  255.         AGE=$((NOW - MTIME))
  256.         if [ "$AGE" -le "$MAXAGE" ] ; then local USE_CACHEFILE=1 ; fi
  257.         # Output the file in any case, even if it is
  258.         # outdated. The new file will not yet be available
  259.         if [ $append_age -eq 1 ] ; then
  260.             # insert the cached-string before the pipe (first -e)
  261.             # or, if no pipe found (-e t) append it (third -e),
  262.             # but only once and on the second line (2!b) (first line is section header,
  263.             # all further lines are long output)
  264.             sed -e "2s/|/ (Cached: ${AGE}\/${MAXAGE}s)|/" -e t -e "2s/$/ (Cached: ${AGE}\/${MAXAGE}s)/" < "$CACHEFILE"
  265.         else
  266.             cat "$CACHEFILE"
  267.         fi
  268.     fi
  269.  
  270.     # Cache file outdated and new job not yet running? Start it
  271.     if [ -z "$USE_CACHEFILE" ] && [ ! -e "$CACHEFILE.new" ] ; then
  272.         # When the command fails, the output is throws away ignored
  273.         if [ $mrpe -eq 1 ] ; then
  274.             echo "set -o noclobber ; exec > \"$CACHEFILE.new\" || exit 1 ; run_mrpe $NAME \"$CMDLINE\" && mv \"$CACHEFILE.new\" \"$CACHEFILE\" || rm -f \"$CACHEFILE\" \"$CACHEFILE.new\"" | nohup /bin/bash >/dev/null 2>&1 &
  275.         else
  276.             echo "set -o noclobber ; exec > \"$CACHEFILE.new\" || exit 1 ; $CMDLINE && mv \"$CACHEFILE.new\" \"$CACHEFILE\" || rm -f \"$CACHEFILE\" \"$CACHEFILE.new\"" | nohup /bin/bash >/dev/null 2>&1 &
  277.         fi
  278.     fi
  279. }
  280.  
  281. # Make run_cached available for subshells (plugins, local checks, etc.)
  282. export -f run_cached
  283.  
  284. # Implements Real-Time Check feature of the Check_MK agent which can send
  285. # some section data in 1 second resolution. Useful for fast notifications and
  286. # detailed graphing (if you configure your RRDs to this resolution).
  287. function run_real_time_checks()
  288. {
  289.     PIDFILE=$MK_VARDIR/real_time_checks.pid
  290.     echo $$ > "$PIDFILE"
  291.  
  292.  
  293.     if [ "$PASSPHRASE" != "" ] ; then
  294.         # new mechanism to set the passphrase has priority
  295.         RTC_SECRET=$PASSPHRASE
  296.     fi
  297.  
  298.     if [ "$ENCRYPTED_RT" != "no" ] ; then
  299.         PROTOCOL=00
  300.     else
  301.         PROTOCOL=99
  302.     fi
  303.  
  304.  
  305.     while true; do
  306.         # terminate when pidfile is gone or other Real-Time Check process started or configured timeout
  307.         if [ ! -e "$PIDFILE" ] || [ "$(<"$PIDFILE")" -ne $$ ] || [ "$RTC_TIMEOUT" -eq 0 ]; then
  308.             exit 1
  309.         fi
  310.  
  311.         for SECTION in $RTC_SECTIONS; do
  312.             # Be aware of maximum packet size. Maybe we need to check the size of the section
  313.             # output and do some kind of nicer error handling.
  314.             # 2 bytes: protocol version, 10 bytes: timestamp, rest: encrypted data
  315.             # dd is used to concatenate the output of all commands to a single write/block => udp packet
  316.             { echo -n $PROTOCOL ;
  317.               date +%s | tr -d '\n' ;
  318.               if [ "$ENCRYPTED_RT" != "no" ] ; then
  319.                   export RTC_SECRET=$RTC_SECRET ; section_"$SECTION" | openssl enc -aes-256-cbc -md md5 -pass env:RTC_SECRET -nosalt ;
  320.               else
  321.                   section_"$SECTION" ;
  322.               fi
  323.             } | dd bs=9999 iflag=fullblock 2>/dev/null >"/dev/udp/${REMOTE}/${RTC_PORT}"
  324.         done
  325.  
  326.  
  327.         # Plugins
  328.         if cd "$PLUGINSDIR" ; then
  329.             for PLUGIN in $RTC_PLUGINS; do
  330.                 if [ ! -f $PLUGIN ] ; then
  331.                     continue
  332.                 fi
  333.  
  334.                 # Be aware of maximum packet size. Maybe we need to check the size of the section
  335.                 # output and do some kind of nicer error handling.
  336.                 # 2 bytes: protocol version, 10 bytes: timestamp, rest: encrypted data
  337.                 # dd is used to concatenate the output of all commands to a single write/block => udp packet
  338.                 { echo -n $PROTOCOL ;
  339.                   date +%s | tr -d '\n' ;
  340.                   if [ "$ENCRYPTED_RT" != "no" ] ; then
  341.                       export RTC_SECRET=$RTC_SECRET ; ./$PLUGIN | openssl enc -aes-256-cbc -md md5 -pass env:RTC_SECRET -nosalt ;
  342.                   else
  343.                       ./"$PLUGIN";
  344.                   fi
  345.                 } | dd bs=9999 iflag=fullblock 2>/dev/null >"/dev/udp/${REMOTE}/${RTC_PORT}"
  346.             done
  347.         fi
  348.  
  349.         sleep 1
  350.         RTC_TIMEOUT=$((RTC_TIMEOUT-1))
  351.     done
  352. }
  353.  
  354. echo '<<<check_mk>>>'
  355. echo Version: 1.5.0p22
  356. echo "AgentOS: linux"
  357. echo "Hostname: $HOSTNAME"
  358. echo "AgentDirectory: $MK_CONFDIR"
  359. echo "DataDirectory: $MK_VARDIR"
  360. echo "SpoolDirectory: $SPOOLDIR"
  361. echo "PluginsDirectory: $PLUGINSDIR"
  362. echo "LocalDirectory: $LOCALDIR"
  363.  
  364. # If we are called via xinetd, try to find only_from configuration
  365. if [ -n "$REMOTE_HOST" ]
  366. then
  367.     echo -n 'OnlyFrom: '
  368.     sed -n '/^service[[:space:]]*'$XINETD_SERVICE_NAME'/,/}/s/^[[:space:]]*only_from[[:space:]]*=[[:space:]]*\(.*\)/\1/p' /etc/xinetd.d/* | head -n1; echo
  369. fi
  370.  
  371. section_df
  372.  
  373. # Filesystem usage for ZFS
  374. if type zfs > /dev/null 2>&1 ; then
  375.     echo '<<<zfsget>>>'
  376.     zfs get -t filesystem,volume -Hp name,quota,used,avail,mountpoint,type 2>/dev/null
  377.     echo '[df]'
  378.     df -PTlk -t zfs | sed 1d
  379. fi
  380.  
  381. # Check NFS mounts by accessing them with stat -f (System
  382. # call statfs()). If this lasts more then 2 seconds we
  383. # consider it as hanging. We need waitmax.
  384. if type waitmax >/dev/null
  385. then
  386.     STAT_VERSION=$(stat --version | head -1 | cut -d" " -f4)
  387.     STAT_BROKE="5.3.0"
  388.  
  389.     echo '<<<nfsmounts>>>'
  390.     sed -n '/ nfs4\? /s/[^ ]* \([^ ]*\) .*/\1/p' < /proc/mounts |
  391.         sed 's/\\040/ /g' |
  392.         while read MP
  393.     do
  394.         if [ "$STAT_VERSION" != "$STAT_BROKE" ]; then
  395.             waitmax -s 9 5 stat -f -c "$MP ok %b %f %a %s" "$MP" || \
  396.                 echo "$MP hanging 0 0 0 0"
  397.         else
  398.             waitmax -s 9 5 stat -f -c "$MP ok %b %f %a %s" "$MP" && \
  399.                 printf '\n'|| echo "$MP hanging 0 0 0 0"
  400.         fi
  401.     done
  402.  
  403.     echo '<<<cifsmounts>>>'
  404.     sed -n '/ cifs\? /s/[^ ]* \([^ ]*\) .*/\1/p' < /proc/mounts |
  405.         sed 's/\\040/ /g' |
  406.         while read MP
  407.     do
  408.         if [ ! -r "$MP" ]; then
  409.             echo "$MP Permission denied"
  410.         elif [ "$STAT_VERSION" != "$STAT_BROKE" ]; then
  411.             waitmax -s 9 2 stat -f -c "$MP ok %b %f %a %s" "$MP" || \
  412.                 echo "$MP hanging 0 0 0 0"
  413.         else
  414.             waitmax -s 9 2 stat -f -c "$MP ok %b %f %a %s" "$MP" && \
  415.                 printf '\n'|| echo "$MP hanging 0 0 0 0"
  416.         fi
  417.     done
  418. fi
  419.  
  420. # Check mount options. Filesystems may switch to 'ro' in case
  421. # of a read error.
  422. echo '<<<mounts>>>'
  423. grep ^/dev < /proc/mounts
  424.  
  425. # processes including username, without kernel processes
  426. echo '<<<ps>>>'
  427. ps ax -o user:32,vsz,rss,cputime,etime,pid,command --columns 10000 | sed -e 1d -e 's/ *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) *\([^ ]*\) */(\1,\2,\3,\4\/\5,\6) /'
  428.  
  429. # Memory usage
  430. section_mem
  431.  
  432. # Load and number of processes
  433. section_cpu
  434.  
  435. # Uptime
  436. section_uptime
  437.  
  438. # New variant: Information about speed and state in one section
  439. if type ip > /dev/null
  440. then
  441.     echo '<<<lnx_if>>>'
  442.     echo "[start_iplink]"
  443.     ip link
  444.     echo "[end_iplink]"
  445. fi
  446.  
  447. echo '<<<lnx_if:sep(58)>>>'
  448. sed 1,2d /proc/net/dev
  449. if type ethtool > /dev/null
  450. then
  451.     sed -e 1,2d /proc/net/dev | cut -d':' -f1 | sort | while read eth; do
  452.         echo "[$eth]"
  453.         ethtool "$eth" | grep -E '(Speed|Duplex|Link detected|Auto-negotiation):'
  454.         echo -e "\tAddress: $(cat "/sys/class/net/$eth/address")\n"
  455.     done
  456. fi
  457.  
  458.  
  459. # Current state of bonding interfaces
  460. if [ -e /proc/net/bonding ] ; then
  461.     echo '<<<lnx_bonding:sep(58)>>>'
  462.     pushd /proc/net/bonding > /dev/null
  463.     head -v -n 1000 ./*
  464.     popd > /dev/null
  465. fi
  466.  
  467. # Same for Open vSwitch bonding
  468. if type ovs-appctl > /dev/null ; then
  469.     BONDS=$(ovs-appctl bond/list)
  470.     COL=$(echo "$BONDS" | awk '{for(i=1;i<=NF;i++) {if($i == "bond") printf("%d", i)} exit 0}')
  471.     echo '<<<ovs_bonding:sep(58)>>>'
  472.     for bond in $(echo "$BONDS" | sed -e 1d | cut -f"${COL}") ; do
  473.         echo "[$bond]"
  474.         ovs-appctl bond/show "$bond"
  475.     done
  476. fi
  477.  
  478.  
  479. # Number of TCP connections in the various states
  480. if type waitmax >/dev/null ; then
  481.     echo '<<<tcp_conn_stats>>>'
  482.     THIS=$(waitmax 5 cat /proc/net/tcp /proc/net/tcp6 2>/dev/null | awk ' /:/ { c[$4]++; } END { for (x in c) { print x, c[x]; } }')
  483.     if [ $? == 0 ] ; then
  484.         echo "$THIS"
  485.     elif type ss > /dev/null ; then
  486.         ss -ant |grep -v ^State | awk ' /:/ { c[$1]++; } END { for (x in c) { print x, c[x]; } }' | sed -e 's/^ESTAB/01/g;s/^SYN-SENT/02/g;s/^SYN-RECV/03/g;s/^FIN-WAIT-1/04/g;s/^FIN-WAIT-2/05/g;s/^TIME-WAIT/06/g;s/^CLOSED/07/g;s/^CLOSE-WAIT/08/g;s/^LAST-ACK/09/g;s/^LISTEN/0A/g;s/^CLOSING/0B/g;'
  487.     fi
  488. fi
  489.  
  490. # Linux Multipathing
  491. if type multipath >/dev/null ; then
  492.     if [ -f /etc/multipath.conf ] ; then
  493.         echo '<<<multipath>>>'
  494.         multipath -l
  495.     fi
  496. fi
  497.  
  498. # Performancecounter Platten
  499. if [ -z "$MK_IN_CONTAINER" ]; then
  500.     echo '<<<diskstat>>>'
  501.     date +%s
  502.     grep -E ' (x?[shv]d[a-z]*[0-9]*|cciss/c[0-9]+d[0-9]+|emcpower[a-z]+|dm-[0-9]+|VxVM.*|mmcblk.*|dasd[a-z]*|bcache[0-9]+|nvme[0-9]+n[0-9]+) ' < /proc/diskstats
  503.     if type dmsetup >/dev/null ; then
  504.         echo '[dmsetup_info]'
  505.         dmsetup info -c --noheadings --separator ' ' -o name,devno,vg_name,lv_name
  506.     fi
  507.     if [ -d /dev/vx/dsk ] ; then
  508.         echo '[vx_dsk]'
  509.         stat -c "%t %T %n" /dev/vx/dsk/*/*
  510.     fi
  511. else
  512.     echo '<<<docker_container_diskstat>>>'
  513.     echo "[time]"
  514.     date +%s
  515.     for F in io_service_bytes io_serviced; do
  516.         echo "[$F]"
  517.         cat "/sys/fs/cgroup/blkio/blkio.throttle.$F"
  518.     done
  519.     echo "[names]"
  520.     for F in /sys/block/*; do
  521.         echo -n "${F##*/} " ;
  522.         cat "$F/dev";
  523.     done
  524. fi
  525.  
  526.  
  527. # Performancecounter Kernel
  528. if [ -z "$MK_IN_CONTAINER" ]; then
  529.     echo '<<<kernel>>>'
  530.     date +%s
  531.     cat /proc/vmstat /proc/stat
  532. fi
  533.  
  534. # Hardware sensors via IPMI (need ipmitool)
  535. if type ipmitool > /dev/null
  536. then
  537.     run_cached -s "ipmi:sep(124)" 300 "waitmax 300 ipmitool sensor list | grep -v 'command failed' | egrep -v '^[^ ]+ na ' | grep -v ' discrete '"
  538.     # readable discrete sensor states
  539.     run_cached -s "ipmi_discrete:sep(124)" 300 "waitmax 300 ipmitool sdr elist compact"
  540. fi
  541.  
  542.  
  543. # IPMI data via ipmi-sensors (of freeipmi). Please make sure, that if you
  544. # have installed freeipmi that IPMI is really support by your hardware.
  545. if (type ipmi-sensors && ls /dev/ipmi*) &>/dev/null
  546. then
  547.     echo '<<<ipmi_sensors>>>'
  548.     # Newer ipmi-sensors version have new output format; Legacy format can be used
  549.     if ipmi-sensors --help | grep -q legacy-output; then
  550.         IPMI_FORMAT="--legacy-output"
  551.     else
  552.         IPMI_FORMAT=""
  553.     fi
  554.     if ipmi-sensors --help | grep -q " \-\-groups"; then
  555.         IPMI_GROUP_OPT="-g"
  556.     else
  557.         IPMI_GROUP_OPT="-t"
  558.     fi
  559.  
  560.     # At least with ipmi-sensors 0.7.16 this group is Power_Unit instead of "Power Unit"
  561.     run_cached -s ipmi_sensors 300 "for class in Temperature Power_Unit Fan
  562.    do
  563.        ipmi-sensors $IPMI_FORMAT --sdr-cache-directory /var/cache $IPMI_GROUP_OPT \"\$class\" | sed -e 's/ /_/g' -e 's/:_\?/ /g' -e 's@ \([^(]*\)_(\([^)]*\))@ \2_\1@'
  564.        # In case of a timeout immediately leave loop.
  565.        if [ $? = 255 ] ; then break ; fi
  566.    done"
  567. fi
  568.  
  569. # RAID status of Linux software RAID
  570. echo '<<<md>>>'
  571. cat /proc/mdstat
  572.  
  573. # RAID status of Linux RAID via device mapper
  574. if type dmraid >/dev/null && DMSTATUS=$(waitmax 3 dmraid -r)
  575. then
  576.     echo '<<<dmraid>>>'
  577.  
  578.     # Output name and status
  579.     waitmax 20 dmraid -s | grep -e ^name -e ^status
  580.  
  581.     # Output disk names of the RAID disks
  582.     DISKS=$(echo "$DMSTATUS" | cut -f1 -d":")
  583.  
  584.     for disk in $DISKS ; do
  585.         device=$(cat /sys/block/"$(basename "$disk")"/device/model )
  586.         status=$(echo "$DMSTATUS" | grep "^${disk}")
  587.         echo "${status} Model: ${device}"
  588.     done
  589. fi
  590.  
  591. # RAID status of LSI controllers via cfggen
  592. if type cfggen > /dev/null ; then
  593.    echo '<<<lsi>>>'
  594.    cfggen 0 DISPLAY | egrep '(Target ID|State|Volume ID|Status of volume)[[:space:]]*:' | sed -e 's/ *//g' -e 's/:/ /'
  595. fi
  596.  
  597. # RAID status of LSI MegaRAID controller via MegaCli. You can download that tool from:
  598. # http://www.lsi.com/downloads/Public/MegaRAID%20Common%20Files/8.02.16_MegaCLI.zip
  599. if type MegaCli >/dev/null ; then
  600.     MegaCli_bin="MegaCli"
  601. elif type MegaCli64 >/dev/null ; then
  602.     MegaCli_bin="MegaCli64"
  603. elif type megacli >/dev/null ; then
  604.     MegaCli_bin="megacli"
  605. elif type storcli >/dev/null ; then
  606.     MegaCli_bin="storcli"
  607. elif type storcli64 >/dev/null ; then
  608.     MegaCli_bin="storcli64"
  609. else
  610.     MegaCli_bin="unknown"
  611. fi
  612.  
  613. if [ "$MegaCli_bin" != "unknown" ]; then
  614.     echo '<<<megaraid_pdisks>>>'
  615.     for part in $($MegaCli_bin -EncInfo -aALL -NoLog < /dev/null \
  616.         | sed -rn 's/:/ /g; s/[[:space:]]+/ /g; s/^ //; s/ $//; s/Number of enclosures on adapter ([0-9]+).*/adapter \1/g; /^(Enclosure|Device ID|adapter) [0-9]+$/ p'); do
  617.         [ "$part" = adapter ] && echo ""
  618.         [ "$part" = 'Enclosure' ] && echo -ne "\ndev2enc"
  619.         echo -n " $part"
  620.     done
  621.     echo
  622.     $MegaCli_bin -PDList -aALL -NoLog < /dev/null | egrep 'Enclosure|Raw Size|Slot Number|Device Id|Firmware state|Inquiry|Adapter'
  623.     echo '<<<megaraid_ldisks>>>'
  624.     $MegaCli_bin -LDInfo -Lall -aALL -NoLog < /dev/null | egrep 'Size|State|Number|Adapter|Virtual'
  625.     echo '<<<megaraid_bbu>>>'
  626.     $MegaCli_bin -AdpBbuCmd -GetBbuStatus -aALL -NoLog < /dev/null | grep -v Exit
  627. fi
  628.  
  629. # RAID status of 3WARE disk controller (by Radoslaw Bak)
  630. if type tw_cli > /dev/null ; then
  631.     for C in $(tw_cli show | awk 'NR < 4 { next } { print $1 }'); do
  632.         echo '<<<3ware_info>>>'
  633.         tw_cli "/$C" show all | egrep 'Model =|Firmware|Serial'
  634.         echo '<<<3ware_disks>>>'
  635.         tw_cli "/$C" show drivestatus | egrep 'p[0-9]' | sed "s/^/$C\//"
  636.         echo '<<<3ware_units>>>'
  637.         tw_cli "/$C" show unitstatus | egrep 'u[0-9]' | sed "s/^/$C\//"
  638.     done
  639. fi
  640.  
  641. # RAID controllers from areca (Taiwan)
  642. # cli64 can be found at ftp://ftp.areca.com.tw/RaidCards/AP_Drivers/Linux/CLI/
  643. if type cli64 >/dev/null ; then
  644.     run_cached -s arc_raid_status 300 "cli64 rsf info | tail -n +3 | head -n -2"
  645. fi
  646.  
  647. # VirtualBox Guests. Section must always been output. Otherwise the
  648. # check would not be executed in case no guest additions are installed.
  649. # And that is something the check wants to detect
  650. echo '<<<vbox_guest>>>'
  651. if type VBoxControl >/dev/null 2>&1 && lsmod | grep vboxguest >/dev/null 2>&1; then
  652.     VBoxControl -nologo guestproperty enumerate | cut -d, -f1,2
  653.     [ "${PIPESTATUS[0]}" = 0 ] || echo "ERROR"
  654. fi
  655.  
  656. # OpenVPN Clients. Currently we assume that the configuration # is in
  657. # /etc/openvpn. We might find a safer way to find the configuration later.
  658. if [ -e /etc/openvpn/openvpn-status.log ] ; then
  659.     echo '<<<openvpn_clients:sep(44)>>>'
  660.     sed -n -e '/CLIENT LIST/,/ROUTING TABLE/p' < /etc/openvpn/openvpn-status.log  | sed -e 1,3d -e '$d'
  661. fi
  662.  
  663. # Time synchronization with NTP
  664. if type ntpq > /dev/null 2>&1 ; then
  665.    # remove heading, make first column space separated
  666.    run_cached -s ntp 30 "waitmax 5 ntpq -np | sed -e 1,2d -e 's/^\(.\)/\1 /' -e 's/^ /%/' || true"
  667. fi
  668.  
  669. # Time synchronization with Chrony
  670. if type chronyc > /dev/null 2>&1 ; then
  671.     # Force successful exit code. Otherwise section will be missing if daemon not running
  672.     #
  673.     # The "| cat" has been added for some kind of regression in RedHat 7.5. The
  674.     # SELinux rules shipped with that release were denying the chronyc call
  675.     # without cat.
  676.     run_cached -s chrony 30 "waitmax 5 chronyc -n tracking | cat || true"
  677. fi
  678.  
  679. if type nvidia-settings >/dev/null && [ -S /tmp/.X11-unix/X0 ]
  680. then
  681.     echo '<<<nvidia>>>'
  682.     for var in GPUErrors GPUCoreTemp
  683.     do
  684.         DISPLAY=:0 waitmax 2 nvidia-settings -t -q $var | sed "s/^/$var: /"
  685.     done
  686. fi
  687.  
  688. if [ -z "$MK_IN_CONTAINER" ] && [ -e /proc/drbd ]; then
  689.   echo '<<<drbd>>>'
  690.   cat /proc/drbd
  691. fi
  692.  
  693. # Heartbeat monitoring
  694. # Different handling for heartbeat clusters with and without CRM
  695. # for the resource state
  696. if [ -S /var/run/heartbeat/crm/cib_ro -o -S /var/run/crm/cib_ro ] || pgrep crmd > /dev/null 2>&1; then
  697.   echo '<<<heartbeat_crm>>>'
  698.   TZ=UTC crm_mon -1 -r | grep -v ^$ | sed 's/^ //; /^\sResource Group:/,$ s/^\s//; s/^\s/_/g'
  699. fi
  700. if type cl_status > /dev/null 2>&1; then
  701.   echo '<<<heartbeat_rscstatus>>>'
  702.   cl_status rscstatus
  703.  
  704.   echo '<<<heartbeat_nodes>>>'
  705.   for NODE in $(cl_status listnodes); do
  706.     if [ "$NODE" != "$(echo "$HOSTNAME" | tr '[:upper:]' '[:lower:]')" ]; then
  707.       STATUS=$(cl_status nodestatus "$NODE")
  708.       echo -n "$NODE $STATUS"
  709.       for LINK in $(cl_status listhblinks "$NODE" 2>/dev/null); do
  710.         echo -n " $LINK $(cl_status hblinkstatus "$NODE" "$LINK")"
  711.       done
  712.       echo
  713.     fi
  714.   done
  715. fi
  716.  
  717. # Postfix mailqueue monitoring
  718. # Determine the number of mails and their size in several postfix mail queues
  719. function read_postfix_queue_dirs {
  720.     postfix_queue_dir=$1
  721.     if [ -n "$postfix_queue_dir" ]; then
  722.         echo '<<<postfix_mailq>>>'
  723.         if [ ! -z "$2" ]; then
  724.             echo "[[[${2}]]]"
  725.         fi
  726.         for queue in deferred active
  727.         do
  728.             count=$(find "${postfix_queue_dir}/$queue" -type f | wc -l)
  729.             size=$(du -s "${postfix_queue_dir}/$queue" | awk '{print $1 }')
  730.             if [ -z "$size" ]; then
  731.                 size=0
  732.             fi
  733.             if [ -z "$count" ]; then
  734.                 echo "Mail queue is empty"
  735.             else
  736.                 echo "QUEUE_${queue} $size $count"
  737.             fi
  738.         done
  739.     fi
  740. }
  741.  
  742. # Postfix mailqueue monitoring
  743. # Determine the number of mails and their size in several postfix mail queues
  744. if type postconf >/dev/null ; then
  745.     # Check if multi_instance_directories exists in main.cf and is not empty
  746.     # always takes the last entry, multiple entries possible
  747.     multi_instances_dirs=$(postconf -c /etc/postfix 2>/dev/null | grep ^multi_instance_directories | sed 's/.*=[[:space:]]*//g')
  748.     if [ ! -z "$multi_instances_dirs" ]; then
  749.         for queue_dir in $multi_instances_dirs
  750.         do
  751.             if [ -n "$queue_dir" ]; then
  752.                 postfix_queue_dir=$(postconf -c "$queue_dir" 2>/dev/null | grep ^queue_directory | sed 's/.*=[[:space:]]*//g')
  753.                 read_postfix_queue_dirs "$postfix_queue_dir" "$queue_dir"
  754.             fi
  755.         done
  756.  
  757.     else
  758.         postfix_queue_dir=$(postconf -h queue_directory 2>/dev/null)
  759.         read_postfix_queue_dirs "$postfix_queue_dir"
  760.     fi
  761.  
  762. elif [ -x /usr/sbin/ssmtp ] ; then
  763.     echo '<<<postfix_mailq>>>'
  764.     mailq 2>&1 | sed 's/^[^:]*: \(.*\)/\1/' | tail -n 6
  765.  
  766. fi
  767.  
  768. # Postfix status monitoring. Can handle multiple instances.
  769. if type postfix >/dev/null ; then
  770.     echo "<<<postfix_mailq_status:sep(58)>>>"
  771.     for i in /var/spool/postfix*/; do
  772.         if [ -e "$i/pid/master.pid" ]; then
  773.             if [ -r "$i/pid/master.pid" ]; then
  774.                 postfix_pid=$(sed 's/ //g' < "$i/pid/master.pid") # handle possible spaces in output
  775.                 if readlink -- "/proc/${postfix_pid}/exe" | grep -q ".*postfix/\(s\?bin/\)\?master.*"; then
  776.                     echo "$i:the Postfix mail system is running:PID:$postfix_pid" | sed 's/\/var\/spool\///g'
  777.                 else
  778.                     echo "$i:PID file exists but instance is not running!" | sed 's/\/var\/spool\///g'
  779.                 fi
  780.             else
  781.                 echo "$i:PID file exists but is not readable"
  782.             fi
  783.         else
  784.             echo "$i:the Postfix mail system is not running" | sed 's/\/var\/spool\///g'
  785.         fi
  786.     done
  787. fi
  788.  
  789. # Check status of qmail mailqueue
  790. if type qmail-qstat >/dev/null
  791. then
  792.    echo "<<<qmail_stats>>>"
  793.    qmail-qstat
  794. fi
  795.  
  796. # Nullmailer queue monitoring
  797. if type nullmailer-send >/dev/null && [ -d /var/spool/nullmailer/queue ]
  798. then
  799.     echo '<<<nullmailer_mailq>>>'
  800.     COUNT=$(find /var/spool/nullmailer/queue -type f | wc -l)
  801.     SIZE=$(du -s /var/spool/nullmailer/queue | awk '{print $1 }')
  802.     echo "$SIZE $COUNT"
  803. fi
  804.  
  805. # Check status of OMD sites and Check_MK Notification spooler
  806. if type omd >/dev/null
  807. then
  808.     run_cached -s omd_status 60 "omd status --bare --auto || true"
  809.     echo '<<<mknotifyd:sep(0)>>>'
  810.     for statefile in /omd/sites/*/var/log/mknotifyd.state ; do
  811.     if [ -e "$statefile" ] ; then
  812.         site=${statefile%/var/log*}
  813.         site=${site#/omd/sites/}
  814.         echo "[$site]"
  815.         grep -v '^#' < "$statefile"
  816.         fi
  817.     done
  818.  
  819.     echo '<<<omd_apache:sep(124)>>>'
  820.     for statsfile in /omd/sites/*/var/log/apache/stats; do
  821.     if [ -e "$statsfile" ] ; then
  822.         site=${statsfile%/var/log*}
  823.         site=${site#/omd/sites/}
  824.         echo "[$site]"
  825.             cat "$statsfile"
  826.             > "$statsfile"
  827.             # prevent next section to fail caused by a missing newline at the end of the statsfile
  828.             echo
  829.         fi
  830.     done
  831. fi
  832.  
  833.  
  834. # Welcome the ZFS check on Linux
  835. # We do not endorse running ZFS on linux if your vendor doesnt support it ;)
  836. # check zpool status
  837. if type zpool >/dev/null; then
  838.    echo "<<<zpool_status>>>"
  839.    zpool status -x
  840. fi
  841.  
  842.  
  843. # Veritas Cluster Server
  844. # Software is always installed in /opt/VRTSvcs.
  845. # Secure mode must be off to allow root to execute commands
  846. if [ -x /opt/VRTSvcs/bin/haclus ]
  847. then
  848.     echo "<<<veritas_vcs>>>"
  849.     vcshost=$(hostname | cut -d. -f1)
  850.     waitmax -s 9 2 /opt/VRTSvcs/bin/haclus -display -localclus | grep -e ClusterName -e ClusState
  851.     waitmax -s 9 2 /opt/VRTSvcs/bin/hasys -display -attribute SysState
  852.     waitmax -s 9 2 /opt/VRTSvcs/bin/hagrp -display -sys "$vcshost" -attribute State -localclus
  853.     waitmax -s 9 2 /opt/VRTSvcs/bin/hares -display -sys "$vcshost" -attribute State -localclus
  854.     waitmax -s 9 2 /opt/VRTSvcs/bin/hagrp -display -attribute TFrozen -attribute Frozen
  855. fi
  856.  
  857.  
  858. # Fileinfo-Check: put patterns for files into /etc/check_mk/fileinfo.cfg
  859. function replace_datevariable()
  860. {
  861.     # Replace the date variable of the input, e.g. $DATE:%Y%m%d$, by
  862.     # the current date. If there's no match just return the input.
  863.     local file_name="$1"
  864.     # shellcheck disable=SC2016
  865.     local pattern='(\$DATE:(.*)\$)'
  866.  
  867.     if [[ ! $file_name =~ $pattern ]]; then
  868.         echo "$file_name"
  869.     else
  870.         date_variable="${BASH_REMATCH[1]}"
  871.         format_string="${BASH_REMATCH[2]}"
  872.         echo "${file_name/$date_variable/$(date +"$format_string")}"
  873.     fi
  874. }
  875.  
  876. if [ -r "$MK_CONFDIR/fileinfo.cfg" ] ; then
  877.     echo '<<<fileinfo:sep(124)>>>'
  878.     date +%s
  879.  
  880.     OLD_IFS=$IFS
  881.     IFS='
  882. '
  883.     while read -r pattern; do
  884.         case $pattern in
  885.             /*) pattern=$(replace_datevariable "$pattern")
  886.                 for file in $pattern; do
  887.                     stat -c "%n|%s|%Y" "$file" 2> /dev/null || echo "$file|missing|$(date +%s)"
  888.                 done ;;
  889.         esac
  890.     done < "$MK_CONFDIR/fileinfo.cfg"
  891.     IFS=$OLD_IFS
  892. fi
  893.  
  894. # Get stats about OMD monitoring cores running on this machine.
  895. # Since cd is a shell builtin the check does not affect the performance
  896. # on non-OMD machines.
  897. if cd /omd/sites
  898. then
  899.     echo '<<<livestatus_status:sep(59)>>>'
  900.     for site in *
  901.     do
  902.         if [ -S "/omd/sites/$site/tmp/run/live" ] ; then
  903.             echo "[$site]"
  904.             echo -e "GET status" | \
  905.                 waitmax 3 "/omd/sites/$site/bin/unixcat" "/omd/sites/$site/tmp/run/live"
  906.         fi
  907.     done
  908.     echo '<<<mkeventd_status:sep(0)>>>'
  909.     for site in *
  910.     do
  911.         if [ -S "/omd/sites/$site/tmp/run/mkeventd/status" ] ; then
  912.             echo "[\"$site\"]"
  913.             echo -e "GET status\nOutputFormat: json" \
  914.                 | waitmax 3 "/omd/sites/$site/bin/unixcat" "/omd/sites/$site/tmp/run/mkeventd/status"
  915.         fi
  916.     done
  917. fi
  918.  
  919. # Collect states of configured Check_MK site backup jobs
  920. if ls /omd/sites/*/var/check_mk/backup/*.state >/dev/null 2>&1; then
  921.     echo "<<<mkbackup>>>"
  922.     for F in /omd/sites/*/var/check_mk/backup/*.state; do
  923.         SITE=${F#/*/*/*}
  924.         SITE=${SITE%%/*}
  925.  
  926.         JOB_IDENT=${F%.state}
  927.         JOB_IDENT=${JOB_IDENT##*/}
  928.  
  929.         if [ "$JOB_IDENT" != "restore" ]; then
  930.             echo "[[[site:$SITE:$JOB_IDENT]]]"
  931.             cat "$F"
  932.             echo
  933.         fi
  934.     done
  935. fi
  936.  
  937. # Collect states of configured CMA backup jobs
  938. if type mkbackup >/dev/null && ls /var/lib/mkbackup/*.state >/dev/null 2>&1; then
  939.     echo "<<<mkbackup>>>"
  940.     for F in /var/lib/mkbackup/*.state; do
  941.         JOB_IDENT=${F%.state}
  942.         JOB_IDENT=${JOB_IDENT##*/}
  943.  
  944.         if [ "$JOB_IDENT" != "restore" ]; then
  945.             echo "[[[system:$JOB_IDENT]]]"
  946.             cat "$F"
  947.             echo
  948.         fi
  949.     done
  950. fi
  951.  
  952. # Get statistics about monitored jobs. Below the job directory there
  953. # is a sub directory per user that ran a job. That directory must be
  954. # owned by the user so that a symlink or hardlink attack for reading
  955. # arbitrary files can be avoided.
  956. if pushd "$MK_VARDIR/job" >/dev/null; then
  957.     echo '<<<job>>>'
  958.     for username in *
  959.     do
  960.         if [ -d "$username" ] && cd "$username" ; then
  961.             if [ $EUID -eq 0 ]; then
  962.                 su -s "$SHELL" "$username" -c "head -n -0 -v *"
  963.             else
  964.                 head -n -0 -v ./*
  965.             fi
  966.             cd ..
  967.         fi
  968.     done
  969.     popd > /dev/null
  970. fi
  971.  
  972. # Gather thermal information provided e.g. by acpi
  973. # At the moment only supporting thermal sensors
  974. if [ -z "$MK_IN_CONTAINER" ] && ls /sys/class/thermal/thermal_zone* >/dev/null 2>&1; then
  975.     echo '<<<lnx_thermal:sep(124)>>>'
  976.     for F in /sys/class/thermal/thermal_zone*; do
  977.         line="${F##*/}"
  978.         if [ ! -e "$F/mode" ] ; then line="${line}|-" ; else line="${line}|$(cat "$F"/mode)"; fi
  979.         line="${line}|$(cat "$F"/{type,temp} | tr \\n "|")"
  980.         for G in $(ls "$F"/trip_point_*_{temp,type}); do
  981.             line="${line}$(< "$G" tr \\n "|")"
  982.         done
  983.         echo "${line%?}"
  984.     done
  985. fi
  986.  
  987. # Libelle Business Shadow
  988. if type trd >/dev/null; then
  989.    echo "<<<libelle_business_shadow:sep(58)>>>"
  990.    trd -s
  991. fi
  992.  
  993. # HTTP Accelerator Statistics
  994. if type varnishstat >/dev/null; then
  995.    echo "<<<varnish>>>"
  996.    varnishstat -1
  997. fi
  998.  
  999. # Proxmox Cluster
  1000. if type pvecm > /dev/null 2>&1 ; then
  1001.     echo "<<<pvecm_status:sep(58)>>>"
  1002.     pvecm status
  1003.     echo "<<<pvecm_nodes>>>"
  1004.     pvecm nodes
  1005. fi
  1006.  
  1007. # Start new liveupdate process in background on each agent execution. Starting
  1008. # a new live update process will terminate the old one automatically after
  1009. # max. 1 sec.
  1010. if [ -e "$MK_CONFDIR/real_time_checks.cfg" ]; then
  1011.     if [ -z "$REMOTE" ]; then
  1012.         echo "ERROR: \$REMOTE not specified. Not starting Real-Time Checks." >&2
  1013.     elif ! type openssl >/dev/null; then
  1014.         echo "ERROR: openssl command is missing. Not starting Real-Time Checks." >&2
  1015.     else
  1016.         run_real_time_checks >/dev/null &
  1017.     fi
  1018. fi
  1019.  
  1020. # MK's Remote Plugin Executor
  1021. if [ -e "$MK_CONFDIR/mrpe.cfg" ]
  1022. then
  1023.     grep -Ev '^[[:space:]]*($|#)' "$MK_CONFDIR/mrpe.cfg" | \
  1024.     while read descr cmdline
  1025.     do
  1026.         interval=
  1027.         args="-m"
  1028.         # NOTE: Due to an escaping-related bug in some old bash versions
  1029.         # (3.2.x), we have to use an intermediate variable for the pattern.
  1030.         pattern='\(([^\)]*)\)[[:space:]](.*)'
  1031.         if [[ $cmdline =~ $pattern ]]
  1032.         then
  1033.             parameters=${BASH_REMATCH[1]}
  1034.             cmdline=${BASH_REMATCH[2]}
  1035.  
  1036.             # split multiple parameter assignments
  1037.             for par in $(echo "$parameters" | tr ":" "\n")
  1038.             do
  1039.                 # split each assignment
  1040.                 key=$(echo "$par" | cut -d= -f1)
  1041.                 value=$(echo "$par" | cut -d= -f2)
  1042.  
  1043.                 if [ "$key" = "interval" ] ; then
  1044.                     interval=$value
  1045.                 elif [ "$key" = "appendage" ] ; then
  1046.                     args="-ma"
  1047.                 fi
  1048.             done
  1049.         fi
  1050.  
  1051.         if [ -z "$interval" ]
  1052.         then
  1053.             run_mrpe "$descr" "$cmdline"
  1054.         else
  1055.             run_cached "$args" "$descr" "$interval" "$cmdline"
  1056.         fi
  1057.     done
  1058. fi
  1059.  
  1060. # MK's runas Executor
  1061. if [ -e "$MK_CONFDIR/runas.cfg" ]
  1062. then
  1063.     grep -Ev '^[[:space:]]*($|#)' "$MK_CONFDIR/runas.cfg" | \
  1064.     while read type user include
  1065.     do
  1066.         if [ -d "$include" -o \( "$type" == "mrpe" -a -f "$include" \) ] ; then
  1067.             PREFIX=""
  1068.             if [ "$user" != "-" ] ; then
  1069.                 PREFIX="su $user -c "
  1070.             fi
  1071.  
  1072.             # mrpe includes
  1073.             if [ "$type" == "mrpe" ] ; then
  1074.                 grep -Ev '^[[:space:]]*($|#)' "$include" | \
  1075.                 while read descr cmdline
  1076.                 do
  1077.                     interval=
  1078.                     # NOTE: Due to an escaping-related bug in some old bash
  1079.                     # versions (3.2.x), we have to use an intermediate variable
  1080.                     # for the pattern.
  1081.                     pattern='\(([^\)]*)\)[[:space:]](.*)'
  1082.                     if [[ $cmdline =~ $pattern ]]
  1083.                     then
  1084.                         parameters=${BASH_REMATCH[1]}
  1085.                         cmdline=${BASH_REMATCH[2]}
  1086.  
  1087.                         # split multiple parameter assignments
  1088.                         for par in $(echo "$parameters" | tr ":" "\n")
  1089.                         do
  1090.                             # split each assignment
  1091.                             IFS='=' read key value <<< $par
  1092.                             if [ "$key" = "interval" ]
  1093.                             then
  1094.                                 interval=$value
  1095.                             # no other parameters supported currently
  1096.                             fi
  1097.                         done
  1098.                     fi
  1099.  
  1100.                     if [ -n "$PREFIX" ] ; then
  1101.                         cmdline="$PREFIX\'$cmdline\'"
  1102.                     fi
  1103.                     if [ -z "$interval" ]
  1104.                     then
  1105.                         run_mrpe "$descr" "$cmdline"
  1106.                     else
  1107.                         run_cached -m "$descr" "$interval" "$cmdline"
  1108.                     fi
  1109.                 done
  1110.  
  1111.             # local and plugin includes
  1112.             elif [ "$type" == "local" -o "$type" == "plugin" ] ; then
  1113.                 if [ "$type" == "local" ] ; then
  1114.                     echo "<<<local>>>"
  1115.                 fi
  1116.  
  1117.                 find "$include" -executable -type f | \
  1118.                 while read filename
  1119.                 do
  1120.                     if [ -n "$PREFIX" ] ; then
  1121.                         cmdline="$PREFIX\"$filename\""
  1122.                     else
  1123.                         cmdline=$filename
  1124.                     fi
  1125.  
  1126.                     $cmdline
  1127.                 done
  1128.             fi
  1129.         fi
  1130.     done
  1131. fi
  1132.  
  1133. function is_valid_plugin () {
  1134.     # NOTE: Due to an escaping-related bug in some old bash versions
  1135.     # (3.2.x), we have to use an intermediate variable for the pattern.
  1136.     pattern='\.dpkg-(new|old|temp)$'
  1137.     #TODO Maybe we should change this mechanism
  1138.     # shellcheck disable=SC2015
  1139.     [[ -f "$1" && -x "$1" && ! "$1" =~ $pattern ]] && true || false
  1140. }
  1141.  
  1142. # Local checks
  1143. echo '<<<local>>>'
  1144. if cd "$LOCALDIR" ; then
  1145.     for skript in ./*; do
  1146.         if is_valid_plugin "$skript"; then
  1147.             ./"$skript"
  1148.         fi
  1149.     done
  1150.     # Call some plugins only every X'th second
  1151.     for skript in [1-9]*/* ; do
  1152.         if is_valid_plugin "$skript"; then
  1153.             run_cached "local_${skript//\//\\}" "${skript%/*}" "$skript"
  1154.         fi
  1155.     done
  1156. fi
  1157.  
  1158. # Plugins
  1159. if cd "$PLUGINSDIR"; then
  1160.     for skript in ./*; do
  1161.         if is_valid_plugin "$skript"; then
  1162.             ./"$skript"
  1163.         fi
  1164.     done
  1165.     # Call some plugins only every Xth second
  1166.     for skript in [1-9]*/* ; do
  1167.         if is_valid_plugin "$skript"; then
  1168.             run_cached "plugins_${skript//\//\\}" "${skript%/*}" "$skript"
  1169.         fi
  1170.     done
  1171. fi
  1172.  
  1173. # Agent output snippets created by cronjobs, etc.
  1174. if [ -d "$SPOOLDIR" ] && [ -r "$SPOOLDIR" ]; then
  1175.     pushd "$SPOOLDIR" >/dev/null
  1176.     now=$(date +%s)
  1177.  
  1178.     for file in *
  1179.     do
  1180.         test "$file" = "*" && break
  1181.         # output every file in this directory. If the file is prefixed
  1182.         # with a number, then that number is the maximum age of the
  1183.         # file in seconds. If the file is older than that, it is ignored.
  1184.         maxage=""
  1185.         part="$file"
  1186.  
  1187.         # Each away all digits from the front of the filename and
  1188.         # collect them in the variable maxage.
  1189.         while [ "${part/#[0-9]/}" != "$part" ]
  1190.         do
  1191.             maxage=$maxage${part:0:1}
  1192.             part=${part:1}
  1193.         done
  1194.  
  1195.         # If there is at least one digit, than we honor that.
  1196.         if [ "$maxage" ] ; then
  1197.             mtime=$(stat -c %Y "$file")
  1198.             if [ $((now - mtime)) -gt "$maxage" ] ; then
  1199.                 continue
  1200.             fi
  1201.         fi
  1202.  
  1203.         # Output the file
  1204.         cat "$file"
  1205.     done
  1206.     popd > /dev/null
  1207. fi
RAW Paste Data
We use cookies for various purposes including analytics. By continuing to use Pastebin, you agree to our use of cookies as described in the Cookies Policy. OK, I Understand
 
Top