FreeBSD unionfs deadlock
Mark Elvers
1 min read

Categories

  • FreeBSD,unionfs

Tags

  • tunbury.org

FreeBSD Jails provide isolated system containers that are perfect for CI testing. Miod ported OBuilder to FreeBSD back in 2023. I have been looking at some different approaches using unionfs.

I’d like to have a read-only base layer with the OS, a middle layer containing source code and system libraries, and a top writable layer for the build results. This is easily constructed in an fstab for the jail like this.

/home/opam/bsd-1402000-x86_64/base/fs /home/opam/temp-2b9f69/work nullfs ro 0 0
/home/opam/temp-2b9f69/lower /home/opam/temp-2b9f69/work unionfs ro 0 0
/home/opam/temp-2b9f69/fs /home/opam/temp-2b9f69/work unionfs rw 0 0
/home/opam/opam-repository /home/opam/temp-2b9f69/work/home/opam/opam-repository nullfs ro 0 0

Running jail -c name=temp-2b9f69 path=/home/opam/temp-2b9f69/work mount.devfs mount.fstab=/home/opam/temp-7323b6/fstab ... works as expected; it’s good enough to build OCaml, but it reliably deadlocks the entire machine when trying to build dune. This appears to be an old problem: 165087, 201677 and unionfs. There is a project aiming to improve unionfs for use in jails.

My workaround is to create a temporary layer that merges the base and lower layers together. Initially, I did this by mounting tmpfs to the lower mount point and using cp to copy the files. The performance was poor, so instead I created the layer on disk and used cp -l to hard link the files. The simplified fstab works successfully in my testing.

/home/opam/temp-2b9f69/lower /home/opam/temp-2b9f69/work nullfs ro 0 0
/home/opam/temp-2b9f69/fs /home/opam/temp-2b9f69/work unionfs rw 0 0
/home/opam/opam-repository /home/opam/temp-2b9f69/work/home/opam/opam-repository nullfs ro 0 0

FreeBSD protects key system files by marking them as immutable; this prevents hard links to the files. Therefore, I needed to remove these flags after the bsdinstall has completed. chflags -R 0 basefs