12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061 |
- // Copyright (C) 2015 The Syncthing Authors.
- //
- // This Source Code Form is subject to the terms of the Mozilla Public
- // License, v. 2.0. If a copy of the MPL was not distributed with this file,
- // You can obtain one at https://mozilla.org/MPL/2.0/.
- // +build !windows
- package osutil
- import (
- "runtime"
- "syscall"
- )
- const (
- darwinOpenMax = 10240
- )
- // MaximizeOpenFileLimit tries to set the resource limit RLIMIT_NOFILE (number
- // of open file descriptors) to the max (hard limit), if the current (soft
- // limit) is below the max. Returns the new (though possibly unchanged) limit,
- // or an error if it could not be changed.
- func MaximizeOpenFileLimit() (int, error) {
- // Get the current limit on number of open files.
- var lim syscall.Rlimit
- if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim); err != nil {
- return 0, err
- }
- // If we're already at max, there's no need to try to raise the limit.
- if lim.Cur >= lim.Max {
- return int(lim.Cur), nil
- }
- // macOS doesn't like a soft limit greater then OPEN_MAX
- // See also: man setrlimit
- if runtime.GOOS == "darwin" && lim.Max > darwinOpenMax {
- lim.Max = darwinOpenMax
- }
- // Try to increase the limit to the max.
- oldLimit := lim.Cur
- lim.Cur = lim.Max
- if err := syscall.Setrlimit(syscall.RLIMIT_NOFILE, &lim); err != nil {
- return int(oldLimit), err
- }
- // If the set succeeded, perform a new get to see what happened. We might
- // have gotten a value lower than the one in lim.Max, if lim.Max was
- // something that indicated "unlimited" (i.e. intmax).
- if err := syscall.Getrlimit(syscall.RLIMIT_NOFILE, &lim); err != nil {
- // We don't really know the correct value here since Getrlimit
- // mysteriously failed after working once... Shouldn't ever happen, I
- // think.
- return 0, err
- }
- return int(lim.Cur), nil
- }
|