Hi all,
I'm a final year undergraduate Computer Science student hoping to
participate in Google's Summer of Code. I'm interested in systems
programming and C, despite having little exposure throughout my degree,
having read K&R and Advanced UNIX Programming in the UNIX Environment
(Richard Stevens) in the past year or so. I'd love to get some
real-world, concrete experience with systems programming and open
source development.
I'm interested in tackling the idea for an automatic host upgrade daemon and
I've outlined my potential approach with some high-level technical detail below.
Does it look like I'm on the right track in my thinking?
Best regards,
Brian.
===========================================================
I propose writing the host upgrade daemon in C.
- Set up daemon
This can be done by having init fork and exec
our host upgrade
daemon. Then, we perform necessary set-up calling setsid to
become the session leader, setting umask to a known value,
close all open descriptors inherited and open 0,1,2 to log or
to /dev/null.
Alternatively, instead of having init fork and exec the daemon
we could have the daemon be an executable that forks and exits,
before carrying out the rest of the set-up.
- Monitor the status of available downloads.
We can use
libcurl (
https://curl.haxx.se/libcurl/) to download the
update and monitor status or, if needed, do some socket programming.
- Apply the Atomic update delta
This is an area I'm
unsure of how to tackle - how do you programmatically
update the changed parts of files? Is there pre-existing functionality
already present?
- set a "boot once' flag to boot the new version via grub
We could modify /boot/grub/grub.conf to boot once-only, allowing us to
boot the new version while also being able to revert if the new version
fails. Or, we could augment the file to specify the old version as a
fallback
- set a hardware watchdog
A hardware watchdog can be set by
writing to the block device
/dev/watchdog periodically (if the timeout elapses and watchdog is not
written to, a reboot occurs).
- initiate a reboot of the system
use reboot(2)
- if boot to normal userspace fails the watchdog triggers and it
resets
to the old version
This should be covered by the above.
- if boot succeeds to the point the daemon starts up it then proceeds
to phase two of the upgrade process.
This could be handled by checking a flag at the beginning of execution
of the program. However, since we're rebooting it can be a flag in
memory, so we could write to a file (maybe the version) and then
check if the current version is the same as the written one. If it is
then the reboot failed, else it succeeded and we carry out phase two.
- unsets watchdog so the OS won't reset
stop watchdog by
writing 'v' to /dev/watchdog and closing the file.
- checks it can see all required network interfaces
We can
get a linked list of all local network interfaces using
getifaddrs(3) and check for presence of required interfaces.
- checks it can resolve addresses and contact the update server
We can use getaddrinfo() here to verify DNS look-ups are still okay.
- Check it's connected to all other critical services
We
can use getaddrinfo() and connect(), checking if they were
successful in order to determine this.
- Checks it can see all sensors and services are running correctly
Checking sensors is something I wouldn't be too familiar about.
We can check processes and services to be present with kill() and
sig==0.
Some manner of specifying what defines critical services for a
particular device needs to be supplied. The most obvious proposal
would be some file where critical components can be specified.