diff --git a/fragment.go b/fragment.go index 81f1fb007..a89702528 100644 --- a/fragment.go +++ b/fragment.go @@ -215,7 +215,7 @@ func (f *fragment) openStorage() error { return fmt.Errorf("init storage file: %s", err) } bi.Flush() - fi, err = f.file.Stat() + _, err = f.file.Stat() if err != nil { return errors.Wrap(err, "statting file after") } diff --git a/server/server.go b/server/server.go index f15965f52..930d7841f 100644 --- a/server/server.go +++ b/server/server.go @@ -179,7 +179,7 @@ func (m *Command) Wait() error { // SetupServer uses the cluster configuration to set up this server. func (m *Command) SetupServer() error { - syswrap.MaxMapCount = m.Config.MaxMapCount + syswrap.SetMaxMapCount(m.Config.MaxMapCount) err := m.setupLogger() if err != nil { diff --git a/syswrap/mmap.go b/syswrap/mmap.go index 51186e55f..a13dff8af 100644 --- a/syswrap/mmap.go +++ b/syswrap/mmap.go @@ -3,6 +3,7 @@ package syswrap import ( + "sync" "sync/atomic" "syscall" @@ -13,16 +14,25 @@ var mapCount uint64 var ErrMaxMapCountReached = errors.New("maximum map count reached") -// MaxMapCount default to slightly less than the typical +// maxMapCount default to slightly less than the typical // default on Linux (65K). We want to leave some // overhead for (e.g.) the Go runtime. -var MaxMapCount uint64 = 60000 +var maxMapCount uint64 = 60000 +var mu sync.RWMutex + +func SetMaxMapCount(max uint64) { + mu.Lock() + maxMapCount = max + mu.Unlock() +} // Mmap increments the global map count, and then calls syscall.Mmap. It // decrements the map count and returns an error if the count was over the // limit. If syscall.Mmap returns an error it also decrements the count. func Mmap(fd int, offset int64, length int, prot int, flags int) (data []byte, err error) { - if newCount := atomic.AddUint64(&mapCount, 1); newCount > MaxMapCount { + mu.RLock() + defer mu.RUnlock() + if newCount := atomic.AddUint64(&mapCount, 1); newCount > maxMapCount { atomic.AddUint64(&mapCount, ^uint64(0)) // decrement return nil, ErrMaxMapCountReached }