Merge pull request #7735 from filecoin-project/feat/storlocks-cmd

Command to list active sector locks
This commit is contained in:
Łukasz Magiera 2021-12-08 00:11:17 +01:00 committed by GitHub
commit 49c619d65d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 170 additions and 0 deletions

View File

@ -145,6 +145,7 @@ type StorageMiner interface {
StorageLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error //perm:admin
StorageTryLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) //perm:admin
StorageList(ctx context.Context) (map[stores.ID][]stores.Decl, error) //perm:admin
StorageGetLocks(ctx context.Context) (storiface.SectorLocks, error) //perm:admin
StorageLocal(ctx context.Context) (map[stores.ID]string, error) //perm:admin
StorageStat(ctx context.Context, id stores.ID) (fsutil.FsStat, error) //perm:admin

View File

@ -254,6 +254,13 @@ func init() {
api.SectorState(sealing.Proving): 120,
})
addExample([]abi.SectorNumber{123, 124})
addExample([]storiface.SectorLock{
{
Sector: abi.SectorID{Number: 123, Miner: 1000},
Write: [storiface.FileTypes]uint{0, 0, 1},
Read: [storiface.FileTypes]uint{2, 3, 0},
},
})
// worker specific
addExample(storiface.AcquireMove)

View File

@ -794,6 +794,8 @@ type StorageMinerStruct struct {
StorageFindSector func(p0 context.Context, p1 abi.SectorID, p2 storiface.SectorFileType, p3 abi.SectorSize, p4 bool) ([]stores.SectorStorageInfo, error) `perm:"admin"`
StorageGetLocks func(p0 context.Context) (storiface.SectorLocks, error) `perm:"admin"`
StorageInfo func(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) `perm:"admin"`
StorageList func(p0 context.Context) (map[stores.ID][]stores.Decl, error) `perm:"admin"`
@ -4647,6 +4649,17 @@ func (s *StorageMinerStub) StorageFindSector(p0 context.Context, p1 abi.SectorID
return *new([]stores.SectorStorageInfo), ErrNotSupported
}
func (s *StorageMinerStruct) StorageGetLocks(p0 context.Context) (storiface.SectorLocks, error) {
if s.Internal.StorageGetLocks == nil {
return *new(storiface.SectorLocks), ErrNotSupported
}
return s.Internal.StorageGetLocks(p0)
}
func (s *StorageMinerStub) StorageGetLocks(p0 context.Context) (storiface.SectorLocks, error) {
return *new(storiface.SectorLocks), ErrNotSupported
}
func (s *StorageMinerStruct) StorageInfo(p0 context.Context, p1 stores.ID) (stores.StorageInfo, error) {
if s.Internal.StorageInfo == nil {
return *new(stores.StorageInfo), ErrNotSupported

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -48,6 +48,7 @@ stored while moving through the sealing pipeline (references as 'seal').`,
storageListCmd,
storageFindCmd,
storageCleanupCmd,
storageLocks,
},
}
@ -758,3 +759,43 @@ func cleanupRemovedSectorData(ctx context.Context, api api.StorageMiner, napi v0
return nil
}
var storageLocks = &cli.Command{
Name: "locks",
Usage: "show active sector locks",
Action: func(cctx *cli.Context) error {
api, closer, err := lcli.GetStorageMinerAPI(cctx)
if err != nil {
return err
}
defer closer()
ctx := lcli.ReqContext(cctx)
locks, err := api.StorageGetLocks(ctx)
if err != nil {
return err
}
for _, lock := range locks.Locks {
st, err := api.SectorsStatus(ctx, lock.Sector.Number, false)
if err != nil {
return xerrors.Errorf("getting sector status(%d): %w", lock.Sector.Number, err)
}
lockstr := fmt.Sprintf("%d\t%s\t", lock.Sector.Number, color.New(stateOrder[sealing.SectorState(st.State)].col).Sprint(st.State))
for i := 0; i < storiface.FileTypes; i++ {
if lock.Write[i] > 0 {
lockstr += fmt.Sprintf("%s(%s) ", storiface.SectorFileType(1<<i).String(), color.RedString("W"))
}
if lock.Read[i] > 0 {
lockstr += fmt.Sprintf("%s(%s:%d) ", storiface.SectorFileType(1<<i).String(), color.GreenString("R"), lock.Read[i])
}
}
fmt.Println(lockstr)
}
return nil
},
}

View File

@ -138,6 +138,7 @@
* [StorageDeclareSector](#StorageDeclareSector)
* [StorageDropSector](#StorageDropSector)
* [StorageFindSector](#StorageFindSector)
* [StorageGetLocks](#StorageGetLocks)
* [StorageInfo](#StorageInfo)
* [StorageList](#StorageList)
* [StorageLocal](#StorageLocal)
@ -2240,6 +2241,37 @@ Inputs:
Response: `null`
### StorageGetLocks
Perms: admin
Inputs: `null`
Response:
```json
{
"Locks": [
{
"Sector": {
"Miner": 1000,
"Number": 123
},
"Write": [
0,
0,
1
],
"Read": [
2,
3,
0
]
}
]
}
```
### StorageInfo

View File

@ -1941,6 +1941,7 @@ COMMANDS:
list list local storage paths
find find sector in the storage system
cleanup trigger cleanup actions
locks show active sector locks
help, h Shows a list of commands or help for one command
OPTIONS:
@ -2050,6 +2051,19 @@ OPTIONS:
```
### lotus-miner storage locks
```
NAME:
lotus-miner storage locks - show active sector locks
USAGE:
lotus-miner storage locks [command options] [arguments...]
OPTIONS:
--help, -h show help (default: false)
```
## lotus-miner sealing
```
NAME:

View File

@ -76,6 +76,7 @@ type SectorIndex interface { // part of storage-miner api
// atomically acquire locks on all sector file types. close ctx to unlock
StorageLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) error
StorageTryLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error)
StorageGetLocks(ctx context.Context) (storiface.SectorLocks, error)
StorageList(ctx context.Context) (map[ID][]Decl, error)
}

View File

@ -2,6 +2,7 @@ package stores
import (
"context"
"sort"
"sync"
"golang.org/x/xerrors"
@ -154,3 +155,32 @@ func (i *indexLocks) StorageLock(ctx context.Context, sector abi.SectorID, read
func (i *indexLocks) StorageTryLock(ctx context.Context, sector abi.SectorID, read storiface.SectorFileType, write storiface.SectorFileType) (bool, error) {
return i.lockWith(ctx, (*sectorLock).tryLockSafe, sector, read, write)
}
func (i *indexLocks) StorageGetLocks(context.Context) (storiface.SectorLocks, error) {
i.lk.Lock()
defer i.lk.Unlock()
out := storiface.SectorLocks{
Locks: []storiface.SectorLock{},
}
for id, lock := range i.locks {
l := storiface.SectorLock{Sector: id}
for t, b := range lock.w.All() {
if b {
l.Write[t]++
}
}
copy(l.Read[:], lock.r[:])
out.Locks = append(out.Locks, l)
}
sort.Slice(out.Locks, func(i, j int) bool {
return out.Locks[i].Sector.Number < out.Locks[j].Sector.Number
})
return out, nil
}

View File

@ -110,6 +110,21 @@ func (mr *MockSectorIndexMockRecorder) StorageFindSector(arg0, arg1, arg2, arg3,
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageFindSector", reflect.TypeOf((*MockSectorIndex)(nil).StorageFindSector), arg0, arg1, arg2, arg3, arg4)
}
// StorageGetLocks mocks base method.
func (m *MockSectorIndex) StorageGetLocks(arg0 context.Context) (storiface.SectorLocks, error) {
m.ctrl.T.Helper()
ret := m.ctrl.Call(m, "StorageGetLocks", arg0)
ret0, _ := ret[0].(storiface.SectorLocks)
ret1, _ := ret[1].(error)
return ret0, ret1
}
// StorageGetLocks indicates an expected call of StorageGetLocks.
func (mr *MockSectorIndexMockRecorder) StorageGetLocks(arg0 interface{}) *gomock.Call {
mr.mock.ctrl.T.Helper()
return mr.mock.ctrl.RecordCallWithMethodType(mr.mock, "StorageGetLocks", reflect.TypeOf((*MockSectorIndex)(nil).StorageGetLocks), arg0)
}
// StorageInfo mocks base method.
func (m *MockSectorIndex) StorageInfo(arg0 context.Context, arg1 stores.ID) (stores.StorageInfo, error) {
m.ctrl.T.Helper()

View File

@ -1,5 +1,7 @@
package storiface
import "github.com/filecoin-project/go-state-types/abi"
type PathType string
const (
@ -13,3 +15,17 @@ const (
AcquireMove AcquireMode = "move"
AcquireCopy AcquireMode = "copy"
)
type Refs struct {
RefCount [FileTypes]uint
}
type SectorLock struct {
Sector abi.SectorID
Write [FileTypes]uint
Read [FileTypes]uint
}
type SectorLocks struct {
Locks []SectorLock
}