Projet

Général

Profil

Paste
Télécharger au format
Statistiques
| Branche: | Révision:

root / plugins / zfs / zfs_usage_ @ cde12172

Historique | Voir | Annoter | Télécharger (10,2 ko)

1
#!/usr/bin/env perl
2
# -*- perl
3

    
4
=pod
5

    
6
=head1 NAME
7

    
8
zfs_usage_ - Script to monitor zfs pool usage
9

    
10
=head1 CONFIGURATION
11

    
12
Create one symlink per zpool for exampe zfs_usage_system
13

    
14
if you need to override the defaults below:
15

    
16
 [zfs_usage_*]
17
  env.zpoolexec - Path to zpool binary
18
  env.zfsexec   - Path to zfs binary
19

    
20
=head2 DEFAULT CONFIGURATION
21

    
22
 [zfs_usage_*]
23
  env.zpoolexec /sbin/zpool
24
  env.zfsexec   /sbin/zfs
25

    
26

    
27
=head1 BUGS
28

    
29
=head1 AUTHOR
30

    
31
2012, Claudius Herder
32

    
33
=head1 MAGIC MARKERS
34

    
35
 #%# family=auto
36
 #%# capabilities=autoconf suggest
37

    
38
=head1 LICENSE
39

    
40
GPLv2
41

    
42
=cut
43

    
44
use strict;
45
use warnings;
46
use Munin::Plugin;
47
need_multigraph();
48

    
49
my $filesystems;
50
my $zpool;
51
my $zpoolexec = (defined($ENV{'zpoolexec'}) ? $ENV{'zpoolexec'} : '/sbin/zpool');
52
my $zfsexec   = (defined($ENV{'zfsexec'}) ? $ENV{'zfsexec'} : '/sbin/zfs');
53

    
54
my $properties = {
55
  available           =>  "Read-only property that identifies the amount of disk"
56
                         ." space available to a file system and all its children,"
57
                         ." assuming no other activity in the pool. Because disk"
58
                         ." space is shared within a pool, available space can be"
59
                         ." limited by various factors including physical pool size,"
60
                         ." quotas, reservations, and other datasets within the"
61
                         ." pool.",
62

    
63
  quota               =>  "Limits the amount of disk space a file system and its"
64
                         ." descendents can consume. This property enforces a"
65
                         ." hard limit on the amount of disk space used, including"
66
                         ." all space consumed by descendents, such as file systems"
67
                         ." and snapshots. Setting a quota on a descendent of a file"
68
                         ." system that already has a quota does not override the"
69
                         ." ancestor's quota, but rather imposes an additional"
70
                         ." limit. Quotas cannot be set on volumes, as the volsize"
71
                         ." property acts as an implicit quota.",
72

    
73
  referenced          =>  "Read-only property that identifies the amount of data"
74
                         ." accessible by a dataset, which might or might not be"
75
                         ." shared with other datasets in the pool."
76
                         ." When a snapshot or clone is created, it initially"
77
                         ." references the same amount of disk space as the file"
78
                         ." system or snapshot it was created from, because its"
79
                         ." contents are identical.",
80

    
81
  refquota            =>  "Sets the amount of disk space that a dataset can"
82
                         ." consume. This property enforces a hard limit on the"
83
                         ." amount of space used. This hard limit does not include"
84
                         ." disk space used by descendents, such as snapshots and"
85
                         ." clones.",
86

    
87
  refreservation      =>  "Sets the minimum amount of disk space that is"
88
                         ." guaranteed to a dataset, not including descendents,"
89
                         ." such as snapshots and clones. When the amount of disk"
90
                         ." space used is below this value, the dataset is treated as if"
91
                         ." it were taking up the amount of space specified by"
92
                         ." refreservation. The refreservation reservation is"
93
                         ." accounted for in the parent dataset's disk space used,"
94
                         ." and counts against the parent dataset's quotas and"
95
                         ." reservations."
96
                         ." If refreservation is set, a snapshot is only allowed if"
97
                         ." enough free pool space is available outside of this"
98
                         ." reservation to accommodate the current number of"
99
                         ." referenced bytes in the dataset.",
100

    
101
  reservation         => "Sets the minimum amount of disk space guaranteed to"
102
                         ." a file system and its descendents. When the amount of"
103
                         ." disk space used is below this value, the file system is"
104
                         ." treated as if it were using the amount of space specified"
105
                         ." by its reservation. Reservations are accounted for in the"
106
                         ." parent file system's disk space used, and count against"
107
                         ." the parent file system's quotas and reservations.",
108

    
109
  type                =>  "Read-only property that identifies the dataset type as"
110
                         ." filesystem (file system or clone), volume, or"
111
                             ." snapshot.",
112

    
113
  used                =>  "Read-only property that identifies the amount of disk"
114
                         ." space consumed by a dataset and all its descendents.",
115

    
116
  usedbychildren      =>  "Read-only property that identifies the amount of disk"
117
                         ." space that is used by children of this dataset, which"
118
                         ." would be freed if all the dataset's children were"
119
                         ." destroyed. The property abbreviation is usedchild.",
120

    
121
  usedbydataset       =>  "Read-only property that identifies the amount of disk"
122
                         ." space that is used by a dataset itself, which would be"
123
                         ." freed if the dataset was destroyed, after first destroying"
124
                         ." any snapshots and removing any refreservation"
125
                         ." reservations. The property abbreviation is usedds.",
126

    
127
  usedbyrefreservation=>  "Read-only property that identifies the amount of disk"
128
                         ." space that is used by a refreservation set on a dataset,"
129
                         ." which would be freed if the refreservation was"
130
                         ." removed.",
131

    
132
  usedbysnapshots     =>  "Read-only property that identifies the amount of disk"
133
                         ." space that is consumed by snapshots of a dataset. In"
134
                         ." particular, it is the amount of disk space that would be"
135
                         ." freed if all of this dataset's snapshots were destroyed."
136
                         ." Note that this value is not simply the sum of the"
137
                         ." snapshots' used properties, because space can be"
138
                         ." shared by multiple snapshots.",
139
  volsize             =>  "For volumes, specifies the logical size of the volume.",
140
};
141

    
142
my @order = (
143
"usedbydataset",
144
"usedbysnapshots",
145
"usedbyrefreservation",
146
"usedbychildren",
147
"available",
148
"quota",
149
"refquota",
150
"referenced",
151
"reservation",
152
"refreservation",
153
"used",
154
"volsize",
155
);
156

    
157
sub do_collect {
158
    my @params = join(',',( keys %{$properties} ));
159
    my $fsget="$zfsexec get -H -p -r -t filesystem,volume @params $zpool";
160

    
161
    foreach my $line (split(/\n/, `$fsget` )) {
162
        my ($name, $key, $value, undef ) = (split(/\t/,$line));
163
        ($name =~ s/\//_/g);
164
        $filesystems->{$name}->{$key}=$value;
165
    }
166
}
167

    
168

    
169
sub do_config_fs {
170
    my ($fs) = @_;
171
    my $fs_slash = ($fs);
172
    ($fs_slash =~ s/_/\//g);
173

    
174
    if ( $fs ne $zpool ) {
175
        printf( "multigraph zfs_usage_%s.%s\n",
176
            clean_fieldname($zpool), clean_fieldname($fs) );
177
        print "graph_title ZFS usage for $filesystems->{$fs}->{type} $fs_slash\n";
178
        print "graph_info This graph shows used bytes of $filesystems->{$fs}->{type} $fs_slash\n";
179
    } else {
180
        printf( "multigraph zfs_usage_%s\n", clean_fieldname($zpool) );
181
        print "graph_title ZFS usage for zpool $zpool\n";
182
        print "graph_info This graph shows used bytes of zpool $zpool\n";
183
    }
184
    print "graph_args --base 1024 --lower-limit 0 --rigid\n";
185
    print "graph_vlabel bytes \n";
186
    print "graph_category zfs\n";
187
    print "graph_order @order\n";
188

    
189
    foreach my $key ( keys %{$filesystems->{$fs}}) {
190
        if ( $key ne "type" ) {
191
            if ( $filesystems->{$fs}->{type} eq "volume" && $key =~ /quota/ ) {
192
            }
193
            elsif ($filesystems->{$fs}->{type} eq "filesystem" && $key eq "volsize") {
194
            }
195
            else {
196
                print "$key.label $key\n";
197
                print "$key.min 0\n";
198
                print "$key.type GAUGE\n";
199
                print "$key.info $properties->{$key}\n";
200
                if ( $key =~ /quota|referenced|^(ref)*reservation|^used$|volsize/ ) {
201
                    print "$key.draw LINE3\n";
202
                }
203
                else {
204
                    print "$key.draw AREASTACK\n";
205
                }
206
            }
207
        }
208
    }
209
}
210

    
211

    
212
sub do_fetch_fs {
213
    my ($fs) = @_;
214

    
215
    if ( $fs ne $zpool ) {
216
        printf( "multigraph zfs_usage_%s.%s\n",
217
            clean_fieldname($zpool), clean_fieldname($fs) );
218
    } else {
219
        printf( "multigraph zfs_usage_%s\n", clean_fieldname($zpool) );
220
    }
221

    
222
    foreach my $key ( keys %{$filesystems->{$fs}}) {
223
        if ( $key ne "type" ) {
224
            if ( $filesystems->{$fs}->{type} eq "volume" && $key =~ /quota/ ) {
225
            }
226
            elsif ($filesystems->{$fs}->{type} eq "filesystem" && $key eq "volsize") {
227
            }
228
            else {
229
                print "$key.value $filesystems->{$fs}->{$key}\n";
230
            }
231
        }
232
    }
233
}
234

    
235
sub do_config {
236
    foreach my $fs ( sort keys %{$filesystems}) {
237
        do_config_fs($fs);
238
    }
239
}
240

    
241
sub do_autoconf {
242
    if (`which $zpoolexec 2>/dev/null` =~ m{^/}) {
243
        print "yes\n";
244
    } else {
245
        print "no ($zpoolexec could not be found)\n";
246
    }
247
    exit 0;
248
}
249

    
250

    
251
sub do_suggest {
252
    my $poollist=(`zpool list -H  -o name`);
253
    print "$poollist";
254
}
255

    
256
sub do_fetch {
257
    foreach my $fs ( sort keys %{$filesystems}) {
258
        do_fetch_fs($fs);
259
    }
260
}
261

    
262
sub do_setpool {
263
    if ( $0 =~ /zfs_usage_$/) {
264
        die ("Can't run without a symlinked name\n")
265
    }
266
    elsif ($0 =~ /zfs_usage_(.+)*$/) {
267
        $zpool = $1;
268
    }
269
}
270

    
271
if ($ARGV[0]) {
272
    if ($ARGV[0] eq "config") {
273
        do_setpool();
274
        do_collect();
275
        do_config();
276
        exit 0;
277
    }
278
    elsif ($ARGV[0] eq "autoconf") {
279
        do_autoconf();
280
        exit 0;
281
    }
282
    elsif ($ARGV[0] eq "suggest") {
283
        do_suggest();
284
        exit 0;
285
    }
286
}
287
else {
288
    do_setpool();
289
    do_collect();
290
    do_fetch();
291
}
292

    
293
exit 0;
294

    
295
__END__