fix(build): raise file limit for native gateway builds (#3122)

Native gateway builds exhaust the default open-file soft limit. Raise the
soft limit to the hard limit (capped) in the shared build environment and
apply it from the gateway task scripts.

Explicitly read the current soft limit and only raise it when needed.

Signed-off-by: Jim Meyer <jimeyer@nvidia.com>
This commit is contained in:
Jim Meyer
2026-10-23 21:59:15 +00:00
committed by GitHub
parent e0ba078920
commit 567d36033b
5 changed files with 25 additions and 37 deletions
+1 -1
View File
@@ -5,7 +5,7 @@
["build:gateway"]
description = "Build the standalone openshell-gateway binary"
run = "cargo build -p openshell-gateway --bin openshell-gateway"
run = "bash -c 'source tasks/scripts/build-env.sh && ensure_build_nofile_limit && cargo build -p openshell-gateway --bin openshell-gateway'"
hide = true
["gateway"]
+14 -18
View File
@@ -3,21 +3,19 @@
# SPDX-FileCopyrightText: Copyright (c) 2025-2026 NVIDIA CORPORATION & AFFILIATES. All rights reserved.
# SPDX-License-Identifier: Apache-2.0
# Shared build-environment helpers for host-side cross-compilation.
# Shared build-environment helpers for host-side Rust builds.
#
# Source this file (do not execute it) and call the helpers before invoking
# cargo-zigbuild on the host.
# Cargo on the host.
# ensure_build_nofile_limit raises the per-process open-file limit before a
# host cargo-zigbuild cross-compile. The static *-unknown-linux-musl link opens
# hundreds of .rlib files simultaneously, which exceeds macOS's default soft
# limit of 256 and fails with ProcessFdQuotaExceeded. The raised limit
# propagates to the cargo/zig children the caller spawns.
# host Rust build. Sccache and static *-unknown-linux-musl links can each open
# hundreds of files simultaneously, exceeding macOS's default soft limit of
# 256. The raised limit propagates to the Cargo children the caller spawns.
#
# The limit is read from OPENSHELL_BUILD_NOFILE_LIMIT (default 8192), honoring
# the legacy OPENSHELL_VM_BUILD_NOFILE_LIMIT for back-compat. This is a no-op on
# Linux and when cargo-zigbuild is not installed (native builds, CI Linux
# runners), so it must be safe to call unconditionally.
# the legacy OPENSHELL_VM_BUILD_NOFILE_LIMIT for back-compat. This is a no-op
# on Linux, so it must be safe to call unconditionally.
ensure_build_nofile_limit() {
local desired="${OPENSHELL_BUILD_NOFILE_LIMIT:-${OPENSHELL_VM_BUILD_NOFILE_LIMIT:-8192}}"
local minimum=1024
@@ -26,9 +24,7 @@ ensure_build_nofile_limit() {
local target=""
[ "$(uname -s)" = "Darwin" ] || return 0
command -v cargo-zigbuild >/dev/null 2>&1 || return 0
current="$(ulimit -n 2>/dev/null || echo "")"
current="$(ulimit -Sn 2>/dev/null || echo "")"
case "${current}" in
''|*[!0-9]*)
return 0
@@ -53,11 +49,11 @@ ensure_build_nofile_limit() {
;;
esac
if [ "${target}" -gt "${current}" ] && ulimit -n "${target}" 2>/dev/null; then
echo "==> Raised open file limit for cargo-zigbuild: ${current} -> $(ulimit -n)"
if [ "${target}" -gt "${current}" ] && ulimit -Sn "${target}" 2>/dev/null; then
echo "==> Raised open file limit for host Cargo build: ${current} -> $(ulimit -Sn)"
fi
current="$(ulimit -n 2>/dev/null || echo "${current}")"
current="$(ulimit -Sn 2>/dev/null || echo "${current}")"
case "${current}" in
''|*[!0-9]*)
return 0
@@ -65,12 +61,12 @@ ensure_build_nofile_limit() {
esac
if [ "${current}" -lt "${desired}" ]; then
echo "WARNING: Open file limit is ${current}; cargo-zigbuild is more reliable at ${desired}+ on macOS."
echo "WARNING: Open file limit is ${current}; host Cargo builds are more reliable at ${desired}+ on macOS."
fi
if [ "${current}" -lt "${minimum}" ]; then
echo "ERROR: Open file limit (${current}) is too low for cargo-zigbuild on macOS." >&2
echo " Run: ulimit -n ${desired}" >&2
echo "ERROR: Open file limit (${current}) is too low for host Cargo builds on macOS." >&2
echo " Run: ulimit -Sn ${desired}" >&2
echo " Then re-run this script." >&2
exit 1
fi
+3
View File
@@ -30,6 +30,9 @@ ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
source "${ROOT}/tasks/scripts/gateway-toml.sh"
# shellcheck source=tasks/scripts/gateway-pull-policy.sh
source "${ROOT}/tasks/scripts/gateway-pull-policy.sh"
# shellcheck source=tasks/scripts/build-env.sh
source "${ROOT}/tasks/scripts/build-env.sh"
ensure_build_nofile_limit
PORT="${OPENSHELL_SERVER_PORT:-18080}"
GATEWAY_NAME="${OPENSHELL_DOCKER_GATEWAY_NAME:-docker-dev}"
STATE_DIR="${OPENSHELL_DOCKER_GATEWAY_STATE_DIR:-${ROOT}/.cache/gateway-docker}"
+3
View File
@@ -35,6 +35,9 @@ set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
# shellcheck source=tasks/scripts/gateway-toml.sh
source "${ROOT}/tasks/scripts/gateway-toml.sh"
# shellcheck source=tasks/scripts/build-env.sh
source "${ROOT}/tasks/scripts/build-env.sh"
ensure_build_nofile_limit
PORT="${OPENSHELL_SERVER_PORT:-18081}"
GATEWAY_NAME="${OPENSHELL_VM_GATEWAY_NAME:-vm-dev}"
STATE_DIR="${OPENSHELL_VM_GATEWAY_STATE_DIR:-${ROOT}/.cache/gateway-vm}"
+4 -18
View File
@@ -38,28 +38,14 @@ if [ "${os}" != "Darwin" ]; then
exit 0
fi
# Darwin below.
if ! command -v cargo-zigbuild >/dev/null 2>&1; then
# Without cargo-zigbuild the helper must be a no-op even on macOS.
(
ulimit -Sn 256 2>/dev/null || true
before="$(ulimit -n)"
ensure_build_nofile_limit >/dev/null
after="$(ulimit -n)"
[ "${before}" = "${after}" ] || fail "limit changed on macOS without cargo-zigbuild (${before} -> ${after})"
)
pass "no-op on macOS without cargo-zigbuild"
echo "All build-env tests passed."
exit 0
fi
# Darwin + cargo-zigbuild: the helper should raise a low soft limit.
# Darwin native Cargo builds need the same protection even when
# cargo-zigbuild is unavailable.
(
if ! ulimit -Sn 256 2>/dev/null; then
echo "SKIP: unable to lower soft limit to 256 for test"
exit 0
fi
ensure_build_nofile_limit >/dev/null
PATH="/usr/bin:/bin" ensure_build_nofile_limit >/dev/null
after="$(ulimit -n)"
hard="$(ulimit -Hn 2>/dev/null || echo unlimited)"
case "${hard}" in
@@ -76,7 +62,7 @@ fi
;;
esac
)
pass "raises low soft limit on macOS with cargo-zigbuild"
pass "raises low soft limit for native Cargo builds on macOS"
# Idempotent: when the current limit already meets the desired value, the helper
# leaves it unchanged (drive this via the env override so it holds regardless of