2 # -*- encoding: utf-8; py-indent-offset: 4 -*-
3 # +------------------------------------------------------------------+
4 # | ____ _ _ __ __ _ __ |
5 # | / ___| |__ ___ ___| | __ | \/ | |/ / |
6 # | | | | '_ \ / _ \/ __| |/ / | |\/| | ' / |
7 # | | |___| | | | __/ (__| < | | | | . \ |
8 # | \____|_| |_|\___|\___|_|\_\___|_| |_|_|\_\ |
10 # | Copyright Mathias Kettner 2013 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.
30 # Version: 6FET49WW (1.19 )
31 # Release Date: 10/17/2008
33 # Runtime Size: 128 kB
37 # PC Card (PCMCIA) is supported
40 # BIOS shadowing is allowed
41 # ESCD support is available
42 # Boot from CD is supported
43 # Selectable boot is supported
44 # BIOS ROM is socketed
47 # USB legacy is supported
48 # BIOS boot specification is supported
49 # Targeted content distribution is supported
51 # Firmware Revision: 1.1
54 # Manufacturer: LENOVO
55 # Product Name: 4061AR7
56 # Version: ThinkPad W500
57 # Serial Number: L3AFB3L
58 # UUID: AD137E01-4A86-11CB-A580-BE0E287D2679
59 # Wake-up Type: Power Switch
60 # SKU Number: Not Specified
61 # Family: ThinkPad W500
63 # ... any many other sections...
65 # Note: on Linux \t is replaced by : and then the split
66 # is done by :. On Windows the \t comes 1:1 and no splitting
67 # is being done. So we need to split manually here
68 def inv_dmidecode(info
):
72 # Windows plugin keeps tabs and has no separator
74 parts
= line
[0].replace("\t", ":").split(":")
75 line
= [ x
.strip() for x
in parts
]
78 inv_dmidecode_parse_section(section_name
, section_lines
)
79 section_name
= line
[0]
82 section_lines
.append(line
[1:])
84 inv_dmidecode_parse_section(section_name
, section_lines
)
86 node
= inv_tree("hardware.")
89 def inv_dmidecode_parse_section(name
, lines
):
90 lines
= [ [ w
.strip() for w
in words
] for words
in lines
]
91 if name
== "BIOS Information":
92 inv_dmidecode_parse_bios(lines
)
93 elif name
== "System Information":
94 inv_dmidecode_parse_system(lines
)
95 elif name
== "Chassis Information":
96 inv_dmidecode_parse_chassis(lines
)
97 elif name
== "Processor Information":
98 inv_dmidecode_parse_processor(lines
)
99 # elif name == "Memory Controller Information":
100 # inv_dmidecode_parse_mem_controller(lines)
101 # elif name == "Memory Module Information":
102 # inv_dmidecode_parse_mem_module(lines)
103 elif name
== "Physical Memory Array":
104 inv_dmidecode_parse_physical_mem_array(lines
)
105 elif name
== "Memory Device":
106 inv_dmidecode_parse_mem_device(lines
)
108 # TODO: Summe über alle Arrays ausrechnen
110 def inv_dmidecode_parse_date(value
):
113 return time
.mktime(time
.strptime(value
, "%m/%d/%Y"))
117 def inv_dmidecode_parse_bios(lines
):
118 inv_dmidecode_parse_generic("hardware.bios.", lines
, {
120 "Version" : "version",
121 "Release Date" : ("date", inv_dmidecode_parse_date
),
122 "BIOS Revision" : "revision",
123 "Firmware Revision" : "firmware",
126 def inv_dmidecode_parse_system(lines
):
127 inv_dmidecode_parse_generic("hardware.system.", lines
, {
128 "Manufacturer" : "manufacturer",
129 "Product Name" : "product",
130 "Version" : "version",
131 "Serial Number" : "serial",
136 def inv_dmidecode_parse_chassis(lines
):
137 inv_dmidecode_parse_generic("hardware.chassis.", lines
, {
138 "Manufacturer" : "manufacturer",
142 # Note: This node is also being filled by lnx_cpuinfo
143 def inv_dmidecode_parse_processor(lines
):
146 if line
[0] == "Manufacturer":
147 cpu_info
["vendor"] = {
148 "GenuineIntel" : "intel",
149 "Intel(R) Corporation" : "intel",
150 "AuthenticAMD" : "amd",
151 }.get(line
[1], line
[1])
152 elif line
[0] == "Max Speed": # 2530 MHz
153 cpu_info
["max_speed"] = dmidecode_parse_speed(line
[1])
154 elif line
[0] == "Voltage":
155 cpu_info
["voltage"] = dmidecode_parse_voltage(line
[1])
156 elif line
[0] == "Status":
157 if line
[1] == "Unpopulated":
160 # Only update our CPU information if the socket is populated
161 inv_tree("hardware.cpu.").update(cpu_info
)
163 # def inv_dmidecode_parse_mem_controller(lines):
164 # # TODO: Can we have multiple memory controllers
165 # node = inv_tree("hardware.memory.")
167 # if line[0] == "Maximum Memory Module Size":
168 # node["max_module_size"] = dmidecode_parse_size(line[1])
169 # elif line[0] == "Maximum Total Memory Size":
170 # node["max_memory_size"] = dmidecode_parse_size(line[1])
171 # elif line[0] == "Memory Module Voltage":
172 # node["module_voltage"] = dmidecode_parse_voltage(line[1])
174 # def inv_dmidecode_parse_mem_module(lines):
175 # node = inv_tree_list("hardware.memory.modules:")
177 # node.append(module)
179 # if line[0] == "Socket Designation":
180 # module["disignation"] = line[1]
181 # elif line[0] == "Type":
182 # module["type"] = line[1]
183 # elif line[0] == "Installed Size":
184 # module["size"] = dmidecode_parse_size(line[1])
185 # elif line[0] == "Enabled Size":
186 # module["enabled_size"] = dmidecode_parse_size(line[1])
187 # elif line[0] == "Current Speed":
188 # time_sec = dmidecode_parse_time(line[1])
189 # speed = 1.0 / time_sec
190 # module["current_speed"] = speed
192 def inv_dmidecode_parse_physical_mem_array(lines
):
193 # We expect several possible arrays
194 node
= inv_tree_list("hardware.memory.arrays:")
196 # If we have a dummy entry from previous Memory Devices (see below)
197 # then we fill that entry rather than creating a new one
198 if len(node
) == 1 and node
[0].keys() == [ "devices" ]:
207 if line
[0] == "Location":
208 array
["location"] = line
[1]
209 elif line
[0] == "Use":
210 array
["use"] = line
[1]
211 elif line
[0] == "Error Correction Type":
212 array
["error_correction"] = line
[1]
213 elif line
[0] == "Maximum Capacity":
214 array
["maximum_capacity"] = dmidecode_parse_size(line
[1])
216 def inv_dmidecode_parse_mem_device(lines
):
217 node
= inv_tree_list("hardware.memory.arrays:")
220 inv_dmidecode_parse_generic(device
, lines
, {
221 "Total Width" : "total_width", # 64 bits
222 "Data Width" : "data_width", # 64 bits
223 "Form Factor" : "form_factor", # SODIMM
224 "Set" : "set", # None
225 "Locator" : "locator", # PROC 1 DIMM 2
226 "Bank Locator" : "bank_locator", # Bank 2/3
227 "Type" : "type", # DDR2
228 "Type Detail" : "type_detail", # Synchronous
229 "Manufacturer" : "manufacturer", # Not Specified
230 "Serial Number" : "serial", # Not Specified
231 "Asset Tag" : "asset_tag", # Not Specified
232 "Part Number" : "part_number", # Not Specified
233 "Speed" : "speed", # 667 MHz
234 "Size" : "size", # 2048 MB
237 # Do we already have an entry for a memory array? Then
238 # we assume that this device belongs to the most recently
239 # read array. Otherwise we create a dummy entry and replace
240 # that later with actual information
241 # If there are already arrays we try to find the right index of
244 if device
.get("locator") and device
["locator"].startswith("PROC"):
245 index
= device
["locator"].split()[1]
249 array
= node
[int(index
) - 1]
253 array
= { "devices": [] }
256 if device
["size"] != "No Module Installed":
257 # Convert speed and size into numbers
258 device
["speed"] = dmidecode_parse_speed(device
.get("speed", "Unknown"))
259 device
["size"] = dmidecode_parse_size(device
.get("size", "Unknown"))
260 array
["devices"].append(device
)
263 def inv_dmidecode_parse_generic(node
, lines
, keyinfo
):
264 if type(node
) == str:
265 node
= inv_tree(node
)
267 if line
[0] in keyinfo
:
268 key
= keyinfo
[line
[0]]
269 if line
[1] != "Not Specified":
271 if type(key
) == tuple:
273 value
= transform(value
)
279 def dmidecode_parse_size(v
): # into Bytes (int)
284 if parts
[1].lower() == "tb":
285 return int(parts
[0]) * 1024 * 1024 * 1024 * 1024
286 elif parts
[1].lower() == "gb":
287 return int(parts
[0]) * 1024 * 1024 * 1024
288 elif parts
[1].lower() == "mb":
289 return int(parts
[0]) * 1024 * 1024
290 elif parts
[1].lower() == "kb":
291 return int(parts
[0]) * 1024
295 def dmidecode_parse_speed(v
): # into Hz (float)
300 if parts
[1] == "GHz":
301 return float(parts
[0]) * 1000000000.0
302 elif parts
[1] == "MHz":
303 return float(parts
[0]) * 1000000.0
304 elif parts
[1] == "kHz":
305 return float(parts
[0]) * 1000.0
306 elif parts
[1] == "Hz":
307 return float(parts
[0])
309 def dmidecode_parse_voltage(v
):
312 return float(v
.split()[0])
314 def dmidecode_parse_time(v
): # 155 ns
317 return float(parts
[0]) / 1000000000.0
319 return float(parts
[0]) # assume seconds
322 inv_info
['dmidecode'] = {
323 "inv_function" : inv_dmidecode
,