forked from TrueCloudLab/frostfs-node
WIP: Morph: Add unit tests #2
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
|
package meta
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
@ -50,7 +51,7 @@ func (db *DB) GetChildren(addresses []oid.Address) (map[oid.Address][]oid.Addres
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return result, nil
|
return result, nil
|
||||||
|
|
|
@ -3,6 +3,7 @@ package meta
|
||||||
import (
|
import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
@ -21,7 +22,7 @@ func (db *DB) Containers() (list []cid.ID, err error) {
|
||||||
return err
|
return err
|
||||||
})
|
})
|
||||||
|
|
||||||
return list, err
|
return list, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) containers(tx *bbolt.Tx) ([]cid.ID, error) {
|
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 err
|
||||||
})
|
})
|
||||||
|
|
||||||
return size, err
|
return size, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) containerSize(tx *bbolt.Tx, id cid.ID) (uint64, error) {
|
func (db *DB) containerSize(tx *bbolt.Tx, id cid.ID) (uint64, error) {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"path/filepath"
|
"path/filepath"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
"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/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
|
||||||
|
@ -34,7 +35,7 @@ func (db *DB) Open(readOnly bool) error {
|
||||||
}
|
}
|
||||||
db.boltOptions.ReadOnly = readOnly
|
db.boltOptions.ReadOnly = readOnly
|
||||||
|
|
||||||
return db.openBolt()
|
return metaerr.Wrap(db.openBolt())
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) openBolt() error {
|
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,
|
// Does nothing if metabase has already been initialized and filled. To roll back the database to its initial state,
|
||||||
// use Reset.
|
// use Reset.
|
||||||
func (db *DB) Init() error {
|
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
|
// 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 ErrDegradedMode
|
||||||
}
|
}
|
||||||
|
|
||||||
return db.init(true)
|
return metaerr.Wrap(db.init(true))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) init(reset bool) error {
|
func (db *DB) init(reset bool) error {
|
||||||
|
@ -167,15 +168,15 @@ func (db *DB) SyncCounters() error {
|
||||||
return ErrReadOnlyMode
|
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)
|
return syncCounter(tx, true)
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// Close closes boltDB instance.
|
// Close closes boltDB instance.
|
||||||
func (db *DB) Close() error {
|
func (db *DB) Close() error {
|
||||||
if db.boltDB != nil {
|
if db.boltDB != nil {
|
||||||
return db.boltDB.Close()
|
return metaerr.Wrap(db.boltDB.Close())
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -203,7 +204,7 @@ func (db *DB) Reload(opts ...Option) (bool, error) {
|
||||||
db.mode = mode.Degraded
|
db.mode = mode.Degraded
|
||||||
db.info.Path = c.info.Path
|
db.info.Path = c.info.Path
|
||||||
if err := db.openBolt(); err != nil {
|
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
|
db.mode = mode.ReadWrite
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"encoding/binary"
|
"encoding/binary"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
|
@ -67,7 +68,7 @@ func (db *DB) ObjectCounters() (cc ObjectCounters, err error) {
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return
|
return cc, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// updateCounter updates the object counter. Tx MUST be writable.
|
// updateCounter updates the object counter. Tx MUST be writable.
|
||||||
|
|
|
@ -8,6 +8,7 @@ import (
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
||||||
storagelog "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/log"
|
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"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
||||||
objectSDK "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
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,
|
availableRemoved: availableRemoved,
|
||||||
sizes: sizes,
|
sizes: sizes,
|
||||||
availableSizes: availableSizes,
|
availableSizes: availableSizes,
|
||||||
}, err
|
}, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// deleteGroup deletes object from the metabase. Handles removal of the
|
// deleteGroup deletes object from the metabase. Handles removal of the
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
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-node/pkg/local_object_storage/util/logicerr"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
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 err
|
||||||
})
|
})
|
||||||
|
|
||||||
return
|
return res, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) exists(tx *bbolt.Tx, addr oid.Address, currEpoch uint64) (exists bool, err error) {
|
func (db *DB) exists(tx *bbolt.Tx, addr oid.Address, currEpoch uint64) (exists bool, err error) {
|
||||||
|
|
|
@ -7,6 +7,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
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"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
|
@ -65,7 +66,7 @@ func (db *DB) FilterExpired(ctx context.Context, epoch uint64, addresses []oid.A
|
||||||
})
|
})
|
||||||
|
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
return result, nil
|
return result, nil
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"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-node/pkg/local_object_storage/util/logicerr"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
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 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) {
|
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"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
@ -65,9 +66,9 @@ func (db *DB) IterateOverGarbage(p GarbageIterationPrm) error {
|
||||||
return ErrDegradedMode
|
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)
|
return db.iterateDeletedObj(tx, gcHandler{p.h}, p.offset)
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TombstonedObject represents descriptor of the
|
// TombstonedObject represents descriptor of the
|
||||||
|
@ -132,9 +133,9 @@ func (db *DB) IterateOverGraveyard(p GraveyardIterationPrm) error {
|
||||||
return ErrDegradedMode
|
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)
|
return db.iterateDeletedObj(tx, graveyardHandler{p.h}, p.offset)
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
type kvHandler interface {
|
type kvHandler interface {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"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-node/pkg/local_object_storage/util/logicerr"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
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 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 {
|
func (db *DB) inhumeTx(tx *bbolt.Tx, epoch uint64, prm InhumePrm, res *InhumeRes) error {
|
||||||
|
|
|
@ -6,6 +6,7 @@ import (
|
||||||
"strconv"
|
"strconv"
|
||||||
|
|
||||||
objectV2 "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
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-node/pkg/local_object_storage/util/logicerr"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
|
@ -51,9 +52,9 @@ func (db *DB) IterateExpired(epoch uint64, h ExpiredObjectHandler) error {
|
||||||
return ErrDegradedMode
|
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)
|
return db.iterateExpired(tx, epoch, h)
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) iterateExpired(tx *bbolt.Tx, epoch uint64, h ExpiredObjectHandler) error {
|
func (db *DB) iterateExpired(tx *bbolt.Tx, epoch uint64, h ExpiredObjectHandler) error {
|
||||||
|
|
|
@ -2,6 +2,7 @@ package meta
|
||||||
|
|
||||||
import (
|
import (
|
||||||
objectcore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
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"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
"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 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) {
|
func (db *DB) listWithCursor(tx *bbolt.Tx, result []objectcore.AddressWithType, count int, cursor *Cursor) ([]objectcore.AddressWithType, *Cursor, error) {
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"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-node/pkg/local_object_storage/util/logicerr"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
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)
|
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 {
|
if firstIrregularObjectType(tx, cnr, bucketKeysLocked...) != object.TypeRegular {
|
||||||
return logicerr.Wrap(apistatus.LockNonRegularObject{})
|
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
|
return nil
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// FreeLockedBy unlocks all objects in DB which are locked by lockers.
|
// 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
|
return nil
|
||||||
}); err != nil {
|
}); err != nil {
|
||||||
return nil, err
|
return nil, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
return unlockedObjects, nil
|
return unlockedObjects, nil
|
||||||
}
|
}
|
||||||
|
@ -292,8 +293,8 @@ func (db *DB) IsLocked(ctx context.Context, prm IsLockedPrm) (res IsLockedRes, e
|
||||||
return res, ErrDegradedMode
|
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())
|
res.locked = objectLocked(tx, prm.addr.Container(), prm.addr.Object())
|
||||||
return nil
|
return nil
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"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 toMoveIt.Put(key, zeroValue)
|
||||||
})
|
})
|
||||||
|
|
||||||
return
|
return res, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// DoNotMove removes `MoveIt` mark from the object.
|
// 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 toMoveIt.Delete(key)
|
||||||
})
|
})
|
||||||
|
|
||||||
return
|
return res, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Movable returns list of marked objects to move into other shard.
|
// 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 {
|
if err != nil {
|
||||||
return MovableRes{}, err
|
return MovableRes{}, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// we can parse strings to structures in-place, but probably it seems
|
// 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 {
|
for i := range strAddrs {
|
||||||
err = decodeAddressFromKey(&addrs[i], []byte(strAddrs[i]))
|
err = decodeAddressFromKey(&addrs[i], []byte(strAddrs[i]))
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return MovableRes{}, fmt.Errorf("can't parse object address %v: %w",
|
return MovableRes{}, metaerr.Wrap(fmt.Errorf("can't parse object address %v: %w",
|
||||||
strAddrs[i], err)
|
strAddrs[i], err))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
objectCore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
objectCore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
||||||
storagelog "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/log"
|
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-node/pkg/local_object_storage/util"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
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"))
|
storagelog.OpField("metabase PUT"))
|
||||||
}
|
}
|
||||||
|
|
||||||
return
|
return res, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) put(tx *bbolt.Tx,
|
func (db *DB) put(tx *bbolt.Tx,
|
||||||
|
|
|
@ -9,6 +9,7 @@ import (
|
||||||
|
|
||||||
v2object "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
v2object "git.frostfs.info/TrueCloudLab/frostfs-api-go/v2/object"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/internal/logs"
|
"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"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
cid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/container/id"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
"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()
|
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)
|
res.addrList, err = db.selectObjects(tx, prm.cnr, prm.filters, currEpoch)
|
||||||
|
|
||||||
return err
|
return err
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) selectObjects(tx *bbolt.Tx, cnr cid.ID, fs object.SearchFilters, currEpoch uint64) ([]oid.Address, error) {
|
func (db *DB) selectObjects(tx *bbolt.Tx, cnr cid.ID, fs object.SearchFilters, currEpoch uint64) ([]oid.Address, error) {
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
package meta
|
package meta
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
@ -28,7 +29,7 @@ func (db *DB) ReadShardID() ([]byte, error) {
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return id, err
|
return id, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// WriteShardID writes shard it to db.
|
// WriteShardID writes shard it to db.
|
||||||
|
@ -42,11 +43,11 @@ func (db *DB) WriteShardID(id []byte) error {
|
||||||
return ErrReadOnlyMode
|
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)
|
b, err := tx.CreateBucketIfNotExists(shardInfoBucket)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
}
|
}
|
||||||
return b.Put(shardIDKey, id)
|
return b.Put(shardIDKey, id)
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"context"
|
"context"
|
||||||
"errors"
|
"errors"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"github.com/nspcc-dev/neo-go/pkg/util/slice"
|
"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 err
|
||||||
})
|
})
|
||||||
|
|
||||||
return
|
return res, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
func (db *DB) storageID(tx *bbolt.Tx, addr oid.Address) ([]byte, error) {
|
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 err
|
||||||
})
|
})
|
||||||
|
|
||||||
return
|
return res, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,6 +12,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"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/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/util/logicerr"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util"
|
"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 {
|
func (t *boltForest) Open(readOnly bool) error {
|
||||||
err := util.MkdirAllX(filepath.Dir(t.path), t.perm)
|
err := util.MkdirAllX(filepath.Dir(t.path), t.perm)
|
||||||
if err != nil {
|
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
|
opts := *bbolt.DefaultOptions
|
||||||
|
@ -116,7 +117,7 @@ func (t *boltForest) Open(readOnly bool) error {
|
||||||
|
|
||||||
t.db, err = bbolt.Open(t.path, t.perm, &opts)
|
t.db, err = bbolt.Open(t.path, t.perm, &opts)
|
||||||
if err != nil {
|
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
|
t.db.MaxBatchSize = t.maxBatchSize
|
||||||
|
@ -174,7 +175,7 @@ func (t *boltForest) TreeMove(ctx context.Context, d CIDDescriptor, treeID strin
|
||||||
|
|
||||||
lm := *m
|
lm := *m
|
||||||
fullID := bucketName(d.CID, treeID)
|
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)
|
bLog, bTree, err := t.getTreeBuckets(tx, fullID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -185,7 +186,7 @@ func (t *boltForest) TreeMove(ctx context.Context, d CIDDescriptor, treeID strin
|
||||||
lm.Child = t.findSpareID(bTree)
|
lm.Child = t.findSpareID(bTree)
|
||||||
}
|
}
|
||||||
return t.do(bLog, bTree, make([]byte, 17), &lm)
|
return t.do(bLog, bTree, make([]byte, 17), &lm)
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *boltForest) TreeHeight(ctx context.Context, cid cidSDK.ID, treeID string) (uint64, error) {
|
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 {
|
if err == nil {
|
||||||
err = retErr
|
err = retErr
|
||||||
}
|
}
|
||||||
return height, err
|
return height, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TreeExists implements the Forest interface.
|
// TreeExists implements the Forest interface.
|
||||||
|
@ -247,7 +248,7 @@ func (t *boltForest) TreeExists(ctx context.Context, cid cidSDK.ID, treeID strin
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return exists, err
|
return exists, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
var syncHeightKey = []byte{'h'}
|
var syncHeightKey = []byte{'h'}
|
||||||
|
@ -267,7 +268,7 @@ func (t *boltForest) TreeUpdateLastSyncHeight(ctx context.Context, cid cidSDK.ID
|
||||||
binary.LittleEndian.PutUint64(rawHeight, height)
|
binary.LittleEndian.PutUint64(rawHeight, height)
|
||||||
|
|
||||||
buck := bucketName(cid, treeID)
|
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)
|
treeRoot := tx.Bucket(buck)
|
||||||
if treeRoot == nil {
|
if treeRoot == nil {
|
||||||
return ErrTreeNotFound
|
return ErrTreeNotFound
|
||||||
|
@ -275,7 +276,7 @@ func (t *boltForest) TreeUpdateLastSyncHeight(ctx context.Context, cid cidSDK.ID
|
||||||
|
|
||||||
b := treeRoot.Bucket(dataBucket)
|
b := treeRoot.Bucket(dataBucket)
|
||||||
return b.Put(syncHeightKey, rawHeight)
|
return b.Put(syncHeightKey, rawHeight)
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TreeLastSyncHeight implements the pilorama.Forest interface.
|
// TreeLastSyncHeight implements the pilorama.Forest interface.
|
||||||
|
@ -304,7 +305,7 @@ func (t *boltForest) TreeLastSyncHeight(ctx context.Context, cid cidSDK.ID, tree
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return height, err
|
return height, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TreeAddByPath implements the Forest interface.
|
// 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 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
|
// 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
|
return nil
|
||||||
})
|
})
|
||||||
if err != nil || seen {
|
if err != nil || seen {
|
||||||
return err
|
return metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if t.db.MaxBatchSize == 1 {
|
if t.db.MaxBatchSize == 1 {
|
||||||
fullID := bucketName(cnr, treeID)
|
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)
|
bLog, bTree, err := t.getTreeBuckets(tx, fullID)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return err
|
||||||
|
@ -464,12 +465,12 @@ func (t *boltForest) TreeApply(ctx context.Context, cnr cidSDK.ID, treeID string
|
||||||
|
|
||||||
var lm Move
|
var lm Move
|
||||||
return t.applyOperation(bLog, bTree, []*Move{m}, &lm)
|
return t.applyOperation(bLog, bTree, []*Move{m}, &lm)
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
ch := make(chan error, 1)
|
ch := make(chan error, 1)
|
||||||
t.addBatch(cnr, treeID, m, ch)
|
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) {
|
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
|
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))
|
treeRoot := tx.Bucket(bucketName(cid, treeID))
|
||||||
if treeRoot == nil {
|
if treeRoot == nil {
|
||||||
return ErrTreeNotFound
|
return ErrTreeNotFound
|
||||||
|
@ -788,7 +789,7 @@ func (t *boltForest) TreeGetByPath(ctx context.Context, cid cidSDK.ID, treeID st
|
||||||
childKey, _ = c.Next()
|
childKey, _ = c.Next()
|
||||||
}
|
}
|
||||||
return nil
|
return nil
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
// TreeGetMeta implements the forest interface.
|
// 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.FromBytes(meta)
|
||||||
})
|
})
|
||||||
|
|
||||||
return m, parentID, err
|
return m, parentID, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TreeGetChildren implements the Forest interface.
|
// TreeGetChildren implements the Forest interface.
|
||||||
|
@ -869,7 +870,7 @@ func (t *boltForest) TreeGetChildren(ctx context.Context, cid cidSDK.ID, treeID
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return children, err
|
return children, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TreeList implements the Forest interface.
|
// TreeList implements the Forest interface.
|
||||||
|
@ -907,7 +908,7 @@ func (t *boltForest) TreeList(ctx context.Context, cid cidSDK.ID) ([]string, err
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
if err != 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
|
return ids, nil
|
||||||
|
@ -949,7 +950,7 @@ func (t *boltForest) TreeGetOpLog(ctx context.Context, cid cidSDK.ID, treeID str
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
|
|
||||||
return lm, err
|
return lm, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// TreeDrop implements the pilorama.Forest interface.
|
// 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 ErrReadOnlyMode
|
||||||
}
|
}
|
||||||
|
|
||||||
return t.db.Batch(func(tx *bbolt.Tx) error {
|
return metaerr.Wrap(t.db.Batch(func(tx *bbolt.Tx) error {
|
||||||
if treeID == "" {
|
if treeID == "" {
|
||||||
c := tx.Cursor()
|
c := tx.Cursor()
|
||||||
prefix := make([]byte, 32)
|
prefix := make([]byte, 32)
|
||||||
|
@ -989,7 +990,7 @@ func (t *boltForest) TreeDrop(ctx context.Context, cid cidSDK.ID, treeID string)
|
||||||
return ErrTreeNotFound
|
return ErrTreeNotFound
|
||||||
}
|
}
|
||||||
return err
|
return err
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *boltForest) getPathPrefix(bTree *bbolt.Bucket, attr string, path []string) (int, Node, error) {
|
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"
|
"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"
|
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"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
|
@ -77,5 +78,5 @@ func (c *cache) Delete(ctx context.Context, addr oid.Address) error {
|
||||||
deleted = true
|
deleted = true
|
||||||
}
|
}
|
||||||
|
|
||||||
return err
|
return metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -10,6 +10,7 @@ import (
|
||||||
objectCore "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/core/object"
|
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"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"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"
|
meta "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/metabase"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
"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()
|
data, err := f()
|
||||||
if err != nil {
|
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 {
|
if ignoreErrors {
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
@ -203,7 +204,7 @@ func (c *cache) flushFSTree(ctx context.Context, ignoreErrors bool) error {
|
||||||
var obj object.Object
|
var obj object.Object
|
||||||
err = obj.Unmarshal(data)
|
err = obj.Unmarshal(data)
|
||||||
if err != nil {
|
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 {
|
if ignoreErrors {
|
||||||
return nil
|
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() {
|
for k, data := cs.Seek(nil); k != nil; k, data = cs.Next() {
|
||||||
sa := string(k)
|
sa := string(k)
|
||||||
if err := addr.DecodeString(sa); err != nil {
|
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 {
|
if ignoreErrors {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
@ -323,7 +324,7 @@ func (c *cache) flush(ctx context.Context, ignoreErrors bool) error {
|
||||||
|
|
||||||
var obj object.Object
|
var obj object.Object
|
||||||
if err := obj.Unmarshal(data); err != nil {
|
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 {
|
if ignoreErrors {
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,6 +5,7 @@ import (
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/common"
|
"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-node/pkg/local_object_storage/util/logicerr"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
apistatus "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/client/status"
|
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()
|
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) {
|
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)
|
obj, err := c.getInternal(ctx, saddr, addr)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
return obj.CutPayload(), nil
|
return obj.CutPayload(), nil
|
||||||
|
@ -95,5 +97,5 @@ func Get(db *bbolt.DB, key []byte) ([]byte, error) {
|
||||||
value = slice.Copy(value)
|
value = slice.Copy(value)
|
||||||
return nil
|
return nil
|
||||||
})
|
})
|
||||||
return value, err
|
return value, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
|
@ -4,6 +4,7 @@ import (
|
||||||
"errors"
|
"errors"
|
||||||
"fmt"
|
"fmt"
|
||||||
|
|
||||||
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/metaerr"
|
||||||
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
oid "git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object/id"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
)
|
)
|
||||||
|
@ -18,7 +19,7 @@ var ErrNoDefaultBucket = errors.New("no default bucket")
|
||||||
//
|
//
|
||||||
// DB must not be nil and should be opened.
|
// DB must not be nil and should be opened.
|
||||||
func IterateDB(db *bbolt.DB, f func(oid.Address) error) error {
|
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)
|
b := tx.Bucket(defaultBucket)
|
||||||
if b == nil {
|
if b == nil {
|
||||||
return ErrNoDefaultBucket
|
return ErrNoDefaultBucket
|
||||||
|
@ -34,5 +35,5 @@ func IterateDB(db *bbolt.DB, f func(oid.Address) error) error {
|
||||||
|
|
||||||
return f(addr)
|
return f(addr)
|
||||||
})
|
})
|
||||||
})
|
}))
|
||||||
}
|
}
|
||||||
|
|
|
@ -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/common"
|
||||||
storagelog "git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/internal/log"
|
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"
|
"git.frostfs.info/TrueCloudLab/frostfs-observability/tracing"
|
||||||
"go.etcd.io/bbolt"
|
"go.etcd.io/bbolt"
|
||||||
"go.opentelemetry.io/otel/attribute"
|
"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 {
|
if err == nil {
|
||||||
added = true
|
added = true
|
||||||
}
|
}
|
||||||
return common.PutRes{}, err
|
return common.PutRes{}, metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// putSmall persists small objects to the write-cache database and
|
// 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/common"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/local_object_storage/blobstor/fstree"
|
"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/local_object_storage/shard/mode"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
"git.frostfs.info/TrueCloudLab/frostfs-node/pkg/util/logger"
|
||||||
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
"git.frostfs.info/TrueCloudLab/frostfs-sdk-go/object"
|
||||||
|
@ -129,14 +130,14 @@ func (c *cache) DumpInfo() Info {
|
||||||
func (c *cache) Open(readOnly bool) error {
|
func (c *cache) Open(readOnly bool) error {
|
||||||
err := c.openStore(readOnly)
|
err := c.openStore(readOnly)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return err
|
return metaerr.Wrap(err)
|
||||||
}
|
}
|
||||||
|
|
||||||
// Opening after Close is done during maintenance mode,
|
// Opening after Close is done during maintenance mode,
|
||||||
// thus we need to create a channel here.
|
// thus we need to create a channel here.
|
||||||
c.closeCh = make(chan struct{})
|
c.closeCh = make(chan struct{})
|
||||||
|
|
||||||
return c.initCounters()
|
return metaerr.Wrap(c.initCounters())
|
||||||
}
|
}
|
||||||
|
|
||||||
// Init runs necessary services.
|
// Init runs necessary services.
|
||||||
|
|
Loading…
Reference in a new issue