#include "main-func.h"
#include "mkdir.h"
#include "pager.h"
+#include "parse-argument.h"
#include "parse-util.h"
#include "pretty-print.h"
#include "random-util.h"
static bool arg_touch_variables = true;
static PagerFlags arg_pager_flags = 0;
static bool arg_graceful = false;
+static int arg_make_machine_id_directory = -1;
STATIC_DESTRUCTOR_REGISTER(arg_esp_path, freep);
STATIC_DESTRUCTOR_REGISTER(arg_xbootldr_path, freep);
return 1;
}
+static void settle_make_machine_id_directory(void) {
+ int r;
+
+ if (arg_make_machine_id_directory >= 0)
+ return;
+
+ r = path_is_temporary_fs("/etc/machine-id");
+ if (r < 0)
+ log_debug_errno(r, "Couldn't determine whether /etc/machine-id is on a temporary file system, assuming so.");
+
+ arg_make_machine_id_directory = r == 0;
+}
+
/* search for "#### LoaderInfo: systemd-boot 218 ####" string inside the binary */
static int get_file_version(int fd, char **v) {
struct stat st;
return r < 0 ? r : q;
}
+static int remove_machine_id_directory(const char *root) {
+ sd_id128_t machine_id;
+ char buf[SD_ID128_STRING_MAX];
+ int r;
+
+ assert(root);
+ assert(arg_make_machine_id_directory >= 0);
+
+ if (!arg_make_machine_id_directory)
+ return 0;
+
+ r = sd_id128_get_machine(&machine_id);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get machine id: %m");
+
+ return rmdir_one(root, sd_id128_to_string(machine_id, buf));
+}
+
static int remove_binaries(const char *esp_path) {
const char *p;
int r, q;
_cleanup_(unlink_and_freep) char *t = NULL;
_cleanup_fclose_ FILE *f = NULL;
_cleanup_close_ int fd = -1;
+ sd_id128_t machine_id;
+ char machine_string[SD_ID128_STRING_MAX];
const char *p;
int r;
+ assert(arg_make_machine_id_directory >= 0);
+
p = prefix_roota(esp_path, "/loader/loader.conf");
if (access(p, F_OK) >= 0) /* Silently skip creation if the file already exists (early check) */
return 0;
fprintf(f, "#timeout 3\n"
"#console-mode keep\n");
+ if (arg_make_machine_id_directory) {
+ r = sd_id128_get_machine(&machine_id);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get machine id: %m");
+
+ fprintf(f, "default %s-*\n", sd_id128_to_string(machine_id, machine_string));
+ }
r = fflush_sync_and_check(f);
if (r < 0)
return 1;
}
+static int install_machine_id_directory(const char *root) {
+ sd_id128_t machine_id;
+ char buf[SD_ID128_STRING_MAX];
+ int r;
+
+ assert(root);
+ assert(arg_make_machine_id_directory >= 0);
+
+ if (!arg_make_machine_id_directory)
+ return 0;
+
+ r = sd_id128_get_machine(&machine_id);
+ if (r < 0)
+ return log_error_errno(r, "Failed to get machine id: %m");
+
+ return mkdir_one(root, sd_id128_to_string(machine_id, buf));
+}
+
static int help(int argc, char *argv[], void *userdata) {
_cleanup_free_ char *link = NULL;
int r;
" --no-pager Do not pipe output into a pager\n"
" --graceful Don't fail when the ESP cannot be found or EFI\n"
" variables cannot be written\n"
+ " --make-machine-id-directory=yes|no|auto\n"
+ " Create $BOOT/$MACHINE_ID\n"
"\nSee the %2$s for details.\n",
program_invocation_short_name,
link,
ARG_NO_VARIABLES,
ARG_NO_PAGER,
ARG_GRACEFUL,
+ ARG_MAKE_MACHINE_ID_DIRECTORY,
};
static const struct option options[] = {
- { "help", no_argument, NULL, 'h' },
- { "version", no_argument, NULL, ARG_VERSION },
- { "esp-path", required_argument, NULL, ARG_ESP_PATH },
- { "path", required_argument, NULL, ARG_ESP_PATH }, /* Compatibility alias */
- { "boot-path", required_argument, NULL, ARG_BOOT_PATH },
- { "print-esp-path", no_argument, NULL, 'p' },
- { "print-path", no_argument, NULL, 'p' }, /* Compatibility alias */
- { "print-boot-path", no_argument, NULL, 'x' },
- { "no-variables", no_argument, NULL, ARG_NO_VARIABLES },
- { "no-pager", no_argument, NULL, ARG_NO_PAGER },
- { "graceful", no_argument, NULL, ARG_GRACEFUL },
+ { "help", no_argument, NULL, 'h' },
+ { "version", no_argument, NULL, ARG_VERSION },
+ { "esp-path", required_argument, NULL, ARG_ESP_PATH },
+ { "path", required_argument, NULL, ARG_ESP_PATH }, /* Compatibility alias */
+ { "boot-path", required_argument, NULL, ARG_BOOT_PATH },
+ { "print-esp-path", no_argument, NULL, 'p' },
+ { "print-path", no_argument, NULL, 'p' }, /* Compatibility alias */
+ { "print-boot-path", no_argument, NULL, 'x' },
+ { "no-variables", no_argument, NULL, ARG_NO_VARIABLES },
+ { "no-pager", no_argument, NULL, ARG_NO_PAGER },
+ { "graceful", no_argument, NULL, ARG_GRACEFUL },
+ { "make-machine-id-directory", required_argument, NULL, ARG_MAKE_MACHINE_ID_DIRECTORY },
{}
};
int c, r;
+ bool b;
assert(argc >= 0);
assert(argv);
arg_graceful = true;
break;
+ case ARG_MAKE_MACHINE_ID_DIRECTORY:
+ if (streq(optarg, "auto"))
+ arg_make_machine_id_directory = -1; /* default */
+ else {
+ r = parse_boolean_argument("--make-machine-id-directory=", optarg, &b);
+ if (r < 0)
+ return r;
+ arg_make_machine_id_directory = b;
+ }
+ break;
+
case '?':
return -EINVAL;
if (r < 0)
return r;
+ settle_make_machine_id_directory();
+
install = streq(argv[0], "install");
RUN_WITH_UMASK(0002) {
if (r < 0)
return r;
+ r = install_machine_id_directory(arg_dollar_boot_path());
+ if (r < 0)
+ return r;
+
r = install_random_seed(arg_esp_path);
if (r < 0)
return r;
if (r < 0)
return r;
+ settle_make_machine_id_directory();
+
r = remove_binaries(arg_esp_path);
q = remove_file(arg_esp_path, "/loader/loader.conf");
if (q < 0 && r >= 0)
r = q;
+ q = remove_machine_id_directory(arg_esp_path);
+ if (q < 0 && r >= 0)
+ r = 1;
+
if (arg_xbootldr_path) {
/* Remove the latter two also in the XBOOTLDR partition if it exists */
q = remove_subdirs(arg_xbootldr_path, dollar_boot_subdirs);
if (q < 0 && r >= 0)
r = q;
+
+ q = remove_machine_id_directory(arg_xbootldr_path);
+ if (q < 0 && r >= 0)
+ r = q;
}
(void) sync_everything();