#include "fd-util.h"
#include "fs-util.h"
#include "id128-util.h"
+#include "io-util.h"
#include "log.h"
#include "machine-id-setup.h"
#include "macro.h"
return 0;
}
-int machine_id_setup(const char *root, sd_id128_t machine_id, sd_id128_t *ret) {
+int machine_id_setup(const char *root, bool force_transient, sd_id128_t machine_id, sd_id128_t *ret) {
const char *etc_machine_id, *run_machine_id;
_cleanup_close_ int fd = -1;
bool writable;
if (ftruncate(fd, 0) < 0)
return log_error_errno(errno, "Failed to truncate %s: %m", etc_machine_id);
- if (id128_write_fd(fd, ID128_PLAIN, machine_id, true) >= 0)
- goto finish;
+ /* If the caller requested a transient machine-id, write the string "uninitialized\n" to
+ * disk and overmount it with a transient file.
+ *
+ * Otherwise write the machine-id directly to disk. */
+ if (force_transient) {
+ r = loop_write(fd, "uninitialized\n", strlen("uninitialized\n"), false);
+ if (r < 0)
+ return log_error_errno(r, "Failed to write uninitialized %s: %m", etc_machine_id);
+
+ r = fsync_full(fd);
+ if (r < 0)
+ return log_error_errno(r, "Failed to sync %s: %m", etc_machine_id);
+ } else {
+ r = id128_write_fd(fd, ID128_PLAIN, machine_id, true);
+ if (r < 0)
+ return log_error_errno(r, "Failed to write %s: %m", etc_machine_id);
+ else
+ goto finish;
+ }
}
fd = safe_close(fd);
- /* Hmm, we couldn't write it? So let's write it to /run/machine-id as a replacement */
+ /* Hmm, we couldn't or shouldn't write the machine-id to /etc?
+ * So let's write it to /run/machine-id as a replacement */
run_machine_id = prefix_roota(root, "/run/machine-id");
return r;
}
- log_info("Installed transient %s file.", etc_machine_id);
+ log_full(force_transient ? LOG_DEBUG : LOG_INFO, "Installed transient %s file.", etc_machine_id);
/* Mark the mount read-only */
r = mount_follow_verbose(LOG_WARNING, NULL, etc_machine_id, NULL, MS_BIND|MS_RDONLY|MS_REMOUNT, NULL);
static int initialize_runtime(
bool skip_setup,
+ bool first_boot,
struct rlimit *saved_rlimit_nofile,
struct rlimit *saved_rlimit_memlock,
const char **ret_error_message) {
status_welcome();
hostname_setup();
- machine_id_setup(NULL, arg_machine_id, NULL);
+ /* Force transient machine-id on first boot. */
+ machine_id_setup(NULL, first_boot, arg_machine_id, NULL);
(void) loopback_setup();
bump_unix_max_dgram_qlen();
bump_file_max_and_nr_open();
log_execution_mode(&first_boot);
r = initialize_runtime(skip_setup,
+ first_boot,
&saved_rlimit_nofile,
&saved_rlimit_memlock,
&error_message);