summaryrefslogtreecommitdiff
path: root/src/boot/bootctl.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/boot/bootctl.c')
-rw-r--r--src/boot/bootctl.c116
1 files changed, 105 insertions, 11 deletions
diff --git a/src/boot/bootctl.c b/src/boot/bootctl.c
index a684717bb0..34f0c14b44 100644
--- a/src/boot/bootctl.c
+++ b/src/boot/bootctl.c
@@ -29,6 +29,7 @@
#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"
@@ -52,6 +53,7 @@ static bool arg_print_dollar_boot_path = false;
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);
@@ -112,6 +114,19 @@ static int acquire_xbootldr(bool unprivileged_mode, sd_id128_t *ret_uuid) {
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;
@@ -888,6 +903,24 @@ static int remove_subdirs(const char *root, const char *const *subdirs) {
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;
@@ -974,9 +1007,13 @@ static int install_loader_config(const char *esp_path) {
_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;
@@ -991,6 +1028,13 @@ static int install_loader_config(const char *esp_path) {
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)
@@ -1006,6 +1050,24 @@ static int install_loader_config(const char *esp_path) {
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;
@@ -1043,6 +1105,8 @@ static int help(int argc, char *argv[], void *userdata) {
" --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,
@@ -1062,24 +1126,27 @@ static int parse_argv(int argc, char *argv[]) {
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);
@@ -1132,6 +1199,17 @@ static int parse_argv(int argc, char *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;
@@ -1530,6 +1608,8 @@ static int verb_install(int argc, char *argv[], void *userdata) {
if (r < 0)
return r;
+ settle_make_machine_id_directory();
+
install = streq(argv[0], "install");
RUN_WITH_UMASK(0002) {
@@ -1555,6 +1635,10 @@ static int verb_install(int argc, char *argv[], void *userdata) {
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;
@@ -1584,6 +1668,8 @@ static int verb_remove(int argc, char *argv[], void *userdata) {
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");
@@ -1602,11 +1688,19 @@ static int verb_remove(int argc, char *argv[], void *userdata) {
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();