This file is indexed.

/usr/share/munin-btrfs/plugins/btrfs_usage is in munin-plugins-btrfs 9-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
#!/usr/bin/python3
#
# Copyright (C) 2016 Hans van Kranenburg <hans@knorrie.org>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public
# License v2 as published by the Free Software Foundation.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public
# License along with this program; if not, write to the
# Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
# Boston, MA 02110-1301 USA


from collections import deque
import btrfs
import sys


def colours():
    colours = deque([
        '33FF33', '00CC00',  # green
        'FFFF33', 'CCCC00',  # yellow
        '3399FF', '0000CC',  # blue
        'FF3333', 'CC0000',  # red
        'FF33FF', 'CC00CC',  # purple
    ])
    while True:
        yield colours[0]
        colours.rotate(-1)


def draw_type():
    yield 'AREA'
    while True:
        yield 'STACK'


def munin_config(fs, spaces, used_types):
    print("multigraph btrfs_usage_{0}".format(str(fs.fsid).replace('-', '_')))
    print("graph_args --base 1024 -l 0")
    print("graph_vlabel bytes")
    print("graph_title btrfs space usage for {0}".format(fs.path))
    print("graph_category disk")
    print("graph_info This graph shows how btrfs uses available space")
    draw = draw_type()
    colour = colours()
    for _type in used_types:
        label = btrfs.utils.block_group_flags_str(_type).lower().replace('|', '_')
        description = btrfs.utils.block_group_type_str(_type)
        print("{0}_used.label Used {1}".format(label, description))
        print("{0}_used.draw {1}".format(label, next(draw)))
        print("{0}_used.info Used {1}".format(label, description))
        print("{0}_used.colour {1}".format(label, next(colour)))
        print("{0}_unused.label Unused {1}".format(label, description))
        print("{0}_unused.draw {1}".format(label, next(draw)))
        print("{0}_unused.info Unused {1}".format(label, description))
        print("{0}_unused.colour {1}".format(label, next(colour)))
    print("unallocated.label Unallocated")
    print("unallocated.draw STACK")
    print("unallocated.info Not allocated raw space")
    print("unallocated.colour FFFFFF")
    print("wasted_soft.label Reclaimable non-alloc")
    print("wasted_soft.draw STACK")
    print("wasted_soft.info Reclaimable not allocatable")
    print("wasted_soft.colour BBBBBB")
    print("wasted_hard.label Non-allocatable")
    print("wasted_hard.draw STACK")
    print("wasted_hard.info Non-allocatable")
    print("wasted_hard.colour 888888")
    print("total.label Total")
    print("total.draw LINE2")
    print("total.info Total raw space")
    print("total.colour 000000")
    print("")


def munin_values(fs, spaces, used_types):
    print("multigraph btrfs_usage_{0}".format(str(fs.fsid).replace('-', '_')))
    for _type in used_types:
        label = btrfs.utils.block_group_flags_str(_type).lower().replace('|', '_')
        used = 0
        allocated = 0
        for space in spaces:
            if space.type == _type:
                used += space.raw_used_bytes
                allocated += space.raw_total_bytes
        print("{0}_used.value {1}".format(label, used))
        print("{0}_unused.value {1}".format(label, allocated - used))

    total, allocated, used, wasted_hard, wasted_soft = btrfs.utils.fs_usage(fs)
    unallocated = total - allocated - wasted_soft - wasted_hard
    print("unallocated.value {0}".format(unallocated))
    print("wasted_soft.value {0}".format(wasted_soft))
    print("wasted_hard.value {0}".format(wasted_hard))
    print("total.value {0}".format(total))
    print("")


def main():
    for fs in btrfs.utils.mounted_filesystems():
        spaces = fs.space_info()
        used_types = []
        for space in spaces:
            if space.type not in used_types and space.type != btrfs.SPACE_INFO_GLOBAL_RSV:
                used_types.append(space.type)

        if len(sys.argv) > 1 and sys.argv[1] == "config":
            munin_config(fs, spaces, used_types)
        else:
            munin_values(fs, spaces, used_types)


if __name__ == "__main__":
    main()