https://pixelfed.de/p/cammelspit/657887422594974310

After using my Steam Deck for over a year, I had an idea regarding network storage when I was installing Emu Deck. Despite the portability of the Steam Deck, I wanted to mount ROMs, Media, and even a Steam Library from a network-attached storage (NAS) device at home.

Recently, due to health reasons, I find myself bed-bound, making the Steam Deck a great companion. However, It’s storage options are rather limited so I attempted to find a solution.

I faced challenges due to SteamOS’s immutable file system. To overcome these I explored using NFS shares for a Steam Library, as Samba shares had limitations and wouldnt work on Linux for a Steam Library. Mounting NFS shares worked as long as i used a specific option to make the files executable.

To automate this process I created a systemd service that loads on boot, triggering a script to mount the shares. However, SteamOS’s immutable file system posed challenges for typical auto-start methods like the KDE autostart tool and especially fstab.

The key was leveraging the service that loads even in in gamemode so you wont have to do anything manually, not even switch to desktop mode at all. The solution involved that service checking network connectivity before mounting the shares. This ensures the script doesn’t run before the wifi comes up, if it has no connectivity it rechecks every 30 seconds for connectivity until it does. Once this happens, the mount script itself is run. On a wired connectionwhile docked the mount is ready before Steam even loads for me so this hasnt been an issue but I felt it was a problem i needed to solve before putting it into production.

I’ve shared the service file and script as well as a handy script that I used to unmount those same shares during testing, noting that hard-coded paths will need to be modified. The script also logs successful and unsuccessful mounts for debugging but i liked the feature so i left it. Although not the final version, it offers a functional solution for now.

If you use Unraid, the script includes paths relevant to its shares. Server IP, share list, and mount points Will need to be modified to fit your needs or it likely won’t work. The script lacks support for authenticated shares, but it persists between reboots and has shown reliability in my testing. I also realize that the script is basically just dumped on my desktop, that’s where I created it and the pads are hard coded and I just don’t care to change it so if you want it somewhere else you’re going to have to do that alteration yourself.

Feel free to modify it or share improved versions and above all, have fun!!

  1. netmount.sh
#!/bin/sh

NFS_SERVER=10.10.10.99
SHARE_PATH="/mnt/user"
SHARES=("Media" "Emulation" "Steam" "Downloads" "DUMPBOX" "isos" "NSFWMedia" "Software" "Tools")

# Set up log file
LOG_FILE="/home/deck/Desktop/netmount.log"

# Loop through the shares and mount each one with -o exec
for SHARE_NAME in "${SHARES[@]}"; do
  MOUNT_POINT="/home/deck/mounts/$SHARE_NAME"
  mkdir -p $MOUNT_POINT  # Create the mount point directory

  TIMESTAMP=$(date +"%Y-%m-%d %H:%M:%S")
  mount -t nfs -o exec $NFS_SERVER:$SHARE_PATH/$SHARE_NAME $MOUNT_POINT

  # Log the results with timestamps
  if [ $? -eq 0 ]; then
    echo "$TIMESTAMP: NFS share '$SHARE_NAME' mounted successfully at $MOUNT_POINT" >> $LOG_FILE
  else
    echo "$TIMESTAMP: Failed to mount NFS share '$SHARE_NAME'" >> $LOG_FILE
  fi
done
  1. unmount.sh
#!/bin/sh

# Unmount all NFS shares
for MOUNT_POINT in /home/deck/mounts/*; do
  umount $MOUNT_POINT
done

echo "All NFS shares unmounted."

  1. netmount.service
[Unit]
Description=Netmount Script at Boot
After=graphical.target

[Service]
Type=simple
ExecStart=/bin/sh -c 'for i in {1..20}; do ping -c 1 google.com && /home/deck/Desktop/netmount.sh && break || sleep 30; done'

[Install]
WantedBy=default.target

You can use these clean versions for your scripts and service file. Adjust paths and configurations as needed.

  • CapillaryUpgrade@lemmy.sdf.org
    link
    fedilink
    arrow-up
    3
    ·
    10 months ago

    Don’t put yourself down! Using systemd wouldn’t make it work “better”, it’s just more “proper” (and a great tool to know in general!)

    Great job and keep going!

    • cammelspit@lemm.eeOP
      link
      fedilink
      arrow-up
      1
      ·
      10 months ago

      Thanks! Yeah, I have noticed a lot of places where the location of things is not necessarily a requirement but it is considered “proper”. It’s a whole different paradigm compared to the rather severely rigid requirements of Windows. I went through a lot of documentation about services and the real eureka moment was when I realized it was more or less just a command being run with extra fluff around it like environment variables and such. I have the service placed in the /etc/systemd/system directory, where all the other ones valve made are. I have seen how powerful systemd can be when leveraged well but for the moment I’m pleased with the results. Thanks for the encouragement!

      • CapillaryUpgrade@lemmy.sdf.org
        link
        fedilink
        arrow-up
        2
        ·
        10 months ago

        No problem!

        I hacked this together instead of going to sleep, so it might make your deck explode, but maybe it’s a starting point for you or someone else:

        # home-deck-mounts.mount
        #
        # Mount units must be named after the destination path, this / replaced by -, like above
        #
        # This is a template unit.
        # That's explained here: https://fedoramagazine.org/systemd-template-unit-files/
        # TL;DR: run it like this `[email protected]` if you want to mount the subdirectory "linuxisos" from SHARE_PATH
        [Unit]
        Description=NetMount %I
        After=graphical.target
        # This is commented out, because it is implicit for network mounts https://www.freedesktop.org/software/systemd/man/latest/systemd.mount.html#Default%20Dependencies
        # I keep it here as an example
        #After=network-online.target
        #Requires=network-online.target
        
        [Mount]
        # %i expands to what ever you put after the @ when starting/activating the service
        What=10.10.10.99:/mnt/user/%i
        Where=/home/deck/mounts/%i
        Type=nfs
        Options=exec
        
        [Install]
        WantedBy=default.target
        

        I couldn’t confirm if mount units are allowed to be template units, but if not, just duplicate the service for each path and replace %i.

        Say the word if you run into issues!