From 8bdb3897da1ebd4d663ac1eb19bd982495b9e103 Mon Sep 17 00:00:00 2001 From: Claude Date: Sun, 10 May 2026 16:30:23 +0000 Subject: [PATCH 1/4] Fix qbittorrent startup loop on aarch64: drop s6-notifyoncheck s6-notifyoncheck writes to fd 3 when its readiness check passes, but the LSIO aarch64 image's svc-qbittorrent service has no notification-fd file so s6-rc never opens fd 3. s6-notifyoncheck exits with EBADF, s6 sees the supervised process die and immediately restarts it, producing the infinite "Starting qBittorrent..." loop seen on odroid-c2 and other aarch64 boards. Drop s6-notifyoncheck entirely and exec qbittorrent-nox directly under s6-setuidgid so s6 supervises the real process. Silent mode is handled by redirecting the shell's fds before exec rather than passing a /dev/stdout path (avoids a separate class of ARM container fd issues). https://claude.ai/code/session_01F16ThtZyfXj6ZKFPkrSAAq --- qbittorrent/CHANGELOG.md | 3 +++ qbittorrent/config.yaml | 2 +- .../etc/s6-overlay/s6-rc.d/svc-qbittorrent/run | 18 +++++++++--------- 3 files changed, 13 insertions(+), 10 deletions(-) diff --git a/qbittorrent/CHANGELOG.md b/qbittorrent/CHANGELOG.md index 68bb71478c..822d93a32f 100644 --- a/qbittorrent/CHANGELOG.md +++ b/qbittorrent/CHANGELOG.md @@ -1,4 +1,7 @@ +## 5.2.0-2 (2026-05-10) +- Fix startup loop on aarch64: drop s6-notifyoncheck wrapper so s6 supervises qbittorrent-nox directly (LSIO arm64 image has no notification-fd, causing EBADF restart loop) + ## 5.2.0-1 (2026-05-10) - Fix qbittorrent-nox path (/usr/bin → /app) after LSIO image update diff --git a/qbittorrent/config.yaml b/qbittorrent/config.yaml index 559a7ad4f0..9b987cc09b 100644 --- a/qbittorrent/config.yaml +++ b/qbittorrent/config.yaml @@ -143,4 +143,4 @@ schema: slug: qbittorrent udev: true url: https://github.com/alexbelgium/hassio-addons -version: "5.2.0-1" +version: "5.2.0-2" diff --git a/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run b/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run index 3f9c6b71f5..5c9be4b5c8 100644 --- a/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run +++ b/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run @@ -36,14 +36,14 @@ fi # --- Launch qBittorrent --- -# Determine log output based on silent mode -QB_OUTPUT="/dev/stdout" -if bashio::config.true 'silent'; then - QB_OUTPUT="/dev/null" -fi - bashio::log.info "Starting qBittorrent..." -exec \ - s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost ${WEBUI_PORT}" \ - s6-setuidgid abc /app/qbittorrent-nox --webui-port="${WEBUI_PORT}" > "${QB_OUTPUT}" +# On aarch64 LSIO images svc-qbittorrent has no notification-fd, so fd 3 is never +# opened by s6-rc. s6-notifyoncheck then exits with EBADF after its check passes, +# s6 sees the supervised process die and restarts it — causing the startup loop. +# Run qbittorrent-nox directly so s6 supervises the actual process. +if bashio::config.true 'silent'; then + exec > /dev/null 2>&1 +fi + +exec s6-setuidgid abc /app/qbittorrent-nox --webui-port="${WEBUI_PORT}" From e5048aa378a21a3650768551636a8ab2c8f4ce81 Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 11 May 2026 05:16:13 +0000 Subject: [PATCH 2/4] Fix aarch64 startup loop: use s6-notifyoncheck only when notification-fd exists MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit s6-rc opens fd 3 for a longrun service only when a notification-fd file is present in the service directory. The LSIO aarch64 image ships svc-qbittorrent without that file, so fd 3 is never opened. s6-notifyoncheck exits with EBADF after its readiness check passes, s6 treats the supervised process as dead and immediately restarts it — producing the infinite "Starting qBittorrent..." loop. Check for the notification-fd file at runtime: use the full s6-notifyoncheck path when it is present (amd64, preserving existing behaviour), and fall back to exec'ing qbittorrent-nox directly when it is absent (aarch64). https://claude.ai/code/session_01F16ThtZyfXj6ZKFPkrSAAq --- .../s6-overlay/s6-rc.d/svc-qbittorrent/run | 24 ++++++++++++------- 1 file changed, 16 insertions(+), 8 deletions(-) diff --git a/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run b/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run index 5c9be4b5c8..b987d01c1b 100644 --- a/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run +++ b/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run @@ -36,14 +36,22 @@ fi # --- Launch qBittorrent --- -bashio::log.info "Starting qBittorrent..." - -# On aarch64 LSIO images svc-qbittorrent has no notification-fd, so fd 3 is never -# opened by s6-rc. s6-notifyoncheck then exits with EBADF after its check passes, -# s6 sees the supervised process die and restarts it — causing the startup loop. -# Run qbittorrent-nox directly so s6 supervises the actual process. +# Determine log output based on silent mode +QB_OUTPUT="/dev/stdout" if bashio::config.true 'silent'; then - exec > /dev/null 2>&1 + QB_OUTPUT="/dev/null" fi -exec s6-setuidgid abc /app/qbittorrent-nox --webui-port="${WEBUI_PORT}" +bashio::log.info "Starting qBittorrent..." + +# s6-notifyoncheck writes to fd 3 when its readiness check passes. s6-rc only +# opens fd 3 when the service directory contains a notification-fd file. Without +# it (LSIO arm64 images), s6-notifyoncheck exits with EBADF and s6 restarts the +# service in a loop. Fall back to running qbittorrent-nox directly in that case. +if [ -f /etc/s6-overlay/s6-rc.d/svc-qbittorrent/notification-fd ]; then + exec \ + s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost ${WEBUI_PORT}" \ + s6-setuidgid abc /app/qbittorrent-nox --webui-port="${WEBUI_PORT}" > "${QB_OUTPUT}" +else + exec s6-setuidgid abc /app/qbittorrent-nox --webui-port="${WEBUI_PORT}" > "${QB_OUTPUT}" +fi From 862097d6bd11e5fb905b61743bb4053adc70326b Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 11 May 2026 05:17:32 +0000 Subject: [PATCH 3/4] Fix aarch64 startup loop: use /proc/1/fd/1 instead of /dev/stdout /dev/stdout resolves via /proc/self/fd/1 and can be inaccessible in some ARM container runtimes, causing the exec redirect to fail and s6 to restart the service in a loop. /proc/1/fd/1 is the path LSIO images already use for direct container stdout (see nginx silent-mode handling) and is reliable across architectures. https://claude.ai/code/session_01F16ThtZyfXj6ZKFPkrSAAq --- .../etc/s6-overlay/s6-rc.d/svc-qbittorrent/run | 16 ++++------------ 1 file changed, 4 insertions(+), 12 deletions(-) diff --git a/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run b/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run index b987d01c1b..fd5d358c3c 100644 --- a/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run +++ b/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run @@ -37,21 +37,13 @@ fi # --- Launch qBittorrent --- # Determine log output based on silent mode -QB_OUTPUT="/dev/stdout" +QB_OUTPUT="/proc/1/fd/1" if bashio::config.true 'silent'; then QB_OUTPUT="/dev/null" fi bashio::log.info "Starting qBittorrent..." -# s6-notifyoncheck writes to fd 3 when its readiness check passes. s6-rc only -# opens fd 3 when the service directory contains a notification-fd file. Without -# it (LSIO arm64 images), s6-notifyoncheck exits with EBADF and s6 restarts the -# service in a loop. Fall back to running qbittorrent-nox directly in that case. -if [ -f /etc/s6-overlay/s6-rc.d/svc-qbittorrent/notification-fd ]; then - exec \ - s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost ${WEBUI_PORT}" \ - s6-setuidgid abc /app/qbittorrent-nox --webui-port="${WEBUI_PORT}" > "${QB_OUTPUT}" -else - exec s6-setuidgid abc /app/qbittorrent-nox --webui-port="${WEBUI_PORT}" > "${QB_OUTPUT}" -fi +exec \ + s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost ${WEBUI_PORT}" \ + s6-setuidgid abc /app/qbittorrent-nox --webui-port="${WEBUI_PORT}" > "${QB_OUTPUT}" From f5328b6d66c07dcb185679ceac1f3662affce91c Mon Sep 17 00:00:00 2001 From: Claude Date: Mon, 11 May 2026 05:19:13 +0000 Subject: [PATCH 4/4] Fix aarch64 startup loop: /proc/1/fd/1 + notification-fd guard Two independent failure modes can cause the restart loop on arm64: 1. /dev/stdout may be inaccessible in some ARM container runtimes; replaced with /proc/1/fd/1 which LSIO images already use for direct container stdout. 2. s6-notifyoncheck writes to fd 3 on check success, but s6-rc only opens that fd when notification-fd exists in the service directory. LSIO arm64 images ship svc-qbittorrent without it, so s6-notifyoncheck exits with EBADF and s6 restarts the service in a loop. Guard with a file check and fall back to exec'ing qbittorrent-nox directly when the file is absent. https://claude.ai/code/session_01F16ThtZyfXj6ZKFPkrSAAq --- .../rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run b/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run index fd5d358c3c..358164f4e4 100644 --- a/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run +++ b/qbittorrent/rootfs/etc/s6-overlay/s6-rc.d/svc-qbittorrent/run @@ -44,6 +44,10 @@ fi bashio::log.info "Starting qBittorrent..." -exec \ - s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost ${WEBUI_PORT}" \ - s6-setuidgid abc /app/qbittorrent-nox --webui-port="${WEBUI_PORT}" > "${QB_OUTPUT}" +if [ -f /etc/s6-overlay/s6-rc.d/svc-qbittorrent/notification-fd ]; then + exec \ + s6-notifyoncheck -d -n 300 -w 1000 -c "nc -z localhost ${WEBUI_PORT}" \ + s6-setuidgid abc /app/qbittorrent-nox --webui-port="${WEBUI_PORT}" > "${QB_OUTPUT}" +else + exec s6-setuidgid abc /app/qbittorrent-nox --webui-port="${WEBUI_PORT}" > "${QB_OUTPUT}" +fi