From e584555a485e565c3de18e4739366888232fdf92 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Romain=20Tarti=C3=A8re?= Date: Fri, 16 Sep 2022 12:49:26 -1000 Subject: [PATCH] (FACT-3149) Fix memory usage reporting on FreeBSD * In vmstat(8), "free memory" correspond to unused memory that does not contain any data, and does not include cache / inactive memory which has some data but is immediatly available to the system if memory is needed. Prefer to get active and wired memory page count form sysctl(3) which correpond to the used memory that can (active) and cannot (wired) be swapped out, and multiply these by the size of a memory page. This give a better overview of the current memory usage. * Prefer `vm.stats.vm.v_page_count` over `hw.physmem`: The available memory can be lower that what is physically present in the system and the free / used memory is a portion of the usable memory more than a portion of the physical memory. --- lib/facter/resolvers/freebsd/system_memory.rb | 22 +++++++++++++------ .../resolvers/freebsd/system_memory_spec.rb | 17 +++++++++----- spec/fixtures/freebsd_vmstat | 6 ----- 3 files changed, 26 insertions(+), 19 deletions(-) delete mode 100644 spec/fixtures/freebsd_vmstat diff --git a/lib/facter/resolvers/freebsd/system_memory.rb b/lib/facter/resolvers/freebsd/system_memory.rb index 5c204617f9..25ba5c536c 100644 --- a/lib/facter/resolvers/freebsd/system_memory.rb +++ b/lib/facter/resolvers/freebsd/system_memory.rb @@ -15,25 +15,33 @@ def post_resolve(fact_name, _options) def calculate_system_memory(fact_name) read_total_memory_in_bytes - read_available_memory_in_bytes + read_used_memory_in_bytes - @fact_list[:used_bytes] = @fact_list[:total_bytes] - @fact_list[:available_bytes] + @fact_list[:available_bytes] = @fact_list[:total_bytes] - @fact_list[:used_bytes] @fact_list[:capacity] = Facter::Util::Resolvers::FilesystemHelper .compute_capacity(@fact_list[:used_bytes], @fact_list[:total_bytes]) @fact_list[fact_name] end - def read_available_memory_in_bytes - output = Facter::Core::Execution.execute('vmstat -H --libxo json', logger: log) - data = JSON.parse(output) - @fact_list[:available_bytes] = data['memory']['free-memory'] * 1024 + def pagesize + @pagesize ||= Facter::Freebsd::FfiHelper.sysctl_by_name(:long, 'vm.stats.vm.v_page_size') + end + + def read_used_memory_in_bytes + require_relative 'ffi/ffi_helper' + + @fact_list[:used_bytes] = pagesize * ( + Facter::Freebsd::FfiHelper.sysctl_by_name(:long, 'vm.stats.vm.v_active_count') + + Facter::Freebsd::FfiHelper.sysctl_by_name(:long, 'vm.stats.vm.v_wire_count') + ) end def read_total_memory_in_bytes require_relative 'ffi/ffi_helper' - @fact_list[:total_bytes] = Facter::Freebsd::FfiHelper.sysctl_by_name(:long, 'hw.physmem') + @fact_list[:total_bytes] = pagesize * + Facter::Freebsd::FfiHelper.sysctl_by_name(:long, 'vm.stats.vm.v_page_count') end end end diff --git a/spec/facter/resolvers/freebsd/system_memory_spec.rb b/spec/facter/resolvers/freebsd/system_memory_spec.rb index 0594a601f2..a95471ec13 100644 --- a/spec/facter/resolvers/freebsd/system_memory_spec.rb +++ b/spec/facter/resolvers/freebsd/system_memory_spec.rb @@ -12,12 +12,17 @@ before do system_memory.instance_variable_set(:@log, log_spy) allow(Facter::Freebsd::FfiHelper).to receive(:sysctl_by_name) - .with(:long, 'hw.physmem') - .and_return(17_043_554_304) - - allow(Facter::Core::Execution).to receive(:execute) - .with('vmstat -H --libxo json', { logger: log_spy }) - .and_return(load_fixture('freebsd_vmstat').read) + .with(:long, 'vm.stats.vm.v_page_size') + .and_return(4096) + allow(Facter::Freebsd::FfiHelper).to receive(:sysctl_by_name) + .with(:long, 'vm.stats.vm.v_page_count') + .and_return(4_161_024) + allow(Facter::Freebsd::FfiHelper).to receive(:sysctl_by_name) + .with(:long, 'vm.stats.vm.v_active_count') + .and_return(2_335_139) + allow(Facter::Freebsd::FfiHelper).to receive(:sysctl_by_name) + .with(:long, 'vm.stats.vm.v_wire_count') + .and_return(1_167_569) end it 'returns available system memory in bytes' do diff --git a/spec/fixtures/freebsd_vmstat b/spec/fixtures/freebsd_vmstat deleted file mode 100644 index 01bcd3679a..0000000000 --- a/spec/fixtures/freebsd_vmstat +++ /dev/null @@ -1,6 +0,0 @@ -{"__version": "1", "processes": {"runnable":2,"waiting":14,"swapped-out":0} -, "memory": {"available-memory":62672436,"free-memory":2633264,"total-page-faults":1972} -, "paging-rates": {"page-reactivated":0,"paged-in":1,"paged-out":0,"freed":1831,"scanned":841} -, "device": [{"name":"ad0","transfers":"0"}, {"name":"pa0","transfers":"0"}], "fault-rates": {"interrupts":3495,"system-calls":17391,"context-switches":11777} -, "cpu-statistics": {"user":" 5","system":" 3","idle":"92"} -}