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