Set ulimit with Python (#19105)

* Set ulimit with python instead of in s6 startup

* move to services and add env var

* add comment
This commit is contained in:
Josh Hawkins 2025-07-11 08:11:35 -05:00 committed by GitHub
parent 687e118b58
commit 3bda638678
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 21 additions and 58 deletions

View File

@ -50,7 +50,6 @@ function set_libva_version() {
echo "[INFO] Preparing Frigate..." echo "[INFO] Preparing Frigate..."
migrate_db_path migrate_db_path
set_libva_version set_libva_version
/usr/local/ulimit/set_ulimit.sh
echo "[INFO] Starting Frigate..." echo "[INFO] Starting Frigate..."
cd /opt/frigate || echo "[ERROR] Failed to change working directory to /opt/frigate" cd /opt/frigate || echo "[ERROR] Failed to change working directory to /opt/frigate"

View File

@ -1,57 +0,0 @@
#!/bin/bash
# Newer versions of containerd 2.X+ impose a very low soft file limit of 1024
# This applies to OSs like HA OS (see https://github.com/home-assistant/operating-system/issues/4110)
# Attempt to increase this limit
# Get current soft and hard nofile limits
current_soft_limit=$(ulimit -Sn)
current_hard_limit=$(ulimit -Hn)
TARGET_SOFT_LIMIT=65536
TARGET_HARD_LIMIT=65536
echo "Current file limits - Soft: $current_soft_limit, Hard: $current_hard_limit"
if [ "$current_soft_limit" -lt "$TARGET_SOFT_LIMIT" ]; then
# Set hard limit first (if it needs to be increased)
hard_limit_success=true
if [ "$current_hard_limit" -lt "$TARGET_HARD_LIMIT" ]; then
if ! ulimit -Hn "$TARGET_HARD_LIMIT"; then
echo "Warning: Failed to set hard limit to $TARGET_HARD_LIMIT"
echo "Current hard limit is $current_hard_limit, will try to set soft limit anyway"
hard_limit_success=false
fi
fi
# Determine what soft limit to use
if [ "$hard_limit_success" = true ] || [ "$current_hard_limit" -ge "$TARGET_SOFT_LIMIT" ]; then
# We can try to set the target soft limit
target_soft=$TARGET_SOFT_LIMIT
else
# Hard limit is too low, set soft limit to current hard limit
target_soft=$current_hard_limit
echo "Setting soft limit to current hard limit ($current_hard_limit) since hard limit couldn't be increased"
fi
# Set soft limit
if ! ulimit -Sn "$target_soft"; then
echo "Warning: Failed to set soft limit to $target_soft"
exit 1
fi
# Verify the new limits
new_soft_limit=$(ulimit -Sn)
new_hard_limit=$(ulimit -Hn)
echo "New limits - Soft: $new_soft_limit, Hard: $new_hard_limit"
if [ "$new_soft_limit" -eq "$TARGET_SOFT_LIMIT" ] && [ "$new_hard_limit" -eq "$TARGET_HARD_LIMIT" ]; then
echo "Successfully set file limits to target values"
elif [ "$new_soft_limit" -gt "$current_soft_limit" ]; then
echo "Successfully increased soft limit from $current_soft_limit to $new_soft_limit"
else
echo "Warning: Soft limit may not have been increased as expected"
fi
else
echo "Soft limit is already sufficient ($current_soft_limit >= $TARGET_SOFT_LIMIT)"
fi

View File

@ -71,6 +71,7 @@ from frigate.timeline import TimelineProcessor
from frigate.util.builtin import empty_and_close_queue from frigate.util.builtin import empty_and_close_queue
from frigate.util.image import SharedMemoryFrameManager, UntrackedSharedMemory from frigate.util.image import SharedMemoryFrameManager, UntrackedSharedMemory
from frigate.util.object import get_camera_regions_grid from frigate.util.object import get_camera_regions_grid
from frigate.util.services import set_file_limit
from frigate.version import VERSION from frigate.version import VERSION
from frigate.video import capture_camera, track_camera from frigate.video import capture_camera, track_camera
from frigate.watchdog import FrigateWatchdog from frigate.watchdog import FrigateWatchdog
@ -587,6 +588,9 @@ class FrigateApp:
# Ensure global state. # Ensure global state.
self.ensure_dirs() self.ensure_dirs()
# Set soft file limits.
set_file_limit()
# Start frigate services. # Start frigate services.
self.init_camera_metrics() self.init_camera_metrics()
self.init_queues() self.init_queues()

View File

@ -5,6 +5,7 @@ import json
import logging import logging
import os import os
import re import re
import resource
import signal import signal
import subprocess as sp import subprocess as sp
import traceback import traceback
@ -632,3 +633,19 @@ async def get_video_properties(
result["fourcc"] = fourcc result["fourcc"] = fourcc
return result return result
def set_file_limit() -> None:
# Newer versions of containerd 2.X+ impose a very low soft file limit of 1024
# This applies to OSs like HA OS (see https://github.com/home-assistant/operating-system/issues/4110)
# Attempt to increase this limit
soft_limit = int(os.getenv("SOFT_FILE_LIMIT", "65536") or "65536")
current_soft, current_hard = resource.getrlimit(resource.RLIMIT_NOFILE)
logger.info(f"Current file limits - Soft: {current_soft}, Hard: {current_hard}")
new_soft = min(soft_limit, current_hard)
resource.setrlimit(resource.RLIMIT_NOFILE, (new_soft, current_hard))
logger.info(
f"File limit set. New soft limit: {new_soft}, Hard limit remains: {current_hard}"
)