Configurable storage path storage limit

This commit is contained in:
Łukasz Magiera 2021-02-18 16:44:34 +01:00
parent 61eb91ff37
commit 37b1fb97fb
8 changed files with 121 additions and 42 deletions

View File

@ -220,7 +220,18 @@ var storageListCmd = &cli.Command{
}
ping := time.Now().Sub(pingStart)
usedPercent := (st.Capacity - st.Available) * 100 / st.Capacity
safeRepeat := func(s string, count int) string {
if count < 0 {
return ""
}
return strings.Repeat(s, count)
}
var barCols = int64(50)
// filesystem use bar
{
usedPercent := (st.Capacity - st.FSAvailable) * 100 / st.Capacity
percCol := color.FgGreen
switch {
@ -230,16 +241,45 @@ var storageListCmd = &cli.Command{
percCol = color.FgYellow
}
var barCols = int64(50)
set := (st.Capacity - st.Available) * barCols / st.Capacity
used := (st.Capacity - (st.Available + st.Reserved)) * barCols / st.Capacity
set := (st.Capacity - st.FSAvailable) * barCols / st.Capacity
used := (st.Capacity - (st.FSAvailable + st.Reserved)) * barCols / st.Capacity
reserved := set - used
bar := strings.Repeat("#", int(used)) + strings.Repeat("*", int(reserved)) + strings.Repeat(" ", int(barCols-set))
bar := safeRepeat("#", int(used)) + safeRepeat("*", int(reserved)) + safeRepeat(" ", int(barCols-set))
fmt.Printf("\t[%s] %s/%s %s\n", color.New(percCol).Sprint(bar),
types.SizeStr(types.NewInt(uint64(st.Capacity-st.Available))),
desc := ""
if st.Max > 0 {
desc = " (filesystem)"
}
fmt.Printf("\t[%s] %s/%s %s%s\n", color.New(percCol).Sprint(bar),
types.SizeStr(types.NewInt(uint64(st.Capacity-st.FSAvailable))),
types.SizeStr(types.NewInt(uint64(st.Capacity))),
color.New(percCol).Sprintf("%d%%", usedPercent), desc)
}
// optional configured limit bar
if st.Max > 0 {
usedPercent := st.Used * 100 / st.Max
percCol := color.FgGreen
switch {
case usedPercent > 98:
percCol = color.FgRed
case usedPercent > 90:
percCol = color.FgYellow
}
set := st.Used * barCols / st.Max
used := (st.Used + st.Reserved) * barCols / st.Max
reserved := set - used
bar := safeRepeat("#", int(used)) + safeRepeat("*", int(reserved)) + safeRepeat(" ", int(barCols-set))
fmt.Printf("\t[%s] %s/%s %s (limit)\n", color.New(percCol).Sprint(bar),
types.SizeStr(types.NewInt(uint64(st.Used))),
types.SizeStr(types.NewInt(uint64(st.Max))),
color.New(percCol).Sprintf("%d%%", usedPercent))
}
fmt.Printf("\t%s; %s; %s; Reserved: %s\n",
color.YellowString("Unsealed: %d", cnt[0]),
color.GreenString("Sealed: %d", cnt[1]),

View File

@ -3,5 +3,10 @@ package fsutil
type FsStat struct {
Capacity int64
Available int64 // Available to use for sector storage
FSAvailable int64 // Available in the filesystem
Reserved int64
// non-zero when storage has configured MaxStorage
Max int64
Used int64
}

View File

@ -16,6 +16,8 @@ func Statfs(path string) (FsStat, error) {
//nolint:unconvert
return FsStat{
Capacity: int64(stat.Blocks) * int64(stat.Bsize),
Available: int64(stat.Bavail) * int64(stat.Bsize),
FSAvailable: int64(stat.Bavail) * int64(stat.Bsize),
}, nil
}

View File

@ -24,5 +24,6 @@ func Statfs(volumePath string) (FsStat, error) {
return FsStat{
Capacity: totalBytes,
Available: availBytes,
FSAvailable: availBytes,
}, nil
}

View File

@ -156,6 +156,7 @@ func addTestWorker(t *testing.T, sched *scheduler, index *stores.Index, name str
}, fsutil.FsStat{
Capacity: 1 << 40,
Available: 1 << 40,
FSAvailable: 1 << 40,
Reserved: 3,
})
require.NoError(t, err)

View File

@ -29,6 +29,7 @@ type StorageInfo struct {
ID ID
URLs []string // TODO: Support non-http transports
Weight uint64
MaxStorage uint64
CanSeal bool
CanStore bool
@ -156,6 +157,7 @@ func (i *Index) StorageAttach(ctx context.Context, si StorageInfo, st fsutil.FsS
}
i.stores[si.ID].info.Weight = si.Weight
i.stores[si.ID].info.MaxStorage = si.MaxStorage
i.stores[si.ID].info.CanSeal = si.CanSeal
i.stores[si.ID].info.CanStore = si.CanStore

View File

@ -42,6 +42,10 @@ type LocalStorageMeta struct {
// Finalized sectors that will be proved over time will be stored here
CanStore bool
// MaxStorage specifies the maximum number of bytes to use for sector storage
// (0 = unlimited)
MaxStorage uint64
}
// StorageConfig .lotusstorage/storage.json
@ -78,6 +82,7 @@ type Local struct {
type path struct {
local string // absolute local path
maxStorage uint64
reserved int64
reservations map[abi.SectorID]storiface.SectorFileType
@ -127,6 +132,25 @@ func (p *path) stat(ls LocalStorage) (fsutil.FsStat, error) {
stat.Available = 0
}
if p.maxStorage > 0 {
used, err := ls.DiskUsage(p.local)
if err != nil {
return fsutil.FsStat{}, err
}
stat.Max = int64(p.maxStorage)
stat.Used = used
avail := int64(p.maxStorage) - used
if uint64(used) > p.maxStorage {
avail = 0
}
if avail < stat.Available {
stat.Available = avail
}
}
return stat, err
}
@ -164,6 +188,7 @@ func (st *Local) OpenPath(ctx context.Context, p string) error {
out := &path{
local: p,
maxStorage: meta.MaxStorage,
reserved: 0,
reservations: map[abi.SectorID]storiface.SectorFileType{},
}
@ -177,6 +202,7 @@ func (st *Local) OpenPath(ctx context.Context, p string) error {
ID: meta.ID,
URLs: st.urls,
Weight: meta.Weight,
MaxStorage: meta.MaxStorage,
CanSeal: meta.CanSeal,
CanStore: meta.CanStore,
}, fst)
@ -240,6 +266,7 @@ func (st *Local) Redeclare(ctx context.Context) error {
ID: id,
URLs: st.urls,
Weight: meta.Weight,
MaxStorage: meta.MaxStorage,
CanSeal: meta.CanSeal,
CanStore: meta.CanStore,
}, fst)

View File

@ -38,6 +38,7 @@ func (t *TestingLocalStorage) Stat(path string) (fsutil.FsStat, error) {
return fsutil.FsStat{
Capacity: pathSize,
Available: pathSize,
FSAvailable: pathSize,
}, nil
}