This file is indexed.

/usr/share/check_mk/checks/df is in check-mk-server 1.2.8p16-1ubuntu0.1.

This file is owned by root:root, with mode 0o755.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
#!/usr/bin/python
# -*- encoding: utf-8; py-indent-offset: 4 -*-
# +------------------------------------------------------------------+
# |             ____ _               _        __  __ _  __           |
# |            / ___| |__   ___  ___| | __   |  \/  | |/ /           |
# |           | |   | '_ \ / _ \/ __| |/ /   | |\/| | ' /            |
# |           | |___| | | |  __/ (__|   <    | |  | | . \            |
# |            \____|_| |_|\___|\___|_|\_\___|_|  |_|_|\_\           |
# |                                                                  |
# | Copyright Mathias Kettner 2014             mk@mathias-kettner.de |
# +------------------------------------------------------------------+
#
# This file is part of Check_MK.
# The official homepage is at http://mathias-kettner.de/check_mk.
#
# check_mk is free software;  you can redistribute it and/or modify it
# under the  terms of the  GNU General Public License  as published by
# the Free Software Foundation in version 2.  check_mk is  distributed
# in the hope that it will be useful, but WITHOUT ANY WARRANTY;  with-
# out even the implied warranty of  MERCHANTABILITY  or  FITNESS FOR A
# PARTICULAR PURPOSE. See the  GNU General Public License for more de-
# tails. You should have  received  a copy of the  GNU  General Public
# License along with GNU Make; see the file  COPYING.  If  not,  write
# to the Free Software Foundation, Inc., 51 Franklin St,  Fifth Floor,
# Boston, MA 02110-1301 USA.

# <<<df>>>
# /dev/sda3     ext4     8123200   1207512   6496392      16% /
# /dev/sda6     ext3   117794932    192192 111522544       1% /data
# /dev/sda2     ext3     8123200    220388   7483516       3% /var
# /dev/sda1     reiserfs  256666     16052    227362       7% /boot
# /dev/mapper/mirrored-database ext3  20642428   1027112  19405604       6% /mirrored/database

# Another example from a Windows 7 system:
# <<<df>>>
# SYSTEM NTFS 312569172 180648472 131920700  58% C:\
# Data NTFS 976506816 528665344 447841472  55% D:\
# PS3 PlayStation(R)3 File System 0 0 0   0% P:\

# An example with btrfs (SLES 12). Here the same device is mounted
# several times at different mount point. But must only be monitored
# once. We use the device instead of the mount point in this case.
# <<<df>>>
# /dev/sda1      btrfs       20970496 4169036  16539348      21% /
# devtmpfs       devtmpfs      497396       0    497396       0% /dev
# tmpfs          tmpfs         506312       0    506312       0% /dev/shm
# tmpfs          tmpfs         506312    6980    499332       2% /run
# tmpfs          tmpfs         506312       0    506312       0% /sys/fs/cgroup
# /dev/sda1      btrfs       20970496 4169036  16539348      21% /.snapshots
# /dev/sda1      btrfs       20970496 4169036  16539348      21% /var/tmp
# /dev/sda1      btrfs       20970496 4169036  16539348      21% /var/spool
# /dev/sda1      btrfs       20970496 4169036  16539348      21% /var/opt
# /dev/sda1      btrfs       20970496 4169036  16539348      21% /var/log


def df_parse_info(info):
    df_blocks = []
    df_inodes = []
    btrfs_devices = set() # We might generalize that later
    lines = iter(info)

    try:
        is_inode = False
        while True:
            line = lines.next()
            if line[-1] == '[df_inodes_start]':
                is_inode = True
                continue
            elif line[-1] == '[df_inodes_end]':
                is_inode = False
                continue
            if not is_inode:
                # Handle known cases, where the file system contains spaces
                if line[2] == "File" and line[3] == "System":
                    line =  [ line[0], " ".join(line[1:4]) ] + line[4:]
                if line[1] == "btrfs":
                    device = line[0]
                    if device not in btrfs_devices:
                        btrfs_devices.add(device)
                        df_blocks.append(line[:6] + [ "btrfs " + line[0] ]) # replace mount point with device
                else:
                    df_blocks.append(line)
            else:
                df_inodes.append(line)
    except StopIteration:
        pass

    return df_blocks, df_inodes

def inventory_df(info):
    df_blocks, df_inodes = df_parse_info(info)
    mplist = []
    for line in df_blocks:
        if line[1] in inventory_df_exclude_fs:
            continue # ignore this filesystem type

        if line[2] == '-' or int(line[2]) == 0 or line[5] == '-':
            continue # exclude filesystems without size

        mountpoint = " ".join(line[6:]).replace('\\', '/') # Windows \ is replaced with /
        if mountpoint in inventory_df_exclude_mountpoints:
            continue # exclude this mount point (/tmp, /proc, whatever user wants)

        mplist.append(mountpoint)

    return df_inventory(mplist)


def check_df(item, params, info):
    fslist_blocks = []
    fslist_inodes = []
    df_blocks, df_inodes = df_parse_info(info)
    for idx, line in enumerate(df_blocks):
        # df outputs seven columns:
        # DEVICE FS-TYPE SIZE(KB) USED(KB) AVAIL(KB) USED(%) MOUNTPOINT
        # The mount point may contain spaces (seen on VMWare volumes and on ESX)
        mountpoint = " ".join(line[6:]).replace('\\', '/')
        if "patterns" in params or item == mountpoint:
            # Beware: the 6th column of df ("used perc") may includes 5% which are reserved
            # for the superuser, whereas the 4th colum ("used MB") does *not* include that.
            # Beware(2): the column used_mb does not account for the reserved space for
            # superusers. So we rather use the column 'avail' and subtract that from total
            # to compute the used space.
            size_mb    = int(line[2]) / 1024.0
            avail_mb   = int(line[4]) / 1024.0
            used_mb    = int(line[3]) / 1024.0
            reserved_mb = size_mb - avail_mb - used_mb # reserved for root
            fslist_blocks.append((mountpoint, size_mb, avail_mb, reserved_mb))
            if df_inodes and len(df_inodes) > idx:
                fslist_inodes.append((mountpoint, int(df_inodes[idx][2]), int(df_inodes[idx][4])))
    return df_check_filesystem_list(item, params, fslist_blocks, fslist_inodes)

check_info['df'] = {
    "check_function"          : check_df,
    "inventory_function"      : inventory_df,
    "service_description"     : "Filesystem %s",
    "has_perfdata"            : True,
    "group"                   : "filesystem",
    "default_levels_variable" : "filesystem_default_levels",
    "includes"                : [ "df.include" ],
}