machine-id-setup.c revision a5c32cff1f56afe6f0c6c70d91a88a7a8238b2d7
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen/*-*- Mode: C; c-basic-offset: 8; indent-tabs-mode: nil -*-*/
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen This file is part of systemd.
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen Copyright 2010 Lennart Poettering
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen systemd is free software; you can redistribute it and/or modify it
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen under the terms of the GNU Lesser General Public License as published by
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen the Free Software Foundation; either version 2.1 of the License, or
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen (at your option) any later version.
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen systemd is distributed in the hope that it will be useful, but
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen WITHOUT ANY WARRANTY; without even the implied warranty of
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen Lesser General Public License for more details.
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen You should have received a copy of the GNU Lesser General Public License
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen along with systemd; If not, see <http://www.gnu.org/licenses/>.
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersenstatic int shorten_uuid(char destination[36], const char *source) {
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen unsigned i, j;
02b59d57e0c08231645120077f651151f5bb2babTom Gundersen unsigned char *p;
02b59d57e0c08231645120077f651151f5bb2babTom Gundersen /* First, try reading the D-Bus machine id, unless it is a symlink */
02b59d57e0c08231645120077f651151f5bb2babTom Gundersen fd = open("/var/lib/dbus/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen if (k >= 32) {
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen log_info("Initializing machine ID from D-Bus machine ID.");
f5be560181d092c5f52a2b819aedcd48220f36abTom Gundersen /* If that didn't work, see if we are running in qemu/kvm and a
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen * machine ID was passed in via -uuid on the qemu/kvm command
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW);
6ae115c1fe95611b39d2f20cfcea3d385429f59eTom Gundersen if (k >= 36) {
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen if (r >= 0) {
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen log_info("Initializing machine ID from KVM UUID.");
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen /* If that didn't work either, see if we are running in a
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen * container, and a machine ID was passed in via
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen * $container_uuid the way libvirt/LXC does it */
b3070dc0258831c7e2b13624f75fa3dbd80d9833Tom Gundersen if (r >= 0) {
6ae115c1fe95611b39d2f20cfcea3d385429f59eTom Gundersen log_info("Initializing machine ID from container UUID.");
6ae115c1fe95611b39d2f20cfcea3d385429f59eTom Gundersen /* If that didn't work, generate a random machine id */
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen log_error("Failed to open /dev/urandom: %s", strerror(-r));
ef1ba6065c6ccea94d4ee867f36df7bbc53a5224Tom Gundersen for (p = buf.bytes, q = id; p < buf.bytes + sizeof(buf); p++, q += 2) {
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen log_info("Initializing machine ID from random generator.");
f882c247ad59776c3a7753bb963c1f8e2386cb79Tom Gundersen /* We create this 0444, to indicate that this isn't really
f882c247ad59776c3a7753bb963c1f8e2386cb79Tom Gundersen * something you should ever modify. Of course, since the file
f5be560181d092c5f52a2b819aedcd48220f36abTom Gundersen * will be owned by root it doesn't matter much, but maybe
f5be560181d092c5f52a2b819aedcd48220f36abTom Gundersen * people look. */
f5be560181d092c5f52a2b819aedcd48220f36abTom Gundersen fd = open("/etc/machine-id", O_RDWR|O_CREAT|O_CLOEXEC|O_NOCTTY, 0444);
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen fd = open("/etc/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY);
2ad8416dd057e7e3185169609ca3006e7649f576Zbigniew Jędrzejewski-Szmek log_error("fstat() failed: %m");
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen /* Hmm, so, the id currently stored is not useful, then let's
f882c247ad59776c3a7753bb963c1f8e2386cb79Tom Gundersen * generate one */
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen /* Hmm, we couldn't write it? So let's write it to
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen * /run/machine-id as a replacement */
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen r = write_one_line_file("/run/machine-id", id);
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen log_error("Cannot write /run/machine-id: %s", strerror(-r));
02b59d57e0c08231645120077f651151f5bb2babTom Gundersen /* And now, let's mount it over */
02b59d57e0c08231645120077f651151f5bb2babTom Gundersen r = mount("/run/machine-id", "/etc/machine-id", NULL, MS_BIND, NULL) < 0 ? -errno : 0;
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen log_error("Failed to mount /etc/machine-id: %s", strerror(-r));
f579559b3a14c1f1ef96c372e7626c4733e6ef7dTom Gundersen log_info("Installed transient /etc/machine-id file.");
f048a16b464295a4e0a4f4c1210f06343ad31231Tom Gundersen /* Mark the mount read-only */