From 4228c591a84c2681e05b61c0eb9b7a4c56cc8ea7 Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Wed, 27 Aug 2014 11:51:02 -0700 Subject: [PATCH 1/6] disk_layout: mount ESP to /boot instead of /boot/efi We have long since stopped installing anything to the /boot directory of the root filesystem. Mount the ESP partition to /boot for consistancy with the discoverable partition spec. --- build_library/build_image_util.sh | 4 ++-- build_library/disk_layout.json | 2 +- build_library/vm_image_util.sh | 8 ++++---- 3 files changed, 7 insertions(+), 7 deletions(-) diff --git a/build_library/build_image_util.sh b/build_library/build_image_util.sh index 6d4f09376f..85d4076843 100755 --- a/build_library/build_image_util.sh +++ b/build_library/build_image_util.sh @@ -202,12 +202,12 @@ finish_image() { ${tmp_ignore} "${root_fs_dir}/etc" # Only configure bootloaders if there is a boot partition - if mountpoint -q "${root_fs_dir}"/boot/efi; then + if mountpoint -q "${root_fs_dir}"/boot; then ${BUILD_LIBRARY_DIR}/configure_bootloaders.sh \ --arch=${ARCH} \ --disk_layout="${disk_layout}" \ --boot_dir="${root_fs_dir}"/usr/boot \ - --esp_dir="${root_fs_dir}"/boot/efi \ + --esp_dir="${root_fs_dir}"/boot \ --boot_args="${FLAGS_boot_args}" fi diff --git a/build_library/disk_layout.json b/build_library/disk_layout.json index c30e9619a8..1649b3ae30 100644 --- a/build_library/disk_layout.json +++ b/build_library/disk_layout.json @@ -12,7 +12,7 @@ "type":"efi", "blocks":"262144", "fs_type":"vfat", - "mount":"/boot/efi", + "mount":"/boot", "features": ["syslinux"] }, "2":{ diff --git a/build_library/vm_image_util.sh b/build_library/vm_image_util.sh index d343bd87ce..f443440f36 100644 --- a/build_library/vm_image_util.sh +++ b/build_library/vm_image_util.sh @@ -276,7 +276,7 @@ setup_disk_image() { "${BUILD_LIBRARY_DIR}/disk_util" --disk_layout="${disk_layout}" \ mount "${VM_TMP_IMG}" "${VM_TMP_ROOT}" - local SYSLINUX_DIR="${VM_TMP_ROOT}/boot/efi/syslinux" + local SYSLINUX_DIR="${VM_TMP_ROOT}/boot/syslinux" if [[ $(_get_vm_opt BOOT_KERNEL) -eq 0 ]]; then sudo mv "${SYSLINUX_DIR}/default.cfg.A" "${SYSLINUX_DIR}/default.cfg" fi @@ -336,9 +336,9 @@ _run_onmetal_fs_hook() { local arg='8250.nr_uarts=5 console=ttyS4,115200n8 modprobe.blacklist=mei_me' local timeout=150 # 15 seconds local totaltimeout=3000 # 5 minutes - sudo sed -i "${VM_TMP_ROOT}/boot/efi/syslinux/boot_kernel.cfg" \ + sudo sed -i "${VM_TMP_ROOT}/boot/syslinux/boot_kernel.cfg" \ -e 's/console=[^ ]*//g' -e "s/\\(append.*$\\)/\\1 ${arg}/" - sudo sed -i "${VM_TMP_ROOT}/boot/efi/syslinux/syslinux.cfg" \ + sudo sed -i "${VM_TMP_ROOT}/boot/syslinux/syslinux.cfg" \ -e "s/^TIMEOUT [0-9]*/TIMEOUT ${timeout}/g" \ -e "s/^TOTALTIMEOUT [0-9]*/TOTALTIMEOUT ${totaltimeout}/g" } @@ -346,7 +346,7 @@ _run_onmetal_fs_hook() { _run_gce_fs_hook() { # HACKITY HACK until OEMs can customize bootloader configs local arg='console=ttyS0,115200n8' - sudo sed -i "${VM_TMP_ROOT}/boot/efi/syslinux/boot_kernel.cfg" \ + sudo sed -i "${VM_TMP_ROOT}/boot/syslinux/boot_kernel.cfg" \ -e 's/console=[^ ]*//g' -e "s/\\(append.*$\\)/\\1 ${arg}/" } From cb97931478066618ae2236d6af90a3c960a177bb Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Fri, 29 Aug 2014 14:05:22 -0700 Subject: [PATCH 2/6] disk_layout: replace unused "BOOT-B" with Grub's BIOS Boot Partition Unlike SYSLINUX, GRUB2 does not recommend embedding itself in a FAT filesystem. Instead GRUB2 prefers embedding in the space between the MBR and first partition or using a dedicated partition that is safe from tampering by fs utilities. In our case the space after the MBR is where the GPT lives so we need to use the extra partition scheme instead. The 64MB "BOOT-B" partition has never been used so we can replace it with a 2MB partition which is more than enough for GRUB. --- build_library/disk_layout.json | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/build_library/disk_layout.json b/build_library/disk_layout.json index 1649b3ae30..de27813a09 100644 --- a/build_library/disk_layout.json +++ b/build_library/disk_layout.json @@ -16,9 +16,9 @@ "features": ["syslinux"] }, "2":{ - "label":"BOOT-B", - "type":"coreos-reserved", - "blocks":"131072" + "label":"BIOS-BOOT", + "type":"bios", + "blocks":"4096" }, "3":{ "label":"USR-A", From fd8618336d2fab3110f0f9da985f998b80be96dd Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Sat, 30 Aug 2014 15:57:23 -0700 Subject: [PATCH 3/6] disk_util: do not zero MBR and GPT when resizing disk Calling cgpt create when resizing zeros the MBR boot code. This worked with the syslinux setup because the boot code was re-written. When not using syslinux it is easier to just preserve the existing MBR instead. --- build_library/disk_util | 12 +++++++++--- 1 file changed, 9 insertions(+), 3 deletions(-) diff --git a/build_library/disk_util b/build_library/disk_util index b59710e43d..6f51e3989e 100755 --- a/build_library/disk_util +++ b/build_library/disk_util @@ -162,6 +162,7 @@ def LoadPartitionConfig(options): # metadata. Kinda odd but the best place I've got with this data structure. if layout_name == options.disk_layout: metadata['blocks'] = disk_block_count + metadata['bytes'] = disk_block_count * metadata['block_size'] # Verify 'base' before other layouts because it is inherited by the others @@ -267,13 +268,18 @@ def WritePartitionTable(options, config=None, partitions=None): if not (config and partitions): config, partitions = LoadPartitionConfig(options) - # If we are not creating a fresh image all partitions must be compatible. - if not options.create: + if options.create: + Cgpt('create', '-c', '-s', config['metadata']['blocks'], options.disk_image) + else: + # If we are not creating a fresh image all partitions must be compatible. GetPartitionTableFromImage(options, config, partitions) if not all(p['image_compat'] for p in partitions.itervalues()): raise InvalidLayout("New disk layout is incompatible existing image") - Cgpt('create', '-c', '-s', config['metadata']['blocks'], options.disk_image) + # Extend the disk image size as needed + with open(options.disk_image, 'r+') as image_fd: + image_fd.truncate(config['metadata']['bytes']) + Cgpt('repair', options.disk_image) syslinux = None for partition in partitions.itervalues(): From 25b20b420cb9b8a93bc86eb9f1b5b601c67859ed Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Sat, 30 Aug 2014 16:26:26 -0700 Subject: [PATCH 4/6] disk_util: support exposing a hybrid partition without syslinux We don't need to do anything like manually install the MBR boot code for grub but we do need to continue to expose the ESP partition as a hybrid partition to support pvgrub. --- build_library/disk_util | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/build_library/disk_util b/build_library/disk_util index 6f51e3989e..995e3fd67a 100755 --- a/build_library/disk_util +++ b/build_library/disk_util @@ -281,7 +281,8 @@ def WritePartitionTable(options, config=None, partitions=None): image_fd.truncate(config['metadata']['bytes']) Cgpt('repair', options.disk_image) - syslinux = None + syslinux = False + hybrid = None for partition in partitions.itervalues(): if partition['type'] != 'blank': Cgpt('add', '-i', partition['num'], @@ -293,13 +294,16 @@ def WritePartitionTable(options, config=None, partitions=None): options.disk_image) features = partition.get('features', []) - if not syslinux and 'syslinux' in features: - syslinux = partition['num'] + if not hybrid and ('syslinux' in features or 'hybrid' in features): + hybrid = partition['num'] + if 'syslinux' in features: + syslinux = True + + if hybrid: + # Enable legacy boot flag and generate a hybrid MBR partition table + Cgpt('add', '-i', hybrid, '-B1', options.disk_image) if syslinux and options.mbr_boot_code: - # Enable legacy boot flag and generate a hybrid MBR partition table - Cgpt('add', '-i', syslinux, '-B1', options.disk_image) - try: with open(options.mbr_boot_code, 'r') as mbr_fd: mbr_code = mbr_fd.read() From 0cc06c9c5ca2017ee096ed29ca2b33bb1c423cd6 Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Sat, 30 Aug 2014 16:39:05 -0700 Subject: [PATCH 5/6] build_image_util: pass the disk image through to configure_bootloaders Required so that configure_bootloaders can now handle installing the bootloaders as well. --- build_library/build_image_util.sh | 10 +++++++--- build_library/configure_bootloaders.sh | 1 + build_library/dev_image_util.sh | 2 +- build_library/prod_image_util.sh | 2 +- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/build_library/build_image_util.sh b/build_library/build_image_util.sh index 85d4076843..c275fc6ceb 100755 --- a/build_library/build_image_util.sh +++ b/build_library/build_image_util.sh @@ -186,9 +186,12 @@ start_image() { } finish_image() { - local disk_layout="$1" - local root_fs_dir="$2" - local image_contents="$3" + local image_name="$1" + local disk_layout="$2" + local root_fs_dir="$3" + local image_contents="$4" + + local disk_img="${BUILD_DIR}/${image_name}" # Record directories installed to the state partition. # Explicitly ignore entries covered by existing configs. @@ -206,6 +209,7 @@ finish_image() { ${BUILD_LIBRARY_DIR}/configure_bootloaders.sh \ --arch=${ARCH} \ --disk_layout="${disk_layout}" \ + --disk_image="${disk_img}" \ --boot_dir="${root_fs_dir}"/usr/boot \ --esp_dir="${root_fs_dir}"/boot \ --boot_args="${FLAGS_boot_args}" diff --git a/build_library/configure_bootloaders.sh b/build_library/configure_bootloaders.sh index 77d5b05758..f3f5bf35dc 100755 --- a/build_library/configure_bootloaders.sh +++ b/build_library/configure_bootloaders.sh @@ -24,6 +24,7 @@ DEFINE_string boot_args "" \ "Additional boot arguments to pass to the commandline (Default: '')" DEFINE_string disk_layout "base" \ "The disk layout type to use for this image." +DEFINE_string disk_image "" "The disk image." # Parse flags FLAGS "$@" || exit 1 diff --git a/build_library/dev_image_util.sh b/build_library/dev_image_util.sh index 84fd5e6b0a..daf2b4a0fc 100755 --- a/build_library/dev_image_util.sh +++ b/build_library/dev_image_util.sh @@ -112,7 +112,7 @@ EOF # The remount services are provided by coreos-base/coreos-init systemd_enable "${root_fs_dir}" "multi-user.target" "remount-usr.service" - finish_image "${disk_layout}" "${root_fs_dir}" "${image_contents}" + finish_image "${image_name}" "${disk_layout}" "${root_fs_dir}" "${image_contents}" upload_image -d "${BUILD_DIR}/${image_name}.bz2.DIGESTS" \ "${BUILD_DIR}/${image_contents}" \ "${BUILD_DIR}/${image_packages}" \ diff --git a/build_library/prod_image_util.sh b/build_library/prod_image_util.sh index 331236afff..dca9f503d2 100755 --- a/build_library/prod_image_util.sh +++ b/build_library/prod_image_util.sh @@ -81,7 +81,7 @@ EOF disable_read_write=${FLAGS_FALSE} fi - finish_image "${disk_layout}" "${root_fs_dir}" "${image_contents}" + finish_image "${image_name}" "${disk_layout}" "${root_fs_dir}" "${image_contents}" # Make the filesystem un-mountable as read-write. if [[ ${disable_read_write} -eq ${FLAGS_TRUE} ]]; then From 680730cc1a1fef815a05e50c104ce31f9019e695 Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Sat, 30 Aug 2014 17:46:38 -0700 Subject: [PATCH 6/6] configure_bootloaders: add grub install stub code Not currently used, this configuration which sets up grub to re-use the syslinux configuration only works with recent git versions, not any releases. Compatibility is also limited because the serial configuration in syslinux must be duplicated in the grub config. --- build_library/configure_bootloaders.sh | 26 +++++++++++++++++++++----- build_library/grub.cfg | 9 +++++++++ 2 files changed, 30 insertions(+), 5 deletions(-) create mode 100644 build_library/grub.cfg diff --git a/build_library/configure_bootloaders.sh b/build_library/configure_bootloaders.sh index f3f5bf35dc..7458838646 100755 --- a/build_library/configure_bootloaders.sh +++ b/build_library/configure_bootloaders.sh @@ -51,7 +51,7 @@ GRUB_DIR="${FLAGS_boot_dir}/grub" SYSLINUX_DIR="${FLAGS_boot_dir}/syslinux" # Build configuration files for pygrub/pvgrub -configure_grub() { +configure_pvgrub() { sudo mkdir -p "${GRUB_DIR}" # Add hvc0 for hypervisors @@ -177,12 +177,28 @@ copy_to_esp() { done } +# Install GRUB2 to the disk image +install_grub() { + # Install under boot/coreos/grub instead of boot/grub to prevent + # more recent versions of pygrub that attempt to read grub2 configs + # from finding it, pygrub and pvgrub must stick with using menu.lst + sudo mkdir -p "${FLAGS_esp_dir}/coreos/grub" + sudo grub-install \ + --target=i386-pc \ + --modules=part_gpt \ + --boot-directory="${FLAGS_esp_dir}/coreos" \ + "${FLAGS_disk_image}" + sudo cp "${BUILD_LIBRARY_DIR}/grub.cfg" \ + "${FLAGS_esp_dir}/coreos/grub/grub.cfg" +} + +[[ -d "${FLAGS_esp_dir}" ]] || die_notrace "--esp_dir is required" +[[ -f "${FLAGS_disk_image}" ]] || die_notrace "--disk_image is required" + if [[ "${FLAGS_arch}" = "x86" || "${FLAGS_arch}" = "amd64" ]]; then - configure_grub + configure_pvgrub configure_syslinux - if [[ -n "${FLAGS_esp_dir}" ]]; then - copy_to_esp - fi + copy_to_esp else error "No bootloader configuration for ${FLAGS_arch}" fi diff --git a/build_library/grub.cfg b/build_library/grub.cfg new file mode 100644 index 0000000000..69bf7d0a36 --- /dev/null +++ b/build_library/grub.cfg @@ -0,0 +1,9 @@ +# Use both default console and ttyS0 +serial --unit=0 --speed=115200 --word=8 --parity=no --stop=1 +terminal_input console serial +terminal_output console serial + +# Re-use the existing syslinux configuration +echo "Loading SYSLINUX configuration..." +insmod syslinuxcfg +syslinux_configfile -s /syslinux/syslinux.cfg