[RFC] Fixing the machine id
Lennart Poettering
mzqohf at 0pointer.de
Fri Mar 4 13:40:36 PST 2011
heya,
one problem the D-Bus machine ID has for usage in various programs is
that it is not available during early boot. Kay and I have been thinking
about this for a while, and the obvious fix is of course to move it from
/var/lib to /etc which is guaranteed to be around right from the
beginning, and is the better place for it anyway, since it is everything
but variable.
Another small issue is that the generation of the id happens at boot
time instead of installation time. (This has the advantage though that
shipping the same OS image is easily doable, becuase they end up using
different is when booted.)
Fixing this second issue is more difficult in /etc, since that directory
is usually read-only during boot, hence we cannot generate the ID
automatically at boot anymore. Or can we?
Thinking about this Kay and I came to the following solution, and I'd
like to ask you for comments on this:
First of all we decided to move the generation of the ID into systemd,
for multiple reasons: it seems like a more appropriate place to maintain
it, given that it is machine and not bus specific; we already maintain
the hostname from /etc/hostname, and hence doing /etc/machine-id too is
only symmetric; we can do mount magic as described below much easier;
and we move the machine id out of the D-Bus context into a distro
context thus hopefully convincing more folks to use it instead of the
host name.
So, here's what systemd now does at boot: when it finds /etc/machine-id
populated, then everything is fine. If it is not populated, it tries to
initialize it from /var/lib/dbus/machine-id, with a fallback on
/dev/urandom. If that works, then everything is fine. If it doesn't but
the file exists and is suitable as mount point we instead store the id
we generated in a file in /dev/.systemd/ and then bind mount it over
/etc/machine-id. If that works, then everything is fine. If that doesn't
work or we cannot create the mount point then we simply fail and give
up.
Yes, on Linux you can bind mount not only directories, but also files.
At package installation time the same algorithm is used, to ensure the
validity of the machine id, at a time where we can actually write to
/etc. If people want to support state-less systems they can simply
create /etc/machine-id empty (so that it is useful as a mount point when
the system boots up and systemd wants to initialize the id) and it will
be mounted over at boot time with a dynamic machine id file
By initializing /etc/machine-id from /var/lib/machine-id we should make
upgrades reliable. On new installations the latter should probably just
be a symlink to the former, since both files use the same format.
What does this mean for D-Bus upstream? Very little, as it is mostly a
downstream decision to adopt systemd and then symlink
/var/lib/machine-id to /etc/machine-id, or not. Other OSes and systems
not using systemd will still continue to use /var/lib/machine-id, and
end up with the very same id. The only D-Bus change we might consider is
to one day teach it to check /etc/machine-id as a fallback or so.
In case you are interested to know what systemd is really doing, here's
the precise logic:
http://cgit.freedesktop.org/systemd/plain/src/machine-id-setup.c
With this in place there's very little left which stops us from spawning
D-Bus already during early boot: the system bus activation needs to be
moved to /usr. Or alternatively we just give up officialyl on seperate
/usr, in which case we don't need to. I'd be very much in favour of
that, but you know the politics. The bigger problem is of course the
system bus socket, which is in /var/run/dbus/. But we probably could
move that to an abstract socket or one in /dev/.dbus, relatively
easily.
Anyway, opinions?
Lennart
--
Lennart Poettering - Red Hat, Inc.
More information about the dbus
mailing list