fixing unison on termux
2026-06-16
Today i spend a bit of time fixing my sync tool on Termux. it had an issue where it complained about lockfiles, despite there being none. it worked fine with -ignorelocks, so i decided to use an llm to try and fix the bug.
I don't know OCaml or how locking works on android, but here's what we came up with (unison now works just fine without -ignorelocks):
first, we tested if hardlinks work on my termux $HOME. they do not.
Unison tries that hardlink trick because NFS has apparently previously caused issues. For my use case, if the files are on a remote server already, why would i need unison? So we simply drop that harlink trick.
claude's solution:
The right fix for your case
Since hardlinks are simply unavailable (not unreliable as on NFS), the hardlink trick is pointless here. Use the O_EXCL path, which works fine on local f2fs. Given that you don't care about NFS or sdcard, the simplest, most robust change is:
let acquire name =
Util.convertUnixErrorsToTransient
"Lock.acquire"
(fun () -> create name 0o600)
This drops the hardlink dance entirely and relies on open(O_WRONLY|O_CREAT|O_EXCL), which is atomic and reliable on f2fs.
This applies to the file src/lock.ml, simply replace the previous "acquire" function.
for completeness, the full (upstream) acuqire function:
let acquire name =
Util.convertUnixErrorsToTransient
"Lock.acquire"
(fun () ->
match Sys.unix with
| true -> (* O_EXCL is broken under NFS... *)
rename (unique name (Unix.getpid ()) 0o600) name
| _ ->
create name 0o600)