Monday, 15 April 2013

Stateful re-exec for Upstart Sessions? You bet!

As of Upstart 1.6, restarting PID 1 is supported without losing state. So as soon as you get an update to either Upstart itself or one of its dependent libraries in Ubuntu, you'll be running the new version automatically, without the need for a reboot.

But what about User Sessions? Are they "second-class citizens"? Of course not! When PID 1 restarts, all the running Session Inits will automatically restart too. You won't notice this of course as your desktop session will continue to run and be fully functional but you too will be running the latest version of Upstart.

How does this work? When an instance of Upstart has restarted, it signals this fact over D-Bus. From the user perspective, the upstart-event-bridge, listening to the system instance of Upstart running as PID 1, will generate a ":sys:restarted" event when it detects the restart. This in turn will cause the session job /usr/share/upstart/sessions/re-exec.conf to run. And that job requests the Session Init restarts. Since all Session Inits will have the re-exec job registered, all Session Init instances will restart as soon as PID 1 does.

To convince yourself, let's create a session job that will start when your Session Init restarts. We'll do this by having the job start when the re-exec job has finished:

$ cat >$HOME/.config/upstart/restart.conf<<EOT
start on stopped re-exec
exec xclock

Now, let's force Upstart running as the system init daemon to restart:

$ sudo telinit u

You should now see xclock running!

Note that the job could have specified any of the following start on conditions...

  • start on starting re-exec
  • start on started re-exec
  • start on stopping re-exec
  • start on stopped re-exec
  • start on :sys:restarted
... however, I chose "start on stopped re-exec" because I want xclock to run just after the re-exec job has finished.