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
|
#
# Author:: Kurt Yoder (ktyopscode@yoderhome.com)
# Copyright:: Copyright (c) 2010 Kurt Yoder
# License:: Apache License, Version 2.0
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#
require "ohai/plugins/dmi_common"
Ohai.plugin do
provides "dmi"
# dmidecode does not return data without access to /dev/mem (or its equivalent)
collect_data do
dmi Mash.new
# all output lines should fall within one of these patterns
handle_line = /^Handle (0x[0-9A-F]{4}), DMI type (\d+), (\d+) bytes/
type_line = /^([A-Z][a-zA-Z ]+)( Information)?/
blank_line = /^\s*$/
data_line = /^\t([^:]+):(?: (.*))?/
extended_data_line = /^\t\t(.+)/
# first lines may contain some interesting information:
# # dmidecode 2.10
# SMBIOS 2.5 present.
# 5 structures occupying 352 bytes.
# Table at 0x000E1000.
dmidecode_version_line = /^# dmidecode (\d+\.\d+)/
smbios_version_line = /^SMBIOS (\d+\.\d+) present\./
structures_line = /^(\d+) structures occupying (\d+) bytes\./
table_location_line = /^Table at (0x[0-9A-E]+)\./
dmi_record = nil
field = nil
popen4("dmidecode") do |pid, stdin, stdout, stderr|
stdin.close
# ==== EXAMPLE RECORD: ====
#Handle 0x0000, DMI type 0, 24 bytes
#BIOS Information
# Vendor: American Megatrends Inc.
# Version: 080012
# ... similar lines trimmed
# Characteristics:
# ISA is supported
# PCI is supported
# ... similar lines trimmed
stdout.each do |line|
next if blank_line.match(line)
if dmidecode_version = dmidecode_version_line.match(line)
dmi[:dmidecode_version] = dmidecode_version[1]
elsif smbios_version = smbios_version_line.match(line)
dmi[:smbios_version] = smbios_version[1]
elsif structures = structures_line.match(line)
dmi[:structures] = Mash.new
dmi[:structures][:count] = structures[1]
dmi[:structures][:size] = structures[2]
elsif table_location = table_location_line.match(line)
dmi[:table_location] = table_location[1]
elsif handle = handle_line.match(line)
# Don't overcapture for now (OHAI-260)
next unless DMI::IdToCapture.include?(handle[2].to_i)
dmi_record = {:type => DMI.id_lookup(handle[2])}
dmi[dmi_record[:type]] = Mash.new unless dmi.has_key?(dmi_record[:type])
dmi[dmi_record[:type]][:all_records] = [] unless dmi[dmi_record[:type]].has_key?(:all_records)
dmi_record[:position] = dmi[dmi_record[:type]][:all_records].length
dmi[dmi_record[:type]][:all_records].push(Mash.new)
dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:record_id] = handle[1]
dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:size] = handle[2]
field = nil
elsif type = type_line.match(line)
if dmi_record == nil
Ohai::Log.debug("unexpected data line found before header; discarding:\n#{line}")
next
end
dmi[dmi_record[:type]][:all_records][dmi_record[:position]][:application_identifier] = type[1]
elsif data = data_line.match(line)
if dmi_record == nil
Ohai::Log.debug("unexpected data line found before header; discarding:\n#{line}")
next
end
dmi[dmi_record[:type]][:all_records][dmi_record[:position]][data[1]] = data[2]
field = data[1]
elsif extended_data = extended_data_line.match(line)
if dmi_record == nil
Ohai::Log.debug("unexpected extended data line found before header; discarding:\n#{line}")
next
end
if field == nil
Ohai::Log.debug("unexpected extended data line found outside data section; discarding:\n#{line}")
next
end
# overwrite "raw" value with a new Mash
dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field] = Mash.new unless dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field].class.to_s == 'Mash'
dmi[dmi_record[:type]][:all_records][dmi_record[:position]][field][extended_data[1]] = nil
else
Ohai::Log.debug("unrecognized output line; discarding:\n#{line}")
end
end
end
DMI.convenience_keys(dmi)
end
end
|