How to let user set the hostname of the device dynamically/writable /etc/?

Hi folks. For a project I’m working on I’d like the user to be able to set the hostname of the device dynamically. This means I need to write to /etc/hosts and /etc/hostname. I was thinking that rather than mounting the firmware folders as writable (and this /etc) - I was wondering if it is possible to mount /etc as tmpfs (or overlay) and copy the contents into it as part of the system bootup?

Anyone know how to do that or have any other more sensible suggestions?

2 Likes

For what purpose? So other things can resolve over mDNS or for some internal purpose?

I know for the Balena Engine system Steffen solved the need for a particular file with a rootfs_overlay and a symlink to /data:

Maybe that serves the need?

2 Likes

This is a really good question since it gets at the boundaries of what’s in the Erlang runtime and what’s in Linux. The files are handled differently in Nerves.

/etc/hosts

Writing configuration to /etc is a common for Linux daemons, but Nerves uses functionality provided by Erlang when possible. For name resolution, Nerves uses Erlang’s inet application (inet_res specifically). The default configuration file is /etc/erl_inetrc. As you can see, it loads hosts from /etc/hosts so you’re in the same situation if you want to update it.

I hope that you really don’t need to update this file, but I’d use the symlink trick of adding a symlink in /etc to a writable file in /root or /tmp. This can be done in your project’s rootfs_overlay. You could also supply a custom erl_inetrc to move the hosts file. The flaw with the latter is that non-Erlang programs won’t know the new place, but that might not be an issue for you.

The name resolver reads /etc/hosts a lot, so you can update it dynamically.

Just as a side note since you brought it up, you can use overlayfs with Nerves to mount a writable filesystem on /etc. It’s not my favorite route, since I like the simplity and specificity of the symlink trick. However, search around the erlinit docs and tests for the --x-pivot-root-on-overlayfs option. OverlayFS is probably more interesting for persistent Erlang hot code updates with Nerves.

/etc/hostname

This file is read once on boot by erlinit, but only if your erlinit.config doesn’t specify a different way of getting the hostname. It’s really common to set a custom hostname by running a program to read an EEPROM, construct it from an Ethernet MAC address, or read some other place that has a unique serial number.

The erlinit docs talk about this generally. When you look through erlinit.config files in Nerves systems, you’ll see calls to the boardid program. boardid is super configurable so without knowing more about your situation, I’d just suggest to try using it first.

After you dynamically change the hostname, you’ll need to reboot. This is fixable in theory since it’s “just” a system call to change the hostname. The catch is that many programs cache the hostname, so you’ll need to restart them too, and in the end, rebooting might be easiest.

5 Likes

thanks for the incredibly detailed reply @fhunleth

1 Like