mirror of
https://github.com/clearlinux/clr-boot-manager.git
synced 2026-06-16 02:35:51 +00:00
bootman: improve filesystem detection
Improve the internal filesystem detection, with these changes we can reuse this code elsewhere and be more efficient - other areas needing the filesystem knowledge can use this mapping strategies adding a more precise and centralized code to that. This patch also makes sure to keep tests and filesystem checks more consistent. When mounting we were assuming the /boot filesystem to always be vfat, with this code now we can have /boot partitions with whatever filesystem we support (for now: vfat, ext[2-4]). Signed-off-by: Leandro Dorileo <leandro.maciel.dorileo@intel.com>
This commit is contained in:
committed by
William Douglas
parent
ef65b290de
commit
486486e19a
@@ -414,6 +414,7 @@ int mount_boot(BootManager *self, char **boot_directory)
|
||||
autofree(char) *boot_dir = NULL;
|
||||
int ret = -1;
|
||||
char *root_base = NULL;
|
||||
const char *fs_name = NULL;
|
||||
|
||||
if (!boot_directory) {
|
||||
goto out;
|
||||
@@ -481,7 +482,12 @@ int mount_boot(BootManager *self, char **boot_directory)
|
||||
}
|
||||
|
||||
LOG_INFO("Mounting boot device %s at %s", root_base, boot_dir);
|
||||
if (cbm_system_mount(root_base, boot_dir, "vfat", MS_MGC_VAL, "") < 0) {
|
||||
|
||||
fs_name = cbm_get_fstype_name(root_base);
|
||||
CHECK_FATAL_GOTO(!fs_name, out, "Could not determine fstype of: %s",
|
||||
root_base);
|
||||
|
||||
if (cbm_system_mount(root_base, boot_dir, fs_name, MS_MGC_VAL, "") < 0) {
|
||||
LOG_FATAL("FATAL: Cannot mount boot device %s on %s: %s",
|
||||
root_base,
|
||||
boot_dir,
|
||||
|
||||
@@ -29,6 +29,13 @@ typedef enum {
|
||||
BOOTLOADER_OPERATION_MAX = 1 << 5
|
||||
} BootLoaderOperation;
|
||||
|
||||
typedef enum {
|
||||
FSTYPE_VFAT = 1 << 0,
|
||||
FSTYPE_EXT2 = 1 << 1,
|
||||
FSTYPE_EXT3 = 1 << 2,
|
||||
FSTYPE_EXT4 = 1 << 3,
|
||||
} FilesystemType;
|
||||
|
||||
/**
|
||||
* Maximum length for each component in a kernel identifier
|
||||
*/
|
||||
|
||||
@@ -74,6 +74,11 @@ int detect_and_mount_boot(BootManager *self, char **boot_dir);
|
||||
*/
|
||||
int kernel_compare_reverse(const void *a, const void *b);
|
||||
|
||||
/**
|
||||
* Given a boot_device returns the filesystem name, if unknown filesystem returns NULL.
|
||||
*/
|
||||
const char *cbm_get_fstype_name(const char *boot_device);
|
||||
|
||||
/*
|
||||
* Editor modelines - https://www.wireshark.org/tools/modelines.html
|
||||
*
|
||||
|
||||
+108
-41
@@ -28,6 +28,30 @@
|
||||
|
||||
#define CBM_BOOTVAR_TEST_MODE_VAR "CBM_BOOTVAR_TEST_MODE"
|
||||
|
||||
struct FilesystemMap {
|
||||
char *name;
|
||||
int id;
|
||||
};
|
||||
|
||||
static const struct FilesystemMap _fsmap[] = {
|
||||
{
|
||||
.id = FSTYPE_VFAT,
|
||||
.name = "vfat",
|
||||
},
|
||||
{
|
||||
.id = FSTYPE_EXT2,
|
||||
.name = "ext2",
|
||||
},
|
||||
{
|
||||
.id = FSTYPE_EXT3,
|
||||
.name = "ext3",
|
||||
},
|
||||
{
|
||||
.id = FSTYPE_EXT4,
|
||||
.name = "ext4",
|
||||
},
|
||||
};
|
||||
|
||||
void cbm_free_sysconfig(SystemConfig *config)
|
||||
{
|
||||
if (!config) {
|
||||
@@ -39,51 +63,94 @@ void cbm_free_sysconfig(SystemConfig *config)
|
||||
free(config);
|
||||
}
|
||||
|
||||
int cbm_get_fstype(const char *boot_device)
|
||||
static const struct FilesystemMap *cbm_find_fstype(const char *fsname)
|
||||
{
|
||||
int rc;
|
||||
blkid_probe pr;
|
||||
const char *data;
|
||||
int ret = 0;
|
||||
int i;
|
||||
int length = sizeof(_fsmap) / sizeof(struct FilesystemMap);
|
||||
|
||||
for (i = 0; i < length; i++) {
|
||||
const struct FilesystemMap *curr = &_fsmap[i];
|
||||
if (!strcmp(curr->name, fsname)) {
|
||||
return curr;
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static const struct FilesystemMap *cbm_get_fstype(const char *boot_device)
|
||||
{
|
||||
autofree(char) *fsname = NULL;
|
||||
const struct FilesystemMap *fs;
|
||||
|
||||
/* Test suite will set the CBM_TEST_FSTYPE env var and inform the wanted fstype */
|
||||
char *test_mode_fs_type_env = getenv("CBM_TEST_FSTYPE");
|
||||
if (test_mode_fs_type_env && !strncmp(test_mode_fs_type_env, "EXTFS", 5)) {
|
||||
return BOOTLOADER_CAP_EXTFS;
|
||||
} else if (test_mode_fs_type_env && !strncmp(test_mode_fs_type_env, "FATFS", 5)) {
|
||||
fsname = getenv("CBM_TEST_FSTYPE");
|
||||
if (fsname) {
|
||||
fsname = strdup(fsname);
|
||||
} else {
|
||||
int rc;
|
||||
blkid_probe pr;
|
||||
const char *tmp;
|
||||
|
||||
pr = blkid_new_probe_from_filename(boot_device);
|
||||
if (!pr) {
|
||||
LOG_ERROR("%s: failed to create a new libblkid probe",
|
||||
boot_device);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_TYPE);
|
||||
rc = blkid_do_safeprobe(pr);
|
||||
if (rc != 0) {
|
||||
LOG_ERROR("%s: blkid_do_safeprobe() failed", boot_device);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
rc = blkid_probe_lookup_value(pr, "TYPE", &tmp, NULL);
|
||||
if (rc != 0 || tmp == NULL || strlen(tmp) == 0) {
|
||||
LOG_ERROR("%s: blkid_probe_lookup_value() failed", boot_device);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
fsname = strdup(tmp);
|
||||
if (fsname == NULL) {
|
||||
DECLARE_OOM();
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
blkid_free_probe(pr);
|
||||
}
|
||||
|
||||
fs = cbm_find_fstype(fsname);
|
||||
CHECK_DBG_RET_VAL(!fs, NULL, "Failed to find fstype for: %s(%s)", boot_device, fsname);
|
||||
|
||||
return fs;
|
||||
}
|
||||
|
||||
const char *cbm_get_fstype_name(const char *boot_device)
|
||||
{
|
||||
const struct FilesystemMap *fs = cbm_get_fstype(boot_device);
|
||||
CHECK_DBG_RET_VAL(!fs, NULL, "Unknown Filesystem of: %s", boot_device);
|
||||
return fs->name;
|
||||
}
|
||||
|
||||
int cbm_get_filesystem_cap(const char *boot_device)
|
||||
{
|
||||
const struct FilesystemMap *fs = NULL;
|
||||
|
||||
fs = cbm_get_fstype(boot_device);
|
||||
CHECK_DBG_RET_VAL(!fs, 0, "Could not find filesystem map for: %s", boot_device);
|
||||
|
||||
switch (fs->id) {
|
||||
case FSTYPE_VFAT:
|
||||
return BOOTLOADER_CAP_FATFS;
|
||||
case FSTYPE_EXT2:
|
||||
case FSTYPE_EXT3:
|
||||
case FSTYPE_EXT4:
|
||||
return BOOTLOADER_CAP_EXTFS;
|
||||
default:
|
||||
return 0;
|
||||
}
|
||||
|
||||
pr = blkid_new_probe_from_filename(boot_device);
|
||||
if (!pr) {
|
||||
LOG_ERROR("%s: failed to create a new libblkid probe",
|
||||
boot_device);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
blkid_probe_set_superblocks_flags(pr, BLKID_SUBLKS_TYPE);
|
||||
rc = blkid_do_safeprobe(pr);
|
||||
if (rc != 0) {
|
||||
LOG_ERROR("%s: blkid_do_safeprobe() failed", boot_device);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
rc = blkid_probe_lookup_value(pr, "TYPE", &data, NULL);
|
||||
if (rc != 0) {
|
||||
LOG_ERROR("%s: blkid_probe_lookup_value() failed", boot_device);
|
||||
exit(EXIT_FAILURE);
|
||||
}
|
||||
|
||||
if ((strcmp(data, "ext2") == 0) ||
|
||||
(strcmp(data, "ext3") == 0) ||
|
||||
(strcmp(data, "ext4") == 0))
|
||||
ret = BOOTLOADER_CAP_EXTFS;
|
||||
else if (strcmp(data, "vfat") == 0)
|
||||
ret = BOOTLOADER_CAP_FATFS;
|
||||
|
||||
blkid_free_probe(pr);
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static void cmb_inspect_root_native(SystemConfig *c, char *realp) {
|
||||
@@ -189,7 +256,7 @@ SystemConfig *cbm_inspect_root(const char *path, bool image_mode)
|
||||
c->wanted_boot_mask |= BOOTLOADER_CAP_GPT;
|
||||
|
||||
/* determine fstype of the boot_device */
|
||||
c->wanted_boot_mask |= cbm_get_fstype(c->boot_device);
|
||||
c->wanted_boot_mask |= cbm_get_filesystem_cap(c->boot_device);
|
||||
}
|
||||
|
||||
c->root_device = cbm_probe_path(realp);
|
||||
|
||||
+1
-1
@@ -434,7 +434,7 @@ int main(void)
|
||||
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
|
||||
|
||||
/* Force detection of `fat` filesystem. */
|
||||
setenv("CBM_TEST_FSTYPE", "FATFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "vfat", 1);
|
||||
|
||||
cbm_blkid_set_vtable(&BlkidTestOps);
|
||||
cbm_system_set_vtable(&SystemTestOps);
|
||||
|
||||
+1
-1
@@ -265,7 +265,7 @@ int main(void)
|
||||
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
|
||||
|
||||
/* Force detection of `ext` filesystem. */
|
||||
setenv("CBM_TEST_FSTYPE", "EXTFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "ext4", 1);
|
||||
|
||||
cbm_blkid_set_vtable(&blkid_ops);
|
||||
cbm_system_set_vtable(&SystemTestOps);
|
||||
|
||||
@@ -304,7 +304,7 @@ int main(void)
|
||||
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
|
||||
|
||||
/* Force detection of `ext` filesystem. */
|
||||
setenv("CBM_TEST_FSTYPE", "EXTFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "ext4", 1);
|
||||
|
||||
cbm_blkid_set_vtable(&blkid_ops);
|
||||
cbm_system_set_vtable(&SystemTestOps);
|
||||
|
||||
+1
-1
@@ -245,7 +245,7 @@ int main(void)
|
||||
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
|
||||
|
||||
/* Force detection of `fat` filesystem. */
|
||||
setenv("CBM_TEST_FSTYPE", "FATFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "vfat", 1);
|
||||
|
||||
s = core_suite();
|
||||
sr = srunner_create(s);
|
||||
|
||||
@@ -104,7 +104,7 @@ static void nuke_boot_device(struct PlaygroundConfig *config)
|
||||
START_TEST(bootman_select_uefi_native_with_boot)
|
||||
{
|
||||
static PlaygroundConfig config = { "4.2.1-121.kvm", NULL, 0, .uefi = true };
|
||||
setenv("CBM_TEST_FSTYPE", "FATFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "vfat", 1);
|
||||
autofree(BootManager) *m = NULL;
|
||||
bootman_select_set_default_vtables();
|
||||
|
||||
@@ -119,7 +119,7 @@ END_TEST
|
||||
START_TEST(bootman_select_uefi_native_without_boot)
|
||||
{
|
||||
static PlaygroundConfig config = { "4.2.1-121.kvm", NULL, 0, .uefi = true };
|
||||
setenv("CBM_TEST_FSTYPE", "FATFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "vfat", 1);
|
||||
autofree(BootManager) *m = NULL;
|
||||
bootman_select_set_default_vtables();
|
||||
|
||||
@@ -138,7 +138,7 @@ END_TEST
|
||||
START_TEST(bootman_select_uefi_image_with_boot)
|
||||
{
|
||||
static PlaygroundConfig config = { "4.2.1-121.kvm", NULL, 0, .uefi = true };
|
||||
setenv("CBM_TEST_FSTYPE", "FATFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "vfat", 1);
|
||||
autofree(BootManager) *m = NULL;
|
||||
bootman_select_set_default_vtables();
|
||||
|
||||
@@ -156,7 +156,7 @@ END_TEST
|
||||
START_TEST(bootman_select_uefi_image_without_boot)
|
||||
{
|
||||
static PlaygroundConfig config = { "4.2.1-121.kvm", NULL, 0, .uefi = true };
|
||||
setenv("CBM_TEST_FSTYPE", "FATFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "vfat", 1);
|
||||
autofree(BootManager) *m = NULL;
|
||||
bootman_select_set_default_vtables();
|
||||
|
||||
@@ -240,7 +240,7 @@ static void bootman_select_set_legacy_vtables(void)
|
||||
START_TEST(bootman_select_extlinux_native_with_boot)
|
||||
{
|
||||
PlaygroundConfig config = { "4.2.1-121.kvm", NULL, 0, .uefi = false };
|
||||
setenv("CBM_TEST_FSTYPE", "EXTFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "ext4", 1);
|
||||
autofree(BootManager) *m = NULL;
|
||||
bootman_select_set_legacy_vtables();
|
||||
|
||||
@@ -255,7 +255,7 @@ END_TEST
|
||||
START_TEST(bootman_select_extlinux_image_with_boot)
|
||||
{
|
||||
PlaygroundConfig config = { "4.2.1-121.kvm", NULL, 0, .uefi = false };
|
||||
setenv("CBM_TEST_FSTYPE", "EXTFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "ext4", 1);
|
||||
autofree(BootManager) *m = NULL;
|
||||
bootman_select_set_legacy_vtables();
|
||||
|
||||
@@ -330,7 +330,7 @@ static void bootman_select_set_grub2_vtables(void)
|
||||
START_TEST(bootman_select_grub2_native_without_boot)
|
||||
{
|
||||
static PlaygroundConfig config = { "4.2.1-121.kvm", NULL, 0, .uefi = false };
|
||||
setenv("CBM_TEST_FSTYPE", "EXTFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "ext4", 1);
|
||||
autofree(BootManager) *m = NULL;
|
||||
bootman_select_set_grub2_vtables();
|
||||
|
||||
@@ -355,7 +355,7 @@ END_TEST
|
||||
START_TEST(bootman_select_edge_uefi_with_legacy_part_native)
|
||||
{
|
||||
static PlaygroundConfig config = { "4.2.1-121.kvm", NULL, 0, .uefi = false };
|
||||
setenv("CBM_TEST_FSTYPE", "EXTFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "ext4", 1);
|
||||
autofree(BootManager) *m = NULL;
|
||||
bootman_select_set_legacy_vtables();
|
||||
|
||||
@@ -378,7 +378,7 @@ END_TEST
|
||||
START_TEST(bootman_select_edge_uefi_with_legacy_part_image)
|
||||
{
|
||||
static PlaygroundConfig config = { "4.2.1-121.kvm", NULL, 0, .uefi = false };
|
||||
setenv("CBM_TEST_FSTYPE", "EXTFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "ext4", 1);
|
||||
autofree(BootManager) *m = NULL;
|
||||
bootman_select_set_legacy_vtables();
|
||||
|
||||
|
||||
@@ -304,7 +304,7 @@ int main(void)
|
||||
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
|
||||
|
||||
/* Force detection of `ext` filesystem. */
|
||||
setenv("CBM_TEST_FSTYPE", "EXTFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "ext4", 1);
|
||||
|
||||
cbm_blkid_set_vtable(&blkid_ops);
|
||||
cbm_system_set_vtable(&SystemTestOps);
|
||||
|
||||
+1
-1
@@ -638,7 +638,7 @@ int main(void)
|
||||
setenv("CBM_BOOTVAR_TEST_MODE", "yes", 1);
|
||||
|
||||
/* Force detection of `fat` filesystem. */
|
||||
setenv("CBM_TEST_FSTYPE", "FATFS", 1);
|
||||
setenv("CBM_TEST_FSTYPE", "vfat", 1);
|
||||
|
||||
cbm_blkid_set_vtable(&BlkidTestOps);
|
||||
cbm_system_set_vtable(&SystemTestOps);
|
||||
|
||||
Reference in New Issue
Block a user