@@ -48,17 +48,21 @@ import (
48
48
// Common structure for Component
49
49
type SizeTracker struct {
50
50
internal.BaseComponent
51
- mountSize * MountSize
51
+ mountSize * MountSize
52
+ bucketCapacityFallback bool
53
+ displayCapacityMb uint64
52
54
}
53
55
54
56
// Structure defining your config parameters
55
57
type SizeTrackerOptions struct {
56
- JournalName string `config:"journal-name" yaml:"journal-name,omitempty"`
58
+ JournalName string `config:"journal-name" yaml:"journal-name,omitempty"`
59
+ BucketCapacityFallback bool `config:"bucket-capacity-fallback" yaml:"bucket-capacity-fallback,omitempty"`
57
60
}
58
61
59
62
const compName = "size_tracker"
60
63
const blockSize = int64 (4096 )
61
- const default_journal_name = "mount_size.dat"
64
+ const defaultJournalName = "mount_size.dat"
65
+ const evictionThreshold = 0.95
62
66
63
67
// Verification to check satisfaction criteria with Component Interface
64
68
var _ internal.Component = & SizeTracker {}
@@ -104,7 +108,21 @@ func (st *SizeTracker) Configure(_ bool) error {
104
108
return fmt .Errorf ("SizeTracker: config error [invalid config attributes]" )
105
109
}
106
110
107
- journalName := default_journal_name
111
+ st .bucketCapacityFallback = conf .BucketCapacityFallback
112
+
113
+ if st .bucketCapacityFallback {
114
+ // Borrow enable-symlinks flag from attribute cache
115
+ if config .IsSet ("libfuse.display-capacity-mb" ) {
116
+ err := config .UnmarshalKey ("libfuse.display-capacity-mb" , & st .displayCapacityMb )
117
+ if err != nil {
118
+ st .bucketCapacityFallback = false
119
+ log .Err ("Configure : Failed to unmarshal libfuse.display-capacity-mb. Attempting to use" +
120
+ " bucket capacity fallback without setting display capacity." )
121
+ }
122
+ }
123
+ }
124
+
125
+ journalName := defaultJournalName
108
126
if config .IsSet (compName + ".journal-name" ) {
109
127
journalName = conf .JournalName
110
128
} else {
@@ -320,8 +338,26 @@ func (st *SizeTracker) FlushFile(options internal.FlushFileOptions) error {
320
338
// Filesystem level operations
321
339
func (st * SizeTracker ) StatFs () (* common.Statfs_t , bool , error ) {
322
340
log .Trace ("SizeTracker::StatFs" )
341
+
342
+ blocks := st .mountSize .GetSize () / uint64 (blockSize )
343
+
344
+ if st .bucketCapacityFallback {
345
+ stat , ret , err := st .NextComponent ().StatFs ()
346
+
347
+ if err == nil && ret {
348
+ // Custom logic for use with Nx Plugin
349
+ // If the user is over the capacity limit set by Nx, then we need to prevent them from
350
+ // accidental overuse of their bucket. So we change our reporting to instead report
351
+ // the used capacity of the bucket to enable the VMS to start eviction
352
+ if evictionThreshold * float64 (stat .Blocks ) > float64 (st .displayCapacityMb ) {
353
+ log .Warn ("SizeTracker::StatFs : changing from size_tracker size to S3 bucket size due to overuse of bucket" )
354
+ blocks = stat .Blocks
355
+ }
356
+ }
357
+ }
358
+
323
359
stat := common.Statfs_t {
324
- Blocks : st . mountSize . GetSize () / uint64 ( blockSize ) ,
360
+ Blocks : blocks ,
325
361
// there is no set capacity limit in cloud storage
326
362
// so we use zero for free and avail
327
363
// this zero value is used in the libfuse component to recognize that cloud storage responded
0 commit comments