Re-enable nice automated formatting.

This commit is contained in:
Arzhan Kinzhalin
2017-09-19 18:49:02 +00:00
parent d842826819
commit d1f96a4bbd
11 changed files with 344 additions and 220 deletions
+1
View File
@@ -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
+4 -3
View File
@@ -44,9 +44,10 @@ typedef enum {
* Virtual BootLoader provider
*/
typedef struct BootLoader {
const char *name; /**<Name of the implementation */
boot_loader_init init; /**<Init function */
boot_loader_get_kernel_dst get_kernel_dst; /**<Get location where bootloader expects the kernels to reside */
const char *name; /**<Name of the implementation */
boot_loader_init init; /**<Init function */
boot_loader_get_kernel_dst
get_kernel_dst; /**<Get location where bootloader expects the kernels to reside */
boot_loader_install_kernel install_kernel; /**<Install a given kernel */
boot_loader_remove_kernel remove_kernel; /**<Remove a given kernel */
boot_loader_set_default_kernel set_default_kernel; /**<Set the default kernel */
+15 -16
View File
@@ -536,22 +536,21 @@ int grub2_get_capabilities(__cbm_unused__ const BootManager *manager)
return BOOTLOADER_CAP_LEGACY;
}
__cbm_export__ const BootLoader grub2_bootloader = {
.name = "grub2",
.init = grub2_init,
.get_kernel_dst = NULL, /* kernel directory only needed for EFI
booloaders */
.install_kernel = grub2_install_kernel,
.remove_kernel = grub2_remove_kernel,
.set_default_kernel = grub2_set_default_kernel,
.needs_install = grub2_needs_install,
.needs_update = grub2_needs_update,
.install = grub2_install,
.update = grub2_update,
.remove = grub2_remove,
.destroy = grub2_destroy,
.get_capabilities = grub2_get_capabilities
};
__cbm_export__ const BootLoader grub2_bootloader = {.name = "grub2",
.init = grub2_init,
.get_kernel_dst = NULL, /* kernel directory only
needed for EFI
booloaders */
.install_kernel = grub2_install_kernel,
.remove_kernel = grub2_remove_kernel,
.set_default_kernel = grub2_set_default_kernel,
.needs_install = grub2_needs_install,
.needs_update = grub2_needs_update,
.install = grub2_install,
.update = grub2_update,
.remove = grub2_remove,
.destroy = grub2_destroy,
.get_capabilities = grub2_get_capabilities };
/*
* Editor modelines - https://www.wireshark.org/tools/modelines.html
+114 -70
View File
@@ -64,154 +64,196 @@ 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 int shim_systemd_get_capabilities(const BootManager *manager);
__cbm_export__ const BootLoader shim_systemd_bootloader = {
.name = "systemd",
.init = shim_systemd_init,
.get_kernel_dst = shim_systemd_get_kernel_dst,
.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
};
__cbm_export__ const BootLoader
shim_systemd_bootloader = {.name = "systemd",
.init = shim_systemd_init,
.get_kernel_dst = shim_systemd_get_kernel_dst,
.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"
#define EFI_SUFFIX "x64.efi"
#else
# define EFI_SUFFIX "ia32.efi"
#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_SRC_DIR "/" "systemd-boot" EFI_SUFFIX
#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 "/loader"
#define SYSTEMD_CONFIG SYSTEMD_CONFIG_DIR "/loader.conf"
#define SYSTEMD_ENTRIES SYSTEMD_CONFIG_DIR "/entries"
#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_SRC_DIR \
"/" \
"systemd-boot" EFI_SUFFIX
#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 "/loader"
#define SYSTEMD_CONFIG SYSTEMD_CONFIG_DIR "/loader.conf"
#define SYSTEMD_ENTRIES SYSTEMD_CONFIG_DIR "/entries"
static char *shim_src;
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 *shim_dst_esp; /* absolute location of shim on the ESP. */
static char *systemd_src;
static char *systemd_dst_host;
static char *shim_systemd_get_kernel_dst(const BootManager *manager) {
static char *shim_systemd_get_kernel_dst(const BootManager *manager)
{
(void)manager;
return strdup(KERNEL_DST_DIR);
}
static bool shim_systemd_install_kernel(const BootManager *manager, const Kernel *kernel) {
static bool shim_systemd_install_kernel(const BootManager *manager, const Kernel *kernel)
{
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) {
static bool shim_systemd_remove_kernel(const BootManager *manager, const Kernel *kernel)
{
return sd_class_remove_kernel(manager, kernel);
}
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)
{
/* 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) {
if (!nc_file_exists(path)) return false;
if (spath && !cbm_files_match(path, spath)) return false;
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_install(const BootManager *manager) {
static bool shim_systemd_needs_install(const BootManager *manager)
{
(void)manager;
if (!exists_identical(shim_dst_host, NULL)) return true;
if (!exists_identical(systemd_dst_host, 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) {
static bool shim_systemd_needs_update(const BootManager *manager)
{
(void)manager;
if (!exists_identical(shim_dst_host, shim_src)) return true;
if (!exists_identical(systemd_dst_host, 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(const BootManager *manager) {
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))
return false;
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))
return false;
snprintf(path, PATH_MAX, "%s%s", boot_root, SYSTEMD_ENTRIES);
if (!nc_mkdir_p(path, 00755)) return false;
if (!nc_mkdir_p(path, 00755))
return false;
return true;
}
static bool shim_systemd_install(const BootManager *manager) {
static bool shim_systemd_install(const BootManager *manager)
{
char varname[9];
(void)manager;
if (!make_layout(manager)) 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;
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(BOOT_DIRECTORY, shim_dst_esp, varname, 9)) return false;
if (bootvar_create(BOOT_DIRECTORY, shim_dst_esp, varname, 9))
return false;
return true;
}
static bool shim_systemd_update(const BootManager *manager) {
static bool shim_systemd_update(const BootManager *manager)
{
return shim_systemd_install(manager);
}
static bool shim_systemd_remove(const BootManager *manager) {
static bool shim_systemd_remove(const BootManager *manager)
{
(void)manager;
fprintf(stderr, "%s is not implemented\n", __func__);
return true;
}
static bool shim_systemd_init(const BootManager *manager) {
static bool shim_systemd_init(const BootManager *manager)
{
size_t len;
char *prefix,
*boot_root;
char *prefix, *boot_root;
if (bootvar_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
* 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"
};
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';
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;
}
+15 -17
View File
@@ -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
+12 -8
View File
@@ -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)
+3 -3
View File
@@ -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);
+22 -12
View File
@@ -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 */
+128 -66
View File
@@ -14,15 +14,15 @@
#include <endian.h>
/* 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 <alloca.h>
#include <blkid.h>
#include <ctype.h>
#include <efiboot.h>
#include <efi.h>
#include <efiboot.h>
#include <efilib.h>
#include <efivar.h>
#include <stdio.h>
@@ -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();
}
+23 -20
View File
@@ -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;
+7 -5
View File
@@ -12,20 +12,22 @@
/* This file is a stub implementing happy src/lib/bootvar.h API. */
#include <bootvar.h>
#include <ctype.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
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";