2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
10 # | Copyright Mathias Kettner 2014 mk@mathias-kettner.de |
11 # +------------------------------------------------------------------+
13 # This file is part of Check_MK.
14 # The official homepage is at http://mathias-kettner.de/check_mk.
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.
27 # Example output from agent (sizes are in bytes). Note: the part
28 # [df] in this check is duplicated. We need this information because
29 # zfsget does not show pass-through filesystems like '/'. :-(
33 # bpool quota 0 default
34 # bpool used 21947036798826 -
35 # bpool available 11329512075414 -
36 # bpool mountpoint /bpool default
37 # bpool type filesystem -
38 # bpool/acs_fs name bpool/acs_fs -
39 # bpool/acs_fs quota 0 default
40 # bpool/acs_fs used 4829131610 -
41 # bpool/acs_fs available 11329512075414 -
42 # bpool/acs_fs mountpoint /backup/acs local
43 # bpool/acs_fs type filesystem -
45 # / 10255636 1836517 8419119 18% /
46 # /dev 10255636 1836517 8419119 18% /dev
48 # ctfs 0 0 0 0% /system/contract
49 # mnttab 0 0 0 0% /etc/mnttab
50 # objfs 0 0 0 0% /system/object
51 # swap 153480592 232 153480360 1% /etc/svc/volatile
52 # /usr/lib/libc/libc_hwcap1.so.1 10255636 1836517 8419119 18% /lib/libc.so.1
54 # swap 2097152 11064 2086088 1% /tmp
55 # swap 153480384 24 153480360 1% /var/run
56 # tsrdb10exp/export 5128704 21 4982717 1% /export
57 # tsrdb10exp/export/home 5128704 55 4982717 1% /home
58 # tsrdb10exp/export/opt 5128704 145743 4982717 3% /opt
59 # tsrdb10exp 5128704 21 4982717 1% /tsrdb10exp
60 # tsrdb10dat 30707712 19914358 10789464 65% /u01
63 def parse_zfs_entry(info
):
65 return saveint(x
) / (1024.0 * 1024)
68 for _name
, what
, value
in info
:
69 if what
in ["used", "available"]:
70 entry
[what
] = mb(value
)
72 if value
not in ['0', '-']:
73 entry
[what
] = mb(value
)
74 elif what
in ['mountpoint', 'type', 'name']:
80 def parse_zfsget(info
):
99 # New block so parse everthing and go on collecting more blocks
100 if last_name
!= name
:
103 new_entry
= parse_zfs_entry(zfs_agent_data
)
105 zfs_converted
.append(new_entry
)
107 zfs_agent_data
.append(line
[:3])
111 device
, kbytes
, used
, avail
, _percent
, mountpoint
= line
113 device
, _fs_type
, kbytes
, used
, avail
, _percent
, mountpoint
= line
114 if mountpoint
.startswith("/"):
116 entry
["name"] = device
117 entry
["mountpoint"] = mountpoint
118 # With some versions of solaris systems such as
119 # solaris 10 10/08 s10s_u6wos_07b SPARC and solaris 10 10/09 s10x_u8wos_08a X86
120 # there migth be a bug in the 'df -h' command which we use for filesystem infos.
121 # Then the received data from the agent looks like "/ 0 12445007 19012273 5% /".
122 # In this case we compute the total size as the sum of used and available.
126 if used
and avail
and not total
:
130 entry
["total"] = total
/ 1024.0
131 entry
["used"] = used
/ 1024.0
132 entry
["available"] = avail
/ 1024.0
133 df_parsed
[mountpoint
] = entry
135 # Now remove duplicate entries for the root filesystem, such
136 # as /dev/ or /lib/libc.so.1. We do this if size, used and
137 # avail is equal. I hope that it will not happen too often
138 # that this is per chance the case for different passed-through
140 root_entry
= df_parsed
.get("/")
142 t_u_a
= (root_entry
["total"], root_entry
["used"], root_entry
["available"])
144 for mountpoint
, entry
in df_parsed
.items():
145 if mountpoint
!= "/" and \
146 t_u_a
== (entry
["total"], entry
["used"], entry
["available"]):
147 drop
.append(mountpoint
)
151 # parsed has the device name as key, because there may exist
152 # several device names per mount point, and we know only
153 # later which one to take
155 for entry
in zfs_converted
:
156 if entry
["mountpoint"].startswith("/"):
157 entry
["is_pool"] = '/' not in entry
["name"]
158 if entry
['available'] != 0 and entry
['type'] == 'filesystem':
159 zfs_parsed
[entry
["name"]] = entry
161 # parsed_df and parsed_final have the mount point as key
163 for mountpoint
, entry_df
in df_parsed
.items():
165 # for every mount point in the df section, if the device name
166 # is also present in the "parsed" variable, we take those data
167 for name
, entry
in zfs_parsed
.items():
168 if entry_df
["name"] == name
:
169 parsed_final
[mountpoint
] = entry
171 # if a mount point in the df section is not present in the
172 # parsed variable, we take the data from the df section
174 parsed_final
[mountpoint
] = entry_df
179 def inventory_zfsget(info
):
181 parsed
= parse_zfsget(info
)
182 for mountpoint
in parsed
.iterkeys():
183 if mountpoint
not in inventory_df_exclude_mountpoints
:
184 mplist
.append(mountpoint
)
185 return df_inventory(mplist
)
188 # def convert_zfssize(txt):
193 # 'T' : 1024 * 1024.0,
194 # 'P' : 1024 * 1024 * 1024.0,
196 # return float(txt[:-1]) * units_to_mb[txt[-1]]
199 def check_zfsget(item
, params
, info
):
200 entries
= parse_zfsget(info
)
201 # ist item drin -> OK, ansonsten gleich hier
203 for mountpoint
, entry
in entries
.items():
204 if "patterns" in params
or item
== mountpoint
:
205 # 1. Filesystems with a quota
207 used_mb
= entry
["used"]
208 total_mb
= entry
["quota"]
209 avail_mb
= total_mb
- used_mb
210 # 2. Normal filesystems.
212 used_mb
= entry
["used"]
213 avail_mb
= entry
["available"]
214 total_mb
= used_mb
+ avail_mb
215 fslist
.append((mountpoint
, total_mb
, avail_mb
, 0))
217 return df_check_filesystem_list(item
, params
, fslist
)
220 check_info
['zfsget'] = {
221 "check_function": check_zfsget
,
222 "inventory_function": inventory_zfsget
,
223 "service_description": "Filesystem %s",
224 "has_perfdata": True,
225 "group": "filesystem",
226 "default_levels_variable": "filesystem_default_levels",
227 "includes": ["size_trend.include", "df.include"],