Thursday, August 4, 2016

FreeBSD on a tiny system; what's missing

Now that I'm trying to use more userland services, there are some obvious shortcomings which need addressing.

The first is a lack of real service management. FreeBSD doesn't have a service management daemon - the framework assumes that daemons implement their own background and monitoring. It would be much nicer if init or something similar to init could manage services and start/restart them where appropriate. Yes, this is one of those arguments for systemd. Eg, maybe I want to only start telnetd or dropbear/sshd whenever a connection comes in. But I'd also like to be able to add services for monitoring, such as dnsmasq and hostapd.

The next is a lack of suitable syslog daemon. Yes, I'd like to be able to log some messages locally - even if it's only a couple hundred kilobytes of messages. I'd also like to be able to push messages to a remote service. Unfortunately the FreeBSD syslog daemon doesn't do log rotation or maximum log file sizes itself - it's done by "newsyslog" which runs out of cron. This isn't any good for real embedded systems with limited storage.

Then yes, there's a lack of a cron service. It'd be nice to have that integrated into the service management framework so things could be easily added/removed. I may just use cron, but that means cron is also always running which adds memory footprint (~1.3 megabytes) for something that is almost never actually active. When you have 32MB of RAM, that's quite a bit of wasted memory.

Finally, there's a lack of some message bus and notification mechanism for device changes. For example, openvpn-client creates a tunnel device - ok, so what should then check to see if a NAT configuration needs updating? Or updated firewall rules? It can be done with shell scripts (which I'll write tomorrow) but ideally there'd be something like dbus (a dirty word, I know) where these systems could push updates to and events could be triggered from them. I'd like to be able to run ntpdate whenever an interface comes up, because yes, there is no RTC on this hardware.

With all of the above in mind, I'll start working on some of it tomorrow. Hopefully I can automate the openvpn NAT configuration a little bit more so I can optionally have wifi NAT or openvpn NAT, depending upon the current requirement. Fixing ntpdate to run out of dhclient as part of the 'up' script may be helpful. I'll see what else I can do to tidy things up before I start the process of merging all of this back into freebsd-wifi-build.

At least this year I can now use the defcon wireless with all of my devices.


  1. You might want to look at s6 and s6-rc. The design is clean and portable enough to work on FreeBSD out of the box even if it's written for Linux. I have s6-svscan working as PID 1 on FreeBSD 10.3 in a test VM and it reduces the userspace boottime to < 1s.

  2. We're using s6 at work, and it works out mostly ok. Mostly once you get around the linuxisms, and the lack of sensible time code in it (its calculations for daemon run duration is based on system time, not wall clock, so if your box boots jan 1, 1970 then gets NTP, things are.. hilarious), and some of the arcane bits to get logging working right.

    But mainly it's how many processes and memory it uses - these boards can have 16MB or 32MB of RAM, so every process adds overhead. I'm thinking of either jobd or writing something single process and lightweight (based on BSD init, and minimal bits from jobd/launchd) because of the insanely small memory footprints for 2016.

    Damned IoT.

  3. devd can do the ntpdate thing, and likely the other stuff that happens when an interface comes up

  4. I'm the author of jobd, and it does sound like your needs mesh well with the design goals of jobd. If you end up hacking on jobd, I'd be interested to hear about it, and willing to take any patches to improve efficiency on tiny hardware.

    It uses kqueue(2) to dispatch events from a single master process, so you don't end up with multiple supervisor processes like in other solutions.

    It's cron emulation code tries to avoid unnecessary wakeups. Unlike tho original cron, which wakes up every minute, jobd only wakes up when there is at least one job that is ready to run. For example, if you had a single cronjob that ran once per hour, it would sleep for an entire hour before waking up to run the job.

    The question about IPC and notifications is another area where I want to improve jobd and offer a simple event notification system. Even without an IPC mechanism, you could do things like have jobd watch a file or directory for changes, and then launch a job when a change is detected.

  5. hi ,

    i have try all the steps given by you and which is present on the to run freebsd on mips processor . i have run the after doing all the neccessary settings , but when i run it using qemu it through an error that no kernel found .

    can you help me in getting out of this , or you can provide me the image which you build for freebsd / mips .