Skip to content

Instantly share code, notes, and snippets.

Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save zeehio/7c67d531236e39496c39b3c5c3b3f268 to your computer and use it in GitHub Desktop.
Save zeehio/7c67d531236e39496c39b3c5c3b3f268 to your computer and use it in GitHub Desktop.
udev rule for Home Assistant OS (hassio) to mount USB drives into the Supervisor Media directory
#
# udev rule
# Mount USB drive to the media directory using the partition name as mount point
#
# Description:
# Created for Home Assistant OS, this rule mounts any USB drives
# into the Hassio media directory (/mnt/data/supervisor/media).
# When a USB drive is connected to the board, the rule creates one directory
# per partition under the media directory. The newly created partition is named
# as the partition name. If the partition does not have a name, then the following
# name format is used: "usb-{block-name}" where the block name is sd[a-z][0-9].
#
# Note 1:
# The rule name is always prefixed with a number. In this case, the rule uses 80.
# This represents the order of the rule when multiple rules exists in udev.
# Low numbers run first, high numbers run last. However, low numbers do not have all
# the facilities than high numbers may have.
# For this rule to run properly, use numbers equal or greater than 80.
#
# Note 2:
# This rule will skip mounting the 'CONFIG' USB key.
# https://github.com/home-assistant/operating-system/blob/dev/Documentation/configuration.md
#
# Note 3:
# This rule will mount the OS partitions if the OS is sorted on a USB drive (i.e. USB booting).
# To prevent this issue from happening, update the rule to skip the booting USB drive.
# See the CAUTION message below.
#
# Source of inspiration:
# https://www.axllent.org/docs/auto-mounting-usb-storage/
#
# Useful links:
# https://wiki.archlinux.org/index.php/Udev
#
# udev commands:
# - Restart udev to reload new rules:
# udevadm control --reload-rules
# - List device attributes of sdb1:
# udevadm info --attribute-walk --name=/dev/sdb1
# - List environment variables of sdb1:
# udevadm info /dev/sdb1
# - Trigger add/remove event for sdb1:
# udevadm trigger --verbose --action=add --sysname-match=sdb1
# udevadm trigger --verbose --action=remove --sysname-match=sdb1
#
# Filter on block devices, exit otherwise
# CAUTION: Change to 'sd[b-z][0-9]' if booting from a USB drive (e.g.: sda)
KERNEL!="sd[a-z][0-9]", GOTO="abort_rule"
# Skip none USB devices (e.g.: internal SATA drive)
ENV{ID_PATH}!="*-usb-*", GOTO="abort_rule"
# Import the partition info into the environment variables
IMPORT{program}="/usr/sbin/blkid -o udev -p %N"
# Exit if partition is not a filesystem
ENV{ID_FS_USAGE}!="filesystem", GOTO="abort_rule"
# Exit if this is the 'CONFIG' USB key
ENV{ID_FS_LABEL}=="CONFIG", GOTO="abort_rule"
ENV{ID_FS_LABEL}=="hassos-data", GOTO="abort_rule"
# Get the partition name if present, otherwise create one
ENV{ID_FS_LABEL}!="", ENV{dir_name}="%E{ID_FS_LABEL}"
ENV{ID_FS_LABEL}=="", ENV{dir_name}="usb-%k"
# Determine the mount point
ENV{mount_point}="/mnt/data/supervisor/media/%E{dir_name}"
# If filesystem is ntfs, use the ntfs3 driver, so we get rw support
# Home Assistant Operating System 8.0 or later required! (linux kernel 5.15)
ENV{ID_FS_TYPE}=="ntfs", ENV{fstype}="-t ntfs3"
ENV{ID_FS_TYPE}!="ntfs", ENV{fstype}="-t auto"
# Mount the device on 'add' action (a.k.a. plug the USB drive)
ACTION=="add", RUN{program}+="/usr/bin/mkdir -p %E{mount_point}", RUN{program}+="/usr/bin/systemd-mount %E{fstype} --no-block --automount=no --collect $devnode %E{mount_point}"
# Umount the device on 'remove' action (a.k.a unplug or eject the USB drive)
ACTION=="remove", ENV{dir_name}!="", RUN{program}+="/usr/bin/systemd-umount %E{mount_point}", RUN{program}+="/usr/bin/rmdir %E{mount_point}"
# Exit
LABEL="abort_rule"
@zeehio
Copy link
Author

zeehio commented May 15, 2022

@NPC-112
Copy link

NPC-112 commented Jul 9, 2022

I successfully installed your file, but when i plug in the usb hdd, the folder it creates in /media is empty. All file changes do not reflect onto the drive, it is only a local folder. Any input on this?

As HAOS boots, some of the start up messages are
Mounting /mnt/data/supervisor/media/Storage.
[FAILED] Failed to mount /mnt/data/supervisor/media/Storage.
See 'systemctl status mnt-data-supervisor-media-Storage.mount' for details.

but when running the command systemctl status mnt-data-supervisor-media-Storage.mount it says the unit cannot be found.

@zeehio
Copy link
Author

zeehio commented Jul 9, 2022

I guess the mount command is failing. I guess the mnt-data-supervisor-media-Storage.mount unit exists in some container. Anyway the journalctl command should give the error in some log, but I'm not sure in which container it should be run. I hope these tips help you

@zeehio
Copy link
Author

zeehio commented Aug 25, 2022

The last revision excludes hassos-data partitions from being mounted as suggested at https://gist.github.com/eklex/c5fac345de5be9d9bc420510617c86b5?permalink_comment_id=4278670#gistcomment-4278670

@MuellerNicolas
Copy link

Hello @zeehio , I am facing the same problem with my ntfs ssd, that no files are written onto it, but it get's displayed in /media.
Even your solution with the adapted 80-mount-usb-to-media-by-label.rules is not working. Can you give me any hints how/ where to "debug" this problem?

Thank you in advance :)

@zeehio
Copy link
Author

zeehio commented Dec 31, 2022

@MuellerNicolas Maybe the drive was not unmounted properly. I guess you could plug it on windows and check it is all right... I don't think I can be of more help

@ttreker
Copy link

ttreker commented Mar 7, 2023

What I found that made things much easier may not be easy for everyone: format the the drive to be mounted under Linux as ext4 and the USB stick (this latter format may be unnecessary but I did it anyway) and use Linux tools to populate the config as prescribed in the doc which will then address the Linux-line-ending issues and likely the files will be in ANSI format (they were for me on a hex dump). This eliminates all of the weird mounting problems and getting the udev rule just right regarding the file system on the extra drive because it is a native format to Linux. Use the instructions gleaned from the above notes in this and other posts regarding the process and getting a drive mounted will be fast and a no-brainer. (There is also a video out there somewhere-- can't find it at this moment-- stepping through its version of this process that is a good reference but the steps are a little more involved than the straight-up Linux approach).

There is a big caveat to my pure-Linux approach: Once the USB disk has succeeded in being persistently mounted Samba reports the size of the HA OS partition, not the USB disk's. Windows File Explorer checks size of what is being copied against the target so will fail if what is being copied is larger than available space on the HA OS partition (which happened to me copying my music folder over). I didn't try to resolve this with File Explorer so there may be a trick I didn't discover to get around this issue. Instead my solution was that I run Cygwin and so just copied from the Cygwin command line (cp) which doesn't check target size. I run Linux in a virtual machine on Virtualbox and could have just done all of this from there. However, I made the error of deleting the USB stick partition before I passed control of the USB stick to the VB VM. Consequently, VB/Windows wouldn't pass the USB to the Linux VM. Makes no sense but it painted me into a corner;

So this did get convoluted for me as I now need to format the USB stick on an actual Linux box rather than a Windows-hosted VB VM. It became a chicken-and-egg problem: I wanted to use the HA OS hardware platform to partition and format my USB stick but I needed the configured USB stick to get to the HA OS to do the format! My trick was to use:

https://community.home-assistant.io/t/add-on-hassos-ssh-port-22222-configurator/264109

This required several HA OS system reboots making it time consuming but it is straight forward.

The upshot:

I now have an ext4 USB that will mount to my VB Linux VM so that I can modify it in the future. The HA OS will load this config quickly from here on out.

Summary:

  • If you can prepare the CONFIG (labeled) USB stick all in Linux (although it probably will work as a FAT USB stick as long as you ensure the config file's text format is Linux line-endings and ANSI text which is likely a no-brainer if prepped under Linux using Linux tools).
  • If formatting under a VM delete the partition under the VM, not Windows as once deleted Windows may not pass the USB stick to the VM.
  • Format the USB disk being added to the media folder as ext4 and it will just mount if the config is correct.

Another way to sum this up for those comfy at the Linux CLI: Think in Linux and things will go much smoother!

(Btw, VSCode has a way to explicitly set text format but this is a little bit of research project as my understanding is ANSI is labeled using a modern standards-based nomenclature and you want to be sure to select the right format or you'll be battling this. Linux is likely the easiest approach and everything will probably just work).

If you can follow this process it will probably take 10-15 mins to get a USB drive persistently mounted under the media share. A good portion of that time will be rebooting the HA OS and restarting HA.

Hopefully this explanation isn't too convoluted for those familiar with Linux. I suspect it isn't helpful to those not comfy on with Linux.

Note: it is unlikely I will be replying to any questions so you'll have to take this post as is. Also, this post has assumed knowledge from previous attempts to mount an external drive so I have assumed a general understanding of the approach described in a bunch of other posts and the HA developer doc.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment