Skip to content

Commit

Permalink
Merge pull request #455 from qbit/openbsd
Browse files Browse the repository at this point in the history
Add support for OpenBSD
  • Loading branch information
iamemilio authored May 10, 2022
2 parents a659df0 + 0e5a9d4 commit aee135d
Show file tree
Hide file tree
Showing 4 changed files with 168 additions and 0 deletions.
35 changes: 35 additions & 0 deletions internal/sysinfo/memtotal_openbsd_amd64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2020 New Relic Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package sysinfo

import (
"syscall"
"unsafe"
)

// PhysicalMemoryBytes returns the total amount of host memory.
func PhysicalMemoryBytes() (uint64, error) {
mib := []int32{6 /* CTL_HW */, 19 /* HW_PHYSMEM64 */}

buf := make([]byte, 8)
bufLen := uintptr(8)

_, _, e1 := syscall.Syscall6(syscall.SYS___SYSCTL,
uintptr(unsafe.Pointer(&mib[0])), uintptr(len(mib)),
uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&bufLen)),
uintptr(0), uintptr(0))

if e1 != 0 {
return 0, e1
}

switch bufLen {
case 4:
return uint64(*(*uint32)(unsafe.Pointer(&buf[0]))), nil
case 8:
return *(*uint64)(unsafe.Pointer(&buf[0])), nil
default:
return 0, syscall.EIO
}
}
49 changes: 49 additions & 0 deletions internal/sysinfo/memtotal_openbsd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2020 New Relic Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package sysinfo

import (
"errors"
"os/exec"
"regexp"
"strconv"
"testing"
)

var re = regexp.MustCompile(`hw\.physmem=(\d+)`)

func openbsdSysctlMemoryBytes() (uint64, error) {
out, err := exec.Command("/sbin/sysctl", "hw.physmem").Output()
if err != nil {
return 0, err
}

match := re.FindSubmatch(out)
if match == nil {
return 0, errors.New("memory size not found in sysctl output")
}

bts, err := strconv.ParseUint(string(match[1]), 10, 64)
if err != nil {
return 0, err
}

return bts, nil
}

func TestPhysicalMemoryBytes(t *testing.T) {
mem, err := PhysicalMemoryBytes()
if err != nil {
t.Fatal(err)
}

mem2, err := openbsdSysctlMemoryBytes()
if nil != err {
t.Fatal(err)
}

if mem != mem2 {
t.Errorf("Expected %d, got %d\n", mem2, mem)
}
}
35 changes: 35 additions & 0 deletions v3/internal/sysinfo/memtotal_openbsd_amd64.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2020 New Relic Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package sysinfo

import (
"syscall"
"unsafe"
)

// PhysicalMemoryBytes returns the total amount of host memory.
func PhysicalMemoryBytes() (uint64, error) {
mib := []int32{6 /* CTL_HW */, 19 /* HW_PHYSMEM64 */}

buf := make([]byte, 8)
bufLen := uintptr(8)

_, _, e1 := syscall.Syscall6(syscall.SYS___SYSCTL,
uintptr(unsafe.Pointer(&mib[0])), uintptr(len(mib)),
uintptr(unsafe.Pointer(&buf[0])), uintptr(unsafe.Pointer(&bufLen)),
uintptr(0), uintptr(0))

if e1 != 0 {
return 0, e1
}

switch bufLen {
case 4:
return uint64(*(*uint32)(unsafe.Pointer(&buf[0]))), nil
case 8:
return *(*uint64)(unsafe.Pointer(&buf[0])), nil
default:
return 0, syscall.EIO
}
}
49 changes: 49 additions & 0 deletions v3/internal/sysinfo/memtotal_openbsd_test.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
// Copyright 2020 New Relic Corporation. All rights reserved.
// SPDX-License-Identifier: Apache-2.0

package sysinfo

import (
"errors"
"os/exec"
"regexp"
"strconv"
"testing"
)

var re = regexp.MustCompile(`hw\.physmem=(\d+)`)

func openbsdSysctlMemoryBytes() (uint64, error) {
out, err := exec.Command("/sbin/sysctl", "hw.physmem").Output()
if err != nil {
return 0, err
}

match := re.FindSubmatch(out)
if match == nil {
return 0, errors.New("memory size not found in sysctl output")
}

bts, err := strconv.ParseUint(string(match[1]), 10, 64)
if err != nil {
return 0, err
}

return bts, nil
}

func TestPhysicalMemoryBytes(t *testing.T) {
mem, err := PhysicalMemoryBytes()
if err != nil {
t.Fatal(err)
}

mem2, err := openbsdSysctlMemoryBytes()
if nil != err {
t.Fatal(err)
}

if mem != mem2 {
t.Errorf("Expected %d, got %d\n", mem2, mem)
}
}

0 comments on commit aee135d

Please sign in to comment.