Skip to content

Commit

Permalink
Add NUMA related facts (#236)
Browse files Browse the repository at this point in the history
Co-authored-by: Trevor Vaughan <[email protected]>
  • Loading branch information
jcpunk and trevor-vaughan authored Sep 29, 2020
1 parent 92c2fd7 commit 943f82c
Show file tree
Hide file tree
Showing 5 changed files with 368 additions and 2 deletions.
5 changes: 4 additions & 1 deletion CHANGELOG
Original file line number Diff line number Diff line change
@@ -1,4 +1,7 @@
* Thu Sep 17 2020 Pat Riehecky <[email protected]> - 4.5.0-0
* Thu Sep 24 2020 Pat Riehecky <[email protected]> - 4.6.0-0
- Add simplib__numa to collect NUMA-related facts

* Thu Sep 17 2020 Pat Riehecky <[email protected]> - 4.5.0-0
- Add facts to note EFI status
- simplib__efi_enabled
- simplib__secure_boot_enabled
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -98,6 +98,7 @@ See [REFERENCE.md](./REFERENCE.md) for all other reference documentation.
are present on the system.
* **simplib__mountpoints** - Return a hash of mountpoints of particular
interest to SIMP modules.
* **simplib__numa** - Return hash of numa values about your system.
* **simplib_sysctl** - Return hash of sysctl values that are relevant
to SIMP
* **simp_puppet_settings** - Returns a hash of all Puppet settings on a node
Expand Down
41 changes: 41 additions & 0 deletions lib/facter/simplib__numa.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
# _Description_
#
# Return a structured NUMA fact with possible nodes, online nodes
# and a memory mapping layout
#
Facter.add('simplib__numa') do
confine :kernel => 'Linux'
confine { File.exist? '/sys/devices/system/node' }

setcode do
result = {}
result['nodes'] = []

# read the 'possible' nodes file
if File.exist?('/sys/devices/system/node/possible')
result['possible'] = File.read('/sys/devices/system/node/possible').strip
end

# read the 'online' nodes file
if File.exist?('/sys/devices/system/node/online')
result['online'] = File.read('/sys/devices/system/node/online').strip
end

require 'pathname'
Dir.glob('/sys/devices/system/node/node*').each do | file |
meminfo_file = Pathname.new(File.join(file, 'meminfo'))
next unless meminfo_file.exist?
nodename = File.basename(file)
result['nodes'].push(nodename)

File.foreach(meminfo_file) do | text |
if text =~ /\sMemTotal:\s+(\d+)/
result[nodename] ||= {}
result[nodename]['MemTotalBytes'] = ($1.to_i * 1024)
end
end
end

result
end
end
2 changes: 1 addition & 1 deletion metadata.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "simp-simplib",
"version": "4.5.0",
"version": "4.6.0",
"author": "SIMP Team",
"summary": "A collection of common SIMP functions, facts, and types",
"license": "Apache-2.0",
Expand Down
321 changes: 321 additions & 0 deletions spec/unit/facter/simplib__numa_spec.rb
Original file line number Diff line number Diff line change
@@ -0,0 +1,321 @@
# frozen_string_literal: true

require 'spec_helper'

describe 'simplib__numa' do
before :each do
Facter.clear
Facter.stubs(:value).with(:kernel).returns('Linux')
File.expects(:exist?).with('/sys/devices/system/node').once.returns(true)
end

context 'with files set for two NUMA zones ' do
before :each do
File.expects(:exist?).with('/sys/devices/system/node/possible').once.returns(true)
File.expects(:read).with('/sys/devices/system/node/possible').once.returns("0-1")

File.expects(:exist?).with('/sys/devices/system/node/online').once.returns(true)
File.expects(:read).with('/sys/devices/system/node/online').once.returns("0-1")

@memory1_tempdir = Dir.mktmpdir
@memory2_tempdir = Dir.mktmpdir

node0 = File.join(@memory1_tempdir, 'node0')
node1 = File.join(@memory2_tempdir, 'node1')

Dir.mkdir(node0)
Dir.mkdir(node1)

Dir.stubs(:glob).with('/sys/devices/system/node/node*').returns([node0, node1])
end

after :each do
FileUtils.remove_entry(@memory1_tempdir) if File.directory?(@memory1_tempdir)
FileUtils.remove_entry(@memory2_tempdir) if File.directory?(@memory2_tempdir)
end

context 'with two NUMA zones' do
before :each do
File.open(File.join(@memory1_tempdir, 'node0', 'meminfo'), 'w') do |fh|
fh.puts <<~EOMEM
Node 0 MemTotal: 16094344 kB
Node 0 MemFree: 1459276 kB
Node 0 MemUsed: 14635068 kB
Node 0 Active: 7113068 kB
Node 0 Inactive: 5666656 kB
Node 0 Active(anon): 3718696 kB
Node 0 Inactive(anon): 911684 kB
Node 0 Active(file): 3394372 kB
Node 0 Inactive(file): 4754972 kB
Node 0 Unevictable: 278436 kB
Node 0 Mlocked: 2044 kB
Node 0 Dirty: 716 kB
Node 0 Writeback: 0 kB
Node 0 FilePages: 9088236 kB
Node 0 Mapped: 1068884 kB
Node 0 AnonPages: 3970156 kB
Node 0 Shmem: 940720 kB
Node 0 KernelStack: 17552 kB
Node 0 PageTables: 40160 kB
Node 0 NFS_Unstable: 0 kB
Node 0 Bounce: 0 kB
Node 0 WritebackTmp: 0 kB
Node 0 KReclaimable: 519780 kB
Node 0 Slab: 926580 kB
Node 0 SReclaimable: 519780 kB
Node 0 SUnreclaim: 406800 kB
Node 0 AnonHugePages: 0 kB
Node 0 ShmemHugePages: 0 kB
Node 0 ShmemPmdMapped: 0 kB
Node 0 FileHugePages: 0 kB
Node 0 FilePmdMapped: 0 kB
Node 0 HugePages_Total: 0
Node 0 HugePages_Free: 0
Node 0 HugePages_Surp: 0
EOMEM
end

File.open(File.join(@memory2_tempdir, 'node1', 'meminfo'), 'w') do |fh|
fh.puts <<~EOMEM
Node 1 MemTotal: 16094344 kB
Node 1 MemFree: 1459276 kB
Node 1 MemUsed: 14635068 kB
Node 1 Active: 7113068 kB
Node 1 Inactive: 5666656 kB
Node 1 Active(anon): 3718696 kB
Node 1 Inactive(anon): 911684 kB
Node 1 Active(file): 3394372 kB
Node 1 Inactive(file): 4754972 kB
Node 1 Unevictable: 278436 kB
Node 1 Mlocked: 2044 kB
Node 1 Dirty: 716 kB
Node 1 Writeback: 0 kB
Node 1 FilePages: 9088236 kB
Node 1 Mapped: 1068884 kB
Node 1 AnonPages: 3970156 kB
Node 1 Shmem: 940720 kB
Node 1 KernelStack: 17552 kB
Node 1 PageTables: 40160 kB
Node 1 NFS_Unstable: 0 kB
Node 1 Bounce: 0 kB
Node 1 WritebackTmp: 0 kB
Node 1 KReclaimable: 519780 kB
Node 1 Slab: 926580 kB
Node 1 SReclaimable: 519780 kB
Node 1 SUnreclaim: 406800 kB
Node 1 AnonHugePages: 0 kB
Node 1 ShmemHugePages: 0 kB
Node 1 ShmemPmdMapped: 0 kB
Node 1 FileHugePages: 0 kB
Node 1 FilePmdMapped: 0 kB
Node 1 HugePages_Total: 0
Node 1 HugePages_Free: 0
Node 1 HugePages_Surp: 0
EOMEM
end
end

it do
expect(Facter.fact('simplib__numa').value).to eq({
'possible' => '0-1',
'online' => '0-1',
'nodes' => ['node0', 'node1'],
'node0' => { 'MemTotalBytes' => 16480608256 },
'node1' => { 'MemTotalBytes' => 16480608256 }
})
end
end
end

context 'with files set for one NUMA zone online ' do
before :each do
File.expects(:exist?).with('/sys/devices/system/node/possible').once.returns(true)
File.expects(:read).with('/sys/devices/system/node/possible').once.returns("0-1")

File.expects(:exist?).with('/sys/devices/system/node/online').once.returns(true)
File.expects(:read).with('/sys/devices/system/node/online').once.returns("0")

@memory1_tempdir = Dir.mktmpdir
@memory2_tempdir = Dir.mktmpdir

node0 = File.join(@memory1_tempdir, 'node0')
node1 = File.join(@memory2_tempdir, 'node1')

Dir.mkdir(node0)
Dir.mkdir(node1)

Dir.stubs(:glob).with('/sys/devices/system/node/node*').returns([node0, node1])
end

after :each do
FileUtils.remove_entry(@memory1_tempdir) if File.directory?(@memory1_tempdir)
FileUtils.remove_entry(@memory2_tempdir) if File.directory?(@memory2_tempdir)
end

context 'with two NUMA zones' do
before :each do
File.open(File.join(@memory1_tempdir, 'node0', 'meminfo'), 'w') do |fh|
fh.puts <<~EOMEM
Node 0 MemTotal: 16094344 kB
Node 0 MemFree: 1459276 kB
Node 0 MemUsed: 14635068 kB
Node 0 Active: 7113068 kB
Node 0 Inactive: 5666656 kB
Node 0 Active(anon): 3718696 kB
Node 0 Inactive(anon): 911684 kB
Node 0 Active(file): 3394372 kB
Node 0 Inactive(file): 4754972 kB
Node 0 Unevictable: 278436 kB
Node 0 Mlocked: 2044 kB
Node 0 Dirty: 716 kB
Node 0 Writeback: 0 kB
Node 0 FilePages: 9088236 kB
Node 0 Mapped: 1068884 kB
Node 0 AnonPages: 3970156 kB
Node 0 Shmem: 940720 kB
Node 0 KernelStack: 17552 kB
Node 0 PageTables: 40160 kB
Node 0 NFS_Unstable: 0 kB
Node 0 Bounce: 0 kB
Node 0 WritebackTmp: 0 kB
Node 0 KReclaimable: 519780 kB
Node 0 Slab: 926580 kB
Node 0 SReclaimable: 519780 kB
Node 0 SUnreclaim: 406800 kB
Node 0 AnonHugePages: 0 kB
Node 0 ShmemHugePages: 0 kB
Node 0 ShmemPmdMapped: 0 kB
Node 0 FileHugePages: 0 kB
Node 0 FilePmdMapped: 0 kB
Node 0 HugePages_Total: 0
Node 0 HugePages_Free: 0
Node 0 HugePages_Surp: 0
EOMEM
end

File.open(File.join(@memory2_tempdir, 'node1', 'meminfo'), 'w') do |fh|
fh.puts <<~EOMEM
Node 1 MemTotal: 16094344 kB
Node 1 MemFree: 1459276 kB
Node 1 MemUsed: 14635068 kB
Node 1 Active: 7113068 kB
Node 1 Inactive: 5666656 kB
Node 1 Active(anon): 3718696 kB
Node 1 Inactive(anon): 911684 kB
Node 1 Active(file): 3394372 kB
Node 1 Inactive(file): 4754972 kB
Node 1 Unevictable: 278436 kB
Node 1 Mlocked: 2044 kB
Node 1 Dirty: 716 kB
Node 1 Writeback: 0 kB
Node 1 FilePages: 9088236 kB
Node 1 Mapped: 1068884 kB
Node 1 AnonPages: 3970156 kB
Node 1 Shmem: 940720 kB
Node 1 KernelStack: 17552 kB
Node 1 PageTables: 40160 kB
Node 1 NFS_Unstable: 0 kB
Node 1 Bounce: 0 kB
Node 1 WritebackTmp: 0 kB
Node 1 KReclaimable: 519780 kB
Node 1 Slab: 926580 kB
Node 1 SReclaimable: 519780 kB
Node 1 SUnreclaim: 406800 kB
Node 1 AnonHugePages: 0 kB
Node 1 ShmemHugePages: 0 kB
Node 1 ShmemPmdMapped: 0 kB
Node 1 FileHugePages: 0 kB
Node 1 FilePmdMapped: 0 kB
Node 1 HugePages_Total: 0
Node 1 HugePages_Free: 0
Node 1 HugePages_Surp: 0
EOMEM
end
end

it do
expect(Facter.fact('simplib__numa').value).to eq({
'possible' => '0-1',
'online' => '0',
'nodes' => ['node0', 'node1'],
'node0' => { 'MemTotalBytes' => 16480608256 },
'node1' => { 'MemTotalBytes' => 16480608256 }
})
end
end
end

context 'with files set for one NUMA zone ' do
before :each do
File.expects(:exist?).with('/sys/devices/system/node/possible').once.returns(true)
File.expects(:read).with('/sys/devices/system/node/possible').once.returns("0")

File.expects(:exist?).with('/sys/devices/system/node/online').once.returns(true)
File.expects(:read).with('/sys/devices/system/node/online').once.returns("0")

@memory1_tempdir = Dir.mktmpdir

node0 = File.join(@memory1_tempdir, 'node0')

Dir.mkdir(node0)

Dir.stubs(:glob).with('/sys/devices/system/node/node*').returns([node0])
end

after :each do
FileUtils.remove_entry(@memory1_tempdir) if File.directory?(@memory1_tempdir)
end

context 'with two NUMA zones' do
before :each do
File.open(File.join(@memory1_tempdir, 'node0', 'meminfo'), 'w') do |fh|
fh.puts <<~EOMEM
Node 0 MemTotal: 16094344 kB
Node 0 MemFree: 1459276 kB
Node 0 MemUsed: 14635068 kB
Node 0 Active: 7113068 kB
Node 0 Inactive: 5666656 kB
Node 0 Active(anon): 3718696 kB
Node 0 Inactive(anon): 911684 kB
Node 0 Active(file): 3394372 kB
Node 0 Inactive(file): 4754972 kB
Node 0 Unevictable: 278436 kB
Node 0 Mlocked: 2044 kB
Node 0 Dirty: 716 kB
Node 0 Writeback: 0 kB
Node 0 FilePages: 9088236 kB
Node 0 Mapped: 1068884 kB
Node 0 AnonPages: 3970156 kB
Node 0 Shmem: 940720 kB
Node 0 KernelStack: 17552 kB
Node 0 PageTables: 40160 kB
Node 0 NFS_Unstable: 0 kB
Node 0 Bounce: 0 kB
Node 0 WritebackTmp: 0 kB
Node 0 KReclaimable: 519780 kB
Node 0 Slab: 926580 kB
Node 0 SReclaimable: 519780 kB
Node 0 SUnreclaim: 406800 kB
Node 0 AnonHugePages: 0 kB
Node 0 ShmemHugePages: 0 kB
Node 0 ShmemPmdMapped: 0 kB
Node 0 FileHugePages: 0 kB
Node 0 FilePmdMapped: 0 kB
Node 0 HugePages_Total: 0
Node 0 HugePages_Free: 0
Node 0 HugePages_Surp: 0
EOMEM
end
end

it do
expect(Facter.fact('simplib__numa').value).to eq({
'possible' => '0',
'online' => '0',
'nodes' => ['node0'],
'node0' => { 'MemTotalBytes' => 16480608256 }
})
end
end
end
end

0 comments on commit 943f82c

Please sign in to comment.