r/unRAID 3d ago

Unraid 7.4.0-beta.2 Now Available

Thumbnail unraid.net
Upvotes

7.4.0-beta.2 Highlights:

  • Docker container templates now support multiple custom networks, plus a new Memory limit field in Advanced View
  • Shared background task tray for plugin, Docker, and VM operations with recall from any browser tab
  • Boot-device backups now run as background tasks with compression options and live progress
  • Mover progress and status tracking
  • Configurable physical power-button actions (Shut down, Reboot, Do nothing)
  • Expanded wireless (Realtek RTW88), controller, and Hyper-V virtualization support
  • Kernel updated to 6.18.47-Unraid, plus security fixes across core packages

Test servers only please. Go kick the tires and let us know what you find. Full changelog in the release notes.

Release Notes | Bug Reports


r/unRAID Jul 29 '26

Release Unraid OS 7.2.8 is out

Thumbnail unraid.net
Upvotes

This is a security-focused stable release recommended for all 7.2.X and older users. Key changes:

  • Broad security remediation: patches across bind, curl (17 CVEs), OpenSSL, Samba (6 CVEs), dnsmasq, libssh (11 CVEs), nginx, xorg-server, libXfont2, p11-kit, and more
  • Linux kernel upgraded to 6.12.98-Unraid
  • Unraid API updated 4.36.1
  • Added Intel iwlwifi firmware files
  • 187 base distro packages touched (5 added, 182 updated), including Docker 29.5.3, QEMU 10.2.3, PHP 8.4.23

r/unRAID 11h ago

ich777 quitting Unraid and creating a competing opensource server to Unraid is direct feedback to the Unraid team about telemetry and cloud integration.

Upvotes

MOS (https://mos-official.net) is more of what we want. No tracking, no telemetry, no cloud service, open source, no weird keys to deal with. I suspect MOS will gain a lot of momentum with it being a free and open source non-tracking software


r/unRAID 5h ago

Consistent Parity Errors

Upvotes

Every parity check i've run since shortly after starting my server a few months ago produces 5 errors. The first 2 or 3 runs, I didnt have the write corrections option selected. But the last two did have it selected and still producing 5 errors.

Anyway to get more details or clear these errors with certainty? Health checks are normal.

I have a pretty normal xfs build with 2 parity drives, 8 storage, and 2 mirrored cache drives.


r/unRAID 18h ago

Any idea what could be causing my Docker folder to be 609GiB?

Post image
Upvotes

r/unRAID 51m ago

UPS without monitoring - is there any point?

Upvotes

I recently picked up a UPS for my unraid server. This was long overdue but triggered by a data scare after a series of power cuts. My question is, without the USB monitoring, am I just postponing or possibly avoiding the cut to power? Should I replace it with one where a controlled shut down is possible?


r/unRAID 7h ago

Remote Desktop / VNC into VMs

Upvotes

Hi everybody, I've had my Unraid server for a year now and have been struggling with a specific problem the whole time. I have Linux and Windows VMs and would like to remote control them from Linux, Windows and my iPhone. Because I could not get it to work with Linux, I resorted to RDP from Windows / iPhone to Windows VMs for now. That worked reasonably well so far.

I'm currently trying Linux on my laptop and Gaming PC and things get difficult. RDP from Linux to Windows VMs need a lot of tinkering (especially turning off Fast Path helped) and doesnt seem to work towards Linux VMs with RDP.

So I considered using VNC. After some keymap problem (solved) with Unraids QEMU VNC, that works, it's not a good user experience though. Running VNC on Windows doesnt work very well either. I switched to Fedora and Kubuntu VMs which are supposed to have RDP built in but I cannot seem to connect to them (ironically) from my Windows machines while RDPin from Remmina works.

So TLDR: What are you guys using for remote desktop to your VMs? My requirements are:

Remote Desktop, ideally open source.

Host: Linux or Windows

Client: Linux, Windows, iPhone.

My Unraid is running on a i5 14500 with 96GB of DDR4 and has a dedicated Geforce 1660 which is currently passed through to immich machine learning.

My Clients are Fedora, Windows Pro and iOS

I'm absolutely willing to learn things by myself, I just want to know what works so I don't waste time learning the wrong thing.

Thanks in advance!


r/unRAID 1d ago

Don't forget your USB drive or boot partition if you've encrypted your Unraid server!

Upvotes

An encrypted array and cache are good, but if you're not careful, the secrets in your Docker containers could be the key to your data.

For example, if you used the same password for the array as you did for a database. Your container settings are stored unencrypted on your boot medium. The config/plugins/dockerMan/templates-user directory contains XML files that hold all your container settings. If you want to store these securely, there’s a simple trick. Create a folder named secrets on the cache, preferably in the appdata folder. There, create a <name>.env file for each container that contains sensitive information. Let’s take kopia.env as an example (Kopia is a backup tool, anyone with the key contained within it can decrypt your backup.). In this file, write the variables from your container that you want to store securely.

KOPIA_PASSWORD=SuperSecretPassword123#

In the container’s settings in Unraid, you can then simply do the following. Delete the KOPIA_PASSWORD variable completely, it’s no longer needed. Instead, have the container load the .env file from the cache as follows. Go to the container, click Edit, and then in the Advanced View, enter the following under Extra Parameters:

--env-file=/mnt/user/appdata/secrets/kopia.env

Your container does NOT need access to this folder as the host system is providing the file to the container while starting.

When the container starts up, it now reads KOPIA_PASSWORD from the .env file, so the data is no longer stored in plain text on your boot partition. You can include as many variables as you like, one per line, in the .env file.

To check if the variables were read successfully you can go to the containers console and just input env to it. It will list up all variables and those from the .env file should be there.

There are other ways to use /run/secrets/, but they don't work for every container or application. The solution above is foolproof. It would be great if there were a native Unraid solution for Docker secrets in the future, but until then, you can do it this way.


r/unRAID 1d ago

Unraid license for test environment

Upvotes

Hi all, I was looking the official docs but I couldn’t find anything, so maybe you know.

I was looking to have an Unraid install (ideally a VM) to test changes on my real machine. Like a sandbox environment. I thought of this specially bcs the new about version 8 being a complete change of the Unraid base OS and all my Unraid servers are production with some degree of customization, I would like to have a safe environment to test the migration, prepare the changes, test all and then do the migration

—-

Tbh I don’t understand why am I getting so much hate. I made a question. And it’s not something crazy even for a home user that deeply cares about their data. I was also very clear that I don’t intend to pirate Lime Tech’s intellectual property. I was asking about a sandbox to test changes on my server.

Yes these are two servers I bought for a business I started roughly 3 months ago and from which I did not derived any income yet. I also live in a country where 250 is almost a third of minimum wage, so yes it’s a lot of money. It would be much easier to just ignore terms of service and etc, create infinite VMs and call it a day but I have some respect

And yes, probably Unraid wasn’t the most wise decision to have as a NAS. I’m using it for a long time now, and I felt confident when I started that things would roughly stay the same from that moment on. Changing it probably will be the go to for other solutions like TrueNas that also offer storage, Docker and VMs


r/unRAID 16h ago

What would a reasonable price be to have someone assist me with building my NAS/Cloud server?

Upvotes

Just what the title states. I am planning on using Unraid.


r/unRAID 19h ago

Am i missing something with Cache drives?

Upvotes

Hello! As the title states, trying to figure out why my Cache drive seems a bit inconsistent when copying new files to my share.

My setup is as follows:

  • Unraid Hardware
    • 3x 4TB Western Digital HDDs in a drive array (12TB array)
    • 1TB Lexar NVME SSD (theoretical write of 6500MBs)
      • Devices is assigned to the "cache" pool
  • Target storage share
    • Primary Storage = Cache pool
    • Secondary Storage = Array, High-water
    • Mover action = Cache -> Array
    • Mover Settings = Hourly, ever hour
  • Source media details
    • Storage reader (Kingston FCR-HS4) has max transfer speed of 5 Gbps
    • Storage medium (CF Card, SanDisk Extreme UDMA 7 compliant) has max read speed of 120 MBs (960 Mbps)
    • Network connection is hard-wired 2.5Gbps

Process:

  • Copying large image files from USB Device & medium above directly to the storage array
  • Both array metrics for my cache drive (as found in unraid/main) and the windows file transfer utility show file transfer speeds of ~30MBs / 240 Mbps
  • After a few seconds, the array metrics for the cache drive begin displaying ~60MBs / 480Mbps, but the Windows File transfer Utility never breaks 30MBs / 240Mbps

Am I missing anything? Anything in Unraid that should be configured that I've missed? Based on my full setup, I'm certainly not expecting to hit NVME max writes, but I thought I'd at least be approaching the max transfer speed of my network. 30MBs seems very slow

Tyty!


r/unRAID 1d ago

Apache-Tika-Server - blacklisted

Upvotes

Just noticed that the "Apache-Tika-Server" template by sgraaf (https://ca.unraid.net/apps/apache-tika-server-0cw4tlc14im17o) is blacklisted:

Attention:
Blacklisted: Unable to be pulled
This application template has been blacklisted.

I can't seem to find any other references online to this being the case.

Is this something I should be addressing, or more likely to be something temporary caused by a change to the template that hasn't been approved/accepted or similar?

The repository is "apache/tika:latest" and the logs show "Starting Apache Tika 4.0.0 server". Otherwise running correctly.


r/unRAID 1d ago

Transferring 20TB to my array

Upvotes

hi, I recently setup my urgent DXP4800 Plus with UNRAID, Jellyfin, standard arr stack, unassigned devices, and krusader. For my array I have 4x 18TB seagate exes drives and a 1tb WD 780 cache ssd

i have a little over 20TB of 4k remux movies that I want to transfer over from a stack of T7 SSD’s, all formatted to Mac OS extended journaled. I can see the drives when I plug them in directly to the 4800 using a usb c cable, and it reads the structure of them, but if I try to transfer them I get the full list of movies that I’m trying to copy and the error “unraid file transfer "osx.com apple finderInf" 0)failed no data available" after each file name

I have searched this error and am not coming up with anything that is marked as solved. I can try doing it straight from my MacBook over the network, but ideally I can get this working via direct usb connection as it is going to take quite a long time to transfer each 4TB drive

any tips would be appreciated!

UPDATE:

Thanks to everyone for for the help. I ended up getting it working with the following command

cp -R /mnt/disks/Movies/* /mnt/user0/media/movies/

I had tried a few different option to get Unraid to ignore the hidden Mac data files, as well as getting terminal in Mac to delete them, but no success with that.

the first 4TB is currently transferring direct to my array at 270MB/sec.


r/unRAID 23h ago

I did a dumb

Upvotes

Ok, so rewind several weeks and I had a drive that partially failed to the point that Unraid disabled it. I was out of space in my previous disk enclosure so after acquiring the necessary bits, I relocated the six drives I was running (1 SATA, 4 SAS, 1 SATA parity) into the disk shelf.

The two SATA drives showed up as "wrong" and prevented the array from starting but curiously all four SAS drives showed up as healthy/onlline. Thinking it was perhaps a connection issue rather than an actual disk failure I proceeded to diagnose the "wrong" message and various forums guided me to a new config to get the drives re-adopted.

After careful checking of the parity and array SATA disk serial numbers, I pulled the trigger and saw several warnings about how the parity drive would be rebuilt and everything currently there erased... I continued.

Now I'm in a state where Unraid is struggling to read a failed drive and build parity, there's no valid parity because the old one was erased, and the system shares are offline because the portions of them that were on the failing disk aren't accessible so a bunch of dockers won't start/work, and I'm looking at 4-5 days before the parity build will complete and I can actually assess what's lost/gone.

Any tips going forward? I'm sure I've lost ~5TB of data (6TB drive that was about 75% full when it failed) and I'll worry about recovery later, but at this point I'm just trying to get to a stable state where I can assess what's gone and get my array healthy and everything properly running again.


r/unRAID 19h ago

Using AI to Help Manage unRAID Server

Upvotes

Not sure how many feel about this topic, but I have been using ChatGPT for a while now with diagnosing, upgrading, and now managing my unRAID server.

Recently I added a Windows 11 VM that has SSH access directly to my unRAID. When setting it up, I ensured to have the AGENT.md restrictions that way I have more control over what the agent actually does to my server.

Being able to just connect to the VM and have it analyze log files for any potential issues, any configuration enhancement opportunities or assistance with setting new docker containers, user scripts creation, etc. has made life way easier and not having to spend hours troubleshooting any issues.

To me the key is having an understanding of what AI recommends prior to allow it to make any changes to my server. I am going to continue enhancing the agent to continue to make my unRAID server optimal.


r/unRAID 3d ago

ich777 is stepping down from maintaining Unraid plugins and drivers

Upvotes

Long-time community developer ich777 posted an announcement letting everyone know he is moving on and stepping back from actively maintaining his plugins and drivers.

Here is his message from the forums:

"Hi everyone,

as many of you might have noticed, I haven't been around much lately, so I wanted to let you know that I've moved on and am no longer actively maintaining my plugins and drivers for Unraid.

The driver compilation will remain in place as long as the drivers compile and no major issues come up, though testing has gotten a lot harder for me these days.

If one of my plugins stops working for you, feel free to fork it and republish it on the CA App, I'd be happy about that! I'll still stop by from time to time and fix whatever I can.

I don't think this will have a big impact anyway, since Unraid is switching to a new base distribution in the near future, which would have meant redoing the plugin compilation and everything around it anyway.

It was a lot of fun. I learned a lot and had many great conversations with the people here on the Forums and Discord, and also with the whole Unraid Team.

Thanks for everything, guys! Take care, everyone!"

https://forums.unraid.net/topic/200476-moving-on-it-was-a-lot-of-fun-thanks-guys/


r/unRAID 21h ago

Anyone have any tips for setting up an AI (subscription like ChatGPT) to manage their unraid?

Upvotes

Would love to have an ai that i can give tasks to like check the health of everything, make sure all my downloads went through, that files look like they're in the right place, things like that.

Thank you!


r/unRAID 2d ago

Thinking about leaving Synology - ugreen vs terramaster

Upvotes

So I’m thinking about migrating from my old Ds916 to something newer.

Form factor is really important to me. I read about installing unraid on a Ugreen DXP or Terramaster f6-424.

Is one of them more stable with unraid ? Stability is my number one priority with a robust file system.

Also, the reason I’m looking at unraid is because I use SHR on synology and not much system seems to support mix and match hard drives (I usually upgrade my hdd over time and SHR gives me the possibility to use all the space)

But from I found, writing performance is bad. Not that I need super fast storage but it seems super slow.

So I suppose I need nvme cache ton speed up all this?

Thanks


r/unRAID 1d ago

Why your Unraid disks won't spin down (and a script to trace the culprit)

Upvotes

If your Unraid server lives in a separate room, you might not notice that your physical hard drives are failing to spin down. I only realised my array was running non-stop after sleeping in the spare bedroom where my server is located.

I assumed my data was strictly sitting on my NVMe cache, but Unraid was still waking up physical disks. A key quirk to keep in mind: Unraid does not clean up empty directories when moving files between array disks and the cache. If an app queries a directory structure that exists on a physical disk, Unraid spins up that disk just to list the folders, even if no files are read from it.

The popular "Open Files" plugin can be confusing to parse, so I used AI to write a custom python script that directly traces kernel I/O and maps real process activity to target drives.

Created using AI assistant.

Here is an example of the live console output:

========================================================================================================================
 UNRAID PHYSICAL DISK I/O — KERNEL TRACE & UNRAID DISK RESOLVER
========================================================================================================================
 Interval: 3.0s   Physical disks: sda [disk5], sdb [parity], sdc [disk2], sdd [disk6], sde [disk1], sdf [flash], sdg [disk4], sdh [disk3]
========================================================================================================================

PHYSICAL DISKS
------------------------------------------------------------------------------------------------------------------------
DISK                            READ             WRITE       OPS
sda [disk5]                  0.0 B/s           0.0 B/s         0
sdb [parity]                 0.0 B/s           0.0 B/s         3
sdc [disk2]                 8.1 MB/s           0.0 B/s       100
sdd [disk6]                  0.0 B/s           0.0 B/s         3
sde [disk1]                34.7 KB/s           0.0 B/s         8
sdf [flash]                  0.0 B/s           0.0 B/s         1
sdg [disk4]                  0.0 B/s           0.0 B/s         3
sdh [disk3]                  0.0 B/s           0.0 B/s         0

PHYSICAL KERNEL ISSUERS
------------------------------------------------------------------------------------------------------------------------
PID     DOCKER / APP                  PROCESS             DISK                        READ         WRITE       OPS
27197   HOST                          mdunraidd2          sdc [disk2]             8.1 MB/s       0.0 B/s       100
27196   HOST                          mdunraidd1          sde [disk1]            34.7 KB/s       0.0 B/s         8

REAL USER-SPACE APPLICATIONS & TARGET DISK LOCATION
------------------------------------------------------------------------------------------------------------------------
PID     APP / DOCKER CONTAINER      PROCESS         TARGET DISK         OPEN PATH
37178   HOST                        qemu-system-x86 cache               /mnt/cache/domains/XUbuntu/vdisk1.qcow2
1766909 HOST                        smbd[192.168.0. disk1               /mnt/user/data
3270942 DOCKER: plex                Plex Transcoder disk2               /mnt/user/data/media/anime tv/xx.mkv

I don't know why my block of code didn't get attached.

#!/usr/bin/env python3
"""
Unraid Physical Disk I/O — KERNEL TRACE & UNRAID DISK RESOLVER

Extends kernel block_rq_issue tracing by resolving open file handles (/proc/*/fd)
and physical kernel devices (sda-sdz) directly to Unraid Array labels (disk1, parity, etc.).

Run as root:
    python3 unraid_disk_io_trace.py
"""

import argparse
import os
import re
import subprocess
import sys
import time
from collections import defaultdict
from pathlib import Path

TRACE_ROOTS = [
    Path("/sys/kernel/tracing"),
    Path("/sys/kernel/debug/tracing"),
]

def trace_root():
    for p in TRACE_ROOTS:
        if (p / "trace_pipe").exists() and (p / "events/block/block_rq_issue").exists():
            return p
    return None

def read(path):
    try:
        return path.read_text(errors="replace").strip()
    except Exception:
        return ""

def is_nvme(name):
    return name.startswith("nvme")

def is_partition(name):
    return bool(re.match(r"^(sd|hd|vd|xvd)[a-z]+\d+$|^mmcblk\d+p\d+$|^nvme\d+n\d+p\d+$", name))

def physical_disks():
    result = {}
    root = Path("/sys/class/block")

    for p in root.iterdir():
        name = p.name
        if is_nvme(name) or is_partition(name) or name.startswith(("loop", "dm-", "md", "zram", "ram")):
            continue
        if not (p / "dev").exists() or not (p / "device").exists():
            continue

        dev = read(p / "dev")
        if not dev:
            continue

        try:
            major, minor = map(int, dev.split(":"))
            result[(major, minor)] = name
        except ValueError:
            continue

    return result

def get_unraid_disk_mappings(disks):
    """
    Maps kernel names (e.g., 'sdh') to Unraid labels (e.g., 'disk3', 'parity')
    using /proc/mounts and Unraid's disks.ini state file.
    """
    dev_to_unraid = {}

    # 1. Parse /proc/mounts for active mount points (/mnt/diskX, /mnt/cache, etc.)
    try:
        with open("/proc/mounts", "r") as f:
            for line in f:
                parts = line.split()
                if len(parts) >= 2:
                    dev_path, mount_point = parts[0], parts[1]
                    if mount_point.startswith("/mnt/"):
                        label = mount_point.replace("/mnt/", "")
                        if label in ("user", "user0", "disks"):
                            continue
                        try:
                            st = os.stat(mount_point)
                            major = os.major(st.st_dev)
                            minor = os.minor(st.st_dev)
                            kernel_dev = disks.get((major, minor))
                            if kernel_dev:
                                dev_to_unraid[kernel_dev] = label
                        except Exception:
                            continue
    except Exception:
        pass

    # 2. Parse Unraid's emhttp status file for assigned/unmounted/parity disks
    disks_ini = Path("/var/local/emhttp/disks.ini")
    if disks_ini.exists():
        try:
            content = disks_ini.read_text(errors="replace")
            current_name = None
            for line in content.splitlines():
                line = line.strip()
                if line.startswith("[") and line.endswith("]"):
                    current_name = line[1:-1].strip('"')
                elif line.startswith("device=") and current_name:
                    dev_name = line.split("=", 1)[1].strip('"')
                    # Strip partition number if present (e.g. sdh1 -> sdh)
                    dev_name = re.sub(r"\d+$", "", dev_name)
                    if dev_name in disks.values() and dev_name not in dev_to_unraid:
                        dev_to_unraid[dev_name] = current_name
        except Exception:
            pass

    return dev_to_unraid

def format_disk_label(dev_name, unraid_map):
    """Returns a string like 'sdh [disk3]' or 'sda [unassigned]'."""
    label = unraid_map.get(dev_name)
    if label:
        return f"{dev_name} [{label}]"
    return dev_name

def docker_containers():
    result = {}
    try:
        out = subprocess.check_output(
            ["docker", "ps", "-a", "--no-trunc", "--format", "{{.ID}}\t{{.Names}}"],
            stderr=subprocess.DEVNULL, text=True, timeout=5
        )
        for line in out.splitlines():
            x = line.split("\t", 1)
            if len(x) == 2:
                result[x[0]] = x[1]
    except Exception:
        pass
    return result

def container_for_pid(pid, containers):
    try:
        text = Path(f"/proc/{pid}/cgroup").read_text(errors="replace")
    except Exception:
        return None

    ids = set(re.findall(r"[0-9a-f]{64}", text))
    ids.update(re.findall(r"docker[-/]([0-9a-f]{12,64})", text))

    for cid, name in containers.items():
        for found in ids:
            if cid.startswith(found) or found.startswith(cid):
                return name
    return None

def find_open_files_on_array(containers, disks, unraid_map):
    active_apps = []

    for pid_dir in Path("/proc").glob("[0-9]*"):
        try:
            pid = int(pid_dir.name)
            fd_dir = pid_dir / "fd"
            if not fd_dir.exists():
                continue

            comm = read(pid_dir / "comm")
            if comm in ("shfs", "mdunraid") or comm.startswith("kworker"):
                continue

            app_name = "HOST"
            container = container_for_pid(pid, containers)
            if container:
                app_name = f"DOCKER: {container}"

            for fd in fd_dir.iterdir():
                try:
                    target = os.readlink(fd)
                    if not target.startswith("/mnt/"):
                        continue

                    actual_disk = "UNKNOWN"
                    real_path = target

                    # If open path is a direct disk mount
                    if not target.startswith("/mnt/user/"):
                        for p in Path("/mnt").glob("*"):
                            if p.name in ("user", "user0", "disks"):
                                continue
                            if target.startswith(str(p) + "/"):
                                dev_name = get_device_for_mount(str(p), disks)
                                actual_disk = format_disk_label(dev_name, unraid_map)
                                break
                    else:
                        # Path opened via /mnt/user/ -> Find physical array location
                        relative_path = target.replace("/mnt/user/", "", 1)
                        found_on_array = False

                        # 1. Check physical array disks FIRST (/mnt/disk1..N)
                        for disk_path in sorted(Path("/mnt").glob("disk*")):
                            check_path = disk_path / relative_path
                            if check_path.exists():
                                dev_name = get_device_for_mount(str(disk_path), disks)
                                actual_disk = format_disk_label(dev_name, unraid_map)
                                real_path = str(check_path)
                                found_on_array = True
                                break

                        # 2. Check cache/pool mounts ONLY if NOT on array
                        if not found_on_array:
                            for pool in Path("/mnt").glob("*"):
                                if pool.name in ("user", "user0", "disks") or pool.name.startswith("disk"):
                                    continue
                                check_path = pool / relative_path
                                if check_path.exists():
                                    actual_disk = f"{pool.name} [POOL]"
                                    real_path = str(check_path)
                                    break

                    if actual_disk != "UNKNOWN":
                        active_apps.append({
                            "pid": pid,
                            "app": app_name,
                            "comm": comm,
                            "disk": actual_disk,
                            "path": target
                        })
                        break
                except Exception:
                    continue
        except Exception:
            continue

    return active_apps

def get_device_for_mount(mount_path, disks):
    try:
        st = os.stat(mount_path)
        major = os.major(st.st_dev)
        minor = os.minor(st.st_dev)
        return disks.get((major, minor), mount_path.replace("/mnt/", ""))
    except Exception:
        return mount_path.replace("/mnt/", "")

def enable_trace(root):
    try:
        (root / "tracing_on").write_text("0")
        (root / "trace").write_text("")
        (root / "events/block/block_rq_issue/enable").write_text("1")
        (root / "tracing_on").write_text("1")
    except Exception as e:
        raise RuntimeError(f"Cannot enable block tracing: {e}")

def disable_trace(root):
    try:
        (root / "tracing_on").write_text("0")
        (root / "events/block/block_rq_issue/enable").write_text("0")
    except Exception:
        pass

def parse_trace_line(line):
    if "block_rq_issue:" not in line:
        return None

    m = re.search(r"\S+-(\d+)\s+\[\d+\]", line) or re.search(r"\s(\d+)\s+\[\d+\]", line)
    pid = int(m.group(1)) if m else -1

    dm = re.search(r"\b(\d+),(\d+)\b", line)
    if not dm:
        return None

    major, minor = int(dm.group(1)), int(dm.group(2))
    after = line.split("block_rq_issue:", 1)[1]
    rm = re.search(r"\b([RWDNSF]+)\b", after)
    if not rm:
        return None

    rwbs = rm.group(1)
    sm = re.search(r"\+\s*(\d+)", after)
    size = int(sm.group(1)) * 512 if sm else 0

    cm = re.match(r"^\s*([^\s-]+(?:/[^\s-]+)?)\s*-\d+", line)
    comm = cm.group(1) if cm else "unknown"

    return {"pid": pid, "major": major, "minor": minor, "rwbs": rwbs, "bytes": size, "comm": comm}

def clear():
    print("\033[2J\033[H", end="")

def fmt_rate(v):
    units = ["B/s", "KB/s", "MB/s", "GB/s", "TB/s"]
    x = float(v)
    for u in units:
        if x < 1024 or u == units[-1]:
            return f"{x:8.1f} {u}"
        x /= 1024
    return f"{x:8.1f} TB/s"

def main():
    parser = argparse.ArgumentParser()
    parser.add_argument("--interval", type=float, default=3.0)
    parser.add_argument("--min-mb", type=float, default=0.01)
    parser.add_argument("--all", action="store_true")
    parser.add_argument("--once", action="store_true")
    args = parser.parse_args()

    if os.geteuid() != 0:
        print("ERROR: Run as root (e.g., sudo python3 unraid_disk_io_trace.py)")
        sys.exit(1)

    root = trace_root()
    if not root:
        print("ERROR: Linux block tracing unavailable.")
        sys.exit(1)

    disks = physical_disks()
    unraid_map = get_unraid_disk_mappings(disks)
    containers = docker_containers()

    try:
        enable_trace(root)
        trace_pipe = open(root / "trace_pipe", "r", buffering=1, errors="replace")
        import select

        while True:
            start = time.monotonic()
            end = start + max(0.1, args.interval)

            by_disk = defaultdict(lambda: {"read": 0, "write": 0, "ops": 0})
            by_issuer = defaultdict(lambda: {
                "read": 0, "write": 0, "ops": 0, "disk": set(),
                "pid": -1, "comm": "", "container": None
            })

            while time.monotonic() < end:
                remaining = end - time.monotonic()
                if remaining <= 0:
                    break

                ready, _, _ = select.select([trace_pipe], [], [], min(remaining, 0.2))
                if not ready:
                    continue

                line = trace_pipe.readline()
                if not line:
                    continue

                event = parse_trace_line(line)
                if not event:
                    continue

                disk = disks.get((event["major"], event["minor"]))
                if not disk or is_nvme(disk):
                    continue

                size = event["bytes"]
                is_write = "W" in event["rwbs"]
                is_read = "R" in event["rwbs"]

                if is_write:
                    by_disk[disk]["write"] += size
                elif is_read:
                    by_disk[disk]["read"] += size
                by_disk[disk]["ops"] += 1

                pid = event["pid"]
                app = container_for_pid(pid, containers) or "HOST"
                key = (pid, app, event["comm"])

                row = by_issuer[key]
                row["pid"] = pid
                row["comm"] = event["comm"]
                row["container"] = app
                row["disk"].add(disk)
                row["ops"] += 1

                if is_write:
                    row["write"] += size
                elif is_read:
                    row["read"] += size

            if not args.once:
                clear()

            disk_summary = ", ".join([format_disk_label(d, unraid_map) for d in sorted(disks.values())])

            print("=" * 120)
            print(" UNRAID PHYSICAL DISK I/O — KERNEL TRACE & UNRAID DISK RESOLVER")
            print("=" * 120)
            print(f" Interval: {args.interval:.1f}s   Physical disks: {disk_summary}")
            print("=" * 120)

            print("\nPHYSICAL DISKS")
            print("-" * 120)
            print(f"{'DISK':<18}{'READ':>18}{'WRITE':>18}{'OPS':>10}")

            for disk in sorted(disks.values()):
                x = by_disk[disk]
                label_str = format_disk_label(disk, unraid_map)
                print(f"{label_str:<18}{fmt_rate(x['read']/args.interval):>18}{fmt_rate(x['write']/args.interval):>18}{x['ops']:>10}")

            print("\nPHYSICAL KERNEL ISSUERS")
            print("-" * 120)
            print(f"{'PID':<8}{'DOCKER / APP':<30}{'PROCESS':<20}{'DISK':<18}{'READ':>14}{'WRITE':>14}{'OPS':>10}")

            rows = [x for x in by_issuer.values() if args.all or (x["read"] + x["write"]) >= args.min_mb * 1024 * 1024]
            rows.sort(key=lambda x: x["read"] + x["write"], reverse=True)

            for x in rows[:60]:
                disks_text = ",".join([format_disk_label(d, unraid_map) for d in sorted(x["disk"])])
                print(f"{x['pid']:<8}{str(x['container'])[:29]:<30}{x['comm'][:19]:<20}{disks_text[:17]:<18}{fmt_rate(x['read']/args.interval):>14}{fmt_rate(x['write']/args.interval):>14}{x['ops']:>10}")

            print("\nREAL USER-SPACE APPLICATIONS & TARGET DISK LOCATION")
            print("-" * 120)
            resolved = find_open_files_on_array(containers, disks, unraid_map)
            if resolved:
                print(f"{'PID':<8}{'APP / DOCKER CONTAINER':<28}{'PROCESS':<16}{'TARGET DISK':<20}{'OPEN PATH'}")
                for app in resolved[:10]:
                    print(f"{app['pid']:<8}{app['app']:<28}{app['comm']:<16}{app['disk']:<20}{app['path']}")
            else:
                print("No open file handles detected on /mnt/disk* or /mnt/user.")

            if args.once:
                break

    except KeyboardInterrupt:
        pass
    finally:
        try:
            trace_pipe.close()
        except Exception:
            pass
        disable_trace(root)

if __name__ == "__main__":
    main()

r/unRAID 1d ago

How do I set up 2nd nvme drive just for file mgt?

Upvotes

I just migrated my Unraid setup to an Aoostar WTR Max and added a cheap 2TB WD 740 nvme along with it. Since it's a ramless drive I was thinking of just using it mainly for downloads. My current setup is basically a Jellyfin server, what's the best way to go about this?

Btw, Aoostar Max is very nice- I managed to get it for ~$400US off AliExpress after discounts and cash back- it's the cost of ddr5 that's the killer. I had to blind buy 2x8gb of unknown 4800 for $75 off Marketplace for $75. Thankfully it works fine.


r/unRAID 1d ago

Root won’t log in….. help please.

Upvotes

Hey guys, last week I upgraded to whatever was the latest update (can’t log in to confirm sorry)

I have followed the user management page. Shut down server, put the usb into my MacBook, changed the root line to root::15477:0:99999:7::: saved and rebooted….. it then says to “start Unraid server and set a new root password” however I can’t figure out how to do this.

Any tips so I can get back in please. Thanks.


r/unRAID 2d ago

I made an XGS-PON ONT monitoring dashboard — now available in Unraid Community Apps

Upvotes

I recently switched to an X-ONU-SFPP XGS-PON ONT running 8311 Community Firmware and wanted a better way to keep an eye on the module without constantly logging into it or running commands manually.

The screenshot above is from my own ONT and shows actual telemetry collected by the dashboard.

So I built **X-ONU-SFPP Dashboard**, and it's now available in **Unraid Community Applications**.

The dashboard monitors:

- RX and TX optical power

- TX laser bias and module voltage

- Optic and CPU temperatures

- PLOAM state / O5.1 association

- Historical optical and temperature data

There's also optional SSH telemetry using `pontop`, which adds:

- Real-time XGS-PON download/upload traffic

- ONT uptime, memory and load

- GEM / allocation information

- Upstream/downstream FEC status

- FEC, BIP, HEC and PLOAM MIC error counters

- Alarm monitoring

- Additional module information

SSH is completely optional. The basic dashboard works using the metrics endpoint provided by 8311 firmware.

Data is stored locally in SQLite, with historical views for 1 hour, 6 hours, 24 hours, 7 days and 30 days. There are no external services, Grafana, InfluxDB or cloud dependencies.

I built and tested it with an **X-ONU-SFPP connected directly to a UniFi Cloud Gateway Fiber**, so I'd especially be interested in hearing from anyone running it with a different XGS-PON/8311 setup.

A couple of security/privacy decisions I made along the way: the dashboard deliberately doesn't expose the ONT/PON or module serial numbers, and the advanced SSH collector doesn't store the SSH password in its database or return it through the API. The dashboard is intended for a trusted LAN and shouldn't be exposed directly to the Internet.

It's open source under **AGPL-3.0-or-later**.

**Unraid:** Search Apps for `X-ONU-SFPP-Dashboard`

**GitHub:**

https://github.com/JPetovello/x-onu-sfpp-dashboard

Feedback, bug reports and compatibility reports are welcome. This is the first public release, so I'm particularly curious whether anyone else with 8311-compatible hardware finds it useful.

**Development disclosure:** This project was developed with substantial assistance from AI-based coding tools. AI was used extensively for code generation, debugging, documentation, and development guidance. I defined the project requirements and design, performed the hardware integration and testing on my own XGS-PON setup, validated the telemetry and behavior, made the deployment and security decisions, and maintain the project.


r/unRAID 2d ago

License and updates.

Upvotes

So when purchasing unraid you get it for a year and then after you have to pay for updates?

I assume that includes security updates? So it's a subscription now from my understanding.

I have an old OG Pro license that includes perpetual updates (as I would expect) from like 2017 but might want another device.


r/unRAID 2d ago

Moving boot drive

Upvotes

I moved my boot drive to my internal m.2 drive and I regret it. My key is on a flash drive without unraid OS on it, is there a process to move the boot to the flash drive?

Can I just use the windows unraid installer on the USB drive then recover my key from the online manager once I set unraid back up?

I've just been playing around for now, I don't really have anything important set up and no data on my drives yet.


r/unRAID 2d ago

Best/Recommended "Pool Device" use with a SATA SSD and NVME combination.

Upvotes

I am currently adding a 2tb SATA SSD (Samsgung 870 QVO) to my array as a Pool Device. I also have an existing 1tb NVME SSD that acts as my cache drive for downloads, VM's, Containers, etc that copies downloaded files to my array once a week.

I initially had the idea of keeping my docker containers and VM's (currently only Home Assistant) on the NVME, but change torrent downloads, and general quick access/loading for specific media (Photos and Music mostly, but primarily music) to the SATA SSD. The reason for this is streaming my music library is my personal primary use for this server, so I think it makes sense to move the library here at least to reduce the use of my HDD array.

I have however read some posts that have recommended the opposite as well.

What would be the recommended setup in my case?