github.com/grafana/pyroscope@v1.18.0/pkg/util/disk/disk.go (about)

     1  //go:build !windows
     2  
     3  package diskutil
     4  
     5  import (
     6  	"fmt"
     7  	"math"
     8  
     9  	"golang.org/x/sys/unix"
    10  )
    11  
    12  type volumeChecker struct {
    13  	minFreeDisk                uint64
    14  	minDiskAvailablePercentage float64
    15  }
    16  
    17  func NewVolumeChecker(minFreeDisk uint64, minDiskAvailablePercentage float64) VolumeChecker {
    18  	return &volumeChecker{
    19  		minFreeDisk:                minFreeDisk,
    20  		minDiskAvailablePercentage: minDiskAvailablePercentage,
    21  	}
    22  }
    23  
    24  func (v *volumeChecker) HasHighDiskUtilization(path string) (*VolumeStats, error) {
    25  	var stat unix.Statfs_t
    26  	if err := unix.Statfs(path, &stat); err != nil {
    27  		return nil, err
    28  	}
    29  
    30  	//nolint:unconvert // In BSD family (except OpenBSD), the type of stat.Bavail is int64.
    31  	avail := uint64(stat.Bavail)
    32  	isValid := avail&math.MaxInt64 == avail && stat.Blocks > 0
    33  	if !isValid {
    34  		return nil, fmt.Errorf("invalid statfs values: %+v", stat)
    35  	}
    36  
    37  	// available means accessible to the current user, while free means bytes
    38  	// for privileged users. (Linux sometimes reserves some space for root)
    39  	var (
    40  		stats = VolumeStats{
    41  			BytesAvailable: avail * uint64(stat.Bsize),
    42  		}
    43  		percentageAvailable = float64(avail) / float64(stat.Blocks*uint64(stat.Bsize))
    44  	)
    45  
    46  	// if bytes available is bigger than minFreeDisk => not in high disk utilization
    47  	if stats.BytesAvailable >= v.minFreeDisk {
    48  		return &stats, nil
    49  	}
    50  
    51  	// no in high disk utilization when more than the constant
    52  	if percentageAvailable > v.minDiskAvailablePercentage {
    53  		return &stats, nil
    54  	}
    55  
    56  	stats.HighDiskUtilization = true
    57  	return &stats, nil
    58  }