Move statfs to fsutil
This commit is contained in:
parent
77cf6e49a0
commit
0bc41d562d
@ -521,8 +521,7 @@ func (sb *Sealer) FinalizeSector(ctx context.Context, sector abi.SectorID, keepU
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
paths, done, err := sb.sectors.AcquireSector(ctx, sector, stores.FTUnsealed, 0, stores.PathStorage)
|
||||||
paths, done, err := sb.sectors.AcquireSector(ctx, sector, stores.FTUnsealed, 0, false)
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return xerrors.Errorf("acquiring sector cache path: %w", err)
|
return xerrors.Errorf("acquiring sector cache path: %w", err)
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ import (
|
|||||||
|
|
||||||
var log = logging.Logger("fsutil")
|
var log = logging.Logger("fsutil")
|
||||||
|
|
||||||
|
|
||||||
func Deallocate(file *os.File, offset int64, length int64) error {
|
func Deallocate(file *os.File, offset int64, length int64) error {
|
||||||
log.Warnf("deallocating space not supported")
|
log.Warnf("deallocating space not supported")
|
||||||
|
|
||||||
|
7
fsutil/statfs.go
Normal file
7
fsutil/statfs.go
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
package fsutil
|
||||||
|
|
||||||
|
type FsStat struct {
|
||||||
|
Capacity int64
|
||||||
|
Available int64 // Available to use for sector storage
|
||||||
|
Reserved int64
|
||||||
|
}
|
19
fsutil/statfs_unix.go
Normal file
19
fsutil/statfs_unix.go
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
package fsutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
|
||||||
|
"golang.org/x/xerrors"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Statfs(path string) (FsStat, error) {
|
||||||
|
var stat syscall.Statfs_t
|
||||||
|
if err := syscall.Statfs(path, &stat); err != nil {
|
||||||
|
return FsStat{}, xerrors.Errorf("statfs: %w", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
return FsStat{
|
||||||
|
Capacity: int64(stat.Blocks) * stat.Bsize,
|
||||||
|
Available: int64(stat.Bavail) * stat.Bsize,
|
||||||
|
}, nil
|
||||||
|
}
|
28
fsutil/statfs_windows.go
Normal file
28
fsutil/statfs_windows.go
Normal file
@ -0,0 +1,28 @@
|
|||||||
|
package fsutil
|
||||||
|
|
||||||
|
import (
|
||||||
|
"syscall"
|
||||||
|
"unsafe"
|
||||||
|
)
|
||||||
|
|
||||||
|
func Statfs(volumePath string) (FsStat, error) {
|
||||||
|
// From https://github.com/ricochet2200/go-disk-usage/blob/master/du/diskusage_windows.go
|
||||||
|
|
||||||
|
h := syscall.MustLoadDLL("kernel32.dll")
|
||||||
|
c := h.MustFindProc("GetDiskFreeSpaceExW")
|
||||||
|
|
||||||
|
var freeBytes int64
|
||||||
|
var totalBytes int64
|
||||||
|
var availBytes int64
|
||||||
|
|
||||||
|
c.Call(
|
||||||
|
uintptr(unsafe.Pointer(syscall.StringToUTF16Ptr(volumePath))),
|
||||||
|
uintptr(unsafe.Pointer(&freeBytes)),
|
||||||
|
uintptr(unsafe.Pointer(&totalBytes)),
|
||||||
|
uintptr(unsafe.Pointer(&availBytes)))
|
||||||
|
|
||||||
|
return FsStat{
|
||||||
|
Capacity: totalBytes,
|
||||||
|
Available: availBytes,
|
||||||
|
}, nil
|
||||||
|
}
|
@ -3,6 +3,7 @@ package sectorstorage
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
"github.com/filecoin-project/sector-storage/fsutil"
|
||||||
"io"
|
"io"
|
||||||
"net/http"
|
"net/http"
|
||||||
|
|
||||||
@ -491,7 +492,7 @@ func (m *Manager) StorageLocal(ctx context.Context) (map[stores.ID]string, error
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (m *Manager) FsStat(ctx context.Context, id stores.ID) (stores.FsStat, error) {
|
func (m *Manager) FsStat(ctx context.Context, id stores.ID) (fsutil.FsStat, error) {
|
||||||
return m.storage.FsStat(ctx, id)
|
return m.storage.FsStat(ctx, id)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -5,6 +5,7 @@ import (
|
|||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
"github.com/filecoin-project/sector-storage/fsutil"
|
||||||
"github.com/filecoin-project/sector-storage/sealtasks"
|
"github.com/filecoin-project/sector-storage/sealtasks"
|
||||||
logging "github.com/ipfs/go-log"
|
logging "github.com/ipfs/go-log"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
@ -69,8 +70,8 @@ func (t *testStorage) SetStorage(f func(*stores.StorageConfig)) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *testStorage) Stat(path string) (stores.FsStat, error) {
|
func (t *testStorage) Stat(path string) (fsutil.FsStat, error) {
|
||||||
return stores.Stat(path)
|
return fsutil.Statfs(path)
|
||||||
}
|
}
|
||||||
|
|
||||||
var _ stores.LocalStorage = &testStorage{}
|
var _ stores.LocalStorage = &testStorage{}
|
||||||
|
@ -2,6 +2,7 @@ package stores
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
|
"github.com/filecoin-project/sector-storage/fsutil"
|
||||||
"net/url"
|
"net/url"
|
||||||
gopath "path"
|
gopath "path"
|
||||||
"sort"
|
"sort"
|
||||||
@ -34,7 +35,7 @@ type StorageInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type HealthReport struct {
|
type HealthReport struct {
|
||||||
Stat FsStat
|
Stat fsutil.FsStat
|
||||||
Err error
|
Err error
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -50,7 +51,7 @@ type SectorStorageInfo struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type SectorIndex interface { // part of storage-miner api
|
type SectorIndex interface { // part of storage-miner api
|
||||||
StorageAttach(context.Context, StorageInfo, FsStat) error
|
StorageAttach(context.Context, StorageInfo, fsutil.FsStat) error
|
||||||
StorageInfo(context.Context, ID) (StorageInfo, error)
|
StorageInfo(context.Context, ID) (StorageInfo, error)
|
||||||
StorageReportHealth(context.Context, ID, HealthReport) error
|
StorageReportHealth(context.Context, ID, HealthReport) error
|
||||||
|
|
||||||
@ -77,7 +78,7 @@ type declMeta struct {
|
|||||||
|
|
||||||
type storageEntry struct {
|
type storageEntry struct {
|
||||||
info *StorageInfo
|
info *StorageInfo
|
||||||
fsi FsStat
|
fsi fsutil.FsStat
|
||||||
|
|
||||||
lastHeartbeat time.Time
|
lastHeartbeat time.Time
|
||||||
heartbeatErr error
|
heartbeatErr error
|
||||||
@ -130,7 +131,7 @@ func (i *Index) StorageList(ctx context.Context) (map[ID][]Decl, error) {
|
|||||||
return out, nil
|
return out, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (i *Index) StorageAttach(ctx context.Context, si StorageInfo, st FsStat) error {
|
func (i *Index) StorageAttach(ctx context.Context, si StorageInfo, st fsutil.FsStat) error {
|
||||||
i.lk.Lock()
|
i.lk.Lock()
|
||||||
defer i.lk.Unlock()
|
defer i.lk.Unlock()
|
||||||
|
|
||||||
|
@ -2,10 +2,7 @@ package stores
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"syscall"
|
"github.com/filecoin-project/sector-storage/fsutil"
|
||||||
|
|
||||||
"golang.org/x/xerrors"
|
|
||||||
|
|
||||||
"github.com/filecoin-project/specs-actors/actors/abi"
|
"github.com/filecoin-project/specs-actors/actors/abi"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -34,24 +31,5 @@ type Store interface {
|
|||||||
// move sectors into storage
|
// move sectors into storage
|
||||||
MoveStorage(ctx context.Context, s abi.SectorID, spt abi.RegisteredSealProof, types SectorFileType) error
|
MoveStorage(ctx context.Context, s abi.SectorID, spt abi.RegisteredSealProof, types SectorFileType) error
|
||||||
|
|
||||||
FsStat(ctx context.Context, id ID) (FsStat, error)
|
FsStat(ctx context.Context, id ID) (fsutil.FsStat, error)
|
||||||
}
|
|
||||||
|
|
||||||
func Stat(path string) (FsStat, error) {
|
|
||||||
var stat syscall.Statfs_t
|
|
||||||
if err := syscall.Statfs(path, &stat); err != nil {
|
|
||||||
return FsStat{}, xerrors.Errorf("statfs: %w", err)
|
|
||||||
}
|
|
||||||
|
|
||||||
return FsStat{
|
|
||||||
Capacity: int64(stat.Blocks) * stat.Bsize,
|
|
||||||
Available: int64(stat.Bavail) * stat.Bsize,
|
|
||||||
}, nil
|
|
||||||
}
|
|
||||||
|
|
||||||
type FsStat struct {
|
|
||||||
Capacity int64
|
|
||||||
Available int64 // Available to use for sector storage
|
|
||||||
Used int64
|
|
||||||
Reserved int64
|
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@ package stores
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/filecoin-project/sector-storage/fsutil"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
@ -48,7 +49,7 @@ type LocalStorage interface {
|
|||||||
GetStorage() (StorageConfig, error)
|
GetStorage() (StorageConfig, error)
|
||||||
SetStorage(func(*StorageConfig)) error
|
SetStorage(func(*StorageConfig)) error
|
||||||
|
|
||||||
Stat(path string) (FsStat, error)
|
Stat(path string) (fsutil.FsStat, error)
|
||||||
DiskUsage(path string) (int64, error) // returns real disk usage for a file/directory
|
DiskUsage(path string) (int64, error) // returns real disk usage for a file/directory
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -73,10 +74,10 @@ type path struct {
|
|||||||
reservations map[abi.SectorID]SectorFileType
|
reservations map[abi.SectorID]SectorFileType
|
||||||
}
|
}
|
||||||
|
|
||||||
func (p *path) stat(ls LocalStorage) (FsStat, error) {
|
func (p *path) stat(ls LocalStorage) (fsutil.FsStat, error) {
|
||||||
stat, err := ls.Stat(p.local)
|
stat, err := ls.Stat(p.local)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return FsStat{}, err
|
return fsutil.FsStat{}, err
|
||||||
}
|
}
|
||||||
|
|
||||||
stat.Reserved = p.reserved
|
stat.Reserved = p.reserved
|
||||||
@ -557,13 +558,13 @@ func (st *Local) MoveStorage(ctx context.Context, s abi.SectorID, spt abi.Regist
|
|||||||
|
|
||||||
var errPathNotFound = xerrors.Errorf("fsstat: path not found")
|
var errPathNotFound = xerrors.Errorf("fsstat: path not found")
|
||||||
|
|
||||||
func (st *Local) FsStat(ctx context.Context, id ID) (FsStat, error) {
|
func (st *Local) FsStat(ctx context.Context, id ID) (fsutil.FsStat, error) {
|
||||||
st.localLk.RLock()
|
st.localLk.RLock()
|
||||||
defer st.localLk.RUnlock()
|
defer st.localLk.RUnlock()
|
||||||
|
|
||||||
p, ok := st.paths[id]
|
p, ok := st.paths[id]
|
||||||
if !ok {
|
if !ok {
|
||||||
return FsStat{}, errPathNotFound
|
return fsutil.FsStat{}, errPathNotFound
|
||||||
}
|
}
|
||||||
|
|
||||||
return p.stat(st.localStorage)
|
return p.stat(st.localStorage)
|
||||||
|
@ -3,6 +3,7 @@ package stores
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/filecoin-project/sector-storage/fsutil"
|
||||||
"github.com/google/uuid"
|
"github.com/google/uuid"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"os"
|
"os"
|
||||||
@ -32,11 +33,10 @@ func (t *TestingLocalStorage) SetStorage(f func(*StorageConfig)) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TestingLocalStorage) Stat(path string) (FsStat, error) {
|
func (t *TestingLocalStorage) Stat(path string) (fsutil.FsStat, error) {
|
||||||
return FsStat{
|
return fsutil.FsStat{
|
||||||
Capacity: pathSize,
|
Capacity: pathSize,
|
||||||
Available: pathSize,
|
Available: pathSize,
|
||||||
Used: 0,
|
|
||||||
}, nil
|
}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,6 +3,7 @@ package stores
|
|||||||
import (
|
import (
|
||||||
"context"
|
"context"
|
||||||
"encoding/json"
|
"encoding/json"
|
||||||
|
"github.com/filecoin-project/sector-storage/fsutil"
|
||||||
"io/ioutil"
|
"io/ioutil"
|
||||||
"math/bits"
|
"math/bits"
|
||||||
"mime"
|
"mime"
|
||||||
@ -270,7 +271,7 @@ func (r *Remote) deleteFromRemote(ctx context.Context, url string) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
func (r *Remote) FsStat(ctx context.Context, id ID) (FsStat, error) {
|
func (r *Remote) FsStat(ctx context.Context, id ID) (fsutil.FsStat, error) {
|
||||||
st, err := r.local.FsStat(ctx, id)
|
st, err := r.local.FsStat(ctx, id)
|
||||||
switch err {
|
switch err {
|
||||||
case nil:
|
case nil:
|
||||||
@ -278,53 +279,53 @@ func (r *Remote) FsStat(ctx context.Context, id ID) (FsStat, error) {
|
|||||||
case errPathNotFound:
|
case errPathNotFound:
|
||||||
break
|
break
|
||||||
default:
|
default:
|
||||||
return FsStat{}, xerrors.Errorf("local stat: %w", err)
|
return fsutil.FsStat{}, xerrors.Errorf("local stat: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
si, err := r.index.StorageInfo(ctx, id)
|
si, err := r.index.StorageInfo(ctx, id)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return FsStat{}, xerrors.Errorf("getting remote storage info: %w", err)
|
return fsutil.FsStat{}, xerrors.Errorf("getting remote storage info: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
if len(si.URLs) == 0 {
|
if len(si.URLs) == 0 {
|
||||||
return FsStat{}, xerrors.Errorf("no known URLs for remote storage %s", id)
|
return fsutil.FsStat{}, xerrors.Errorf("no known URLs for remote storage %s", id)
|
||||||
}
|
}
|
||||||
|
|
||||||
rl, err := url.Parse(si.URLs[0])
|
rl, err := url.Parse(si.URLs[0])
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return FsStat{}, xerrors.Errorf("failed to parse url: %w", err)
|
return fsutil.FsStat{}, xerrors.Errorf("failed to parse url: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
rl.Path = gopath.Join(rl.Path, "stat", string(id))
|
rl.Path = gopath.Join(rl.Path, "stat", string(id))
|
||||||
|
|
||||||
req, err := http.NewRequest("GET", rl.String(), nil)
|
req, err := http.NewRequest("GET", rl.String(), nil)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return FsStat{}, xerrors.Errorf("request: %w", err)
|
return fsutil.FsStat{}, xerrors.Errorf("request: %w", err)
|
||||||
}
|
}
|
||||||
req.Header = r.auth
|
req.Header = r.auth
|
||||||
req = req.WithContext(ctx)
|
req = req.WithContext(ctx)
|
||||||
|
|
||||||
resp, err := http.DefaultClient.Do(req)
|
resp, err := http.DefaultClient.Do(req)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return FsStat{}, xerrors.Errorf("do request: %w", err)
|
return fsutil.FsStat{}, xerrors.Errorf("do request: %w", err)
|
||||||
}
|
}
|
||||||
switch resp.StatusCode {
|
switch resp.StatusCode {
|
||||||
case 200:
|
case 200:
|
||||||
break
|
break
|
||||||
case 404:
|
case 404:
|
||||||
return FsStat{}, errPathNotFound
|
return fsutil.FsStat{}, errPathNotFound
|
||||||
case 500:
|
case 500:
|
||||||
b, err := ioutil.ReadAll(resp.Body)
|
b, err := ioutil.ReadAll(resp.Body)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return FsStat{}, xerrors.Errorf("fsstat: got http 500, then failed to read the error: %w", err)
|
return fsutil.FsStat{}, xerrors.Errorf("fsstat: got http 500, then failed to read the error: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return FsStat{}, xerrors.Errorf("fsstat: got http 500: %s", string(b))
|
return fsutil.FsStat{}, xerrors.Errorf("fsstat: got http 500: %s", string(b))
|
||||||
}
|
}
|
||||||
|
|
||||||
var out FsStat
|
var out fsutil.FsStat
|
||||||
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
|
if err := json.NewDecoder(resp.Body).Decode(&out); err != nil {
|
||||||
return FsStat{}, xerrors.Errorf("decoding fsstat: %w", err)
|
return fsutil.FsStat{}, xerrors.Errorf("decoding fsstat: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
defer resp.Body.Close()
|
defer resp.Body.Close()
|
||||||
|
Loading…
Reference in New Issue
Block a user