Skip to content

Commit

Permalink
Only syscall.Stat() vol paths in metrics path
Browse files Browse the repository at this point in the history
Balance between syscall.Stat() everything with
the aim of very accurate allocated storage usage
or syscall.Stat() nothing which will miss the deltas
of provisioned vs allocated storage.
Don't syscall.Stat() in the child directories of each
volume path.

Signed-off-by: Andrew Durbin <andrewd@zededa.com>
  • Loading branch information
andrewd-zededa authored and eriknordmark committed Jul 11, 2024
1 parent c784fd6 commit dd5838a
Showing 1 changed file with 29 additions and 13 deletions.
42 changes: 29 additions & 13 deletions pkg/pillar/diskmetrics/usage.go
Original file line number Diff line number Diff line change
Expand Up @@ -69,20 +69,36 @@ func SizeFromDir(log *base.LogObject, dirname string) (uint64, error) {
log.Tracef("Dir %s size %d\n", filename, size)
totalUsed += size
} else {
// FileInfo.Size() returns the provisioned size
// Sparse files will have a smaller allocated size than provisioned
// Use full syscall.Stat_t to get the allocated size
allocatedBytes, err := StatAllocatedBytes(filename)
if err != nil {
allocatedBytes = uint64(location.Size())
// The selection of these two persist directories is intended to pick a balance
// between:
// - calling syscall.Stat() on every file which is heavy on time and compute
// - not calling syscall.Stat() on anything which can overestimate storage allocated
// because the difference between allocated and provisioned storage is
// not accounted for.
//
// It is believed that the majority of sparsefile usage (by provisioned GB)
// will be in the clear and vault volumes base directories so a lot of compute time
// can be saved by not checking detailed allocated bytes information in deeper
// directories.
if dirname == types.VolumeEncryptedDirName || dirname == types.VolumeClearDirName {
// FileInfo.Size() returns the provisioned size
// Sparse files will have a smaller allocated size than provisioned
// Use full syscall.Stat_t to get the allocated size
allocatedBytes, err := StatAllocatedBytes(filename)
if err != nil {
allocatedBytes = uint64(location.Size())
}
// Fully Allocated: don't use allocated bytes
// stat math of %b*%B as it will over-account space
if allocatedBytes >= uint64(location.Size()) {
allocatedBytes = uint64(location.Size())
}
log.Tracef("File %s Size %d\n", filename, allocatedBytes)
totalUsed += allocatedBytes
} else {
log.Tracef("File %s Size %d\n", filename, location.Size())
totalUsed += uint64(location.Size())
}
// Fully Allocated: don't use allocated bytes
// stat math of %b*%B as it will over-account space
if allocatedBytes >= uint64(location.Size()) {
allocatedBytes = uint64(location.Size())
}
log.Tracef("File %s Size %d\n", filename, allocatedBytes)
totalUsed += allocatedBytes
}
}
}
Expand Down

0 comments on commit dd5838a

Please sign in to comment.