int main(int argc, char *argv[]) { const char *id = NULL; int retval = EXIT_SUCCESS; int r; /* This is mostly intended to be used for scripts which want * to detect whether we are being run in a virtualized * environment or not */ log_parse_environment(); log_open(); r = parse_argv(argc, argv); if (r <= 0) return r < 0 ? EXIT_FAILURE : EXIT_SUCCESS; switch (arg_mode) { case ANY_VIRTUALIZATION: { int v; v = detect_virtualization(&id); if (v < 0) { log_error("Failed to check for virtualization: %s", strerror(-v)); return EXIT_FAILURE; } retval = v != VIRTUALIZATION_NONE ? EXIT_SUCCESS : EXIT_FAILURE; break; } case ONLY_CONTAINER: r = detect_container(&id); if (r < 0) { log_error("Failed to check for container: %s", strerror(-r)); return EXIT_FAILURE; } retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE; break; case ONLY_VM: r = detect_vm(&id); if (r < 0) { log_error("Failed to check for vm: %s", strerror(-r)); return EXIT_FAILURE; } retval = r > 0 ? EXIT_SUCCESS : EXIT_FAILURE; break; } if (!arg_quiet) puts(id ? id : "none"); return retval; }
static int generate(char id[34]) { int fd, r; unsigned char *p; sd_id128_t buf; char *q; ssize_t k; const char *vm_id; assert(id); /* First, try reading the D-Bus machine id, unless it is a symlink */ fd = open("/var/lib/dbus/machine-id", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); if (fd >= 0) { k = loop_read(fd, id, 32, false); close_nointr_nofail(fd); if (k >= 32) { id[32] = '\n'; id[33] = 0; log_info("Initializing machine ID from D-Bus machine ID."); return 0; } } /* If that didn't work, see if we are running in qemu/kvm and a * machine ID was passed in via -uuid on the qemu/kvm command * line */ r = detect_vm(&vm_id); if (r > 0 && streq(vm_id, "kvm")) { char uuid[37]; fd = open("/sys/class/dmi/id/product_uuid", O_RDONLY|O_CLOEXEC|O_NOCTTY|O_NOFOLLOW); if (fd >= 0) { k = loop_read(fd, uuid, 36, false); close_nointr_nofail(fd); if (k >= 36) { r = shorten_uuid(id, uuid); if (r >= 0) { log_info("Initializing machine ID from KVM UUID."); return 0; } } } } /* If that didn't work either, see if we are running in a * container, and a machine ID was passed in via * $container_uuid the way libvirt/LXC does it */ r = detect_container(NULL); if (r > 0) { char *e; r = getenv_for_pid(1, "container_uuid", &e); if (r > 0) { if (strlen(e) >= 36) { r = shorten_uuid(id, e); if (r >= 0) { log_info("Initializing machine ID from container UUID."); free(e); return 0; } } free(e); } } /* If that didn't work, generate a random machine id */ r = sd_id128_randomize(&buf); if (r < 0) { log_error("Failed to open /dev/urandom: %s", strerror(-r)); return r; } for (p = buf.bytes, q = id; p < buf.bytes + sizeof(buf); p++, q += 2) { q[0] = hexchar(*p >> 4); q[1] = hexchar(*p & 15); } id[32] = '\n'; id[33] = 0; log_info("Initializing machine ID from random generator."); return 0; }