From 4f427fb8a1050aab50328f1cb6f1d6bdaf747003 Mon Sep 17 00:00:00 2001 From: Silke Hofstra Date: Sat, 22 Aug 2020 15:56:08 +0200 Subject: [PATCH 1/3] Rename and expose detect_and_mount_boot --- src/bootman/bootman.c | 10 +++++----- src/bootman/bootman.h | 7 +++++++ src/bootman/bootman_private.h | 2 +- src/bootman/update.c | 2 +- 4 files changed, 14 insertions(+), 7 deletions(-) diff --git a/src/bootman/bootman.c b/src/bootman/bootman.c index a35381ab..0fefb92a 100644 --- a/src/bootman/bootman.c +++ b/src/bootman/bootman.c @@ -212,7 +212,7 @@ bool boot_manager_set_prefix(BootManager *self, char *prefix) free(self->user_initrd_freestanding_dir); } self->user_initrd_freestanding_dir = user_initrd_dir; - + if (self->bootloader) { self->bootloader->destroy(self); self->bootloader = NULL; @@ -331,7 +331,7 @@ bool boot_manager_remove_kernel_wrapper(BootManager *self, const Kernel *kernel) CHECK_ERR_RET_VAL(!kernels || kernels->len == 0, false, "No kernels discovered in %s, bailing", self->kernel_dir); - did_mount = detect_and_mount_boot(self, &boot_dir); + did_mount = boot_manager_detect_and_mount_boot(self, &boot_dir); CHECK_DBG_RET_VAL(did_mount < 0, false, "Boot was not mounted"); for (uint16_t i = 0; i < kernels->len; i++) { @@ -371,7 +371,7 @@ bool boot_manager_remove_kernel(BootManager *self, const Kernel *kernel) return self->bootloader->remove_kernel(self, kernel); } -int detect_and_mount_boot(BootManager *self, char **boot_dir) { +int boot_manager_detect_and_mount_boot(BootManager *self, char **boot_dir) { autofree(char) *boot_dev = NULL; const char *prefix; int wanted_boot_mask; @@ -412,7 +412,7 @@ bool boot_manager_set_default_kernel(BootManager *self, const Kernel *kernel) CHECK_ERR_RET_VAL(!kernels || kernels->len == 0, false, "No kernels discovered in %s, bailing", self->kernel_dir); - did_mount = detect_and_mount_boot(self, &boot_dir); + did_mount = boot_manager_detect_and_mount_boot(self, &boot_dir); CHECK_DBG_RET_VAL(did_mount < 0, false, "Boot was not mounted"); for (uint16_t i = 0; i < kernels->len; i++) { @@ -608,7 +608,7 @@ char **boot_manager_list_kernels(BootManager *self) /* Sort them to ensure static ordering */ nc_array_qsort(kernels, kernel_compare_reverse); - did_mount = detect_and_mount_boot(self, &boot_dir); + did_mount = boot_manager_detect_and_mount_boot(self, &boot_dir); if (did_mount >= 0) { default_kernel = boot_manager_get_default_kernel(self); if (did_mount > 0) { diff --git a/src/bootman/bootman.h b/src/bootman/bootman.h index e949a8f8..d7345d33 100644 --- a/src/bootman/bootman.h +++ b/src/bootman/bootman.h @@ -297,6 +297,13 @@ bool boot_manager_set_default_kernel(BootManager *manager, const Kernel *kernel) */ char *boot_manager_get_default_kernel(BootManager *manager); +/** + * Detect and mount the boot directory. + * @param boot_dir Path indicating the mounted boot directory. + * @return an integer value, indicating success or failure. + */ +int boot_manager_detect_and_mount_boot(BootManager *self, char **boot_dir); + /** * Return the CbmDeviceProbe for the root partition * diff --git a/src/bootman/bootman_private.h b/src/bootman/bootman_private.h index cd0b14f3..1fcc5e4e 100644 --- a/src/bootman/bootman_private.h +++ b/src/bootman/bootman_private.h @@ -71,7 +71,7 @@ int mount_boot(BootManager *self, char **boot_directory); * * @see mount_boot() for return and error conditions. */ -int detect_and_mount_boot(BootManager *self, char **boot_dir); +int boot_manager_detect_and_mount_boot(BootManager *self, char **boot_dir); /** * Internal function to sort by Kernel structs by release number (highest first) diff --git a/src/bootman/update.c b/src/bootman/update.c index b9c06bb1..15538c8e 100644 --- a/src/bootman/update.c +++ b/src/bootman/update.c @@ -41,7 +41,7 @@ bool boot_manager_update(BootManager *self) return boot_manager_update_image(self); } - did_mount = detect_and_mount_boot(self, &boot_dir); + did_mount = boot_manager_detect_and_mount_boot(self, &boot_dir); if (did_mount >= 0) { /* Do a native update */ ret = boot_manager_update_native(self); From affae84cdd9dd7c0b515b5dfb4ef1064c7956309 Mon Sep 17 00:00:00 2001 From: Silke Hofstra Date: Sat, 22 Aug 2020 15:56:14 +0200 Subject: [PATCH 2/3] Add `mount-boot` command. The `mount-boot` command mounts the boot partitions. This is useful for when the user, any system component, requires the boot directory to be mounted. As unmounting afterwards is a simple `umount`, no `unmount-boot` command is added. --- src/cli/main.c | 17 +++++++++ src/cli/ops/mount.c | 87 +++++++++++++++++++++++++++++++++++++++++++++ src/cli/ops/mount.h | 29 +++++++++++++++ src/meson.build | 1 + 4 files changed, 134 insertions(+) create mode 100644 src/cli/ops/mount.c create mode 100644 src/cli/ops/mount.h diff --git a/src/cli/main.c b/src/cli/main.c index 79cf021f..7d9db60c 100644 --- a/src/cli/main.c +++ b/src/cli/main.c @@ -22,6 +22,7 @@ #include "ops/timeout.h" #include "ops/update.h" #include "ops/kernels.h" +#include "ops/mount.h" static SubCommand cmd_update; static SubCommand cmd_help; @@ -32,6 +33,7 @@ static SubCommand cmd_report_booted; static SubCommand cmd_list_kernels; static SubCommand cmd_set_kernel; static SubCommand cmd_remove_kernel; +static SubCommand cmd_mount_boot; static char *binary_name = NULL; static NcHashmap *g_commands = NULL; static bool explicit_help = false; @@ -225,6 +227,21 @@ kernel for the next time the system boots.", return EXIT_FAILURE; } + /* Mount the boot directory */ + cmd_mount_boot = (SubCommand){ + .name = "mount-boot", + .blurb = "Mount the boot directory", + .help = "This command ensures the boot directory is mounted.", + .callback = cbm_command_mount_boot, + .usage = " [--path=/path/to/filesystem/root]", + .requires_root = true + }; + + if (!nc_hashmap_put(commands, cmd_mount_boot.name, &cmd_mount_boot)) { + DECLARE_OOM(); + return EXIT_FAILURE; + } + /* Version */ cmd_version = (SubCommand){ .name = "version", diff --git a/src/cli/ops/mount.c b/src/cli/ops/mount.c new file mode 100644 index 00000000..4f5417ad --- /dev/null +++ b/src/cli/ops/mount.c @@ -0,0 +1,87 @@ +/* + * This file is part of clr-boot-manager. + * + * Copyright © 2016-2018 Intel Corporation + * Copyright © 2020 Silke Hofstra + * + * clr-boot-manager is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + */ + +#define _GNU_SOURCE + +#include +#include + +#include "bootman.h" +#include "cli.h" +#include "log.h" + +bool cbm_command_mount_boot(int argc, char **argv) +{ + autofree(char) *root = NULL; + autofree(BootManager) *manager = NULL; + bool forced_image = false; + bool update_efi_vars = false; + autofree(char) *boot_dir = NULL; + int did_mount = -1; + + if (!cli_default_args_init(&argc, &argv, &root, &forced_image, &update_efi_vars)) { + return false; + } + + manager = boot_manager_new(); + if (!manager) { + DECLARE_OOM(); + return false; + } + + boot_manager_set_update_efi_vars(manager, update_efi_vars); + + if (root) { + autofree(char) *realp = NULL; + + realp = realpath(root, NULL); + if (!realp) { + LOG_FATAL("Path specified does not exist: %s", root); + return false; + } + /* Anything not / is image mode */ + if (!streq(realp, "/")) { + boot_manager_set_image_mode(manager, true); + } else { + boot_manager_set_image_mode(manager, forced_image); + } + + /* CBM will check this again, we just needed to check for + * image mode.. */ + if (!boot_manager_set_prefix(manager, root)) { + return false; + } + } else { + boot_manager_set_image_mode(manager, forced_image); + /* Default to "/", bail if it doesn't work. */ + if (!boot_manager_set_prefix(manager, "/")) { + return false; + } + } + + /* Let CBM detect and mount the boot directory */ + did_mount = boot_manager_detect_and_mount_boot(manager, &boot_dir); + return did_mount >= 0; +} + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=8 tabstop=8 expandtab: + * :indentSize=8:tabSize=8:noTabs=true: + */ diff --git a/src/cli/ops/mount.h b/src/cli/ops/mount.h new file mode 100644 index 00000000..df5d8995 --- /dev/null +++ b/src/cli/ops/mount.h @@ -0,0 +1,29 @@ +/* + * This file is part of clr-boot-manager. + * + * Copyright © 2020 Silke Hofstra + * + * clr-boot-manager is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public License as + * published by the Free Software Foundation; either version 2.1 + * of the License, or (at your option) any later version. + */ + +#pragma once + +#include "cli.h" + +bool cbm_command_mount_boot(int argc, char **argv); + +/* + * Editor modelines - https://www.wireshark.org/tools/modelines.html + * + * Local variables: + * c-basic-offset: 8 + * tab-width: 8 + * indent-tabs-mode: nil + * End: + * + * vi: set shiftwidth=8 tabstop=8 expandtab: + * :indentSize=8:tabSize=8:noTabs=true: + */ diff --git a/src/meson.build b/src/meson.build index 5bba913b..c4b6c7cf 100644 --- a/src/meson.build +++ b/src/meson.build @@ -98,6 +98,7 @@ clr_boot_manager_sources = [ 'cli/cli.c', 'cli/main.c', 'cli/ops/kernels.c', + 'cli/ops/mount.c', 'cli/ops/report_booted.c', 'cli/ops/timeout.c', 'cli/ops/update.c', From 36698ac1e85963db1b241a56fcff88a461f2c415 Mon Sep 17 00:00:00 2001 From: Silke Hofstra Date: Sat, 17 Oct 2020 14:17:56 +0200 Subject: [PATCH 3/3] Add service for mounting /boot using CBM --- data/clr-boot-manager-mount-boot.service.in | 11 +++++++++++ data/meson.build | 8 ++++++++ 2 files changed, 19 insertions(+) create mode 100644 data/clr-boot-manager-mount-boot.service.in diff --git a/data/clr-boot-manager-mount-boot.service.in b/data/clr-boot-manager-mount-boot.service.in new file mode 100644 index 00000000..c82e4414 --- /dev/null +++ b/data/clr-boot-manager-mount-boot.service.in @@ -0,0 +1,11 @@ +[Unit] +Description=mount @BOOTDIR@ using clr-boot-manager + +[Service] +Type=oneshot +RemainAfterExit=yes +ExecStart=@BINDIR@/clr-boot-manager mount-boot +ExecStop=@BINDIR@/umount @BOOTDIR@ + +[Install] +WantedBy=multi-user.target diff --git a/data/meson.build b/data/meson.build index e14f45a4..3a4f15ea 100644 --- a/data/meson.build +++ b/data/meson.build @@ -1,6 +1,7 @@ # Write systemd unit data_conf = configuration_data() data_conf.set('BINDIR', path_bindir) +data_conf.set('BOOTDIR', with_boot_dir) configure_file( input: 'clr-boot-manager-booted.service.in', @@ -8,3 +9,10 @@ configure_file( configuration: data_conf, install_dir: with_systemd_system_unit_dir, ) + +configure_file( + input: 'clr-boot-manager-mount-boot.service.in', + output: 'clr-boot-manager-mount-boot.service', + configuration: data_conf, + install_dir: with_systemd_system_unit_dir, +)