From 0f6191987ef73067a8d66750cc95cccb1b99f760 Mon Sep 17 00:00:00 2001 From: Dominik Honnef Date: Mon, 26 Dec 2016 22:50:52 +0100 Subject: [PATCH] Implement file systems on FreeBSD without cgo The code may also work for other BSDs, but I don't have access to those for testing. --- collector/filesystem_bsd.go | 2 +- collector/filesystem_freebsd.go | 88 +++++++++++++++++++++++++++++++++ 2 files changed, 89 insertions(+), 1 deletion(-) create mode 100644 collector/filesystem_freebsd.go diff --git a/collector/filesystem_bsd.go b/collector/filesystem_bsd.go index 3a2037a..7a98161 100644 --- a/collector/filesystem_bsd.go +++ b/collector/filesystem_bsd.go @@ -11,7 +11,7 @@ // See the License for the specific language governing permissions and // limitations under the License. -// +build freebsd openbsd darwin,amd64 dragonfly +// +build openbsd darwin,amd64 dragonfly // +build !nofilesystem package collector diff --git a/collector/filesystem_freebsd.go b/collector/filesystem_freebsd.go new file mode 100644 index 0000000..8bd697b --- /dev/null +++ b/collector/filesystem_freebsd.go @@ -0,0 +1,88 @@ +// Copyright 2015 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 !nofilesystem + +package collector + +import ( + "bytes" + "unsafe" + + "github.com/prometheus/common/log" + "golang.org/x/sys/unix" +) + +const ( + defIgnoredMountPoints = "^/(dev)($|/)" + defIgnoredFSTypes = "^devfs$" + MNT_RDONLY = 0x1 + MNT_NOWAIT = 0x2 +) + +func gostring(b []int8) string { + bb := *(*[]byte)(unsafe.Pointer(&b)) + idx := bytes.IndexByte(bb, 0) + if idx < 0 { + return "" + } + return string(bb[:idx]) +} + +// Expose filesystem fullness. +func (c *filesystemCollector) GetStats() (stats []filesystemStats, err error) { + buf := make([]unix.Statfs_t, 16) + for { + n, err := unix.Getfsstat(buf, MNT_NOWAIT) + if err != nil { + return nil, err + } + if n < len(buf) { + buf = buf[:n] + break + } + buf = make([]unix.Statfs_t, len(buf)*2) + } + stats = []filesystemStats{} + for _, fs := range buf { + mountpoint := gostring(fs.Mntonname[:]) + if c.ignoredMountPointsPattern.MatchString(mountpoint) { + log.Debugf("Ignoring mount point: %s", mountpoint) + continue + } + + device := gostring(fs.Mntfromname[:]) + fstype := gostring(fs.Fstypename[:]) + if c.ignoredFSTypesPattern.MatchString(fstype) { + log.Debugf("Ignoring fs type: %s", fstype) + continue + } + + var ro float64 + if (fs.Flags & MNT_RDONLY) != 0 { + ro = 1 + } + + labelValues := []string{device, mountpoint, fstype} + stats = append(stats, filesystemStats{ + labelValues: labelValues, + size: float64(fs.Blocks) * float64(fs.Bsize), + free: float64(fs.Bfree) * float64(fs.Bsize), + avail: float64(fs.Bavail) * float64(fs.Bsize), + files: float64(fs.Files), + filesFree: float64(fs.Ffree), + ro: ro, + }) + } + return stats, nil +}