forked from TrueCloudLab/frostfs-node
[#446] los: Wrap SSD errors in a separate type
Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
parent
20b84f183a
commit
fe01781811
27 changed files with 202 additions and 76 deletions
33
pkg/local_object_storage/internal/metaerr/error.go
Normal file
33
pkg/local_object_storage/internal/metaerr/error.go
Normal file
|
@ -0,0 +1,33 @@
|
|||
package metaerr
|
||||
|
||||
import "errors"
|
||||
|
||||
// Error is a wrapper for SSD-related errors.
|
||||
// In our model it unites metabase, pilorama and write-cache errors.
|
||||
type Error struct {
|
||||
err error
|
||||
}
|
||||
|
||||
// New returns simple error with a provided error message.
|
||||
func New(msg string) Error {
|
||||
return Error{err: errors.New(msg)}
|
||||
}
|
||||
|
||||
// Error implements the error interface.
|
||||
func (e Error) Error() string {
|
||||
return e.err.Error()
|
||||
}
|
||||
|
||||
// Wrap wraps arbitrary error.
|
||||
// Returns nil if err == nil.
|
||||
func Wrap(err error) error {
|
||||
if err != nil {
|
||||
return Error{err: err}
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
||||
// Unwrap returns underlying error.
|
||||
func (e Error) Unwrap() error {
|
||||
return e.err
|
||||
}
|
67
pkg/local_object_storage/internal/metaerr/error_test.go
Normal file
67
pkg/local_object_storage/internal/metaerr/error_test.go
Normal file
|
@ -0,0 +1,67 @@
|
|||
package metaerr
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"fmt"
|
||||
"strconv"
|
||||
"testing"
|
||||
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestError(t *testing.T) {
|
||||
t.Run("errors.Is", func(t *testing.T) {
|
||||
e1 := errors.New("some error")
|
||||
ee := Wrap(e1)
|
||||
require.ErrorIs(t, ee, e1)
|
||||
|
||||
e2 := fmt.Errorf("wrap: %w", e1)
|
||||
ee = Wrap(e2)
|
||||
require.ErrorIs(t, ee, e1)
|
||||
require.ErrorIs(t, ee, e2)
|
||||
|
||||
require.Equal(t, errors.Unwrap(ee), e2)
|
||||
})
|
||||
|
||||
t.Run("errors.As", func(t *testing.T) {
|
||||
e1 := testError{42}
|
||||
ee := Wrap(e1)
|
||||
|
||||
{
|
||||
var actual testError
|
||||
require.ErrorAs(t, ee, &actual)
|
||||
require.Equal(t, e1.data, actual.data)
|
||||
}
|
||||
{
|
||||
var actual Error
|
||||
require.ErrorAs(t, ee, &actual)
|
||||
require.Equal(t, e1, actual.err)
|
||||
}
|
||||
|
||||
e2 := fmt.Errorf("wrap: %w", e1)
|
||||
ee = Wrap(e2)
|
||||
|
||||
{
|
||||
var actual testError
|
||||
require.ErrorAs(t, ee, &actual)
|
||||
require.Equal(t, e1.data, actual.data)
|
||||
}
|
||||
})
|
||||
}
|
||||
func TestNilWrap(t *testing.T) {
|
||||
require.NoError(t, Wrap(nil))
|
||||
}
|
||||
|
||||
func TestErrorMessage(t *testing.T) {
|
||||
msg := "sth to report"
|
||||
err := New(msg)
|
||||
require.Contains(t, err.Error(), msg)
|
||||
}
|
||||
|
||||
type testError struct {
|
||||
data uint64
|
||||
}
|
||||
|
||||
func (e testError) Error() string {
|
||||
return strconv.FormatUint(e.data, 10)
|
||||
}
|
|
@ -1,6 +1,7 @@
|
|||
package meta
|
||||
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
@ -50,7 +51,7 @@ func (db *DB) GetChildren(addresses []oid.Address) (map[oid.Address][]oid.Addres
|
|||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
return result, nil
|
||||
|
|
|
@ -3,6 +3,7 @@ package meta
|
|||
import (
|
||||
"encoding/binary"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
@ -21,7 +22,7 @@ func (db *DB) Containers() (list []cid.ID, err error) {
|
|||
return err
|
||||
})
|
||||
|
||||
return list, err
|
||||
return list, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
func (db *DB) containers(tx *bbolt.Tx) ([]cid.ID, error) {
|
||||
|
@ -55,7 +56,7 @@ func (db *DB) ContainerSize(id cid.ID) (size uint64, err error) {
|
|||
return err
|
||||
})
|
||||
|
||||
return size, err
|
||||
return size, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
func (db *DB) containerSize(tx *bbolt.Tx, id cid.ID) (uint64, error) {
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"path/filepath"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
|
||||
|
@ -34,7 +35,7 @@ func (db *DB) Open(readOnly bool) error {
|
|||
}
|
||||
db.boltOptions.ReadOnly = readOnly
|
||||
|
||||
return db.openBolt()
|
||||
return metaerr.Wrap(db.openBolt())
|
||||
}
|
||||
|
||||
func (db *DB) openBolt() error {
|
||||
|
@ -79,7 +80,7 @@ func (db *DB) openBolt() error {
|
|||
// Does nothing if metabase has already been initialized and filled. To roll back the database to its initial state,
|
||||
// use Reset.
|
||||
func (db *DB) Init() error {
|
||||
return db.init(false)
|
||||
return metaerr.Wrap(db.init(false))
|
||||
}
|
||||
|
||||
// Reset resets metabase. Works similar to Init but cleans up all static buckets and
|
||||
|
@ -92,7 +93,7 @@ func (db *DB) Reset() error {
|
|||
return ErrDegradedMode
|
||||
}
|
||||
|
||||
return db.init(true)
|
||||
return metaerr.Wrap(db.init(true))
|
||||
}
|
||||
|
||||
func (db *DB) init(reset bool) error {
|
||||
|
@ -167,15 +168,15 @@ func (db *DB) SyncCounters() error {
|
|||
return ErrReadOnlyMode
|
||||
}
|
||||
|
||||
return db.boltDB.Update(func(tx *bbolt.Tx) error {
|
||||
return metaerr.Wrap(db.boltDB.Update(func(tx *bbolt.Tx) error {
|
||||
return syncCounter(tx, true)
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
// Close closes boltDB instance.
|
||||
func (db *DB) Close() error {
|
||||
if db.boltDB != nil {
|
||||
return db.boltDB.Close()
|
||||
return metaerr.Wrap(db.boltDB.Close())
|
||||
}
|
||||
return nil
|
||||
}
|
||||
|
@ -203,7 +204,7 @@ func (db *DB) Reload(opts ...Option) (bool, error) {
|
|||
db.mode = mode.Degraded
|
||||
db.info.Path = c.info.Path
|
||||
if err := db.openBolt(); err != nil {
|
||||
return false, fmt.Errorf("%w: %v", ErrDegradedMode, err)
|
||||
return false, metaerr.Wrap(fmt.Errorf("%w: %v", ErrDegradedMode, err))
|
||||
}
|
||||
|
||||
db.mode = mode.ReadWrite
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"encoding/binary"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"go.etcd.io/bbolt"
|
||||
|
@ -67,7 +68,7 @@ func (db *DB) ObjectCounters() (cc ObjectCounters, err error) {
|
|||
return nil
|
||||
})
|
||||
|
||||
return
|
||||
return cc, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// updateCounter updates the object counter. Tx MUST be writable.
|
||||
|
|
|
@ -8,6 +8,7 @@ import (
|
|||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
||||
storagelog "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/log"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
|
@ -108,7 +109,7 @@ func (db *DB) Delete(ctx context.Context, prm DeletePrm) (DeleteRes, error) {
|
|||
availableRemoved: availableRemoved,
|
||||
sizes: sizes,
|
||||
availableSizes: availableSizes,
|
||||
}, err
|
||||
}, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// deleteGroup deletes object from the metabase. Handles removal of the
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"fmt"
|
||||
|
||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
|
@ -65,7 +66,7 @@ func (db *DB) Exists(ctx context.Context, prm ExistsPrm) (res ExistsRes, err err
|
|||
return err
|
||||
})
|
||||
|
||||
return
|
||||
return res, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
func (db *DB) exists(tx *bbolt.Tx, addr oid.Address, currEpoch uint64) (exists bool, err error) {
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
"strconv"
|
||||
|
||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"go.etcd.io/bbolt"
|
||||
|
@ -65,7 +66,7 @@ func (db *DB) FilterExpired(ctx context.Context, epoch uint64, addresses []oid.A
|
|||
})
|
||||
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, metaerr.Wrap(err)
|
||||
}
|
||||
return result, nil
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
|
@ -74,7 +75,7 @@ func (db *DB) Get(ctx context.Context, prm GetPrm) (res GetRes, err error) {
|
|||
return err
|
||||
})
|
||||
|
||||
return
|
||||
return res, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
func (db *DB) get(tx *bbolt.Tx, addr oid.Address, key []byte, checkStatus, raw bool, currEpoch uint64) (*objectSDK.Object, error) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
@ -65,9 +66,9 @@ func (db *DB) IterateOverGarbage(p GarbageIterationPrm) error {
|
|||
return ErrDegradedMode
|
||||
}
|
||||
|
||||
return db.boltDB.View(func(tx *bbolt.Tx) error {
|
||||
return metaerr.Wrap(db.boltDB.View(func(tx *bbolt.Tx) error {
|
||||
return db.iterateDeletedObj(tx, gcHandler{p.h}, p.offset)
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
// TombstonedObject represents descriptor of the
|
||||
|
@ -132,9 +133,9 @@ func (db *DB) IterateOverGraveyard(p GraveyardIterationPrm) error {
|
|||
return ErrDegradedMode
|
||||
}
|
||||
|
||||
return db.boltDB.View(func(tx *bbolt.Tx) error {
|
||||
return metaerr.Wrap(db.boltDB.View(func(tx *bbolt.Tx) error {
|
||||
return db.iterateDeletedObj(tx, graveyardHandler{p.h}, p.offset)
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
type kvHandler interface {
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
|
@ -138,7 +139,7 @@ func (db *DB) Inhume(ctx context.Context, prm InhumePrm) (res InhumeRes, err err
|
|||
return db.inhumeTx(tx, currEpoch, prm, &res)
|
||||
})
|
||||
|
||||
return
|
||||
return res, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
func (db *DB) inhumeTx(tx *bbolt.Tx, epoch uint64, prm InhumePrm, res *InhumeRes) error {
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
"strconv"
|
||||
|
||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
|
@ -51,9 +52,9 @@ func (db *DB) IterateExpired(epoch uint64, h ExpiredObjectHandler) error {
|
|||
return ErrDegradedMode
|
||||
}
|
||||
|
||||
return db.boltDB.View(func(tx *bbolt.Tx) error {
|
||||
return metaerr.Wrap(db.boltDB.View(func(tx *bbolt.Tx) error {
|
||||
return db.iterateExpired(tx, epoch, h)
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
func (db *DB) iterateExpired(tx *bbolt.Tx, epoch uint64, h ExpiredObjectHandler) error {
|
||||
|
|
|
@ -2,6 +2,7 @@ package meta
|
|||
|
||||
import (
|
||||
objectcore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
|
@ -75,7 +76,7 @@ func (db *DB) ListWithCursor(prm ListPrm) (res ListRes, err error) {
|
|||
return err
|
||||
})
|
||||
|
||||
return res, err
|
||||
return res, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
func (db *DB) listWithCursor(tx *bbolt.Tx, result []objectcore.AddressWithType, count int, cursor *Cursor) ([]objectcore.AddressWithType, *Cursor, error) {
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
|
@ -63,7 +64,7 @@ func (db *DB) Lock(ctx context.Context, cnr cid.ID, locker oid.ID, locked []oid.
|
|||
}
|
||||
key := make([]byte, cidSize)
|
||||
|
||||
return db.boltDB.Update(func(tx *bbolt.Tx) error {
|
||||
return metaerr.Wrap(db.boltDB.Update(func(tx *bbolt.Tx) error {
|
||||
if firstIrregularObjectType(tx, cnr, bucketKeysLocked...) != object.TypeRegular {
|
||||
return logicerr.Wrap(apistatus.LockNonRegularObject{})
|
||||
}
|
||||
|
@ -109,7 +110,7 @@ func (db *DB) Lock(ctx context.Context, cnr cid.ID, locker oid.ID, locked []oid.
|
|||
}
|
||||
|
||||
return nil
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
// FreeLockedBy unlocks all objects in DB which are locked by lockers.
|
||||
|
@ -135,7 +136,7 @@ func (db *DB) FreeLockedBy(lockers []oid.Address) ([]oid.Address, error) {
|
|||
|
||||
return nil
|
||||
}); err != nil {
|
||||
return nil, err
|
||||
return nil, metaerr.Wrap(err)
|
||||
}
|
||||
return unlockedObjects, nil
|
||||
}
|
||||
|
@ -292,8 +293,8 @@ func (db *DB) IsLocked(ctx context.Context, prm IsLockedPrm) (res IsLockedRes, e
|
|||
return res, ErrDegradedMode
|
||||
}
|
||||
|
||||
return res, db.boltDB.View(func(tx *bbolt.Tx) error {
|
||||
return res, metaerr.Wrap(db.boltDB.View(func(tx *bbolt.Tx) error {
|
||||
res.locked = objectLocked(tx, prm.addr.Container(), prm.addr.Object())
|
||||
return nil
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"go.etcd.io/bbolt"
|
||||
|
@ -76,7 +77,7 @@ func (db *DB) ToMoveIt(ctx context.Context, prm ToMoveItPrm) (res ToMoveItRes, e
|
|||
return toMoveIt.Put(key, zeroValue)
|
||||
})
|
||||
|
||||
return
|
||||
return res, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// DoNotMove removes `MoveIt` mark from the object.
|
||||
|
@ -98,7 +99,7 @@ func (db *DB) DoNotMove(prm DoNotMovePrm) (res DoNotMoveRes, err error) {
|
|||
return toMoveIt.Delete(key)
|
||||
})
|
||||
|
||||
return
|
||||
return res, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// Movable returns list of marked objects to move into other shard.
|
||||
|
@ -121,7 +122,7 @@ func (db *DB) Movable(_ MovablePrm) (MovableRes, error) {
|
|||
})
|
||||
})
|
||||
if err != nil {
|
||||
return MovableRes{}, err
|
||||
return MovableRes{}, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// we can parse strings to structures in-place, but probably it seems
|
||||
|
@ -132,8 +133,8 @@ func (db *DB) Movable(_ MovablePrm) (MovableRes, error) {
|
|||
for i := range strAddrs {
|
||||
err = decodeAddressFromKey(&addrs[i], []byte(strAddrs[i]))
|
||||
if err != nil {
|
||||
return MovableRes{}, fmt.Errorf("can't parse object address %v: %w",
|
||||
strAddrs[i], err)
|
||||
return MovableRes{}, metaerr.Wrap(fmt.Errorf("can't parse object address %v: %w",
|
||||
strAddrs[i], err))
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
objectCore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
||||
storagelog "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/log"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
|
@ -83,7 +84,7 @@ func (db *DB) Put(ctx context.Context, prm PutPrm) (res PutRes, err error) {
|
|||
storagelog.OpField("metabase PUT"))
|
||||
}
|
||||
|
||||
return
|
||||
return res, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
func (db *DB) put(tx *bbolt.Tx,
|
||||
|
|
|
@ -9,6 +9,7 @@ import (
|
|||
|
||||
v2object "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
|
@ -80,11 +81,11 @@ func (db *DB) Select(ctx context.Context, prm SelectPrm) (res SelectRes, err err
|
|||
|
||||
currEpoch := db.epochState.CurrentEpoch()
|
||||
|
||||
return res, db.boltDB.View(func(tx *bbolt.Tx) error {
|
||||
return res, metaerr.Wrap(db.boltDB.View(func(tx *bbolt.Tx) error {
|
||||
res.addrList, err = db.selectObjects(tx, prm.cnr, prm.filters, currEpoch)
|
||||
|
||||
return err
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
func (db *DB) selectObjects(tx *bbolt.Tx, cnr cid.ID, fs object.SearchFilters, currEpoch uint64) ([]oid.Address, error) {
|
||||
|
|
|
@ -1,6 +1,7 @@
|
|||
package meta
|
||||
|
||||
import (
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
@ -28,7 +29,7 @@ func (db *DB) ReadShardID() ([]byte, error) {
|
|||
}
|
||||
return nil
|
||||
})
|
||||
return id, err
|
||||
return id, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// WriteShardID writes shard it to db.
|
||||
|
@ -42,11 +43,11 @@ func (db *DB) WriteShardID(id []byte) error {
|
|||
return ErrReadOnlyMode
|
||||
}
|
||||
|
||||
return db.boltDB.Update(func(tx *bbolt.Tx) error {
|
||||
return metaerr.Wrap(db.boltDB.Update(func(tx *bbolt.Tx) error {
|
||||
b, err := tx.CreateBucketIfNotExists(shardInfoBucket)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
return b.Put(shardIDKey, id)
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"context"
|
||||
"errors"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||
|
@ -54,7 +55,7 @@ func (db *DB) StorageID(ctx context.Context, prm StorageIDPrm) (res StorageIDRes
|
|||
return err
|
||||
})
|
||||
|
||||
return
|
||||
return res, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
func (db *DB) storageID(tx *bbolt.Tx, addr oid.Address) ([]byte, error) {
|
||||
|
@ -113,5 +114,5 @@ func (db *DB) UpdateStorageID(prm UpdateStorageIDPrm) (res UpdateStorageIDRes, e
|
|||
return err
|
||||
})
|
||||
|
||||
return
|
||||
return res, metaerr.Wrap(err)
|
||||
}
|
||||
|
|
|
@ -12,6 +12,7 @@ import (
|
|||
"sync"
|
||||
"time"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
|
||||
|
@ -105,7 +106,7 @@ func (t *boltForest) SetMode(m mode.Mode) error {
|
|||
func (t *boltForest) Open(readOnly bool) error {
|
||||
err := util.MkdirAllX(filepath.Dir(t.path), t.perm)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't create dir %s for the pilorama: %w", t.path, err)
|
||||
return metaerr.Wrap(fmt.Errorf("can't create dir %s for the pilorama: %w", t.path, err))
|
||||
}
|
||||
|
||||
opts := *bbolt.DefaultOptions
|
||||
|
@ -116,7 +117,7 @@ func (t *boltForest) Open(readOnly bool) error {
|
|||
|
||||
t.db, err = bbolt.Open(t.path, t.perm, &opts)
|
||||
if err != nil {
|
||||
return fmt.Errorf("can't open the pilorama DB: %w", err)
|
||||
return metaerr.Wrap(fmt.Errorf("can't open the pilorama DB: %w", err))
|
||||
}
|
||||
|
||||
t.db.MaxBatchSize = t.maxBatchSize
|
||||
|
@ -174,7 +175,7 @@ func (t *boltForest) TreeMove(ctx context.Context, d CIDDescriptor, treeID strin
|
|||
|
||||
lm := *m
|
||||
fullID := bucketName(d.CID, treeID)
|
||||
return &lm, t.db.Batch(func(tx *bbolt.Tx) error {
|
||||
return &lm, metaerr.Wrap(t.db.Batch(func(tx *bbolt.Tx) error {
|
||||
bLog, bTree, err := t.getTreeBuckets(tx, fullID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -185,7 +186,7 @@ func (t *boltForest) TreeMove(ctx context.Context, d CIDDescriptor, treeID strin
|
|||
lm.Child = t.findSpareID(bTree)
|
||||
}
|
||||
return t.do(bLog, bTree, make([]byte, 17), &lm)
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
func (t *boltForest) TreeHeight(ctx context.Context, cid cidSDK.ID, treeID string) (uint64, error) {
|
||||
|
@ -219,7 +220,7 @@ func (t *boltForest) TreeHeight(ctx context.Context, cid cidSDK.ID, treeID strin
|
|||
if err == nil {
|
||||
err = retErr
|
||||
}
|
||||
return height, err
|
||||
return height, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// TreeExists implements the Forest interface.
|
||||
|
@ -247,7 +248,7 @@ func (t *boltForest) TreeExists(ctx context.Context, cid cidSDK.ID, treeID strin
|
|||
return nil
|
||||
})
|
||||
|
||||
return exists, err
|
||||
return exists, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
var syncHeightKey = []byte{'h'}
|
||||
|
@ -267,7 +268,7 @@ func (t *boltForest) TreeUpdateLastSyncHeight(ctx context.Context, cid cidSDK.ID
|
|||
binary.LittleEndian.PutUint64(rawHeight, height)
|
||||
|
||||
buck := bucketName(cid, treeID)
|
||||
return t.db.Batch(func(tx *bbolt.Tx) error {
|
||||
return metaerr.Wrap(t.db.Batch(func(tx *bbolt.Tx) error {
|
||||
treeRoot := tx.Bucket(buck)
|
||||
if treeRoot == nil {
|
||||
return ErrTreeNotFound
|
||||
|
@ -275,7 +276,7 @@ func (t *boltForest) TreeUpdateLastSyncHeight(ctx context.Context, cid cidSDK.ID
|
|||
|
||||
b := treeRoot.Bucket(dataBucket)
|
||||
return b.Put(syncHeightKey, rawHeight)
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
// TreeLastSyncHeight implements the pilorama.Forest interface.
|
||||
|
@ -304,7 +305,7 @@ func (t *boltForest) TreeLastSyncHeight(ctx context.Context, cid cidSDK.ID, tree
|
|||
}
|
||||
return nil
|
||||
})
|
||||
return height, err
|
||||
return height, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// TreeAddByPath implements the Forest interface.
|
||||
|
@ -384,7 +385,7 @@ func (t *boltForest) TreeAddByPath(ctx context.Context, d CIDDescriptor, treeID
|
|||
}
|
||||
return t.do(bLog, bTree, key[:], &lm[len(lm)-1])
|
||||
})
|
||||
return lm, err
|
||||
return lm, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// getLatestTimestamp returns timestamp for a new operation which is guaranteed to be bigger than
|
||||
|
@ -450,13 +451,13 @@ func (t *boltForest) TreeApply(ctx context.Context, cnr cidSDK.ID, treeID string
|
|||
return nil
|
||||
})
|
||||
if err != nil || seen {
|
||||
return err
|
||||
return metaerr.Wrap(err)
|
||||
}
|
||||
}
|
||||
|
||||
if t.db.MaxBatchSize == 1 {
|
||||
fullID := bucketName(cnr, treeID)
|
||||
return t.db.Update(func(tx *bbolt.Tx) error {
|
||||
return metaerr.Wrap(t.db.Update(func(tx *bbolt.Tx) error {
|
||||
bLog, bTree, err := t.getTreeBuckets(tx, fullID)
|
||||
if err != nil {
|
||||
return err
|
||||
|
@ -464,12 +465,12 @@ func (t *boltForest) TreeApply(ctx context.Context, cnr cidSDK.ID, treeID string
|
|||
|
||||
var lm Move
|
||||
return t.applyOperation(bLog, bTree, []*Move{m}, &lm)
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
ch := make(chan error, 1)
|
||||
t.addBatch(cnr, treeID, m, ch)
|
||||
return <-ch
|
||||
return metaerr.Wrap(<-ch)
|
||||
}
|
||||
|
||||
func (t *boltForest) addBatch(cnr cidSDK.ID, treeID string, m *Move, ch chan error) {
|
||||
|
@ -751,7 +752,7 @@ func (t *boltForest) TreeGetByPath(ctx context.Context, cid cidSDK.ID, treeID st
|
|||
|
||||
var nodes []Node
|
||||
|
||||
return nodes, t.db.View(func(tx *bbolt.Tx) error {
|
||||
return nodes, metaerr.Wrap(t.db.View(func(tx *bbolt.Tx) error {
|
||||
treeRoot := tx.Bucket(bucketName(cid, treeID))
|
||||
if treeRoot == nil {
|
||||
return ErrTreeNotFound
|
||||
|
@ -788,7 +789,7 @@ func (t *boltForest) TreeGetByPath(ctx context.Context, cid cidSDK.ID, treeID st
|
|||
childKey, _ = c.Next()
|
||||
}
|
||||
return nil
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
// TreeGetMeta implements the forest interface.
|
||||
|
@ -828,7 +829,7 @@ func (t *boltForest) TreeGetMeta(ctx context.Context, cid cidSDK.ID, treeID stri
|
|||
return m.FromBytes(meta)
|
||||
})
|
||||
|
||||
return m, parentID, err
|
||||
return m, parentID, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// TreeGetChildren implements the Forest interface.
|
||||
|
@ -869,7 +870,7 @@ func (t *boltForest) TreeGetChildren(ctx context.Context, cid cidSDK.ID, treeID
|
|||
return nil
|
||||
})
|
||||
|
||||
return children, err
|
||||
return children, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// TreeList implements the Forest interface.
|
||||
|
@ -907,7 +908,7 @@ func (t *boltForest) TreeList(ctx context.Context, cid cidSDK.ID) ([]string, err
|
|||
return nil
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("could not list trees: %w", err)
|
||||
return nil, metaerr.Wrap(fmt.Errorf("could not list trees: %w", err))
|
||||
}
|
||||
|
||||
return ids, nil
|
||||
|
@ -949,7 +950,7 @@ func (t *boltForest) TreeGetOpLog(ctx context.Context, cid cidSDK.ID, treeID str
|
|||
return nil
|
||||
})
|
||||
|
||||
return lm, err
|
||||
return lm, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// TreeDrop implements the pilorama.Forest interface.
|
||||
|
@ -971,7 +972,7 @@ func (t *boltForest) TreeDrop(ctx context.Context, cid cidSDK.ID, treeID string)
|
|||
return ErrReadOnlyMode
|
||||
}
|
||||
|
||||
return t.db.Batch(func(tx *bbolt.Tx) error {
|
||||
return metaerr.Wrap(t.db.Batch(func(tx *bbolt.Tx) error {
|
||||
if treeID == "" {
|
||||
c := tx.Cursor()
|
||||
prefix := make([]byte, 32)
|
||||
|
@ -989,7 +990,7 @@ func (t *boltForest) TreeDrop(ctx context.Context, cid cidSDK.ID, treeID string)
|
|||
return ErrTreeNotFound
|
||||
}
|
||||
return err
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
||||
func (t *boltForest) getPathPrefix(bTree *bbolt.Bucket, attr string, path []string) (int, Node, error) {
|
||||
|
|
|
@ -6,6 +6,7 @@ import (
|
|||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||
storagelog "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/log"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"go.etcd.io/bbolt"
|
||||
|
@ -77,5 +78,5 @@ func (c *cache) Delete(ctx context.Context, addr oid.Address) error {
|
|||
deleted = true
|
||||
}
|
||||
|
||||
return err
|
||||
return metaerr.Wrap(err)
|
||||
}
|
||||
|
|
|
@ -10,6 +10,7 @@ import (
|
|||
objectCore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
meta "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metabase"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
|
@ -193,7 +194,7 @@ func (c *cache) flushFSTree(ctx context.Context, ignoreErrors bool) error {
|
|||
|
||||
data, err := f()
|
||||
if err != nil {
|
||||
c.reportFlushError("can't read a file", sAddr, err)
|
||||
c.reportFlushError("can't read a file", sAddr, metaerr.Wrap(err))
|
||||
if ignoreErrors {
|
||||
return nil
|
||||
}
|
||||
|
@ -203,7 +204,7 @@ func (c *cache) flushFSTree(ctx context.Context, ignoreErrors bool) error {
|
|||
var obj object.Object
|
||||
err = obj.Unmarshal(data)
|
||||
if err != nil {
|
||||
c.reportFlushError("can't unmarshal an object", sAddr, err)
|
||||
c.reportFlushError("can't unmarshal an object", sAddr, metaerr.Wrap(err))
|
||||
if ignoreErrors {
|
||||
return nil
|
||||
}
|
||||
|
@ -314,7 +315,7 @@ func (c *cache) flush(ctx context.Context, ignoreErrors bool) error {
|
|||
for k, data := cs.Seek(nil); k != nil; k, data = cs.Next() {
|
||||
sa := string(k)
|
||||
if err := addr.DecodeString(sa); err != nil {
|
||||
c.reportFlushError("can't decode object address from the DB", sa, err)
|
||||
c.reportFlushError("can't decode object address from the DB", sa, metaerr.Wrap(err))
|
||||
if ignoreErrors {
|
||||
continue
|
||||
}
|
||||
|
@ -323,7 +324,7 @@ func (c *cache) flush(ctx context.Context, ignoreErrors bool) error {
|
|||
|
||||
var obj object.Object
|
||||
if err := obj.Unmarshal(data); err != nil {
|
||||
c.reportFlushError("can't unmarshal an object from the DB", sa, err)
|
||||
c.reportFlushError("can't unmarshal an object from the DB", sa, metaerr.Wrap(err))
|
||||
if ignoreErrors {
|
||||
continue
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
"time"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||
|
@ -28,7 +29,8 @@ func (c *cache) Get(ctx context.Context, addr oid.Address) (*objectSDK.Object, e
|
|||
))
|
||||
defer span.End()
|
||||
|
||||
return c.getInternal(ctx, saddr, addr)
|
||||
obj, err := c.getInternal(ctx, saddr, addr)
|
||||
return obj, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
func (c *cache) getInternal(ctx context.Context, saddr string, addr oid.Address) (*objectSDK.Object, error) {
|
||||
|
@ -71,7 +73,7 @@ func (c *cache) Head(ctx context.Context, addr oid.Address) (*objectSDK.Object,
|
|||
|
||||
obj, err := c.getInternal(ctx, saddr, addr)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
return nil, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
return obj.CutPayload(), nil
|
||||
|
@ -95,5 +97,5 @@ func Get(db *bbolt.DB, key []byte) ([]byte, error) {
|
|||
value = slice.Copy(value)
|
||||
return nil
|
||||
})
|
||||
return value, err
|
||||
return value, metaerr.Wrap(err)
|
||||
}
|
||||
|
|
|
@ -4,6 +4,7 @@ import (
|
|||
"errors"
|
||||
"fmt"
|
||||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||
"go.etcd.io/bbolt"
|
||||
)
|
||||
|
@ -18,7 +19,7 @@ var ErrNoDefaultBucket = errors.New("no default bucket")
|
|||
//
|
||||
// DB must not be nil and should be opened.
|
||||
func IterateDB(db *bbolt.DB, f func(oid.Address) error) error {
|
||||
return db.View(func(tx *bbolt.Tx) error {
|
||||
return metaerr.Wrap(db.View(func(tx *bbolt.Tx) error {
|
||||
b := tx.Bucket(defaultBucket)
|
||||
if b == nil {
|
||||
return ErrNoDefaultBucket
|
||||
|
@ -34,5 +35,5 @@ func IterateDB(db *bbolt.DB, f func(oid.Address) error) error {
|
|||
|
||||
return f(addr)
|
||||
})
|
||||
})
|
||||
}))
|
||||
}
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||
storagelog "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/log"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||
"go.etcd.io/bbolt"
|
||||
"go.opentelemetry.io/otel/attribute"
|
||||
|
@ -72,7 +73,7 @@ func (c *cache) Put(ctx context.Context, prm common.PutPrm) (common.PutRes, erro
|
|||
if err == nil {
|
||||
added = true
|
||||
}
|
||||
return common.PutRes{}, err
|
||||
return common.PutRes{}, metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// putSmall persists small objects to the write-cache database and
|
||||
|
|
|
@ -7,6 +7,7 @@ import (
|
|||
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/shard/mode"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||
|
@ -129,14 +130,14 @@ func (c *cache) DumpInfo() Info {
|
|||
func (c *cache) Open(readOnly bool) error {
|
||||
err := c.openStore(readOnly)
|
||||
if err != nil {
|
||||
return err
|
||||
return metaerr.Wrap(err)
|
||||
}
|
||||
|
||||
// Opening after Close is done during maintenance mode,
|
||||
// thus we need to create a channel here.
|
||||
c.closeCh = make(chan struct{})
|
||||
|
||||
return c.initCounters()
|
||||
return metaerr.Wrap(c.initCounters())
|
||||
}
|
||||
|
||||
// Init runs necessary services.
|
||||
|
|
Loading…
Reference in a new issue