Perform unmap when failing to mlock or both meta pages corrupted

Signed-off-by: Benjamin Wang <wachao@vmware.com>
pull/433/head
Benjamin Wang 2023-03-21 16:35:22 +08:00
parent d8ac759d4f
commit b2f3dd5dba
2 changed files with 14 additions and 4 deletions

16
db.go
View File

@ -388,7 +388,7 @@ func (db *DB) hasSyncedFreelist() bool {
// mmap opens the underlying memory-mapped file and initializes the meta references.
// minsz is the minimum size that the new mmap can be.
func (db *DB) mmap(minsz int) error {
func (db *DB) mmap(minsz int) (err error) {
db.mmaplock.Lock()
defer db.mmaplock.Unlock()
@ -423,17 +423,27 @@ func (db *DB) mmap(minsz int) error {
}
// Unmap existing data before continuing.
if err := db.munmap(); err != nil {
if err = db.munmap(); err != nil {
return err
}
// Memory-map the data file as a byte slice.
// gofail: var mapError string
// return errors.New(mapError)
if err := mmap(db, size); err != nil {
if err = mmap(db, size); err != nil {
return err
}
// Perform unmmap on any error to reset all data fields:
// dataref, data, datasz, meta0 and meta1.
defer func() {
if err != nil {
if unmapErr := db.munmap(); unmapErr != nil {
err = fmt.Errorf("%w; unmap failed: %v", err, unmapErr)
}
}
}()
if db.Mlock {
// Don't allow swapping of data file
if err := db.mlock(fileSize); err != nil {

View File

@ -2,7 +2,6 @@ package failpoint
import (
"fmt"
"go.etcd.io/bbolt/internal/btesting"
"path/filepath"
"testing"
"time"
@ -10,6 +9,7 @@ import (
"github.com/stretchr/testify/require"
bolt "go.etcd.io/bbolt"
"go.etcd.io/bbolt/internal/btesting"
gofail "go.etcd.io/gofail/runtime"
)