[Anleitung] Behebung des Fehlers bei der Initialisierung der Netzwerkkarte beim Start

QNAP QTS Boot-Time LAN Recovery Watchdog

Hardware: QNAP TS-451
OS: QTS 5.2.9 (Build 20260214)
NIC: Dual Intel I210 Gigabit (driver: igb)
Target interface: eth0, static IP 192.168.1.x/24 (where x = the desired static IP address of the NAS. In this excercise x= 6)


Problem Description

The NAS fail to establish LAN connection, or it succeeds only in approximately 9 out of 10 cold boots. After boot completion (confirmed by the final single beep), the network is unreachable, but QTS is running. Connecting a second network cable to LAN port 2 acted as a stimulus to the driver and caused the primary interface to come alive as a side effect. This made it possible to investigate and derive a permanent solution as described in this document.

Root Cause

The Intel igb driver loads correctly at boot and the physical link (carrier) is established on eth0. However, the QTS Network & Virtual Switch service (NVS) fails to apply the static IP configuration to eth0 from its configuration file /etc/config/nm.conf. The result is:

  • eth0 has carrier (physical link up)

  • eth0 has no IP address assigned

  • The NAS is completely unreachable

This was confirmed by inspecting /sys/class/net/eth0/carrier which returns 1 (link present) even in the failed state, while ip addr show eth0 shows no inet address.

Network Configuration

The NAS network configuration is managed by NVS and stored in /etc/config/nm.conf. The relevant section:

[interface0]
ifname = eth0
ip = 192.168.1.x
ip4_type = STATIC
default_gateway = 192.168.1.1
domain_name_server4_1 = 1.1.1.1
domain_name_server4_2 = 8.8.8.8
subnet_mask = 255.255.255.0

Solution

Since the carrier is already up when the failure occurs, the fix requires only a single command to assign the static IP directly to the interface, bypassing NVS entirely:

ip addr add 192.168.1.x/24 dev eth0

Followed by a gratuitous ARP broadcast to announce the new address to all devices on the network:

arping -c 3 -I eth0 192.168.1.x

A watchdog script running at every boot detects the missing IP and applies these two commands automatically.


Critical Implementation Details

Why ip addr add and not NVS or DHCP

Several approaches were investigated and rejected:

  • /etc/init.d/netmgr.sh link_event eth0 up — rejected. NVS returns status=-2 because this call requires a real hardware link-up event transition, not just a carrier-present state.

  • dhclient eth0 — rejected. The IP is statically configured outside the DHCP scope of the router. Calling dhclient would assign a random DHCP address, overwriting the static configuration.

  • modprobe -r igb / modprobe igb — rejected. Unnecessary since carrier is already up. Additionally, both eth0 and eth1 share the same igb driver instance, so evicting the module would drop both interfaces simultaneously.

Direct assignment via ip addr add is the correct, minimal, and dependency-free solution.

Why arping is necessary

After ip addr add, the address is locally valid but the rest of the network has no ARP entry for it. Without a gratuitous ARP broadcast, other devices (router, Windows clients) will have stale or missing ARP table entries and be unable to route packets to the NAS, despite the IP being correctly assigned. The arping -c 3 call sends three broadcast ARP announcements, ensuring all devices on the subnet learn the new address immediately.

Why the health check does not ping the gateway

The NAS has two physical ports on the same 192.168.1.0/24 subnet. When both cables are connected, reply packets from the NAS may egress via eth1 (e.g. 192.168.1.83) instead of eth0 (192.168.1.x), causing the remote host to discard them as arriving from the wrong source address. A gateway ping would therefore succeed via eth1 even when eth0 is broken, producing a false healthy result.

The health check is deliberately limited to verifying that 192.168.1.x/24 is assigned to eth0:

ip -4 addr show eth0 | grep -q "inet 192.168.1.x/24 "

This is unambiguous and cannot produce false results regardless of how many interfaces are active.


File System and Persistence

The QNAP QTS storage hierarchy

Understanding where files persist on QTS is critical to a working deployment:

Path Type Survives reboot Survives firmware upgrade
/usr/local/bin/ Firmware ramdisk No No
/tmp/ RAM No No
/etc/config/ Bind mount → /mnt/HDA_ROOT/.config/ Yes Yes
/mnt/HDA_ROOT/.config/ Data volume (ext4) Yes Yes

All scripts must be stored in /etc/config/ — this is the only location that survives both reboots and firmware upgrades on QNAP QTS 5.x.

The autorun mechanism

QTS executes /tmp/config/autorun.sh during the boot sequence via /etc/init.d/init_nas.sh. The relevant boot sequence logic is:

/bin/mount $DEV_NAS_CONFIG -t ext2 /tmp/config
if [ -f /tmp/config/autorun.sh ]; then
    if [ "`/sbin/getcfg Misc Autorun -d 0`" = "TRUE" ]; then
        /tmp/config/autorun.sh
    fi
fi

Two conditions must both be true for autorun to fire:

  1. /tmp/config/autorun.sh must exist on the config partition

  2. The Misc Autorun setting must be TRUE in QTS config

/tmp/config/ is a direct mount of the raw config partition (/dev/sdc6), separate from the /etc/config/ bind mount. Writing to /etc/config/autorun.sh alone is not sufficient — the file must be written directly to the partition via /tmp/config/.

The config partition

The config partition on the TS-451 is /dev/sdc6. This is hardcoded in both scripts as-is and has been verified to work correctly on this specific hardware.

The partition number 6 is used across many QNAP NAS models running QTS.

  • Some specific models (TS-X16, TS-X28A, TS-XA28A, TS-X33, TS-X35EU) use partition 5
  • ARM-based models use /dev/mtdblock5 — a completely different device type (MTD flash, not a block device)
  • QuTS Hero uses the system device directly without appending a partition number

The device name sdc however is specific to my hardware. It is determined by the system device declared in /etc/config/uLinux.conf:

[System]
System Device = /dev/sdc

On other QNAP models it could be /dev/sda, /dev/sdb, or on newer models with eMMC flash storage, /dev/mmcblk0 (in which case the config partition would be /dev/mmcblk0p6). Also check out this source: create-autorun.sh

Note — portability: The current scripts hardcode /dev/sdc6 and are not intended to be portable. If the scripts are ever ported to a different QNAP NAS model, the config partition device must be verified first. The hardcoded value in both lan_watchdog.sh and install_watchdog.sh is:

CONFIG_PARTITION="/dev/sdc6"

To make this truly generic, replace that hardcoded value with a dynamic lookup in both scripts:

SYSDEV=$(/sbin/getcfg System "System Device" -f /etc/config/uLinux.conf)
CONFIG_PARTITION="${SYSDEV}6"

This reads the system device directly from QTS configuration and appends the partition number, making it correct on any QNAP hardware. This change is not implemented in the current solution and is not required unless the script is ported to a different NAS.

Enabling autorun in QTS

The Misc Autorun setting must be enabled and autorun.sh must contain the watchdog launch command. Both can be handled in a single step via the web UI, or separately via CLI.

Web UI method (simplest):

Navigate to Control Panel → Hardware → General. At the bottom of the page is a checkbox labelled *“Run user defined processes during startup (autorun.sh)”* with a direct link to edit the autorun.sh file inline. Checking the box enables autorun, and the editor allows you to paste the required content directly:

#!/bin/sh
/etc/config/lan_watchdog.sh >> /var/log/lan_watchdog.log 2>&1 &

This approach requires no knowledge of the underlying partition layout, no mounting of /dev/sdc6, and no elevated CLI commands. The web UI writes directly to the correct location on the config partition transparently.

CLI method (used by the current installer):

The installer handles both steps automatically:

  • Mounts /dev/sdc6 and writes autorun.sh directly to the config partition

  • Calls /sbin/setcfg Misc Autorun TRUE to enable the setting

The CLI method is equivalent to the web UI method — both write to the same location on /dev/sdc6.

Permissions

/etc/config/ is owned by admin:administrators with drwxr-xr-x permissions. Regular users cannot write to it directly. Files must be copied using sudo:

sudo cp lan_watchdog.sh /etc/config/lan_watchdog.sh
sudo chmod 755 /etc/config/lan_watchdog.sh

Writing to /tmp/config/ (the raw partition mount) also requires elevated privileges and must be done via sudo tee.


Safety Mechanisms

The watchdog includes three independent safety mechanisms that prevent it from causing harm if something goes wrong.

1. Hard process timeout

The script re-launches itself as a supervised background child. The parent runs a parallel timer and kills the entire child process tree with SIGKILL after 120 seconds if it has not exited. SIGKILL cannot be caught, blocked, or ignored — this makes an infinite loop physically impossible.

2. Persistent strike counter

A strike counter is stored at /etc/config/lan_watchdog_strikes. It is incremented unconditionally at the start of every boot, before any other action. It is only reset to zero when a confirmed successful IP assignment is made. If the hard timeout fires, the strike stays on disk.

After MAX_STRIKES (default: 3) consecutive unsuccessful boots, self-destruct fires.

3. Self-destruct

When the strike limit is reached, the watchdog:

  1. Mounts /dev/sdc6 and removes itself from autorun.sh

  2. Removes the strike counter file

  3. Writes a human-readable post-mortem marker to /etc/config/lan_watchdog_SELFDESTRUCTED

  4. Deletes the installer script

  5. Deletes itself

After self-destruct, the NAS boots completely normally as if the watchdog was never installed. The log file at /var/log/lan_watchdog.log and the marker file are preserved for diagnosis.


Approval Criteria

A boot is considered successful when the following condition is true within the 120-second timeout window:

ip -4 addr show eth0 | grep -q "inet 192.168.1.x/24 "

That is: the exact address 192.168.1.x with prefix length 24 must be assigned to eth0.

A clean boot (NVS applied the IP correctly without watchdog intervention) is confirmed when this condition is true immediately after the 30-second grace period, before any recovery attempt is made.


Final Code

lan_watchdog.sh

#!/bin/sh
# =============================================================================
#  lan_watchdog.sh — LAN boot-time recovery watchdog for QNAP QTS 5.x
# =============================================================================

SCRIPT_TIMEOUT_SECS=120

if [ -z "$WATCHDOG_CHILD" ]; then
    export WATCHDOG_CHILD=1
    "$0" "$@" &
    CHILD_PID=$!

    elapsed=0
    while [ $elapsed -lt $SCRIPT_TIMEOUT_SECS ]; do
        sleep 5
        elapsed=$((elapsed + 5))
        kill -0 "$CHILD_PID" 2>/dev/null || exit 0
    done

    echo "[$(date '+%Y-%m-%d %H:%M:%S')] HARD TIMEOUT: watchdog killed after ${SCRIPT_TIMEOUT_SECS}s" \
        >> /var/log/lan_watchdog.log
    pkill -KILL -P "$CHILD_PID" 2>/dev/null
    kill  -KILL "$CHILD_PID"    2>/dev/null
    exit 1
fi

exec > /dev/null 2>&1

IFACE="eth0"
STATIC_IP="192.168.1.x"
STATIC_PREFIX="24"
STATIC_CIDR="${STATIC_IP}/${STATIC_PREFIX}"

BOOT_GRACE_PERIOD=30
MAX_RETRIES=5
RETRY_INTERVAL=15

LOG_FILE="/var/log/lan_watchdog.log"
MAX_LOG_SIZE=524288

STRIKE_FILE="/etc/config/lan_watchdog_strikes"
MAX_STRIKES=3
SELF_DESTRUCT_MARKER="/etc/config/lan_watchdog_SELFDESTRUCTED"

SCRIPT_DEST="/etc/config/lan_watchdog.sh"
INSTALLER_DEST="/etc/config/install_watchdog.sh"
AUTORUN="/tmp/config/autorun.sh"
CRON_TAG="lan_watchdog"

log() {
    local msg="[$(date '+%Y-%m-%d %H:%M:%S')] $1"
    echo "$msg"
    if [ -f "$LOG_FILE" ]; then
        local sz; sz=$(wc -c < "$LOG_FILE" 2>/dev/null || echo 0)
        [ "$sz" -ge "$MAX_LOG_SIZE" ] && mv "$LOG_FILE" "${LOG_FILE}.old"
    fi
    echo "$msg" >> "$LOG_FILE"
}

has_expected_ip() {
    ip -4 addr show "$IFACE" 2>/dev/null | grep -q "inet ${STATIC_CIDR} "
}

read_strikes() {
    [ -f "$STRIKE_FILE" ] && cat "$STRIKE_FILE" 2>/dev/null | tr -dc '0-9' || echo 0
}
write_strikes()     { echo "$1" > "$STRIKE_FILE"; }
clear_strikes()     { write_strikes 0; log "Strike counter cleared — IP confirmed on $IFACE."; }
increment_strikes() {
    local n; n=$(read_strikes)
    n=$((n + 1))
    write_strikes "$n"
    echo "$n"
}

self_destruct() {
    local reason="$1"

    log "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"
    log "!! SELF-DESTRUCT TRIGGERED"
    log "!! Reason : $reason"
    log "!! Removing all watchdog hooks and files."
    log "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"

    sudo mount -t ext2 /dev/sdc6 /tmp/config 2>/dev/null
    if [ -f "$AUTORUN" ]; then
        grep -v "$CRON_TAG" "$AUTORUN" > "${AUTORUN}.tmp" 2>/dev/null \
            && mv "${AUTORUN}.tmp" "$AUTORUN" \
            && log "  [SD 1/4] Cleaned $AUTORUN" \
            || log "  [SD 1/4] WARN: Could not edit $AUTORUN"
    fi
    sudo umount /tmp/config 2>/dev/null

    rm -f "$STRIKE_FILE" 2>/dev/null
    log "  [SD 2/4] Strike file removed"

    cat > "$SELF_DESTRUCT_MARKER" << EOF
LAN Watchdog self-destructed
=============================
Time    : $(date)
Reason  : $reason
Log     : $LOG_FILE
Strikes : $MAX_STRIKES consecutive failed/timed-out boot cycles

To reinstall after fixing the underlying NIC problem:
  1. Copy lan_watchdog.sh and install_watchdog.sh back to the NAS
  2. sh /etc/config/install_watchdog.sh
EOF
    log "  [SD 3/4] Marker written → $SELF_DESTRUCT_MARKER"

    rm -f "$INSTALLER_DEST" 2>/dev/null
    rm -f "$SCRIPT_DEST" 2>/dev/null
    log "  [SD 4/4] Watchdog fully removed. Normal boot resumes next restart."
    log "!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!"

    exit 0
}

reinit_lan() {
    log "--- Recovery: assigning $STATIC_CIDR to $IFACE ---"

    local existing
    existing=$(ip -4 addr show "$IFACE" 2>/dev/null | awk '/inet /{print $2}')
    if [ -n "$existing" ]; then
        log "  Flushing existing address(es): $existing"
        ip addr flush dev "$IFACE" 2>/dev/null
    fi

    log "  ip addr add $STATIC_CIDR dev $IFACE"
    if ! ip addr add "$STATIC_CIDR" dev "$IFACE" 2>/dev/null; then
        log "  ERROR: ip addr add failed"
        return 1
    fi

    ip link set "$IFACE" up 2>/dev/null

    log "  arping: broadcasting $STATIC_IP on $IFACE"
    arping -c 3 -I "$IFACE" "$STATIC_IP" >/dev/null 2>&1

    log "--- Recovery complete ---"
}

log "========================================================"
log " LAN Watchdog  |  PID $$  |  $(date)"
log " Interface     : $IFACE  →  $STATIC_CIDR"
log " Hard timeout  : ${SCRIPT_TIMEOUT_SECS}s  |  Max strikes: $MAX_STRIKES"
log "========================================================"

if [ ! -d "/sys/class/net/$IFACE" ]; then
    log "FATAL: $IFACE not found — aborting (no strike recorded)."
    exit 1
fi

STRIKES=$(increment_strikes)
log "Strike counter: $STRIKES / $MAX_STRIKES"

if [ "$STRIKES" -ge "$MAX_STRIKES" ]; then
    self_destruct "Strike limit reached: $STRIKES consecutive unsuccessful/timed-out boots"
fi

log "Waiting ${BOOT_GRACE_PERIOD}s for normal boot to settle..."
sleep "$BOOT_GRACE_PERIOD"

if has_expected_ip; then
    log "LAN is healthy — $STATIC_CIDR is already assigned to $IFACE."
    clear_strikes
    exit 0
fi

log "$STATIC_IP is NOT assigned to $IFACE — entering recovery loop."

attempt=0
while [ $attempt -lt $MAX_RETRIES ]; do
    attempt=$((attempt + 1))
    log ""
    log "Recovery attempt $attempt / $MAX_RETRIES"

    reinit_lan

    if has_expected_ip; then
        log ""
        log "SUCCESS on attempt $attempt — $STATIC_CIDR is now assigned to $IFACE."
        clear_strikes
        exit 0
    else
        log "  IP not yet assigned after attempt $attempt."
        [ $attempt -lt $MAX_RETRIES ] && { log "  Waiting ${RETRY_INTERVAL}s..."; sleep "$RETRY_INTERVAL"; }
    fi
done

log ""
log "FAILED: Could not assign $STATIC_IP to $IFACE after $MAX_RETRIES attempts."
log "Strike $STRIKES remains on disk. Self-destruct triggers at strike $MAX_STRIKES."
exit 1

install_watchdog.sh

#!/bin/sh
# =============================================================================
#  install_watchdog.sh — Installs lan_watchdog.sh on QNAP QTS 5.x
# =============================================================================

SCRIPT_SRC="$(dirname "$0")/lan_watchdog.sh"
SCRIPT_DEST="/etc/config/lan_watchdog.sh"
INSTALLER_DEST="/etc/config/install_watchdog.sh"
CONFIG_PARTITION="/dev/sdc6"
AUTORUN="/tmp/config/autorun.sh"
STRIKE_FILE="/etc/config/lan_watchdog_strikes"
SELF_DESTRUCT_MARKER="/etc/config/lan_watchdog_SELFDESTRUCTED"

IFACE="eth0"
STATIC_IP="192.168.1.x"
STATIC_CIDR="${STATIC_IP}/24"

echo "=== LAN Watchdog Installer ==="
echo ""

[ ! -f "$SCRIPT_SRC" ] && { echo "ERROR: $SCRIPT_SRC not found. Run from same directory."; exit 1; }

if [ -f "$SELF_DESTRUCT_MARKER" ]; then
    echo "NOTICE: A previous self-destruct marker was found at:"
    echo "        $SELF_DESTRUCT_MARKER"
    echo "        Fix the underlying NIC issue before reinstalling."
    echo ""
    printf "Continue reinstall anyway? [y/N] "
    read -r ans
    case "$ans" in [yY]*) ;; *) echo "Aborted."; exit 0 ;; esac
    rm -f "$SELF_DESTRUCT_MARKER"
    echo ""
fi

rm -f "$STRIKE_FILE" 2>/dev/null
echo "[1/4] Strike counter reset"

sudo cp "$SCRIPT_SRC" "$SCRIPT_DEST" && sudo chmod 755 "$SCRIPT_DEST"
echo "[2/4] Installed $SCRIPT_DEST"
sudo cp "$0" "$INSTALLER_DEST" && sudo chmod 755 "$INSTALLER_DEST"
echo "[2/4] Installed $INSTALLER_DEST"

echo "[3/4] Writing autorun.sh to config partition ($CONFIG_PARTITION)..."
sudo mount -t ext2 "$CONFIG_PARTITION" /tmp/config 2>/dev/null

if grep -q "lan_watchdog" "$AUTORUN" 2>/dev/null; then
    echo "      autorun.sh entry already present — skipped"
else
    echo '#!/bin/sh' | sudo tee "$AUTORUN" > /dev/null
    echo '/etc/config/lan_watchdog.sh >> /var/log/lan_watchdog.log 2>&1 &' | sudo tee -a "$AUTORUN" > /dev/null
    sudo chmod +x "$AUTORUN"
    echo "      autorun.sh written successfully"
fi
sudo umount /tmp/config 2>/dev/null

sudo /sbin/setcfg Misc Autorun TRUE
echo "[4/4] Autorun enabled in QTS config"

echo ""
echo "Current NIC status:"
CARRIER=$(cat "/sys/class/net/$IFACE/carrier" 2>/dev/null || echo "?")
IP=$(ip -4 addr show "$IFACE" 2>/dev/null | awk '/inet /{print $2}' | head -1)
DRV=""
[ -L "/sys/class/net/$IFACE/device/driver" ] && \
    DRV=$(basename "$(readlink -f "/sys/class/net/$IFACE/device/driver")" 2>/dev/null)

echo "  Interface   : $IFACE"
echo "  Driver      : ${DRV:-not detected}"
echo "  Carrier     : $([ "$CARRIER" = "1" ] && echo UP || echo DOWN)"
echo "  Current IP  : ${IP:-none}"
echo "  Expected IP : $STATIC_CIDR"
echo ""

if echo "$IP" | grep -q "^${STATIC_IP}/"; then
    echo "  LAN is HEALTHY — watchdog will fast-exit on a clean boot."
else
    echo "  $STATIC_IP not yet assigned — watchdog will activate on next boot."
fi

echo ""
echo "=== Installation complete ==="
echo ""
echo "Scripts           : $SCRIPT_DEST"
echo "Dead man's switch : self-destructs after 3 consecutive failed/timed-out boots"
echo "Log file          : /var/log/lan_watchdog.log"
echo "Marker (if fired) : $SELF_DESTRUCT_MARKER"

Deployment

Prerequisites

  • SSH access to the NAS

  • A user account with sudo privileges

  • The admin built-in account is not required

Step 1 — Transfer files to the NAS

From Windows PowerShell or any SCP client:

scp lan_watchdog.sh install_watchdog.sh youruser@192.168.1.x:/share/homes/youruser/

Step 2 — SSH into the NAS and run the installer

ssh youruser@192.168.1.x
cd /share/homes/youruser
chmod +x lan_watchdog.sh install_watchdog.sh
sh install_watchdog.sh

Step 3 — Enable autorun in the web UI

Navigate to Control Panel → Hardware → General and ensure *“Run user defined processes during startup (autorun.sh)”* is checked. The installer also sets this via CLI, but confirming it in the UI provides an additional safety check.

Step 4 — Reboot and verify

reboot

After the NAS completes its boot sequence (final single beep), verify connectivity from a Windows client:

ping 192.168.1.x

Then SSH in and inspect the log:

cat /var/log/lan_watchdog.log

Verification

Successful recovery boot — expected log output

[2026-03-15 19:07:04] ========================================================
[2026-03-15 19:07:04]  LAN Watchdog  |  PID 23582  |  Sun Mar 15 19:07:04 CET 2026
[2026-03-15 19:07:04]  Interface     : eth0  →  192.168.1.x/24
[2026-03-15 19:07:04]  Hard timeout  : 120s  |  Max strikes: 3
[2026-03-15 19:07:04] ========================================================
[2026-03-15 19:07:04] Strike counter: 1 / 3
[2026-03-15 19:07:04] Waiting 30s for normal boot to settle...
[2026-03-15 19:07:34] 192.168.1.x is NOT assigned to eth0 — entering recovery loop.
[2026-03-15 19:07:34] Recovery attempt 1 / 5
[2026-03-15 19:07:34] --- Recovery: assigning 192.168.1.x/24 to eth0 ---
[2026-03-15 19:07:34]   ip addr add 192.168.1.x/24 dev eth0
[2026-03-15 19:07:34]   arping: broadcasting 192.168.1.x on eth0
[2026-03-15 19:07:37] --- Recovery complete ---
[2026-03-15 19:07:38] SUCCESS on attempt 1 — 192.168.1.x/24 is now assigned to eth0.
[2026-03-15 19:07:38] Strike counter cleared — IP confirmed on eth0.

Clean boot (NVS worked correctly) — expected log output

[2026-03-15 19:07:04] ========================================================
[2026-03-15 19:07:04]  LAN Watchdog  |  PID 23582  |  Sun Mar 15 19:07:04 CET 2026
[2026-03-15 19:07:04]  Interface     : eth0  →  192.168.1.x/24
[2026-03-15 19:07:04]  Hard timeout  : 120s  |  Max strikes: 3
[2026-03-15 19:07:04] ========================================================
[2026-03-15 19:07:04] Strike counter: 1 / 3
[2026-03-15 19:07:04] Waiting 30s for normal boot to settle...
[2026-03-15 19:07:34] LAN is healthy — 192.168.1.x/24 is already assigned to eth0.
[2026-03-15 19:07:34] Strike counter cleared — IP confirmed on eth0.

After a Firmware Upgrade

No action is required. All components of the solution are fully persistent across QTS firmware upgrades:

Component Location Survives firmware upgrade
lan_watchdog.sh /etc/config//dev/sdc6 Yes
install_watchdog.sh /etc/config//dev/sdc6 Yes
autorun.sh entry /dev/sdc6 config partition Yes
Misc Autorun = TRUE QTS config database on /dev/sdc6 Yes
Strike counter /etc/config//dev/sdc6 Yes

All files and settings live on /dev/sdc6, the dedicated config partition, which QTS firmware upgrades never touch. The firmware ramdisk (paths such as /usr/local/bin/, /tmp/, and most of /etc/) is rebuilt on every boot and upgrade, but /dev/sdc6 is a persistent data partition that is mounted at boot and left intact by the upgrade process.


Uninstalling

To remove the watchdog completely:

# Mount the config partition and remove autorun.sh entry
sudo mount -t ext2 /dev/sdc6 /tmp/config
sudo grep -v "lan_watchdog" /tmp/config/autorun.sh > /tmp/autorun.tmp
sudo mv /tmp/autorun.tmp /tmp/config/autorun.sh
sudo umount /tmp/config

# Remove all watchdog files
sudo rm -f /etc/config/lan_watchdog.sh
sudo rm -f /etc/config/install_watchdog.sh
sudo rm -f /etc/config/lan_watchdog_strikes
sudo rm -f /etc/config/lan_watchdog_SELFDESTRUCTED
1 „Gefällt mir“

Hi Kumpel, gute Arbeit!

Allerdings braucht dieser Abschnitt mehr Infos:

Es ist immer Partition 6, außer wenn es Partition 5 ist (oder etwas ganz anderes). :wink:

Aus create-autorun.sh:

	if [[ -n $r_nas_dev_node ]]; then
		autorun_partition=${r_nas_dev_node}${r_nas_autorun_part}
	else
		if [[ -e /sbin/hal_app ]]; then
			if IsQuTS; then
				autorun_partition=$r_nas_system_dev
			else
				autorun_partition=$(/sbin/hal_app --get_boot_pd port_id=0)
			fi

			case $(/sbin/getcfg System Model) in
				TS-X@(16|28A|A28A|33|35EU))
					autorun_partition+='5'
					;;
				*)
					autorun_partition+='6'
			esac
		elif [[ $r_nas_arc = TS-NASARM ]]; then
			autorun_partition=/dev/mtdblock5
		else
			autorun_partition=/dev/sdx6
		fi
	fi

Hallo, du hast recht – meine Aussage war ungenau. Ich hätte nicht sagen sollen „immer Partition 6 nach QNAP-Konvention“. Korrekt ist vielmehr:

  • Die meisten QNAP-Modelle verwenden Partition 6

  • Einige spezifische Modelle (TS-X16, TS-X28A, TS-A28A, TS-X33, TS-X35EU) verwenden Partition 5

  • ARM-basierte Modelle verwenden /dev/mtdblock5 — ein völlig anderer Gerätetyp (MTD-Flash, kein Blockgerät)

  • QuTS Hero verwendet das Systemgerät direkt, ohne eine Partitionsnummer anzuhängen

„Partition 6“ ist also der Regelfall, aber keine universelle Regel. Die Dokumentation muss korrigiert werden und ich werde das tun. :+1:

Das sollte TS-XA28A sein. :nerd_face:

Oder führe einfach create-autorun.sh aus und füge dann dein Skript zum Skriptpfad hinzu. create-autorun.sh wurde ziemlich gründlich getestet und enthält die gesamte erforderliche Ausnahme-Logik, um den richtigen Speicherort auf jedem NAS-Modell zu finden.

Hallo @Oyvind,

vielen Dank, dass du diese unglaublich detaillierte und gut dokumentierte Anleitung zusammengestellt hast! Deine Analyse der eigentlichen Ursache in Bezug auf den NVS-Dienst und den Intel igb-Treiber ist äußerst aufschlussreich.

Ich schätze besonders das elegante Watchdog-Skript, das du erstellt hast, insbesondere die robusten Sicherheitsmechanismen (wie das harte Timeout und die Selbstzerstörungsfunktion), um Bootschleifen zu verhindern. Diese Art von tiefgehender Fehlersuche und gewissenhaftem Teilen ist genau das, was diese Community so wertvoll macht. Es wird zweifellos eine große Hilfe für alle Nutzer sein, die auf ähnliche Probleme bei der Netzwerkinitialisierung stoßen könnten.

Auch ein Dank an @OneCD für den Hinweis bezüglich der unterschiedlichen Partitionsnummern bei verschiedenen QNAP-Modellen. Das ist ein sehr hilfreicher Tipp für alle, die das einsetzen möchten!

Nochmals vielen Dank für deinen fantastischen Beitrag zur QNAP-Community!

1 „Gefällt mir“

Danke, @Lucas, das ist sehr ermutigendes Feedback :+1:

1 „Gefällt mir“