diff --git a/CHANGELOG.md b/CHANGELOG.md index c88e3a09a4..9f2510c65a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -26,6 +26,7 @@ attribute, which is used for container domain name in NNS contracts (#2954) - False negative connection to NeoFS chain in multi-endpoint setup with at least one live node (#2986) - Overriding the default container and object attributes only with the appropriate flags (#2985) - RPC client reconnection failures leading to complete SN failure (#2797) +- `meta.DB.Open(readOnly)` moves metabase in RO mode (#3000) ### Changed - `ObjectService`'s `Put` RPC handler caches up to 10K lists of per-object sorted container nodes (#2901) diff --git a/pkg/local_object_storage/metabase/control.go b/pkg/local_object_storage/metabase/control.go index ff00632685..2311411c5a 100644 --- a/pkg/local_object_storage/metabase/control.go +++ b/pkg/local_object_storage/metabase/control.go @@ -33,6 +33,10 @@ func (db *DB) Open(readOnly bool) error { } db.boltOptions.ReadOnly = readOnly + if readOnly { + db.mode = mode.ReadOnly + } + return db.openBolt() } diff --git a/pkg/local_object_storage/metabase/control_test.go b/pkg/local_object_storage/metabase/control_test.go index 162f98f9bb..01de6bc091 100644 --- a/pkg/local_object_storage/metabase/control_test.go +++ b/pkg/local_object_storage/metabase/control_test.go @@ -1,6 +1,7 @@ package meta_test import ( + "path/filepath" "testing" "github.com/nspcc-dev/neofs-node/pkg/core/object" @@ -50,6 +51,43 @@ func TestReset(t *testing.T) { assertExists(addr, false, nil) } +func TestOpenRO(t *testing.T) { + path := filepath.Join(t.TempDir(), "meta") + + db := meta.New( + meta.WithPath(path), + meta.WithPermissions(0o600), + meta.WithEpochState(epochState{}), + ) + + require.NoError(t, db.Open(false)) + require.NoError(t, db.Init()) + + obj := generateObject(t) + addr := object.AddressOf(obj) + + require.NoError(t, putBig(db, obj)) + exists, err := metaExists(db, addr) + require.NoError(t, err) + require.True(t, exists) + + require.NoError(t, db.Close()) + + // Open in RO mode + require.NoError(t, db.Open(true)) + + // we can't write + err = putBig(db, obj) + require.ErrorIs(t, err, meta.ErrReadOnlyMode) + + // but can read + exists, err = metaExists(db, addr) + require.NoError(t, err) + require.True(t, exists) + + require.NoError(t, db.Close()) +} + func metaExists(db *meta.DB, addr oid.Address) (bool, error) { return db.Exists(addr, false) }