From 3bda638678fd8b33f93954a353660b48b3152efc Mon Sep 17 00:00:00 2001 From: Josh Hawkins <32435876+hawkeye217@users.noreply.github.com> Date: Fri, 11 Jul 2025 08:11:35 -0500 Subject: [PATCH] Set ulimit with Python (#19105) * Set ulimit with python instead of in s6 startup * move to services and add env var * add comment --- .../rootfs/etc/s6-overlay/s6-rc.d/frigate/run | 1 - .../rootfs/usr/local/ulimit/set_ulimit.sh | 57 ------------------- frigate/app.py | 4 ++ frigate/util/services.py | 17 ++++++ 4 files changed, 21 insertions(+), 58 deletions(-) delete mode 100755 docker/main/rootfs/usr/local/ulimit/set_ulimit.sh diff --git a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run index a42afe300..e4a1b20e5 100755 --- a/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run +++ b/docker/main/rootfs/etc/s6-overlay/s6-rc.d/frigate/run @@ -50,7 +50,6 @@ function set_libva_version() { echo "[INFO] Preparing Frigate..." migrate_db_path set_libva_version -/usr/local/ulimit/set_ulimit.sh echo "[INFO] Starting Frigate..." cd /opt/frigate || echo "[ERROR] Failed to change working directory to /opt/frigate" diff --git a/docker/main/rootfs/usr/local/ulimit/set_ulimit.sh b/docker/main/rootfs/usr/local/ulimit/set_ulimit.sh deleted file mode 100755 index fd172735f..000000000 --- a/docker/main/rootfs/usr/local/ulimit/set_ulimit.sh +++ /dev/null @@ -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 \ No newline at end of file diff --git a/frigate/app.py b/frigate/app.py index 02955b6c9..23facba40 100644 --- a/frigate/app.py +++ b/frigate/app.py @@ -71,6 +71,7 @@ from frigate.timeline import TimelineProcessor from frigate.util.builtin import empty_and_close_queue from frigate.util.image import SharedMemoryFrameManager, UntrackedSharedMemory from frigate.util.object import get_camera_regions_grid +from frigate.util.services import set_file_limit from frigate.version import VERSION from frigate.video import capture_camera, track_camera from frigate.watchdog import FrigateWatchdog @@ -587,6 +588,9 @@ class FrigateApp: # Ensure global state. self.ensure_dirs() + # Set soft file limits. + set_file_limit() + # Start frigate services. self.init_camera_metrics() self.init_queues() diff --git a/frigate/util/services.py b/frigate/util/services.py index 2fd701298..cb573a331 100644 --- a/frigate/util/services.py +++ b/frigate/util/services.py @@ -5,6 +5,7 @@ import json import logging import os import re +import resource import signal import subprocess as sp import traceback @@ -632,3 +633,19 @@ async def get_video_properties( result["fourcc"] = fourcc 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}" + )