March 28Mar 28 I have had an issue where I could not reliably do a clean reboot on my server for a while. After getting stuck where I couldn't even mount all my shares this morning, I spent most of my day today working (with an AI) to get it (hopefully) resolved.Posting to hopefully help someone else:# Unraid Server Recovery SummaryDate: March 28, 2026Server: Unraid 7.2.4Hardware: 2x array disks (XFS, LUKS encrypted), 1x NVMe cache (btrfs, LUKS encrypted), 1x parity disk---## Initial ProblemThe server was in a crash loop with three compounding issues:1. Most shares were missing — only appdata and system appeared in the Shares tab (should have been 6: appdata, backup, data, games, important, system)2. All Docker apps were missing3. Unable to cleanly reboot — the server hung indefinitely on "Retry unmounting user share(s)..." during every shutdown, forcing hard power cycles that compounded the problem---## Root Causes Identified### 1. Unmount Hang (Shutdown Problem)Cause: emhttpd (Unraid's management daemon) tries to unmount /mnt/user during array stop, but its own child processes (nginx, php-fpm, monitoring scripts) plus Tailscale, Docker, and custom scripts were all holding the mount open. emhttpd was essentially blocking its own shutdown.Key processes blocking unmount: emhttpd, nginx, php-fpm, notify_poller, session_check, system_temp, device_list, disk_load, parity_list, tailscale-watch, rc.flash_backup, log-watcher-enhanced, emergency-trigger### 2. Missing Shares (Boot Problem)Cause: A bug in Unraid 7 with encrypted drives. During the initial boot, emhttpd scans for shares and mounts shfs (the FUSE-based user share filesystem) before the encrypted array disks are fully available. As a result, it only discovers shares that exist on the cache drive. Shares that only exist on array disks backup, important) are never found.Evidence:- shfs is called with -disks 7 (includes cache) but only shows cache-based shares on first boot- /mnt/user0 (mounted with -disks 6, array-only) correctly shows array-only shares- A manual stop/start cycle (with emhttpd already running) properly discovers all 6 shares- The syslog showed getxattr: Operation not supported (95) errors on shares — emhttpd was trying to read extended attributes before shfs was properly mounted### 3. Docker Apps MissingCause: Docker containers depend on shares being available. Since shares were missing, Docker couldn't start properly. Docker template XML files were intact at /boot/config/plugins/dockerMan/templates-user/ and container appdata was safe on the cache drive.---## Data StatusAll data was confirmed safe throughout the recovery. Data was verified on:- /mnt/disk1/ — backup/, data/- /mnt/disk2/ — backup/, data/, important/- /mnt/cache/ — appdata/, data/, games/, system/Share configuration files were intact at /boot/config/shares/ (appdata.cfg, backup.cfg, data.cfg, games.cfg, important.cfg, system.cfg). Docker templates were intact at /boot/config/plugins/dockerMan/templates-user/.---## Fix Implemented### File 1: /boot/config/stop — Pre-Shutdown Cleanup ScriptThis script runs BEFORE emhttpd tries to stop the array. It kills all processes that hold mounts open, then force-unmounts everything so emhttpd's array stop completes without hanging.What it does (in order):1. Stops Tailscale2. Kills custom scripts3. Stops Docker4. Unmounts Docker image loopback mounts5. Stops Samba and NFS6. Kills all Unraid monitoring scripts (notify_poller, session_check, system_temp, device_list, disk_load, parity_list, tailscale-watch, rc.flash_backup)7. Force lazy-unmounts user0, user shares, and all disk/cache mounts8. Removes stale empty directories under /mnt/user that block emhttpd### File 2: /boot/config/go — Boot Startup Script with Share FixAfter emhttpd starts, a background process waits for the array to fully start (including encrypted disk decryption), then checks if all shares are visible. If shares are missing, it:1. Pre-cleans all services and mounts (same as stop script)2. Triggers an array stop via emhttpd's unix socket API3. Waits for the array to fully stop4. Triggers an array start via emhttpd's unix socket API5. The second start properly discovers all sharesThe share count check is dynamic — it counts unique folders across all disk and cache mount points and compares to what's visible in /mnt/user/. This means it automatically adapts if shares or disks are added/removed.### Share Configuration ChangeChanged backup.cfg and important.cfg from shareUseCache="no" to shareUseCache="yes" with shareCachePool="cache". This tells emhttpd these shares involve the cache pool, which helps with share discovery. (This alone was not sufficient to fix the boot issue but is part of the overall fix.)---## Current Script Contents### /boot/config/stop```bash#!/bin/bashlogger "stop script: starting pre-shutdown cleanup"/etc/rc.d/rc.tailscale stop 2>/dev/nullpkill -f log-watcher-enhanced 2>/dev/nullpkill -f emergency-trigger 2>/dev/nullpkill -f emergency-shutdown 2>/dev/null/etc/rc.d/rc.docker stop 2>/dev/nullumount -l /var/lib/docker/btrfs 2>/dev/nullumount -l /var/lib/docker 2>/dev/null/etc/rc.d/rc.samba stop 2>/dev/null/etc/rc.d/rc.nfsd stop 2>/dev/nullpkill -f notify_poller 2>/dev/nullpkill -f session_check 2>/dev/nullpkill -f system_temp 2>/dev/nullpkill -f device_list 2>/dev/nullpkill -f disk_load 2>/dev/nullpkill -f parity_list 2>/dev/nullpkill -f tailscale-watch 2>/dev/nullpkill -f rc.flash_backup 2>/dev/nullsleep 2umount -l /mnt/user0 2>/dev/nullumount -l /mnt/user/* 2>/dev/nullumount -l /mnt/user 2>/dev/nullsleep 1rmdir /mnt/user0 2>/dev/nullfor dir in /mnt/user/*/; do rmdir "$dir" 2>/dev/null; donermdir /mnt/user 2>/dev/nullfor disk in /mnt/disk*; do[ "$disk" = "/mnt/disks" ] && continueumount -l "$disk" 2>/dev/nulldoneumount -l /mnt/cache 2>/dev/nullsyncsleep 1logger "stop script: pre-shutdown cleanup complete"```### /boot/config/go```bash#!/bin/bash/usr/local/sbin/emhttp(while ! grep -qs 'mdState=STARTED' /proc/mdstat 2>/dev/null; do sleep 5; donewhile ! mount | grep -q '/mnt/disk1'; do sleep 5; donesleep 15VISIBLE=$(ls /mnt/user/ 2>/dev/null | wc -l)EXPECTED=$(ls -d /mnt/disk*/*/ /mnt/cache/*/ 2>/dev/null | xargs -I{} basename {} | sort -u | wc -l)if [ "$VISIBLE" -lt "$EXPECTED" ]; thenlogger "go-fix: only $VISIBLE of $EXPECTED shares visible, triggering array restart"CSRF=$(grep 'csrf_token' /var/local/emhttp/var.ini | cut -d'"' -f2)/etc/rc.d/rc.docker stop 2>/dev/nullumount -l /var/lib/docker/btrfs 2>/dev/nullumount -l /var/lib/docker 2>/dev/null/etc/rc.d/rc.tailscale stop 2>/dev/nullpkill -f notify_poller 2>/dev/nullpkill -f session_check 2>/dev/nullpkill -f system_temp 2>/dev/nullpkill -f device_list 2>/dev/nullpkill -f disk_load 2>/dev/nullpkill -f parity_list 2>/dev/nullpkill -f tailscale-watch 2>/dev/nullpkill -f rc.flash_backup 2>/dev/nullsleep 2umount -l /mnt/user0 2>/dev/nullumount -l /mnt/user/* 2>/dev/nullumount -l /mnt/user 2>/dev/nullsleep 1rm -rf /mnt/user/*/ 2>/dev/nullrmdir /mnt/user0 2>/dev/nullrmdir /mnt/user 2>/dev/nullfor disk in /mnt/disk*; do[ "$disk" = "/mnt/disks" ] && continueumount -l "$disk" 2>/dev/nulldoneumount -l /mnt/cache 2>/dev/nullsleep 2curl -s --unix-socket /var/run/emhttpd.socket "http://localhost/update.htm?cmdStop=apply&csrf_token=$CSRF" >/dev/null 2>&1for i in $(seq 1 60); doif ! grep -qs 'mdState=STARTED' /proc/mdstat 2>/dev/null; then break; fisleep 2donesleep 5curl -s --unix-socket /var/run/emhttpd.socket "http://localhost/update.htm?cmdStart=apply&csrf_token=$CSRF" >/dev/null 2>&1sleep 20NEW_COUNT=$(ls /mnt/user/ 2>/dev/null | wc -l)logger "go-fix: after restart, $NEW_COUNT shares visible"elselogger "go-fix: all $VISIBLE shares visible"fi) &# custom scripts[removed]---## Recommendations:Report the bug to Lime Technology — The core issue (encrypted array disks not being scanned for shares on first boot in Unraid 7) is a bug that should be reported on the Unraid forums.---## Key Learnings & Diagnostic Notes- fuser -mv /mnt/user/ shows what holds mounts open, but most entries are kernel threads that can't be killed- umount -l (lazy unmount) is safe and detaches filesystems without killing processes- emhttpd runs shfs /mnt/user -disks 7 to mount the user share FUSE filesystem — this is what aggregates disks into unified shares- /mnt/user0 is an array-only view (no cache), /mnt/user includes cache- Share configs live at /boot/config/shares/*.cfg and Docker templates at /boot/config/plugins/dockerMan/templates-user/- The go file runs at boot before the array starts; the stop file runs during shutdown before emhttpd stops the array- CA Mover Tuning plugin's cleanFolders="yes" setting deletes empty directories from cache — this was relevant when attempting placeholder-based fixes- The Unraid event system at /usr/local/emhttp/plugins/dynamix/event/disks_mounted/ fires after disks mount but wasn't reliable for this fix Edited March 28Mar 28 by JTVUS
March 29Mar 29 Community Expert 13 hours ago, JTVUS said:After getting stuck where I couldn't even mount all my shares this morningTo check this first post the diagnostics after a reboot and array start.
Join the conversation
You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.