This file is indexed.

/usr/share/munin/plugins/buddyinfo is in munin-node 1.4.6-3ubuntu3.4.

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
142
143
144
145
146
147
148
149
150
#!/usr/bin/perl -w

=pod

=encoding UTF-8

=head1 NAME

buddyinfo - Plugin to monitor memory fragmentation on Linux systems.

=head1 APPLICABLE SYSTEMS

Linux 2.5.40+, 2.6.x

=head1 CONFIGURATION

None needed.

=head1 INTERPRETATION

Linux manages virtual memory on a page granularity. There are some operations
however that require physically contiguous pages to be allocated by the kernel.
Such allocations may fail if the memory gets fragmented and even though there
are enough pages free, but they are not contiguous.

This plugin monitors the amount of contiguous areas, called higher order pages.
The order means the exponent of two of the size of the area, so order 2 means
2^2 = 4 pages.

=head1 SEE ALSO

See C<Documentation/filesystems/proc.txt> in the Linux source tree for the
description of the buddyinfo file.

=head1 MAGIC MARKERS

 #%# family=manual
 #%# capabilities=autoconf

=head1 AUTHOR

Gábor Gombás <gombasg@sztaki.hu>

=head1 LICENSE

GPLv2 or later

=cut

use strict;
use Munin::Plugin;
use POSIX;
use Carp;

need_multigraph();

if ($ARGV[0] and $ARGV[0] eq 'autoconf') {
	if (-f "/proc/buddyinfo") {
		print "yes\n";
	}
	else {
		print "no (/proc/buddyinfo is missing)\n";
	}
	exit 0;
}

# The most common page size is 4k, but it is not universal
my $pagesize = POSIX::sysconf(&POSIX::_SC_PAGESIZE) / 1024;

my $zones = {};

open(FH, '< /proc/buddyinfo')
	or croak "Failed to open '/proc/buddyinfo': $!";
while (my $line = <FH>) {
	chomp $line;

	$line =~ m/Node (\d+), zone\s+(\S+)\s+(\S.*)$/;
	my $name = "Node $1, zone $2";
	my @cnt = split(/ +/, $3);
	$zones->{$name} = \@cnt;
}
close FH;

my $totals = [];
foreach my $zone (keys %$zones) {
	for my $i (0 .. $#{$zones->{$zone}}) {
		$totals->[$i] += $zones->{$zone}->[$i]
	}
}

sub do_config {
	print "multigraph buddyinfo\n";
	print "graph_title Memory fragmentation\n";
	print "graph_args --base 1024 --lower-limit 0\n";
	print "graph_vlabel pages free\n";
	print "graph_category system\n";
	print "graph_info This graph shows the number of free pages of different size\n";
	print "graph_order " . join(' ', map { "order$_" } (0 .. $#{$totals})) . "\n";
	for my $i (0 .. $#{$totals}) {
		print "order$i.label Order $i\n";
		print "order$i.info Number of order $i (" . ($pagesize * 2 ** $i) . " KiB) pages\n";
		print "order$i.type GAUGE\n";
		print "order$i.draw LINE2\n";
		print "order$i.min 0\n";
	}
	for my $zone (sort keys %$zones) {
		my $zoneid = $zone;
		$zoneid = clean_fieldname($zone);

		print "multigraph buddyinfo.$zoneid\n";
		print "graph_title Memory fragmentation in $zone\n";
		print "graph_args --base 1024 --lower-limit 0\n";
		print "graph_vlabel pages free\n";
		print "graph_category system\n";
		print "graph_info This graph shows the number of free pages in $zone\n";
		print "graph_order " .
			join(' ', map { "order$_" } (0 .. $#{$zones->{$zone}})) . "\n";
		for my $i (0 .. $#{$zones->{$zone}}) {
			print "order$i.label Order $i\n";
			print "order$i.info Number of order $i (" .
				($pagesize * 2 ** $i) . " KiB) pages\n";
			print "order$i.type GAUGE\n";
			print "order$i.draw LINE2\n";
			print "order$i.min 0\n";
		}
	}
}

sub do_fetch {
	print "multigraph buddyinfo\n";
	for my $i (0 .. $#{$totals}) {
		print "order$i.value " . $totals->[$i] . "\n";
	}
	for my $zone (sort keys %$zones) {
		my $zoneid = $zone;
		$zoneid =~ tr/ ,/__/;

		print "multigraph buddyinfo.$zoneid\n";
		for my $i (0 .. $#{$zones->{$zone}}) {
			print "order$i.value " . $zones->{$zone}->[$i] . "\n";
		}
	}
}

if ($ARGV[0] and $ARGV[0] eq 'config') {
	do_config();
	exit 0;
}

do_fetch();