#2705 PR merged
: minimal changes needed for hybrid boot (bios+uefi)¶
Labels: enhancement
, cleanup
, fixed / solved / done
,
hacktoberfest-accepted
DEvil0000 opened issue at 2021-10-29 16:35:¶
- Type: New Feature / Enhancement
- Impact: Normal
- Reference to related issue (URL): #2698
- How was this pull request tested?
created with the following config on a BIOS machine:
OUTPUT=USB
BACKUP=BORG
USB_DEVICE=/dev/disk/by-label/REAR-000
USB_DEVICE_FILESYSTEM_LABEL=REAR-000
USB_DEVICE_PARTED_LABEL=gpt
USB_DEVICE_FILESYSTEM=ext4
USB_UEFI_PART_SIZE="512"
CLONE_USERS=(root)
CLONE_GROUPS=(root)
CLONE_ALL_USERS_GROUPS="false"
BORGBACKUP_REPO="/borg"
BORGBACKUP_UMASK="0002"
BORGBACKUP_ENC_TYPE="repokey"
export BORG_RELOCATED_REPO_ACCESS_IS_OK="yes"
export BORG_UNKNOWN_UNENCRYPTED_REPO_ACCESS_IS_OK="yes"
export TMPDIR="/wsp_var/tmp/"
USE_RESOLV_CONF="no"
USE_DHCLIENT=no
USE_STATIC_NETWORKING=1
USE_SERIAL_CONSOLE=y
COPY_KERNEL_PARAMETERS=( 'net.ifnames' 'biosdevname', 'console' )
REAR_INITRD_COMPRESSION="fast"
USING_UEFI_BOOTLOADER=1
OUTPUT_URL=usb:///dev/disk/by-label/REARBOOT
USB_BOOTLOADER=grub
GRUB2_DEFAULT_BOOT="1"
USB_BOOT_PART_SIZE="2048"
MODULES=( 'no_modules' )
FIRMWARE_FILES=( 'no' )
EXCLUDE_RUNTIME_LOGFILE="yes"
SERIAL_CONSOLE_DEVICES="/dev/ttyS0"
tested boot on PCEngines APU2 (BIOS) and HP gen9 UEFI.
-
Brief description of the changes in this pull request:
As discussed in #2698 this is a startingpoint for implementing a hybrid boot supporting BIOS and UEFI from the same media. -
prerequisit:
For this to work you must have the following packages installed:grub-efi-amd64-bin
andgrub-pc-bin
. They will install the grub binaries needed for efi and bios boot installation. Don't confuse those packages withgrub-efi
,grub-efi-amd64
andgrub-pc
which configure the systems primary boot option and they conflict the other one for a reason I don't quite get. (this is on ubuntu 20.04) -
format command change
In addition to the --efi format switch I added a --bios switch. If none is given it will do a hybrid installation. -
more details:
This is more like a minimal changeset and prrof of concept but not a full featured or super clean PR.
Since realizing how this is done inRAWDISK
(basically a complete rewrite bypassing lib code and features) and thatRAWDISK
does use syslinux but not grub (with which I am more familiar) I decided to ignore theRAWDISK
for the moment.
I mostly rearanged the code in 300_format_usb_disk.sh without changing much beside checking the --efi/--bios switches. There are however two fixes to mention: 1) setting esp with parted for EFI to have the correct partition type set. 2) using partprobe more offten to make sure data gets written to the correct locations. I think this code change is very clean.
The code change in 850_save_sysfs_uefi_vars.sh is a bit more hacky and you may want to do this differently.
I did not change output/USB/Linux-i386/300_create_grub.sh for the moment since it was not strictly needed but it may be better to install the grub efi binary withgrub-install --efi-directory=<path> --target=x86_64-efi --recheck <device>
instead of the way done in 850_save_sysfs_uefi_vars.sh and such. -
future work:
-
while working on this I realized once more that the same basic stuff like partitioning, formatting, writing bootloaders and boot config is written multiple times in the code base and basically every workflow and output method has its own rewrites instead of using some common lib code for those things. I think a major cleanup of those things would make perfect sense. Maybe starting with the partitioning code - moving in a library script and creating functions out of it.
- Also testing is very time consuming and a bit of a pain due to all those options and combinations. Maybe it would be a good idea to use some build/test server. For example by adding travis jobs or such.
- Since I only did the work for
output=USB
andGRUB
it may make sense to add this feature to all variants or deprecate some of those. Also keep in mind that GRUB could mount a ISO image and boot from there (stored on boot partition / where the kernel and initrd is stored). - When using Serial tty and non Serial tty machines the grub config is at the moment not flexible enough to provide both options. One with ttyS0 and one entry with just tty. This issue may occur everywhere a tty is used in some sort. So thats also some feature or more flexibiliy to consider adding.
Of course I would like to see a merge and the hacktoberfest-accepted
label ;)
I am aware that this PR is not touching all config variants and is maybe
not super clean. A complete integration on all configuration variants
would however mean a quite big change.
edit: please note that there is no 32bit grub efi I know of but it may exist
jsmeix commented at 2021-11-02 08:11:¶
@DEvil0000
thank you for your enhancement and cleanup work.
It is much appreciated!
I will test it soon...
jsmeix commented at 2021-11-02 08:54:¶
I think the reason why in ReaR same functionality is implemented
several times in separated code instead of using common library
functions
is that contributions happen this way.
I think this is because for an individual contributor it is simpler
and more straightforward to implement what he specifically needs
in his own separated code than to adapt and enhance already existing
code
because the latter may cause regressions in special cases of the
existing code
or in areas of the existing code where the current contributor has no
good knowledge
in particular when the existing code is not well documented so the
current contributor
cannot fully understand why existing code is as is so he better does not
touch it,
cf.
https://github.com/rear/rear/wiki/Coding-Style
Also we ReaR uspream maintainers usually don't have sufficient
knowledge
in all those various different areas what ReaR is about (we are not
better
than any other contributor) to be able to make generic common
functions
from various code pieces that do not have regressions or shortcomings.
In particular we can not at all test all the possible cases of existing
code
so in general we don't touch existing code unless we must.
Simply put: There is no "master mind" who could clean it all up.
I think in the end we must accept that in practice
ReaR's code as a whole cannot be clean,
cf. "Dirty hacks welcome" in
https://github.com/rear/rear/wiki/Coding-Style
This does not mean that certain parts of ReaR's code cannot be cleaned
up.
It is only meant to explain why ReaR's code is not clean by default.
It is a lot of laborious work to make code clean.
Here a quotation from a colleague at SUSE
where I do 100% agree:
If you look at things from an evolutionary point of view
the solution that works good enough while consuming
least amount of resources wins.
It does not have to be perfect, or even good,
just as good or better than alternatives.
And here I think is the biggest strength of Linux, the pragmatism,
we try out things and keep these that work well enough.
In that sense Linux is full of ugly hacks that, in the end,
resemble how biological systems are structured.
Sure it's hell to maintain, it's complex, we are unable to
build an abstract model the system and reason about it,
but in the end it does the job.
Sometimes I wonder if this is unevitable property
of the universe we live in.
Maybe you can't have nice and clean system
that is efficient enough.
DEvil0000 commented at 2021-11-02 10:59:¶
@jsmeix I was not asking why it is like it is but more pointing out arear where things can or should improve. Maybe it is a good iead to track such things in tickets and assign a milestone. Maybe lable them as "help welcome" or such.
jsmeix commented at 2021-11-02 13:12:¶
I tested it as far as I currently use a USB disk:
On my homeoffice laptop
with UEFI in legacy BIOS mode
and a USB disk as /dev/sdb
with this etc/rear/local.conf
FIRMWARE_FILES=( 'no' )
MODULES=( 'loaded_modules' )
PROGRESS_MODE="plain"
PROGRESS_WAIT_SECONDS="3"
SSH_ROOT_PASSWORD="rear"
OUTPUT=USB
USB_DEVICE_FILESYSTEM_PERCENTAGE=10
USB_DEVICE_FILESYSTEM_LABEL='MY-DATA'
USB_BOOT_PART_SIZE=1024
USB_BOOTLOADER="grub"
USB_DEVICE_BOOT_LABEL=MY-BOOT
OUTPUT_URL=usb:///dev/disk/by-label/MY-BOOT
USB_DEVICE_PARTED_LABEL=gpt
BACKUP=NETFS
BACKUP_URL=usb:///dev/disk/by-label/MY-DATA
I get
# usr/sbin/rear -D format /dev/sdb
Relax-and-Recover 2.6 / Git
Running rear format (PID 819 date 2021-11-02 13:06:27)
Command line options: usr/sbin/rear -D format /dev/sdb
Using log file: /root/rear.wingcon-feature_hybrid_boot/var/log/rear/rear-linux-h9wr.log
Using build area: /var/tmp/rear.b3dmAzJw333oeKE
Running 'init' stage ======================
Running workflow format on the normal/original system
Running 'format' stage ======================
USB or disk device /dev/sdb is not formatted with ext2/3/4 or btrfs filesystem
Formatting /dev/sdb will remove all currently existing data on that whole device
UserInput -I USB_DEVICE_CONFIRM_FORMAT needed in /root/rear.wingcon-feature_hybrid_boot/usr/share/rear/format/USB/default/200_check_usb_layout.sh line 62
Type exactly 'Yes' to format /dev/sdb with ext3 filesystem
(default 'No' timeout 300 seconds)
Yes
UserInput: No choices - result is 'Yes'
Repartitioning /dev/sdb
Creating partition table of type gpt on /dev/sdb
The --bios toggle was used with format - making an BIOS bootable device /dev/sdb
Creating BIOS boot partition /dev/sdb1
Setting 'bios_grub' flag on BIOS boot partition /dev/sdb1
The --efi toggle was used with format - making an EFI bootable device /dev/sdb
Creating EFI system partition /dev/sdb2 with size 512 MiB aligned at 8 MiB
Setting 'esp' flag on EFI partition /dev/sdb2
Creating boot partition /dev/sdb3 with size 1024 MiB aligned at 8 MiB
Setting 'legacy_boot' flag on boot partition /dev/sdb3
Creating ReaR data partition /dev/sdb4 up to 10% of /dev/sdb
Creating vfat filesystem on EFI system partition on /dev/sdb2
Creating ext2 filesystem with label 'MY-BOOT' on boot partition /dev/sdb3
Creating ext3 filesystem with label 'MY-DATA' on ReaR data partition /dev/sdb4
Adjusting filesystem parameters on ReaR data partition /dev/sdb4
Exiting rear format (PID 819) and its descendant processes ...
which results this /dev/sdb
# parted -s /dev/sdb unit MiB print
Model: TOSHIBA External USB 3.0 (scsi)
Disk /dev/sdb: 476940MiB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 0.02MiB 8.00MiB 7.98MiB primary bios_grub
2 8.00MiB 520MiB 512MiB fat32 primary boot, esp
3 520MiB 1544MiB 1024MiB ext2 primary legacy_boot
4 1544MiB 47694MiB 46150MiB ext3 primary
# lsblk -ipo NAME,KNAME,LABEL,UUID,PTUUID,PARTUUID /dev/sdb
NAME KNAME LABEL UUID PTUUID PARTUUID
/dev/sdb /dev/sdb 9b0a1287-b816-4a56-958d-8842d9eb9d65
|-/dev/sdb1 /dev/sdb1 9b0a1287-b816-4a56-958d-8842d9eb9d65 06d5168b-3135-4492-8881-9f0ecaa0d56f
|-/dev/sdb2 /dev/sdb2 REAR-EFI 9F73-4885 9b0a1287-b816-4a56-958d-8842d9eb9d65 cdb9a83a-233f-4cd7-bd88-59f89512ac89
|-/dev/sdb3 /dev/sdb3 MY-BOOT fb10f97d-d189-439b-910c-669da4d05214 9b0a1287-b816-4a56-958d-8842d9eb9d65 d4edc850-a5e9-4925-8cbf-86677f551eec
`-/dev/sdb4 /dev/sdb4 MY-DATA 8472ff6f-8a30-4d94-b065-66595eb9052f 9b0a1287-b816-4a56-958d-8842d9eb9d65 584151c2-7ada-4ffb-bfa3-38dc4b3e98a4
For comparison what rear -D format /dev/sdb
had resulted before
# parted -s /dev/sdb unit MiB print
Model: TOSHIBA External USB 3.0 (scsi)
Disk /dev/sdb: 476940MiB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 0.02MiB 8.00MiB 7.98MiB primary bios_grub
2 8.00MiB 1032MiB 1024MiB ext2 primary legacy_boot
3 1032MiB 47694MiB 46662MiB ext3 primary
# lsblk -ipo NAME,KNAME,LABEL,UUID,PTUUID,PARTUUID /dev/sdb
NAME KNAME LABEL UUID PTUUID PARTUUID
/dev/sdb /dev/sdb 546e029a-9ee2-4a33-a747-aa14bfface75
|-/dev/sdb1 /dev/sdb1 546e029a-9ee2-4a33-a747-aa14bfface75 2733c621-ac3a-4a98-af0f-d02da15dec36
|-/dev/sdb2 /dev/sdb2 MY-BOOT 16d6cce4-cef4-4d1a-8fe8-e2f6af0f535a 546e029a-9ee2-4a33-a747-aa14bfface75 ff41080b-6262-4cab-b82d-7c9a0a213dce
`-/dev/sdb3 /dev/sdb3 MY-DATA bbc17933-7a79-46bb-9756-d173a7e9d481 546e029a-9ee2-4a33-a747-aa14bfface75 4bdfeea3-1b96-4832-b63f-820b91a3880a
cf. https://github.com/rear/rear/pull/2662#issuecomment-888310850
After rear mkbackup
I got that on my /dev/sdb
# find /tmp/sdb3
/tmp/sdb3
/tmp/sdb3/rear
/tmp/sdb3/rear/linux-h9wr
/tmp/sdb3/rear/linux-h9wr/20211102.1312
/tmp/sdb3/rear/linux-h9wr/20211102.1312/rear-linux-h9wr.log
/tmp/sdb3/rear/linux-h9wr/20211102.1312/initrd.cgz
/tmp/sdb3/rear/linux-h9wr/20211102.1312/kernel
/tmp/sdb3/lost+found
/tmp/sdb3/boot
/tmp/sdb3/boot/grub2
/tmp/sdb3/boot/grub2/i386-pc
/tmp/sdb3/boot/grub2/i386-pc/biosdisk.mod
/tmp/sdb3/boot/grub2/i386-pc/cmdline_cat_test.mod
...
/tmp/sdb3/boot/grub2/i386-pc/zfsinfo.mod
/tmp/sdb3/boot/grub2/fonts
/tmp/sdb3/boot/grub2/fonts/unicode.pf2
/tmp/sdb3/boot/grub2/grub.cfg
/tmp/sdb3/boot/grub2/grubenv
/tmp/sdb3/linux-h9wr
# find /tmp/sdb4
/tmp/sdb4
/tmp/sdb4/lost+found
/tmp/sdb4/rear
/tmp/sdb4/rear/linux-h9wr
/tmp/sdb4/rear/linux-h9wr/20211102.1312
/tmp/sdb4/rear/linux-h9wr/20211102.1312/backup.log
/tmp/sdb4/rear/linux-h9wr/20211102.1312/backup.tar.gz
Booting from that USB disk works well for me
on my other older x86_64 laptop with traditional BIOS
both booting the ReaR recovery system and
chainloading its bootloader on its built-in harddisk
to boot its original system.
jsmeix commented at 2021-11-02 13:15:¶
@rear/contributors
could you have a look here if you find time for it.
I would like to merge it tomorrow afternoon unless there are objections.
jsmeix commented at 2021-11-03 11:23:¶
Tested "rear format" and "rear mkbackup" plus "rear recover"
on the same two VMs as in
https://github.com/rear/rear/pull/2703#issuecomment-952888484
original system replacement system
sda 8 GiB system disk sda the 8 GiB ReaR "USB" disk from the original system
sdb 8 GiB ReaR "USB" disk sdb 9 GiB replacement system disk
etc/rear/local.conf
DISKS_TO_BE_WIPED=''
FIRMWARE_FILES=( 'no' )
MODULES=( 'loaded_modules' )
PROGRESS_MODE="plain"
PROGRESS_WAIT_SECONDS="3"
SSH_ROOT_PASSWORD="rear"
OUTPUT=USB
USB_DEVICE_FILESYSTEM_PERCENTAGE=90
USB_DEVICE_FILESYSTEM_LABEL="MY-DATA"
USB_BOOT_PART_SIZE=1024
USB_BOOTLOADER="grub"
USB_DEVICE_BOOT_LABEL="MY-BOOT"
OUTPUT_URL=usb:///dev/disk/by-label/MY-BOOT
USB_DEVICE_PARTED_LABEL=gpt
BACKUP=NETFS
BACKUP_URL=usb:///dev/disk/by-label/MY-DATA
Excerpts:
# usr/sbin/rear -D format /dev/sdb
Relax-and-Recover 2.6 / Git
Running rear format (PID 1355 date 2021-11-03 11:20:57)
Command line options: usr/sbin/rear -D format /dev/sdb
Using log file: /root/rear.wingcon-feature_hybrid_boot/var/log/rear/rear-localhost.log
Using build area: /var/tmp/rear.K0IoksPaoVt9sZD
Running 'init' stage ======================
Running workflow format on the normal/original system
Running 'format' stage ======================
USB or disk device /dev/sdb is not formatted with ext2/3/4 or btrfs filesystem
Formatting /dev/sdb will remove all currently existing data on that whole device
UserInput -I USB_DEVICE_CONFIRM_FORMAT needed in /root/rear.wingcon-feature_hybrid_boot/usr/share/rear/format/USB/default/200_check_usb_layout.sh line 62
Type exactly 'Yes' to format /dev/sdb with ext3 filesystem
(default 'No' timeout 300 seconds)
Yes
UserInput: No choices - result is 'Yes'
Repartitioning /dev/sdb
Creating partition table of type gpt on /dev/sdb
Making a BIOS bootable device /dev/sdb
Creating BIOS boot partition /dev/sdb1
Setting 'bios_grub' flag on BIOS boot partition /dev/sdb1
Making an EFI bootable device /dev/sdb
Creating EFI system partition /dev/sdb2 with size 512 MiB aligned at 8 MiB
Setting 'esp' flag on EFI partition /dev/sdb2
Creating boot partition /dev/sdb3 with size 1024 MiB aligned at 8 MiB
Setting 'legacy_boot' flag on boot partition /dev/sdb3
Creating ReaR data partition /dev/sdb4 up to 90% of /dev/sdb
Creating vfat filesystem on EFI system partition on /dev/sdb2
Creating ext2 filesystem with label 'MY-BOOT' on boot partition /dev/sdb3
Creating ext3 filesystem with label 'MY-DATA' on ReaR data partition /dev/sdb4
Adjusting filesystem parameters on ReaR data partition /dev/sdb4
Exiting rear format (PID 1355) and its descendant processes ...
# parted -s /dev/sdb unit MiB print
Model: ATA QEMU HARDDISK (scsi)
Disk /dev/sdb: 8192MiB
Sector size (logical/physical): 512B/512B
Partition Table: gpt
Disk Flags:
Number Start End Size File system Name Flags
1 0.02MiB 8.00MiB 7.98MiB primary bios_grub
2 8.00MiB 520MiB 512MiB fat32 primary boot, esp
3 520MiB 1544MiB 1024MiB ext2 primary legacy_boot
4 1544MiB 7373MiB 5829MiB ext3 primary
# lsblk -ipo NAME,KNAME,LABEL,SIZE /dev/sdb
NAME KNAME LABEL SIZE
/dev/sdb /dev/sdb 8G
|-/dev/sdb1 /dev/sdb1 8M
|-/dev/sdb2 /dev/sdb2 REAR-EFI 512M
|-/dev/sdb3 /dev/sdb3 MY-BOOT 1G
`-/dev/sdb4 /dev/sdb4 MY-DATA 5.7G
"rear mkbackup" on the original system and
then booting the replacement system from that disk
plus "rear recover" worked well for me.
[Export of Github issue for rear/rear.]