installer: Bind-mount /sys/firmware/efi/efivars into chroot

Signed-off-by: Michael Tremer <michael.tremer@ipfire.org>
Acked-by: Peter Müller <peter.mueller@ipfire.org>
This commit is contained in:
Michael Tremer
2021-11-04 09:05:54 +00:00
committed by Peter Müller
parent 27944cdc4a
commit ced15fdfaf
3 changed files with 78 additions and 39 deletions

View File

@@ -46,13 +46,6 @@
#include "hw.h" #include "hw.h"
const char* other_filesystems[] = {
"/dev",
"/proc",
"/sys",
NULL
};
static int system_chroot(const char* output, const char* path, const char* cmd) { static int system_chroot(const char* output, const char* path, const char* cmd) {
char chroot_cmd[STRING_SIZE]; char chroot_cmd[STRING_SIZE];
@@ -149,14 +142,53 @@ int hw_mount(const char* source, const char* target, const char* fs, int flags)
return mount(source, target, fs, flags, NULL); return mount(source, target, fs, flags, NULL);
} }
int hw_umount(const char* target) { static int hw_bind_mount(const char* source, const char* prefix) {
int r = umount2(target, 0); if (!source || !prefix) {
errno = EINVAL;
return 1;
}
if (r && errno == EBUSY) { char target[PATH_MAX];
// Give it a moment to settle int r;
sleep(1);
r = umount2(target, MNT_FORCE); // Format target
r = snprintf(target, sizeof(target) - 1, "%s/%s", prefix, source);
if (r < 0)
return 1;
// Ensure target exists
mkdir(target, S_IRWXU|S_IRWXG|S_IRWXO);
return hw_mount(source, target, NULL, MS_BIND);
}
int hw_umount(const char* source, const char* prefix) {
char target[PATH_MAX];
int r;
if (prefix)
r = snprintf(target, sizeof(target) - 1, "%s/%s", prefix, source);
else
r = snprintf(target, sizeof(target) - 1, "%s", source);
if (r < 0)
return r;
// Perform umount
r = umount2(target, 0);
if (r) {
switch (errno) {
// Try again with force if umount wasn't successful
case EBUSY:
sleep(1);
r = umount2(target, MNT_FORCE);
break;
// target wasn't a mountpoint. Ignore.
case EINVAL:
r = 0;
break;
}
} }
return r; return r;
@@ -174,7 +206,7 @@ static int hw_test_source_medium(const char* path) {
ret = access(SOURCE_TEST_FILE, R_OK); ret = access(SOURCE_TEST_FILE, R_OK);
// Umount the test device. // Umount the test device.
hw_umount(SOURCE_MOUNT_PATH); hw_umount(SOURCE_MOUNT_PATH, NULL);
return ret; return ret;
} }
@@ -881,20 +913,21 @@ int hw_mount_filesystems(struct hw_destination* dest, const char* prefix) {
} }
// bind-mount misc filesystems // bind-mount misc filesystems
char** otherfs = other_filesystems; r = hw_bind_mount("/dev", prefix);
while (*otherfs) { if (r)
snprintf(target, sizeof(target), "%s%s", prefix, *otherfs); return r;
mkdir(target, S_IRWXU|S_IRWXG|S_IRWXO); r = hw_bind_mount("/proc", prefix);
r = hw_mount(*otherfs, target, NULL, MS_BIND); if (r)
if (r) { return r;
hw_umount_filesystems(dest, prefix);
return r; r = hw_bind_mount("/sys", prefix);
} if (r)
return r;
otherfs++; r = hw_bind_mount("/sys/firmware/efi/efivars", prefix);
} if (r && errno != ENOENT)
return r;
return 0; return 0;
} }
@@ -908,16 +941,14 @@ int hw_umount_filesystems(struct hw_destination* dest, const char* prefix) {
// ESP // ESP
if (*dest->part_boot_efi) { if (*dest->part_boot_efi) {
snprintf(target, sizeof(target), "%s%s", prefix, HW_PATH_BOOT_EFI); r = hw_umount(HW_PATH_BOOT_EFI, prefix);
r = hw_umount(target);
if (r) if (r)
return -1; return -1;
} }
// boot // boot
if (*dest->part_boot) { if (*dest->part_boot) {
snprintf(target, sizeof(target), "%s%s", prefix, HW_PATH_BOOT); r = hw_umount(HW_PATH_BOOT, prefix);
r = hw_umount(target);
if (r) if (r)
return -1; return -1;
} }
@@ -928,16 +959,24 @@ int hw_umount_filesystems(struct hw_destination* dest, const char* prefix) {
} }
// misc filesystems // misc filesystems
char** otherfs = other_filesystems; r = hw_umount("/sys/firmware/efi/efivars", prefix);
while (*otherfs) { if (r)
snprintf(target, sizeof(target), "%s%s", prefix, *otherfs++); return -1;
r = hw_umount(target);
if (r) r = hw_umount("/sys", prefix);
return -1; if (r)
} return -1;
r = hw_umount("/proc", prefix);
if (r)
return -1;
r = hw_umount("/dev", prefix);
if (r)
return -1;
// root // root
r = hw_umount(prefix); r = hw_umount(prefix, NULL);
if (r) if (r)
return -1; return -1;

View File

@@ -108,7 +108,7 @@ struct hw* hw_init();
void hw_free(struct hw* hw); void hw_free(struct hw* hw);
int hw_mount(const char* source, const char* target, const char* fs, int flags); int hw_mount(const char* source, const char* target, const char* fs, int flags);
int hw_umount(const char* target); int hw_umount(const char* source, const char* prefix);
char* hw_find_source_medium(struct hw* hw); char* hw_find_source_medium(struct hw* hw);

View File

@@ -909,7 +909,7 @@ int main(int argc, char *argv[]) {
} }
// Umount source drive and eject // Umount source drive and eject
hw_umount(SOURCE_MOUNT_PATH); hw_umount(SOURCE_MOUNT_PATH, NULL);
// Free downloaded ISO image // Free downloaded ISO image
if (strcmp(sourcedrive, SOURCE_TEMPFILE) == 0) { if (strcmp(sourcedrive, SOURCE_TEMPFILE) == 0) {