setup-machine-id — set up the machine ID
setup-machine-id
setup-machine-id creates a machine ID, if one has not already been created, and stores it in various areas of non-volatile storage. It also stores the machine ID, newly created or read from storage, in various areas of volatile storage.
A machine ID is a 128-bit number that is intended to be a globally unique ID for identifying the machine, and that is intended to be constant across system restarts (once it has been set up), or (failing that) from restart to shutdown.
It is not dependent from the presence of any particular piece of hardware. Replacing hardware is not intended to affect a machine ID; although replacing the particular non-volatile storage that is used to store the machine ID when the system is powered off will result in a change to the machine ID, obviously.
It identifies the whole machine, not individual pieces. It is not suitable for use (in whole or in part) in IPv6 addresses (which identify individual interfaces), but it is suitable for identifying entire hosts on a network at the application protocol layer.
Machine IDs are intended to be UUIDs. Some older softwares do not create valid UUIDs as machine IDs. In particular, they create entirely random UUIDs where even the UUID variant and type are random. setup-machine-id will attempt to correct for this, by converting any UUID that is not a type 1 to type 5 DCE-variant UUID into a type 4 DCE-variant UUID by simply overwriting the type and variant parts of the UUID. As a special case, it will treat a nil UUID (NCS-variant with all zeroes) as invalid rather than correct it. (A nil UUID isn't globally unique by its very nature and is unsuitable as a machine ID.)
The machine ID, once set up, is stored in the file /etc/machine-id
.
If setup-machine-id can read and parse a machine ID from that file, then (subject to the aforementioned corrections of variant and type) it will consider the machine ID to be already set up.
Machine IDs are stored in the file as 32 lowercase hexadecimal characters (the machine ID as a 128-bit bigendian integer) followed by a linefeed.
Not all other softwares support it, but setup-machine-id allows the file to contain further lines beyond that first one, which it will ignore when reading the file.
If that file does not exist or there is no correctly formatted machine ID stored in its first line, setup-machine-id will attempt to find or to create a machine ID.
Once it has found or created a machine ID (or if it has needed to correct it) setup-machine-id will write it to /etc/machine-id
, creating or truncating the file.
This will fail if the file is on a read-only volume, as will be the case for bootable CD-ROMs and so forth.
In that case, and on systems that support doing so, it will then attempt to use a bind mount (see mount(2)) to place one of the volatile storage locations of the machine ID over the top of /etc/machine-id
.
setup-machine-id generates or imports machine IDs as follows:
It will attempt to read the UUID from volatile storage and use that.
Thus, if the file /etc/machine-id
is deleted but the system is not restarted,
setup-machine-id can restore the existing machine ID from volatile storage.
It will attempt to read the UUID from various older locations, such as the D-Bus machine ID files and (on BSD systems) the /etc/hostid
file.
Thus, if the file /etc/machine-id
has not yet been created but the system has machine IDs from older mechanisms, setup-machine-id will attempt to retain the machine IDs from those mechanisms.
If it detects that it is running in a container/jail, it will use the value of the container_uuid
environment variable, if it is correctly formatted.
This environment variable is a convention and is set by various jailer and container management utilities.
If it detects that it is not running in a container/jail, it will attempt to read the SMBIOS-generated system GUID and use that.
This GUID is taken from either the smbios.system.uuid
variable (see sysctl(1)) or the /sys/class/dmi/id/product_uuid
file.
Thus, if available, the SMBIOS unique identifier for the first bootstrap also becomes the machine identifier. The SMBIOS system GUID is not used in containers/jails because it will be the same as in the containing system itself, which may have used it as a machine ID.
As a final fallback, it will create a UUID using the uuid_create(3) or the uuid_generate(3) library function.
Various softwares expect to find the machine ID in various areas of volatile storage.
setup-machine-id itself uses /run/machine-id
.
It always creates it, and it will also use it as the source of a bind mount should it need to (and be able to) bind mount over the top of /etc/machine-id
.
BSD systems expect the machine ID to be stored in the kern.hostuuid
variable (see sysctl(1)), so it is written there.
setup-machine-id will attempt to read from these locations when attempting to "rescue" a lost machine ID from volatile storage.
The /etc/machine-id
file is compatible with systemd.
It is also compatible with D-Bus.
D-Bus looks for files named /var/lib/dbus/machine-id
or /var/db/dbus/machine-id
, which can just be symbolic links to /etc/machine-id
.
(Symbolic links the other way around would break if /var
or one of its subdirectories is not mounted, as can be the case at the point that setup-machine-id is run during system bootstrap.)
An older unique ID for machines is the host ID, as queried and set by the gethostid(3) and sethostid(3) library functions. As those functions' manual pages state, this is a mechanism that was dropped by its originating system in 1994, but that has continued since largely due to the inertia of standardization. It really shouldn't be used at all on systems with machine UUIDs available.
setup-machine-id creates a host ID by hashing the machine ID. The hashing function used is to take the lower 32-bits of the CubeHash (see cubehash(1)) of the machine ID, although this choice of hash function should not be relied upon by anything. Ironically, this provides a more stable host ID than some of the original schemes for determining a host ID did. As long as the machine ID does not change, the host ID will not change; and the host ID can be set up before network interfaces, and domain name to address mapping facilities, are even available.
The GNU C library expects the /etc/hostid
file to contain the host ID.
(On BSD systems, this file contains the machine ID as a human-readable-form UUID.)
setup-machine-id writes the host ID to that file if it can, and to /run/hostid
as well.
If /etc/hostid
is unwritable, and if bind mounting is available, it will attempt to bind mount /run/hostid
in place of it.
The BSD C library expects the host ID to be stored in the kern.hostid
variable (see sysctl(1)), so it is written there.