We just released UpdateHub Agent v2.0

Jonathas Conceição
O.S. Systems
Published in
5 min readMar 9, 2021

We are happy to announce the release of UpdateHub Agent v2.0, a fully rewritten version of our IoT Application for OTA updates with some overall improvements. In this article, we will be talking about some of the main changes to the UpdateHub Agent that come with this new version.

The UpdateHub has been fully rewritten in Rust, but be aware, this is not a language comparison as the internal implementations have also changed considerably from the original Go implementation we had for the UpdateHub Agent v1.1.

We want to start by sharing some of the major problems we’ve faced with the past version of the UpdateHub Agent. The main one we faced was about “memory usage predictability”, given the tight restrictions that some embedded devices enforce us, Go’s model of occasionally running a Garbage Collector, took away some of the control we needed to achieve the required performance. Memory usage would reach a peak only when installing a new update due to the need to decompress data and heavy write to disk, which was mostly handled by libarchive, but even when the agent was idle (e.g. waiting for a time to probe the UpdateHub Cloud for a new update) there would still be a considerable memory footprint.

Another point that definitely needed an improvement was the overall logging of the application. Finding both software and hardware malfunctions is a common task we get from our clients here at O.S. Systems, so having a complete and clean log for our update process is very important to help to look for potential issues. The application would also send its log to the UpdateHub Cloud when an update had failed, but the overall logging lacked some important points that would have helped us find the source of the error.

In order to fix the major issues we had with the UpdateHub Agent, we decided to rewrite the software from scratch. Mainly due to how memory management works in Rust, we decided to give the language a try for this version, not to mention that we are always excited about new technologies. Rust model’s of ownership and the guarantee of having a segfault-free software was satisfactory since the early development stages.

We also starting adding detailed logging of operations in different levels from the beginning. But the main improvement to log was the new feature we added to access the log of the last update cycle by the agent; this makes it especially useful for investigating bugs when an update process doesn’t go as expected. This last operation log is also sent to the UpdateHub Cloud if something goes wrong, making identifying faulty updates easier even without having direct access to the device.

We also took advantage of the full rewrite to simplify some aspects of the agent internal code structure to be more extensible and easy to maintain. The State Change Callback Scripts, which can be used to add custom hooks to specific states (e.g. turning Wi-Fi on before probing the UpdateHub Cloud for updates), were simplified to avoid some redundancy while maintaining the same usability. The internal State machine has also been updated to better represent the handle of use requested actions like the installation of a local package, or the command to cancel the download of a new update.

We have collected some data to compare how the memory usage has changed from the UpdateHub Agent v1.1 to this new v2.0 release. We used a RaspberryPi 3B+ to fetch and install the very same system update package, we used mprof to measure the residual memory the application consumed from the probe time till the agent was ready to reboot the device into the new installation. Here’s the memory usage plot:

Memory usage from fetch to install of an update package.

Both versions have a very similar increase in memory usage since the process to install a package has not changed much, and the new version also uses libarchive for handling compressed archives. But the residual memory both before and after the heavier workload had some significant decrease. The overall installation time has also been smaller for the UpdateHub Agent v2.0 which is always a good thing.

We also captured the residual memory usage of the Agents without having an update available and probing the server every minute. In this case, we can see that the new version not only has a lower memory footprint but also keeps a steady memory usage over time. Agent v1.1 shows a small (but constant) increase in memory usage due to how to Go’s runtime doesn’t fully release resilient memory unless the OS actually needs more memory.

Idle application’s memory usage.

Another important parameter when it comes to IoT devices is binary size. On this front, however, we actually had a little fallout. Rust’s micro-dependency model has not been kind to us, and even after some tweaking of our major dependencies we still ended up with a slightly bigger binary.

What we did to have some improvement in binary size was to combine the Agent application with its command-line app, which was previously separated from the agent in v1.1. Since not everyone that uses the UpdateHub Agent actually needs the CLI controller, this is not exactly a win for the v2.0 release but is still an important parameter to share.

Binary size comparison between versions

We have been working on this v2.0 release on and off for a long time due to some other project for our clients. But through the whole process over these past two years of development, we have always been excited about the new changes. The biggest advantage is that the overall code structure of the newly rewritten agent has been improved, and now that it’s finished we can start to look at the new features and improvements we can make.

The next feature we are eager to release is the support for Differential Updates, a way to only download and install the chunks of data that has actually changed from one version to another. Right now we are exploring the use of bita for it, a well-performing tool also written in Rust that supports Differential Updates for file synchronization.

If you wanna keep up to date with the lasted changes to the UpdateHub Agent be sure to follow us on GitHub at https://github.com/UpdateHub/updatehub

--

--

Jonathas Conceição
O.S. Systems

Computer Scientist from Brazil. Interested in programming languages, concurrent and parallel systems, high performance, open source software, GNU/Linux and IoT.