123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263 |
- // 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/.
- //go:build !windows
- // +build !windows
- package osutil
- import (
- "syscall"
- "github.com/syncthing/syncthing/lib/build"
- )
- 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 build.IsDarwin && 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
- }
|