Cleanup config.nodes_of
[check_mk.git] / checks / aix_lvm
blob238c44a293f313cc83452f478c6cf6c1a1175eef
1 #!/usr/bin/python
2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
9 # | |
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 # Agent output and things to know:
29 # hd5 boot 1 2 2 closed/syncd N/A
30 # hd6 paging 65 130 2 open/syncd N/A
31 # hd8 jfs2log 1 2 2 open/syncd N/A
32 # hd4 jfs2 1 2 2 open/syncd /
33 # hd2 jfs2 5 10 2 open/syncd /usr
34 # hd9var jfs2 3 6 2 open/syncd /var
35 # hd3 jfs2 2 4 2 open/syncd /tmp
36 # hd1 jfs2 1 2 2 open/syncd /home
37 # hd10opt jfs2 3 6 2 open/syncd /opt
38 # hd11admin jfs2 1 2 2 open/syncd /admin
39 # lg_dumplv sysdump 6 6 1 open/syncd N/A
40 # livedump jfs2 1 2 2 open/syncd /var/adm/ras/livedump
41 # lvwork jfs2 1 2 2 open/syncd /work
42 # lvbackup jfs2 200 200 1 open/syncd /backup
43 # fwdump jfs2 5 5 1 open/syncd /var/adm/ras/platform
44 # lvoracle jfs2 30 30 1 open/syncd /oracle
46 # hd5 which contains the boot kernel is normally always closed (but it doesn't
47 # matter IF it's closed.
49 # row3: 1 means it alloceted one lvm logical extent (called partition on AIX), so
50 # it's likely 256MB in size.
51 # row4: 2 means it uses two physical extents. So if it uses two physical for
52 # one logical ... yeah, a mirror
54 # row5: 2 means that the volume uses two physical volumes to store those
55 # extents. So the mirror isn't on the same disk if it dies.
57 # row6: here open/syncd is OK for every active volume
59 #lvmconf = {
60 # rootvg : {
61 # hd5 : ("boot", 1, 2, 2, "closed/syncd", None)
62 # hd4 : ("/", 1, 2, 2, "open/syncd", "/")
63 # }
67 def parse_aix_lvm(info):
68 lvmconf = {}
69 for line in info:
70 if len(line) == 1:
71 vgname = line[0][:-1]
72 lvmconf.update({vgname: {}})
73 # Some versions send a title line "LV NAME ..."
74 elif line[0] == "LV" and line[1] == "NAME":
75 continue
76 else:
77 lv, lvtype, num_lp, num_pp, num_pv, act_state, mountpoint = line
78 # split lv state into two relevant values
79 activation, mirror = act_state.split("/")
80 if mountpoint == "N/A":
81 mountpoint = None
82 lvmconf[vgname].update({
83 lv: (lvtype, int(num_lp), int(num_pp), int(num_pv), activation, mirror, mountpoint)
85 return lvmconf
88 def inventory_aix_lvm(info):
89 inventory = []
90 for vg, volumes in parse_aix_lvm(info).iteritems():
91 for lv in volumes:
92 #inventory.append(("%s/%s" % (vg, lv), ('%s' % volumes[lv][4],)))
93 inventory.append(("%s/%s" % (vg, lv), None))
94 return inventory
97 def check_aix_lvm(item, _no_params, info):
99 # Get ready to find our item and settings.
100 #target_activation = params
101 target_vg, target_lv = item.split("/")
103 # Get structured LVM info
104 lvmconf = parse_aix_lvm(info)
106 if target_vg in lvmconf and target_lv in lvmconf[target_vg]:
107 msgtxt = []
108 state = 0
110 lvtype, num_lp, num_pp, num_pv, activation, mirror, _mountpoint = lvmconf[target_vg][
111 target_lv]
113 # Test if the volume is mirrored.
114 # Yes? Test for an even distribution of PP's over volumes.
115 # This is cannot detect crossover misaligns and other bad practices.
116 if num_pp / num_lp > 1:
117 if not num_pp / num_pv == num_lp:
118 msgtxt.append("LV Mirrors are misaligned between physical volumes(!)")
119 state = max(state, 1)
121 # If it's not the boot volume I suspect it should be open.
122 # This may need to be changed for some scenarios
123 if lvtype != "boot":
124 if activation != "open": # and activation != target_activation:
125 msgtxt.append("LV is not opened(!)")
126 state = max(state, 1)
128 # Detect any, not just mirrored, volumes, that have stale PPs.
129 # This means either a disk write failure causing a mirror to go stale
130 # or some kind of split mirror backup.
131 if mirror != "syncd":
133 msgtxt.append("LV is not in sync state(!!)")
134 state = max(state, 2)
136 if state == 0:
137 msgtxt = "LV is open/syncd"
138 else:
139 msgtxt = ", ".join(msgtxt)
140 return (state, msgtxt)
142 return (3, "no such volume found")
145 check_info['aix_lvm'] = {
146 "check_function": check_aix_lvm,
147 "inventory_function": inventory_aix_lvm,
148 "service_description": "Logical Volume %s",
149 # "group" : "",
150 # "default_levels_variable" : "services_default_levels",
151 # first check we have a vendor mib from W&T, then check for the model in their MIB.