Repository: prometheus/procfs
Pull request #196 (2019-07-15 05:58:05)

Adds /sys/class/thermal/cooling_device* support
Adds support for `/sys/class/thermal/cooling_device[0-9]+` devices, returning name, type, cur_state and max_state. 

The latter 2 are int64, which differs from most values in this library which appear to be uint64 - this is due to the type `intel_powerclamp` returning a -1 as it's `cur_value` when idle injection is disabled.


Patch:
diff --git a/fixtures.ttar b/fixtures.ttar
index 75dd29d..4140a66 100644
--- a/fixtures.ttar
+++ b/fixtures.ttar
@@ -1701,6 +1701,42 @@ Mode: 444
 Directory: fixtures/sys/class/thermal
 Mode: 775
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/thermal/cooling_device0
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/thermal/cooling_device0/cur_state
+Lines: 1
+0
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/thermal/cooling_device0/max_state
+Lines: 1
+50
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/thermal/cooling_device0/type
+Lines: 1
+Processor
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Directory: fixtures/sys/class/thermal/cooling_device1
+Mode: 755
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/thermal/cooling_device1/cur_state
+Lines: 1
+-1
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/thermal/cooling_device1/max_state
+Lines: 1
+27
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/class/thermal/cooling_device1/type
+Lines: 1
+intel_powerclamp
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Directory: fixtures/sys/class/thermal/thermal_zone0
 Mode: 775
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
diff --git a/sysfs/class_cooling_device.go b/sysfs/class_cooling_device.go
new file mode 100644
index 0000000..8927b02
--- /dev/null
+++ b/sysfs/class_cooling_device.go
@@ -0,0 +1,90 @@
+// Copyright 2019 The Prometheus Authors
+// 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.
+
+// +build !windows
+
+package sysfs
+
+import (
+	"path/filepath"
+	"strconv"
+	"strings"
+
+	"github.com/prometheus/procfs/internal/util"
+)
+
+// ClassCoolingDeviceStats contains info from files in /sys/class/thermal/cooling_device[0-9]*
+// for a single device.
+// https://www.kernel.org/doc/Documentation/thermal/sysfs-api.txt
+type ClassCoolingDeviceStats struct {
+	Name     string // The name of the cooling device.
+	Type     string // Type of the cooling device(processor/fan/...)
+	MaxState int64  // Maximum cooling state of the cooling device
+	CurState int64  // Current cooling state of the cooling device
+}
+
+func (fs FS) ClassCoolingDeviceStats() ([]ClassCoolingDeviceStats, error) {
+	cds, err := filepath.Glob(fs.sys.Path("class/thermal/cooling_device[0-9]*"))
+	if err != nil {
+		return []ClassCoolingDeviceStats{}, err
+	}
+
+	var coolingDeviceStats = ClassCoolingDeviceStats{}
+	stats := make([]ClassCoolingDeviceStats, len(cds))
+	for i, cd := range cds {
+		cdName := strings.TrimPrefix(filepath.Base(cd), "cooling_device")
+
+		coolingDeviceStats, err = parseCoolingDeviceStats(cd)
+		if err != nil {
+			return []ClassCoolingDeviceStats{}, err
+		}
+
+		coolingDeviceStats.Name = cdName
+		stats[i] = coolingDeviceStats
+	}
+	return stats, nil
+}
+
+func parseCoolingDeviceStats(cd string) (ClassCoolingDeviceStats, error) {
+	cdType, err := util.SysReadFile(filepath.Join(cd, "type"))
+	if err != nil {
+		return ClassCoolingDeviceStats{}, err
+	}
+
+	cdMaxStateString, err := util.SysReadFile(filepath.Join(cd, "max_state"))
+	if err != nil {
+		return ClassCoolingDeviceStats{}, err
+	}
+	cdMaxStateInt, err := strconv.ParseInt(cdMaxStateString, 10, 64)
+	if err != nil {
+		return ClassCoolingDeviceStats{}, err
+	}
+
+	// cur_state can be -1, eg intel powerclamp
+	// https://www.kernel.org/doc/Documentation/thermal/intel_powerclamp.txt
+	cdCurStateString, err := util.SysReadFile(filepath.Join(cd, "cur_state"))
+	if err != nil {
+		return ClassCoolingDeviceStats{}, err
+	}
+
+	cdCurStateInt, err := strconv.ParseInt(cdCurStateString, 10, 64)
+	if err != nil {
+		return ClassCoolingDeviceStats{}, err
+	}
+
+	return ClassCoolingDeviceStats{
+		Type:     cdType,
+		MaxState: cdMaxStateInt,
+		CurState: cdCurStateInt,
+	}, nil
+}
diff --git a/vm.go b/vm.go
index f22651c..cb13891 100644
--- a/vm.go
+++ b/vm.go
@@ -31,49 +31,49 @@ import (
 // Each file contains one line with a single numerical value, except lowmem_reserve_ratio which holds an array
 // and numa_zonelist_order (deprecated) which is a string
 type VM struct {
-	AdminReserveKbytes        int64   // /proc/sys/vm/admin_reserve_kbytes
-	BlockDump                 int64   // /proc/sys/vm/block_dump
-	CompactUnevictableAllowed int64   // /proc/sys/vm/compact_unevictable_allowed
-	DirtyBackgroundBytes      int64   // /proc/sys/vm/dirty_background_bytes
-	DirtyBackgroundRatio      int64   // /proc/sys/vm/dirty_background_ratio
-	DirtyBytes                int64   // /proc/sys/vm/dirty_bytes
-	DirtyExpireCentisecs      int64   // /proc/sys/vm/dirty_expire_centisecs
-	DirtyRatio                int64   // /proc/sys/vm/dirty_ratio
-	DirtytimeExpireSeconds    int64   // /proc/sys/vm/dirtytime_expire_seconds
-	DirtyWritebackCentisecs   int64   // /proc/sys/vm/dirty_writeback_centisecs
-	DropCaches                int64   // /proc/sys/vm/drop_caches
-	ExtfragThreshold          int64   // /proc/sys/vm/extfrag_threshold
-	HugetlbShmGroup           int64   // /proc/sys/vm/hugetlb_shm_group
-	LaptopMode                int64   // /proc/sys/vm/laptop_mode
-	LegacyVaLayout            int64   // /proc/sys/vm/legacy_va_layout
-	LowmemReserveRatio        []int64 // /proc/sys/vm/lowmem_reserve_ratio
-	MaxMapCount               int64   // /proc/sys/vm/max_map_count
-	MemoryFailureEarlyKill    int64   // /proc/sys/vm/memory_failure_early_kill
-	MemoryFailureRecovery     int64   // /proc/sys/vm/memory_failure_recovery
-	MinFreeKbytes             int64   // /proc/sys/vm/min_free_kbytes
-	MinSlabRatio              int64   // /proc/sys/vm/min_slab_ratio
-	MinUnmappedRatio          int64   // /proc/sys/vm/min_unmapped_ratio
-	MmapMinAddr               int64   // /proc/sys/vm/mmap_min_addr
-	NrHugepages               int64   // /proc/sys/vm/nr_hugepages
-	NrHugepagesMempolicy      int64   // /proc/sys/vm/nr_hugepages_mempolicy
-	NrOvercommitHugepages     int64   // /proc/sys/vm/nr_overcommit_hugepages
-	NumaStat                  int64   // /proc/sys/vm/numa_stat
-	NumaZonelistOrder         string  // /proc/sys/vm/numa_zonelist_order
-	OomDumpTasks              int64   // /proc/sys/vm/oom_dump_tasks
-	OomKillAllocatingTask     int64   // /proc/sys/vm/oom_kill_allocating_task
-	OvercommitKbytes          int64   // /proc/sys/vm/overcommit_kbytes
-	OvercommitMemory          int64   // /proc/sys/vm/overcommit_memory
-	OvercommitRatio           int64   // /proc/sys/vm/overcommit_ratio
-	PageCluster               int64   // /proc/sys/vm/page-cluster
-	PanicOnOom                int64   // /proc/sys/vm/panic_on_oom
-	PercpuPagelistFraction    int64   // /proc/sys/vm/percpu_pagelist_fraction
-	StatInterval              int64   // /proc/sys/vm/stat_interval
-	Swappiness                int64   // /proc/sys/vm/swappiness
-	UserReserveKbytes         int64   // /proc/sys/vm/user_reserve_kbytes
-	VfsCachePressure          int64   // /proc/sys/vm/vfs_cache_pressure
-	WatermarkBoostFactor      int64   // /proc/sys/vm/watermark_boost_factor
-	WatermarkScaleFactor      int64   // /proc/sys/vm/watermark_scale_factor
-	ZoneReclaimMode           int64   // /proc/sys/vm/zone_reclaim_mode
+	AdminReserveKbytes        *int64   // /proc/sys/vm/admin_reserve_kbytes
+	BlockDump                 *int64   // /proc/sys/vm/block_dump
+	CompactUnevictableAllowed *int64   // /proc/sys/vm/compact_unevictable_allowed
+	DirtyBackgroundBytes      *int64   // /proc/sys/vm/dirty_background_bytes
+	DirtyBackgroundRatio      *int64   // /proc/sys/vm/dirty_background_ratio
+	DirtyBytes                *int64   // /proc/sys/vm/dirty_bytes
+	DirtyExpireCentisecs      *int64   // /proc/sys/vm/dirty_expire_centisecs
+	DirtyRatio                *int64   // /proc/sys/vm/dirty_ratio
+	DirtytimeExpireSeconds    *int64   // /proc/sys/vm/dirtytime_expire_seconds
+	DirtyWritebackCentisecs   *int64   // /proc/sys/vm/dirty_writeback_centisecs
+	DropCaches                *int64   // /proc/sys/vm/drop_caches
+	ExtfragThreshold          *int64   // /proc/sys/vm/extfrag_threshold
+	HugetlbShmGroup           *int64   // /proc/sys/vm/hugetlb_shm_group
+	LaptopMode                *int64   // /proc/sys/vm/laptop_mode
+	LegacyVaLayout            *int64   // /proc/sys/vm/legacy_va_layout
+	LowmemReserveRatio        []*int64 // /proc/sys/vm/lowmem_reserve_ratio
+	MaxMapCount               *int64   // /proc/sys/vm/max_map_count
+	MemoryFailureEarlyKill    *int64   // /proc/sys/vm/memory_failure_early_kill
+	MemoryFailureRecovery     *int64   // /proc/sys/vm/memory_failure_recovery
+	MinFreeKbytes             *int64   // /proc/sys/vm/min_free_kbytes
+	MinSlabRatio              *int64   // /proc/sys/vm/min_slab_ratio
+	MinUnmappedRatio          *int64   // /proc/sys/vm/min_unmapped_ratio
+	MmapMinAddr               *int64   // /proc/sys/vm/mmap_min_addr
+	NrHugepages               *int64   // /proc/sys/vm/nr_hugepages
+	NrHugepagesMempolicy      *int64   // /proc/sys/vm/nr_hugepages_mempolicy
+	NrOvercommitHugepages     *int64   // /proc/sys/vm/nr_overcommit_hugepages
+	NumaStat                  *int64   // /proc/sys/vm/numa_stat
+	NumaZonelistOrder         string   // /proc/sys/vm/numa_zonelist_order
+	OomDumpTasks              *int64   // /proc/sys/vm/oom_dump_tasks
+	OomKillAllocatingTask     *int64   // /proc/sys/vm/oom_kill_allocating_task
+	OvercommitKbytes          *int64   // /proc/sys/vm/overcommit_kbytes
+	OvercommitMemory          *int64   // /proc/sys/vm/overcommit_memory
+	OvercommitRatio           *int64   // /proc/sys/vm/overcommit_ratio
+	PageCluster               *int64   // /proc/sys/vm/page-cluster
+	PanicOnOom                *int64   // /proc/sys/vm/panic_on_oom
+	PercpuPagelistFraction    *int64   // /proc/sys/vm/percpu_pagelist_fraction
+	StatInterval              *int64   // /proc/sys/vm/stat_interval
+	Swappiness                *int64   // /proc/sys/vm/swappiness
+	UserReserveKbytes         *int64   // /proc/sys/vm/user_reserve_kbytes
+	VfsCachePressure          *int64   // /proc/sys/vm/vfs_cache_pressure
+	WatermarkBoostFactor      *int64   // /proc/sys/vm/watermark_boost_factor
+	WatermarkScaleFactor      *int64   // /proc/sys/vm/watermark_scale_factor
+	ZoneReclaimMode           *int64   // /proc/sys/vm/zone_reclaim_mode
 }
 
 // VM reads the VM statistics from the specified `proc` filesystem.
@@ -109,97 +109,97 @@ func (fs FS) VM() (*VM, error) {
 
 		switch f.Name() {
 		case "admin_reserve_kbytes":
-			vm.AdminReserveKbytes = *vp.PInt64()
+			vm.AdminReserveKbytes = vp.PInt64()
 		case "block_dump":
-			vm.BlockDump = *vp.PInt64()
+			vm.BlockDump = vp.PInt64()
 		case "compact_unevictable_allowed":
-			vm.CompactUnevictableAllowed = *vp.PInt64()
+			vm.CompactUnevictableAllowed = vp.PInt64()
 		case "dirty_background_bytes":
-			vm.DirtyBackgroundBytes = *vp.PInt64()
+			vm.DirtyBackgroundBytes = vp.PInt64()
 		case "dirty_background_ratio":
-			vm.DirtyBackgroundRatio = *vp.PInt64()
+			vm.DirtyBackgroundRatio = vp.PInt64()
 		case "dirty_bytes":
-			vm.DirtyBytes = *vp.PInt64()
+			vm.DirtyBytes = vp.PInt64()
 		case "dirty_expire_centisecs":
-			vm.DirtyExpireCentisecs = *vp.PInt64()
+			vm.DirtyExpireCentisecs = vp.PInt64()
 		case "dirty_ratio":
-			vm.DirtyRatio = *vp.PInt64()
+			vm.DirtyRatio = vp.PInt64()
 		case "dirtytime_expire_seconds":
-			vm.DirtytimeExpireSeconds = *vp.PInt64()
+			vm.DirtytimeExpireSeconds = vp.PInt64()
 		case "dirty_writeback_centisecs":
-			vm.DirtyWritebackCentisecs = *vp.PInt64()
+			vm.DirtyWritebackCentisecs = vp.PInt64()
 		case "drop_caches":
-			vm.DropCaches = *vp.PInt64()
+			vm.DropCaches = vp.PInt64()
 		case "extfrag_threshold":
-			vm.ExtfragThreshold = *vp.PInt64()
+			vm.ExtfragThreshold = vp.PInt64()
 		case "hugetlb_shm_group":
-			vm.HugetlbShmGroup = *vp.PInt64()
+			vm.HugetlbShmGroup = vp.PInt64()
 		case "laptop_mode":
-			vm.LaptopMode = *vp.PInt64()
+			vm.LaptopMode = vp.PInt64()
 		case "legacy_va_layout":
-			vm.LegacyVaLayout = *vp.PInt64()
+			vm.LegacyVaLayout = vp.PInt64()
 		case "lowmem_reserve_ratio":
 			stringSlice := strings.Fields(value)
-			int64Slice := make([]int64, 0, len(stringSlice))
+			pint64Slice := make([]*int64, 0, len(stringSlice))
 			for _, value := range stringSlice {
 				vp := util.NewValueParser(value)
-				int64Slice = append(int64Slice, *vp.PInt64())
+				pint64Slice = append(pint64Slice, vp.PInt64())
 			}
-			vm.LowmemReserveRatio = int64Slice
+			vm.LowmemReserveRatio = pint64Slice
 		case "max_map_count":
-			vm.MaxMapCount = *vp.PInt64()
+			vm.MaxMapCount = vp.PInt64()
 		case "memory_failure_early_kill":
-			vm.MemoryFailureEarlyKill = *vp.PInt64()
+			vm.MemoryFailureEarlyKill = vp.PInt64()
 		case "memory_failure_recovery":
-			vm.MemoryFailureRecovery = *vp.PInt64()
+			vm.MemoryFailureRecovery = vp.PInt64()
 		case "min_free_kbytes":
-			vm.MinFreeKbytes = *vp.PInt64()
+			vm.MinFreeKbytes = vp.PInt64()
 		case "min_slab_ratio":
-			vm.MinSlabRatio = *vp.PInt64()
+			vm.MinSlabRatio = vp.PInt64()
 		case "min_unmapped_ratio":
-			vm.MinUnmappedRatio = *vp.PInt64()
+			vm.MinUnmappedRatio = vp.PInt64()
 		case "mmap_min_addr":
-			vm.MmapMinAddr = *vp.PInt64()
+			vm.MmapMinAddr = vp.PInt64()
 		case "nr_hugepages":
-			vm.NrHugepages = *vp.PInt64()
+			vm.NrHugepages = vp.PInt64()
 		case "nr_hugepages_mempolicy":
-			vm.NrHugepagesMempolicy = *vp.PInt64()
+			vm.NrHugepagesMempolicy = vp.PInt64()
 		case "nr_overcommit_hugepages":
-			vm.NrOvercommitHugepages = *vp.PInt64()
+			vm.NrOvercommitHugepages = vp.PInt64()
 		case "numa_stat":
-			vm.NumaStat = *vp.PInt64()
+			vm.NumaStat = vp.PInt64()
 		case "numa_zonelist_order":
 			vm.NumaZonelistOrder = value
 		case "oom_dump_tasks":
-			vm.OomDumpTasks = *vp.PInt64()
+			vm.OomDumpTasks = vp.PInt64()
 		case "oom_kill_allocating_task":
-			vm.OomKillAllocatingTask = *vp.PInt64()
+			vm.OomKillAllocatingTask = vp.PInt64()
 		case "overcommit_kbytes":
-			vm.OvercommitKbytes = *vp.PInt64()
+			vm.OvercommitKbytes = vp.PInt64()
 		case "overcommit_memory":
-			vm.OvercommitMemory = *vp.PInt64()
+			vm.OvercommitMemory = vp.PInt64()
 		case "overcommit_ratio":
-			vm.OvercommitRatio = *vp.PInt64()
+			vm.OvercommitRatio = vp.PInt64()
 		case "page-cluster":
-			vm.PageCluster = *vp.PInt64()
+			vm.PageCluster = vp.PInt64()
 		case "panic_on_oom":
-			vm.PanicOnOom = *vp.PInt64()
+			vm.PanicOnOom = vp.PInt64()
 		case "percpu_pagelist_fraction":
-			vm.PercpuPagelistFraction = *vp.PInt64()
+			vm.PercpuPagelistFraction = vp.PInt64()
 		case "stat_interval":
-			vm.StatInterval = *vp.PInt64()
+			vm.StatInterval = vp.PInt64()
 		case "swappiness":
-			vm.Swappiness = *vp.PInt64()
+			vm.Swappiness = vp.PInt64()
 		case "user_reserve_kbytes":
-			vm.UserReserveKbytes = *vp.PInt64()
+			vm.UserReserveKbytes = vp.PInt64()
 		case "vfs_cache_pressure":
-			vm.VfsCachePressure = *vp.PInt64()
+			vm.VfsCachePressure = vp.PInt64()
 		case "watermark_boost_factor":
-			vm.WatermarkBoostFactor = *vp.PInt64()
+			vm.WatermarkBoostFactor = vp.PInt64()
 		case "watermark_scale_factor":
-			vm.WatermarkScaleFactor = *vp.PInt64()
+			vm.WatermarkScaleFactor = vp.PInt64()
 		case "zone_reclaim_mode":
-			vm.ZoneReclaimMode = *vp.PInt64()
+			vm.ZoneReclaimMode = vp.PInt64()
 		}
 		if err := vp.Err(); err != nil {
 			return nil, err


Test patch:
diff --git a/sysfs/class_cooling_device_test.go b/sysfs/class_cooling_device_test.go
new file mode 100644
index 0000000..a94a12c
--- /dev/null
+++ b/sysfs/class_cooling_device_test.go
@@ -0,0 +1,52 @@
+// Copyright 2019 The Prometheus Authors
+// 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.
+
+// +build !windows
+
+package sysfs
+
+import (
+	"reflect"
+	"testing"
+)
+
+func TestClassCoolingDeviceStats(t *testing.T) {
+	fs, err := NewFS(sysTestFixtures)
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	coolingDeviceTest, err := fs.ClassCoolingDeviceStats()
+	if err != nil {
+		t.Fatal(err)
+	}
+
+	classCoolingDeviceStats := []ClassCoolingDeviceStats{
+		{
+			Name:     "0",
+			Type:     "Processor",
+			MaxState: 50,
+			CurState: 0,
+		},
+		{
+			Name:     "1",
+			Type:     "intel_powerclamp",
+			MaxState: 27,
+			CurState: -1,
+		},
+	}
+
+	if !reflect.DeepEqual(classCoolingDeviceStats, coolingDeviceTest) {
+		t.Errorf("Result not correct: want %v, have %v", classCoolingDeviceStats, coolingDeviceTest)
+	}
+}
diff --git a/vm_test.go b/vm_test.go
index 492f166..b4d9aad 100644
--- a/vm_test.go
+++ b/vm_test.go
@@ -14,51 +14,72 @@
 package procfs
 
 import (
-	"reflect"
 	"testing"
+
+	"github.com/google/go-cmp/cmp"
 )
 
+func newPInt64(i int64) *int64 {
+	return &i
+}
+
 func TestVM(t *testing.T) {
 	fs, err := NewFS(procTestFixtures)
 	if err != nil {
 		t.Fatal(err)
 	}
-	stats, err := fs.VM()
+	got, err := fs.VM()
 	if err != nil {
 		t.Fatal(err)
 	}
-
-	lowmemreserveratio := []int64{256, 256, 32, 0, 0}
-	vm := &VM{
-		AdminReserveKbytes:        8192,
-		CompactUnevictableAllowed: 1,
-		DirtyBackgroundRatio:      10,
-		DirtyExpireCentisecs:      3000,
-		DirtyRatio:                20,
-		DirtytimeExpireSeconds:    43200,
-		DirtyWritebackCentisecs:   500,
-		ExtfragThreshold:          500,
-		LaptopMode:                5,
+	zeroPointer := newPInt64(0)
+	lowmemreserveratio := []*int64{newPInt64(256), newPInt64(256), newPInt64(32), zeroPointer, zeroPointer}
+	want := &VM{
+		AdminReserveKbytes:        newPInt64(8192),
+		BlockDump:                 zeroPointer,
+		CompactUnevictableAllowed: newPInt64(1),
+		DirtyBackgroundBytes:      zeroPointer,
+		DirtyBackgroundRatio:      newPInt64(10),
+		DirtyBytes:                zeroPointer,
+		DirtyExpireCentisecs:      newPInt64(3000),
+		DirtyRatio:                newPInt64(20),
+		DirtytimeExpireSeconds:    newPInt64(43200),
+		DirtyWritebackCentisecs:   newPInt64(500),
+		DropCaches:                zeroPointer,
+		ExtfragThreshold:          newPInt64(500),
+		HugetlbShmGroup:           zeroPointer,
+		LaptopMode:                newPInt64(5),
+		LegacyVaLayout:            zeroPointer,
 		LowmemReserveRatio:        lowmemreserveratio,
-		MaxMapCount:               65530,
-		MemoryFailureRecovery:     1,
-		MinFreeKbytes:             67584,
-		MinSlabRatio:              5,
-		MinUnmappedRatio:          1,
-		MmapMinAddr:               65536,
-		NumaStat:                  1,
+		MaxMapCount:               newPInt64(65530),
+		MemoryFailureEarlyKill:    zeroPointer,
+		MemoryFailureRecovery:     newPInt64(1),
+		MinFreeKbytes:             newPInt64(67584),
+		MinSlabRatio:              newPInt64(5),
+		MinUnmappedRatio:          newPInt64(1),
+		MmapMinAddr:               newPInt64(65536),
+		NumaStat:                  newPInt64(1),
 		NumaZonelistOrder:         "Node",
-		OomDumpTasks:              1,
-		OvercommitRatio:           50,
-		PageCluster:               3,
-		StatInterval:              1,
-		Swappiness:                60,
-		UserReserveKbytes:         131072,
-		VfsCachePressure:          100,
-		WatermarkBoostFactor:      15000,
-		WatermarkScaleFactor:      10,
+		NrHugepages:               zeroPointer,
+		NrHugepagesMempolicy:      zeroPointer,
+		NrOvercommitHugepages:     zeroPointer,
+		OomDumpTasks:              newPInt64(1),
+		OomKillAllocatingTask:     zeroPointer,
+		OvercommitKbytes:          zeroPointer,
+		OvercommitMemory:          zeroPointer,
+		OvercommitRatio:           newPInt64(50),
+		PageCluster:               newPInt64(3),
+		PanicOnOom:                zeroPointer,
+		PercpuPagelistFraction:    zeroPointer,
+		StatInterval:              newPInt64(1),
+		Swappiness:                newPInt64(60),
+		UserReserveKbytes:         newPInt64(131072),
+		VfsCachePressure:          newPInt64(100),
+		WatermarkBoostFactor:      newPInt64(15000),
+		WatermarkScaleFactor:      newPInt64(10),
+		ZoneReclaimMode:           zeroPointer,
 	}
-	if !reflect.DeepEqual(vm, stats) {
-		t.Errorf("Result not correct: want %v\n, have %v", vm, stats)
+	if diff := cmp.Diff(want, got); diff != "" {
+		t.Fatalf("unexpected power supply class (-want +got):\n%s", diff)
 	}
 }