mirror of
https://github.com/clearlinux/clr-boot-manager.git
synced 2026-08-27 08:55:51 +00:00
Add diagnostics and err handling for shim/systemd.
This commit is contained in:
@@ -18,6 +18,7 @@
|
||||
#include "bootvar.h"
|
||||
#include "config.h"
|
||||
#include "files.h"
|
||||
#include <log.h>
|
||||
#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);
|
||||
|
||||
+81
-30
@@ -11,6 +11,8 @@
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include "bootvar.h"
|
||||
|
||||
#include <endian.h>
|
||||
/* Workaround for using --std=c11 in CBM. Provide "relaxed" defines which efivar
|
||||
* expects. */
|
||||
@@ -21,10 +23,12 @@
|
||||
#include <alloca.h>
|
||||
#include <blkid.h>
|
||||
#include <ctype.h>
|
||||
#include <efi.h>
|
||||
#include <efiboot.h>
|
||||
#include <efi.h>
|
||||
#include <efilib.h>
|
||||
#include <efivar.h>
|
||||
#include <errno.h>
|
||||
#include <log.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -11,6 +11,9 @@
|
||||
|
||||
#include <stdlib.h>
|
||||
|
||||
#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);
|
||||
|
||||
Reference in New Issue
Block a user