From 1fa59f4a6a8f61a970ec3531955fe04554168306 Mon Sep 17 00:00:00 2001 From: Andrey Butusov Date: Wed, 6 Nov 2024 18:07:50 +0300 Subject: [PATCH] metabase: `Open(readOnly)` sets mode to RO Now, when the metabase is opened with the readOnly flag, it sets the mode to ReadOnly. Add test. Closes #2889. Signed-off-by: Andrey Butusov --- CHANGELOG.md | 1 + pkg/local_object_storage/metabase/control.go | 4 ++ .../metabase/control_test.go | 38 +++++++++++++++++++ 3 files changed, 43 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 1aef08c7f4..ded98676b0 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -25,6 +25,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 da6766693b..714a38494c 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) { var existsPrm meta.ExistsPrm existsPrm.SetAddress(addr)