github.com/cloud-foundations/dominator@v0.0.0-20221004181915-6e4fee580046/lib/objectserver/filesystem/garbageCollector.go (about)

     1  package filesystem
     2  
     3  import (
     4  	"syscall"
     5  	"time"
     6  
     7  	"github.com/Cloud-Foundations/Dominator/lib/format"
     8  )
     9  
    10  func (objSrv *ObjectServer) garbageCollector() (uint64, error) {
    11  	if objSrv.gc == nil {
    12  		return 0, nil
    13  	}
    14  	objSrv.rwLock.Lock()
    15  	if time.Since(objSrv.lastGarbageCollection) < time.Second {
    16  		objSrv.rwLock.Unlock()
    17  		return 0, nil
    18  	}
    19  	objSrv.lastGarbageCollection = time.Now()
    20  	objSrv.rwLock.Unlock()
    21  	free, capacity, err := objSrv.getSpaceMetrics()
    22  	if err != nil {
    23  		return 0, err
    24  	}
    25  	cleanupStartPercent := sanitisePercentage(*objectServerCleanupStartPercent)
    26  	cleanupStopPercent := sanitisePercentage(*objectServerCleanupStopPercent)
    27  	if cleanupStopPercent >= cleanupStartPercent {
    28  		cleanupStopPercent = cleanupStartPercent - 1
    29  	}
    30  	utilisation := (capacity - free) * 100 / capacity
    31  	if utilisation < cleanupStartPercent {
    32  		return 0, nil
    33  	}
    34  	bytesToDelete := (utilisation - cleanupStopPercent) * capacity / 100
    35  	bytesDeleted, err := objSrv.gc(bytesToDelete)
    36  	if err != nil {
    37  		objSrv.logger.Printf("Error collecting garbage, only deleted: %s: %s\n",
    38  			format.FormatBytes(bytesDeleted), err)
    39  		return 0, err
    40  	}
    41  	return bytesDeleted, nil
    42  }
    43  
    44  func (t *ObjectServer) getSpaceMetrics() (uint64, uint64, error) {
    45  	if fd, err := syscall.Open(t.baseDir, syscall.O_RDONLY, 0); err != nil {
    46  		t.logger.Printf("error opening: %s: %s", t.baseDir, err)
    47  		return 0, 0, err
    48  	} else {
    49  		defer syscall.Close(fd)
    50  		var statbuf syscall.Statfs_t
    51  		if err := syscall.Fstatfs(fd, &statbuf); err != nil {
    52  			t.logger.Printf("error getting file-system stats: %s\n", err)
    53  			return 0, 0, err
    54  		}
    55  		rootReservation := statbuf.Bfree - statbuf.Bavail
    56  		return uint64(statbuf.Bavail) * uint64(statbuf.Bsize),
    57  			uint64(statbuf.Blocks-rootReservation) * uint64(statbuf.Bsize), nil
    58  	}
    59  }
    60  
    61  func sanitisePercentage(percent int) uint64 {
    62  	if percent < 1 {
    63  		return 1
    64  	}
    65  	if percent > 99 {
    66  		return 99
    67  	}
    68  	return uint64(percent)
    69  }