ohai 18.2.6 → 19.0.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/Gemfile +28 -28
- data/LICENSE +201 -201
- data/bin/ohai +25 -25
- data/lib/ohai/application.rb +189 -189
- data/lib/ohai/common/dmi.rb +167 -167
- data/lib/ohai/config.rb +51 -51
- data/lib/ohai/dsl/plugin/versionvii.rb +203 -203
- data/lib/ohai/dsl/plugin.rb +232 -232
- data/lib/ohai/dsl.rb +22 -22
- data/lib/ohai/exception.rb +36 -36
- data/lib/ohai/hints.rb +68 -68
- data/lib/ohai/loader.rb +178 -178
- data/lib/ohai/log.rb +34 -34
- data/lib/ohai/mash.rb +22 -22
- data/lib/ohai/mixin/alibaba_metadata.rb +83 -83
- data/lib/ohai/mixin/azure_metadata.rb +105 -105
- data/lib/ohai/mixin/chef_utils_wiring.rb +52 -52
- data/lib/ohai/mixin/command.rb +4 -4
- data/lib/ohai/mixin/constant_helper.rb +55 -55
- data/lib/ohai/mixin/dmi_decode.rb +54 -54
- data/lib/ohai/mixin/do_metadata.rb +48 -48
- data/lib/ohai/mixin/ec2_metadata.rb +264 -270
- data/lib/ohai/mixin/gce_metadata.rb +79 -79
- data/lib/ohai/mixin/http_helper.rb +64 -64
- data/lib/ohai/mixin/json_helper.rb +36 -36
- data/lib/ohai/mixin/network_helper.rb +92 -92
- data/lib/ohai/mixin/oci_metadata.rb +60 -60
- data/lib/ohai/mixin/os.rb +128 -128
- data/lib/ohai/mixin/scaleway_metadata.rb +51 -51
- data/lib/ohai/mixin/seconds_to_human.rb +52 -52
- data/lib/ohai/mixin/shell_out.rb +51 -51
- data/lib/ohai/mixin/softlayer_metadata.rb +74 -74
- data/lib/ohai/mixin/string.rb +31 -31
- data/lib/ohai/mixin/train_helpers.rb +36 -36
- data/lib/ohai/mixin/which.rb +39 -39
- data/lib/ohai/plugin_config.rb +47 -47
- data/lib/ohai/plugins/aix/kernel.rb +50 -50
- data/lib/ohai/plugins/aix/memory.rb +37 -37
- data/lib/ohai/plugins/aix/network.rb +142 -142
- data/lib/ohai/plugins/aix/platform.rb +30 -30
- data/lib/ohai/plugins/aix/uptime.rb +54 -54
- data/lib/ohai/plugins/aix/virtualization.rb +154 -154
- data/lib/ohai/plugins/alibaba.rb +72 -72
- data/lib/ohai/plugins/azure.rb +154 -154
- data/lib/ohai/plugins/bsd/virtualization.rb +121 -121
- data/lib/ohai/plugins/c.rb +178 -178
- data/lib/ohai/plugins/chef.rb +50 -50
- data/lib/ohai/plugins/cloud.rb +379 -379
- data/lib/ohai/plugins/command.rb +26 -26
- data/lib/ohai/plugins/cpu.rb +642 -642
- data/lib/ohai/plugins/darwin/hardware.rb +99 -99
- data/lib/ohai/plugins/darwin/memory.rb +62 -62
- data/lib/ohai/plugins/darwin/network.rb +207 -207
- data/lib/ohai/plugins/darwin/platform.rb +40 -40
- data/lib/ohai/plugins/darwin/virtualization.rb +104 -104
- data/lib/ohai/plugins/digital_ocean.rb +67 -67
- data/lib/ohai/plugins/dmi.rb +134 -134
- data/lib/ohai/plugins/docker.rb +58 -58
- data/lib/ohai/plugins/dragonflybsd/memory.rb +60 -60
- data/lib/ohai/plugins/dragonflybsd/network.rb +128 -128
- data/lib/ohai/plugins/dragonflybsd/platform.rb +28 -28
- data/lib/ohai/plugins/ec2.rb +148 -148
- data/lib/ohai/plugins/elixir.rb +36 -36
- data/lib/ohai/plugins/erlang.rb +60 -60
- data/lib/ohai/plugins/eucalyptus.rb +86 -86
- data/lib/ohai/plugins/filesystem.rb +753 -753
- data/lib/ohai/plugins/fips.rb +36 -36
- data/lib/ohai/plugins/freebsd/memory.rb +60 -60
- data/lib/ohai/plugins/freebsd/network.rb +128 -128
- data/lib/ohai/plugins/freebsd/platform.rb +28 -28
- data/lib/ohai/plugins/gce.rb +89 -89
- data/lib/ohai/plugins/go.rb +34 -34
- data/lib/ohai/plugins/groovy.rb +38 -38
- data/lib/ohai/plugins/grub2.rb +40 -40
- data/lib/ohai/plugins/habitat.rb +73 -73
- data/lib/ohai/plugins/haskell.rb +96 -96
- data/lib/ohai/plugins/hostname.rb +133 -133
- data/lib/ohai/plugins/init_package.rb +26 -26
- data/lib/ohai/plugins/java.rb +78 -78
- data/lib/ohai/plugins/kernel.rb +292 -292
- data/lib/ohai/plugins/keys.rb +27 -27
- data/lib/ohai/plugins/languages.rb +26 -26
- data/lib/ohai/plugins/libvirt.rb +114 -114
- data/lib/ohai/plugins/linode.rb +73 -73
- data/lib/ohai/plugins/linux/block_device.rb +48 -48
- data/lib/ohai/plugins/linux/hostnamectl.rb +34 -34
- data/lib/ohai/plugins/linux/interrupts.rb +84 -83
- data/lib/ohai/plugins/linux/ipc.rb +52 -52
- data/lib/ohai/plugins/linux/livepatch.rb +38 -38
- data/lib/ohai/plugins/linux/lsb.rb +46 -46
- data/lib/ohai/plugins/linux/lspci.rb +80 -80
- data/lib/ohai/plugins/linux/machineid.rb +36 -36
- data/lib/ohai/plugins/linux/mdadm.rb +120 -120
- data/lib/ohai/plugins/linux/memory.rb +106 -106
- data/lib/ohai/plugins/linux/network.rb +879 -879
- data/lib/ohai/plugins/linux/os_release.rb +38 -38
- data/lib/ohai/plugins/linux/platform.rb +314 -314
- data/lib/ohai/plugins/linux/selinux.rb +69 -69
- data/lib/ohai/plugins/linux/sessions.rb +54 -54
- data/lib/ohai/plugins/linux/sysctl.rb +39 -39
- data/lib/ohai/plugins/linux/systemd_paths.rb +36 -36
- data/lib/ohai/plugins/linux/tc.rb +61 -61
- data/lib/ohai/plugins/linux/virtualization.rb +300 -300
- data/lib/ohai/plugins/lua.rb +39 -39
- data/lib/ohai/plugins/mono.rb +50 -50
- data/lib/ohai/plugins/netbsd/memory.rb +99 -99
- data/lib/ohai/plugins/netbsd/network.rb +122 -122
- data/lib/ohai/plugins/netbsd/platform.rb +28 -28
- data/lib/ohai/plugins/network.rb +186 -186
- data/lib/ohai/plugins/nodejs.rb +40 -40
- data/lib/ohai/plugins/oci.rb +94 -94
- data/lib/ohai/plugins/ohai.rb +29 -29
- data/lib/ohai/plugins/ohai_time.rb +26 -26
- data/lib/ohai/plugins/openbsd/memory.rb +99 -99
- data/lib/ohai/plugins/openbsd/network.rb +122 -122
- data/lib/ohai/plugins/openbsd/platform.rb +28 -28
- data/lib/ohai/plugins/openstack.rb +84 -84
- data/lib/ohai/plugins/os.rb +55 -55
- data/lib/ohai/plugins/packages.rb +234 -234
- data/lib/ohai/plugins/passwd.rb +104 -104
- data/lib/ohai/plugins/perl.rb +45 -45
- data/lib/ohai/plugins/php.rb +52 -52
- data/lib/ohai/plugins/platform.rb +41 -41
- data/lib/ohai/plugins/powershell.rb +82 -82
- data/lib/ohai/plugins/ps.rb +35 -35
- data/lib/ohai/plugins/python.rb +43 -43
- data/lib/ohai/plugins/rackspace.rb +177 -177
- data/lib/ohai/plugins/root_group.rb +41 -41
- data/lib/ohai/plugins/rpm.rb +121 -121
- data/lib/ohai/plugins/ruby.rb +66 -66
- data/lib/ohai/plugins/rust.rb +34 -34
- data/lib/ohai/plugins/scala.rb +38 -38
- data/lib/ohai/plugins/scaleway.rb +58 -58
- data/lib/ohai/plugins/scsi.rb +52 -52
- data/lib/ohai/plugins/shard.rb +142 -142
- data/lib/ohai/plugins/shells.rb +32 -32
- data/lib/ohai/plugins/softlayer.rb +48 -48
- data/lib/ohai/plugins/solaris2/dmi.rb +191 -191
- data/lib/ohai/plugins/solaris2/memory.rb +32 -32
- data/lib/ohai/plugins/solaris2/network.rb +192 -192
- data/lib/ohai/plugins/solaris2/platform.rb +58 -58
- data/lib/ohai/plugins/solaris2/virtualization.rb +90 -90
- data/lib/ohai/plugins/ssh_host_key.rb +84 -84
- data/lib/ohai/plugins/sysconf.rb +46 -46
- data/lib/ohai/plugins/timezone.rb +45 -45
- data/lib/ohai/plugins/train.rb +35 -35
- data/lib/ohai/plugins/uptime.rb +95 -95
- data/lib/ohai/plugins/virtualbox.rb +197 -197
- data/lib/ohai/plugins/vmware.rb +109 -109
- data/lib/ohai/plugins/windows/dmi.rb +95 -95
- data/lib/ohai/plugins/windows/drivers.rb +52 -52
- data/lib/ohai/plugins/windows/memory.rb +39 -39
- data/lib/ohai/plugins/windows/network.rb +222 -222
- data/lib/ohai/plugins/windows/platform.rb +34 -34
- data/lib/ohai/plugins/windows/system_enclosure.rb +29 -29
- data/lib/ohai/plugins/windows/virtualization.rb +45 -45
- data/lib/ohai/plugins/zpools.rb +94 -94
- data/lib/ohai/provides_map.rb +208 -208
- data/lib/ohai/runner.rb +128 -126
- data/lib/ohai/system.rb +258 -258
- data/lib/ohai/train_transport.rb +29 -29
- data/lib/ohai/util/file_helper.rb +6 -6
- data/lib/ohai/util/ip_helper.rb +56 -56
- data/lib/ohai/util/win32.rb +47 -47
- data/lib/ohai/version.rb +23 -23
- data/lib/ohai.rb +23 -23
- data/ohai.gemspec +35 -35
- metadata +9 -15
data/lib/ohai/plugins/cpu.rb
CHANGED
@@ -1,642 +1,642 @@
|
|
1
|
-
# frozen_string_literal: true
|
2
|
-
#
|
3
|
-
# Author:: Adam Jacob (<adam@chef.io>)
|
4
|
-
# Author:: Bryan McLellan (btm@loftninjas.org)
|
5
|
-
# Author:: Tim Smith (tsmith@chef.io)
|
6
|
-
# Author:: Mathieu Sauve-Frankel <msf@kisoku.net>
|
7
|
-
# Author:: Nathan L Smith (<nlloyds@gmail.com>)
|
8
|
-
# Author:: Joshua Timberman <joshua@chef.io>
|
9
|
-
# Author:: Prabhu Das (<prabhu.das@clogeny.com>)
|
10
|
-
# Author:: Isa Farnik (<isa@chef.io>)
|
11
|
-
# Author:: Doug MacEachern <dougm@vmware.com>
|
12
|
-
# Author:: Lance Albertson <lance@osuosl.org>
|
13
|
-
# Copyright:: Copyright (c) Chef Software Inc.
|
14
|
-
# License:: Apache License, Version 2.0
|
15
|
-
#
|
16
|
-
# Licensed under the Apache License, Version 2.0 (the "License");
|
17
|
-
# you may not use this file except in compliance with the License.
|
18
|
-
# You may obtain a copy of the License at
|
19
|
-
#
|
20
|
-
# http://www.apache.org/licenses/LICENSE-2.0
|
21
|
-
#
|
22
|
-
# Unless required by applicable law or agreed to in writing, software
|
23
|
-
# distributed under the License is distributed on an "AS IS" BASIS,
|
24
|
-
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
25
|
-
# See the License for the specific language governing permissions and
|
26
|
-
# limitations under the License.
|
27
|
-
#
|
28
|
-
|
29
|
-
Ohai.plugin(:CPU) do
|
30
|
-
provides "cpu"
|
31
|
-
|
32
|
-
def parse_bsd_dmesg(&block)
|
33
|
-
cpuinfo = Mash.new
|
34
|
-
cpuinfo["flags"] = []
|
35
|
-
file_open("/var/run/dmesg.boot").each do |line|
|
36
|
-
case line
|
37
|
-
when /CPU:\s+(.+) \(([\d.]+).+\)/
|
38
|
-
cpuinfo["model_name"] = $1
|
39
|
-
cpuinfo["mhz"] = $2
|
40
|
-
when /Features=.+<(.+)>/, /Features2=[a-f\dx]+<(.+)>/
|
41
|
-
cpuinfo["flags"].concat($1.downcase.split(","))
|
42
|
-
# Features2=0x80000001<SSE3,<b31>>
|
43
|
-
else
|
44
|
-
yield(cpuinfo, line)
|
45
|
-
end
|
46
|
-
end
|
47
|
-
cpuinfo
|
48
|
-
end
|
49
|
-
|
50
|
-
# Convert a string that looks like range of CPUs to an array
|
51
|
-
# Given the following range: 1-7
|
52
|
-
# Convert it into an array: [1, 2, 3, 4, 5, 6, 7]
|
53
|
-
def range_str_to_a(range)
|
54
|
-
range.split(",").each_with_object([]) do |cpu, arr|
|
55
|
-
if /\d+-\d+/.match?(cpu.to_s)
|
56
|
-
arr << Range.new(*cpu.split("-").map(&:to_i)).to_a
|
57
|
-
else
|
58
|
-
arr << cpu.to_i
|
59
|
-
end
|
60
|
-
end.flatten
|
61
|
-
end
|
62
|
-
|
63
|
-
def parse_lscpu(cpu_info)
|
64
|
-
lscpu_info = Mash.new
|
65
|
-
begin
|
66
|
-
# Pipe to cat to retain previous output on newer util-linux (see lscpu(1))
|
67
|
-
so = shell_out("lscpu | cat")
|
68
|
-
cpu_cores = shell_out("lscpu -p=CPU,CORE,SOCKET")
|
69
|
-
if so.exitstatus == 0 && cpu_cores.exitstatus == 0
|
70
|
-
lscpu_info[:numa_node_cpus] = Mash.new
|
71
|
-
lscpu_info[:vulnerability] = Mash.new
|
72
|
-
so.stdout.each_line do |line|
|
73
|
-
case line
|
74
|
-
when /^Architecture:\s+(.+)/
|
75
|
-
lscpu_info[:architecture] = $1.to_s
|
76
|
-
when /^CPU op-mode\(s\):\s+(.+)/
|
77
|
-
lscpu_info[:cpu_opmodes] = $1.split(", ")
|
78
|
-
when /^Byte Order:\s+(.+)/
|
79
|
-
lscpu_info[:byte_order] = $1.downcase
|
80
|
-
when /^Address sizes:\s+(.+)/
|
81
|
-
lscpu_info[:address_sizes] = $1.split(", ")
|
82
|
-
when /^CPU\(s\):\s+(.+)/
|
83
|
-
lscpu_info[:cpus] = $1.to_i
|
84
|
-
when /^On-line CPU\(s\) list:\s+(.+)/
|
85
|
-
cpu_range = range_str_to_a($1)
|
86
|
-
if cpu_range == [0]
|
87
|
-
lscpu_info[:cpus_online] = 0
|
88
|
-
else
|
89
|
-
lscpu_info[:cpus_online] = cpu_range.length
|
90
|
-
end
|
91
|
-
when /^Off-line CPU\(s\) list:\s+(.+)/
|
92
|
-
cpu_range = range_str_to_a($1)
|
93
|
-
if cpu_range == [0]
|
94
|
-
lscpu_info[:cpus_offline] = 0
|
95
|
-
else
|
96
|
-
lscpu_info[:cpus_offline] = cpu_range.length
|
97
|
-
end
|
98
|
-
when /^Thread\(s\) per core:\s+(.+)/ # http://rubular.com/r/lOw2pRrw1q
|
99
|
-
lscpu_info[:threads_per_core] = $1.to_i
|
100
|
-
when /^Core\(s\) per (?:socket|cluster):\s+(.+)/ # http://rubular.com/r/lOw2pRrw1q
|
101
|
-
lscpu_info[:cores_per_socket] = $1.to_i
|
102
|
-
when /^Socket\(s\):\s+(.+)/ # http://rubular.com/r/DIzmPtJFvK
|
103
|
-
lscpu_info[:sockets] = $1.to_i
|
104
|
-
when /^Clusters\(s\):\s+(.+)/
|
105
|
-
lscpu_info[:clusters] = $1.to_i
|
106
|
-
when /^Socket\(s\) per book:\s+(.+)/
|
107
|
-
lscpu_info[:sockets_per_book] = $1.to_i
|
108
|
-
when /^Book\(s\) per drawer:\s+(.+)/
|
109
|
-
lscpu_info[:books_per_drawer] = $1.to_i
|
110
|
-
when /^Drawer\(s\):\s+(.+)/
|
111
|
-
lscpu_info[:drawers] = $1.to_i
|
112
|
-
when /^NUMA node\(s\):\s+(.+)/
|
113
|
-
lscpu_info[:numa_nodes] = $1.to_i
|
114
|
-
when /^Vendor ID:\s+(.+)/
|
115
|
-
lscpu_info[:vendor_id] = $1
|
116
|
-
when /^BIOS Vendor ID:\s+(.+)/
|
117
|
-
lscpu_info[:bios_vendor_id] = $1
|
118
|
-
when /^BIOS Model name:\s+(.+)/
|
119
|
-
lscpu_info[:bios_model_name] = $1.strip
|
120
|
-
when /^Machine type:\s+(.+)/
|
121
|
-
lscpu_info[:machine_type] = $1
|
122
|
-
when /^CPU family:\s+(.+)/
|
123
|
-
lscpu_info[:family] = $1
|
124
|
-
when /^Model:\s+(.+)/
|
125
|
-
lscpu_info[:model] = $1
|
126
|
-
when /^Model name:\s+(.+)/
|
127
|
-
lscpu_info[:model_name] = $1
|
128
|
-
when /^Stepping:\s+(.+)/
|
129
|
-
lscpu_info[:stepping] = $1
|
130
|
-
when /^CPU MHz:\s+(.+)/
|
131
|
-
lscpu_info[:mhz] = $1
|
132
|
-
when /^CPU static MHz:\s+(.+)/
|
133
|
-
lscpu_info[:mhz] = $1
|
134
|
-
when /^CPU max MHz:\s+(.+)/
|
135
|
-
lscpu_info[:mhz_max] = $1
|
136
|
-
when /^CPU min MHz:\s+(.+)/
|
137
|
-
lscpu_info[:mhz_min] = $1
|
138
|
-
when /^CPU dynamic MHz:\s+(.+)/
|
139
|
-
lscpu_info[:mhz_dynamic] = $1
|
140
|
-
when /^BogoMIPS:\s+(.+)/
|
141
|
-
lscpu_info[:bogomips] = $1
|
142
|
-
when /^Virtualization:\s+(.+)/
|
143
|
-
lscpu_info[:virtualization] = $1
|
144
|
-
when /^Virtualization type:\s+(.+)/
|
145
|
-
lscpu_info[:virtualization_type] = $1
|
146
|
-
when /^Hypervisor vendor:\s+(.+)/
|
147
|
-
lscpu_info[:hypervisor_vendor] = $1
|
148
|
-
when /^Dispatching mode:\s+(.+)/
|
149
|
-
lscpu_info[:dispatching_mode] = $1
|
150
|
-
when /^L1d cache:\s+(.+)/
|
151
|
-
lscpu_info[:l1d_cache] = $1
|
152
|
-
when /^L1i cache:\s+(.+)/
|
153
|
-
lscpu_info[:l1i_cache] = $1
|
154
|
-
when /^L2 cache:\s+(.+)/
|
155
|
-
lscpu_info[:l2_cache] = $1
|
156
|
-
when /^L2d cache:\s+(.+)/
|
157
|
-
lscpu_info[:l2d_cache] = $1
|
158
|
-
when /^L2i cache:\s+(.+)/
|
159
|
-
lscpu_info[:l2i_cache] = $1
|
160
|
-
when /^L3 cache:\s+(.+)/
|
161
|
-
lscpu_info[:l3_cache] = $1
|
162
|
-
when /^L4 cache:\s+(.+)/
|
163
|
-
lscpu_info[:l4_cache] = $1
|
164
|
-
when /^NUMA node(\d+) CPU\(s\):\s+(.+)/
|
165
|
-
numa_node = $1
|
166
|
-
cpus = $2
|
167
|
-
lscpu_info[:numa_node_cpus][numa_node] = range_str_to_a(cpus)
|
168
|
-
when /^Vulnerability (.+?):\s+(.+)/ # https://rubular.com/r/aKtSD1ypUlKbGm
|
169
|
-
name = $1.strip.downcase.tr(" ", "_")
|
170
|
-
description = $2.strip
|
171
|
-
lscpu_info[:vulnerability][name] = Mash.new
|
172
|
-
lscpu_info[:vulnerability][name] = description
|
173
|
-
when /^Flags:\s+(.+)/
|
174
|
-
lscpu_info[:flags] = $1.split(" ").sort
|
175
|
-
# flags are "features" on aarch64 and s390x so add it for backwards computability
|
176
|
-
lscpu_info[:features] = lscpu_info[:flags] if lscpu_info[:architecture].match?(/aarch64|s390x/)
|
177
|
-
end
|
178
|
-
end
|
179
|
-
|
180
|
-
case lscpu_info[:architecture]
|
181
|
-
when "s390x"
|
182
|
-
# Add data from /proc/cpuinfo that isn't available from lscpu
|
183
|
-
lscpu_info[:bogomips_per_cpu] = cpu_info[:bogomips_per_cpu]
|
184
|
-
lscpu_info[:version] = cpu_info["0"][:version]
|
185
|
-
lscpu_info[:identification] = cpu_info["0"][:identification]
|
186
|
-
lscpu_info[:machine] = cpu_info["0"][:machine]
|
187
|
-
lscpu_total = lscpu_info[:sockets_per_book] * lscpu_info[:cores_per_socket] * lscpu_info[:threads_per_core] * lscpu_info[:books_per_drawer] * lscpu_info[:drawers]
|
188
|
-
lscpu_real = lscpu_info[:sockets_per_book]
|
189
|
-
lscpu_cores = lscpu_info[:sockets_per_book] * lscpu_info[:cores_per_socket] * lscpu_info[:books_per_drawer] * lscpu_info[:drawers]
|
190
|
-
when "ppc64le"
|
191
|
-
# Add data from /proc/cpuinfo that isn't available from lscpu
|
192
|
-
lscpu_info[:timebase] = cpu_info[:timebase]
|
193
|
-
lscpu_info[:platform] = cpu_info[:platform]
|
194
|
-
lscpu_info[:machine_model] = cpu_info[:machine_model]
|
195
|
-
lscpu_info[:machine] = cpu_info[:machine]
|
196
|
-
lscpu_info[:firmware] = cpu_info[:firmware] if cpu_info[:firmware]
|
197
|
-
lscpu_info[:mmu] = cpu_info[:mmu] if cpu_info[:mmu]
|
198
|
-
lscpu_info[:mhz] = cpu_info["0"][:mhz]
|
199
|
-
lscpu_total = lscpu_info[:sockets] * lscpu_info[:cores_per_socket] * lscpu_info[:threads_per_core]
|
200
|
-
lscpu_real = lscpu_info[:sockets]
|
201
|
-
lscpu_cores = lscpu_info[:sockets] * lscpu_info[:cores_per_socket]
|
202
|
-
else
|
203
|
-
threads_per_core = [lscpu_info[:threads_per_core], 1].max
|
204
|
-
lscpu_total = lscpu_info[:sockets] * lscpu_info[:cores_per_socket] * threads_per_core
|
205
|
-
lscpu_real = lscpu_info[:sockets]
|
206
|
-
lscpu_cores = lscpu_info[:sockets] * lscpu_info[:cores_per_socket]
|
207
|
-
end
|
208
|
-
|
209
|
-
# Enumerate cpus and fill out data to provide backwards compatibility data
|
210
|
-
cpu_cores.stdout.each_line do |line|
|
211
|
-
current_cpu = nil
|
212
|
-
current_core = nil
|
213
|
-
current_socket = nil
|
214
|
-
|
215
|
-
case line
|
216
|
-
# skip comments
|
217
|
-
when /^#/
|
218
|
-
next
|
219
|
-
# Parse data from "lscpu -p=CPU,CORE,SOCKET"
|
220
|
-
when /(\d+),(\d+),(\d+)/
|
221
|
-
current_cpu = $1
|
222
|
-
current_core = $2
|
223
|
-
current_socket = $3
|
224
|
-
end
|
225
|
-
lscpu_info[current_cpu] = Mash.new
|
226
|
-
lscpu_info[current_cpu][:vendor_id] = lscpu_info[:vendor_id] if lscpu_info[:vendor_id]
|
227
|
-
lscpu_info[current_cpu][:family] = lscpu_info[:family] if lscpu_info[:family]
|
228
|
-
lscpu_info[current_cpu][:model] = lscpu_info[:model] if lscpu_info[:model]
|
229
|
-
lscpu_info[current_cpu][:model_name] = lscpu_info[:model_name] if lscpu_info[:model_name]
|
230
|
-
lscpu_info[current_cpu][:stepping] = lscpu_info[:stepping] if lscpu_info[:stepping]
|
231
|
-
lscpu_info[current_cpu][:mhz] = lscpu_info[:mhz] if lscpu_info[:mhz]
|
232
|
-
lscpu_info[current_cpu][:bogomips] = lscpu_info[:bogomips] if lscpu_info[:bogomips]
|
233
|
-
# Per cpu cache_size is only really available from /proc/cpuinfo on x86
|
234
|
-
lscpu_info[current_cpu][:cache_size] = cpu_info[current_cpu][:cache_size] if cpu_info[current_cpu] && cpu_info[current_cpu][:cache_size]
|
235
|
-
lscpu_info[current_cpu][:physical_id] = current_socket
|
236
|
-
lscpu_info[current_cpu][:core_id] = current_core
|
237
|
-
lscpu_info[current_cpu][:cores] = lscpu_info[:cores_per_socket].to_s
|
238
|
-
lscpu_info[current_cpu][:flags] = lscpu_info[:flags] if lscpu_info[:flags]
|
239
|
-
lscpu_info[current_cpu][:features] = lscpu_info[:flags] if lscpu_info[:architecture].match?(/aarch64|s390x/)
|
240
|
-
if lscpu_info[:architecture] == "s390x"
|
241
|
-
lscpu_info[current_cpu][:version] = cpu_info[current_cpu][:version] if cpu_info[current_cpu][:version]
|
242
|
-
lscpu_info[current_cpu][:identification] = cpu_info[current_cpu][:identification] if cpu_info[current_cpu][:identification]
|
243
|
-
lscpu_info[current_cpu][:machine] = cpu_info[current_cpu][:machine] if cpu_info[current_cpu][:machine]
|
244
|
-
end
|
245
|
-
end
|
246
|
-
lscpu_info[:total] = lscpu_total
|
247
|
-
lscpu_info[:real] = lscpu_real
|
248
|
-
lscpu_info[:cores] = lscpu_cores
|
249
|
-
else
|
250
|
-
logger.trace("Plugin CPU: Error executing lscpu. CPU data may not be available.")
|
251
|
-
end
|
252
|
-
rescue Ohai::Exceptions::Exec # util-linux isn't installed most likely
|
253
|
-
logger.trace("Plugin CPU: Error executing lscpu. util-linux may not be installed.")
|
254
|
-
end
|
255
|
-
lscpu_info
|
256
|
-
end
|
257
|
-
|
258
|
-
def parse_cpuinfo
|
259
|
-
cpuinfo = Mash.new
|
260
|
-
real_cpu = Mash.new
|
261
|
-
cpu_number = 0
|
262
|
-
current_cpu = nil
|
263
|
-
|
264
|
-
file_open("/proc/cpuinfo").each_line do |line|
|
265
|
-
case line
|
266
|
-
when /processor\s+:\s(.+)/
|
267
|
-
cpuinfo[$1] = Mash.new
|
268
|
-
current_cpu = $1
|
269
|
-
cpu_number += 1
|
270
|
-
when /vendor_id\s+:\s(.+)/
|
271
|
-
vendor_id = $1
|
272
|
-
if vendor_id.include?("IBM/S390")
|
273
|
-
cpuinfo["vendor_id"] = vendor_id
|
274
|
-
else
|
275
|
-
cpuinfo[current_cpu]["vendor_id"] = vendor_id
|
276
|
-
end
|
277
|
-
when /cpu family\s+:\s(.+)/
|
278
|
-
cpuinfo[current_cpu]["family"] = $1
|
279
|
-
when /model\s+:\s(.+)/
|
280
|
-
model = $1
|
281
|
-
cpuinfo[current_cpu]["model"] = model
|
282
|
-
# ppc has "model" at the end of /proc/cpuinfo. In addition it should always include a include a dash or "IBM".
|
283
|
-
# So let's put this in cpu/model on ppc
|
284
|
-
cpuinfo["machine_model"] = model if model.match?(/-|IBM/)
|
285
|
-
when /stepping\s+:\s(.+)/
|
286
|
-
cpuinfo[current_cpu]["stepping"] = $1
|
287
|
-
when /physical id\s+:\s(.+)/
|
288
|
-
cpuinfo[current_cpu]["physical_id"] = $1
|
289
|
-
real_cpu[$1] = true
|
290
|
-
when /core id\s+:\s(.+)/
|
291
|
-
cpuinfo[current_cpu]["core_id"] = $1
|
292
|
-
when /cpu cores\s+:\s(.+)/
|
293
|
-
cpuinfo[current_cpu]["cores"] = $1
|
294
|
-
when /model name\s+:\s(.+)/
|
295
|
-
cpuinfo[current_cpu]["model_name"] = $1
|
296
|
-
when /cpu MHz\s+:\s(.+)/
|
297
|
-
cpuinfo[current_cpu]["mhz"] = $1
|
298
|
-
when /cache size\s+:\s(.+)/
|
299
|
-
cpuinfo[current_cpu]["cache_size"] = $1
|
300
|
-
when /flags\s+:\s(.+)/
|
301
|
-
cpuinfo[current_cpu]["flags"] = $1.split
|
302
|
-
when /BogoMIPS\s+:\s(.+)/
|
303
|
-
cpuinfo[current_cpu]["bogomips"] = $1
|
304
|
-
when /Features\s+:\s(.+)/
|
305
|
-
cpuinfo[current_cpu]["features"] = $1.split
|
306
|
-
when /bogomips per cpu:\s(.+)/
|
307
|
-
cpuinfo["bogomips_per_cpu"] = $1
|
308
|
-
when /features\s+:\s(.+)/
|
309
|
-
cpuinfo["features"] = $1.split
|
310
|
-
# ppc64le
|
311
|
-
when /revision\s+:\s(.+)/
|
312
|
-
cpuinfo[current_cpu]["model"] = $1
|
313
|
-
when /cpu\s+:\s(.+)/
|
314
|
-
cpuinfo[current_cpu]["model_name"] = $1
|
315
|
-
when /clock\s+:\s(.+)/
|
316
|
-
cpuinfo[current_cpu]["mhz"] = $1
|
317
|
-
when /timebase\s+:\s(.+)/
|
318
|
-
cpuinfo["timebase"] = $1
|
319
|
-
when /platform\s+:\s(.+)/
|
320
|
-
cpuinfo["platform"] = $1
|
321
|
-
when /machine\s+:\s(.+)/
|
322
|
-
cpuinfo["machine"] = $1
|
323
|
-
when /firmware\s+:\s(.+)/
|
324
|
-
cpuinfo["firmware"] = $1
|
325
|
-
when /MMU\s+:\s(.+)/
|
326
|
-
cpuinfo["mmu"] = $1
|
327
|
-
# s390x
|
328
|
-
when /processor\s(\d):\s(.+)/
|
329
|
-
current_cpu = $1
|
330
|
-
cpu_number += 1
|
331
|
-
cpuinfo[current_cpu] = Mash.new
|
332
|
-
current_cpu_info = $2.split(",")
|
333
|
-
current_cpu_info.each do |i|
|
334
|
-
name_value = i.split("=")
|
335
|
-
name = name_value[0].strip
|
336
|
-
value = name_value[1].strip
|
337
|
-
cpuinfo[current_cpu][name] = value
|
338
|
-
end
|
339
|
-
end
|
340
|
-
end
|
341
|
-
|
342
|
-
# use data we collected unless cpuinfo is lacking core information
|
343
|
-
# which is the case on older linux distros
|
344
|
-
if !real_cpu.empty? && cpuinfo["0"]["cores"]
|
345
|
-
logger.trace("Plugin CPU: Error executing lscpu. CPU data may not be available.")
|
346
|
-
cpuinfo[:real] = real_cpu.keys.length
|
347
|
-
cpuinfo[:cores] = real_cpu.keys.length * cpuinfo["0"]["cores"].to_i
|
348
|
-
else
|
349
|
-
logger.trace("Plugin CPU: real cpu & core data is missing in /proc/cpuinfo and lscpu")
|
350
|
-
end
|
351
|
-
cpuinfo[:total] = cpu_number
|
352
|
-
cpuinfo
|
353
|
-
end
|
354
|
-
|
355
|
-
# Check if the `lscpu` data looks reasonable
|
356
|
-
def valid_lscpu?(lscpu)
|
357
|
-
return false if lscpu.empty?
|
358
|
-
return false if %i{total real cores}.any? { |key| lscpu[key].to_i == 0 }
|
359
|
-
|
360
|
-
true
|
361
|
-
end
|
362
|
-
|
363
|
-
collect_data(:linux) do
|
364
|
-
cpuinfo = parse_cpuinfo
|
365
|
-
lscpu = parse_lscpu(cpuinfo)
|
366
|
-
|
367
|
-
# If we don't have any sensible data from lscpu then get it from /proc/cpuinfo
|
368
|
-
if valid_lscpu?(lscpu)
|
369
|
-
cpu lscpu
|
370
|
-
else
|
371
|
-
cpu cpuinfo
|
372
|
-
end
|
373
|
-
end
|
374
|
-
|
375
|
-
collect_data(:freebsd) do
|
376
|
-
# all dmesg output for smp I can find only provides info about a single processor
|
377
|
-
# identical processors is probably a hardware requirement so we'll duplicate data for each cpu
|
378
|
-
# old examples: http://www.bnv-bamberg.de/home/ba3294/smp/rbuild/index.htm
|
379
|
-
|
380
|
-
# /var/run/dmesg.boot
|
381
|
-
# CPU: Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz (2793.59-MHz K8-class CPU)
|
382
|
-
# Origin="GenuineIntel" Id=0x40661 Family=0x6 Model=0x46 Stepping=1
|
383
|
-
# Features=0x783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2>
|
384
|
-
# Features2=0x5ed8220b<SSE3,PCLMULQDQ,MON,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,AVX,RDRAND>
|
385
|
-
# AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
|
386
|
-
# AMD Features2=0x21<LAHF,ABM>
|
387
|
-
# Structured Extended Features=0x2000<NFPUSG>
|
388
|
-
# TSC: P-state invariant
|
389
|
-
# ...
|
390
|
-
# FreeBSD/SMP: Multiprocessor System Detected: 16 CPUs
|
391
|
-
# FreeBSD/SMP: 2 package(s) x 4 core(s) x 2 SMT threads
|
392
|
-
|
393
|
-
info = parse_bsd_dmesg do |cpuinfo, line|
|
394
|
-
case line
|
395
|
-
when /Origin.*"(.*)".*Family.*0x(\S+).*Model.*0x(\S+).*Stepping.*(\S+)/
|
396
|
-
cpuinfo["vendor_id"] = $1
|
397
|
-
# convert from hex value to int, but keep a string to match Linux ohai
|
398
|
-
cpuinfo["family"] = $2.to_i(16).to_s
|
399
|
-
cpuinfo["model"] = $3.to_i(16).to_s
|
400
|
-
cpuinfo["stepping"] = $4
|
401
|
-
# These _should_ match /AMD Features2?/ lines as well
|
402
|
-
when %r{FreeBSD/SMP: Multiprocessor System Detected: (\d*) CPUs}
|
403
|
-
cpuinfo["total"] = $1.to_i
|
404
|
-
when %r{FreeBSD/SMP: (\d*) package\(s\) x (\d*) core\(s\)}
|
405
|
-
cpuinfo["real"] = $1.to_i
|
406
|
-
cpuinfo["cores"] = $1.to_i * $2.to_i
|
407
|
-
end
|
408
|
-
end
|
409
|
-
cpu info
|
410
|
-
end
|
411
|
-
|
412
|
-
collect_data(:dragonflybsd) do
|
413
|
-
# /var/run/dmesg.boot
|
414
|
-
# CPU: Intel(R) Core(TM) i7-3615QM CPU @ 2.30GHz (3516.61-MHz K8-class CPU)
|
415
|
-
# Origin = "GenuineIntel" Id = 0x306a9 Family = 6 Model = 3a Stepping = 9
|
416
|
-
# Features=0x783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2>
|
417
|
-
# Features2=0x209<SSE3,MON,SSSE3>
|
418
|
-
# AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
|
419
|
-
# AMD Features2=0x1<LAHF>
|
420
|
-
|
421
|
-
info = parse_bsd_dmesg do |cpuinfo, line|
|
422
|
-
case line
|
423
|
-
when /Origin = "(.+)"\s+Id = (.+)\s+Stepping = (.+)/
|
424
|
-
cpuinfo["vendor_id"] = $1
|
425
|
-
cpuinfo["stepping"] = $3
|
426
|
-
end
|
427
|
-
end
|
428
|
-
|
429
|
-
so = shell_out("sysctl -n hw.ncpu")
|
430
|
-
info[:total] = so.stdout.strip.to_i
|
431
|
-
cpu info
|
432
|
-
end
|
433
|
-
|
434
|
-
collect_data(:openbsd) do
|
435
|
-
cpuinfo = Mash.new
|
436
|
-
|
437
|
-
# OpenBSD provides most cpu information via sysctl, the only thing we need to
|
438
|
-
# to scrape from dmesg.boot is the cpu feature list.
|
439
|
-
# cpu0: FPU,V86,DE,PSE,TSC,MSR,MCE,CX8,SEP,MTRR,PGE,MCA,CMOV,PAT,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,TM,SBF,EST,TM2
|
440
|
-
|
441
|
-
file_open("/var/run/dmesg.boot").each do |line|
|
442
|
-
case line
|
443
|
-
when /cpu\d+:\s+([A-Z]+$|[A-Z]+,.*$)/
|
444
|
-
cpuinfo["flags"] = $1.downcase.split(",")
|
445
|
-
end
|
446
|
-
end
|
447
|
-
|
448
|
-
[["hw.model", :model_name], ["hw.ncpu", :total], ["hw.cpuspeed", :mhz]].each do |param, node|
|
449
|
-
so = shell_out("sysctl -n #{param}")
|
450
|
-
cpuinfo[node] = so.stdout.strip
|
451
|
-
end
|
452
|
-
|
453
|
-
cpu cpuinfo
|
454
|
-
end
|
455
|
-
|
456
|
-
collect_data(:netbsd) do
|
457
|
-
cpuinfo = Mash.new
|
458
|
-
|
459
|
-
# NetBSD provides some cpu information via sysctl, and a little via dmesg.boot
|
460
|
-
# unlike OpenBSD and FreeBSD, NetBSD does not provide information about the
|
461
|
-
# available instruction set
|
462
|
-
# cpu0 at mainbus0 apid 0: Intel 686-class, 2134MHz, id 0x6f6
|
463
|
-
|
464
|
-
file_open("/var/run/dmesg.boot").each do |line|
|
465
|
-
case line
|
466
|
-
when /cpu[\d\w\s]+:\s([\w\s\-]+),\s+(\w+),/
|
467
|
-
cpuinfo[:model_name] = $1
|
468
|
-
cpuinfo[:mhz] = $2.gsub(/mhz/i, "")
|
469
|
-
end
|
470
|
-
end
|
471
|
-
|
472
|
-
flags = []
|
473
|
-
so = shell_out("dmidecode")
|
474
|
-
so.stdout.lines do |line|
|
475
|
-
if line =~ /^\s+([A-Z\d-]+)\s+\([\w\s-]+\)$/
|
476
|
-
flags << $1.downcase
|
477
|
-
end
|
478
|
-
end
|
479
|
-
|
480
|
-
cpuinfo[:flags] = flags unless flags.empty?
|
481
|
-
|
482
|
-
cpu cpuinfo
|
483
|
-
end
|
484
|
-
|
485
|
-
collect_data(:darwin) do
|
486
|
-
cpu Mash.new
|
487
|
-
shell_out("sysctl hw machdep").stdout.lines.each do |line|
|
488
|
-
case line
|
489
|
-
when /^hw.packages: (.*)$/
|
490
|
-
cpu[:real] = Regexp.last_match[1].to_i
|
491
|
-
when /^hw.physicalcpu: (.*)$/
|
492
|
-
cpu[:cores] = Regexp.last_match[1].to_i
|
493
|
-
when /^hw.logicalcpu: (.*)$/
|
494
|
-
cpu[:total] = Regexp.last_match[1].to_i
|
495
|
-
when /^hw.cpufrequency: (.*)$/
|
496
|
-
cpu[:mhz] = Regexp.last_match[1].to_i / 1000000
|
497
|
-
when /^machdep.cpu.vendor: (.*)$/
|
498
|
-
cpu[:vendor_id] = Regexp.last_match[1].chomp
|
499
|
-
when /^machdep.cpu.brand_string: (.*)$/
|
500
|
-
cpu[:model_name] = Regexp.last_match[1].chomp
|
501
|
-
when /^machdep.cpu.model: (.*)$/
|
502
|
-
cpu[:model] = Regexp.last_match[1].to_i
|
503
|
-
when /^machdep.cpu.family: (.*)$/
|
504
|
-
cpu[:family] = Regexp.last_match[1].to_i
|
505
|
-
when /^machdep.cpu.stepping: (.*)$/
|
506
|
-
cpu[:stepping] = Regexp.last_match[1].to_i
|
507
|
-
when /^machdep.cpu.features: (.*)$/
|
508
|
-
cpu[:flags] = Regexp.last_match[1].downcase.split
|
509
|
-
end
|
510
|
-
end
|
511
|
-
end
|
512
|
-
|
513
|
-
collect_data(:aix) do
|
514
|
-
cpu Mash.new
|
515
|
-
|
516
|
-
cpu[:total] = shell_out("pmcycles -m").stdout.lines.length
|
517
|
-
|
518
|
-
# The below is only relevant on an LPAR
|
519
|
-
if shell_out("uname -W").stdout.strip == "0"
|
520
|
-
|
521
|
-
# At least one CPU will be available, but we'll wait to increment this later.
|
522
|
-
cpu[:available] = 0
|
523
|
-
|
524
|
-
cpudevs = shell_out("lsdev -Cc processor").stdout.lines
|
525
|
-
# from http://www-01.ibm.com/software/passportadvantage/pvu_terminology_for_customers.html
|
526
|
-
# on AIX number of cores and processors are considered same
|
527
|
-
cpu[:real] = cpu[:cores] = cpudevs.length
|
528
|
-
cpudevs.each.with_index do |c, i|
|
529
|
-
name, status, location = c.split
|
530
|
-
index = i.to_s
|
531
|
-
cpu[index] = Mash.new
|
532
|
-
cpu[index][:status] = status
|
533
|
-
cpu[index][:location] = location
|
534
|
-
if status.include?("Available")
|
535
|
-
cpu[:available] += 1
|
536
|
-
lsattr = shell_out("lsattr -El #{name}").stdout.lines
|
537
|
-
lsattr.each do |attribute|
|
538
|
-
attrib, value = attribute.split
|
539
|
-
if attrib == "type"
|
540
|
-
cpu[index][:model_name] = value
|
541
|
-
elsif attrib == "frequency"
|
542
|
-
cpu[index][:mhz] = value.to_i / (1000 * 1000) # convert from hz to MHz
|
543
|
-
else
|
544
|
-
cpu[index][attrib] = value
|
545
|
-
end
|
546
|
-
end
|
547
|
-
# IBM is the only maker of CPUs for AIX systems.
|
548
|
-
cpu[index][:vendor_id] = "IBM"
|
549
|
-
end
|
550
|
-
end
|
551
|
-
end
|
552
|
-
end
|
553
|
-
|
554
|
-
collect_data(:solaris2) do
|
555
|
-
cpu Mash.new
|
556
|
-
# This does assume that /usr/bin/kstat is in the path
|
557
|
-
processor_info = shell_out("kstat -p cpu_info").stdout.lines
|
558
|
-
cpu["total"] = 0
|
559
|
-
cpu["sockets"] = 0
|
560
|
-
cpu["cores"] = 0
|
561
|
-
cpu["corethreads"] = 0
|
562
|
-
cpu["cpustates"] = Mash.new
|
563
|
-
|
564
|
-
currentcpu = 0
|
565
|
-
cpucores = []
|
566
|
-
cpusockets = []
|
567
|
-
processor_info.each do |processor|
|
568
|
-
_desc, instance, _record, keyvalue = processor.split(":")
|
569
|
-
cpu[instance] ||= Mash.new
|
570
|
-
if currentcpu != instance
|
571
|
-
cpu["total"] += 1
|
572
|
-
currentcpu = instance
|
573
|
-
end
|
574
|
-
kv = keyvalue.split(/\s+/)
|
575
|
-
key = kv.shift
|
576
|
-
value = kv.join(" ").chomp
|
577
|
-
case key
|
578
|
-
when /chip_id/
|
579
|
-
cpu[instance]["socket"] = value
|
580
|
-
cpusockets.push(value) if cpusockets.index(value).nil?
|
581
|
-
when /cpu_type/
|
582
|
-
cpu[instance]["arch"] = value
|
583
|
-
when /clock_MHz/
|
584
|
-
cpu[instance]["mhz"] = value
|
585
|
-
when /brand/
|
586
|
-
cpu[instance]["model_name"] = value.sub(/\s+/, " ")
|
587
|
-
when /^state$/
|
588
|
-
cpu[instance]["state"] = value
|
589
|
-
cpu["cpustates"][value] ||= 0
|
590
|
-
cpu["cpustates"][value] += 1
|
591
|
-
when /core_id/
|
592
|
-
cpu[instance]["core_id"] = value
|
593
|
-
# Detect hyperthreading/multithreading
|
594
|
-
cpucores.push(value) if cpucores.index(value).nil?
|
595
|
-
when /family|fpu_type|model|stepping|vendor_id/
|
596
|
-
cpu[instance][key] = value
|
597
|
-
end
|
598
|
-
end
|
599
|
-
cpu["cores"] = cpucores.size
|
600
|
-
cpu["corethreads"] = (cpu["total"] / cpucores.size)
|
601
|
-
cpu["sockets"] = cpusockets.size
|
602
|
-
cpu["real"] = cpusockets.size
|
603
|
-
end
|
604
|
-
|
605
|
-
collect_data(:windows) do
|
606
|
-
require "wmi-lite/wmi" unless defined?(WmiLite::Wmi)
|
607
|
-
|
608
|
-
cpu Mash.new
|
609
|
-
cores = 0
|
610
|
-
logical_processors = 0
|
611
|
-
|
612
|
-
wmi = WmiLite::Wmi.new
|
613
|
-
processors = wmi.instances_of("Win32_Processor")
|
614
|
-
|
615
|
-
processors.each_with_index do |processor, index|
|
616
|
-
current_cpu = index.to_s
|
617
|
-
cpu[current_cpu] = Mash.new
|
618
|
-
|
619
|
-
cpu[current_cpu]["cores"] = processor["numberofcores"]
|
620
|
-
cores += processor["numberofcores"]
|
621
|
-
|
622
|
-
logical_processors += processor["numberoflogicalprocessors"]
|
623
|
-
cpu[current_cpu]["vendor_id"] = processor["manufacturer"]
|
624
|
-
cpu[current_cpu]["family"] = processor["family"].to_s
|
625
|
-
cpu[current_cpu]["model"] = processor["revision"].to_s
|
626
|
-
cpu[current_cpu]["stepping"] = if processor["stepping"].nil?
|
627
|
-
processor["description"].match(/Stepping\s+(\d+)/)[1]
|
628
|
-
else
|
629
|
-
processor["stepping"]
|
630
|
-
end
|
631
|
-
cpu[current_cpu]["physical_id"] = processor["deviceid"]
|
632
|
-
cpu[current_cpu]["model_name"] = processor["name"]
|
633
|
-
cpu[current_cpu]["description"] = processor["description"]
|
634
|
-
cpu[current_cpu]["mhz"] = processor["maxclockspeed"].to_s
|
635
|
-
cpu[current_cpu]["cache_size"] = "#{processor["l2cachesize"]} KB"
|
636
|
-
end
|
637
|
-
|
638
|
-
cpu[:total] = logical_processors
|
639
|
-
cpu[:cores] = cores
|
640
|
-
cpu[:real] =
|
641
|
-
end
|
642
|
-
end
|
1
|
+
# frozen_string_literal: true
|
2
|
+
#
|
3
|
+
# Author:: Adam Jacob (<adam@chef.io>)
|
4
|
+
# Author:: Bryan McLellan (btm@loftninjas.org)
|
5
|
+
# Author:: Tim Smith (tsmith@chef.io)
|
6
|
+
# Author:: Mathieu Sauve-Frankel <msf@kisoku.net>
|
7
|
+
# Author:: Nathan L Smith (<nlloyds@gmail.com>)
|
8
|
+
# Author:: Joshua Timberman <joshua@chef.io>
|
9
|
+
# Author:: Prabhu Das (<prabhu.das@clogeny.com>)
|
10
|
+
# Author:: Isa Farnik (<isa@chef.io>)
|
11
|
+
# Author:: Doug MacEachern <dougm@vmware.com>
|
12
|
+
# Author:: Lance Albertson <lance@osuosl.org>
|
13
|
+
# Copyright:: Copyright (c) Chef Software Inc.
|
14
|
+
# License:: Apache License, Version 2.0
|
15
|
+
#
|
16
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
17
|
+
# you may not use this file except in compliance with the License.
|
18
|
+
# You may obtain a copy of the License at
|
19
|
+
#
|
20
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
21
|
+
#
|
22
|
+
# Unless required by applicable law or agreed to in writing, software
|
23
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
24
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
25
|
+
# See the License for the specific language governing permissions and
|
26
|
+
# limitations under the License.
|
27
|
+
#
|
28
|
+
|
29
|
+
Ohai.plugin(:CPU) do
|
30
|
+
provides "cpu"
|
31
|
+
|
32
|
+
def parse_bsd_dmesg(&block)
|
33
|
+
cpuinfo = Mash.new
|
34
|
+
cpuinfo["flags"] = []
|
35
|
+
file_open("/var/run/dmesg.boot").each do |line|
|
36
|
+
case line
|
37
|
+
when /CPU:\s+(.+) \(([\d.]+).+\)/
|
38
|
+
cpuinfo["model_name"] = $1
|
39
|
+
cpuinfo["mhz"] = $2
|
40
|
+
when /Features=.+<(.+)>/, /Features2=[a-f\dx]+<(.+)>/
|
41
|
+
cpuinfo["flags"].concat($1.downcase.split(","))
|
42
|
+
# Features2=0x80000001<SSE3,<b31>>
|
43
|
+
else
|
44
|
+
yield(cpuinfo, line)
|
45
|
+
end
|
46
|
+
end
|
47
|
+
cpuinfo
|
48
|
+
end
|
49
|
+
|
50
|
+
# Convert a string that looks like range of CPUs to an array
|
51
|
+
# Given the following range: 1-7
|
52
|
+
# Convert it into an array: [1, 2, 3, 4, 5, 6, 7]
|
53
|
+
def range_str_to_a(range)
|
54
|
+
range.split(",").each_with_object([]) do |cpu, arr|
|
55
|
+
if /\d+-\d+/.match?(cpu.to_s)
|
56
|
+
arr << Range.new(*cpu.split("-").map(&:to_i)).to_a
|
57
|
+
else
|
58
|
+
arr << cpu.to_i
|
59
|
+
end
|
60
|
+
end.flatten
|
61
|
+
end
|
62
|
+
|
63
|
+
def parse_lscpu(cpu_info)
|
64
|
+
lscpu_info = Mash.new
|
65
|
+
begin
|
66
|
+
# Pipe to cat to retain previous output on newer util-linux (see lscpu(1))
|
67
|
+
so = shell_out("lscpu | cat")
|
68
|
+
cpu_cores = shell_out("lscpu -p=CPU,CORE,SOCKET")
|
69
|
+
if so.exitstatus == 0 && cpu_cores.exitstatus == 0
|
70
|
+
lscpu_info[:numa_node_cpus] = Mash.new
|
71
|
+
lscpu_info[:vulnerability] = Mash.new
|
72
|
+
so.stdout.each_line do |line|
|
73
|
+
case line
|
74
|
+
when /^Architecture:\s+(.+)/
|
75
|
+
lscpu_info[:architecture] = $1.to_s
|
76
|
+
when /^CPU op-mode\(s\):\s+(.+)/
|
77
|
+
lscpu_info[:cpu_opmodes] = $1.split(", ")
|
78
|
+
when /^Byte Order:\s+(.+)/
|
79
|
+
lscpu_info[:byte_order] = $1.downcase
|
80
|
+
when /^Address sizes:\s+(.+)/
|
81
|
+
lscpu_info[:address_sizes] = $1.split(", ")
|
82
|
+
when /^CPU\(s\):\s+(.+)/
|
83
|
+
lscpu_info[:cpus] = $1.to_i
|
84
|
+
when /^On-line CPU\(s\) list:\s+(.+)/
|
85
|
+
cpu_range = range_str_to_a($1)
|
86
|
+
if cpu_range == [0]
|
87
|
+
lscpu_info[:cpus_online] = 0
|
88
|
+
else
|
89
|
+
lscpu_info[:cpus_online] = cpu_range.length
|
90
|
+
end
|
91
|
+
when /^Off-line CPU\(s\) list:\s+(.+)/
|
92
|
+
cpu_range = range_str_to_a($1)
|
93
|
+
if cpu_range == [0]
|
94
|
+
lscpu_info[:cpus_offline] = 0
|
95
|
+
else
|
96
|
+
lscpu_info[:cpus_offline] = cpu_range.length
|
97
|
+
end
|
98
|
+
when /^Thread\(s\) per core:\s+(.+)/ # http://rubular.com/r/lOw2pRrw1q
|
99
|
+
lscpu_info[:threads_per_core] = $1.to_i
|
100
|
+
when /^Core\(s\) per (?:socket|cluster):\s+(.+)/ # http://rubular.com/r/lOw2pRrw1q
|
101
|
+
lscpu_info[:cores_per_socket] = $1.to_i
|
102
|
+
when /^Socket\(s\):\s+(.+)/ # http://rubular.com/r/DIzmPtJFvK
|
103
|
+
lscpu_info[:sockets] = $1.to_i
|
104
|
+
when /^Clusters\(s\):\s+(.+)/
|
105
|
+
lscpu_info[:clusters] = $1.to_i
|
106
|
+
when /^Socket\(s\) per book:\s+(.+)/
|
107
|
+
lscpu_info[:sockets_per_book] = $1.to_i
|
108
|
+
when /^Book\(s\) per drawer:\s+(.+)/
|
109
|
+
lscpu_info[:books_per_drawer] = $1.to_i
|
110
|
+
when /^Drawer\(s\):\s+(.+)/
|
111
|
+
lscpu_info[:drawers] = $1.to_i
|
112
|
+
when /^NUMA node\(s\):\s+(.+)/
|
113
|
+
lscpu_info[:numa_nodes] = $1.to_i
|
114
|
+
when /^Vendor ID:\s+(.+)/
|
115
|
+
lscpu_info[:vendor_id] = $1
|
116
|
+
when /^BIOS Vendor ID:\s+(.+)/
|
117
|
+
lscpu_info[:bios_vendor_id] = $1
|
118
|
+
when /^BIOS Model name:\s+(.+)/
|
119
|
+
lscpu_info[:bios_model_name] = $1.strip
|
120
|
+
when /^Machine type:\s+(.+)/
|
121
|
+
lscpu_info[:machine_type] = $1
|
122
|
+
when /^CPU family:\s+(.+)/
|
123
|
+
lscpu_info[:family] = $1
|
124
|
+
when /^Model:\s+(.+)/
|
125
|
+
lscpu_info[:model] = $1
|
126
|
+
when /^Model name:\s+(.+)/
|
127
|
+
lscpu_info[:model_name] = $1
|
128
|
+
when /^Stepping:\s+(.+)/
|
129
|
+
lscpu_info[:stepping] = $1
|
130
|
+
when /^CPU MHz:\s+(.+)/
|
131
|
+
lscpu_info[:mhz] = $1
|
132
|
+
when /^CPU static MHz:\s+(.+)/
|
133
|
+
lscpu_info[:mhz] = $1
|
134
|
+
when /^CPU max MHz:\s+(.+)/
|
135
|
+
lscpu_info[:mhz_max] = $1
|
136
|
+
when /^CPU min MHz:\s+(.+)/
|
137
|
+
lscpu_info[:mhz_min] = $1
|
138
|
+
when /^CPU dynamic MHz:\s+(.+)/
|
139
|
+
lscpu_info[:mhz_dynamic] = $1
|
140
|
+
when /^BogoMIPS:\s+(.+)/
|
141
|
+
lscpu_info[:bogomips] = $1
|
142
|
+
when /^Virtualization:\s+(.+)/
|
143
|
+
lscpu_info[:virtualization] = $1
|
144
|
+
when /^Virtualization type:\s+(.+)/
|
145
|
+
lscpu_info[:virtualization_type] = $1
|
146
|
+
when /^Hypervisor vendor:\s+(.+)/
|
147
|
+
lscpu_info[:hypervisor_vendor] = $1
|
148
|
+
when /^Dispatching mode:\s+(.+)/
|
149
|
+
lscpu_info[:dispatching_mode] = $1
|
150
|
+
when /^L1d cache:\s+(.+)/
|
151
|
+
lscpu_info[:l1d_cache] = $1
|
152
|
+
when /^L1i cache:\s+(.+)/
|
153
|
+
lscpu_info[:l1i_cache] = $1
|
154
|
+
when /^L2 cache:\s+(.+)/
|
155
|
+
lscpu_info[:l2_cache] = $1
|
156
|
+
when /^L2d cache:\s+(.+)/
|
157
|
+
lscpu_info[:l2d_cache] = $1
|
158
|
+
when /^L2i cache:\s+(.+)/
|
159
|
+
lscpu_info[:l2i_cache] = $1
|
160
|
+
when /^L3 cache:\s+(.+)/
|
161
|
+
lscpu_info[:l3_cache] = $1
|
162
|
+
when /^L4 cache:\s+(.+)/
|
163
|
+
lscpu_info[:l4_cache] = $1
|
164
|
+
when /^NUMA node(\d+) CPU\(s\):\s+(.+)/
|
165
|
+
numa_node = $1
|
166
|
+
cpus = $2
|
167
|
+
lscpu_info[:numa_node_cpus][numa_node] = range_str_to_a(cpus)
|
168
|
+
when /^Vulnerability (.+?):\s+(.+)/ # https://rubular.com/r/aKtSD1ypUlKbGm
|
169
|
+
name = $1.strip.downcase.tr(" ", "_")
|
170
|
+
description = $2.strip
|
171
|
+
lscpu_info[:vulnerability][name] = Mash.new
|
172
|
+
lscpu_info[:vulnerability][name] = description
|
173
|
+
when /^Flags:\s+(.+)/
|
174
|
+
lscpu_info[:flags] = $1.split(" ").sort
|
175
|
+
# flags are "features" on aarch64 and s390x so add it for backwards computability
|
176
|
+
lscpu_info[:features] = lscpu_info[:flags] if lscpu_info[:architecture].match?(/aarch64|s390x/)
|
177
|
+
end
|
178
|
+
end
|
179
|
+
|
180
|
+
case lscpu_info[:architecture]
|
181
|
+
when "s390x"
|
182
|
+
# Add data from /proc/cpuinfo that isn't available from lscpu
|
183
|
+
lscpu_info[:bogomips_per_cpu] = cpu_info[:bogomips_per_cpu]
|
184
|
+
lscpu_info[:version] = cpu_info["0"][:version]
|
185
|
+
lscpu_info[:identification] = cpu_info["0"][:identification]
|
186
|
+
lscpu_info[:machine] = cpu_info["0"][:machine]
|
187
|
+
lscpu_total = lscpu_info[:sockets_per_book] * lscpu_info[:cores_per_socket] * lscpu_info[:threads_per_core] * lscpu_info[:books_per_drawer] * lscpu_info[:drawers]
|
188
|
+
lscpu_real = lscpu_info[:sockets_per_book]
|
189
|
+
lscpu_cores = lscpu_info[:sockets_per_book] * lscpu_info[:cores_per_socket] * lscpu_info[:books_per_drawer] * lscpu_info[:drawers]
|
190
|
+
when "ppc64le"
|
191
|
+
# Add data from /proc/cpuinfo that isn't available from lscpu
|
192
|
+
lscpu_info[:timebase] = cpu_info[:timebase]
|
193
|
+
lscpu_info[:platform] = cpu_info[:platform]
|
194
|
+
lscpu_info[:machine_model] = cpu_info[:machine_model]
|
195
|
+
lscpu_info[:machine] = cpu_info[:machine]
|
196
|
+
lscpu_info[:firmware] = cpu_info[:firmware] if cpu_info[:firmware]
|
197
|
+
lscpu_info[:mmu] = cpu_info[:mmu] if cpu_info[:mmu]
|
198
|
+
lscpu_info[:mhz] = cpu_info["0"][:mhz]
|
199
|
+
lscpu_total = lscpu_info[:sockets] * lscpu_info[:cores_per_socket] * lscpu_info[:threads_per_core]
|
200
|
+
lscpu_real = lscpu_info[:sockets]
|
201
|
+
lscpu_cores = lscpu_info[:sockets] * lscpu_info[:cores_per_socket]
|
202
|
+
else
|
203
|
+
threads_per_core = [lscpu_info[:threads_per_core], 1].max
|
204
|
+
lscpu_total = lscpu_info[:sockets] * lscpu_info[:cores_per_socket] * threads_per_core
|
205
|
+
lscpu_real = lscpu_info[:sockets]
|
206
|
+
lscpu_cores = lscpu_info[:sockets] * lscpu_info[:cores_per_socket]
|
207
|
+
end
|
208
|
+
|
209
|
+
# Enumerate cpus and fill out data to provide backwards compatibility data
|
210
|
+
cpu_cores.stdout.each_line do |line|
|
211
|
+
current_cpu = nil
|
212
|
+
current_core = nil
|
213
|
+
current_socket = nil
|
214
|
+
|
215
|
+
case line
|
216
|
+
# skip comments
|
217
|
+
when /^#/
|
218
|
+
next
|
219
|
+
# Parse data from "lscpu -p=CPU,CORE,SOCKET"
|
220
|
+
when /(\d+),(\d+),(\d+)/
|
221
|
+
current_cpu = $1
|
222
|
+
current_core = $2
|
223
|
+
current_socket = $3
|
224
|
+
end
|
225
|
+
lscpu_info[current_cpu] = Mash.new
|
226
|
+
lscpu_info[current_cpu][:vendor_id] = lscpu_info[:vendor_id] if lscpu_info[:vendor_id]
|
227
|
+
lscpu_info[current_cpu][:family] = lscpu_info[:family] if lscpu_info[:family]
|
228
|
+
lscpu_info[current_cpu][:model] = lscpu_info[:model] if lscpu_info[:model]
|
229
|
+
lscpu_info[current_cpu][:model_name] = lscpu_info[:model_name] if lscpu_info[:model_name]
|
230
|
+
lscpu_info[current_cpu][:stepping] = lscpu_info[:stepping] if lscpu_info[:stepping]
|
231
|
+
lscpu_info[current_cpu][:mhz] = lscpu_info[:mhz] if lscpu_info[:mhz]
|
232
|
+
lscpu_info[current_cpu][:bogomips] = lscpu_info[:bogomips] if lscpu_info[:bogomips]
|
233
|
+
# Per cpu cache_size is only really available from /proc/cpuinfo on x86
|
234
|
+
lscpu_info[current_cpu][:cache_size] = cpu_info[current_cpu][:cache_size] if cpu_info[current_cpu] && cpu_info[current_cpu][:cache_size]
|
235
|
+
lscpu_info[current_cpu][:physical_id] = current_socket
|
236
|
+
lscpu_info[current_cpu][:core_id] = current_core
|
237
|
+
lscpu_info[current_cpu][:cores] = lscpu_info[:cores_per_socket].to_s
|
238
|
+
lscpu_info[current_cpu][:flags] = lscpu_info[:flags] if lscpu_info[:flags]
|
239
|
+
lscpu_info[current_cpu][:features] = lscpu_info[:flags] if lscpu_info[:architecture].match?(/aarch64|s390x/)
|
240
|
+
if lscpu_info[:architecture] == "s390x"
|
241
|
+
lscpu_info[current_cpu][:version] = cpu_info[current_cpu][:version] if cpu_info[current_cpu][:version]
|
242
|
+
lscpu_info[current_cpu][:identification] = cpu_info[current_cpu][:identification] if cpu_info[current_cpu][:identification]
|
243
|
+
lscpu_info[current_cpu][:machine] = cpu_info[current_cpu][:machine] if cpu_info[current_cpu][:machine]
|
244
|
+
end
|
245
|
+
end
|
246
|
+
lscpu_info[:total] = lscpu_total
|
247
|
+
lscpu_info[:real] = lscpu_real
|
248
|
+
lscpu_info[:cores] = lscpu_cores
|
249
|
+
else
|
250
|
+
logger.trace("Plugin CPU: Error executing lscpu. CPU data may not be available.")
|
251
|
+
end
|
252
|
+
rescue Ohai::Exceptions::Exec # util-linux isn't installed most likely
|
253
|
+
logger.trace("Plugin CPU: Error executing lscpu. util-linux may not be installed.")
|
254
|
+
end
|
255
|
+
lscpu_info
|
256
|
+
end
|
257
|
+
|
258
|
+
def parse_cpuinfo
|
259
|
+
cpuinfo = Mash.new
|
260
|
+
real_cpu = Mash.new
|
261
|
+
cpu_number = 0
|
262
|
+
current_cpu = nil
|
263
|
+
|
264
|
+
file_open("/proc/cpuinfo").each_line do |line|
|
265
|
+
case line
|
266
|
+
when /processor\s+:\s(.+)/
|
267
|
+
cpuinfo[$1] = Mash.new
|
268
|
+
current_cpu = $1
|
269
|
+
cpu_number += 1
|
270
|
+
when /vendor_id\s+:\s(.+)/
|
271
|
+
vendor_id = $1
|
272
|
+
if vendor_id.include?("IBM/S390")
|
273
|
+
cpuinfo["vendor_id"] = vendor_id
|
274
|
+
else
|
275
|
+
cpuinfo[current_cpu]["vendor_id"] = vendor_id
|
276
|
+
end
|
277
|
+
when /cpu family\s+:\s(.+)/
|
278
|
+
cpuinfo[current_cpu]["family"] = $1
|
279
|
+
when /model\s+:\s(.+)/
|
280
|
+
model = $1
|
281
|
+
cpuinfo[current_cpu]["model"] = model
|
282
|
+
# ppc has "model" at the end of /proc/cpuinfo. In addition it should always include a include a dash or "IBM".
|
283
|
+
# So let's put this in cpu/model on ppc
|
284
|
+
cpuinfo["machine_model"] = model if model.match?(/-|IBM/)
|
285
|
+
when /stepping\s+:\s(.+)/
|
286
|
+
cpuinfo[current_cpu]["stepping"] = $1
|
287
|
+
when /physical id\s+:\s(.+)/
|
288
|
+
cpuinfo[current_cpu]["physical_id"] = $1
|
289
|
+
real_cpu[$1] = true
|
290
|
+
when /core id\s+:\s(.+)/
|
291
|
+
cpuinfo[current_cpu]["core_id"] = $1
|
292
|
+
when /cpu cores\s+:\s(.+)/
|
293
|
+
cpuinfo[current_cpu]["cores"] = $1
|
294
|
+
when /model name\s+:\s(.+)/
|
295
|
+
cpuinfo[current_cpu]["model_name"] = $1
|
296
|
+
when /cpu MHz\s+:\s(.+)/
|
297
|
+
cpuinfo[current_cpu]["mhz"] = $1
|
298
|
+
when /cache size\s+:\s(.+)/
|
299
|
+
cpuinfo[current_cpu]["cache_size"] = $1
|
300
|
+
when /flags\s+:\s(.+)/
|
301
|
+
cpuinfo[current_cpu]["flags"] = $1.split
|
302
|
+
when /BogoMIPS\s+:\s(.+)/
|
303
|
+
cpuinfo[current_cpu]["bogomips"] = $1
|
304
|
+
when /Features\s+:\s(.+)/
|
305
|
+
cpuinfo[current_cpu]["features"] = $1.split
|
306
|
+
when /bogomips per cpu:\s(.+)/
|
307
|
+
cpuinfo["bogomips_per_cpu"] = $1
|
308
|
+
when /features\s+:\s(.+)/
|
309
|
+
cpuinfo["features"] = $1.split
|
310
|
+
# ppc64le
|
311
|
+
when /revision\s+:\s(.+)/
|
312
|
+
cpuinfo[current_cpu]["model"] = $1
|
313
|
+
when /cpu\s+:\s(.+)/
|
314
|
+
cpuinfo[current_cpu]["model_name"] = $1
|
315
|
+
when /clock\s+:\s(.+)/
|
316
|
+
cpuinfo[current_cpu]["mhz"] = $1
|
317
|
+
when /timebase\s+:\s(.+)/
|
318
|
+
cpuinfo["timebase"] = $1
|
319
|
+
when /platform\s+:\s(.+)/
|
320
|
+
cpuinfo["platform"] = $1
|
321
|
+
when /machine\s+:\s(.+)/
|
322
|
+
cpuinfo["machine"] = $1
|
323
|
+
when /firmware\s+:\s(.+)/
|
324
|
+
cpuinfo["firmware"] = $1
|
325
|
+
when /MMU\s+:\s(.+)/
|
326
|
+
cpuinfo["mmu"] = $1
|
327
|
+
# s390x
|
328
|
+
when /processor\s(\d):\s(.+)/
|
329
|
+
current_cpu = $1
|
330
|
+
cpu_number += 1
|
331
|
+
cpuinfo[current_cpu] = Mash.new
|
332
|
+
current_cpu_info = $2.split(",")
|
333
|
+
current_cpu_info.each do |i|
|
334
|
+
name_value = i.split("=")
|
335
|
+
name = name_value[0].strip
|
336
|
+
value = name_value[1].strip
|
337
|
+
cpuinfo[current_cpu][name] = value
|
338
|
+
end
|
339
|
+
end
|
340
|
+
end
|
341
|
+
|
342
|
+
# use data we collected unless cpuinfo is lacking core information
|
343
|
+
# which is the case on older linux distros
|
344
|
+
if !real_cpu.empty? && cpuinfo["0"]["cores"]
|
345
|
+
logger.trace("Plugin CPU: Error executing lscpu. CPU data may not be available.")
|
346
|
+
cpuinfo[:real] = real_cpu.keys.length
|
347
|
+
cpuinfo[:cores] = real_cpu.keys.length * cpuinfo["0"]["cores"].to_i
|
348
|
+
else
|
349
|
+
logger.trace("Plugin CPU: real cpu & core data is missing in /proc/cpuinfo and lscpu")
|
350
|
+
end
|
351
|
+
cpuinfo[:total] = cpu_number
|
352
|
+
cpuinfo
|
353
|
+
end
|
354
|
+
|
355
|
+
# Check if the `lscpu` data looks reasonable
|
356
|
+
def valid_lscpu?(lscpu)
|
357
|
+
return false if lscpu.empty?
|
358
|
+
return false if %i{total real cores}.any? { |key| lscpu[key].to_i == 0 }
|
359
|
+
|
360
|
+
true
|
361
|
+
end
|
362
|
+
|
363
|
+
collect_data(:linux) do
|
364
|
+
cpuinfo = parse_cpuinfo
|
365
|
+
lscpu = parse_lscpu(cpuinfo)
|
366
|
+
|
367
|
+
# If we don't have any sensible data from lscpu then get it from /proc/cpuinfo
|
368
|
+
if valid_lscpu?(lscpu)
|
369
|
+
cpu lscpu
|
370
|
+
else
|
371
|
+
cpu cpuinfo
|
372
|
+
end
|
373
|
+
end
|
374
|
+
|
375
|
+
collect_data(:freebsd) do
|
376
|
+
# all dmesg output for smp I can find only provides info about a single processor
|
377
|
+
# identical processors is probably a hardware requirement so we'll duplicate data for each cpu
|
378
|
+
# old examples: http://www.bnv-bamberg.de/home/ba3294/smp/rbuild/index.htm
|
379
|
+
|
380
|
+
# /var/run/dmesg.boot
|
381
|
+
# CPU: Intel(R) Core(TM) i7-4980HQ CPU @ 2.80GHz (2793.59-MHz K8-class CPU)
|
382
|
+
# Origin="GenuineIntel" Id=0x40661 Family=0x6 Model=0x46 Stepping=1
|
383
|
+
# Features=0x783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2>
|
384
|
+
# Features2=0x5ed8220b<SSE3,PCLMULQDQ,MON,SSSE3,CX16,SSE4.1,SSE4.2,MOVBE,POPCNT,AESNI,XSAVE,OSXSAVE,AVX,RDRAND>
|
385
|
+
# AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
|
386
|
+
# AMD Features2=0x21<LAHF,ABM>
|
387
|
+
# Structured Extended Features=0x2000<NFPUSG>
|
388
|
+
# TSC: P-state invariant
|
389
|
+
# ...
|
390
|
+
# FreeBSD/SMP: Multiprocessor System Detected: 16 CPUs
|
391
|
+
# FreeBSD/SMP: 2 package(s) x 4 core(s) x 2 SMT threads
|
392
|
+
|
393
|
+
info = parse_bsd_dmesg do |cpuinfo, line|
|
394
|
+
case line
|
395
|
+
when /Origin.*"(.*)".*Family.*0x(\S+).*Model.*0x(\S+).*Stepping.*(\S+)/
|
396
|
+
cpuinfo["vendor_id"] = $1
|
397
|
+
# convert from hex value to int, but keep a string to match Linux ohai
|
398
|
+
cpuinfo["family"] = $2.to_i(16).to_s
|
399
|
+
cpuinfo["model"] = $3.to_i(16).to_s
|
400
|
+
cpuinfo["stepping"] = $4
|
401
|
+
# These _should_ match /AMD Features2?/ lines as well
|
402
|
+
when %r{FreeBSD/SMP: Multiprocessor System Detected: (\d*) CPUs}
|
403
|
+
cpuinfo["total"] = $1.to_i
|
404
|
+
when %r{FreeBSD/SMP: (\d*) package\(s\) x (\d*) core\(s\)}
|
405
|
+
cpuinfo["real"] = $1.to_i
|
406
|
+
cpuinfo["cores"] = $1.to_i * $2.to_i
|
407
|
+
end
|
408
|
+
end
|
409
|
+
cpu info
|
410
|
+
end
|
411
|
+
|
412
|
+
collect_data(:dragonflybsd) do
|
413
|
+
# /var/run/dmesg.boot
|
414
|
+
# CPU: Intel(R) Core(TM) i7-3615QM CPU @ 2.30GHz (3516.61-MHz K8-class CPU)
|
415
|
+
# Origin = "GenuineIntel" Id = 0x306a9 Family = 6 Model = 3a Stepping = 9
|
416
|
+
# Features=0x783fbff<FPU,VME,DE,PSE,TSC,MSR,PAE,MCE,CX8,APIC,SEP,MTRR,PGE,MCA,CMOV,PAT,PSE36,MMX,FXSR,SSE,SSE2>
|
417
|
+
# Features2=0x209<SSE3,MON,SSSE3>
|
418
|
+
# AMD Features=0x28100800<SYSCALL,NX,RDTSCP,LM>
|
419
|
+
# AMD Features2=0x1<LAHF>
|
420
|
+
|
421
|
+
info = parse_bsd_dmesg do |cpuinfo, line|
|
422
|
+
case line
|
423
|
+
when /Origin = "(.+)"\s+Id = (.+)\s+Stepping = (.+)/
|
424
|
+
cpuinfo["vendor_id"] = $1
|
425
|
+
cpuinfo["stepping"] = $3
|
426
|
+
end
|
427
|
+
end
|
428
|
+
|
429
|
+
so = shell_out("sysctl -n hw.ncpu")
|
430
|
+
info[:total] = so.stdout.strip.to_i
|
431
|
+
cpu info
|
432
|
+
end
|
433
|
+
|
434
|
+
collect_data(:openbsd) do
|
435
|
+
cpuinfo = Mash.new
|
436
|
+
|
437
|
+
# OpenBSD provides most cpu information via sysctl, the only thing we need to
|
438
|
+
# to scrape from dmesg.boot is the cpu feature list.
|
439
|
+
# cpu0: FPU,V86,DE,PSE,TSC,MSR,MCE,CX8,SEP,MTRR,PGE,MCA,CMOV,PAT,CFLUSH,DS,ACPI,MMX,FXSR,SSE,SSE2,SS,TM,SBF,EST,TM2
|
440
|
+
|
441
|
+
file_open("/var/run/dmesg.boot").each do |line|
|
442
|
+
case line
|
443
|
+
when /cpu\d+:\s+([A-Z]+$|[A-Z]+,.*$)/
|
444
|
+
cpuinfo["flags"] = $1.downcase.split(",")
|
445
|
+
end
|
446
|
+
end
|
447
|
+
|
448
|
+
[["hw.model", :model_name], ["hw.ncpu", :total], ["hw.cpuspeed", :mhz]].each do |param, node|
|
449
|
+
so = shell_out("sysctl -n #{param}")
|
450
|
+
cpuinfo[node] = so.stdout.strip
|
451
|
+
end
|
452
|
+
|
453
|
+
cpu cpuinfo
|
454
|
+
end
|
455
|
+
|
456
|
+
collect_data(:netbsd) do
|
457
|
+
cpuinfo = Mash.new
|
458
|
+
|
459
|
+
# NetBSD provides some cpu information via sysctl, and a little via dmesg.boot
|
460
|
+
# unlike OpenBSD and FreeBSD, NetBSD does not provide information about the
|
461
|
+
# available instruction set
|
462
|
+
# cpu0 at mainbus0 apid 0: Intel 686-class, 2134MHz, id 0x6f6
|
463
|
+
|
464
|
+
file_open("/var/run/dmesg.boot").each do |line|
|
465
|
+
case line
|
466
|
+
when /cpu[\d\w\s]+:\s([\w\s\-]+),\s+(\w+),/
|
467
|
+
cpuinfo[:model_name] = $1
|
468
|
+
cpuinfo[:mhz] = $2.gsub(/mhz/i, "")
|
469
|
+
end
|
470
|
+
end
|
471
|
+
|
472
|
+
flags = []
|
473
|
+
so = shell_out("dmidecode")
|
474
|
+
so.stdout.lines do |line|
|
475
|
+
if line =~ /^\s+([A-Z\d-]+)\s+\([\w\s-]+\)$/
|
476
|
+
flags << $1.downcase
|
477
|
+
end
|
478
|
+
end
|
479
|
+
|
480
|
+
cpuinfo[:flags] = flags unless flags.empty?
|
481
|
+
|
482
|
+
cpu cpuinfo
|
483
|
+
end
|
484
|
+
|
485
|
+
collect_data(:darwin) do
|
486
|
+
cpu Mash.new
|
487
|
+
shell_out("sysctl hw machdep").stdout.lines.each do |line|
|
488
|
+
case line
|
489
|
+
when /^hw.packages: (.*)$/
|
490
|
+
cpu[:real] = Regexp.last_match[1].to_i
|
491
|
+
when /^hw.physicalcpu: (.*)$/
|
492
|
+
cpu[:cores] = Regexp.last_match[1].to_i
|
493
|
+
when /^hw.logicalcpu: (.*)$/
|
494
|
+
cpu[:total] = Regexp.last_match[1].to_i
|
495
|
+
when /^hw.cpufrequency: (.*)$/
|
496
|
+
cpu[:mhz] = Regexp.last_match[1].to_i / 1000000
|
497
|
+
when /^machdep.cpu.vendor: (.*)$/
|
498
|
+
cpu[:vendor_id] = Regexp.last_match[1].chomp
|
499
|
+
when /^machdep.cpu.brand_string: (.*)$/
|
500
|
+
cpu[:model_name] = Regexp.last_match[1].chomp
|
501
|
+
when /^machdep.cpu.model: (.*)$/
|
502
|
+
cpu[:model] = Regexp.last_match[1].to_i
|
503
|
+
when /^machdep.cpu.family: (.*)$/
|
504
|
+
cpu[:family] = Regexp.last_match[1].to_i
|
505
|
+
when /^machdep.cpu.stepping: (.*)$/
|
506
|
+
cpu[:stepping] = Regexp.last_match[1].to_i
|
507
|
+
when /^machdep.cpu.features: (.*)$/
|
508
|
+
cpu[:flags] = Regexp.last_match[1].downcase.split
|
509
|
+
end
|
510
|
+
end
|
511
|
+
end
|
512
|
+
|
513
|
+
collect_data(:aix) do
|
514
|
+
cpu Mash.new
|
515
|
+
|
516
|
+
cpu[:total] = shell_out("pmcycles -m").stdout.lines.length
|
517
|
+
|
518
|
+
# The below is only relevant on an LPAR
|
519
|
+
if shell_out("uname -W").stdout.strip == "0"
|
520
|
+
|
521
|
+
# At least one CPU will be available, but we'll wait to increment this later.
|
522
|
+
cpu[:available] = 0
|
523
|
+
|
524
|
+
cpudevs = shell_out("lsdev -Cc processor").stdout.lines
|
525
|
+
# from http://www-01.ibm.com/software/passportadvantage/pvu_terminology_for_customers.html
|
526
|
+
# on AIX number of cores and processors are considered same
|
527
|
+
cpu[:real] = cpu[:cores] = cpudevs.length
|
528
|
+
cpudevs.each.with_index do |c, i|
|
529
|
+
name, status, location = c.split
|
530
|
+
index = i.to_s
|
531
|
+
cpu[index] = Mash.new
|
532
|
+
cpu[index][:status] = status
|
533
|
+
cpu[index][:location] = location
|
534
|
+
if status.include?("Available")
|
535
|
+
cpu[:available] += 1
|
536
|
+
lsattr = shell_out("lsattr -El #{name}").stdout.lines
|
537
|
+
lsattr.each do |attribute|
|
538
|
+
attrib, value = attribute.split
|
539
|
+
if attrib == "type"
|
540
|
+
cpu[index][:model_name] = value
|
541
|
+
elsif attrib == "frequency"
|
542
|
+
cpu[index][:mhz] = value.to_i / (1000 * 1000) # convert from hz to MHz
|
543
|
+
else
|
544
|
+
cpu[index][attrib] = value
|
545
|
+
end
|
546
|
+
end
|
547
|
+
# IBM is the only maker of CPUs for AIX systems.
|
548
|
+
cpu[index][:vendor_id] = "IBM"
|
549
|
+
end
|
550
|
+
end
|
551
|
+
end
|
552
|
+
end
|
553
|
+
|
554
|
+
collect_data(:solaris2) do
|
555
|
+
cpu Mash.new
|
556
|
+
# This does assume that /usr/bin/kstat is in the path
|
557
|
+
processor_info = shell_out("kstat -p cpu_info").stdout.lines
|
558
|
+
cpu["total"] = 0
|
559
|
+
cpu["sockets"] = 0
|
560
|
+
cpu["cores"] = 0
|
561
|
+
cpu["corethreads"] = 0
|
562
|
+
cpu["cpustates"] = Mash.new
|
563
|
+
|
564
|
+
currentcpu = 0
|
565
|
+
cpucores = []
|
566
|
+
cpusockets = []
|
567
|
+
processor_info.each do |processor|
|
568
|
+
_desc, instance, _record, keyvalue = processor.split(":")
|
569
|
+
cpu[instance] ||= Mash.new
|
570
|
+
if currentcpu != instance
|
571
|
+
cpu["total"] += 1
|
572
|
+
currentcpu = instance
|
573
|
+
end
|
574
|
+
kv = keyvalue.split(/\s+/)
|
575
|
+
key = kv.shift
|
576
|
+
value = kv.join(" ").chomp
|
577
|
+
case key
|
578
|
+
when /chip_id/
|
579
|
+
cpu[instance]["socket"] = value
|
580
|
+
cpusockets.push(value) if cpusockets.index(value).nil?
|
581
|
+
when /cpu_type/
|
582
|
+
cpu[instance]["arch"] = value
|
583
|
+
when /clock_MHz/
|
584
|
+
cpu[instance]["mhz"] = value
|
585
|
+
when /brand/
|
586
|
+
cpu[instance]["model_name"] = value.sub(/\s+/, " ")
|
587
|
+
when /^state$/
|
588
|
+
cpu[instance]["state"] = value
|
589
|
+
cpu["cpustates"][value] ||= 0
|
590
|
+
cpu["cpustates"][value] += 1
|
591
|
+
when /core_id/
|
592
|
+
cpu[instance]["core_id"] = value
|
593
|
+
# Detect hyperthreading/multithreading
|
594
|
+
cpucores.push(value) if cpucores.index(value).nil?
|
595
|
+
when /family|fpu_type|model|stepping|vendor_id/
|
596
|
+
cpu[instance][key] = value
|
597
|
+
end
|
598
|
+
end
|
599
|
+
cpu["cores"] = cpucores.size
|
600
|
+
cpu["corethreads"] = (cpu["total"] / cpucores.size)
|
601
|
+
cpu["sockets"] = cpusockets.size
|
602
|
+
cpu["real"] = cpusockets.size
|
603
|
+
end
|
604
|
+
|
605
|
+
collect_data(:windows) do
|
606
|
+
require "wmi-lite/wmi" unless defined?(WmiLite::Wmi)
|
607
|
+
|
608
|
+
cpu Mash.new
|
609
|
+
cores = 0
|
610
|
+
logical_processors = 0
|
611
|
+
|
612
|
+
wmi = WmiLite::Wmi.new
|
613
|
+
processors = wmi.instances_of("Win32_Processor")
|
614
|
+
|
615
|
+
processors.each_with_index do |processor, index|
|
616
|
+
current_cpu = index.to_s
|
617
|
+
cpu[current_cpu] = Mash.new
|
618
|
+
|
619
|
+
cpu[current_cpu]["cores"] = processor["numberofcores"]
|
620
|
+
cores += processor["numberofcores"]
|
621
|
+
|
622
|
+
logical_processors += processor["numberoflogicalprocessors"]
|
623
|
+
cpu[current_cpu]["vendor_id"] = processor["manufacturer"]
|
624
|
+
cpu[current_cpu]["family"] = processor["family"].to_s
|
625
|
+
cpu[current_cpu]["model"] = processor["revision"].to_s
|
626
|
+
cpu[current_cpu]["stepping"] = if processor["stepping"].nil?
|
627
|
+
processor["description"].match(/Stepping\s+(\d+)/)[1]
|
628
|
+
else
|
629
|
+
processor["stepping"]
|
630
|
+
end
|
631
|
+
cpu[current_cpu]["physical_id"] = processor["deviceid"]
|
632
|
+
cpu[current_cpu]["model_name"] = processor["name"]
|
633
|
+
cpu[current_cpu]["description"] = processor["description"]
|
634
|
+
cpu[current_cpu]["mhz"] = processor["maxclockspeed"].to_s
|
635
|
+
cpu[current_cpu]["cache_size"] = "#{processor["l2cachesize"]} KB"
|
636
|
+
end
|
637
|
+
|
638
|
+
cpu[:total] = logical_processors
|
639
|
+
cpu[:cores] = cores
|
640
|
+
cpu[:real] = processors.length
|
641
|
+
end
|
642
|
+
end
|