From 4837aef7f9f97df7086dcd55ff23ae5a3ef06fcb Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Fri, 4 Aug 2017 14:40:17 +0000 Subject: [PATCH 01/38] Add stub shim-systemd support. Does nothing at this point. --- Makefile.am | 1 + configure.ac | 16 +++- src/bootloaders/shim-systemd.c | 152 +++++++++++++++++++++++++++++++++ src/bootman/bootman.c | 5 +- 4 files changed, 169 insertions(+), 5 deletions(-) create mode 100644 src/bootloaders/shim-systemd.c diff --git a/Makefile.am b/Makefile.am index b8e6e9f..abdcc49 100644 --- a/Makefile.am +++ b/Makefile.am @@ -93,6 +93,7 @@ libcbm_la_SOURCES = \ src/bootloaders/bootloader.h \ src/bootloaders/systemd-class.h \ src/bootloaders/systemd-class.c \ + src/bootloaders/shim-systemd.c \ src/bootloaders/systemd-boot.c \ src/bootloaders/grub2.c \ src/bootloaders/gummiboot.c \ diff --git a/configure.ac b/configure.ac index d235da7..bb92e0d 100644 --- a/configure.ac +++ b/configure.ac @@ -42,7 +42,11 @@ AC_ARG_WITH([bootloader], AS_HELP_STRING([--with-bootloader=BOOTLOADER], if test x$bootloader = "xauto"; then AC_MSG_CHECKING([whether an EFI bootloader is available]) if test -e "/usr/lib/systemd/boot/efi"; then - bootloader="systemd-boot" + if test -e "/usr/lib/shim"; then + bootloader="shim-systemd-boot" + else + bootloader="systemd-boot" + fi elif test -e "/usr/lib/goofiboot"; then bootloader="goofiboot" # use newer goofiboot, may be dual installed @@ -50,13 +54,16 @@ if test x$bootloader = "xauto"; then bootloader="gummiboot" else AC_MSG_WARN([Cannot find a valid EFI bootloader, defaulting to systemd-boot]) - bootloader="systemd-boot" + bootloader="shim-systemd-boot" fi AC_MSG_RESULT([$bootloader]) fi # Now test the option -if test x$bootloader = "xsystemd-boot"; then +if test x$bootloader = "xshim-systemd-boot"; then + have_shim_systemdboot="yes" + AC_DEFINE([HAVE_SHIM_SYSTEMD_BOOT], [1], [Using shim-systemd-boot]) +elif test x$bootloader = "xsystemd-boot"; then have_systemdboot="yes" AC_DEFINE([HAVE_SYSTEMD_BOOT], [1], [Using systemd-boot]) elif test x$bootloader = "xgummiboot"; then @@ -66,9 +73,10 @@ elif test x$bootloader = "xgoofiboot"; then have_goofiboot="yes" AC_DEFINE([HAVE_GOOFIBOOT], [1], [Using goofiboot]) else - AC_MSG_ERROR([Unknown bootloader, use: systemd-boot, gummiboot, or goofiboot]) + AC_MSG_ERROR([Unknown bootloader, use: shim-systemd-boot, systemd-boot, gummiboot, or goofiboot]) fi +AM_CONDITIONAL([HAVE_SHIM_SYSTEMD_BOOT], [test x$have_shim_systemdboot = "xyes"]) AM_CONDITIONAL([HAVE_SYSTEMD_BOOT], [test x$have_systemdboot = "xyes"]) AM_CONDITIONAL([HAVE_GUMMIBOOT], [test x$have_gummiboot = "xyes"]) AM_CONDITIONAL([HAVE_GOOFIBOOT], [test x$have_goofiboot = "xyes"]) diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c new file mode 100644 index 0000000..c893040 --- /dev/null +++ b/src/bootloaders/shim-systemd.c @@ -0,0 +1,152 @@ +/* + * This file is part of clr-boot-manager. + * + * Copyright © 2016-2017 Intel Corporation + * + * 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 "bootman.h" +#include "bootloader.h" +#include "config.h" + +/* + * This file implements 2-stage bootloader configuration in which shim is used as + * the first stage bootloader and systemd-boot as the second stage bootloader. + * + * This implementation uses the following ESP layout: + * + * /EFI/ + * Boot/ + * BOOTX64.EFI <-- whatever was there before + * + * /org.clearlinux/ + * bootloaderx64.efi <-- shim + * loaderx64.efi <-- systemd-boot bootloader + * mmx64.efi <-- MOK mgr + * fbx64.efi <-- MOK mgr + * + * kernel/ <-- kernels + * kernel-org.clearlinux..... + * ... + * + * /loader/ <-- systemd-boot config + * entries/ <-- boot menu entries + * Clear-linux...conf + * ... + * loader.conf <-- bootloader config + * + * Note that default bootloader at /EFI/Boot/BOOTX64.EFI is never modified. + * Instead, we create an EFI BootXXX variable and put it first in the BootOrder + * EFI variable. + */ + +static bool _shim_systemd_install_kernel(const BootManager *manager, const Kernel *kernel); +static bool _shim_systemd_remove_kernel(const BootManager *manager, const Kernel *kernel); +static bool _shim_systemd_set_default_kernel(const BootManager *manager, const Kernel *kernel); +static bool _shim_systemd_needs_install(const BootManager *manager); +static bool _shim_systemd_needs_update(const BootManager *manager); +static bool _shim_systemd_install(const BootManager *manager); +static bool _shim_systemd_update(const BootManager *manager); +static bool _shim_systemd_remove(const BootManager *manager); +static bool _shim_systemd_init(const BootManager *manager); +static void _shim_systemd_destroy(const BootManager *manager); +static int _shim_systemd_get_capabilities(const BootManager *manager); + +__cbm_export__ const BootLoader shim_systemd_bootloader = { + .name = "systemd", + .init = _shim_systemd_init, + .install_kernel = _shim_systemd_install_kernel, + .remove_kernel = _shim_systemd_remove_kernel, + .set_default_kernel = _shim_systemd_set_default_kernel, + .needs_install = _shim_systemd_needs_install, + .needs_update = _shim_systemd_needs_update, + .install = _shim_systemd_install, + .update = _shim_systemd_update, + .remove = _shim_systemd_remove, + .destroy = _shim_systemd_destroy, + .get_capabilities = _shim_systemd_get_capabilities +}; + +#if UINTPTR_MAX == 0xffffffffffffffff +# define EFI_SUFFIX "x64.efi" +#else +# define EFI_SUFFIX "ia32.efi" +#endif + +/* Layout entries, see the layout description at the top of the file. */ +#define SHIM_SRC_DIR "/usr/lib/shim" +#define SHIM_SRC SHIM_SRC_DIR "/" "shim" EFI_SUFFIX +#define MM_SRC SHIM_SRC_DIR "/" "mm" EFI_SUFFIX +#define FB_SRC SHIM_SRC_DIR "/" "fb" EFI_SUFFIX +#define SYSTEMD_SRC_DIR "/usr/lib/systemd/boot/efi" +#define SYSTEMD_SRC SYSTEMD "/" "systemd-boot" EFI_SUFFIX +#define DST_DIR BOOT_DIRECTORY "/" KERNEL_NAMESPACE +#define SHIM_DST DST_DIR "/" "bootloader" EFI_SUFFIX +#define SYSTEMD_DST DST_DIR "/" "loader" EFI_SUFFIX +#define KERNEL_DST_DIR DST_DIR "/kernel" +#define SYSTEMD_CONFIG_DIR BOOT_DIRECTORY "/loader" +#define SYSTEMD_CONFIG SYSTEMD_CONFIG_DIR "/loader.conf" +#define SYSTEMD_ENTRIES SYSTEMD_CONFIG_DIR "/entries" + +static bool _shim_systemd_install_kernel(const BootManager *manager, const Kernel *kernel) { + return true; +} + +static bool _shim_systemd_remove_kernel(const BootManager *manager, const Kernel *kernel) { + return true; +} + +static bool _shim_systemd_set_default_kernel(const BootManager *manager, const Kernel *kernel) { + return true; +} + +static bool _shim_systemd_needs_install(const BootManager *manager) { + return true; +} + +static bool _shim_systemd_needs_update(const BootManager *manager) { + return true; +} + +static bool _shim_systemd_install(const BootManager *manager) { + return true; +} + +static bool _shim_systemd_update(const BootManager *manager) { + return true; +} + +static bool _shim_systemd_remove(const BootManager *manager) { + return true; +} + +static bool _shim_systemd_init(const BootManager *manager) { + return true; +} + +static void _shim_systemd_destroy(const BootManager *manager) { + return true; +} + +static int _shim_systemd_get_capabilities(const BootManager *manager) { + return 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/bootman/bootman.c b/src/bootman/bootman.c index d720047..5334363 100644 --- a/src/bootman/bootman.c +++ b/src/bootman/bootman.c @@ -31,6 +31,7 @@ * Total "usable" bootloaders */ extern const BootLoader grub2_bootloader; +extern const BootLoader shim_systemd_bootloader; extern const BootLoader systemd_bootloader; extern const BootLoader gummiboot_bootloader; extern const BootLoader goofiboot_bootloader; @@ -41,7 +42,9 @@ extern const BootLoader syslinux_bootloader; */ const BootLoader *bootman_known_loaders[] = { &grub2_bootloader, /** Date: Fri, 4 Aug 2017 22:58:22 +0000 Subject: [PATCH 02/38] Add partial implementation. Bootloaders are installed, but not kernels. Kernels are installed (copied) into wrong location by a completely different piece of code. --- src/bootloaders/shim-systemd.c | 133 ++++++++++++++++++++++++--------- 1 file changed, 96 insertions(+), 37 deletions(-) diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index c893040..79cfe97 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -14,6 +14,8 @@ #include "bootman.h" #include "bootloader.h" #include "config.h" +#include "nica/files.h" +#include "files.h" /* * This file implements 2-stage bootloader configuration in which shim is used as @@ -46,31 +48,31 @@ * EFI variable. */ -static bool _shim_systemd_install_kernel(const BootManager *manager, const Kernel *kernel); -static bool _shim_systemd_remove_kernel(const BootManager *manager, const Kernel *kernel); -static bool _shim_systemd_set_default_kernel(const BootManager *manager, const Kernel *kernel); -static bool _shim_systemd_needs_install(const BootManager *manager); -static bool _shim_systemd_needs_update(const BootManager *manager); -static bool _shim_systemd_install(const BootManager *manager); -static bool _shim_systemd_update(const BootManager *manager); -static bool _shim_systemd_remove(const BootManager *manager); -static bool _shim_systemd_init(const BootManager *manager); -static void _shim_systemd_destroy(const BootManager *manager); -static int _shim_systemd_get_capabilities(const BootManager *manager); +static bool shim_systemd_install_kernel(const BootManager *manager, const Kernel *kernel); +static bool shim_systemd_remove_kernel(const BootManager *manager, const Kernel *kernel); +static bool shim_systemd_set_default_kernel(const BootManager *manager, const Kernel *kernel); +static bool shim_systemd_needs_install(const BootManager *manager); +static bool shim_systemd_needs_update(const BootManager *manager); +static bool shim_systemd_install(const BootManager *manager); +static bool shim_systemd_update(const BootManager *manager); +static bool shim_systemd_remove(const BootManager *manager); +static bool shim_systemd_init(const BootManager *manager); +static void shim_systemd_destroy(const BootManager *manager); +static int shim_systemd_get_capabilities(const BootManager *manager); __cbm_export__ const BootLoader shim_systemd_bootloader = { .name = "systemd", - .init = _shim_systemd_init, - .install_kernel = _shim_systemd_install_kernel, - .remove_kernel = _shim_systemd_remove_kernel, - .set_default_kernel = _shim_systemd_set_default_kernel, - .needs_install = _shim_systemd_needs_install, - .needs_update = _shim_systemd_needs_update, - .install = _shim_systemd_install, - .update = _shim_systemd_update, - .remove = _shim_systemd_remove, - .destroy = _shim_systemd_destroy, - .get_capabilities = _shim_systemd_get_capabilities + .init = shim_systemd_init, + .install_kernel = shim_systemd_install_kernel, + .remove_kernel = shim_systemd_remove_kernel, + .set_default_kernel = shim_systemd_set_default_kernel, + .needs_install = shim_systemd_needs_install, + .needs_update = shim_systemd_needs_update, + .install = shim_systemd_install, + .update = shim_systemd_update, + .remove = shim_systemd_remove, + .destroy = shim_systemd_destroy, + .get_capabilities = shim_systemd_get_capabilities }; #if UINTPTR_MAX == 0xffffffffffffffff @@ -80,12 +82,12 @@ __cbm_export__ const BootLoader shim_systemd_bootloader = { #endif /* Layout entries, see the layout description at the top of the file. */ -#define SHIM_SRC_DIR "/usr/lib/shim" +#define SHIM_SRC_DIR "usr/lib/shim" #define SHIM_SRC SHIM_SRC_DIR "/" "shim" EFI_SUFFIX #define MM_SRC SHIM_SRC_DIR "/" "mm" EFI_SUFFIX #define FB_SRC SHIM_SRC_DIR "/" "fb" EFI_SUFFIX -#define SYSTEMD_SRC_DIR "/usr/lib/systemd/boot/efi" -#define SYSTEMD_SRC SYSTEMD "/" "systemd-boot" EFI_SUFFIX +#define SYSTEMD_SRC_DIR "usr/lib/systemd/boot/efi" +#define SYSTEMD_SRC SYSTEMD_SRC_DIR "/" "systemd-boot" EFI_SUFFIX #define DST_DIR BOOT_DIRECTORY "/" KERNEL_NAMESPACE #define SHIM_DST DST_DIR "/" "bootloader" EFI_SUFFIX #define SYSTEMD_DST DST_DIR "/" "loader" EFI_SUFFIX @@ -94,48 +96,105 @@ __cbm_export__ const BootLoader shim_systemd_bootloader = { #define SYSTEMD_CONFIG SYSTEMD_CONFIG_DIR "/loader.conf" #define SYSTEMD_ENTRIES SYSTEMD_CONFIG_DIR "/entries" -static bool _shim_systemd_install_kernel(const BootManager *manager, const Kernel *kernel) { +static char *shim_src; +static char *shim_dst; +static char *systemd_src; +static char *systemd_dst; + +static bool shim_systemd_install_kernel(const BootManager *manager, const Kernel *kernel) { + fprintf(stderr, "Call %s\n", __func__); return true; } -static bool _shim_systemd_remove_kernel(const BootManager *manager, const Kernel *kernel) { +static bool shim_systemd_remove_kernel(const BootManager *manager, const Kernel *kernel) { + fprintf(stderr, "Call %s\n", __func__); return true; } -static bool _shim_systemd_set_default_kernel(const BootManager *manager, const Kernel *kernel) { +static bool shim_systemd_set_default_kernel(const BootManager *manager, const Kernel *kernel) { + fprintf(stderr, "Call %s\n", __func__); return true; } -static bool _shim_systemd_needs_install(const BootManager *manager) { +static bool exists_identical(const char *path, const char *spath) { + if (!nc_file_exists(path)) return false; + if (spath && !cbm_files_match(path, spath)) return false; return true; } -static bool _shim_systemd_needs_update(const BootManager *manager) { +static bool shim_systemd_needs_install(const BootManager *manager) { + fprintf(stderr, "Call %s\n", __func__); + if (!exists_identical(shim_dst, NULL)) return true; + if (!exists_identical(systemd_dst, NULL)) return true; + return false; +} + +static bool shim_systemd_needs_update(const BootManager *manager) { + fprintf(stderr, "Call %s\n", __func__); + if (!exists_identical(shim_dst, shim_src)) return true; + if (!exists_identical(systemd_dst, systemd_src)) return true; + return false; +} + +static bool make_layout() { + if (!nc_mkdir_p(DST_DIR, 00755)) return false; + if (!nc_mkdir_p(KERNEL_DST_DIR, 00755)) return false; + if (!nc_mkdir_p(SYSTEMD_ENTRIES, 00755)) return false; return true; } -static bool _shim_systemd_install(const BootManager *manager) { +static bool shim_systemd_install(const BootManager *manager) { + fprintf(stderr, "Call %s\n", __func__); + + if (!make_layout()) return false; + + if (!copy_file_atomic(shim_src, shim_dst, 00644)) return false; + if (!copy_file_atomic(systemd_src, systemd_dst, 00644)) return false; + return true; } -static bool _shim_systemd_update(const BootManager *manager) { +static bool shim_systemd_update(const BootManager *manager) { + fprintf(stderr, "Call %s\n", __func__); return true; } -static bool _shim_systemd_remove(const BootManager *manager) { +static bool shim_systemd_remove(const BootManager *manager) { + fprintf(stderr, "Call %s\n", __func__); return true; } -static bool _shim_systemd_init(const BootManager *manager) { +static bool shim_systemd_init(const BootManager *manager) { + fprintf(stderr, "Call %s\n", __func__); + int len; + char *prefix; + + prefix = strdup(boot_manager_get_prefix((BootManager *)manager)); + len = strlen(prefix); + if (prefix[len-1] == '/') prefix[len-1] = '\0'; + shim_src = string_printf("%s/%s", prefix, SHIM_SRC); + systemd_src = string_printf("%s/%s", prefix, SYSTEMD_SRC); + + shim_dst = SHIM_DST; + systemd_dst = SYSTEMD_DST; + + free(prefix); + return true; } -static void _shim_systemd_destroy(const BootManager *manager) { +static void shim_systemd_destroy(const BootManager *manager) { + fprintf(stderr, "Call %s\n", __func__); + + free(shim_src); + free(systemd_src); + return true; } -static int _shim_systemd_get_capabilities(const BootManager *manager) { - return 0; +static int shim_systemd_get_capabilities(const BootManager *manager) { + fprintf(stderr, "Call %s\n", __func__); + return BOOTLOADER_CAP_GPT | BOOTLOADER_CAP_UEFI; } /* From 32904c4bc07cbbd6c76090445de7177e20a0fdf9 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Sat, 5 Aug 2017 02:51:21 +0000 Subject: [PATCH 03/38] Ask bootloader where to copy the kernels. --- src/bootloaders/bootloader.h | 2 ++ src/bootloaders/goofiboot.c | 1 + src/bootloaders/grub2.c | 28 ++++++++++++++++------------ src/bootloaders/gummiboot.c | 1 + src/bootloaders/shim-systemd.c | 8 +++++++- src/bootloaders/syslinux.c | 31 +++++++++++++++++-------------- src/bootloaders/systemd-boot.c | 1 + src/bootloaders/systemd-class.c | 8 ++++++++ src/bootloaders/systemd-class.h | 2 ++ src/bootman/kernel.c | 13 ++++--------- 10 files changed, 59 insertions(+), 36 deletions(-) diff --git a/src/bootloaders/bootloader.h b/src/bootloaders/bootloader.h index 2f0ac49..661b081 100644 --- a/src/bootloaders/bootloader.h +++ b/src/bootloaders/bootloader.h @@ -21,6 +21,7 @@ typedef bool (*boot_loader_init)(const BootManager *); typedef bool (*boot_loader_install_kernel)(const BootManager *, const Kernel *); +typedef char *(*boot_loader_get_kernel_dst)(const BootManager *); typedef bool (*boot_loader_remove_kernel)(const BootManager *, const Kernel *); typedef bool (*boot_loader_set_default_kernel)(const BootManager *, const Kernel *kernel); typedef bool (*boot_loader_needs_update)(const BootManager *); @@ -45,6 +46,7 @@ typedef enum { typedef struct BootLoader { const char *name; /**bootloader->get_capabilities(manager) & BOOTLOADER_CAP_UEFI); + autofree(char) *efi_boot_dir = is_uefi ? manager->bootloader->get_kernel_dst(manager) : NULL; assert(manager != NULL); assert(kernel != NULL); + if (is_uefi && !efi_boot_dir) return false; + /* Boot path */ base_path = boot_manager_get_boot_dir((BootManager *)manager); OOM_CHECK_RET(base_path, false); - /* Determine if UEFI is in use */ - if ((manager->bootloader->get_capabilities(manager) & BOOTLOADER_CAP_UEFI) == - BOOTLOADER_CAP_UEFI) { - is_uefi = true; - efi_boot_dir = nc_build_case_correct_path(base_path, "EFI", KERNEL_NAMESPACE, NULL); - } - /* For UEFI kernels we namespace into /EFI/$NEEDLE, i.e. /EFI/org.clearlinux */ if (is_uefi) { /* Ensure namespace directory exists */ From edebfc34bde3814e0704b504a0b0d79853250351 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Mon, 7 Aug 2017 17:05:29 +0000 Subject: [PATCH 04/38] Clean up. --- src/bootloaders/shim-systemd.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index 1a91237..5dcb794 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -25,7 +25,8 @@ * * /EFI/ * Boot/ - * BOOTX64.EFI <-- whatever was there before + * BOOTX64.EFI <-- this implementation never modifies the + * default fallback loader * * /org.clearlinux/ * bootloaderx64.efi <-- shim @@ -162,7 +163,7 @@ static bool shim_systemd_install(const BootManager *manager) { static bool shim_systemd_update(const BootManager *manager) { fprintf(stderr, "Call %s\n", __func__); - return true; + return shim_systemd_install(manager); } static bool shim_systemd_remove(const BootManager *manager) { @@ -177,7 +178,7 @@ static bool shim_systemd_init(const BootManager *manager) { prefix = strdup(boot_manager_get_prefix((BootManager *)manager)); len = strlen(prefix); - if (prefix[len-1] == '/') prefix[len-1] = '\0'; + if (len > 0 && prefix[len-1] == '/') prefix[len-1] = '\0'; shim_src = string_printf("%s/%s", prefix, SHIM_SRC); systemd_src = string_printf("%s/%s", prefix, SYSTEMD_SRC); From 734c911d44937ac82e8e10203bae95aa37f52b62 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Mon, 7 Aug 2017 17:14:52 +0000 Subject: [PATCH 05/38] Use get_kernel_dst() instead of hard-coded value. --- src/bootloaders/systemd-class.c | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bootloaders/systemd-class.c b/src/bootloaders/systemd-class.c index d8eec0d..1750dee 100644 --- a/src/bootloaders/systemd-class.c +++ b/src/bootloaders/systemd-class.c @@ -218,8 +218,8 @@ bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel) /* Standard title + linux lines */ cbm_writer_append_printf(writer, "title %s\n", os_name); cbm_writer_append_printf(writer, - "linux /EFI/%s/%s\n", - KERNEL_NAMESPACE, + "linux %s/%s\n", + sd_class_get_kernel_dst(manager), kernel->target.path); /* Optional initrd */ if (kernel->target.initrd_path) { From 4f52d149af252e24842fdae53228cf0d2417abfe Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Mon, 7 Aug 2017 18:55:41 +0000 Subject: [PATCH 06/38] Add working impl of kernel install. --- src/bootloaders/shim-systemd.c | 14 +++++++++++++- src/bootloaders/systemd-class.c | 20 ++++++++++++++------ src/bootloaders/systemd-class.h | 4 ++++ 3 files changed, 31 insertions(+), 7 deletions(-) diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index 5dcb794..08a7eb0 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -16,6 +16,7 @@ #include "config.h" #include "nica/files.h" #include "files.h" +#include "systemd-class.h" /* * This file implements 2-stage bootloader configuration in which shim is used as @@ -110,7 +111,7 @@ static char *shim_systemd_get_kernel_dst(const BootManager *manager) { static bool shim_systemd_install_kernel(const BootManager *manager, const Kernel *kernel) { fprintf(stderr, "Call %s\n", __func__); - return true; + return sd_class_install_kernel_impl(manager, kernel, shim_systemd_get_kernel_dst, NULL); } static bool shim_systemd_remove_kernel(const BootManager *manager, const Kernel *kernel) { @@ -176,6 +177,17 @@ static bool shim_systemd_init(const BootManager *manager) { int len; char *prefix; + /* init systemd-class since we're reusing it for kernel install. + * specific values do not matter as long as sd_class is not used to + * install the bootloaders themselves. */ + static BootLoaderConfig systemd_config = { + .vendor_dir = "systemd", + .efi_dir = "/usr/lib/systemd/boot/efi", + .efi_blob = "systemd-boot" EFI_SUFFIX, + .name = "systemd-boot" + }; + sd_class_init(manager, &systemd_config); + prefix = strdup(boot_manager_get_prefix((BootManager *)manager)); len = strlen(prefix); if (len > 0 && prefix[len-1] == '/') prefix[len-1] = '\0'; diff --git a/src/bootloaders/systemd-class.c b/src/bootloaders/systemd-class.c index 1750dee..85ad830 100644 --- a/src/bootloaders/systemd-class.c +++ b/src/bootloaders/systemd-class.c @@ -177,12 +177,15 @@ static bool sd_class_ensure_dirs(__cbm_unused__ const BootManager *manager) return true; } -char *sd_class_get_kernel_dst(const BootManager *manager) { +char *sd_class_get_kernel_dst(const BootManager *manager) +{ (void)manager; return strdup(sd_class_config.kernel_dir); } -bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel) +bool sd_class_install_kernel_impl(const BootManager *manager, const Kernel *kernel, + char *(*get_kernel_dst)(const BootManager *), + bool (*ensure_layout)(const BootManager *)) { if (!manager || !kernel) { return false; @@ -196,7 +199,7 @@ bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel) conf_path = get_entry_path_for_kernel((BootManager *)manager, kernel); /* Ensure all the relevant directories exist */ - if (!sd_class_ensure_dirs(manager)) { + if (ensure_layout && !ensure_layout(manager)) { LOG_FATAL("Failed to create required directories"); return false; } @@ -219,13 +222,13 @@ bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel) cbm_writer_append_printf(writer, "title %s\n", os_name); cbm_writer_append_printf(writer, "linux %s/%s\n", - sd_class_get_kernel_dst(manager), + get_kernel_dst(manager), kernel->target.path); /* Optional initrd */ if (kernel->target.initrd_path) { cbm_writer_append_printf(writer, - "initrd /EFI/%s/%s\n", - KERNEL_NAMESPACE, + "initrd %s/%s\n", + get_kernel_dst(manager), kernel->target.initrd_path); } /* Add the root= section */ @@ -267,6 +270,11 @@ bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel) return true; } +bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel) { + return sd_class_install_kernel_impl(manager, kernel, + sd_class_get_kernel_dst, sd_class_ensure_dirs); +} + bool sd_class_remove_kernel(const BootManager *manager, const Kernel *kernel) { if (!manager || !kernel) { diff --git a/src/bootloaders/systemd-class.h b/src/bootloaders/systemd-class.h index 6050107..6347096 100644 --- a/src/bootloaders/systemd-class.h +++ b/src/bootloaders/systemd-class.h @@ -33,6 +33,10 @@ char *sd_class_get_kernel_dst(const BootManager *manager); bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel); +bool sd_class_install_kernel_impl(const BootManager *manager, const Kernel *kernel, + char *(*get_kernel_dst)(const BootManager *), + bool (*ensure_layout)(const BootManager *)); + bool sd_class_remove_kernel(const BootManager *manager, const Kernel *kernel); bool sd_class_set_default_kernel(const BootManager *manager, const Kernel *kernel); From e9fd24b763c86f11189f9f5851bf6a4cdf94d1e9 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Tue, 8 Aug 2017 23:18:51 +0000 Subject: [PATCH 07/38] WIP: efi boot var implementation. --- Makefile.am | 7 ++- src/efi/efisupport.c | 126 +++++++++++++++++++++++++++++++++++++++++++ src/efi/efisupport.h | 6 +++ 3 files changed, 137 insertions(+), 2 deletions(-) create mode 100644 src/efi/efisupport.c create mode 100644 src/efi/efisupport.h diff --git a/Makefile.am b/Makefile.am index abdcc49..2f9df9b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -58,7 +58,8 @@ AM_CFLAGS = -fstack-protector -Wall -pedantic \ -Wall -W -D_FORTIFY_SOURCE=2 \ -Wno-missing-field-initializers \ -std=c11 \ - -DSYSCONFDIR=\"$(sysconfdir)\" + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -D_POSIX_C_SOURCE=201112L AM_CPPFLAGS = \ -I $(top_srcdir)/src \ @@ -123,7 +124,9 @@ libcbm_la_SOURCES = \ src/lib/writer.h \ src/lib/writer.c \ src/lib/util.h \ - src/lib/util.c + src/lib/util.c \ + src/efi/efisupport.c \ + src/efi/efisupport.h libcbm_la_CFLAGS = \ -D_BOOTMAN_INTERNAL_ \ diff --git a/src/efi/efisupport.c b/src/efi/efisupport.c new file mode 100644 index 0000000..34e07d5 --- /dev/null +++ b/src/efi/efisupport.c @@ -0,0 +1,126 @@ +#include +/* Workaround for using --std=c11 in CBM. Provide "relaxed" defines which efivar + * expects. */ +#define BYTE_ORDER __BYTE_ORDER +#define LITTLE_ENDIAN __LITTLE_ENDIAN +#define BIG_ENDIAN __BIG_ENDIAN +#include +#include +#include +#include +#include +#include + +typedef struct boot_rec boot_rec_t; + +struct boot_rec { + char *name; + int num; + unsigned char *data; + boot_rec_t *next; +}; + +static boot_rec_t *boot_recs; +static int boot_recs_cnt; + +static void free_boot_recs(void) { + boot_rec_t *p, *c; + c = boot_recs; + if (!c) return; + do { + p = c; + c = c->next; + free(p); + } while (c); +} + +static void print_boot_recs(void) { + boot_rec_t *c = boot_recs; + if (!c) return; + do { + fprintf(stderr, "Boot record #%d: %s\n", c->num, c->name); + } while ((c = c->next)); +} + +static int read_boot_recs(void) { + int res; + efi_guid_t *guid = NULL; + char *name = NULL; + boot_rec_t *p, *c; + int i = 0; + + while ((res = efi_get_next_variable_name(&guid, &name)) > 0) { + char *num_end; + if (strncmp(name, "Boot", 4)) continue; + if (!isxdigit(name[4]) || !isxdigit(name[5]) || !isxdigit(name[6]) + || !isxdigit(name[7])) continue; + if (memcmp(guid, &efi_guid_global, sizeof(efi_guid_t))) continue; + + c = (boot_rec_t *)malloc(sizeof(boot_rec_t)); + memset(c, 0, sizeof(boot_rec_t)); + c->name = strdup(name); + c->num = (int)strtol(name + 4, &num_end, 16); + if (num_end - name - 4 != 4) continue; + + if (!boot_recs) { + boot_recs = p = c; + } else { + p->next = c; + p = c; + } + i++; + } + boot_recs_cnt = i; + print_boot_recs(); + return 0; +} + +static int cmp(const void *a, const void *b) { + return *((int *)a) - *((int *)b); +} + +static int find_free_boot_rec(void) { + int *nums; + int res; + int i = 0; + boot_rec_t *c = boot_recs; + size_t cnt; + + if (!boot_recs) return -1; + if (boot_recs_cnt < 1) return 0; + + cnt = (size_t)boot_recs_cnt; + + nums = (int *)alloca(sizeof(int) * cnt); + memset(nums, 0, sizeof(int) * cnt); + + do { + nums[i] = c->num; + i++; + } while ((c = c->next)); + + qsort(nums, cnt, sizeof(int), cmp); + + for (i = 0, res = 0; i < boot_recs_cnt; i++, res++) { + if (res < nums[i]) break; + } + if (res == nums[boot_recs_cnt - 1]) res++; + fprintf(stderr, "Found: %d\n", res); + return res; +} + +int efi_create_boot_rec(void) { + int slot = find_free_boot_rec(); + + if (slot < 0) return -1; + + return 0; +} + +int efi_init(void) { + if (efi_variables_supported() < 0) return -1; + if (read_boot_recs() < 0) return -1; + return 0; +} + +/* vim: set nosi noai cin ts=4 sw=4 et tw=80: */ diff --git a/src/efi/efisupport.h b/src/efi/efisupport.h new file mode 100644 index 0000000..70bd8a7 --- /dev/null +++ b/src/efi/efisupport.h @@ -0,0 +1,6 @@ +/* TODO: copyright */ + +int efi_init(); +int efi_create_boot_rec(); + +/* vim: set nosi noai cin ts=4 sw=4 et tw=80: */ From b3bc61b25434fede649401ea5c8eb940bfff473e Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Mon, 14 Aug 2017 18:39:35 +0000 Subject: [PATCH 08/38] Get rid of the maybe uninitialized warning. --- src/efi/efisupport.c | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/src/efi/efisupport.c b/src/efi/efisupport.c index 34e07d5..8fa7f07 100644 --- a/src/efi/efisupport.c +++ b/src/efi/efisupport.c @@ -46,7 +46,8 @@ static int read_boot_recs(void) { int res; efi_guid_t *guid = NULL; char *name = NULL; - boot_rec_t *p, *c; + boot_rec_t *p = NULL, + *c; int i = 0; while ((res = efi_get_next_variable_name(&guid, &name)) > 0) { From 84860370d77872f4a212f9279f6c36b5e5c4cc8b Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Wed, 16 Aug 2017 07:09:18 +0000 Subject: [PATCH 09/38] Add draft implementation of boot var support. --- Makefile.am | 1 + src/bootloaders/shim-systemd.c | 5 +++ src/efi/efisupport.c | 75 +++++++++++++++++++++++++++++++++- 3 files changed, 80 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 2f9df9b..095c1d2 100644 --- a/Makefile.am +++ b/Makefile.am @@ -67,6 +67,7 @@ AM_CPPFLAGS = \ -I $(top_srcdir)/src/cli \ -I $(top_srcdir)/src/bootloaders \ -I $(top_srcdir)/src/lib \ + -I $(top_srcdir)/src/efi \ -I $(top_srcdir)/src/libnica/src/include \ -DTOP_DIR=\"$(abs_top_srcdir)\" \ -DTOP_BUILD_DIR=\"$(abs_top_builddir)\" diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index 08a7eb0..8f30ac7 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -17,6 +17,7 @@ #include "nica/files.h" #include "files.h" #include "systemd-class.h" +#include "efisupport.h" /* * This file implements 2-stage bootloader configuration in which shim is used as @@ -159,6 +160,8 @@ static bool shim_systemd_install(const BootManager *manager) { if (!copy_file_atomic(shim_src, shim_dst, 00644)) return false; if (!copy_file_atomic(systemd_src, systemd_dst, 00644)) return false; + if (efi_create_boot_rec(shim_dst)) return false; + return true; } @@ -177,6 +180,8 @@ static bool shim_systemd_init(const BootManager *manager) { int len; char *prefix; + if (efi_init()) return false; + /* init systemd-class since we're reusing it for kernel install. * specific values do not matter as long as sd_class is not used to * install the bootloaders themselves. */ diff --git a/src/efi/efisupport.c b/src/efi/efisupport.c index 8fa7f07..5899b74 100644 --- a/src/efi/efisupport.c +++ b/src/efi/efisupport.c @@ -1,3 +1,4 @@ +#define _GNU_SOURCE #include /* Workaround for using --std=c11 in CBM. Provide "relaxed" defines which efivar * expects. */ @@ -5,11 +6,16 @@ #define LITTLE_ENDIAN __LITTLE_ENDIAN #define BIG_ENDIAN __BIG_ENDIAN #include +#include #include +#include #include #include #include #include +#include + +#include typedef struct boot_rec boot_rec_t; @@ -32,6 +38,7 @@ static void free_boot_recs(void) { c = c->next; free(p); } while (c); + boot_recs = NULL; } static void print_boot_recs(void) { @@ -50,6 +57,8 @@ static int read_boot_recs(void) { *c; int i = 0; + free_boot_recs(); + while ((res = efi_get_next_variable_name(&guid, &name)) > 0) { char *num_end; if (strncmp(name, "Boot", 4)) continue; @@ -110,11 +119,75 @@ static int find_free_boot_rec(void) { return res; } -int efi_create_boot_rec(void) { +typedef struct part_info { + char *disk_path; + int part_no; + char *part_type; +} part_info_t; + +/* Given the location of the booloader, returns the partition information needed + * to create boot variable which points to that bootloader. */ +int get_part_info(const char *path, part_info_t *pi) { + blkid_probe probe; + blkid_partition part; + blkid_partlist parts; + struct stat st; + dev_t disk_dev; + char disk_path[PATH_MAX]; + + if (stat(path, &st)) return -1; + + strcpy(disk_path, "/dev/"); + if (blkid_devno_to_wholedisk(st.st_dev, disk_path + 5, PATH_MAX - 5, &disk_dev)) return -1; + + if (!(probe = blkid_new_probe_from_filename(disk_path))) return -1; + + if (blkid_probe_enable_partitions(probe, 1)) return -1; + + if (!(parts = blkid_probe_get_partitions(probe))) return -1; + part = blkid_partlist_devno_to_partition(parts, st.st_dev); + + pi->disk_path = strdup(disk_path); + pi->part_no = blkid_partition_get_partno(part); + pi->part_type = strdup(blkid_partition_get_type_string(part)); + + blkid_free_probe(probe); + + return 0; +} + +int efi_create_boot_rec(const char *boot_loader_path) { + part_info_t pi; + uint8_t fdev_path[PATH_MAX]; + char *boot_var_name; + uint8_t boot_var_data[PATH_MAX]; + uint32_t boot_var_attr = EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS + | EFI_VARIABLE_RUNTIME_ACCESS; + char rel_path[PATH_MAX]; int slot = find_free_boot_rec(); + ssize_t len; if (slot < 0) return -1; + if (get_part_info(boot_loader_path, &pi)) return -1; + + /* FIXME: pass the booloader in two parts. The below cuts off /boot where + * it's normally mounted. */ + strcpy(rel_path, boot_loader_path + 5); + + len = efi_generate_file_device_path_from_esp(fdev_path, PATH_MAX, pi.disk_path, pi.part_no, rel_path, EFIBOOT_ABBREV_HD); + if (len < 0) return -1; + + /* FIXME: figure out why LOAD_OPTION_ACTIVE is not defined (should be + * defined via efi.h) */ + len = efi_loadopt_create(boot_var_data, PATH_MAX, 0x00000001 /* LOAD_OPTION_ACTIVE */, + (void *)fdev_path, len, (unsigned char *)"Linux bootloader", NULL, 0); + + if (len < 0) return -1; + + if (asprintf(&boot_var_name, "%s%04x", "Boot", slot) < 0) return -1; + if (efi_set_variable(EFI_GLOBAL_GUID, boot_var_name, boot_var_data, (size_t)len, boot_var_attr, 0644) < 0) return -1; return 0; } From 065662f702ad618b87840cdafd49fce3a0570c17 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Wed, 16 Aug 2017 07:13:15 +0000 Subject: [PATCH 10/38] Rename files, clean up. --- Makefile.am | 4 ++-- src/bootloaders/shim-systemd.c | 6 +++--- src/efi/{efisupport.c => cbm_efi.c} | 9 ++++----- src/efi/{efisupport.h => cbm_efi.h} | 0 4 files changed, 9 insertions(+), 10 deletions(-) rename src/efi/{efisupport.c => cbm_efi.c} (99%) rename src/efi/{efisupport.h => cbm_efi.h} (100%) diff --git a/Makefile.am b/Makefile.am index 095c1d2..a8bc157 100644 --- a/Makefile.am +++ b/Makefile.am @@ -126,8 +126,8 @@ libcbm_la_SOURCES = \ src/lib/writer.c \ src/lib/util.h \ src/lib/util.c \ - src/efi/efisupport.c \ - src/efi/efisupport.h + src/efi/cbm_efi.c \ + src/efi/cbm_efi.h libcbm_la_CFLAGS = \ -D_BOOTMAN_INTERNAL_ \ diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index 8f30ac7..76760a3 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -11,13 +11,13 @@ #define _GNU_SOURCE -#include "bootman.h" #include "bootloader.h" +#include "bootman.h" +#include "cbm_efi.h" #include "config.h" -#include "nica/files.h" #include "files.h" +#include "nica/files.h" #include "systemd-class.h" -#include "efisupport.h" /* * This file implements 2-stage bootloader configuration in which shim is used as diff --git a/src/efi/efisupport.c b/src/efi/cbm_efi.c similarity index 99% rename from src/efi/efisupport.c rename to src/efi/cbm_efi.c index 5899b74..8aec55d 100644 --- a/src/efi/efisupport.c +++ b/src/efi/cbm_efi.c @@ -5,18 +5,17 @@ #define BYTE_ORDER __BYTE_ORDER #define LITTLE_ENDIAN __LITTLE_ENDIAN #define BIG_ENDIAN __BIG_ENDIAN +#include +#include #include +#include #include #include -#include -#include #include +#include #include -#include #include -#include - typedef struct boot_rec boot_rec_t; struct boot_rec { diff --git a/src/efi/efisupport.h b/src/efi/cbm_efi.h similarity index 100% rename from src/efi/efisupport.h rename to src/efi/cbm_efi.h From 1269f54de24eecf893f28b546a1150d7a57c110b Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Wed, 16 Aug 2017 07:17:07 +0000 Subject: [PATCH 11/38] Add/correct copyright notice. --- src/bootloaders/shim-systemd.c | 2 +- src/efi/cbm_efi.c | 13 +++++++++++++ src/efi/cbm_efi.h | 11 ++++++++++- 3 files changed, 24 insertions(+), 2 deletions(-) diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index 76760a3..62d8318 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -1,7 +1,7 @@ /* * This file is part of clr-boot-manager. * - * Copyright © 2016-2017 Intel Corporation + * Copyright © 2017 Intel Corporation * * 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 diff --git a/src/efi/cbm_efi.c b/src/efi/cbm_efi.c index 8aec55d..cced9e9 100644 --- a/src/efi/cbm_efi.c +++ b/src/efi/cbm_efi.c @@ -1,10 +1,23 @@ +/* + * This file is part of clr-boot-manager. + * + * Copyright © 2017 Intel Corporation + * + * 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 /* Workaround for using --std=c11 in CBM. Provide "relaxed" defines which efivar * expects. */ #define BYTE_ORDER __BYTE_ORDER #define LITTLE_ENDIAN __LITTLE_ENDIAN #define BIG_ENDIAN __BIG_ENDIAN + #include #include #include diff --git a/src/efi/cbm_efi.h b/src/efi/cbm_efi.h index 70bd8a7..e5a54e2 100644 --- a/src/efi/cbm_efi.h +++ b/src/efi/cbm_efi.h @@ -1,4 +1,13 @@ -/* TODO: copyright */ +/* + * This file is part of clr-boot-manager. + * + * Copyright © 2017 Intel Corporation + * + * 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. + */ int efi_init(); int efi_create_boot_rec(); From 9df212a9c30ec35bf532bacc8c5963a3b1724353 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Fri, 18 Aug 2017 03:58:18 +0000 Subject: [PATCH 12/38] Clean up. --- src/bootloaders/shim-systemd.c | 15 +++++++++++++-- src/efi/cbm_efi.h | 4 ++-- 2 files changed, 15 insertions(+), 4 deletions(-) diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index 62d8318..f574c9a 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -107,6 +107,7 @@ static char *systemd_src; static char *systemd_dst; static char *shim_systemd_get_kernel_dst(const BootManager *manager) { + (void)manager; return strdup(KERNEL_DST_DIR); } @@ -116,11 +117,15 @@ static bool shim_systemd_install_kernel(const BootManager *manager, const Kernel } static bool shim_systemd_remove_kernel(const BootManager *manager, const Kernel *kernel) { + (void)manager; + (void)kernel; fprintf(stderr, "Call %s\n", __func__); return true; } static bool shim_systemd_set_default_kernel(const BootManager *manager, const Kernel *kernel) { + (void)manager; + (void)kernel; fprintf(stderr, "Call %s\n", __func__); return true; } @@ -132,6 +137,7 @@ static bool exists_identical(const char *path, const char *spath) { } static bool shim_systemd_needs_install(const BootManager *manager) { + (void)manager; fprintf(stderr, "Call %s\n", __func__); if (!exists_identical(shim_dst, NULL)) return true; if (!exists_identical(systemd_dst, NULL)) return true; @@ -139,13 +145,14 @@ static bool shim_systemd_needs_install(const BootManager *manager) { } static bool shim_systemd_needs_update(const BootManager *manager) { + (void)manager; fprintf(stderr, "Call %s\n", __func__); if (!exists_identical(shim_dst, shim_src)) return true; if (!exists_identical(systemd_dst, systemd_src)) return true; return false; } -static bool make_layout() { +static bool make_layout(void) { if (!nc_mkdir_p(DST_DIR, 00755)) return false; if (!nc_mkdir_p(KERNEL_DST_DIR, 00755)) return false; if (!nc_mkdir_p(SYSTEMD_ENTRIES, 00755)) return false; @@ -153,6 +160,7 @@ static bool make_layout() { } static bool shim_systemd_install(const BootManager *manager) { + (void)manager; fprintf(stderr, "Call %s\n", __func__); if (!make_layout()) return false; @@ -171,13 +179,14 @@ static bool shim_systemd_update(const BootManager *manager) { } static bool shim_systemd_remove(const BootManager *manager) { + (void)manager; fprintf(stderr, "Call %s\n", __func__); return true; } static bool shim_systemd_init(const BootManager *manager) { fprintf(stderr, "Call %s\n", __func__); - int len; + size_t len; char *prefix; if (efi_init()) return false; @@ -208,6 +217,7 @@ static bool shim_systemd_init(const BootManager *manager) { } static void shim_systemd_destroy(const BootManager *manager) { + (void)manager; fprintf(stderr, "Call %s\n", __func__); free(shim_src); @@ -217,6 +227,7 @@ static void shim_systemd_destroy(const BootManager *manager) { } static int shim_systemd_get_capabilities(const BootManager *manager) { + (void)manager; fprintf(stderr, "Call %s\n", __func__); return BOOTLOADER_CAP_GPT | BOOTLOADER_CAP_UEFI; } diff --git a/src/efi/cbm_efi.h b/src/efi/cbm_efi.h index e5a54e2..ac293a3 100644 --- a/src/efi/cbm_efi.h +++ b/src/efi/cbm_efi.h @@ -9,7 +9,7 @@ * of the License, or (at your option) any later version. */ -int efi_init(); -int efi_create_boot_rec(); +int efi_init(void); +int efi_create_boot_rec(const char *); /* vim: set nosi noai cin ts=4 sw=4 et tw=80: */ From d0bbf4df138ce889f264947fb73dfb57999d5a1f Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Fri, 18 Aug 2017 04:33:59 +0000 Subject: [PATCH 13/38] Separate host and ESP paths and use them properly. --- src/bootloaders/shim-systemd.c | 38 ++++++++++++++++++++-------------- src/bootman/kernel.c | 4 ++-- src/efi/cbm_efi.c | 11 +++------- src/efi/cbm_efi.h | 2 +- 4 files changed, 28 insertions(+), 27 deletions(-) diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index f574c9a..7e3ba47 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -11,6 +11,8 @@ #define _GNU_SOURCE +#include + #include "bootloader.h" #include "bootman.h" #include "cbm_efi.h" @@ -93,18 +95,19 @@ __cbm_export__ const BootLoader shim_systemd_bootloader = { #define FB_SRC SHIM_SRC_DIR "/" "fb" EFI_SUFFIX #define SYSTEMD_SRC_DIR "usr/lib/systemd/boot/efi" #define SYSTEMD_SRC SYSTEMD_SRC_DIR "/" "systemd-boot" EFI_SUFFIX -#define DST_DIR BOOT_DIRECTORY "/" KERNEL_NAMESPACE +#define DST_DIR "/" KERNEL_NAMESPACE #define SHIM_DST DST_DIR "/" "bootloader" EFI_SUFFIX #define SYSTEMD_DST DST_DIR "/" "loader" EFI_SUFFIX #define KERNEL_DST_DIR DST_DIR "/kernel" -#define SYSTEMD_CONFIG_DIR BOOT_DIRECTORY "/loader" +#define SYSTEMD_CONFIG_DIR "/loader" #define SYSTEMD_CONFIG SYSTEMD_CONFIG_DIR "/loader.conf" #define SYSTEMD_ENTRIES SYSTEMD_CONFIG_DIR "/entries" static char *shim_src; -static char *shim_dst; +static char *shim_dst_host; /* as accessible by the CMB for file ops. */ +static char *shim_dst_esp; /* absolute location of shim on the ESP. */ static char *systemd_src; -static char *systemd_dst; +static char *systemd_dst_host; static char *shim_systemd_get_kernel_dst(const BootManager *manager) { (void)manager; @@ -139,23 +142,23 @@ static bool exists_identical(const char *path, const char *spath) { static bool shim_systemd_needs_install(const BootManager *manager) { (void)manager; fprintf(stderr, "Call %s\n", __func__); - if (!exists_identical(shim_dst, NULL)) return true; - if (!exists_identical(systemd_dst, NULL)) return true; + if (!exists_identical(shim_dst_host, NULL)) return true; + if (!exists_identical(systemd_dst_host, NULL)) return true; return false; } static bool shim_systemd_needs_update(const BootManager *manager) { (void)manager; fprintf(stderr, "Call %s\n", __func__); - if (!exists_identical(shim_dst, shim_src)) return true; - if (!exists_identical(systemd_dst, systemd_src)) return true; + if (!exists_identical(shim_dst_host, shim_src)) return true; + if (!exists_identical(systemd_dst_host, systemd_src)) return true; return false; } static bool make_layout(void) { - if (!nc_mkdir_p(DST_DIR, 00755)) return false; - if (!nc_mkdir_p(KERNEL_DST_DIR, 00755)) return false; - if (!nc_mkdir_p(SYSTEMD_ENTRIES, 00755)) return false; + if (!nc_mkdir_p(BOOT_DIRECTORY DST_DIR, 00755)) return false; + if (!nc_mkdir_p(BOOT_DIRECTORY KERNEL_DST_DIR, 00755)) return false; + if (!nc_mkdir_p(BOOT_DIRECTORY SYSTEMD_ENTRIES, 00755)) return false; return true; } @@ -165,10 +168,10 @@ static bool shim_systemd_install(const BootManager *manager) { if (!make_layout()) return false; - if (!copy_file_atomic(shim_src, shim_dst, 00644)) return false; - if (!copy_file_atomic(systemd_src, systemd_dst, 00644)) return false; + if (!copy_file_atomic(shim_src, shim_dst_host, 00644)) return false; + if (!copy_file_atomic(systemd_src, systemd_dst_host, 00644)) return false; - if (efi_create_boot_rec(shim_dst)) return false; + if (efi_create_boot_rec(shim_dst_host, shim_dst_esp)) return false; return true; } @@ -208,8 +211,11 @@ static bool shim_systemd_init(const BootManager *manager) { shim_src = string_printf("%s/%s", prefix, SHIM_SRC); systemd_src = string_printf("%s/%s", prefix, SYSTEMD_SRC); - shim_dst = SHIM_DST; - systemd_dst = SYSTEMD_DST; + /* SHIM_DST and SYSTEMD_DST are defined with leading '/' */ + shim_dst_host = BOOT_DIRECTORY SHIM_DST; + systemd_dst_host = BOOT_DIRECTORY SYSTEMD_DST; + + shim_dst_esp = SHIM_DST; free(prefix); diff --git a/src/bootman/kernel.c b/src/bootman/kernel.c index a0b1a5b..c69c974 100644 --- a/src/bootman/kernel.c +++ b/src/bootman/kernel.c @@ -613,7 +613,7 @@ bool boot_manager_install_kernel_internal(const BootManager *manager, const Kern strerror(errno)); return false; } - kfile_target = string_printf("%s/%s", efi_boot_dir, kernel->target.path); + kfile_target = string_printf(BOOT_DIRECTORY "%s/%s", efi_boot_dir, kernel->target.path); } else { kfile_target = string_printf("%s/%s", base_path, kernel->target.legacy_path); } @@ -637,7 +637,7 @@ bool boot_manager_install_kernel_internal(const BootManager *manager, const Kern } if (is_uefi) { - initrd_target = string_printf("%s/%s", efi_boot_dir, kernel->target.initrd_path); + initrd_target = string_printf(BOOT_DIRECTORY "%s/%s", efi_boot_dir, kernel->target.initrd_path); } else { initrd_target = string_printf("%s/%s", base_path, kernel->target.initrd_path); } diff --git a/src/efi/cbm_efi.c b/src/efi/cbm_efi.c index cced9e9..afbfc59 100644 --- a/src/efi/cbm_efi.c +++ b/src/efi/cbm_efi.c @@ -168,7 +168,7 @@ int get_part_info(const char *path, part_info_t *pi) { return 0; } -int efi_create_boot_rec(const char *boot_loader_path) { +int efi_create_boot_rec(const char *bootloader_host_path, const char *bootloader_esp_path) { part_info_t pi; uint8_t fdev_path[PATH_MAX]; char *boot_var_name; @@ -176,19 +176,14 @@ int efi_create_boot_rec(const char *boot_loader_path) { uint32_t boot_var_attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; - char rel_path[PATH_MAX]; int slot = find_free_boot_rec(); ssize_t len; if (slot < 0) return -1; - if (get_part_info(boot_loader_path, &pi)) return -1; + if (get_part_info(bootloader_host_path, &pi)) return -1; - /* FIXME: pass the booloader in two parts. The below cuts off /boot where - * it's normally mounted. */ - strcpy(rel_path, boot_loader_path + 5); - - len = efi_generate_file_device_path_from_esp(fdev_path, PATH_MAX, pi.disk_path, pi.part_no, rel_path, EFIBOOT_ABBREV_HD); + len = efi_generate_file_device_path_from_esp(fdev_path, PATH_MAX, pi.disk_path, pi.part_no, bootloader_esp_path, EFIBOOT_ABBREV_HD); if (len < 0) return -1; /* FIXME: figure out why LOAD_OPTION_ACTIVE is not defined (should be diff --git a/src/efi/cbm_efi.h b/src/efi/cbm_efi.h index ac293a3..9066da1 100644 --- a/src/efi/cbm_efi.h +++ b/src/efi/cbm_efi.h @@ -10,6 +10,6 @@ */ int efi_init(void); -int efi_create_boot_rec(const char *); +int efi_create_boot_rec(const char *, const char *); /* vim: set nosi noai cin ts=4 sw=4 et tw=80: */ From eacdfc4293f9ec54b110d2791c861a5d7a6fc975 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Fri, 18 Aug 2017 05:12:04 +0000 Subject: [PATCH 14/38] Make internal function static. --- src/efi/cbm_efi.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/efi/cbm_efi.c b/src/efi/cbm_efi.c index afbfc59..990cd1d 100644 --- a/src/efi/cbm_efi.c +++ b/src/efi/cbm_efi.c @@ -139,7 +139,7 @@ typedef struct part_info { /* Given the location of the booloader, returns the partition information needed * to create boot variable which points to that bootloader. */ -int get_part_info(const char *path, part_info_t *pi) { +static int get_part_info(const char *path, part_info_t *pi) { blkid_probe probe; blkid_partition part; blkid_partlist parts; From 30e9f067606f69976dfe3ec00ecc39a101ef6832 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Fri, 18 Aug 2017 06:53:38 +0000 Subject: [PATCH 15/38] Avoid creating duplicate Boot* vars. Attempt to find variables with exaact same content before creating a new one. --- src/efi/cbm_efi.c | 49 ++++++++++++++++++++++++++++++++++++++++++----- 1 file changed, 44 insertions(+), 5 deletions(-) diff --git a/src/efi/cbm_efi.c b/src/efi/cbm_efi.c index 990cd1d..63ba510 100644 --- a/src/efi/cbm_efi.c +++ b/src/efi/cbm_efi.c @@ -131,6 +131,29 @@ static int find_free_boot_rec(void) { return res; } +static boot_rec_t *find_boot_rec(uint8_t *data, size_t size) { + boot_rec_t *c = boot_recs; + boot_rec_t *res = NULL; + + uint8_t *cdata; + size_t csize; + uint32_t cattr; + + if (!boot_recs) return NULL; + if (boot_recs_cnt < 1) return NULL; + + do { + if (efi_get_variable(EFI_GLOBAL_GUID, c->name, &cdata, &csize, &cattr) < 0) continue; + if (csize == size && !memcmp(cdata, data, csize)) { + res = c; + break; + } + } while ((c = c->next)); + + return res; + +} + typedef struct part_info { char *disk_path; int part_no; @@ -176,11 +199,9 @@ int efi_create_boot_rec(const char *bootloader_host_path, const char *bootloader uint32_t boot_var_attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; - int slot = find_free_boot_rec(); + boot_rec_t *rec; ssize_t len; - if (slot < 0) return -1; - if (get_part_info(bootloader_host_path, &pi)) return -1; len = efi_generate_file_device_path_from_esp(fdev_path, PATH_MAX, pi.disk_path, pi.part_no, bootloader_esp_path, EFIBOOT_ABBREV_HD); @@ -193,8 +214,26 @@ int efi_create_boot_rec(const char *bootloader_host_path, const char *bootloader if (len < 0) return -1; - if (asprintf(&boot_var_name, "%s%04x", "Boot", slot) < 0) return -1; - if (efi_set_variable(EFI_GLOBAL_GUID, boot_var_name, boot_var_data, (size_t)len, boot_var_attr, 0644) < 0) return -1; + if (!(rec = find_boot_rec(boot_var_data, (size_t)len))) { + int slot = find_free_boot_rec(); + boot_rec_t *c; + if (slot < 0) return -1; + if (asprintf(&boot_var_name, "%s%04x", "Boot", slot) < 0) return -1; + if (efi_set_variable(EFI_GLOBAL_GUID, boot_var_name, boot_var_data, (size_t)len, boot_var_attr, 0644) < 0) return -1; + /* re-read the records and find the variable that was just created. */ + if (read_boot_recs() < 0) return -1; + if (!boot_recs) return -1; /* something went terribly wrong */ + c = boot_recs; + do { + if (!strcmp(c->name, boot_var_name)) { + rec = c; + break; + } + } while ((c = c->next)); + if (!rec) return -1; + } + /* TODO: put the var first in the boot order */ + return 0; } From 79b8c78b916e0508428f8e482a203913d93e332d Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Sun, 20 Aug 2017 06:38:40 +0000 Subject: [PATCH 16/38] Clean up. Refactor. --- src/efi/cbm_efi.c | 98 ++++++++++++++++++++++++++++------------------- src/efi/cbm_efi.h | 1 + 2 files changed, 60 insertions(+), 39 deletions(-) diff --git a/src/efi/cbm_efi.c b/src/efi/cbm_efi.c index 63ba510..b067fe9 100644 --- a/src/efi/cbm_efi.c +++ b/src/efi/cbm_efi.c @@ -23,12 +23,17 @@ #include #include #include +#include #include #include #include #include #include +/* 1K is the limit for boot var storage that efivar defines. it should be + * enough. actual space occupied is normally >2 times less. */ +#define BOOT_VAR_MAX 1024 + typedef struct boot_rec boot_rec_t; struct boot_rec { @@ -45,14 +50,15 @@ static void free_boot_recs(void) { boot_rec_t *p, *c; c = boot_recs; if (!c) return; + boot_recs = NULL; do { p = c; c = c->next; free(p); } while (c); - boot_recs = NULL; } +static void print_boot_recs(void) __attribute__((unused)); static void print_boot_recs(void) { boot_rec_t *c = boot_recs; if (!c) return; @@ -61,6 +67,7 @@ static void print_boot_recs(void) { } while ((c = c->next)); } +/* enumerates boot recs and initializes boot_recs and boot_recs_cnt. */ static int read_boot_recs(void) { int res; efi_guid_t *guid = NULL; @@ -93,7 +100,6 @@ static int read_boot_recs(void) { i++; } boot_recs_cnt = i; - print_boot_recs(); return 0; } @@ -101,6 +107,7 @@ static int cmp(const void *a, const void *b) { return *((int *)a) - *((int *)b); } +/* finds the first available free number for a boot var. */ static int find_free_boot_rec(void) { int *nums; int res; @@ -109,7 +116,7 @@ static int find_free_boot_rec(void) { size_t cnt; if (!boot_recs) return -1; - if (boot_recs_cnt < 1) return 0; + if (!boot_recs_cnt) return 0; /* no records. */ cnt = (size_t)boot_recs_cnt; @@ -126,11 +133,11 @@ static int find_free_boot_rec(void) { for (i = 0, res = 0; i < boot_recs_cnt; i++, res++) { if (res < nums[i]) break; } - if (res == nums[boot_recs_cnt - 1]) res++; - fprintf(stderr, "Found: %d\n", res); + if (res == nums[boot_recs_cnt - 1]) res++; /* no gap. */ return res; } +/* finds and returns boot rec whose value is data of size. NULL if not found. */ static boot_rec_t *find_boot_rec(uint8_t *data, size_t size) { boot_rec_t *c = boot_recs; boot_rec_t *res = NULL; @@ -139,8 +146,7 @@ static boot_rec_t *find_boot_rec(uint8_t *data, size_t size) { size_t csize; uint32_t cattr; - if (!boot_recs) return NULL; - if (boot_recs_cnt < 1) return NULL; + if (!boot_recs || !boot_recs_cnt) return NULL; do { if (efi_get_variable(EFI_GLOBAL_GUID, c->name, &cdata, &csize, &cattr) < 0) continue; @@ -151,7 +157,6 @@ static boot_rec_t *find_boot_rec(uint8_t *data, size_t size) { } while ((c = c->next)); return res; - } typedef struct part_info { @@ -160,8 +165,9 @@ typedef struct part_info { char *part_type; } part_info_t; -/* Given the location of the booloader, returns the partition information needed - * to create boot variable which points to that bootloader. */ +/* given the location of the booloader (as accessible by the host), returns the + * partition information needed to create boot variable which points to that + * bootloader. */ static int get_part_info(const char *path, part_info_t *pi) { blkid_probe probe; blkid_partition part; @@ -191,48 +197,58 @@ static int get_part_info(const char *path, part_info_t *pi) { return 0; } +/* attempts to look up existing record, otherwise creates a new one. */ +static boot_rec_t *efi_add_boot_rec(uint8_t *data, size_t len) { + char name[9]; /* variable name, e.g. "BootXXXX". */ + int slot; + uint32_t attr = EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS + | EFI_VARIABLE_RUNTIME_ACCESS; + boot_rec_t *c, + *res = find_boot_rec(data, len); + + if (res) return res; + /* no such record, create one. */ + slot = find_free_boot_rec(); + if (slot < 0) return NULL; + if (snprintf(name, 9, "Boot%04x", slot) > 8) return NULL; + if (efi_set_variable(EFI_GLOBAL_GUID, name, data, len, attr, 0644) < 0) return NULL; + /* re-read the records and find the variable that was just created. */ + if (read_boot_recs() < 0) return NULL; + if (!boot_recs) return NULL; /* something went terribly wrong. */ + c = boot_recs; + do { + if (!strcmp(c->name, name)) { + res = c; + break; + } + } while ((c = c->next)); + + return res; +} + int efi_create_boot_rec(const char *bootloader_host_path, const char *bootloader_esp_path) { part_info_t pi; uint8_t fdev_path[PATH_MAX]; - char *boot_var_name; - uint8_t boot_var_data[PATH_MAX]; - uint32_t boot_var_attr = EFI_VARIABLE_NON_VOLATILE - | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS; + uint8_t data[BOOT_VAR_MAX]; /* this is what efivar supports and it should be + enough. */ + long int len; boot_rec_t *rec; - ssize_t len; if (get_part_info(bootloader_host_path, &pi)) return -1; - len = efi_generate_file_device_path_from_esp(fdev_path, PATH_MAX, pi.disk_path, pi.part_no, bootloader_esp_path, EFIBOOT_ABBREV_HD); + len = efi_generate_file_device_path_from_esp(fdev_path, PATH_MAX, + pi.disk_path, pi.part_no, bootloader_esp_path, EFIBOOT_ABBREV_HD); if (len < 0) return -1; - /* FIXME: figure out why LOAD_OPTION_ACTIVE is not defined (should be - * defined via efi.h) */ - len = efi_loadopt_create(boot_var_data, PATH_MAX, 0x00000001 /* LOAD_OPTION_ACTIVE */, + len = efi_loadopt_create(data, 1024, LOAD_OPTION_ACTIVE, (void *)fdev_path, len, (unsigned char *)"Linux bootloader", NULL, 0); - if (len < 0) return -1; - if (!(rec = find_boot_rec(boot_var_data, (size_t)len))) { - int slot = find_free_boot_rec(); - boot_rec_t *c; - if (slot < 0) return -1; - if (asprintf(&boot_var_name, "%s%04x", "Boot", slot) < 0) return -1; - if (efi_set_variable(EFI_GLOBAL_GUID, boot_var_name, boot_var_data, (size_t)len, boot_var_attr, 0644) < 0) return -1; - /* re-read the records and find the variable that was just created. */ - if (read_boot_recs() < 0) return -1; - if (!boot_recs) return -1; /* something went terribly wrong */ - c = boot_recs; - do { - if (!strcmp(c->name, boot_var_name)) { - rec = c; - break; - } - } while ((c = c->next)); - if (!rec) return -1; - } + rec = efi_add_boot_rec(data, (size_t)len); + /* TODO: put the var first in the boot order */ + (void)rec; return 0; } @@ -243,4 +259,8 @@ int efi_init(void) { return 0; } +void efi_destroy(void) { + free_boot_recs(); +} + /* vim: set nosi noai cin ts=4 sw=4 et tw=80: */ diff --git a/src/efi/cbm_efi.h b/src/efi/cbm_efi.h index 9066da1..da4b3e4 100644 --- a/src/efi/cbm_efi.h +++ b/src/efi/cbm_efi.h @@ -10,6 +10,7 @@ */ int efi_init(void); +void efi_destroy(void); int efi_create_boot_rec(const char *, const char *); /* vim: set nosi noai cin ts=4 sw=4 et tw=80: */ From b8b996968dcc45c1e5858ac396c7c92ac69456ed Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Sun, 20 Aug 2017 07:10:12 +0000 Subject: [PATCH 17/38] Move implementation. Rename and prefix functions. --- Makefile.am | 4 +-- src/bootloaders/shim-systemd.c | 8 +++--- src/{efi/cbm_efi.c => lib/bootvar.c} | 38 ++++++++++++++-------------- src/{efi/cbm_efi.h => lib/bootvar.h} | 6 ++--- 4 files changed, 29 insertions(+), 27 deletions(-) rename src/{efi/cbm_efi.c => lib/bootvar.c} (87%) rename src/{efi/cbm_efi.h => lib/bootvar.h} (80%) diff --git a/Makefile.am b/Makefile.am index a8bc157..19b3881 100644 --- a/Makefile.am +++ b/Makefile.am @@ -126,8 +126,8 @@ libcbm_la_SOURCES = \ src/lib/writer.c \ src/lib/util.h \ src/lib/util.c \ - src/efi/cbm_efi.c \ - src/efi/cbm_efi.h + src/lib/bootvar.c \ + src/lib/bootvar.h libcbm_la_CFLAGS = \ -D_BOOTMAN_INTERNAL_ \ diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index 7e3ba47..20e22f5 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -15,7 +15,7 @@ #include "bootloader.h" #include "bootman.h" -#include "cbm_efi.h" +#include "bootvar.h" #include "config.h" #include "files.h" #include "nica/files.h" @@ -171,7 +171,7 @@ static bool shim_systemd_install(const BootManager *manager) { if (!copy_file_atomic(shim_src, shim_dst_host, 00644)) return false; if (!copy_file_atomic(systemd_src, systemd_dst_host, 00644)) return false; - if (efi_create_boot_rec(shim_dst_host, shim_dst_esp)) return false; + if (bootvar_create(shim_dst_host, shim_dst_esp)) return false; return true; } @@ -192,7 +192,7 @@ static bool shim_systemd_init(const BootManager *manager) { size_t len; char *prefix; - if (efi_init()) return false; + if (bootvar_init()) return false; /* init systemd-class since we're reusing it for kernel install. * specific values do not matter as long as sd_class is not used to @@ -229,6 +229,8 @@ static void shim_systemd_destroy(const BootManager *manager) { free(shim_src); free(systemd_src); + bootvar_destroy(); + return; } diff --git a/src/efi/cbm_efi.c b/src/lib/bootvar.c similarity index 87% rename from src/efi/cbm_efi.c rename to src/lib/bootvar.c index b067fe9..afa5e90 100644 --- a/src/efi/cbm_efi.c +++ b/src/lib/bootvar.c @@ -46,7 +46,7 @@ struct boot_rec { static boot_rec_t *boot_recs; static int boot_recs_cnt; -static void free_boot_recs(void) { +static void bootvar_free_boot_recs(void) { boot_rec_t *p, *c; c = boot_recs; if (!c) return; @@ -58,8 +58,8 @@ static void free_boot_recs(void) { } while (c); } -static void print_boot_recs(void) __attribute__((unused)); -static void print_boot_recs(void) { +static void bootvar_print_boot_recs(void) __attribute__((unused)); +static void bootvar_print_boot_recs(void) { boot_rec_t *c = boot_recs; if (!c) return; do { @@ -68,7 +68,7 @@ static void print_boot_recs(void) { } /* enumerates boot recs and initializes boot_recs and boot_recs_cnt. */ -static int read_boot_recs(void) { +static int bootvar_read_boot_recs(void) { int res; efi_guid_t *guid = NULL; char *name = NULL; @@ -76,7 +76,7 @@ static int read_boot_recs(void) { *c; int i = 0; - free_boot_recs(); + bootvar_free_boot_recs(); while ((res = efi_get_next_variable_name(&guid, &name)) > 0) { char *num_end; @@ -108,7 +108,7 @@ static int cmp(const void *a, const void *b) { } /* finds the first available free number for a boot var. */ -static int find_free_boot_rec(void) { +static int bootvar_find_free_no(void) { int *nums; int res; int i = 0; @@ -138,7 +138,7 @@ static int find_free_boot_rec(void) { } /* finds and returns boot rec whose value is data of size. NULL if not found. */ -static boot_rec_t *find_boot_rec(uint8_t *data, size_t size) { +static boot_rec_t *bootvar_find_boot_rec(uint8_t *data, size_t size) { boot_rec_t *c = boot_recs; boot_rec_t *res = NULL; @@ -168,7 +168,7 @@ typedef struct part_info { /* given the location of the booloader (as accessible by the host), returns the * partition information needed to create boot variable which points to that * bootloader. */ -static int get_part_info(const char *path, part_info_t *pi) { +static int bootvar_get_part_info(const char *path, part_info_t *pi) { blkid_probe probe; blkid_partition part; blkid_partlist parts; @@ -198,23 +198,23 @@ static int get_part_info(const char *path, part_info_t *pi) { } /* attempts to look up existing record, otherwise creates a new one. */ -static boot_rec_t *efi_add_boot_rec(uint8_t *data, size_t len) { +static boot_rec_t *bootvar_add_boot_rec(uint8_t *data, size_t len) { char name[9]; /* variable name, e.g. "BootXXXX". */ int slot; uint32_t attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | EFI_VARIABLE_RUNTIME_ACCESS; boot_rec_t *c, - *res = find_boot_rec(data, len); + *res = bootvar_find_boot_rec(data, len); if (res) return res; /* no such record, create one. */ - slot = find_free_boot_rec(); + slot = bootvar_find_free_no(); if (slot < 0) return NULL; if (snprintf(name, 9, "Boot%04x", slot) > 8) return NULL; if (efi_set_variable(EFI_GLOBAL_GUID, name, data, len, attr, 0644) < 0) return NULL; /* re-read the records and find the variable that was just created. */ - if (read_boot_recs() < 0) return NULL; + if (bootvar_read_boot_recs() < 0) return NULL; if (!boot_recs) return NULL; /* something went terribly wrong. */ c = boot_recs; do { @@ -227,7 +227,7 @@ static boot_rec_t *efi_add_boot_rec(uint8_t *data, size_t len) { return res; } -int efi_create_boot_rec(const char *bootloader_host_path, const char *bootloader_esp_path) { +int bootvar_create(const char *bootloader_host_path, const char *bootloader_esp_path) { part_info_t pi; uint8_t fdev_path[PATH_MAX]; uint8_t data[BOOT_VAR_MAX]; /* this is what efivar supports and it should be @@ -235,7 +235,7 @@ int efi_create_boot_rec(const char *bootloader_host_path, const char *bootloader long int len; boot_rec_t *rec; - if (get_part_info(bootloader_host_path, &pi)) return -1; + if (bootvar_get_part_info(bootloader_host_path, &pi)) return -1; len = efi_generate_file_device_path_from_esp(fdev_path, PATH_MAX, pi.disk_path, pi.part_no, bootloader_esp_path, EFIBOOT_ABBREV_HD); @@ -245,7 +245,7 @@ int efi_create_boot_rec(const char *bootloader_host_path, const char *bootloader (void *)fdev_path, len, (unsigned char *)"Linux bootloader", NULL, 0); if (len < 0) return -1; - rec = efi_add_boot_rec(data, (size_t)len); + rec = bootvar_add_boot_rec(data, (size_t)len); /* TODO: put the var first in the boot order */ (void)rec; @@ -253,14 +253,14 @@ int efi_create_boot_rec(const char *bootloader_host_path, const char *bootloader return 0; } -int efi_init(void) { +int bootvar_init(void) { if (efi_variables_supported() < 0) return -1; - if (read_boot_recs() < 0) return -1; + if (bootvar_read_boot_recs() < 0) return -1; return 0; } -void efi_destroy(void) { - free_boot_recs(); +void bootvar_destroy(void) { + bootvar_free_boot_recs(); } /* vim: set nosi noai cin ts=4 sw=4 et tw=80: */ diff --git a/src/efi/cbm_efi.h b/src/lib/bootvar.h similarity index 80% rename from src/efi/cbm_efi.h rename to src/lib/bootvar.h index da4b3e4..99d7121 100644 --- a/src/efi/cbm_efi.h +++ b/src/lib/bootvar.h @@ -9,8 +9,8 @@ * of the License, or (at your option) any later version. */ -int efi_init(void); -void efi_destroy(void); -int efi_create_boot_rec(const char *, const char *); +int bootvar_init(void); +void bootvar_destroy(void); +int bootvar_create(const char *, const char *); /* vim: set nosi noai cin ts=4 sw=4 et tw=80: */ From 809aeb2ce804e63450679b29df6d732bd059fbd2 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Sun, 20 Aug 2017 07:36:39 +0000 Subject: [PATCH 18/38] Remove debug output. --- src/bootloaders/shim-systemd.c | 14 +++----------- 1 file changed, 3 insertions(+), 11 deletions(-) diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index 20e22f5..06a9d11 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -115,21 +115,20 @@ static char *shim_systemd_get_kernel_dst(const BootManager *manager) { } static bool shim_systemd_install_kernel(const BootManager *manager, const Kernel *kernel) { - fprintf(stderr, "Call %s\n", __func__); return sd_class_install_kernel_impl(manager, kernel, shim_systemd_get_kernel_dst, NULL); } static bool shim_systemd_remove_kernel(const BootManager *manager, const Kernel *kernel) { (void)manager; (void)kernel; - fprintf(stderr, "Call %s\n", __func__); + fprintf(stderr, "%s is not implemented\n", __func__); return true; } static bool shim_systemd_set_default_kernel(const BootManager *manager, const Kernel *kernel) { (void)manager; (void)kernel; - fprintf(stderr, "Call %s\n", __func__); + fprintf(stderr, "%s is not implemented\n", __func__); return true; } @@ -141,7 +140,6 @@ static bool exists_identical(const char *path, const char *spath) { static bool shim_systemd_needs_install(const BootManager *manager) { (void)manager; - fprintf(stderr, "Call %s\n", __func__); if (!exists_identical(shim_dst_host, NULL)) return true; if (!exists_identical(systemd_dst_host, NULL)) return true; return false; @@ -149,7 +147,6 @@ static bool shim_systemd_needs_install(const BootManager *manager) { static bool shim_systemd_needs_update(const BootManager *manager) { (void)manager; - fprintf(stderr, "Call %s\n", __func__); if (!exists_identical(shim_dst_host, shim_src)) return true; if (!exists_identical(systemd_dst_host, systemd_src)) return true; return false; @@ -164,7 +161,6 @@ static bool make_layout(void) { static bool shim_systemd_install(const BootManager *manager) { (void)manager; - fprintf(stderr, "Call %s\n", __func__); if (!make_layout()) return false; @@ -177,18 +173,16 @@ static bool shim_systemd_install(const BootManager *manager) { } static bool shim_systemd_update(const BootManager *manager) { - fprintf(stderr, "Call %s\n", __func__); return shim_systemd_install(manager); } static bool shim_systemd_remove(const BootManager *manager) { (void)manager; - fprintf(stderr, "Call %s\n", __func__); + fprintf(stderr, "%s is not implemented\n", __func__); return true; } static bool shim_systemd_init(const BootManager *manager) { - fprintf(stderr, "Call %s\n", __func__); size_t len; char *prefix; @@ -224,7 +218,6 @@ static bool shim_systemd_init(const BootManager *manager) { static void shim_systemd_destroy(const BootManager *manager) { (void)manager; - fprintf(stderr, "Call %s\n", __func__); free(shim_src); free(systemd_src); @@ -236,7 +229,6 @@ static void shim_systemd_destroy(const BootManager *manager) { static int shim_systemd_get_capabilities(const BootManager *manager) { (void)manager; - fprintf(stderr, "Call %s\n", __func__); return BOOTLOADER_CAP_GPT | BOOTLOADER_CAP_UEFI; } From 43baee8f91f503f9a118c8e0b17a803637df73cb Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Sun, 20 Aug 2017 07:49:22 +0000 Subject: [PATCH 19/38] Reuse set_default_kernel from systemd-class. --- src/bootloaders/shim-systemd.c | 7 +++---- src/bootloaders/systemd-class.c | 9 +++++++-- src/bootloaders/systemd-class.h | 3 +++ 3 files changed, 13 insertions(+), 6 deletions(-) diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index 06a9d11..a600d18 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -126,10 +126,9 @@ static bool shim_systemd_remove_kernel(const BootManager *manager, const Kernel } static bool shim_systemd_set_default_kernel(const BootManager *manager, const Kernel *kernel) { - (void)manager; - (void)kernel; - fprintf(stderr, "%s is not implemented\n", __func__); - return true; + /* this writes systemd config. systemd has the configuration paths + * hardcoded, hence whatever sd_class is doing is OK. */ + return sd_class_set_default_kernel_impl(manager, kernel, NULL); } static bool exists_identical(const char *path, const char *spath) { diff --git a/src/bootloaders/systemd-class.c b/src/bootloaders/systemd-class.c index 85ad830..b5efa62 100644 --- a/src/bootloaders/systemd-class.c +++ b/src/bootloaders/systemd-class.c @@ -300,13 +300,14 @@ bool sd_class_remove_kernel(const BootManager *manager, const Kernel *kernel) return true; } -bool sd_class_set_default_kernel(const BootManager *manager, const Kernel *kernel) +bool sd_class_set_default_kernel_impl(const BootManager *manager, const Kernel *kernel, + bool (*ensure_layout)(const BootManager *)) { if (!manager) { return false; } - if (!sd_class_ensure_dirs(manager)) { + if (ensure_layout && !ensure_layout(manager)) { LOG_FATAL("Failed to create required directories for %s", sd_config->name); return false; } @@ -366,6 +367,10 @@ write_config: return true; } +bool sd_class_set_default_kernel(const BootManager *manager, const Kernel *kernel) { + return sd_class_set_default_kernel_impl(manager, kernel, sd_class_ensure_dirs); +} + bool sd_class_needs_install(const BootManager *manager) { if (!manager) { diff --git a/src/bootloaders/systemd-class.h b/src/bootloaders/systemd-class.h index 6347096..5003039 100644 --- a/src/bootloaders/systemd-class.h +++ b/src/bootloaders/systemd-class.h @@ -41,6 +41,9 @@ bool sd_class_remove_kernel(const BootManager *manager, const Kernel *kernel); bool sd_class_set_default_kernel(const BootManager *manager, const Kernel *kernel); +bool sd_class_set_default_kernel_impl(const BootManager *manager, const Kernel *kernel, + bool (*ensure_layout)(const BootManager *)); + bool sd_class_needs_install(const BootManager *manager); bool sd_class_needs_update(const BootManager *manager); From d2c0fa4248344603e6a5c11ec8e085c5e11d0c3a Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Sun, 20 Aug 2017 08:13:35 +0000 Subject: [PATCH 20/38] Make bootvar_create return boot var name. Also, pass the ESP mount point instead of host bootloader path to determine the partition information. --- src/bootloaders/shim-systemd.c | 4 ++-- src/lib/bootvar.c | 20 ++++++++++++++------ src/lib/bootvar.h | 2 +- 3 files changed, 17 insertions(+), 9 deletions(-) diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index a600d18..a2283be 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -159,6 +159,7 @@ static bool make_layout(void) { } static bool shim_systemd_install(const BootManager *manager) { + char varname[9]; (void)manager; if (!make_layout()) return false; @@ -166,7 +167,7 @@ static bool shim_systemd_install(const BootManager *manager) { if (!copy_file_atomic(shim_src, shim_dst_host, 00644)) return false; if (!copy_file_atomic(systemd_src, systemd_dst_host, 00644)) return false; - if (bootvar_create(shim_dst_host, shim_dst_esp)) return false; + if (bootvar_create(BOOT_DIRECTORY, shim_dst_esp, varname, 9)) return false; return true; } @@ -220,7 +221,6 @@ static void shim_systemd_destroy(const BootManager *manager) { free(shim_src); free(systemd_src); - bootvar_destroy(); return; diff --git a/src/lib/bootvar.c b/src/lib/bootvar.c index afa5e90..3d9fd53 100644 --- a/src/lib/bootvar.c +++ b/src/lib/bootvar.c @@ -165,9 +165,8 @@ typedef struct part_info { char *part_type; } part_info_t; -/* given the location of the booloader (as accessible by the host), returns the - * partition information needed to create boot variable which points to that - * bootloader. */ +/* given the location of the ESP mount point, returns the partition information + * needed to create boot variable which points to that bootloader. */ static int bootvar_get_part_info(const char *path, part_info_t *pi) { blkid_probe probe; blkid_partition part; @@ -227,7 +226,8 @@ static boot_rec_t *bootvar_add_boot_rec(uint8_t *data, size_t len) { return res; } -int bootvar_create(const char *bootloader_host_path, const char *bootloader_esp_path) { +int bootvar_create(const char *esp_mount_path, const char *bootloader_esp_path, + char *varname, size_t size) { part_info_t pi; uint8_t fdev_path[PATH_MAX]; uint8_t data[BOOT_VAR_MAX]; /* this is what efivar supports and it should be @@ -235,17 +235,25 @@ int bootvar_create(const char *bootloader_host_path, const char *bootloader_esp_ long int len; boot_rec_t *rec; - if (bootvar_get_part_info(bootloader_host_path, &pi)) return -1; + if (bootvar_get_part_info(esp_mount_path, &pi)) return -1; len = efi_generate_file_device_path_from_esp(fdev_path, PATH_MAX, pi.disk_path, pi.part_no, bootloader_esp_path, EFIBOOT_ABBREV_HD); if (len < 0) return -1; - len = efi_loadopt_create(data, 1024, LOAD_OPTION_ACTIVE, + len = efi_loadopt_create(data, BOOT_VAR_MAX, LOAD_OPTION_ACTIVE, (void *)fdev_path, len, (unsigned char *)"Linux bootloader", NULL, 0); if (len < 0) return -1; rec = bootvar_add_boot_rec(data, (size_t)len); + if (!rec) return -1; + + if (varname && size) { + size_t len = strlen(rec->name); + if (len < size) { + snprintf(varname, len + 1, "%s", rec->name); + } + } /* TODO: put the var first in the boot order */ (void)rec; diff --git a/src/lib/bootvar.h b/src/lib/bootvar.h index 99d7121..dd5300a 100644 --- a/src/lib/bootvar.h +++ b/src/lib/bootvar.h @@ -11,6 +11,6 @@ int bootvar_init(void); void bootvar_destroy(void); -int bootvar_create(const char *, const char *); +int bootvar_create(const char *, const char *, char *, size_t); /* vim: set nosi noai cin ts=4 sw=4 et tw=80: */ From 1e125542fbd3518718cfbaba31aa0786bf06f25f Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Sun, 20 Aug 2017 08:20:27 +0000 Subject: [PATCH 21/38] Use capital hex in boot vars(compliant with UEFI). --- src/lib/bootvar.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/lib/bootvar.c b/src/lib/bootvar.c index 3d9fd53..08aa8f1 100644 --- a/src/lib/bootvar.c +++ b/src/lib/bootvar.c @@ -210,7 +210,7 @@ static boot_rec_t *bootvar_add_boot_rec(uint8_t *data, size_t len) { /* no such record, create one. */ slot = bootvar_find_free_no(); if (slot < 0) return NULL; - if (snprintf(name, 9, "Boot%04x", slot) > 8) return NULL; + if (snprintf(name, 9, "Boot%04X", slot) > 8) return NULL; if (efi_set_variable(EFI_GLOBAL_GUID, name, data, len, attr, 0644) < 0) return NULL; /* re-read the records and find the variable that was just created. */ if (bootvar_read_boot_recs() < 0) return NULL; From 2133e5f6faf67316e657d7d49f985b9d0eff55e5 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Sun, 20 Aug 2017 08:43:56 +0000 Subject: [PATCH 22/38] Fix memory usage. --- src/lib/bootvar.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/lib/bootvar.c b/src/lib/bootvar.c index 08aa8f1..bc24665 100644 --- a/src/lib/bootvar.c +++ b/src/lib/bootvar.c @@ -160,9 +160,9 @@ static boot_rec_t *bootvar_find_boot_rec(uint8_t *data, size_t size) { } typedef struct part_info { - char *disk_path; + char disk_path[PATH_MAX]; int part_no; - char *part_type; + char part_type[36+1]; /* GUID string, hyphen notation */ } part_info_t; /* given the location of the ESP mount point, returns the partition information @@ -187,9 +187,9 @@ static int bootvar_get_part_info(const char *path, part_info_t *pi) { if (!(parts = blkid_probe_get_partitions(probe))) return -1; part = blkid_partlist_devno_to_partition(parts, st.st_dev); - pi->disk_path = strdup(disk_path); + snprintf(pi->disk_path, strlen(disk_path) + 1, "%s", disk_path); pi->part_no = blkid_partition_get_partno(part); - pi->part_type = strdup(blkid_partition_get_type_string(part)); + snprintf(pi->part_type, 36 + 1, "%s", blkid_partition_get_type_string(part)); blkid_free_probe(probe); From 4b2e4dadc1b10a5f09f6280fab9c3b25b99d6026 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Mon, 21 Aug 2017 21:14:25 +0000 Subject: [PATCH 23/38] Add the boot record first to the boot order. --- src/lib/bootvar.c | 58 ++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 55 insertions(+), 3 deletions(-) diff --git a/src/lib/bootvar.c b/src/lib/bootvar.c index bc24665..e9ea62c 100644 --- a/src/lib/bootvar.c +++ b/src/lib/bootvar.c @@ -103,6 +103,59 @@ static int bootvar_read_boot_recs(void) { return 0; } +/* given the record, puts it first in the boot order (via BootOrder EFI + * variable). */ +static int bootvar_push_to_boot_order(boot_rec_t *rec) { + uint16_t number; + uint16_t *boot_order; + uint16_t *new_boot_order; + size_t boot_order_size; + size_t new_boot_order_size; + uint32_t boot_order_attrs; + unsigned int i; + int found = 0; + + if (!rec || !rec->name) return -1; + + if (efi_get_variable(EFI_GLOBAL_GUID, "BootOrder", (uint8_t **)&boot_order, &boot_order_size, &boot_order_attrs)) return -1; + + sscanf(rec->name, "Boot%04hX", &number); + + /* read as uint16_t, hence twice less the returned size */ + boot_order_size >>= 1; + + for (i = 0; i < boot_order_size; i++) { + if (boot_order[i] == number) { + found = 1; + break; + } + } + + if (!found) { + new_boot_order_size = boot_order_size + 1; + new_boot_order = (uint16_t *)malloc(new_boot_order_size * sizeof(uint16_t)); + new_boot_order[0] = number; + memcpy(new_boot_order + 1, boot_order, boot_order_size * sizeof(uint16_t)); + } else { + uint16_t *c; + new_boot_order = (uint16_t *)malloc(boot_order_size * sizeof(uint16_t)); + new_boot_order[0] = number; + c = new_boot_order + 1; + for (i = 0; i < boot_order_size; i++) { + if (boot_order[i] != number) { + *c = boot_order[i]; + c++; + } + } + new_boot_order_size = (size_t)(c - new_boot_order); + } + + new_boot_order_size <<= 1; + if (efi_set_variable(EFI_GLOBAL_GUID, "BootOrder", (uint8_t *)new_boot_order, new_boot_order_size, boot_order_attrs, 0644)) return -1; + + return 0; +} + static int cmp(const void *a, const void *b) { return *((int *)a) - *((int *)b); } @@ -248,6 +301,8 @@ int bootvar_create(const char *esp_mount_path, const char *bootloader_esp_path, rec = bootvar_add_boot_rec(data, (size_t)len); if (!rec) return -1; + if (bootvar_push_to_boot_order(rec)) return -1; + if (varname && size) { size_t len = strlen(rec->name); if (len < size) { @@ -255,9 +310,6 @@ int bootvar_create(const char *esp_mount_path, const char *bootloader_esp_path, } } - /* TODO: put the var first in the boot order */ - (void)rec; - return 0; } From c4c0d1b201a05d48fd2937d8ff4ebcf9ee938d39 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Tue, 29 Aug 2017 17:59:26 +0000 Subject: [PATCH 24/38] Change code style to 8-space indent. --- src/lib/bootvar.c | 380 +++++++++++++++++++++++----------------------- src/lib/bootvar.h | 2 +- 2 files changed, 190 insertions(+), 192 deletions(-) diff --git a/src/lib/bootvar.c b/src/lib/bootvar.c index e9ea62c..ff022da 100644 --- a/src/lib/bootvar.c +++ b/src/lib/bootvar.c @@ -37,290 +37,288 @@ typedef struct boot_rec boot_rec_t; struct boot_rec { - char *name; - int num; - unsigned char *data; - boot_rec_t *next; + char *name; + int num; + unsigned char *data; + boot_rec_t *next; }; static boot_rec_t *boot_recs; static int boot_recs_cnt; static void bootvar_free_boot_recs(void) { - boot_rec_t *p, *c; - c = boot_recs; - if (!c) return; - boot_recs = NULL; - do { - p = c; - c = c->next; - free(p); - } while (c); + boot_rec_t *p, *c; + c = boot_recs; + if (!c) return; + boot_recs = NULL; + do { + p = c; + c = c->next; + free(p); + } while (c); } static void bootvar_print_boot_recs(void) __attribute__((unused)); static void bootvar_print_boot_recs(void) { - boot_rec_t *c = boot_recs; - if (!c) return; - do { - fprintf(stderr, "Boot record #%d: %s\n", c->num, c->name); - } while ((c = c->next)); + boot_rec_t *c = boot_recs; + if (!c) return; + do { + fprintf(stderr, "Boot record #%d: %s\n", c->num, c->name); + } while ((c = c->next)); } /* enumerates boot recs and initializes boot_recs and boot_recs_cnt. */ static int bootvar_read_boot_recs(void) { - int res; - efi_guid_t *guid = NULL; - char *name = NULL; - boot_rec_t *p = NULL, - *c; - int i = 0; + int res; + efi_guid_t *guid = NULL; + char *name = NULL; + boot_rec_t *p = NULL, + *c; + int i = 0; - bootvar_free_boot_recs(); + bootvar_free_boot_recs(); - while ((res = efi_get_next_variable_name(&guid, &name)) > 0) { - char *num_end; - if (strncmp(name, "Boot", 4)) continue; - if (!isxdigit(name[4]) || !isxdigit(name[5]) || !isxdigit(name[6]) - || !isxdigit(name[7])) continue; - if (memcmp(guid, &efi_guid_global, sizeof(efi_guid_t))) continue; + while ((res = efi_get_next_variable_name(&guid, &name)) > 0) { + char *num_end; + if (strncmp(name, "Boot", 4)) continue; + if (!isxdigit(name[4]) || !isxdigit(name[5]) || !isxdigit(name[6]) + || !isxdigit(name[7])) continue; + if (memcmp(guid, &efi_guid_global, sizeof(efi_guid_t))) continue; - c = (boot_rec_t *)malloc(sizeof(boot_rec_t)); - memset(c, 0, sizeof(boot_rec_t)); - c->name = strdup(name); - c->num = (int)strtol(name + 4, &num_end, 16); - if (num_end - name - 4 != 4) continue; + c = (boot_rec_t *)malloc(sizeof(boot_rec_t)); + memset(c, 0, sizeof(boot_rec_t)); + c->name = strdup(name); + c->num = (int)strtol(name + 4, &num_end, 16); + if (num_end - name - 4 != 4) continue; - if (!boot_recs) { - boot_recs = p = c; - } else { - p->next = c; - p = c; + if (!boot_recs) { + boot_recs = p = c; + } else { + p->next = c; + p = c; + } + i++; } - i++; - } - boot_recs_cnt = i; - return 0; + boot_recs_cnt = i; + return 0; } /* given the record, puts it first in the boot order (via BootOrder EFI * variable). */ static int bootvar_push_to_boot_order(boot_rec_t *rec) { - uint16_t number; - uint16_t *boot_order; - uint16_t *new_boot_order; - size_t boot_order_size; - size_t new_boot_order_size; - uint32_t boot_order_attrs; - unsigned int i; - int found = 0; + uint16_t number; + uint16_t *boot_order; + uint16_t *new_boot_order; + size_t boot_order_size; + size_t new_boot_order_size; + uint32_t boot_order_attrs; + unsigned int i; + int found = 0; - if (!rec || !rec->name) return -1; + if (!rec || !rec->name) return -1; - if (efi_get_variable(EFI_GLOBAL_GUID, "BootOrder", (uint8_t **)&boot_order, &boot_order_size, &boot_order_attrs)) return -1; + if (efi_get_variable(EFI_GLOBAL_GUID, "BootOrder", (uint8_t **)&boot_order, &boot_order_size, &boot_order_attrs)) return -1; - sscanf(rec->name, "Boot%04hX", &number); + sscanf(rec->name, "Boot%04hX", &number); - /* read as uint16_t, hence twice less the returned size */ - boot_order_size >>= 1; + /* read as uint16_t, hence twice less the returned size */ + boot_order_size >>= 1; - for (i = 0; i < boot_order_size; i++) { - if (boot_order[i] == number) { - found = 1; - break; - } - } - - if (!found) { - new_boot_order_size = boot_order_size + 1; - new_boot_order = (uint16_t *)malloc(new_boot_order_size * sizeof(uint16_t)); - new_boot_order[0] = number; - memcpy(new_boot_order + 1, boot_order, boot_order_size * sizeof(uint16_t)); - } else { - uint16_t *c; - new_boot_order = (uint16_t *)malloc(boot_order_size * sizeof(uint16_t)); - new_boot_order[0] = number; - c = new_boot_order + 1; for (i = 0; i < boot_order_size; i++) { - if (boot_order[i] != number) { - *c = boot_order[i]; - c++; - } + if (boot_order[i] == number) { + found = 1; + break; + } } - new_boot_order_size = (size_t)(c - new_boot_order); - } - new_boot_order_size <<= 1; - if (efi_set_variable(EFI_GLOBAL_GUID, "BootOrder", (uint8_t *)new_boot_order, new_boot_order_size, boot_order_attrs, 0644)) return -1; + if (!found) { + new_boot_order_size = boot_order_size + 1; + new_boot_order = (uint16_t *)malloc(new_boot_order_size * sizeof(uint16_t)); + new_boot_order[0] = number; + memcpy(new_boot_order + 1, boot_order, boot_order_size * sizeof(uint16_t)); + } else { + uint16_t *c; + new_boot_order = (uint16_t *)malloc(boot_order_size * sizeof(uint16_t)); + new_boot_order[0] = number; + c = new_boot_order + 1; + for (i = 0; i < boot_order_size; i++) { + if (boot_order[i] != number) { + *c = boot_order[i]; + c++; + } + } + new_boot_order_size = (size_t)(c - new_boot_order); + } - return 0; + new_boot_order_size <<= 1; + if (efi_set_variable(EFI_GLOBAL_GUID, "BootOrder", (uint8_t *)new_boot_order, new_boot_order_size, boot_order_attrs, 0644)) return -1; + + return 0; } static int cmp(const void *a, const void *b) { - return *((int *)a) - *((int *)b); + return *((int *)a) - *((int *)b); } /* finds the first available free number for a boot var. */ static int bootvar_find_free_no(void) { - int *nums; - int res; - int i = 0; - boot_rec_t *c = boot_recs; - size_t cnt; + int *nums; + int res; + int i = 0; + boot_rec_t *c = boot_recs; + size_t cnt; - if (!boot_recs) return -1; - if (!boot_recs_cnt) return 0; /* no records. */ + if (!boot_recs) return -1; + if (!boot_recs_cnt) return 0; /* no records. */ - cnt = (size_t)boot_recs_cnt; + cnt = (size_t)boot_recs_cnt; - nums = (int *)alloca(sizeof(int) * cnt); - memset(nums, 0, sizeof(int) * cnt); + nums = (int *)alloca(sizeof(int) * cnt); + memset(nums, 0, sizeof(int) * cnt); - do { - nums[i] = c->num; - i++; - } while ((c = c->next)); + do { + nums[i] = c->num; + i++; + } while ((c = c->next)); - qsort(nums, cnt, sizeof(int), cmp); + qsort(nums, cnt, sizeof(int), cmp); - for (i = 0, res = 0; i < boot_recs_cnt; i++, res++) { - if (res < nums[i]) break; - } - if (res == nums[boot_recs_cnt - 1]) res++; /* no gap. */ - return res; + for (i = 0, res = 0; i < boot_recs_cnt; i++, res++) { + if (res < nums[i]) break; + } + if (res == nums[boot_recs_cnt - 1]) res++; /* no gap. */ + return res; } /* finds and returns boot rec whose value is data of size. NULL if not found. */ static boot_rec_t *bootvar_find_boot_rec(uint8_t *data, size_t size) { - boot_rec_t *c = boot_recs; - boot_rec_t *res = NULL; + boot_rec_t *c = boot_recs; + boot_rec_t *res = NULL; - uint8_t *cdata; - size_t csize; - uint32_t cattr; + uint8_t *cdata; + size_t csize; + uint32_t cattr; - if (!boot_recs || !boot_recs_cnt) return NULL; + if (!boot_recs || !boot_recs_cnt) return NULL; - do { - if (efi_get_variable(EFI_GLOBAL_GUID, c->name, &cdata, &csize, &cattr) < 0) continue; - if (csize == size && !memcmp(cdata, data, csize)) { - res = c; - break; - } - } while ((c = c->next)); + do { + if (efi_get_variable(EFI_GLOBAL_GUID, c->name, &cdata, &csize, &cattr) < 0) continue; + if (csize == size && !memcmp(cdata, data, csize)) { + res = c; + break; + } + } while ((c = c->next)); - return res; + return res; } typedef struct part_info { - char disk_path[PATH_MAX]; - int part_no; - char part_type[36+1]; /* GUID string, hyphen notation */ + char disk_path[PATH_MAX]; + int part_no; + char part_type[36+1]; /* GUID string, hyphen notation */ } part_info_t; /* given the location of the ESP mount point, returns the partition information * needed to create boot variable which points to that bootloader. */ static int bootvar_get_part_info(const char *path, part_info_t *pi) { - blkid_probe probe; - blkid_partition part; - blkid_partlist parts; - struct stat st; - dev_t disk_dev; - char disk_path[PATH_MAX]; + blkid_probe probe; + blkid_partition part; + blkid_partlist parts; + struct stat st; + dev_t disk_dev; + char disk_path[PATH_MAX]; - if (stat(path, &st)) return -1; + if (stat(path, &st)) return -1; - strcpy(disk_path, "/dev/"); - if (blkid_devno_to_wholedisk(st.st_dev, disk_path + 5, PATH_MAX - 5, &disk_dev)) return -1; + strcpy(disk_path, "/dev/"); + if (blkid_devno_to_wholedisk(st.st_dev, disk_path + 5, PATH_MAX - 5, &disk_dev)) return -1; - if (!(probe = blkid_new_probe_from_filename(disk_path))) return -1; + if (!(probe = blkid_new_probe_from_filename(disk_path))) return -1; - if (blkid_probe_enable_partitions(probe, 1)) return -1; + if (blkid_probe_enable_partitions(probe, 1)) return -1; - if (!(parts = blkid_probe_get_partitions(probe))) return -1; - part = blkid_partlist_devno_to_partition(parts, st.st_dev); + if (!(parts = blkid_probe_get_partitions(probe))) return -1; + part = blkid_partlist_devno_to_partition(parts, st.st_dev); - snprintf(pi->disk_path, strlen(disk_path) + 1, "%s", disk_path); - pi->part_no = blkid_partition_get_partno(part); - snprintf(pi->part_type, 36 + 1, "%s", blkid_partition_get_type_string(part)); + snprintf(pi->disk_path, strlen(disk_path) + 1, "%s", disk_path); + pi->part_no = blkid_partition_get_partno(part); + snprintf(pi->part_type, 36 + 1, "%s", blkid_partition_get_type_string(part)); - blkid_free_probe(probe); + blkid_free_probe(probe); - return 0; + return 0; } /* attempts to look up existing record, otherwise creates a new one. */ static boot_rec_t *bootvar_add_boot_rec(uint8_t *data, size_t len) { - char name[9]; /* variable name, e.g. "BootXXXX". */ - int slot; - uint32_t attr = EFI_VARIABLE_NON_VOLATILE - | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS; - boot_rec_t *c, - *res = bootvar_find_boot_rec(data, len); + char name[9]; /* variable name, e.g. "BootXXXX". */ + int slot; + uint32_t attr = EFI_VARIABLE_NON_VOLATILE + | EFI_VARIABLE_BOOTSERVICE_ACCESS + | EFI_VARIABLE_RUNTIME_ACCESS; + boot_rec_t *c, + *res = bootvar_find_boot_rec(data, len); - if (res) return res; - /* no such record, create one. */ - slot = bootvar_find_free_no(); - if (slot < 0) return NULL; - if (snprintf(name, 9, "Boot%04X", slot) > 8) return NULL; - if (efi_set_variable(EFI_GLOBAL_GUID, name, data, len, attr, 0644) < 0) return NULL; - /* re-read the records and find the variable that was just created. */ - if (bootvar_read_boot_recs() < 0) return NULL; - if (!boot_recs) return NULL; /* something went terribly wrong. */ - c = boot_recs; - do { - if (!strcmp(c->name, name)) { - res = c; - break; - } - } while ((c = c->next)); + if (res) return res; + /* no such record, create one. */ + slot = bootvar_find_free_no(); + if (slot < 0) return NULL; + if (snprintf(name, 9, "Boot%04X", slot) > 8) return NULL; + if (efi_set_variable(EFI_GLOBAL_GUID, name, data, len, attr, 0644) < 0) return NULL; + /* re-read the records and find the variable that was just created. */ + if (bootvar_read_boot_recs() < 0) return NULL; + if (!boot_recs) return NULL; /* something went terribly wrong. */ + c = boot_recs; + do { + if (!strcmp(c->name, name)) { + res = c; + break; + } + } while ((c = c->next)); - return res; + return res; } int bootvar_create(const char *esp_mount_path, const char *bootloader_esp_path, char *varname, size_t size) { - part_info_t pi; - uint8_t fdev_path[PATH_MAX]; - uint8_t data[BOOT_VAR_MAX]; /* this is what efivar supports and it should be - enough. */ - long int len; - boot_rec_t *rec; + part_info_t pi; + uint8_t fdev_path[PATH_MAX]; + uint8_t data[BOOT_VAR_MAX]; /* this is what efivar supports and it should be + enough. */ + long int len; + boot_rec_t *rec; - if (bootvar_get_part_info(esp_mount_path, &pi)) return -1; + if (bootvar_get_part_info(esp_mount_path, &pi)) return -1; - len = efi_generate_file_device_path_from_esp(fdev_path, PATH_MAX, - pi.disk_path, pi.part_no, bootloader_esp_path, EFIBOOT_ABBREV_HD); - if (len < 0) return -1; + len = efi_generate_file_device_path_from_esp(fdev_path, PATH_MAX, + pi.disk_path, pi.part_no, bootloader_esp_path, EFIBOOT_ABBREV_HD); + if (len < 0) return -1; - len = efi_loadopt_create(data, BOOT_VAR_MAX, LOAD_OPTION_ACTIVE, - (void *)fdev_path, len, (unsigned char *)"Linux bootloader", NULL, 0); - if (len < 0) return -1; + len = efi_loadopt_create(data, BOOT_VAR_MAX, LOAD_OPTION_ACTIVE, + (void *)fdev_path, len, (unsigned char *)"Linux bootloader", NULL, 0); + if (len < 0) return -1; - rec = bootvar_add_boot_rec(data, (size_t)len); - if (!rec) return -1; + rec = bootvar_add_boot_rec(data, (size_t)len); + if (!rec) return -1; - if (bootvar_push_to_boot_order(rec)) return -1; + if (bootvar_push_to_boot_order(rec)) return -1; - if (varname && size) { - size_t len = strlen(rec->name); - if (len < size) { - snprintf(varname, len + 1, "%s", rec->name); + if (varname && size) { + size_t len = strlen(rec->name); + if (len < size) snprintf(varname, len + 1, "%s", rec->name); } - } - return 0; + return 0; } int bootvar_init(void) { - if (efi_variables_supported() < 0) return -1; - if (bootvar_read_boot_recs() < 0) return -1; - return 0; + if (efi_variables_supported() < 0) return -1; + if (bootvar_read_boot_recs() < 0) return -1; + return 0; } void bootvar_destroy(void) { - bootvar_free_boot_recs(); + bootvar_free_boot_recs(); } -/* vim: set nosi noai cin ts=4 sw=4 et tw=80: */ +/* vim: set nosi noai cin ts=8 sw=8 et tw=80: */ diff --git a/src/lib/bootvar.h b/src/lib/bootvar.h index dd5300a..636e3f0 100644 --- a/src/lib/bootvar.h +++ b/src/lib/bootvar.h @@ -13,4 +13,4 @@ int bootvar_init(void); void bootvar_destroy(void); int bootvar_create(const char *, const char *, char *, size_t); -/* vim: set nosi noai cin ts=4 sw=4 et tw=80: */ +/* vim: set nosi noai cin ts=8 sw=8 et tw=80: */ From 400fee87cde9bf30396d23546b461373cfb7174f Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Tue, 29 Aug 2017 21:29:00 +0000 Subject: [PATCH 25/38] Add dependencies properly to the build system. --- Makefile.am | 25 ++++++++++++++++++++++++- configure.ac | 17 +++++++++++++++++ 2 files changed, 41 insertions(+), 1 deletion(-) diff --git a/Makefile.am b/Makefile.am index 19b3881..912ee5b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,7 +59,10 @@ AM_CFLAGS = -fstack-protector -Wall -pedantic \ -Wno-missing-field-initializers \ -std=c11 \ -DSYSCONFDIR=\"$(sysconfdir)\" \ - -D_POSIX_C_SOURCE=201112L + -D_POSIX_C_SOURCE=201112L \ + -isystem @efivar@ \ + -isystem @gnuefi@ \ + -isystem @gnuefi@/@host_cpu@ AM_CPPFLAGS = \ -I $(top_srcdir)/src \ @@ -155,6 +158,8 @@ clr_boot_manager_CFLAGS = \ clr_boot_manager_LDADD = \ libcbm.la \ src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ $(BLKID_LIBS) install-exec-hook: @@ -201,6 +206,8 @@ check_core_CFLAGS = \ check_core_LDADD = \ libcbm.la \ src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ $(BLKID_LIBS) \ $(CHECK_LIBS) @@ -215,6 +222,8 @@ check_cmdline_CFLAGS = \ check_cmdline_LDADD = \ libcbm.la \ src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ $(BLKID_LIBS) \ $(CHECK_LIBS) @@ -231,6 +240,8 @@ check_files_CFLAGS = \ check_files_LDADD = \ libcbm.la \ src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ $(BLKID_LIBS) \ $(CHECK_LIBS) @@ -249,6 +260,8 @@ check_legacy_CFLAGS = \ check_legacy_LDADD = \ libcbm.la \ src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ $(BLKID_LIBS) \ $(CHECK_LIBS) @@ -263,6 +276,8 @@ check_os_release_CFLAGS = \ check_os_release_LDADD = \ libcbm.la \ src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ $(BLKID_LIBS) \ $(CHECK_LIBS) @@ -281,6 +296,8 @@ check_uefi_CFLAGS = \ check_uefi_LDADD = \ libcbm.la \ src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ $(BLKID_LIBS) \ $(CHECK_LIBS) @@ -299,6 +316,8 @@ check_grub2_CFLAGS = \ check_grub2_LDADD = \ libcbm.la \ src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ $(BLKID_LIBS) \ $(CHECK_LIBS) @@ -317,6 +336,8 @@ check_select_bootloader_CFLAGS = \ check_select_bootloader_LDADD = \ libcbm.la \ src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ $(BLKID_LIBS) \ $(CHECK_LIBS) @@ -335,6 +356,8 @@ check_probe_CFLAGS = \ check_probe_LDADD = \ libcbm.la \ src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ $(BLKID_LIBS) \ $(CHECK_LIBS) diff --git a/configure.ac b/configure.ac index bb92e0d..fa6b721 100644 --- a/configure.ac +++ b/configure.ac @@ -2,6 +2,7 @@ AC_INIT([clr-boot-manager], 1.5.4, [michael.i.doherty@intel.com], [clr-boot-mana AM_INIT_AUTOMAKE([-Wno-portability no-dist-gzip dist-xz foreign subdir-objects]) AC_PROG_CC AC_PROG_CC_STDC +AC_CANONICAL_HOST AC_CONFIG_HEADERS([config.h]) AC_PREFIX_DEFAULT(/usr/local) AM_SILENT_RULES([yes]) @@ -63,6 +64,7 @@ fi if test x$bootloader = "xshim-systemd-boot"; then have_shim_systemdboot="yes" AC_DEFINE([HAVE_SHIM_SYSTEMD_BOOT], [1], [Using shim-systemd-boot]) + AC_DEFINE([HAVE_SYSTEMD_BOOT], [1], [Adding systemd-boot]) elif test x$bootloader = "xsystemd-boot"; then have_systemdboot="yes" AC_DEFINE([HAVE_SYSTEMD_BOOT], [1], [Using systemd-boot]) @@ -97,6 +99,19 @@ AC_SUBST(kernelmodulesdir) AC_DEFINE_UNQUOTED(KERNEL_MODULES_DIRECTORY, "$kernelmodulesdir", [The location of kernel modules in this OS configuration]) +AC_ARG_WITH([gnu-efi], AS_HELP_STRING([--with-gnu-efi], + [the location of gnu-efi headers]), [gnuefi=${withval}], + [gnuefi="/usr/include/efi"]) +AC_SUBST(gnuefi) + +dnl DO NOT use PKG_CHECK_MODULES for efivar: it's headers do not compile with +dnl -pendantic --std=c11 with standard -I. Instead capture the directory and use +dnl -isystem (to avoid enforcement of the standards). +AC_ARG_WITH([efivar], AS_HELP_STRING([--with-efivar], + [the location of efivar headers]), [efivar=${withval}], + [efivar="/usr/include/efivar"]) +AC_SUBST(efivar) + AC_ARG_WITH([kernel-namespace], AS_HELP_STRING([--with-kernel-namespace], [the kernel path namespace to use]), [kernelnamespace=${withval}], [kernelnamespace="org.clearlinux"]) @@ -176,6 +191,8 @@ AC_MSG_RESULT([ bootloader: ${bootloader} kernel-dir: ${kerneldir} kernel-modules-dir: ${kernelmodulesdir} + gnu-efi: ${gnuefi} + efivar: ${efivar} kernel-namespace: ${kernelnamespace} kernel-conf-dir: ${kernelconfdir} vendor-kernel-conf-dir: ${vendorkernelconfdir} From 6579daf395fefe64f4aad82c9113f1c062f94931 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Tue, 29 Aug 2017 21:43:33 +0000 Subject: [PATCH 26/38] Add packages to CI. --- .travis.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.travis.yml b/.travis.yml index 8e58d9a..ebe5317 100644 --- a/.travis.yml +++ b/.travis.yml @@ -31,6 +31,8 @@ addons: - lcov - llvm-3.8 - valgrind + - gnu-efi + - libefivar-dev before_install: From 827f24f2a068869a1ba8548ac2fa1495fc5229dc Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Wed, 30 Aug 2017 18:22:34 +0000 Subject: [PATCH 27/38] Use boot mount provided by bootman. Prefix source and destination for install/update using boot root returned by boot_manager_get_boot_dir() as opposed to BOOT_DIRECTORY. Both work, but boot_manager_get_boot_dir() allows for testing. --- src/bootloaders/shim-systemd.c | 13 ++++++++++--- 1 file changed, 10 insertions(+), 3 deletions(-) diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index a2283be..b6a7889 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -184,7 +184,8 @@ static bool shim_systemd_remove(const BootManager *manager) { static bool shim_systemd_init(const BootManager *manager) { size_t len; - char *prefix; + char *prefix, + *boot_root; if (bootvar_init()) return false; @@ -206,12 +207,16 @@ static bool shim_systemd_init(const BootManager *manager) { systemd_src = string_printf("%s/%s", prefix, SYSTEMD_SRC); /* SHIM_DST and SYSTEMD_DST are defined with leading '/' */ - shim_dst_host = BOOT_DIRECTORY SHIM_DST; - systemd_dst_host = BOOT_DIRECTORY SYSTEMD_DST; + boot_root = strdup(boot_manager_get_boot_dir((BootManager *)manager)); + len = strlen(boot_root); + if (len > 0 && boot_root[len-1] == '/') boot_root[len-1] = '\0'; + shim_dst_host = string_printf("%s%s", boot_root, SHIM_DST); + systemd_dst_host = string_printf("%s%s", boot_root, SYSTEMD_DST); shim_dst_esp = SHIM_DST; free(prefix); + free(boot_root); return true; } @@ -221,6 +226,8 @@ static void shim_systemd_destroy(const BootManager *manager) { free(shim_src); free(systemd_src); + free(shim_dst_host); + free(systemd_dst_host); bootvar_destroy(); return; From 49868238a77d1cdb36ef4085cd7b29b40ad69757 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Sat, 2 Sep 2017 07:11:42 +0000 Subject: [PATCH 28/38] Fix tests (and implementation). --- Makefile.am | 54 +++++++++++++++++++++++----------- src/bootloaders/shim-systemd.c | 20 +++++++------ src/bootman/kernel.c | 52 +++++++++++--------------------- src/lib/bootvar.h | 2 ++ tests/harness.c | 49 +++++++++++++++++++++++------- tests/stub/bootvar.c | 37 +++++++++++++++++++++++ 6 files changed, 143 insertions(+), 71 deletions(-) create mode 100644 tests/stub/bootvar.c diff --git a/Makefile.am b/Makefile.am index 912ee5b..981baa5 100644 --- a/Makefile.am +++ b/Makefile.am @@ -59,10 +59,7 @@ AM_CFLAGS = -fstack-protector -Wall -pedantic \ -Wno-missing-field-initializers \ -std=c11 \ -DSYSCONFDIR=\"$(sysconfdir)\" \ - -D_POSIX_C_SOURCE=201112L \ - -isystem @efivar@ \ - -isystem @gnuefi@ \ - -isystem @gnuefi@/@host_cpu@ + -D_POSIX_C_SOURCE=201112L AM_CPPFLAGS = \ -I $(top_srcdir)/src \ @@ -70,8 +67,10 @@ AM_CPPFLAGS = \ -I $(top_srcdir)/src/cli \ -I $(top_srcdir)/src/bootloaders \ -I $(top_srcdir)/src/lib \ - -I $(top_srcdir)/src/efi \ -I $(top_srcdir)/src/libnica/src/include \ + -isystem @efivar@ \ + -isystem @gnuefi@ \ + -isystem @gnuefi@/@host_cpu@ \ -DTOP_DIR=\"$(abs_top_srcdir)\" \ -DTOP_BUILD_DIR=\"$(abs_top_builddir)\" @@ -94,7 +93,7 @@ noinst_LTLIBRARIES = \ bin_PROGRAMS = clr-boot-manager -libcbm_la_SOURCES = \ +SOURCE_FILES = \ src/bootloaders/bootloader.h \ src/bootloaders/systemd-class.h \ src/bootloaders/systemd-class.c \ @@ -129,9 +128,18 @@ libcbm_la_SOURCES = \ src/lib/writer.c \ src/lib/util.h \ src/lib/util.c \ - src/lib/bootvar.c \ src/lib/bootvar.h +PROD_SOURCE_FILES = \ + src/lib/bootvar.c + +STUB_SOURCE_FILES = \ + tests/stub/bootvar.c + +libcbm_la_SOURCES = \ + $(SOURCE_FILES) \ + $(PROD_SOURCE_FILES) + libcbm_la_CFLAGS = \ -D_BOOTMAN_INTERNAL_ \ $(BLKID_CFLAGS) \ @@ -191,6 +199,19 @@ TESTS = \ check_PROGRAMS = $(TESTS) +check_LTLIBRARIES = libcbm-check.la + +libcbm_check_la_SOURCES = \ + $(SOURCE_FILES) \ + $(STUB_SOURCE_FILES) + +libcbm_check_la_CFLAGS = \ + $(libcbm_la_CFLAGS) \ + -DTEST_STUB=1 + +libcbm_check_la_LIBADD = $(libcbm_la_LIBADD) + + check_core_SOURCES = \ tests/check-core.c \ tests/blkid-harness.h \ @@ -204,7 +225,7 @@ check_core_CFLAGS = \ $(AM_CFLAGS) check_core_LDADD = \ - libcbm.la \ + libcbm-check.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -220,7 +241,7 @@ check_cmdline_CFLAGS = \ $(AM_CFLAGS) check_cmdline_LDADD = \ - libcbm.la \ + libcbm-check.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -238,7 +259,7 @@ check_files_CFLAGS = \ $(AM_CFLAGS) check_files_LDADD = \ - libcbm.la \ + libcbm-check.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -258,7 +279,7 @@ check_legacy_CFLAGS = \ $(AM_CFLAGS) check_legacy_LDADD = \ - libcbm.la \ + libcbm-check.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -274,7 +295,7 @@ check_os_release_CFLAGS = \ $(AM_CFLAGS) check_os_release_LDADD = \ - libcbm.la \ + libcbm-check.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -294,7 +315,7 @@ check_uefi_CFLAGS = \ $(AM_CFLAGS) check_uefi_LDADD = \ - libcbm.la \ + libcbm-check.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -314,7 +335,7 @@ check_grub2_CFLAGS = \ $(AM_CFLAGS) check_grub2_LDADD = \ - libcbm.la \ + libcbm-check.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -334,7 +355,7 @@ check_select_bootloader_CFLAGS = \ $(AM_CFLAGS) check_select_bootloader_LDADD = \ - libcbm.la \ + libcbm-check.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -354,7 +375,7 @@ check_probe_CFLAGS = \ $(AM_CFLAGS) check_probe_LDADD = \ - libcbm.la \ + libcbm-check.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -364,6 +385,5 @@ check_probe_LDADD = \ @VALGRIND_CHECK_RULES@ - VALGRIND_SUPPRESSIONS_FILES = \ ${abs_top_srcdir}/sgcheck.suppressions diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index b6a7889..39fa84e 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -119,10 +119,7 @@ static bool shim_systemd_install_kernel(const BootManager *manager, const Kernel } static bool shim_systemd_remove_kernel(const BootManager *manager, const Kernel *kernel) { - (void)manager; - (void)kernel; - fprintf(stderr, "%s is not implemented\n", __func__); - return true; + return sd_class_remove_kernel(manager, kernel); } static bool shim_systemd_set_default_kernel(const BootManager *manager, const Kernel *kernel) { @@ -151,10 +148,15 @@ static bool shim_systemd_needs_update(const BootManager *manager) { return false; } -static bool make_layout(void) { - if (!nc_mkdir_p(BOOT_DIRECTORY DST_DIR, 00755)) return false; - if (!nc_mkdir_p(BOOT_DIRECTORY KERNEL_DST_DIR, 00755)) return false; - if (!nc_mkdir_p(BOOT_DIRECTORY SYSTEMD_ENTRIES, 00755)) return false; +static bool make_layout(const BootManager *manager) { + char *boot_root = boot_manager_get_boot_dir((BootManager *)manager); + char path[PATH_MAX]; + snprintf(path, PATH_MAX, "%s%s", boot_root, DST_DIR); + if (!nc_mkdir_p(path, 00755)) return false; + snprintf(path, PATH_MAX, "%s%s", boot_root, KERNEL_DST_DIR); + if (!nc_mkdir_p(path, 00755)) return false; + snprintf(path, PATH_MAX, "%s%s", boot_root, SYSTEMD_ENTRIES); + if (!nc_mkdir_p(path, 00755)) return false; return true; } @@ -162,7 +164,7 @@ static bool shim_systemd_install(const BootManager *manager) { char varname[9]; (void)manager; - if (!make_layout()) return false; + if (!make_layout(manager)) return false; if (!copy_file_atomic(shim_src, shim_dst_host, 00644)) return false; if (!copy_file_atomic(systemd_src, systemd_dst_host, 00644)) return false; diff --git a/src/bootman/kernel.c b/src/bootman/kernel.c index c69c974..709c97f 100644 --- a/src/bootman/kernel.c +++ b/src/bootman/kernel.c @@ -604,19 +604,12 @@ bool boot_manager_install_kernel_internal(const BootManager *manager, const Kern base_path = boot_manager_get_boot_dir((BootManager *)manager); OOM_CHECK_RET(base_path, false); - /* For UEFI kernels we namespace into /EFI/$NEEDLE, i.e. /EFI/org.clearlinux */ - if (is_uefi) { - /* Ensure namespace directory exists */ - if (!nc_mkdir_p(efi_boot_dir, 00755)) { - LOG_FATAL("Failed to create namespace directory: %s %s", - efi_boot_dir, - strerror(errno)); - return false; - } - kfile_target = string_printf(BOOT_DIRECTORY "%s/%s", efi_boot_dir, kernel->target.path); - } else { - kfile_target = string_printf("%s/%s", base_path, kernel->target.legacy_path); - } + /* for UEFI, the kernel location is prefixed with efi_boot_dir which is + * guaranteed to start with '/' since it's its absolute path on ESP. */ + kfile_target = string_printf("%s%s/%s", + base_path, + (is_uefi ? efi_boot_dir : ""), + (is_uefi ? kernel->target.path : kernel->target.legacy_path)); /* Now copy the kernel file to it's new location */ if (!cbm_files_match(kernel->source.path, kfile_target)) { @@ -636,11 +629,7 @@ bool boot_manager_install_kernel_internal(const BootManager *manager, const Kern return true; } - if (is_uefi) { - initrd_target = string_printf(BOOT_DIRECTORY "%s/%s", efi_boot_dir, kernel->target.initrd_path); - } else { - initrd_target = string_printf("%s/%s", base_path, kernel->target.initrd_path); - } + initrd_target = string_printf("%s%s/%s", base_path, (is_uefi ? efi_boot_dir : ""), kernel->target.initrd_path); if (!cbm_files_match(initrd_source, initrd_target)) { if (!copy_file_atomic(initrd_source, initrd_target, 00644)) { @@ -671,34 +660,27 @@ bool boot_manager_remove_kernel_internal(const BootManager *manager, const Kerne autofree(char) *kfile_target = NULL; autofree(char) *base_path = NULL; autofree(char) *initrd_target = NULL; - bool is_uefi = false; - autofree(char) *efi_boot_dir = NULL; + int is_uefi = (manager->bootloader->get_capabilities(manager) & BOOTLOADER_CAP_UEFI); + autofree(char) *efi_boot_dir = is_uefi ? manager->bootloader->get_kernel_dst(manager) : NULL; assert(manager != NULL); assert(kernel != NULL); + /* if it's UEFI, then bootloader->get_kernel_dst() must return a value. */ + if (is_uefi && !efi_boot_dir) return false; + /* Boot path */ base_path = boot_manager_get_boot_dir((BootManager *)manager); OOM_CHECK_RET(base_path, false); - /* Determine if UEFI is in use */ - if ((manager->bootloader->get_capabilities(manager) & BOOTLOADER_CAP_UEFI) == - BOOTLOADER_CAP_UEFI) { - is_uefi = true; - efi_boot_dir = nc_build_case_correct_path(base_path, "EFI", KERNEL_NAMESPACE, NULL); - } - /* Remove old blobs */ - if (is_uefi) { - kfile_target = string_printf("%s/%s", efi_boot_dir, kernel->target.path); - } else { - kfile_target = string_printf("%s/%s", base_path, kernel->target.legacy_path); - } + kfile_target = string_printf("%s%s/%s", + base_path, + (is_uefi ? efi_boot_dir : ""), + (is_uefi ? kernel->target.path : kernel->target.legacy_path)); if (kernel->source.initrd_file) { - initrd_target = string_printf("%s/%s", - is_uefi ? efi_boot_dir : base_path, - kernel->target.initrd_path); + initrd_target = string_printf("%s%s/%s", base_path, (is_uefi ? efi_boot_dir : ""), kernel->target.initrd_path); } /* Remove the kernel from the ESP */ diff --git a/src/lib/bootvar.h b/src/lib/bootvar.h index 636e3f0..6df8ea7 100644 --- a/src/lib/bootvar.h +++ b/src/lib/bootvar.h @@ -9,6 +9,8 @@ * of the License, or (at your option) any later version. */ +#include + int bootvar_init(void); void bootvar_destroy(void); int bootvar_create(const char *, const char *, char *, size_t); diff --git a/tests/harness.c b/tests/harness.c index 8321814..f4d1fef 100644 --- a/tests/harness.c +++ b/tests/harness.c @@ -14,6 +14,7 @@ #include #include #include +#include #include #include #include @@ -59,15 +60,20 @@ */ /** - * Systemd support + * Systemd support, including shim-systemd two-stage */ #if defined(HAVE_SYSTEMD_BOOT) -#define ESP_BOOT_DIR EFI_START "/systemd" -#define ESP_BOOT_STUB ESP_BOOT_DIR "/systemd-boot" EFI_STUB_SUFFIX_L - -#define BOOT_COPY_TARGET PLAYGROUND_ROOT "/usr/lib/systemd/boot/efi/systemd-boot" EFI_STUB_SUFFIX_L -#define BOOT_COPY_DIR PLAYGROUND_ROOT "/usr/lib/systemd/boot/efi" +# if defined(HAVE_SHIM_SYSTEMD_BOOT) +# define ESP_BOOT_DIR BOOT_FULL "/" KERNEL_NAMESPACE +# define ESP_BOOT_STUB ESP_BOOT_DIR "/bootloader" EFI_STUB_SUFFIX_L +# define SHIM_BOOT_COPY_DIR PLAYGROUND_ROOT "/usr/lib/shim" +# else +# define ESP_BOOT_DIR EFI_START "/systemd" +# define ESP_BOOT_STUB ESP_BOOT_DIR "/systemd-boot" EFI_STUB_SUFFIX_L +# endif /* HAVE_SHIM_SYSTEMD_BOOT */ +# define BOOT_COPY_TARGET PLAYGROUND_ROOT "/usr/lib/systemd/boot/efi/systemd-boot" EFI_STUB_SUFFIX_L +# define BOOT_COPY_DIR PLAYGROUND_ROOT "/usr/lib/systemd/boot/efi" /** * gummiboot support */ @@ -126,17 +132,21 @@ static void push_syslinux(void) void confirm_bootloader(void) { +#if !defined(HAVE_SHIM_SYSTEMD_BOOT) fail_if(!noisy_file_exists(EFI_STUB_MAIN), "Main EFI stub missing"); +#endif fail_if(!noisy_file_exists(ESP_BOOT_DIR), "ESP target directory missing"); fail_if(!noisy_file_exists(ESP_BOOT_STUB), "ESP target stub missing"); } bool confirm_bootloader_match(void) { +#if !defined(HAVE_SHIM_SYSTEMD_BOOT) if (!cbm_files_match(BOOT_COPY_TARGET, EFI_STUB_MAIN)) { fprintf(stderr, "EFI_STUB_MAIN doesn't match the source\n"); return false; } +#endif /* !HAVE_SHIM_SYSTEMD_BOOT */ if (!cbm_files_match(BOOT_COPY_TARGET, ESP_BOOT_STUB)) { fprintf(stderr, "ESP_BOOT_STUB(vendor) doesn't match the source\n"); return false; @@ -322,6 +332,23 @@ bool push_bootloader_update(int revision) fprintf(stderr, "Failed to update bootloader: %s\n", strerror(errno)); return false; } +#if defined(HAVE_SHIM_SYSTEMD_BOOT) + { + int i; + char path[PATH_MAX]; + char *files[3] = { + "fb", + "mm", + "shim" + }; + if (!nc_file_exists(SHIM_BOOT_COPY_DIR) + && !nc_mkdir_p(SHIM_BOOT_COPY_DIR, 0755)) return false; + for (i = 0; i < 3; i++) { + snprintf(path, PATH_MAX, "%s/%s" EFI_STUB_SUFFIX_L, SHIM_BOOT_COPY_DIR, files[i]); + if (!file_set_text(path, text)) return false; + } + } +#endif /* HAVE_SHIM_SYSTEMD_BOOT */ return true; } @@ -449,14 +476,16 @@ int kernel_installed_files_count(BootManager *manager, PlaygroundKernel *kernel) autofree(char) *kernel_blob_legacy = NULL; autofree(char) *initrd_file = NULL; autofree(char) *initrd_file_legacy = NULL; + /* where the kernel files are expected to be found on the ESP */ + char *esp_path = manager->bootloader->get_kernel_dst ? manager->bootloader->get_kernel_dst(manager) : "efi/" KERNEL_NAMESPACE; const char *vendor = NULL; int file_count = 0; vendor = boot_manager_get_vendor_prefix(manager); - kernel_blob = string_printf("%s/efi/%s/kernel-%s.%s.%s-%d", + kernel_blob = string_printf("%s/%s/kernel-%s.%s.%s-%d", BOOT_FULL, - KERNEL_NAMESPACE, + esp_path, KERNEL_NAMESPACE, kernel->ktype, kernel->version, @@ -470,9 +499,9 @@ int kernel_installed_files_count(BootManager *manager, PlaygroundKernel *kernel) kernel->version, kernel->release); - initrd_file = string_printf("%s/efi/%s/initrd-%s.%s.%s-%d", + initrd_file = string_printf("%s/%s/initrd-%s.%s.%s-%d", BOOT_FULL, - KERNEL_NAMESPACE, + esp_path, KERNEL_NAMESPACE, kernel->ktype, kernel->version, diff --git a/tests/stub/bootvar.c b/tests/stub/bootvar.c new file mode 100644 index 0000000..800daa2 --- /dev/null +++ b/tests/stub/bootvar.c @@ -0,0 +1,37 @@ +/* + * This file is part of clr-boot-manager. + * + * Copyright © 2017 Intel Corporation + * + * 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. + */ + +/* This file is a stub implementing happy src/lib/bootvar.h API. */ + +#include +#include +#include +#include +#include + +int bootvar_init(void) { + return 0; +} +void bootvar_destroy(void) { + return; +} + +int bootvar_create(const char *mnt_path, const char *bootloader_path, + char *name, size_t sz) { + (void)mnt_path; + (void)bootloader_path; + static char *stub_name = "Boot0001"; + static size_t len = 8; // strlen(stub_name) + if (name && sz > len) { + snprintf(name, len + 1, "%s", stub_name); + } + return 0; +} From d84282681926d5458e714a77b256eb8db66987ef Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Sun, 3 Sep 2017 23:58:45 +0000 Subject: [PATCH 29/38] Remove automated format check. --- .travis.yml | 2 -- 1 file changed, 2 deletions(-) diff --git a/.travis.yml b/.travis.yml index ebe5317..6b0883e 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,8 +42,6 @@ script: - lcov --version | grep "1.10" - export CC="gcc-5" - ./configure --enable-coverage && make && make check && make distcheck && make check-valgrind - - clang-format-3.8 -i $(find . -name '*.[ch]') && git diff --exit-code - after_success: - cd ${TRAVIS_BUILD_DIR} From d1f96a4bbdf322b6a756dd711bc41d99a6dc7051 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Wed, 6 Sep 2017 17:30:01 +0000 Subject: [PATCH 30/38] Re-enable nice automated formatting. --- .travis.yml | 1 + src/bootloaders/bootloader.h | 7 +- src/bootloaders/grub2.c | 31 +++-- src/bootloaders/shim-systemd.c | 184 ++++++++++++++++++------------ src/bootloaders/syslinux.c | 32 +++--- src/bootloaders/systemd-class.c | 20 ++-- src/bootloaders/systemd-class.h | 6 +- src/bootman/kernel.c | 34 ++++-- src/lib/bootvar.c | 194 +++++++++++++++++++++----------- tests/harness.c | 43 +++---- tests/stub/bootvar.c | 12 +- 11 files changed, 344 insertions(+), 220 deletions(-) diff --git a/.travis.yml b/.travis.yml index 6b0883e..35da5a9 100644 --- a/.travis.yml +++ b/.travis.yml @@ -48,3 +48,4 @@ after_success: - lcov --compat-libtool --directory . --capture --output-file coverage.info - lcov --remove coverage.info 'tests/*' '/usr/*' --output-file coverage.info - coveralls-lcov coverage.info + - clang-format-3.8 -i $(find . -name '*.[ch]') && git diff --exit-code diff --git a/src/bootloaders/bootloader.h b/src/bootloaders/bootloader.h index 661b081..bf92a2b 100644 --- a/src/bootloaders/bootloader.h +++ b/src/bootloaders/bootloader.h @@ -44,9 +44,10 @@ typedef enum { * Virtual BootLoader provider */ typedef struct BootLoader { - const char *name; /** 0 && prefix[len-1] == '/') prefix[len-1] = '\0'; + if (len > 0 && prefix[len - 1] == '/') + prefix[len - 1] = '\0'; shim_src = string_printf("%s/%s", prefix, SHIM_SRC); systemd_src = string_printf("%s/%s", prefix, SYSTEMD_SRC); /* SHIM_DST and SYSTEMD_DST are defined with leading '/' */ boot_root = strdup(boot_manager_get_boot_dir((BootManager *)manager)); len = strlen(boot_root); - if (len > 0 && boot_root[len-1] == '/') boot_root[len-1] = '\0'; + if (len > 0 && boot_root[len - 1] == '/') + boot_root[len - 1] = '\0'; shim_dst_host = string_printf("%s%s", boot_root, SHIM_DST); systemd_dst_host = string_printf("%s%s", boot_root, SYSTEMD_DST); @@ -223,7 +265,8 @@ static bool shim_systemd_init(const BootManager *manager) { return true; } -static void shim_systemd_destroy(const BootManager *manager) { +static void shim_systemd_destroy(const BootManager *manager) +{ (void)manager; free(shim_src); @@ -235,7 +278,8 @@ static void shim_systemd_destroy(const BootManager *manager) { return; } -static int shim_systemd_get_capabilities(const BootManager *manager) { +static int shim_systemd_get_capabilities(const BootManager *manager) +{ (void)manager; return BOOTLOADER_CAP_GPT | BOOTLOADER_CAP_UEFI; } diff --git a/src/bootloaders/syslinux.c b/src/bootloaders/syslinux.c index 09a9637..89f2d43 100644 --- a/src/bootloaders/syslinux.c +++ b/src/bootloaders/syslinux.c @@ -272,23 +272,21 @@ static int syslinux_get_capabilities(__cbm_unused__ const BootManager *manager) return BOOTLOADER_CAP_GPT | BOOTLOADER_CAP_LEGACY; } -__cbm_export__ const BootLoader syslinux_bootloader = { - .name = "syslinux", - .init = syslinux_init, - .get_kernel_dst = NULL, /* kernel dir only needed for EFI-enable - bootloaders */ - .install_kernel = syslinux_install_kernel, - .remove_kernel = syslinux_remove_kernel, - .set_default_kernel = syslinux_set_default_kernel, - .needs_install = syslinux_needs_install, - .needs_update = syslinux_needs_update, - .install = syslinux_install, - .update = syslinux_update, - .remove = syslinux_remove, - .destroy = syslinux_destroy, - .get_capabilities = - syslinux_get_capabilities -}; +__cbm_export__ const BootLoader + syslinux_bootloader = {.name = "syslinux", + .init = syslinux_init, + .get_kernel_dst = NULL, /* kernel dir only needed for EFI-enable + bootloaders */ + .install_kernel = syslinux_install_kernel, + .remove_kernel = syslinux_remove_kernel, + .set_default_kernel = syslinux_set_default_kernel, + .needs_install = syslinux_needs_install, + .needs_update = syslinux_needs_update, + .install = syslinux_install, + .update = syslinux_update, + .remove = syslinux_remove, + .destroy = syslinux_destroy, + .get_capabilities = syslinux_get_capabilities }; /* * Editor modelines - https://www.wireshark.org/tools/modelines.html diff --git a/src/bootloaders/systemd-class.c b/src/bootloaders/systemd-class.c index b5efa62..51c6fb4 100644 --- a/src/bootloaders/systemd-class.c +++ b/src/bootloaders/systemd-class.c @@ -184,8 +184,8 @@ char *sd_class_get_kernel_dst(const BootManager *manager) } bool sd_class_install_kernel_impl(const BootManager *manager, const Kernel *kernel, - char *(*get_kernel_dst)(const BootManager *), - bool (*ensure_layout)(const BootManager *)) + char *(*get_kernel_dst)(const BootManager *), + bool (*ensure_layout)(const BootManager *)) { if (!manager || !kernel) { return false; @@ -270,9 +270,12 @@ bool sd_class_install_kernel_impl(const BootManager *manager, const Kernel *kern return true; } -bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel) { - return sd_class_install_kernel_impl(manager, kernel, - sd_class_get_kernel_dst, sd_class_ensure_dirs); +bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel) +{ + return sd_class_install_kernel_impl(manager, + kernel, + sd_class_get_kernel_dst, + sd_class_ensure_dirs); } bool sd_class_remove_kernel(const BootManager *manager, const Kernel *kernel) @@ -301,7 +304,7 @@ bool sd_class_remove_kernel(const BootManager *manager, const Kernel *kernel) } bool sd_class_set_default_kernel_impl(const BootManager *manager, const Kernel *kernel, - bool (*ensure_layout)(const BootManager *)) + bool (*ensure_layout)(const BootManager *)) { if (!manager) { return false; @@ -367,8 +370,9 @@ write_config: return true; } -bool sd_class_set_default_kernel(const BootManager *manager, const Kernel *kernel) { - return sd_class_set_default_kernel_impl(manager, kernel, sd_class_ensure_dirs); +bool sd_class_set_default_kernel(const BootManager *manager, const Kernel *kernel) +{ + return sd_class_set_default_kernel_impl(manager, kernel, sd_class_ensure_dirs); } bool sd_class_needs_install(const BootManager *manager) diff --git a/src/bootloaders/systemd-class.h b/src/bootloaders/systemd-class.h index 5003039..1d90035 100644 --- a/src/bootloaders/systemd-class.h +++ b/src/bootloaders/systemd-class.h @@ -34,15 +34,15 @@ char *sd_class_get_kernel_dst(const BootManager *manager); bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel); bool sd_class_install_kernel_impl(const BootManager *manager, const Kernel *kernel, - char *(*get_kernel_dst)(const BootManager *), - bool (*ensure_layout)(const BootManager *)); + char *(*get_kernel_dst)(const BootManager *), + bool (*ensure_layout)(const BootManager *)); bool sd_class_remove_kernel(const BootManager *manager, const Kernel *kernel); bool sd_class_set_default_kernel(const BootManager *manager, const Kernel *kernel); bool sd_class_set_default_kernel_impl(const BootManager *manager, const Kernel *kernel, - bool (*ensure_layout)(const BootManager *)); + bool (*ensure_layout)(const BootManager *)); bool sd_class_needs_install(const BootManager *manager); diff --git a/src/bootman/kernel.c b/src/bootman/kernel.c index 709c97f..3c416c4 100644 --- a/src/bootman/kernel.c +++ b/src/bootman/kernel.c @@ -593,12 +593,14 @@ bool boot_manager_install_kernel_internal(const BootManager *manager, const Kern autofree(char) *initrd_target = NULL; const char *initrd_source = NULL; int is_uefi = (manager->bootloader->get_capabilities(manager) & BOOTLOADER_CAP_UEFI); - autofree(char) *efi_boot_dir = is_uefi ? manager->bootloader->get_kernel_dst(manager) : NULL; + autofree(char) *efi_boot_dir = + is_uefi ? manager->bootloader->get_kernel_dst(manager) : NULL; assert(manager != NULL); assert(kernel != NULL); - if (is_uefi && !efi_boot_dir) return false; + if (is_uefi && !efi_boot_dir) + return false; /* Boot path */ base_path = boot_manager_get_boot_dir((BootManager *)manager); @@ -607,9 +609,9 @@ bool boot_manager_install_kernel_internal(const BootManager *manager, const Kern /* for UEFI, the kernel location is prefixed with efi_boot_dir which is * guaranteed to start with '/' since it's its absolute path on ESP. */ kfile_target = string_printf("%s%s/%s", - base_path, - (is_uefi ? efi_boot_dir : ""), - (is_uefi ? kernel->target.path : kernel->target.legacy_path)); + base_path, + (is_uefi ? efi_boot_dir : ""), + (is_uefi ? kernel->target.path : kernel->target.legacy_path)); /* Now copy the kernel file to it's new location */ if (!cbm_files_match(kernel->source.path, kfile_target)) { @@ -629,7 +631,10 @@ bool boot_manager_install_kernel_internal(const BootManager *manager, const Kern return true; } - initrd_target = string_printf("%s%s/%s", base_path, (is_uefi ? efi_boot_dir : ""), kernel->target.initrd_path); + initrd_target = string_printf("%s%s/%s", + base_path, + (is_uefi ? efi_boot_dir : ""), + kernel->target.initrd_path); if (!cbm_files_match(initrd_source, initrd_target)) { if (!copy_file_atomic(initrd_source, initrd_target, 00644)) { @@ -661,13 +666,15 @@ bool boot_manager_remove_kernel_internal(const BootManager *manager, const Kerne autofree(char) *base_path = NULL; autofree(char) *initrd_target = NULL; int is_uefi = (manager->bootloader->get_capabilities(manager) & BOOTLOADER_CAP_UEFI); - autofree(char) *efi_boot_dir = is_uefi ? manager->bootloader->get_kernel_dst(manager) : NULL; + autofree(char) *efi_boot_dir = + is_uefi ? manager->bootloader->get_kernel_dst(manager) : NULL; assert(manager != NULL); assert(kernel != NULL); /* if it's UEFI, then bootloader->get_kernel_dst() must return a value. */ - if (is_uefi && !efi_boot_dir) return false; + if (is_uefi && !efi_boot_dir) + return false; /* Boot path */ base_path = boot_manager_get_boot_dir((BootManager *)manager); @@ -675,12 +682,15 @@ bool boot_manager_remove_kernel_internal(const BootManager *manager, const Kerne /* Remove old blobs */ kfile_target = string_printf("%s%s/%s", - base_path, - (is_uefi ? efi_boot_dir : ""), - (is_uefi ? kernel->target.path : kernel->target.legacy_path)); + base_path, + (is_uefi ? efi_boot_dir : ""), + (is_uefi ? kernel->target.path : kernel->target.legacy_path)); if (kernel->source.initrd_file) { - initrd_target = string_printf("%s%s/%s", base_path, (is_uefi ? efi_boot_dir : ""), kernel->target.initrd_path); + initrd_target = string_printf("%s%s/%s", + base_path, + (is_uefi ? efi_boot_dir : ""), + kernel->target.initrd_path); } /* Remove the kernel from the ESP */ diff --git a/src/lib/bootvar.c b/src/lib/bootvar.c index ff022da..9c8a7b8 100644 --- a/src/lib/bootvar.c +++ b/src/lib/bootvar.c @@ -14,15 +14,15 @@ #include /* Workaround for using --std=c11 in CBM. Provide "relaxed" defines which efivar * expects. */ -#define BYTE_ORDER __BYTE_ORDER -#define LITTLE_ENDIAN __LITTLE_ENDIAN -#define BIG_ENDIAN __BIG_ENDIAN +#define BYTE_ORDER __BYTE_ORDER +#define LITTLE_ENDIAN __LITTLE_ENDIAN +#define BIG_ENDIAN __BIG_ENDIAN #include #include #include -#include #include +#include #include #include #include @@ -32,7 +32,7 @@ /* 1K is the limit for boot var storage that efivar defines. it should be * enough. actual space occupied is normally >2 times less. */ -#define BOOT_VAR_MAX 1024 +#define BOOT_VAR_MAX 1024 typedef struct boot_rec boot_rec_t; @@ -46,10 +46,12 @@ struct boot_rec { static boot_rec_t *boot_recs; static int boot_recs_cnt; -static void bootvar_free_boot_recs(void) { +static void bootvar_free_boot_recs(void) +{ boot_rec_t *p, *c; c = boot_recs; - if (!c) return; + if (!c) + return; boot_recs = NULL; do { p = c; @@ -59,37 +61,43 @@ static void bootvar_free_boot_recs(void) { } static void bootvar_print_boot_recs(void) __attribute__((unused)); -static void bootvar_print_boot_recs(void) { +static void bootvar_print_boot_recs(void) +{ boot_rec_t *c = boot_recs; - if (!c) return; + if (!c) + return; do { fprintf(stderr, "Boot record #%d: %s\n", c->num, c->name); } while ((c = c->next)); } /* enumerates boot recs and initializes boot_recs and boot_recs_cnt. */ -static int bootvar_read_boot_recs(void) { +static int bootvar_read_boot_recs(void) +{ int res; efi_guid_t *guid = NULL; char *name = NULL; - boot_rec_t *p = NULL, - *c; + boot_rec_t *p = NULL, *c; int i = 0; bootvar_free_boot_recs(); while ((res = efi_get_next_variable_name(&guid, &name)) > 0) { char *num_end; - if (strncmp(name, "Boot", 4)) continue; - if (!isxdigit(name[4]) || !isxdigit(name[5]) || !isxdigit(name[6]) - || !isxdigit(name[7])) continue; - if (memcmp(guid, &efi_guid_global, sizeof(efi_guid_t))) continue; + if (strncmp(name, "Boot", 4)) + continue; + if (!isxdigit(name[4]) || !isxdigit(name[5]) || !isxdigit(name[6]) || + !isxdigit(name[7])) + continue; + if (memcmp(guid, &efi_guid_global, sizeof(efi_guid_t))) + continue; c = (boot_rec_t *)malloc(sizeof(boot_rec_t)); memset(c, 0, sizeof(boot_rec_t)); c->name = strdup(name); c->num = (int)strtol(name + 4, &num_end, 16); - if (num_end - name - 4 != 4) continue; + if (num_end - name - 4 != 4) + continue; if (!boot_recs) { boot_recs = p = c; @@ -105,7 +113,8 @@ static int bootvar_read_boot_recs(void) { /* given the record, puts it first in the boot order (via BootOrder EFI * variable). */ -static int bootvar_push_to_boot_order(boot_rec_t *rec) { +static int bootvar_push_to_boot_order(boot_rec_t *rec) +{ uint16_t number; uint16_t *boot_order; uint16_t *new_boot_order; @@ -115,9 +124,15 @@ static int bootvar_push_to_boot_order(boot_rec_t *rec) { unsigned int i; int found = 0; - if (!rec || !rec->name) return -1; + if (!rec || !rec->name) + return -1; - if (efi_get_variable(EFI_GLOBAL_GUID, "BootOrder", (uint8_t **)&boot_order, &boot_order_size, &boot_order_attrs)) return -1; + if (efi_get_variable(EFI_GLOBAL_GUID, + "BootOrder", + (uint8_t **)&boot_order, + &boot_order_size, + &boot_order_attrs)) + return -1; sscanf(rec->name, "Boot%04hX", &number); @@ -151,29 +166,39 @@ static int bootvar_push_to_boot_order(boot_rec_t *rec) { } new_boot_order_size <<= 1; - if (efi_set_variable(EFI_GLOBAL_GUID, "BootOrder", (uint8_t *)new_boot_order, new_boot_order_size, boot_order_attrs, 0644)) return -1; + if (efi_set_variable(EFI_GLOBAL_GUID, + "BootOrder", + (uint8_t *)new_boot_order, + new_boot_order_size, + boot_order_attrs, + 0644)) + return -1; return 0; } -static int cmp(const void *a, const void *b) { +static int cmp(const void *a, const void *b) +{ return *((int *)a) - *((int *)b); } /* finds the first available free number for a boot var. */ -static int bootvar_find_free_no(void) { +static int bootvar_find_free_no(void) +{ int *nums; int res; int i = 0; boot_rec_t *c = boot_recs; size_t cnt; - if (!boot_recs) return -1; - if (!boot_recs_cnt) return 0; /* no records. */ + if (!boot_recs) + return -1; + if (!boot_recs_cnt) + return 0; /* no records. */ cnt = (size_t)boot_recs_cnt; - nums = (int *)alloca(sizeof(int) * cnt); + nums = (int *)alloca(sizeof(int) * cnt); memset(nums, 0, sizeof(int) * cnt); do { @@ -184,14 +209,17 @@ static int bootvar_find_free_no(void) { qsort(nums, cnt, sizeof(int), cmp); for (i = 0, res = 0; i < boot_recs_cnt; i++, res++) { - if (res < nums[i]) break; + if (res < nums[i]) + break; } - if (res == nums[boot_recs_cnt - 1]) res++; /* no gap. */ + if (res == nums[boot_recs_cnt - 1]) + res++; /* no gap. */ return res; } /* finds and returns boot rec whose value is data of size. NULL if not found. */ -static boot_rec_t *bootvar_find_boot_rec(uint8_t *data, size_t size) { +static boot_rec_t *bootvar_find_boot_rec(uint8_t *data, size_t size) +{ boot_rec_t *c = boot_recs; boot_rec_t *res = NULL; @@ -199,10 +227,12 @@ static boot_rec_t *bootvar_find_boot_rec(uint8_t *data, size_t size) { size_t csize; uint32_t cattr; - if (!boot_recs || !boot_recs_cnt) return NULL; + if (!boot_recs || !boot_recs_cnt) + return NULL; do { - if (efi_get_variable(EFI_GLOBAL_GUID, c->name, &cdata, &csize, &cattr) < 0) continue; + if (efi_get_variable(EFI_GLOBAL_GUID, c->name, &cdata, &csize, &cattr) < 0) + continue; if (csize == size && !memcmp(cdata, data, csize)) { res = c; break; @@ -215,12 +245,13 @@ static boot_rec_t *bootvar_find_boot_rec(uint8_t *data, size_t size) { typedef struct part_info { char disk_path[PATH_MAX]; int part_no; - char part_type[36+1]; /* GUID string, hyphen notation */ + char part_type[36 + 1]; /* GUID string, hyphen notation */ } part_info_t; /* given the location of the ESP mount point, returns the partition information * needed to create boot variable which points to that bootloader. */ -static int bootvar_get_part_info(const char *path, part_info_t *pi) { +static int bootvar_get_part_info(const char *path, part_info_t *pi) +{ blkid_probe probe; blkid_partition part; blkid_partlist parts; @@ -228,16 +259,21 @@ static int bootvar_get_part_info(const char *path, part_info_t *pi) { dev_t disk_dev; char disk_path[PATH_MAX]; - if (stat(path, &st)) return -1; + if (stat(path, &st)) + return -1; strcpy(disk_path, "/dev/"); - if (blkid_devno_to_wholedisk(st.st_dev, disk_path + 5, PATH_MAX - 5, &disk_dev)) return -1; + if (blkid_devno_to_wholedisk(st.st_dev, disk_path + 5, PATH_MAX - 5, &disk_dev)) + return -1; - if (!(probe = blkid_new_probe_from_filename(disk_path))) return -1; + if (!(probe = blkid_new_probe_from_filename(disk_path))) + return -1; - if (blkid_probe_enable_partitions(probe, 1)) return -1; + if (blkid_probe_enable_partitions(probe, 1)) + return -1; - if (!(parts = blkid_probe_get_partitions(probe))) return -1; + if (!(parts = blkid_probe_get_partitions(probe))) + return -1; part = blkid_partlist_devno_to_partition(parts, st.st_dev); snprintf(pi->disk_path, strlen(disk_path) + 1, "%s", disk_path); @@ -250,24 +286,29 @@ static int bootvar_get_part_info(const char *path, part_info_t *pi) { } /* attempts to look up existing record, otherwise creates a new one. */ -static boot_rec_t *bootvar_add_boot_rec(uint8_t *data, size_t len) { +static boot_rec_t *bootvar_add_boot_rec(uint8_t *data, size_t len) +{ char name[9]; /* variable name, e.g. "BootXXXX". */ int slot; - uint32_t attr = EFI_VARIABLE_NON_VOLATILE - | EFI_VARIABLE_BOOTSERVICE_ACCESS - | EFI_VARIABLE_RUNTIME_ACCESS; - boot_rec_t *c, - *res = bootvar_find_boot_rec(data, len); + uint32_t attr = EFI_VARIABLE_NON_VOLATILE | EFI_VARIABLE_BOOTSERVICE_ACCESS | + EFI_VARIABLE_RUNTIME_ACCESS; + boot_rec_t *c, *res = bootvar_find_boot_rec(data, len); - if (res) return res; + if (res) + return res; /* no such record, create one. */ slot = bootvar_find_free_no(); - if (slot < 0) return NULL; - if (snprintf(name, 9, "Boot%04X", slot) > 8) return NULL; - if (efi_set_variable(EFI_GLOBAL_GUID, name, data, len, attr, 0644) < 0) return NULL; + if (slot < 0) + return NULL; + if (snprintf(name, 9, "Boot%04X", slot) > 8) + return NULL; + if (efi_set_variable(EFI_GLOBAL_GUID, name, data, len, attr, 0644) < 0) + return NULL; /* re-read the records and find the variable that was just created. */ - if (bootvar_read_boot_recs() < 0) return NULL; - if (!boot_recs) return NULL; /* something went terribly wrong. */ + if (bootvar_read_boot_recs() < 0) + return NULL; + if (!boot_recs) + return NULL; /* something went terribly wrong. */ c = boot_recs; do { if (!strcmp(c->name, name)) { @@ -279,8 +320,9 @@ static boot_rec_t *bootvar_add_boot_rec(uint8_t *data, size_t len) { return res; } -int bootvar_create(const char *esp_mount_path, const char *bootloader_esp_path, - char *varname, size_t size) { +int bootvar_create(const char *esp_mount_path, const char *bootloader_esp_path, char *varname, + size_t size) +{ part_info_t pi; uint8_t fdev_path[PATH_MAX]; uint8_t data[BOOT_VAR_MAX]; /* this is what efivar supports and it should be @@ -288,36 +330,56 @@ int bootvar_create(const char *esp_mount_path, const char *bootloader_esp_path, long int len; boot_rec_t *rec; - if (bootvar_get_part_info(esp_mount_path, &pi)) return -1; + if (bootvar_get_part_info(esp_mount_path, &pi)) + return -1; - len = efi_generate_file_device_path_from_esp(fdev_path, PATH_MAX, - pi.disk_path, pi.part_no, bootloader_esp_path, EFIBOOT_ABBREV_HD); - if (len < 0) return -1; + len = efi_generate_file_device_path_from_esp(fdev_path, + PATH_MAX, + pi.disk_path, + pi.part_no, + bootloader_esp_path, + EFIBOOT_ABBREV_HD); + if (len < 0) + return -1; - len = efi_loadopt_create(data, BOOT_VAR_MAX, LOAD_OPTION_ACTIVE, - (void *)fdev_path, len, (unsigned char *)"Linux bootloader", NULL, 0); - if (len < 0) return -1; + len = efi_loadopt_create(data, + BOOT_VAR_MAX, + LOAD_OPTION_ACTIVE, + (void *)fdev_path, + len, + (unsigned char *)"Linux bootloader", + NULL, + 0); + if (len < 0) + return -1; rec = bootvar_add_boot_rec(data, (size_t)len); - if (!rec) return -1; + if (!rec) + return -1; - if (bootvar_push_to_boot_order(rec)) return -1; + if (bootvar_push_to_boot_order(rec)) + return -1; if (varname && size) { size_t len = strlen(rec->name); - if (len < size) snprintf(varname, len + 1, "%s", rec->name); + if (len < size) + snprintf(varname, len + 1, "%s", rec->name); } return 0; } -int bootvar_init(void) { - if (efi_variables_supported() < 0) return -1; - if (bootvar_read_boot_recs() < 0) return -1; +int bootvar_init(void) +{ + if (efi_variables_supported() < 0) + return -1; + if (bootvar_read_boot_recs() < 0) + return -1; return 0; } -void bootvar_destroy(void) { +void bootvar_destroy(void) +{ bootvar_free_boot_recs(); } diff --git a/tests/harness.c b/tests/harness.c index f4d1fef..3af1dc4 100644 --- a/tests/harness.c +++ b/tests/harness.c @@ -63,17 +63,17 @@ * Systemd support, including shim-systemd two-stage */ #if defined(HAVE_SYSTEMD_BOOT) -# if defined(HAVE_SHIM_SYSTEMD_BOOT) -# define ESP_BOOT_DIR BOOT_FULL "/" KERNEL_NAMESPACE -# define ESP_BOOT_STUB ESP_BOOT_DIR "/bootloader" EFI_STUB_SUFFIX_L -# define SHIM_BOOT_COPY_DIR PLAYGROUND_ROOT "/usr/lib/shim" -# else -# define ESP_BOOT_DIR EFI_START "/systemd" -# define ESP_BOOT_STUB ESP_BOOT_DIR "/systemd-boot" EFI_STUB_SUFFIX_L -# endif /* HAVE_SHIM_SYSTEMD_BOOT */ +#if defined(HAVE_SHIM_SYSTEMD_BOOT) +#define ESP_BOOT_DIR BOOT_FULL "/" KERNEL_NAMESPACE +#define ESP_BOOT_STUB ESP_BOOT_DIR "/bootloader" EFI_STUB_SUFFIX_L +#define SHIM_BOOT_COPY_DIR PLAYGROUND_ROOT "/usr/lib/shim" +#else +#define ESP_BOOT_DIR EFI_START "/systemd" +#define ESP_BOOT_STUB ESP_BOOT_DIR "/systemd-boot" EFI_STUB_SUFFIX_L +#endif /* HAVE_SHIM_SYSTEMD_BOOT */ -# define BOOT_COPY_TARGET PLAYGROUND_ROOT "/usr/lib/systemd/boot/efi/systemd-boot" EFI_STUB_SUFFIX_L -# define BOOT_COPY_DIR PLAYGROUND_ROOT "/usr/lib/systemd/boot/efi" +#define BOOT_COPY_TARGET PLAYGROUND_ROOT "/usr/lib/systemd/boot/efi/systemd-boot" EFI_STUB_SUFFIX_L +#define BOOT_COPY_DIR PLAYGROUND_ROOT "/usr/lib/systemd/boot/efi" /** * gummiboot support */ @@ -336,16 +336,17 @@ bool push_bootloader_update(int revision) { int i; char path[PATH_MAX]; - char *files[3] = { - "fb", - "mm", - "shim" - }; - if (!nc_file_exists(SHIM_BOOT_COPY_DIR) - && !nc_mkdir_p(SHIM_BOOT_COPY_DIR, 0755)) return false; + char *files[3] = { "fb", "mm", "shim" }; + if (!nc_file_exists(SHIM_BOOT_COPY_DIR) && !nc_mkdir_p(SHIM_BOOT_COPY_DIR, 0755)) + return false; for (i = 0; i < 3; i++) { - snprintf(path, PATH_MAX, "%s/%s" EFI_STUB_SUFFIX_L, SHIM_BOOT_COPY_DIR, files[i]); - if (!file_set_text(path, text)) return false; + snprintf(path, + PATH_MAX, + "%s/%s" EFI_STUB_SUFFIX_L, + SHIM_BOOT_COPY_DIR, + files[i]); + if (!file_set_text(path, text)) + return false; } } #endif /* HAVE_SHIM_SYSTEMD_BOOT */ @@ -477,7 +478,9 @@ int kernel_installed_files_count(BootManager *manager, PlaygroundKernel *kernel) autofree(char) *initrd_file = NULL; autofree(char) *initrd_file_legacy = NULL; /* where the kernel files are expected to be found on the ESP */ - char *esp_path = manager->bootloader->get_kernel_dst ? manager->bootloader->get_kernel_dst(manager) : "efi/" KERNEL_NAMESPACE; + char *esp_path = manager->bootloader->get_kernel_dst + ? manager->bootloader->get_kernel_dst(manager) + : "efi/" KERNEL_NAMESPACE; const char *vendor = NULL; int file_count = 0; diff --git a/tests/stub/bootvar.c b/tests/stub/bootvar.c index 800daa2..c8649aa 100644 --- a/tests/stub/bootvar.c +++ b/tests/stub/bootvar.c @@ -12,20 +12,22 @@ /* This file is a stub implementing happy src/lib/bootvar.h API. */ #include +#include #include #include #include -#include -int bootvar_init(void) { +int bootvar_init(void) +{ return 0; } -void bootvar_destroy(void) { +void bootvar_destroy(void) +{ return; } -int bootvar_create(const char *mnt_path, const char *bootloader_path, - char *name, size_t sz) { +int bootvar_create(const char *mnt_path, const char *bootloader_path, char *name, size_t sz) +{ (void)mnt_path; (void)bootloader_path; static char *stub_name = "Boot0001"; From 1b410619f714fa57df980deee81d92fc3212d626 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Wed, 6 Sep 2017 18:44:01 +0000 Subject: [PATCH 31/38] Use spaces/tabs consistently in Makefile.am. --- Makefile.am | 589 ++++++++++++++++++++++++++-------------------------- 1 file changed, 294 insertions(+), 295 deletions(-) diff --git a/Makefile.am b/Makefile.am index 981baa5..53be198 100644 --- a/Makefile.am +++ b/Makefile.am @@ -2,77 +2,78 @@ ACLOCAL_AMFLAGS = -I m4 -EXTRA_DIST = ${top_srcdir}/README.md \ - ${top_srcdir}/LICENSE.LGPL2.1 \ - ${top_srcdir}/HACKING \ - ${top_srcdir}/findstatic.pl \ - ${top_srcdir}/tests/data/blobfile \ - ${top_srcdir}/tests/data/match \ - ${top_srcdir}/tests/data/match1 \ - ${top_srcdir}/tests/data/nomatch1 \ - ${top_srcdir}/tests/data/nomatch2 \ - ${top_srcdir}/tests/data/clear.os-release \ - ${top_srcdir}/tests/data/solus.os-release \ - ${top_srcdir}/tests/data/cmdline/comments \ - ${top_srcdir}/tests/data/cmdline/mangledmess \ - ${top_srcdir}/tests/data/cmdline/multi \ - ${top_srcdir}/tests/data/cmdline/oneline \ - ${top_srcdir}/tests/data/etc/kernel/cmdline \ - ${top_srcdir}/tests/data/etc/kernel/cmdline.d/00_empty.conf \ - ${top_srcdir}/tests/data/etc/kernel/cmdline.d/00_newline.conf \ - ${top_srcdir}/tests/data/etc/kernel/cmdline.d/10_first.conf \ - ${top_srcdir}/tests/data/etc/kernel/cmdline.d/20_second.conf \ - ${top_srcdir}/tests/data/etc/kernel/cmdline.d/30_third.conf \ - ${top_srcdir}/tests/data/cmdline_vendor_only/usr/share/kernel/cmdline.d/10_first.conf \ - ${top_srcdir}/tests/data/cmdline_vendor_only/usr/share/kernel/cmdline.d/20_second.conf \ - ${top_srcdir}/tests/data/cmdline_vendor_only/usr/share/kernel/cmdline.d/30_third.conf \ - ${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/00_empty.conf \ - ${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/00_newline.conf \ - ${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/10_first.conf \ - ${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/20_second.conf \ - ${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/30_third.conf \ - ${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/40_masked.conf \ - ${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline \ - ${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/10_local_first.conf \ - ${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/20_local_second.conf \ - ${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/30_local_third.conf \ - ${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/40_masked.conf \ - ${top_srcdir}/tests/data/gptmbr.bin \ - ${top_srcdir}/tests/data/gptmbr.bin.v2 \ - ${top_srcdir}/sgcheck.suppressions \ - ${top_srcdir}/data/clr-boot-manager-booted.service \ - ${top_srcdir}/man/clr-boot-manager.1 +EXTRA_DIST = \ + ${top_srcdir}/README.md \ + ${top_srcdir}/LICENSE.LGPL2.1 \ + ${top_srcdir}/HACKING \ + ${top_srcdir}/findstatic.pl \ + ${top_srcdir}/tests/data/blobfile \ + ${top_srcdir}/tests/data/match \ + ${top_srcdir}/tests/data/match1 \ + ${top_srcdir}/tests/data/nomatch1 \ + ${top_srcdir}/tests/data/nomatch2 \ + ${top_srcdir}/tests/data/clear.os-release \ + ${top_srcdir}/tests/data/solus.os-release \ + ${top_srcdir}/tests/data/cmdline/comments \ + ${top_srcdir}/tests/data/cmdline/mangledmess \ + ${top_srcdir}/tests/data/cmdline/multi \ + ${top_srcdir}/tests/data/cmdline/oneline \ + ${top_srcdir}/tests/data/etc/kernel/cmdline \ + ${top_srcdir}/tests/data/etc/kernel/cmdline.d/00_empty.conf \ + ${top_srcdir}/tests/data/etc/kernel/cmdline.d/00_newline.conf \ + ${top_srcdir}/tests/data/etc/kernel/cmdline.d/10_first.conf \ + ${top_srcdir}/tests/data/etc/kernel/cmdline.d/20_second.conf \ + ${top_srcdir}/tests/data/etc/kernel/cmdline.d/30_third.conf \ + ${top_srcdir}/tests/data/cmdline_vendor_only/usr/share/kernel/cmdline.d/10_first.conf \ + ${top_srcdir}/tests/data/cmdline_vendor_only/usr/share/kernel/cmdline.d/20_second.conf \ + ${top_srcdir}/tests/data/cmdline_vendor_only/usr/share/kernel/cmdline.d/30_third.conf \ + ${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/00_empty.conf \ + ${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/00_newline.conf \ + ${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/10_first.conf \ + ${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/20_second.conf \ + ${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/30_third.conf \ + ${top_srcdir}/tests/data/cmdline_vendor_merged/usr/share/kernel/cmdline.d/40_masked.conf \ + ${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline \ + ${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/10_local_first.conf \ + ${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/20_local_second.conf \ + ${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/30_local_third.conf \ + ${top_srcdir}/tests/data/cmdline_vendor_merged/etc/kernel/cmdline.d/40_masked.conf \ + ${top_srcdir}/tests/data/gptmbr.bin \ + ${top_srcdir}/tests/data/gptmbr.bin.v2 \ + ${top_srcdir}/sgcheck.suppressions \ + ${top_srcdir}/data/clr-boot-manager-booted.service \ + ${top_srcdir}/man/clr-boot-manager.1 NULL = CLEANFILES = DISTCHECK_CONFIGURE_FLAGS = \ - --with-systemdsystemunitdir="${distdir}/${libdir}/systemd/system" + --with-systemdsystemunitdir="${distdir}/${libdir}/systemd/system" -AM_CFLAGS = -fstack-protector -Wall -pedantic \ - -Wstrict-prototypes -Wundef -fno-common \ - -Werror-implicit-function-declaration \ - -Wformat -Wformat-security -Werror=format-security \ - -Wconversion -Wunused-variable -Wunreachable-code \ - -Wall -W -D_FORTIFY_SOURCE=2 \ - -Wno-missing-field-initializers \ - -std=c11 \ - -DSYSCONFDIR=\"$(sysconfdir)\" \ - -D_POSIX_C_SOURCE=201112L +AM_CFLAGS = -fstack-protector -Wall -pedantic \ + -Wstrict-prototypes -Wundef -fno-common \ + -Werror-implicit-function-declaration \ + -Wformat -Wformat-security -Werror=format-security \ + -Wconversion -Wunused-variable -Wunreachable-code \ + -Wall -W -D_FORTIFY_SOURCE=2 \ + -Wno-missing-field-initializers \ + -std=c11 \ + -DSYSCONFDIR=\"$(sysconfdir)\" \ + -D_POSIX_C_SOURCE=201112L -AM_CPPFLAGS = \ - -I $(top_srcdir)/src \ - -I $(top_srcdir)/src/bootman \ - -I $(top_srcdir)/src/cli \ - -I $(top_srcdir)/src/bootloaders \ - -I $(top_srcdir)/src/lib \ - -I $(top_srcdir)/src/libnica/src/include \ - -isystem @efivar@ \ - -isystem @gnuefi@ \ - -isystem @gnuefi@/@host_cpu@ \ - -DTOP_DIR=\"$(abs_top_srcdir)\" \ - -DTOP_BUILD_DIR=\"$(abs_top_builddir)\" +AM_CPPFLAGS = \ + -I $(top_srcdir)/src \ + -I $(top_srcdir)/src/bootman \ + -I $(top_srcdir)/src/cli \ + -I $(top_srcdir)/src/bootloaders \ + -I $(top_srcdir)/src/lib \ + -I $(top_srcdir)/src/libnica/src/include \ + -isystem @efivar@ \ + -isystem @gnuefi@ \ + -isystem @gnuefi@/@host_cpu@ \ + -DTOP_DIR=\"$(abs_top_srcdir)\" \ + -DTOP_BUILD_DIR=\"$(abs_top_builddir)\" AUTOMAKE_OPTIONS = color-tests parallel-tests @@ -93,82 +94,82 @@ noinst_LTLIBRARIES = \ bin_PROGRAMS = clr-boot-manager -SOURCE_FILES = \ - src/bootloaders/bootloader.h \ - src/bootloaders/systemd-class.h \ - src/bootloaders/systemd-class.c \ - src/bootloaders/shim-systemd.c \ - src/bootloaders/systemd-boot.c \ - src/bootloaders/grub2.c \ - src/bootloaders/gummiboot.c \ - src/bootloaders/goofiboot.c \ - src/bootloaders/syslinux.c \ - src/bootman/bootman.h \ - src/bootman/bootman_private.h \ - src/bootman/bootman.c \ - src/bootman/kernel.c \ - src/bootman/sysconfig.c \ - src/bootman/timeout.c \ - src/bootman/update.c \ - src/lib/blkid_stub.h \ - src/lib/blkid_stub.c \ - src/lib/cmdline.h \ - src/lib/cmdline.c \ - src/lib/files.h \ - src/lib/files.c \ - src/lib/os-release.h \ - src/lib/os-release.c \ - src/lib/log.h \ - src/lib/log.c \ - src/lib/probe.h \ - src/lib/probe.c \ - src/lib/system_stub.h \ - src/lib/system_stub.c \ - src/lib/writer.h \ - src/lib/writer.c \ - src/lib/util.h \ - src/lib/util.c \ - src/lib/bootvar.h +SOURCE_FILES = \ + src/bootloaders/bootloader.h \ + src/bootloaders/systemd-class.h \ + src/bootloaders/systemd-class.c \ + src/bootloaders/shim-systemd.c \ + src/bootloaders/systemd-boot.c \ + src/bootloaders/grub2.c \ + src/bootloaders/gummiboot.c \ + src/bootloaders/goofiboot.c \ + src/bootloaders/syslinux.c \ + src/bootman/bootman.h \ + src/bootman/bootman_private.h \ + src/bootman/bootman.c \ + src/bootman/kernel.c \ + src/bootman/sysconfig.c \ + src/bootman/timeout.c \ + src/bootman/update.c \ + src/lib/blkid_stub.h \ + src/lib/blkid_stub.c \ + src/lib/cmdline.h \ + src/lib/cmdline.c \ + src/lib/files.h \ + src/lib/files.c \ + src/lib/os-release.h \ + src/lib/os-release.c \ + src/lib/log.h \ + src/lib/log.c \ + src/lib/probe.h \ + src/lib/probe.c \ + src/lib/system_stub.h \ + src/lib/system_stub.c \ + src/lib/writer.h \ + src/lib/writer.c \ + src/lib/util.h \ + src/lib/util.c \ + src/lib/bootvar.h -PROD_SOURCE_FILES = \ - src/lib/bootvar.c +PROD_SOURCE_FILES = \ + src/lib/bootvar.c -STUB_SOURCE_FILES = \ - tests/stub/bootvar.c +STUB_SOURCE_FILES = \ + tests/stub/bootvar.c -libcbm_la_SOURCES = \ - $(SOURCE_FILES) \ - $(PROD_SOURCE_FILES) +libcbm_la_SOURCES = \ + $(SOURCE_FILES) \ + $(PROD_SOURCE_FILES) -libcbm_la_CFLAGS = \ - -D_BOOTMAN_INTERNAL_ \ - $(BLKID_CFLAGS) \ - $(AM_CFLAGS) +libcbm_la_CFLAGS = \ + -D_BOOTMAN_INTERNAL_ \ + $(BLKID_CFLAGS) \ + $(AM_CFLAGS) -libcbm_la_LIBADD = \ - src/libnica/libnica.la +libcbm_la_LIBADD = \ + src/libnica/libnica.la -clr_boot_manager_SOURCES = \ - src/cli/cli.h \ - src/cli/cli.c \ - src/cli/ops/update.h \ - src/cli/ops/update.c \ - src/cli/ops/timeout.h \ - src/cli/ops/timeout.c \ - src/cli/ops/report_booted.h \ - src/cli/ops/report_booted.c \ - src/cli/main.c +clr_boot_manager_SOURCES = \ + src/cli/cli.h \ + src/cli/cli.c \ + src/cli/ops/update.h \ + src/cli/ops/update.c \ + src/cli/ops/timeout.h \ + src/cli/ops/timeout.c \ + src/cli/ops/report_booted.h \ + src/cli/ops/report_booted.c \ + src/cli/main.c -clr_boot_manager_CFLAGS = \ - $(BLKID_CFLAGS) \ - $(AM_CFLAGS) +clr_boot_manager_CFLAGS = \ + $(BLKID_CFLAGS) \ + $(AM_CFLAGS) -clr_boot_manager_LDADD = \ - libcbm.la \ - src/libnica/libnica.la \ - -lefiboot \ - -lefivar \ - $(BLKID_LIBS) +clr_boot_manager_LDADD = \ + libcbm.la \ + src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ + $(BLKID_LIBS) install-exec-hook: perl ${top_srcdir}/findstatic.pl ${top_builddir}/src/*.o ${top_builddir}/src/*/*.o | grep -v Checking ||: @@ -180,210 +181,208 @@ dist_systemdsystemunit_DATA = ${top_srcdir}/data/clr-boot-manager-booted.service endif manpagesdir = $(mandir)/man1 -manpages_DATA = \ - man/clr-boot-manager.1 +manpages_DATA = \ + man/clr-boot-manager.1 distclean-local: rm -rf ${top_builddir}/tests/update_playground -TESTS = \ - check_core \ - check_cmdline \ - check_files \ - check_legacy \ - check_os_release \ - check_uefi \ - check_grub2 \ - check_select_bootloader \ - check_probe +TESTS = \ + check_core \ + check_cmdline \ + check_files \ + check_legacy \ + check_os_release \ + check_uefi \ + check_grub2 \ + check_select_bootloader \ + check_probe check_PROGRAMS = $(TESTS) check_LTLIBRARIES = libcbm-check.la -libcbm_check_la_SOURCES = \ - $(SOURCE_FILES) \ - $(STUB_SOURCE_FILES) +libcbm_check_la_SOURCES = \ + $(SOURCE_FILES) \ + $(STUB_SOURCE_FILES) -libcbm_check_la_CFLAGS = \ - $(libcbm_la_CFLAGS) \ - -DTEST_STUB=1 +libcbm_check_la_CFLAGS = \ + $(libcbm_la_CFLAGS) \ + -DTEST_STUB=1 libcbm_check_la_LIBADD = $(libcbm_la_LIBADD) +check_core_SOURCES = \ + tests/check-core.c \ + tests/blkid-harness.h \ + tests/system-harness.h \ + tests/harness.h \ + tests/harness.c -check_core_SOURCES = \ - tests/check-core.c \ - tests/blkid-harness.h \ - tests/system-harness.h \ - tests/harness.h \ - tests/harness.c +check_core_CFLAGS = \ + $(BLKID_CFLAGS) \ + $(CHECK_CFLAGS) \ + $(AM_CFLAGS) -check_core_CFLAGS = \ - $(BLKID_CFLAGS) \ - $(CHECK_CFLAGS) \ - $(AM_CFLAGS) +check_core_LDADD = \ + libcbm-check.la \ + src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ + $(BLKID_LIBS) \ + $(CHECK_LIBS) -check_core_LDADD = \ - libcbm-check.la \ - src/libnica/libnica.la \ - -lefiboot \ - -lefivar \ - $(BLKID_LIBS) \ - $(CHECK_LIBS) +check_cmdline_SOURCES = \ + tests/check-cmdline.c -check_cmdline_SOURCES = \ - tests/check-cmdline.c +check_cmdline_CFLAGS = \ + $(BLKID_CFLAGS) \ + $(CHECK_CFLAGS) \ + $(AM_CFLAGS) -check_cmdline_CFLAGS = \ - $(BLKID_CFLAGS) \ - $(CHECK_CFLAGS) \ - $(AM_CFLAGS) +check_cmdline_LDADD = \ + libcbm-check.la \ + src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ + $(BLKID_LIBS) \ + $(CHECK_LIBS) -check_cmdline_LDADD = \ - libcbm-check.la \ - src/libnica/libnica.la \ - -lefiboot \ - -lefivar \ - $(BLKID_LIBS) \ - $(CHECK_LIBS) +check_files_SOURCES = \ + tests/check-files.c \ + tests/harness.h \ + tests/harness.c -check_files_SOURCES = \ - tests/check-files.c \ - tests/harness.h \ - tests/harness.c +check_files_CFLAGS = \ + $(BLKID_CFLAGS) \ + $(CHECK_CFLAGS) \ + $(AM_CFLAGS) -check_files_CFLAGS = \ - $(BLKID_CFLAGS) \ - $(CHECK_CFLAGS) \ - $(AM_CFLAGS) +check_files_LDADD = \ + libcbm-check.la \ + src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ + $(BLKID_LIBS) \ + $(CHECK_LIBS) -check_files_LDADD = \ - libcbm-check.la \ - src/libnica/libnica.la \ - -lefiboot \ - -lefivar \ - $(BLKID_LIBS) \ - $(CHECK_LIBS) +check_legacy_SOURCES = \ + tests/check-legacy.c \ + tests/blkid-harness.h \ + tests/system-harness.h \ + tests/harness.h \ + tests/harness.c -check_legacy_SOURCES = \ - tests/check-legacy.c \ - tests/blkid-harness.h \ - tests/system-harness.h \ - tests/harness.h \ - tests/harness.c +check_legacy_CFLAGS = \ + $(BLKID_CFLAGS) \ + $(CHECK_CFLAGS) \ + $(AM_CFLAGS) -check_legacy_CFLAGS = \ - $(BLKID_CFLAGS) \ - $(CHECK_CFLAGS) \ - $(AM_CFLAGS) +check_legacy_LDADD = \ + libcbm-check.la \ + src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ + $(BLKID_LIBS) \ + $(CHECK_LIBS) -check_legacy_LDADD = \ - libcbm-check.la \ - src/libnica/libnica.la \ - -lefiboot \ - -lefivar \ - $(BLKID_LIBS) \ - $(CHECK_LIBS) +check_os_release_SOURCES = \ + tests/check-os-release.c -check_os_release_SOURCES = \ - tests/check-os-release.c +check_os_release_CFLAGS = \ + $(BLKID_CFLAGS) \ + $(CHECK_CFLAGS) \ + $(AM_CFLAGS) -check_os_release_CFLAGS = \ - $(BLKID_CFLAGS) \ - $(CHECK_CFLAGS) \ - $(AM_CFLAGS) +check_os_release_LDADD = \ + libcbm-check.la \ + src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ + $(BLKID_LIBS) \ + $(CHECK_LIBS) -check_os_release_LDADD = \ - libcbm-check.la \ - src/libnica/libnica.la \ - -lefiboot \ - -lefivar \ - $(BLKID_LIBS) \ - $(CHECK_LIBS) +check_uefi_SOURCES = \ + tests/check-uefi.c \ + tests/blkid-harness.h \ + tests/system-harness.h \ + tests/harness.h \ + tests/harness.c -check_uefi_SOURCES = \ - tests/check-uefi.c \ - tests/blkid-harness.h \ - tests/system-harness.h \ - tests/harness.h \ - tests/harness.c +check_uefi_CFLAGS = \ + $(BLKID_CFLAGS) \ + $(CHECK_CFLAGS) \ + $(AM_CFLAGS) -check_uefi_CFLAGS = \ - $(BLKID_CFLAGS) \ - $(CHECK_CFLAGS) \ - $(AM_CFLAGS) +check_uefi_LDADD = \ + libcbm-check.la \ + src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ + $(BLKID_LIBS) \ + $(CHECK_LIBS) -check_uefi_LDADD = \ - libcbm-check.la \ - src/libnica/libnica.la \ - -lefiboot \ - -lefivar \ - $(BLKID_LIBS) \ - $(CHECK_LIBS) +check_grub2_SOURCES = \ + tests/check-grub2.c \ + tests/blkid-harness.h \ + tests/system-harness.h \ + tests/harness.h \ + tests/harness.c -check_grub2_SOURCES = \ - tests/check-grub2.c \ - tests/blkid-harness.h \ - tests/system-harness.h \ - tests/harness.h \ - tests/harness.c +check_grub2_CFLAGS = \ + $(BLKID_CFLAGS) \ + $(CHECK_CFLAGS) \ + $(AM_CFLAGS) -check_grub2_CFLAGS = \ - $(BLKID_CFLAGS) \ - $(CHECK_CFLAGS) \ - $(AM_CFLAGS) +check_grub2_LDADD = \ + libcbm-check.la \ + src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ + $(BLKID_LIBS) \ + $(CHECK_LIBS) -check_grub2_LDADD = \ - libcbm-check.la \ - src/libnica/libnica.la \ - -lefiboot \ - -lefivar \ - $(BLKID_LIBS) \ - $(CHECK_LIBS) +check_select_bootloader_SOURCES = \ + tests/check-select-bootloader.c \ + tests/blkid-harness.h \ + tests/system-harness.h \ + tests/harness.h \ + tests/harness.c -check_select_bootloader_SOURCES = \ - tests/check-select-bootloader.c \ - tests/blkid-harness.h \ - tests/system-harness.h \ - tests/harness.h \ - tests/harness.c +check_select_bootloader_CFLAGS = \ + $(BLKID_CFLAGS) \ + $(CHECK_CFLAGS) \ + $(AM_CFLAGS) -check_select_bootloader_CFLAGS = \ - $(BLKID_CFLAGS) \ - $(CHECK_CFLAGS) \ - $(AM_CFLAGS) +check_select_bootloader_LDADD = \ + libcbm-check.la \ + src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ + $(BLKID_LIBS) \ + $(CHECK_LIBS) -check_select_bootloader_LDADD = \ - libcbm-check.la \ - src/libnica/libnica.la \ - -lefiboot \ - -lefivar \ - $(BLKID_LIBS) \ - $(CHECK_LIBS) +check_probe_SOURCES = \ + tests/check-probe.c \ + tests/blkid-harness.h \ + tests/system-harness.h \ + tests/harness.h \ + tests/harness.c -check_probe_SOURCES = \ - tests/check-probe.c \ - tests/blkid-harness.h \ - tests/system-harness.h \ - tests/harness.h \ - tests/harness.c - -check_probe_CFLAGS = \ - $(BLKID_CFLAGS) \ - $(CHECK_CFLAGS) \ - $(AM_CFLAGS) - -check_probe_LDADD = \ - libcbm-check.la \ - src/libnica/libnica.la \ - -lefiboot \ - -lefivar \ - $(BLKID_LIBS) \ - $(CHECK_LIBS) +check_probe_CFLAGS = \ + $(BLKID_CFLAGS) \ + $(CHECK_CFLAGS) \ + $(AM_CFLAGS) +check_probe_LDADD = \ + libcbm-check.la \ + src/libnica/libnica.la \ + -lefiboot \ + -lefivar \ + $(BLKID_LIBS) \ + $(CHECK_LIBS) @VALGRIND_CHECK_RULES@ -VALGRIND_SUPPRESSIONS_FILES = \ +VALGRIND_SUPPRESSIONS_FILES = \ ${abs_top_srcdir}/sgcheck.suppressions From d8166f7a1b4200b0c627a622f947809315074926 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Thu, 7 Sep 2017 03:56:47 +0000 Subject: [PATCH 32/38] Remove leftover mark for unused argument. --- src/bootloaders/shim-systemd.c | 1 - 1 file changed, 1 deletion(-) diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index 5284823..1503716 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -197,7 +197,6 @@ static bool make_layout(const BootManager *manager) static bool shim_systemd_install(const BootManager *manager) { char varname[9]; - (void)manager; if (!make_layout(manager)) return false; From f2fedf1e12a160c69744a6738d8db58dffa0f975 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Wed, 11 Oct 2017 08:33:52 +0000 Subject: [PATCH 33/38] Add diagnostics and err handling for shim/systemd. --- src/bootloaders/shim-systemd.c | 38 +++++++---- src/lib/bootvar.c | 111 ++++++++++++++++++++++++--------- src/lib/bootvar.h | 3 + 3 files changed, 111 insertions(+), 41 deletions(-) diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index 1503716..84326cb 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -18,6 +18,7 @@ #include "bootvar.h" #include "config.h" #include "files.h" +#include #include "nica/files.h" #include "systemd-class.h" @@ -183,31 +184,45 @@ static bool make_layout(const BootManager *manager) char *boot_root = boot_manager_get_boot_dir((BootManager *)manager); char path[PATH_MAX]; snprintf(path, PATH_MAX, "%s%s", boot_root, DST_DIR); - if (!nc_mkdir_p(path, 00755)) - return false; + if (!nc_mkdir_p(path, 00755)) { + goto fail; + } snprintf(path, PATH_MAX, "%s%s", boot_root, KERNEL_DST_DIR); - if (!nc_mkdir_p(path, 00755)) - return false; + if (!nc_mkdir_p(path, 00755)) { + goto fail; + } snprintf(path, PATH_MAX, "%s%s", boot_root, SYSTEMD_ENTRIES); - if (!nc_mkdir_p(path, 00755)) - return false; + if (!nc_mkdir_p(path, 00755)) { + goto fail; + } return true; +fail: + LOG_FATAL("Failed to make dir: %s", path); + return false; } static bool shim_systemd_install(const BootManager *manager) { char varname[9]; - if (!make_layout(manager)) + if (!make_layout(manager)) { + LOG_FATAL("Cannot create layout"); return false; + } - if (!copy_file_atomic(shim_src, shim_dst_host, 00644)) + if (!copy_file_atomic(shim_src, shim_dst_host, 00644)) { + LOG_FATAL("Cannot copy %s to %s", shim_src, shim_dst_host); return false; - if (!copy_file_atomic(systemd_src, systemd_dst_host, 00644)) + } + if (!copy_file_atomic(systemd_src, systemd_dst_host, 00644)) { + LOG_FATAL("Cannot copy %s to %s", systemd_src, systemd_dst_host); return false; + } - if (bootvar_create(BOOT_DIRECTORY, shim_dst_esp, varname, 9)) + if (bootvar_create(BOOT_DIRECTORY, shim_dst_esp, varname, 9)) { + LOG_FATAL("Cannot create EFI variable"); return false; + } return true; } @@ -248,9 +263,10 @@ static bool shim_systemd_init(const BootManager *manager) shim_src = string_printf("%s/%s", prefix, SHIM_SRC); systemd_src = string_printf("%s/%s", prefix, SYSTEMD_SRC); - /* SHIM_DST and SYSTEMD_DST are defined with leading '/' */ boot_root = strdup(boot_manager_get_boot_dir((BootManager *)manager)); len = strlen(boot_root); + /* SHIM_DST and SYSTEMD_DST are defined with leading '/', take extra + * care to produce clean paths. */ if (len > 0 && boot_root[len - 1] == '/') boot_root[len - 1] = '\0'; shim_dst_host = string_printf("%s%s", boot_root, SHIM_DST); diff --git a/src/lib/bootvar.c b/src/lib/bootvar.c index 9c8a7b8..ba06816 100644 --- a/src/lib/bootvar.c +++ b/src/lib/bootvar.c @@ -11,6 +11,8 @@ #define _GNU_SOURCE +#include "bootvar.h" + #include /* Workaround for using --std=c11 in CBM. Provide "relaxed" defines which efivar * expects. */ @@ -21,10 +23,12 @@ #include #include #include -#include #include +#include #include #include +#include +#include #include #include #include @@ -107,6 +111,10 @@ static int bootvar_read_boot_recs(void) } i++; } + if (res < 0) { + LOG_FATAL("efi_get_next_variable_name() failed: %s", strerror(errno)); + return -EBOOT_VAR_ERR; + } boot_recs_cnt = i; return 0; } @@ -125,14 +133,16 @@ static int bootvar_push_to_boot_order(boot_rec_t *rec) int found = 0; if (!rec || !rec->name) - return -1; + return -EBOOT_VAR_ERR; if (efi_get_variable(EFI_GLOBAL_GUID, "BootOrder", (uint8_t **)&boot_order, &boot_order_size, - &boot_order_attrs)) - return -1; + &boot_order_attrs)) { + LOG_FATAL("efi_get_variable() failed: %s", strerror(errno)); + return -EBOOT_VAR_ERR; + } sscanf(rec->name, "Boot%04hX", &number); @@ -171,8 +181,10 @@ static int bootvar_push_to_boot_order(boot_rec_t *rec) (uint8_t *)new_boot_order, new_boot_order_size, boot_order_attrs, - 0644)) - return -1; + 0644)) { + LOG_FATAL("efi_set_variable() failed: %s", strerror(errno)); + return -EBOOT_VAR_ERR; + } return 0; } @@ -231,8 +243,10 @@ static boot_rec_t *bootvar_find_boot_rec(uint8_t *data, size_t size) return NULL; do { - if (efi_get_variable(EFI_GLOBAL_GUID, c->name, &cdata, &csize, &cattr) < 0) + if (efi_get_variable(EFI_GLOBAL_GUID, c->name, &cdata, &csize, &cattr) < 0) { + LOG_ERROR("efi_get_variable() failed: %s", strerror(errno)); continue; + } if (csize == size && !memcmp(cdata, data, csize)) { res = c; break; @@ -258,27 +272,55 @@ static int bootvar_get_part_info(const char *path, part_info_t *pi) struct stat st; dev_t disk_dev; char disk_path[PATH_MAX]; + const char *part_type; - if (stat(path, &st)) - return -1; + if (stat(path, &st)) { + LOG_FATAL("stat() failed on %s: %s", path, strerror(errno)); + return -EBOOT_VAR_ERR; + } strcpy(disk_path, "/dev/"); - if (blkid_devno_to_wholedisk(st.st_dev, disk_path + 5, PATH_MAX - 5, &disk_dev)) - return -1; + if (blkid_devno_to_wholedisk(st.st_dev, disk_path + 5, PATH_MAX - 5, &disk_dev)) { + LOG_FATAL("blkid_devno_to_wholedisk() error"); + return -EBOOT_VAR_ERR; + } - if (!(probe = blkid_new_probe_from_filename(disk_path))) - return -1; + if (!(probe = blkid_new_probe_from_filename(disk_path))) { + LOG_FATAL("blkid_new_probe_from_filename() error"); + return -EBOOT_VAR_ERR; + } - if (blkid_probe_enable_partitions(probe, 1)) - return -1; + if (blkid_probe_enable_partitions(probe, 1)) { + LOG_FATAL("blkid_probe_enable_partitions() error"); + return -EBOOT_VAR_ERR; + } - if (!(parts = blkid_probe_get_partitions(probe))) - return -1; - part = blkid_partlist_devno_to_partition(parts, st.st_dev); + if (!(parts = blkid_probe_get_partitions(probe))) { + LOG_FATAL("blkid_probe_get_partitions() error"); + return -EBOOT_VAR_ERR; + } + + if (!(part = blkid_partlist_devno_to_partition(parts, st.st_dev))) { + LOG_FATAL("blkid_partlist_devno_to_partition() error"); + return -EBOOT_VAR_ERR; + } + + if ((pi->part_no = blkid_partition_get_partno(part)) < 0) { + LOG_FATAL("blkid_partition_get_partno() error"); + return -EBOOT_VAR_ERR; + } + + part_type = blkid_partition_get_type_string(part); + if (!part_type) { + LOG_FATAL("blkid_partition_get_type_string() returned NULL"); + return -EBOOT_VAR_ERR; + } else if (strlen(part_type) != 36) { + LOG_FATAL("partition type does not seem to be a GUID: %s", part_type); + return -EBOOT_VAR_ERR; + } snprintf(pi->disk_path, strlen(disk_path) + 1, "%s", disk_path); - pi->part_no = blkid_partition_get_partno(part); - snprintf(pi->part_type, 36 + 1, "%s", blkid_partition_get_type_string(part)); + snprintf(pi->part_type, 36 + 1, "%s", part_type); blkid_free_probe(probe); @@ -302,8 +344,10 @@ static boot_rec_t *bootvar_add_boot_rec(uint8_t *data, size_t len) return NULL; if (snprintf(name, 9, "Boot%04X", slot) > 8) return NULL; - if (efi_set_variable(EFI_GLOBAL_GUID, name, data, len, attr, 0644) < 0) + if (efi_set_variable(EFI_GLOBAL_GUID, name, data, len, attr, 0644) < 0) { + LOG_FATAL("efi_set_variable() failed: %s", strerror(errno)); return NULL; + } /* re-read the records and find the variable that was just created. */ if (bootvar_read_boot_recs() < 0) return NULL; @@ -339,8 +383,10 @@ int bootvar_create(const char *esp_mount_path, const char *bootloader_esp_path, pi.part_no, bootloader_esp_path, EFIBOOT_ABBREV_HD); - if (len < 0) - return -1; + if (len < 0) { + LOG_FATAL("efi_generate_file_device_path_from_esp() failed: %s", strerror(errno)); + return -EBOOT_VAR_ERR; + } len = efi_loadopt_create(data, BOOT_VAR_MAX, @@ -350,20 +396,25 @@ int bootvar_create(const char *esp_mount_path, const char *bootloader_esp_path, (unsigned char *)"Linux bootloader", NULL, 0); - if (len < 0) - return -1; + if (len < 0) { + LOG_FATAL("efi_loadopt_create() failed: %s", strerror(errno)); + return -EBOOT_VAR_ERR; + } rec = bootvar_add_boot_rec(data, (size_t)len); if (!rec) - return -1; + return -EBOOT_VAR_ERR; if (bootvar_push_to_boot_order(rec)) - return -1; + return -EBOOT_VAR_ERR; if (varname && size) { size_t len = strlen(rec->name); - if (len < size) + if (len < size) { snprintf(varname, len + 1, "%s", rec->name); + } else { + LOG_ERROR("%lu bytes is not enough. Need %lu.", size, len); + } } return 0; @@ -372,9 +423,9 @@ int bootvar_create(const char *esp_mount_path, const char *bootloader_esp_path, int bootvar_init(void) { if (efi_variables_supported() < 0) - return -1; + return -EBOOT_VAR_NOSUP; if (bootvar_read_boot_recs() < 0) - return -1; + return -EBOOT_VAR_ERR; return 0; } diff --git a/src/lib/bootvar.h b/src/lib/bootvar.h index 6df8ea7..b245ea4 100644 --- a/src/lib/bootvar.h +++ b/src/lib/bootvar.h @@ -11,6 +11,9 @@ #include +#define EBOOT_VAR_ERR 1 /* general error */ +#define EBOOT_VAR_NOSUP 127 /* EFI vars not supported */ + int bootvar_init(void); void bootvar_destroy(void); int bootvar_create(const char *, const char *, char *, size_t); From 48d2488b1b2c8176e970b056cde4edb529e24243 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Wed, 11 Oct 2017 08:43:43 +0000 Subject: [PATCH 34/38] Put code format check in its original place. --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index 35da5a9..dfd85d4 100644 --- a/.travis.yml +++ b/.travis.yml @@ -42,10 +42,10 @@ script: - lcov --version | grep "1.10" - export CC="gcc-5" - ./configure --enable-coverage && make && make check && make distcheck && make check-valgrind + - clang-format-3.8 -i $(find . -name '*.[ch]') && git diff --exit-code after_success: - cd ${TRAVIS_BUILD_DIR} - lcov --compat-libtool --directory . --capture --output-file coverage.info - lcov --remove coverage.info 'tests/*' '/usr/*' --output-file coverage.info - coveralls-lcov coverage.info - - clang-format-3.8 -i $(find . -name '*.[ch]') && git diff --exit-code From 8966a64612d40922ef4dd4f1d9c77a0d434fde26 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Wed, 11 Oct 2017 08:56:46 +0000 Subject: [PATCH 35/38] Recover the beauty. --- src/bootloaders/grub2.c | 4 ++-- src/bootloaders/shim-systemd.c | 26 +++++++++++++------------- src/lib/bootvar.c | 2 +- src/lib/bootvar.h | 4 ++-- src/lib/files.h | 6 +++--- 5 files changed, 21 insertions(+), 21 deletions(-) diff --git a/src/bootloaders/grub2.c b/src/bootloaders/grub2.c index b86d262..609fb31 100644 --- a/src/bootloaders/grub2.c +++ b/src/bootloaders/grub2.c @@ -538,8 +538,8 @@ int grub2_get_capabilities(__cbm_unused__ const BootManager *manager) __cbm_export__ const BootLoader grub2_bootloader = {.name = "grub2", .init = grub2_init, - .get_kernel_dst = NULL, /* kernel directory only - needed for EFI + .get_kernel_dst = NULL, /* kernel directory + only needed for EFI booloaders */ .install_kernel = grub2_install_kernel, .remove_kernel = grub2_remove_kernel, diff --git a/src/bootloaders/shim-systemd.c b/src/bootloaders/shim-systemd.c index 84326cb..9706f48 100644 --- a/src/bootloaders/shim-systemd.c +++ b/src/bootloaders/shim-systemd.c @@ -18,9 +18,9 @@ #include "bootvar.h" #include "config.h" #include "files.h" -#include #include "nica/files.h" #include "systemd-class.h" +#include /* * This file implements 2-stage bootloader configuration in which shim is used as @@ -92,30 +92,30 @@ __cbm_export__ const BootLoader #define SHIM_SRC_DIR "usr/lib/shim" #define SHIM_SRC \ SHIM_SRC_DIR \ - "/" \ - "shim" EFI_SUFFIX + "/" \ + "shim" EFI_SUFFIX #define MM_SRC \ SHIM_SRC_DIR \ - "/" \ - "mm" EFI_SUFFIX + "/" \ + "mm" EFI_SUFFIX #define FB_SRC \ SHIM_SRC_DIR \ - "/" \ - "fb" EFI_SUFFIX + "/" \ + "fb" EFI_SUFFIX #define SYSTEMD_SRC_DIR "usr/lib/systemd/boot/efi" #define SYSTEMD_SRC \ SYSTEMD_SRC_DIR \ - "/" \ - "systemd-boot" EFI_SUFFIX + "/" \ + "systemd-boot" EFI_SUFFIX #define DST_DIR "/" KERNEL_NAMESPACE #define SHIM_DST \ DST_DIR \ - "/" \ - "bootloader" EFI_SUFFIX + "/" \ + "bootloader" EFI_SUFFIX #define SYSTEMD_DST \ DST_DIR \ - "/" \ - "loader" EFI_SUFFIX + "/" \ + "loader" EFI_SUFFIX #define KERNEL_DST_DIR DST_DIR "/kernel" #define SYSTEMD_CONFIG_DIR "/loader" #define SYSTEMD_CONFIG SYSTEMD_CONFIG_DIR "/loader.conf" diff --git a/src/lib/bootvar.c b/src/lib/bootvar.c index ba06816..cf67274 100644 --- a/src/lib/bootvar.c +++ b/src/lib/bootvar.c @@ -23,8 +23,8 @@ #include #include #include -#include #include +#include #include #include #include diff --git a/src/lib/bootvar.h b/src/lib/bootvar.h index b245ea4..bf48a62 100644 --- a/src/lib/bootvar.h +++ b/src/lib/bootvar.h @@ -11,8 +11,8 @@ #include -#define EBOOT_VAR_ERR 1 /* general error */ -#define EBOOT_VAR_NOSUP 127 /* EFI vars not supported */ +#define EBOOT_VAR_ERR 1 /* general error */ +#define EBOOT_VAR_NOSUP 127 /* EFI vars not supported */ int bootvar_init(void); void bootvar_destroy(void); diff --git a/src/lib/files.h b/src/lib/files.h index 1042b02..b8f6f05 100644 --- a/src/lib/files.h +++ b/src/lib/files.h @@ -59,9 +59,9 @@ char *get_parent_disk(char *path); char *get_legacy_boot_device(char *path); /** -* Determine if the files match in content by comparing -* their checksums -*/ + * Determine if the files match in content by comparing + * their checksums + */ bool cbm_files_match(const char *p1, const char *p2); /** From 26bbec84c1e82b7fa21bb1c4164ffd9b824a3a09 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Thu, 12 Oct 2017 19:58:56 +0000 Subject: [PATCH 36/38] Use env var to turn off EFI var manipulation. To turn off creation and modification of EFI variable, define environment variable CBM_BOOTVAR_TEST_MODE=yes. --- src/lib/bootvar.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/src/lib/bootvar.c b/src/lib/bootvar.c index cf67274..d0c4ec5 100644 --- a/src/lib/bootvar.c +++ b/src/lib/bootvar.c @@ -38,6 +38,11 @@ * enough. actual space occupied is normally >2 times less. */ #define BOOT_VAR_MAX 1024 +/* env var to turn on the test mode. if set to "yes", turns off any side-effects + * functions defined in this file may have: the call will always succeed without + * side effects. */ +#define CBM_BOOTVAR_TEST_MODE_VAR "CBM_BOOTVAR_TEST_MODE" + typedef struct boot_rec boot_rec_t; struct boot_rec { @@ -50,6 +55,8 @@ struct boot_rec { static boot_rec_t *boot_recs; static int boot_recs_cnt; +static int test_mode = 0; + static void bootvar_free_boot_recs(void) { boot_rec_t *p, *c; @@ -374,6 +381,9 @@ int bootvar_create(const char *esp_mount_path, const char *bootloader_esp_path, long int len; boot_rec_t *rec; + if (test_mode) + return 0; + if (bootvar_get_part_info(esp_mount_path, &pi)) return -1; @@ -422,6 +432,13 @@ int bootvar_create(const char *esp_mount_path, const char *bootloader_esp_path, int bootvar_init(void) { + char *test_mode_env = getenv(CBM_BOOTVAR_TEST_MODE_VAR); + if (test_mode_env && !strncmp(test_mode_env, "yes", 4)) { + LOG_INFO("EFI variables support is disabled: " CBM_BOOTVAR_TEST_MODE_VAR " is set"); + test_mode = 1; + } + if (test_mode) + return 0; if (efi_variables_supported() < 0) return -EBOOT_VAR_NOSUP; if (bootvar_read_boot_recs() < 0) @@ -431,6 +448,8 @@ int bootvar_init(void) void bootvar_destroy(void) { + if (test_mode) + return; bootvar_free_boot_recs(); } From c04f191505bd51f9bf8fbb87aeadea3f54851d1b Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Thu, 12 Oct 2017 20:43:21 +0000 Subject: [PATCH 37/38] Get rid of the bootvar stub. Use CBM_BOOTVAR_TEST_MODE instead in tests. --- Makefile.am | 40 +++++++++------------------------ tests/check-cmdline.c | 3 +++ tests/check-core.c | 3 +++ tests/check-files.c | 3 +++ tests/check-grub2.c | 3 +++ tests/check-legacy.c | 3 +++ tests/check-os-release.c | 3 +++ tests/check-probe.c | 3 +++ tests/check-select-bootloader.c | 3 +++ tests/check-uefi.c | 3 +++ tests/stub/bootvar.c | 39 -------------------------------- 11 files changed, 38 insertions(+), 68 deletions(-) delete mode 100644 tests/stub/bootvar.c diff --git a/Makefile.am b/Makefile.am index 53be198..55794cc 100644 --- a/Makefile.am +++ b/Makefile.am @@ -129,17 +129,11 @@ SOURCE_FILES = \ src/lib/writer.c \ src/lib/util.h \ src/lib/util.c \ - src/lib/bootvar.h - -PROD_SOURCE_FILES = \ + src/lib/bootvar.h \ src/lib/bootvar.c -STUB_SOURCE_FILES = \ - tests/stub/bootvar.c - libcbm_la_SOURCES = \ - $(SOURCE_FILES) \ - $(PROD_SOURCE_FILES) + $(SOURCE_FILES) libcbm_la_CFLAGS = \ -D_BOOTMAN_INTERNAL_ \ @@ -200,18 +194,6 @@ TESTS = \ check_PROGRAMS = $(TESTS) -check_LTLIBRARIES = libcbm-check.la - -libcbm_check_la_SOURCES = \ - $(SOURCE_FILES) \ - $(STUB_SOURCE_FILES) - -libcbm_check_la_CFLAGS = \ - $(libcbm_la_CFLAGS) \ - -DTEST_STUB=1 - -libcbm_check_la_LIBADD = $(libcbm_la_LIBADD) - check_core_SOURCES = \ tests/check-core.c \ tests/blkid-harness.h \ @@ -225,7 +207,7 @@ check_core_CFLAGS = \ $(AM_CFLAGS) check_core_LDADD = \ - libcbm-check.la \ + libcbm.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -241,7 +223,7 @@ check_cmdline_CFLAGS = \ $(AM_CFLAGS) check_cmdline_LDADD = \ - libcbm-check.la \ + libcbm.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -259,7 +241,7 @@ check_files_CFLAGS = \ $(AM_CFLAGS) check_files_LDADD = \ - libcbm-check.la \ + libcbm.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -279,7 +261,7 @@ check_legacy_CFLAGS = \ $(AM_CFLAGS) check_legacy_LDADD = \ - libcbm-check.la \ + libcbm.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -295,7 +277,7 @@ check_os_release_CFLAGS = \ $(AM_CFLAGS) check_os_release_LDADD = \ - libcbm-check.la \ + libcbm.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -315,7 +297,7 @@ check_uefi_CFLAGS = \ $(AM_CFLAGS) check_uefi_LDADD = \ - libcbm-check.la \ + libcbm.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -335,7 +317,7 @@ check_grub2_CFLAGS = \ $(AM_CFLAGS) check_grub2_LDADD = \ - libcbm-check.la \ + libcbm.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -355,7 +337,7 @@ check_select_bootloader_CFLAGS = \ $(AM_CFLAGS) check_select_bootloader_LDADD = \ - libcbm-check.la \ + libcbm.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ @@ -375,7 +357,7 @@ check_probe_CFLAGS = \ $(AM_CFLAGS) check_probe_LDADD = \ - libcbm-check.la \ + libcbm.la \ src/libnica/libnica.la \ -lefiboot \ -lefivar \ diff --git a/tests/check-cmdline.c b/tests/check-cmdline.c index c048b92..3d1f45e 100644 --- a/tests/check-cmdline.c +++ b/tests/check-cmdline.c @@ -134,6 +134,9 @@ int main(void) setenv("CBM_DEBUG", "1", 1); cbm_log_init(stderr); + /* Turn off the EFI variable manipulation. */ + setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1); + s = core_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); diff --git a/tests/check-core.c b/tests/check-core.c index 60c49b5..83f7cd6 100644 --- a/tests/check-core.c +++ b/tests/check-core.c @@ -430,6 +430,9 @@ int main(void) setenv("CBM_DEBUG", "1", 1); cbm_log_init(stderr); + /* Turn off the EFI variable manipulation. */ + setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1); + cbm_blkid_set_vtable(&BlkidTestOps); cbm_system_set_vtable(&SystemTestOps); diff --git a/tests/check-files.c b/tests/check-files.c index 6480c23..f58fdd0 100644 --- a/tests/check-files.c +++ b/tests/check-files.c @@ -110,6 +110,9 @@ int main(void) setenv("CBM_DEBUG", "1", 1); cbm_log_init(stderr); + /* Turn off the EFI variable manipulation. */ + setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1); + s = core_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); diff --git a/tests/check-grub2.c b/tests/check-grub2.c index 4868cf1..1303383 100644 --- a/tests/check-grub2.c +++ b/tests/check-grub2.c @@ -261,6 +261,9 @@ int main(void) setenv("CBM_DEBUG", "1", 1); cbm_log_init(stderr); + /* Turn off the EFI variable manipulation. */ + setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1); + cbm_blkid_set_vtable(&blkid_ops); cbm_system_set_vtable(&SystemTestOps); diff --git a/tests/check-legacy.c b/tests/check-legacy.c index e780fad..e60d115 100644 --- a/tests/check-legacy.c +++ b/tests/check-legacy.c @@ -294,6 +294,9 @@ int main(void) setenv("CBM_DEBUG", "1", 1); cbm_log_init(stderr); + /* Turn off the EFI variable manipulation. */ + setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1); + cbm_blkid_set_vtable(&blkid_ops); cbm_system_set_vtable(&SystemTestOps); diff --git a/tests/check-os-release.c b/tests/check-os-release.c index 954cd4c..583264e 100644 --- a/tests/check-os-release.c +++ b/tests/check-os-release.c @@ -73,6 +73,9 @@ int main(void) setenv("CBM_DEBUG", "1", 1); cbm_log_init(stderr); + /* Turn off the EFI variable manipulation. */ + setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1); + s = core_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); diff --git a/tests/check-probe.c b/tests/check-probe.c index 2aea5a3..a538e53 100644 --- a/tests/check-probe.c +++ b/tests/check-probe.c @@ -241,6 +241,9 @@ int main(void) setenv("CBM_DEBUG", "1", 1); cbm_log_init(stderr); + /* Turn off the EFI variable manipulation. */ + setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1); + s = core_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); diff --git a/tests/check-select-bootloader.c b/tests/check-select-bootloader.c index 96db3d9..946fc20 100644 --- a/tests/check-select-bootloader.c +++ b/tests/check-select-bootloader.c @@ -441,6 +441,9 @@ int main(void) setenv("CBM_DEBUG", "1", 1); cbm_log_init(stderr); + /* Turn off the EFI variable manipulation. */ + setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1); + s = core_suite(); sr = srunner_create(s); srunner_run_all(sr, CK_VERBOSE); diff --git a/tests/check-uefi.c b/tests/check-uefi.c index b748012..8e09e83 100644 --- a/tests/check-uefi.c +++ b/tests/check-uefi.c @@ -453,6 +453,9 @@ int main(void) setenv("CBM_DEBUG", "1", 1); cbm_log_init(stderr); + /* Turn off the EFI variable manipulation. */ + setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1); + cbm_blkid_set_vtable(&BlkidTestOps); cbm_system_set_vtable(&SystemTestOps); diff --git a/tests/stub/bootvar.c b/tests/stub/bootvar.c deleted file mode 100644 index c8649aa..0000000 --- a/tests/stub/bootvar.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * This file is part of clr-boot-manager. - * - * Copyright © 2017 Intel Corporation - * - * 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. - */ - -/* This file is a stub implementing happy src/lib/bootvar.h API. */ - -#include -#include -#include -#include -#include - -int bootvar_init(void) -{ - return 0; -} -void bootvar_destroy(void) -{ - return; -} - -int bootvar_create(const char *mnt_path, const char *bootloader_path, char *name, size_t sz) -{ - (void)mnt_path; - (void)bootloader_path; - static char *stub_name = "Boot0001"; - static size_t len = 8; // strlen(stub_name) - if (name && sz > len) { - snprintf(name, len + 1, "%s", stub_name); - } - return 0; -} From 8f534f0e352796e50074a879c4f2060d5fb6ff95 Mon Sep 17 00:00:00 2001 From: Arzhan Kinzhalin Date: Mon, 16 Oct 2017 09:27:37 +0000 Subject: [PATCH 38/38] Refactor to get rid of _impl functions. --- src/bootloaders/bootloader.h | 6 ++-- src/bootloaders/goofiboot.c | 29 +++++++++--------- src/bootloaders/grub2.c | 3 +- src/bootloaders/gummiboot.c | 29 +++++++++--------- src/bootloaders/shim-systemd.c | 36 +++++++++++----------- src/bootloaders/syslinux.c | 29 +++++++++--------- src/bootloaders/systemd-boot.c | 1 - src/bootloaders/systemd-class.c | 53 +++++++++++---------------------- src/bootloaders/systemd-class.h | 9 +----- src/bootman/kernel.c | 4 +-- tests/harness.c | 4 +-- 11 files changed, 88 insertions(+), 115 deletions(-) diff --git a/src/bootloaders/bootloader.h b/src/bootloaders/bootloader.h index bf92a2b..7441b59 100644 --- a/src/bootloaders/bootloader.h +++ b/src/bootloaders/bootloader.h @@ -21,7 +21,7 @@ typedef bool (*boot_loader_init)(const BootManager *); typedef bool (*boot_loader_install_kernel)(const BootManager *, const Kernel *); -typedef char *(*boot_loader_get_kernel_dst)(const BootManager *); +typedef char *(*boot_loader_get_kernel_destination)(const BootManager *); typedef bool (*boot_loader_remove_kernel)(const BootManager *, const Kernel *); typedef bool (*boot_loader_set_default_kernel)(const BootManager *, const Kernel *kernel); typedef bool (*boot_loader_needs_update)(const BootManager *); @@ -46,8 +46,8 @@ typedef enum { typedef struct BootLoader { const char *name; /**target.path); /* Optional initrd */ if (kernel->target.initrd_path) { cbm_writer_append_printf(writer, "initrd %s/%s\n", - get_kernel_dst(manager), + get_kernel_destination_impl(manager), kernel->target.initrd_path); } /* Add the root= section */ @@ -270,14 +270,6 @@ bool sd_class_install_kernel_impl(const BootManager *manager, const Kernel *kern return true; } -bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel) -{ - return sd_class_install_kernel_impl(manager, - kernel, - sd_class_get_kernel_dst, - sd_class_ensure_dirs); -} - bool sd_class_remove_kernel(const BootManager *manager, const Kernel *kernel) { if (!manager || !kernel) { @@ -303,18 +295,12 @@ bool sd_class_remove_kernel(const BootManager *manager, const Kernel *kernel) return true; } -bool sd_class_set_default_kernel_impl(const BootManager *manager, const Kernel *kernel, - bool (*ensure_layout)(const BootManager *)) +bool sd_class_set_default_kernel(const BootManager *manager, const Kernel *kernel) { if (!manager) { return false; } - if (ensure_layout && !ensure_layout(manager)) { - LOG_FATAL("Failed to create required directories for %s", sd_config->name); - return false; - } - autofree(char) *item_name = NULL; int timeout = 0; const char *prefix = NULL; @@ -370,11 +356,6 @@ write_config: return true; } -bool sd_class_set_default_kernel(const BootManager *manager, const Kernel *kernel) -{ - return sd_class_set_default_kernel_impl(manager, kernel, sd_class_ensure_dirs); -} - bool sd_class_needs_install(const BootManager *manager) { if (!manager) { @@ -429,7 +410,7 @@ bool sd_class_install(const BootManager *manager) return false; } - if (!sd_class_ensure_dirs(manager)) { + if (!sd_class_ensure_dirs()) { LOG_FATAL("Failed to create required directories for %s", sd_config->name); return false; } @@ -464,7 +445,7 @@ bool sd_class_update(const BootManager *manager) if (!manager) { return false; } - if (!sd_class_ensure_dirs(manager)) { + if (!sd_class_ensure_dirs()) { LOG_FATAL("Failed to create required directories for %s", sd_config->name); return false; } diff --git a/src/bootloaders/systemd-class.h b/src/bootloaders/systemd-class.h index 1d90035..64e0ef1 100644 --- a/src/bootloaders/systemd-class.h +++ b/src/bootloaders/systemd-class.h @@ -29,21 +29,14 @@ typedef struct BootLoaderConfig { const char *name; } BootLoaderConfig; -char *sd_class_get_kernel_dst(const BootManager *manager); +char *sd_class_get_kernel_destination(const BootManager *manager); bool sd_class_install_kernel(const BootManager *manager, const Kernel *kernel); -bool sd_class_install_kernel_impl(const BootManager *manager, const Kernel *kernel, - char *(*get_kernel_dst)(const BootManager *), - bool (*ensure_layout)(const BootManager *)); - bool sd_class_remove_kernel(const BootManager *manager, const Kernel *kernel); bool sd_class_set_default_kernel(const BootManager *manager, const Kernel *kernel); -bool sd_class_set_default_kernel_impl(const BootManager *manager, const Kernel *kernel, - bool (*ensure_layout)(const BootManager *)); - bool sd_class_needs_install(const BootManager *manager); bool sd_class_needs_update(const BootManager *manager); diff --git a/src/bootman/kernel.c b/src/bootman/kernel.c index 3c416c4..f881625 100644 --- a/src/bootman/kernel.c +++ b/src/bootman/kernel.c @@ -594,7 +594,7 @@ bool boot_manager_install_kernel_internal(const BootManager *manager, const Kern const char *initrd_source = NULL; int is_uefi = (manager->bootloader->get_capabilities(manager) & BOOTLOADER_CAP_UEFI); autofree(char) *efi_boot_dir = - is_uefi ? manager->bootloader->get_kernel_dst(manager) : NULL; + is_uefi ? manager->bootloader->get_kernel_destination(manager) : NULL; assert(manager != NULL); assert(kernel != NULL); @@ -667,7 +667,7 @@ bool boot_manager_remove_kernel_internal(const BootManager *manager, const Kerne autofree(char) *initrd_target = NULL; int is_uefi = (manager->bootloader->get_capabilities(manager) & BOOTLOADER_CAP_UEFI); autofree(char) *efi_boot_dir = - is_uefi ? manager->bootloader->get_kernel_dst(manager) : NULL; + is_uefi ? manager->bootloader->get_kernel_destination(manager) : NULL; assert(manager != NULL); assert(kernel != NULL); diff --git a/tests/harness.c b/tests/harness.c index 3af1dc4..f8b95b9 100644 --- a/tests/harness.c +++ b/tests/harness.c @@ -478,8 +478,8 @@ int kernel_installed_files_count(BootManager *manager, PlaygroundKernel *kernel) autofree(char) *initrd_file = NULL; autofree(char) *initrd_file_legacy = NULL; /* where the kernel files are expected to be found on the ESP */ - char *esp_path = manager->bootloader->get_kernel_dst - ? manager->bootloader->get_kernel_dst(manager) + char *esp_path = manager->bootloader->get_kernel_destination + ? manager->bootloader->get_kernel_destination(manager) : "efi/" KERNEL_NAMESPACE; const char *vendor = NULL; int file_count = 0;