[#446] los: Wrap SSD errors in a separate type

Signed-off-by: Evgenii Stratonikov <e.stratonikov@yadro.com>
This commit is contained in:
Evgenii Stratonikov 2023-06-15 13:19:36 +03:00
parent 20b84f183a
commit fe01781811
27 changed files with 202 additions and 76 deletions

View 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
}

View 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)
}

View file

@ -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

View file

@ -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) {

View file

@ -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

View file

@ -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.

View file

@ -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

View file

@ -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) {

View file

@ -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
}

View file

@ -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) {

View file

@ -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 {

View file

@ -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 {

View file

@ -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 {

View file

@ -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) {

View file

@ -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
})
}))
}

View file

@ -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))
}
}

View file

@ -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,

View file

@ -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) {

View file

@ -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)
})
}))
}

View file

@ -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)
}

View file

@ -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) {

View file

@ -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)
}

View file

@ -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
}

View file

@ -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)
}

View file

@ -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)
})
})
}))
}

View file

@ -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

View file

@ -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.