Skip to content

Instantly share code, notes, and snippets.

@dlitz
Last active May 21, 2026 12:35
Show Gist options
  • Select an option

  • Save dlitz/4e78fa5bd02ab28f62932c1b0b180cac to your computer and use it in GitHub Desktop.

Select an option

Save dlitz/4e78fa5bd02ab28f62932c1b0b180cac to your computer and use it in GitHub Desktop.
HAOS virtiofs hack
# dlitz 2025
ACTION!="remove", DRIVER=="virtiofs", RUN{program}+="/etc/udev/rules.d/dlitz-mount-virtiofs %n"

This is meant more for reading & understanding than for running as-is.

Basically put this in a folder on the host, and set up a virtiofs filesystem on the VM pointing to that folder. If the tag name is "localdata", then do mkdir /mnt/localdata ; mount -t virtiofs localdata /mnt/localdata and then run /mnt/localdata/install-rules.sh to install the udev rule into HAOS.

#!/bin/sh
# dlitz 2025
set -eux
number="$1"
tag=$(cat "/sys/fs/virtiofs/${number}/tag")
case "$tag" in
# backup|media|share|ssl)
# mntpt=/mnt/data/supervisor/"$tag"
# run_script=
# ;;
localdata)
mntpt=/mnt/data/"$tag"
run_script=1
;;
*)
exit 0
;;
esac
rc=0
systemd-run -u "dlitz-mount-virtiofs-run@${tag}.service" --slice-inherit --wait --quiet --collect \
mount --onlyonce -t virtiofs "$tag" "$mntpt" -o rw || rc=$?
if ! ( [ "$rc" -eq 32 ] && mountpoint -q "$mntpt" ); then
exit "$rc"
fi
if [ "${run_script:+1}" ] && [ -x "$mntpt/postmount" ]; then
systemd-run -u "dlitz-mount-virtiofs-postmount@${tag}.service" --slice-inherit --wait --quiet --collect \
/usr/bin/env "number=$number" "tag=$tag" "mntpt=$mntpt" "$mntpt/postmount"
fi
#!/bin/sh
# dlitz 2025
set -eu
if ! test -e /mnt/data/supervisor; then
echo >&2 "error: This should be run inside the HaOS image."
exit 1
fi
cp -av 80-dlitz-mount-virtiofs.rules dlitz-mount-virtiofs /etc/udev/rules.d/
#!/bin/sh
# dlitz 2025
# Performs bind mounts after the virtiofs is mounted
set -eux
run_cmd() {
if [ "$tag" != "localdata" ]; then
echo >&2 "would run: $*"
else
"$@"
fi
}
umask 022
# Edit these to be whatever makes sense for you.
for d in \
"addons/local" \
"addons/data/5c53de3b_esphome" \
"backup" \
"media" \
"share" \
"ssl" \
"homeassistant/blueprints" \
"homeassistant/esphome" \
"homeassistant/local" \
"homeassistant/www/local" \
; do
run_cmd mkdir -m000 -p /mnt/data/supervisor/"$d"
run_cmd mount --onlyonce --bind "$mntpt/$d" /mnt/data/supervisor/"$d" || true
done
for f in \
homeassistant/configuration.yaml \
homeassistant/secrets.yaml \
; do
if ! [ -e "/mnt/data/supervisor/$f" ]; then
run_cmd touch /mnt/data/supervisor/"$f"
fi
run_cmd mount --onlyonce --bind "$mntpt/$f" /mnt/data/supervisor/"$f" || true
done
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment