This commit is contained in:
@@ -0,0 +1,39 @@
|
||||
//go:build linux
|
||||
|
||||
package hostcollect
|
||||
|
||||
import "syscall"
|
||||
|
||||
// statFS reads capacity and inode usage for one mount point. statfs(2) is a read-only
|
||||
// syscall that needs no capability, which keeps the agent inside cap_drop: [ALL].
|
||||
//
|
||||
// "Used" follows df: total blocks minus free blocks, so the filesystem's reserved
|
||||
// blocks count as used rather than as available headroom the operator does not have.
|
||||
func statFS(path string) (FilesystemUsage, error) {
|
||||
var stat syscall.Statfs_t
|
||||
if err := syscall.Statfs(path, &stat); err != nil {
|
||||
return FilesystemUsage{}, err
|
||||
}
|
||||
blockSize := uint64(stat.Bsize) //nolint:gosec,unconvert // Bsize is int64 on some arches, uint32 on others
|
||||
if blockSize == 0 {
|
||||
return FilesystemUsage{}, nil
|
||||
}
|
||||
blocks := stat.Blocks
|
||||
free := stat.Bfree
|
||||
if free > blocks {
|
||||
free = blocks
|
||||
}
|
||||
usage := FilesystemUsage{
|
||||
CapacityBytes: blocks * blockSize,
|
||||
UsedBytes: (blocks - free) * blockSize,
|
||||
InodesTotal: stat.Files,
|
||||
}
|
||||
if stat.Files > 0 {
|
||||
freeInodes := stat.Ffree
|
||||
if freeInodes > stat.Files {
|
||||
freeInodes = stat.Files
|
||||
}
|
||||
usage.InodesUsed = stat.Files - freeInodes
|
||||
}
|
||||
return usage, nil
|
||||
}
|
||||
Reference in New Issue
Block a user