A different proposal for XO upgrade.
C. Scott Ananian
cscott at laptop.org
Mon Jun 25 17:51:19 EDT 2007
As food for discussion, here's a counter proposal for an XO upgrade
mechanism, focusing on the network side.
---------
Design goals:
- minimize round-trips necessary for successful upgrade
- minimize size of upgrades
Software versions are assigned sequential integers. Version 1, 2,
etc. We assume that every machine should discover an available
upgrade within a day, on average. The constants below can be tweaked
to adjust this interval.
Upgrades consist of a number of messages U_0 through U_N with a
maximum size Umax. The maximum size is chosen either so that a) each
U_i fits in a single network packet, or b) each U_i can fits into a
reserved storage area on the XO (to allow it to be shared with
neighbors). Upgrade messages are independent. It may be worthwhile
for upgrade messages to be applied in any order, but for simplicity
we'll constrain the order of application to be sequential. U_i is
authenticated and self-labeling: it contains a signature as well as a
field specifying the version # of the upgrade as well as i, the
sequence number of the upgrade message.
Part 1: discovering an upgrade.
Every hour, the XO looks to see how many mesh neighbors it has,
counting itself. Call this number N. N is always at least 1.
It then generates a random number in [0, N*24). If the number is
0, does a DNS lookup on update.laptop.org to check for a new
version. (Note that the DNS lookup may be cached by the mesh portal
or school server.)
XOs which have version V of the base system also listen to the
multicast address xxxx:yyyy:zzzz::<V+1>
Part 2: announcing the upgrade.
If you are the person to discover a new version V', you are the
Upgrade Leader. While the version on your laptop (V) is less than V' do
the following:
a) Set i=0. Stop listening to the multicast address.
b) download U_i for (V+1) via http from update.laptop.org (again,
these queries are often cached by a school server). Apply it
to our local copy (using COW techniques to prevent the
application from being globally visible until the upgrade is complete)
c) Broadcast U_i to the multicast address xxxx:yyyy:zzzz::<V+1>.
d) If U_i is not the last upgrade message, increment i, and repeat
from step b)
e) Otherwise, atomically make our updates visible to the system,
increment V, and restart part 2 if necessary.
f) Start listening to the multicast address xxxx:yyyy:zzzz::<V'+1>
Part 3: casual bystanders.
If you hear a piece of the upgrade U_i on the multicast address
xxxx:yyyy:zzzz::<V+1>:
a) If there is a piece U_j between U_0 and U_i which you have not
already heard, ignore this packet.
b) Otherwise, apply U_i and (re)set the Upgrade Timer to expire
some random time in the future (some 10s of minutes).
c) If U_i was the last upgrade message, atomically make the
updates visible, delete the Upgrade timer, increment our local
version, and rebind our multicast listening address to
xxxx:yyyy:zzzz::<V+1> for our new version V.
d) If the Upgrade Timer expires, become a new Upgrade Leader:
set i = the smallest i such that we don't have U_i,
and jump to Part 2 step b.
----------------------
Structure of upgrade messages:
<Version # from>
<Version # to>
<Sequence #>
<final message flag?>
<msg length>
1 or more of:
<filename to patch>
<pre-patch hash>
<post-patch hash>
<bsdiff format diff>
<signature>
We might keep a git-style manifest for system, patching this like any
other file. This can be used like fsck to sanity-check/verify the
end-result.
Further, although the 'from' version and 'to' version are separated by
exactly 1 in typical usage, a sequence of upgrade messages can be used
to perform any desired amount of up/down grade. I would propose
keeping 'up-by-one' and 'down-by-one' upgrade message sequences on
update.laptop.org, so that the user can downgrade to any chosen
revision. We might either store 'skip-by-N' sequences on the server
(for N=1,2,4,8,16,32,...) or generate upgrade messages on the fly if
we want faster/further upgrades/downgrades.
---------------------
Notes:
a) the school server can trigger updates on all machines by becoming
an Upgrade Leader and broadcasting bits.
b) Upgrades are distributed very efficiently over the air if
mesh broadcast is working (ie, not too many nodes drop packets). It
could be even more efficient if we were allowed to cache entire
upgrade message sequences on the XO and/or apply upgrade messages
out-of-order.
c) The Upgrade Timer timeout should probably depend on the number of
messages in the upgrade and the # of the message you lost.
d) Although I've described the process above as an automatic
upgrade, once the sequence of upgrades has been applied, the actual
atomic swap of current-tree to upgraded-tree could be deferred until
some point in the future.
e) Limiting the size of the upgrade messages U_i is primarily done
by limiting the # of files patched by a particular message.
However, we can also split bsdiff patches: bsdiff messages
consist of a control block specifying a # of operations to
perform on the input file to create the output file. We can
split the control block into pieces to create multiple smaller bsdiffs
from a monolithic diff. This is where it would be tricky to
allow upgrade messages to be applied in any order.
f) If we distribute any gzipped files (do we?) we should be sure to
use the --rsyncable option to gzip to ensure efficient binary
diffs.
--
( http://cscott.net/ )
More information about the Devel
mailing list