From: Daniel Swarbrick <dswarbrick@debian.org>
Date: Mon, 17 Feb 2025 15:09:38 +0100
Subject: Backport PR 644

Origin: https://github.com/prometheus/procfs/pull/644

This small enhancement is required for prometheus-node-exporter >=
1.9.0.
---
 sysfs/system_cpu.go      | 10 ++++++++++
 sysfs/system_cpu_test.go | 29 +++++++++++++++++++++++++++++
 testdata/fixtures.ttar   |  5 +++++
 3 files changed, 44 insertions(+)

diff --git a/sysfs/system_cpu.go b/sysfs/system_cpu.go
index 5b1bec8..a68c6d9 100644
--- a/sysfs/system_cpu.go
+++ b/sysfs/system_cpu.go
@@ -132,6 +132,16 @@ func (c CPU) ThermalThrottle() (*CPUThermalThrottle, error) {
 	return t, nil
 }
 
+// Online returns the online status of a CPU from `/sys/devices/system/cpu/cpuN/online`.
+func (c CPU) Online() (bool, error) {
+	cpuPath := filepath.Join(string(c), "online")
+	str, err := util.SysReadFile(cpuPath)
+	if err != nil {
+		return false, err
+	}
+	return str == "1", nil
+}
+
 func parseCPUThermalThrottle(cpuPath string) (*CPUThermalThrottle, error) {
 	t := CPUThermalThrottle{}
 	var err error
diff --git a/sysfs/system_cpu_test.go b/sysfs/system_cpu_test.go
index 577c118..a39c570 100644
--- a/sysfs/system_cpu_test.go
+++ b/sysfs/system_cpu_test.go
@@ -18,6 +18,7 @@ package sysfs
 
 import (
 	"errors"
+	"os"
 	"reflect"
 	"testing"
 )
@@ -63,6 +64,34 @@ func TestCPUTopology(t *testing.T) {
 	}
 }
 
+func TestCPUOnline(t *testing.T) {
+	fs, err := NewFS(sysTestFixtures)
+	if err != nil {
+		t.Fatal(err)
+	}
+	cpus, err := fs.CPUs()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if want, have := 3, len(cpus); want != have {
+		t.Errorf("incorrect number of CPUs, have %v, want %v", want, have)
+	}
+	cpu0Online, err := cpus[0].Online()
+	if err != nil {
+		t.Fatal(err)
+	}
+	if want, have := true, cpu0Online; want != have {
+		t.Errorf("incorrect online status, have %v, want %v", want, have)
+	}
+	cpu1Online, err := cpus[1].Online()
+	if err != nil && !errors.Is(err, os.ErrNotExist) {
+		t.Fatal(err)
+	}
+	if want, have := false, cpu1Online; want != have {
+		t.Errorf("incorrect online status, have %v, want %v", want, have)
+	}
+}
+
 func TestCPUThermalThrottle(t *testing.T) {
 	fs, err := NewFS(sysTestFixtures)
 	if err != nil {
diff --git a/testdata/fixtures.ttar b/testdata/fixtures.ttar
index 32bbd1e..9d7ca95 100644
--- a/testdata/fixtures.ttar
+++ b/testdata/fixtures.ttar
@@ -13441,6 +13441,11 @@ Mode: 775
 Path: fixtures/sys/devices/system/cpu/cpu0/cpufreq
 SymlinkTo: ../cpufreq/policy0
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
+Path: fixtures/sys/devices/system/cpu/cpu0/online
+Lines: 1
+1EOF
+Mode: 644
+# ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
 Directory: fixtures/sys/devices/system/cpu/cpu0/thermal_throttle
 Mode: 755
 # ttar - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
