diff --git a/README-User_Script_Plug-in.md b/README-User_Script_Plug-in.md index 9e7ff75..1d54f11 100644 --- a/README-User_Script_Plug-in.md +++ b/README-User_Script_Plug-in.md @@ -155,10 +155,11 @@ auto-flip to SSD, missing transcoding-temp → recreate immediately. **Output when healthy:** session list only — no flip messages = ramdisk managing fine -> ⚠️ The Emby Docker container must have -> `--mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared` -> in Extra Parameters. Without `shared` propagation, symlink flips are silently -> ignored after the first flip and all sessions land permanently on SSD. +> ⚠️ The Emby/Jellyfin Docker container must have +> `--mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode` +> in Extra Parameters. Do **not** add `bind-propagation=shared` — runc v1.3.5+ +> (Docker 29.x, Unraid 7.3+) rejects it with a mountinfo error. The ramdisk tmpfs +> is already MS\_SHARED at the kernel level — propagation is inherited automatically. --- diff --git a/README.md b/README.md index 079729a..0ade8ad 100644 --- a/README.md +++ b/README.md @@ -702,17 +702,17 @@ unRAID forum posts, community applications templates, and most search results. **Why it breaks here:** -1. `--runtime=nvidia` combined with `NVIDIA_VISIBLE_DEVICES` conflicts with - `bind-propagation=shared` on unRAID 7.2.5+. A kernel change in mount namespace - initialization exposed a conflict between the NVIDIA device mount phase and shared - propagation setup. The container fails to start with: +1. `--runtime=nvidia` combined with `NVIDIA_VISIBLE_DEVICES` has caused conflicts + historically and breaks on container rebuilds. With Docker 29.x (Unraid 7.3+), + `bind-propagation=shared` crashes runc v1.3.5 entirely — with any container, + GPU or not. The container fails to start with: ``` OCI runtime create failed: unable to start container process: error jailing process inside rootfs: open /proc/self/mountinfo: no such file or directory ``` - This system uses `bind-propagation=shared` for the transcode ramdisk mount. - Emby and Jellyfin both require it. The old nvidia method makes them incompatible. + The ramdisk tmpfs is already MS\_SHARED at the kernel level. Do not use + `bind-propagation=shared` in Extra Parameters on Unraid 7.3+. 2. When unRAID rebuilds a container from template (update, reinstall from Community Applications), the `--runtime=nvidia` field and the NVIDIA env vars can be dropped @@ -723,13 +723,13 @@ unRAID forum posts, community applications templates, and most search results. ```bash # DO THIS — everything in Extra Parameters, nothing in Variables ---gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared +--gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode ``` `--gpus "device=UUID"` is Docker-native GPU support (Docker 19.03+, released 2019). One field in Extra Parameters. The UUID pins a specific device — no ambiguity on -single-GPU systems. No env vars needed. No `--runtime=nvidia`. No conflict with -`bind-propagation=shared`. Survives container rebuilds. This is the correct method. +single-GPU systems. No env vars needed. No `--runtime=nvidia`. Survives container +rebuilds. This is the correct method. Find your GPU UUID: `nvidia-smi -L` @@ -836,13 +836,13 @@ Things that are different from what you might expect: # HOST1 and HOST2 — no branching on server identity inside scripts. # 6. GPU containers: ignore every Google result. Use --gpus, not --runtime=nvidia. -# --runtime=nvidia conflicts with bind-propagation=shared on unRAID 7.2.5+. -# It also breaks on container rebuilds. See GPU CONTAINERS section above. +# --runtime=nvidia breaks on container rebuilds. See GPU CONTAINERS section above. -# 7. The Emby Docker mount is unusual and critical. -# --mount type=bind,...,bind-propagation=shared in Extra Parameters — not a -# standard path mapping. Without shared propagation symlink flips are silently -# ignored. README-Transcoding.md explains why in detail. +# 7. The Emby/Jellyfin Docker mount is unusual and critical. +# --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode +# in Extra Parameters — not a standard path mapping. Do NOT add bind-propagation=shared: +# runc v1.3.5+ (Docker 29.x, Unraid 7.3+) rejects it. The ramdisk is already +# MS_SHARED at the kernel level. README-Transcoding.md explains in detail. # 8. arr cleanup scripts can delete files. # lidarr_cleanup.sh, sonarr_cleanup.sh, radarr_cleanup.sh permanently delete diff --git a/Transcodes/Manual-Transcoding.md b/Transcodes/Manual-Transcoding.md index 32cd9be..a0a040d 100644 --- a/Transcodes/Manual-Transcoding.md +++ b/Transcodes/Manual-Transcoding.md @@ -45,18 +45,22 @@ suppressed. ### Required Mount Everything goes in the unRAID Docker template **Extra Parameters** field. Do NOT use the -path mapping UI for the transcode directory — it does not support `bind-propagation`. +path mapping UI for the transcode directory — it does not support `--mount` syntax. **Non-GPU containers:** ``` ---mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared +--mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode ``` **GPU-accelerated containers (Emby, Jellyfin with NVENC/NVDEC):** ``` ---gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared +--gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode ``` +> ⚠️ **Unraid 7.3+ / Docker 29.x / runc v1.3.5+:** Do NOT add `bind-propagation=shared`. +> runc v1.3.5 crashes on it with `open /proc/self/mountinfo: no such file or directory`. +> The ramdisk tmpfs is already `MS_SHARED` at the kernel level — propagation is automatic. + Replace the UUID with your GPU's UUID (`nvidia-smi -L` to find it). In Emby and Jellyfin's transcoding settings, set the transcode path to `/ext-ram-transcode`. @@ -70,39 +74,37 @@ There are two ways to give a container GPU access. **Always use `--gpus`.** at the Docker daemon level and spreads across multiple XML fields (runtime flag + `NVIDIA_VISIBLE_DEVICES` env var + `NVIDIA_DRIVER_CAPABILITIES` env var). When unRAID rebuilds a container from template (update, reinstall) these fields can break or get dropped -— requiring manual XML repair to recover. `--runtime=nvidia` combined with -`NVIDIA_VISIBLE_DEVICES` also conflicts with `bind-propagation=shared` on unRAID 7.2.5+ -due to a kernel change in mount namespace initialization (see -[Troubleshooting](#emby-with-nvidia-gpu--bind-propagationshared-fails-to-start) for the -full error and fix). +— requiring manual XML repair to recover. `--runtime=nvidia` combined with `NVIDIA_VISIBLE_DEVICES` breaks on container rebuilds +and has historically conflicted with bind mount propagation settings. `--gpus "device=UUID"` is Docker-native GPU support (Docker 19.03+). One field in Extra Parameters. Pins a specific GPU by UUID — no ambiguity on a single-GPU system. Survives -container rebuilds cleanly. Does not conflict with `bind-propagation=shared`. +container rebuilds cleanly. **HOST1 GPU UUID (Quadro P2000):** `GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1` -### Why `shared` Is Required +### Mount Propagation — Unraid 7.3+ / Docker 29.x -``` -rprivate (Docker's default): - Docker resolves the symlink target at first mount and locks that inode. - Flip: ramdisk → SSD → works (new target locked in) - Flip: SSD → ramdisk → Docker ignores it. Container still sees SSD binding. - All sessions continue to land on SSD forever until Emby restarts. - Symptom: symlink on host is correct, Emby still uses SSD. Confusing. +> **Do NOT use `bind-propagation=shared`** on Unraid 7.3+ (Docker 29.x / runc v1.3.5+). +> runc v1.3.5 rejects it with `open /proc/self/mountinfo: no such file or directory` and +> the container fails to start. This applies to all containers — GPU and non-GPU alike. -shared: - Host mount changes propagate into the container in real time. - Every symlink flip is immediately visible inside the container. ✅ -``` +The ramdisk tmpfs is mounted `MS_SHARED` at the kernel level (`shared:N` in +`/proc/self/mountinfo`). Bind mounts from it inherit shared propagation automatically — +specifying it in Docker is redundant and breaks on runc v1.3.5+. + +**Historical context (Unraid ≤ 7.2.5):** `bind-propagation=shared` was required +because Docker's default `rprivate` resolves the symlink target at mount time and locks +that inode, making subsequent flips invisible to the container. On Unraid 7.3+ this +option crashes container start entirely. The ramdisk's kernel-level MS_SHARED makes it +unnecessary. ### Verify the Mount ```bash -# Check propagation — must show "shared": +# Check the mount is present: docker inspect Emby | grep -A4 "ext-ram" -# Expected: "Propagation": "shared" +# Expected: "Destination": "/ext-ram-transcode" # Check Emby's transcode path setting: docker exec Emby cat /config/config/encoding.xml | grep TranscodingTempPath @@ -417,17 +419,18 @@ Do NOT schedule transcode_manager.sh or transcode_cleanup.sh directly. ### Sessions Landing on SSD Despite Symlink Pointing at Ramdisk ```bash -# Check 1 — Docker mount propagation (most common cause): -docker inspect Emby | grep Propagation -# Expected: "Propagation": "shared" -# Wrong: "Propagation": "rprivate" +# Check 1 — Docker mount is present: +docker inspect Emby | grep -A4 "ext-ram" +# Expected: "Destination": "/ext-ram-transcode" +# Wrong: no ext-ram-transcode entry # # Fix: Update Emby Extra Parameters, restart Emby. # GPU containers (full string): -# --gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared +# --gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode # Non-GPU (mount only): -# --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared +# --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode # Remove any standard path mapping for the transcode directory. +# Do NOT add bind-propagation=shared — runc v1.3.5+ (Docker 29.x, Unraid 7.3+) rejects it. # Check 2 — transcoding-temp exists on ramdisk: ls /mnt/ramdisk_transcodes/ @@ -505,8 +508,8 @@ leave the container in a broken state where Emby refuses to start at all. # 1. Remove the entire Extra Parameters line from Emby in unRAID Docker UI # 2. Start Emby and wait for it to fully load (check the WebUI is responsive) # 3. Add the full Extra Parameters line back: -# GPU: --gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared -# Non-GPU: --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared +# GPU: --gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode +# Non-GPU: --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode # 4. Save changes and restart Emby # # The container starts cleanly without the mount, which clears the broken state. @@ -587,13 +590,10 @@ assign. Always confirm VRAM is actually free before troubleshooting container GP --- -### Emby With NVIDIA GPU — bind-propagation=shared Fails to Start +### Container Fails to Start — open /proc/self/mountinfo: no such file or directory -> **Regression:** This worked before unRAID 7.2.5. The kernel update changed how mount -> namespaces are initialized, exposing a conflict in the NVIDIA container runtime path. - -`--runtime=nvidia` combined with a `NVIDIA_VISIBLE_DEVICES` environment variable conflicts -with `bind-propagation=shared`. Docker fails during container init with: +> **Unraid 7.3+ / Docker 29.x / runc v1.3.5+** — any container with `bind-propagation=shared` +> in Extra Parameters crashes with this error. Not GPU-specific — affects all containers. ``` OCI runtime create failed: runc create failed: unable to start container process: @@ -601,28 +601,24 @@ error during container init: error jailing process inside rootfs: open /proc/self/mountinfo: no such file or directory ``` -`--runtime=nvidia` alone (no `NVIDIA_VISIBLE_DEVICES` env var) does NOT cause this. -The conflict requires both. +**Root cause:** runc v1.3.5 tries to read `/proc/self/mountinfo` inside the new mount +namespace before `/proc` is mounted, crashing when `bind-propagation=shared` is present. -**Root cause:** `NVIDIA_VISIBLE_DEVICES` triggers the NVIDIA container runtime to bind -mount CUDA libraries and device nodes into the container namespace. This GPU device setup -interferes with the mount namespace initialization that `bind-propagation=shared` requires. +**Fix:** Remove `bind-propagation=shared` from Extra Parameters entirely. -**Fix — replace the NVIDIA env var approach with the `--gpus` flag:** +In the unRAID Docker template: -In the unRAID Docker template for Emby: - -1. **Extra Parameters** — remove `--runtime=nvidia`, replace with the full line: +1. **Extra Parameters** — remove `bind-propagation=shared` from the `--mount` option: ``` - --gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared + --gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode ``` -2. **Variables** — remove the `NVIDIA_VISIBLE_DEVICES` variable entirely. - The `--gpus` flag handles GPU assignment without the env var. +2. The ramdisk tmpfs is already `MS_SHARED` at the kernel level (`shared:N` in + `/proc/self/mountinfo`). Propagation is inherited automatically — no Docker flag needed. -`--gpus "device=UUID"` uses Docker's native GPU device flag (default runtime) rather than -the full NVIDIA container runtime setup. The container still gets GPU access; it just -skips the device mount phase that conflicts with `bind-propagation=shared`. +**Historical note:** On Unraid ≤ 7.2.5 (Docker <29.x), `bind-propagation=shared` was +required for symlink flips to propagate into running containers. On Unraid 7.3+ it crashes +container start. The kernel-level MS_SHARED on the tmpfs makes it unnecessary. ### Increasing Ramdisk Size After Initial Setup diff --git a/Transcodes/README-Transcoding.md b/Transcodes/README-Transcoding.md index 2176d9c..433a59f 100644 --- a/Transcodes/README-Transcoding.md +++ b/Transcodes/README-Transcoding.md @@ -6,16 +6,15 @@ without interrupting anything already playing. When pressure drops, new sessions back to RAM. > **Three configuration requirements that are not obvious and were all discovered the -> hard way in production.** The Docker mount must use `bind-propagation=shared` or -> symlink flips are silently ignored after the first flip. The `transcoding-temp` -> directory must be pre-created on the ramdisk or Emby finds the SSD version and -> routes all sessions there until restarted. GPU containers require `--gpus "device=UUID"` -> in Extra Parameters — not `--runtime=nvidia` — or the container fails to start after -> unRAID 7.2.5. Additionally: any GPU-accelerated sidecar (OCR plugins, credit detection) -> that holds VRAM and never releases it will starve Emby and Jellyfin of VRAM for -> transcoding — Jellyfin hard-fails, Emby silently falls back to CPU. Emby's startup -> NVIDIA probe is one-shot: if VRAM is exhausted when the container starts, NVIDIA stays -> disabled for the entire session. All three are documented in Manual-Transcoding.md. +> hard way in production.** The `transcoding-temp` directory must be pre-created on +> the ramdisk or Emby finds the SSD version and routes all sessions there until +> restarted. GPU containers require `--gpus "device=UUID"` in Extra Parameters — +> not `--runtime=nvidia`. Do **not** use `bind-propagation=shared` on Unraid 7.3+ +> (Docker 29.x / runc v1.3.5+) — it crashes container start; the ramdisk is already +> MS\_SHARED at the kernel level. Additionally: any GPU-accelerated sidecar (OCR plugins, +> credit detection) that holds VRAM and never releases it will starve Emby and Jellyfin +> of VRAM for transcoding — Jellyfin hard-fails, Emby silently falls back to CPU. +> All three are documented in Manual-Transcoding.md. --- @@ -24,21 +23,20 @@ back to RAM. > **Stop. Set this before starting Emby or Jellyfin. If you Google how to add GPU > access to a Docker container on unRAID you will find the wrong answer.** Every > forum post and guide shows `--runtime=nvidia` + `NVIDIA_VISIBLE_DEVICES`. That -> method conflicts with `bind-propagation=shared` on unRAID 7.2.5+ and breaks on -> container rebuilds. Use `--gpus` instead. +> method breaks on container rebuilds. Use `--gpus` instead. In the unRAID Docker template, open **Advanced View** and paste the following into the **Extra Parameters** field. Do not use the path mapping UI for the transcode -directory — it does not support `bind-propagation`. +directory — it does not support the `--mount` syntax. **GPU-accelerated (Emby, Jellyfin with NVENC/NVDEC) — use this:** ``` ---gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared +--gpus "device=GPU-62e1659d-1ed4-935f-3df3-4bb4339438f1" --pids-limit=0 --mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode ``` **Non-GPU — use this:** ``` ---mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode,bind-propagation=shared +--mount type=bind,source=/mnt/ram-transcode,target=/ext-ram-transcode ``` In Emby and Jellyfin's transcoding settings, set the transcode temp path to `/ext-ram-transcode`. @@ -66,14 +64,13 @@ Fix: symlink indirection. Emby points at a fixed path. The symlink target change ffmpeg resolves the symlink once at session start — existing sessions are completely unaffected by flips. Only new sessions follow the new target. -**Docker Bind Mount Silently Ignored After First Flip** +**Docker Bind Mount Silently Ignored After First Flip** *(historical — resolved differently)* Symlink flip from ramdisk → SSD worked. Flip back: nothing. All new sessions still land on SSD. The symlink on the host is correct. Emby doesn't see it. -Cause: Docker's default `rprivate` propagation resolves the symlink target at mount time -and locks that inode. Subsequent flips are invisible to the container. -Fix: `bind-propagation=shared` in Extra Parameters. Host mount changes propagate into -the container in real time. Requires `--mount` syntax — the path mapping UI doesn't -support propagation. +Original fix was `bind-propagation=shared` — but this crashes runc v1.3.5+ (Docker 29.x, +Unraid 7.3+) on any container start. The ramdisk tmpfs is `MS_SHARED` at the kernel level, +so propagation is inherited automatically without specifying it in Docker. Do not add +`bind-propagation=shared` to Extra Parameters. **Sessions Drifting to SSD After a Day of Operation** System working correctly for hours, then sessions gradually drift to SSD despite the