I think that I'm the only user of relsync with nerves, but just in
case there are others, I'm in the process of updating things. Here's
the story:
relsync lets you update the contents of an Erlang/OTP release on a
target using the Erlang distribution protocol. Basically, instead of
burning a new SDCard, you run relsync and the target is updated from
your build machine in a couple seconds. It works sort of like Rusty
Klophaus's sync project except that it also synchronizes files in the
priv directory (so that you can update ports) and it can automatically
run a script to stop and start your app.
A while ago, I found out that if relsync actually wrote the updates to
the SDCard that it was really easy to break things enough that you'd
need to reflash the SDCard on the build machine. E.g., if your updated
application no longer starts and you reboot, the board will fail
initialization, and you'll need to remove the SDCard, put it in your
PC, and reprogram it. Because this was a pain, I switched all of the
platforms to use a union filesystem. The idea was that the base SDCard
would be unmodified and all relsync updates would be to a temporary
writable filesystem that was layered on top of SDCard's filesystem.
The tradeoff was that if you rebooted, any relsync'd changes would be
lost, but the system would always reboot. It worked pretty well for
me.
Everything was good again until Garth noticed a weird UnionFS and EXT4
corruption issue that only appeared to happen on x86. I have since
learned that union filesystems on Linux are not bug free (there's a
reason Linus hasn't merged one into the kernel even though people have
been trying for 10 years or so). You can get them to work, but there
are gotchas, and cross-compilation doesn't make things easier.
Here's what I'm doing: I just updated relsync to support sync'ing to a
writable directory that is different from where the release exists on
the SDCard. I do this by replicating the original release tree in the
writable directory, copying in the changed files, and using symlinks
for all the files that didn't change. I then update the Erlang VM's
search path to point to the writable location instead and force
reloads for changed modules. This works, doesn't require a unionfs,
and has the same features as the old unionfs relsync that I liked.
Since union filesystems have been so much of a distraction and they're
not as directly useful for Nerves anymore, I'll be ripping support for
them out of default nerves configurations and erlinit. Those of you
who don't use it might notice your kernel shrinking by 10s of KB, but
that's it. Please let me know if you use union file systems with
Nerves for some other purpose, and I'll see what I can do.
Frank
--
Frank Hunleth
Troodon Software LLC
Embedded Software Development
http://troodon-software.com/