From bb1c2559fbe441d8dbb755f841d74f7fa999f1bf Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Wed, 8 Oct 2014 12:05:45 -0700 Subject: [PATCH 1/4] grub_install: work around intermittent missing loopback partitions I am unsure exactly what situation is causing the loopback partition device node to not exist when it is being mounted but this should help work around the situation and log loudly about it so we can hopefully figure out where to dig further. --- build_library/grub_install.sh | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/build_library/grub_install.sh b/build_library/grub_install.sh index b43853fff0..4861369083 100755 --- a/build_library/grub_install.sh +++ b/build_library/grub_install.sh @@ -97,6 +97,25 @@ grub-mkimage \ info "Installing GRUB ${FLAGS_target} to ${FLAGS_disk_image##*/}" LOOP_DEV=$(sudo losetup --find --show --partscan "${FLAGS_disk_image}") ESP_DIR=$(mktemp --directory) + +# work around slow/buggy udev, make sure the node is there before mounting +if [[ ! -b "${LOOP_DEV}p1" ]]; then + # sleep a little just in case udev is ok but just not finished yet + warn "loopback device node ${LOOP_DEV}p1 missing, waiting on udev..." + sleep 0.5 + for (( i=0; i<5; i++ )); do + if [[ -b "${LOOP_DEV}p1" ]]; then + break + fi + warn "looback device node still ${LOOP_DEV}p1 missing, reprobing..." + blockdev --rereadpt ${LOOP_DEV} + sleep 0.5 + done + if [[ ! -b "${LOOP_DEV}p1" ]]; then + failboat "${LOOP_DEV}p1 where art thou? udev has forsaken us!" + fi +fi + sudo mount -t vfat "${LOOP_DEV}p1" "${ESP_DIR}" sudo cp -r "${STAGE_DIR}/." "${ESP_DIR}/." From e361e9170ec0d1c649f35fbf2fc1bde6a4e22158 Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Wed, 8 Oct 2014 20:40:12 -0700 Subject: [PATCH 2/4] vm_image_util: Enable new VMware OEM package. --- build_library/vm_image_util.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/build_library/vm_image_util.sh b/build_library/vm_image_util.sh index 3deb3793a9..f52a28bd90 100644 --- a/build_library/vm_image_util.sh +++ b/build_library/vm_image_util.sh @@ -44,6 +44,7 @@ VALID_OEM_PACKAGES=( rackspace-onmetal vagrant vagrant-key + vmware ) # Set at runtime to one of the above types @@ -139,6 +140,7 @@ IMG_vagrant_vmware_fusion_OEM_PACKAGE=oem-vagrant IMG_vmware_DISK_FORMAT=vmdk_scsi IMG_vmware_DISK_LAYOUT=vm IMG_vmware_CONF_FORMAT=vmx +IMG_vmware_OEM_PACKAGE=oem-vmware ## vmware_insecure IMG_vmware_insecure_DISK_FORMAT=vmdk_scsi From e77e4e549965a83c1c5bdb8c14cff5ee3fb76e50 Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Wed, 8 Oct 2014 20:12:53 -0700 Subject: [PATCH 3/4] disk_layout: Align disk sizes to both 1MB and cylinder boundaries. The VHD disk format internally includes CHS addressing and qemu-img respectfully aligns disk images to the common 16 heads 63 sectors geometry when possible. This is unfortunate since images uploaded to Azure must also be aligned to 1MB we normally do. Since qemu-img doesn't have a way to handle this well right now adjust our existing alignment logic to create disk images aligned to both. --- build_library/disk_layout.json | 4 +++- build_library/disk_util | 19 +++++++------------ 2 files changed, 10 insertions(+), 13 deletions(-) diff --git a/build_library/disk_layout.json b/build_library/disk_layout.json index 9445d2b5e9..937a3ca40c 100644 --- a/build_library/disk_layout.json +++ b/build_library/disk_layout.json @@ -1,7 +1,9 @@ { "_comment": "See http://www.chromium.org/chromium-os/building-chromium-os/disk-layout-format", "metadata":{ - "alignment": 2048, + "_comment": "Partitions are aligned to 1MB (2048 blocks), disks sizes should align to *both* 1MB and a CHS cylender boundry for the common 16H 63S geometry (16*63 = 1008 blocks). The least common multiple of 2048 and 1008 is 129024 blocks.", + "part_alignment": 2048, + "disk_alignment": 129024, "block_size": 512, "fs_block_size": 4096 }, diff --git a/build_library/disk_util b/build_library/disk_util index 995e3fd67a..61c177778e 100755 --- a/build_library/disk_util +++ b/build_library/disk_util @@ -44,10 +44,10 @@ def LoadPartitionConfig(options): valid_keys = set(('_comment', 'metadata', 'layouts')) valid_layout_keys = set(( '_comment', 'type', 'num', 'label', 'blocks', 'block_size', 'fs_blocks', - 'fs_block_size', 'fs_type', 'features', 'uuid', 'alignment', 'mount', + 'fs_block_size', 'fs_type', 'features', 'uuid', 'part_alignment', 'mount', 'binds', 'fs_subvolume')) integer_layout_keys = set(( - 'blocks', 'block_size', 'fs_blocks', 'fs_block_size', 'alignment')) + 'blocks', 'block_size', 'fs_blocks', 'fs_block_size', 'part_alignment')) required_layout_keys = set(('type', 'num', 'label', 'blocks')) filename = options.disk_layout_file @@ -63,17 +63,12 @@ def LoadPartitionConfig(options): try: metadata = config['metadata'] base = config['layouts']['base'] - for key in ('alignment', 'block_size', 'fs_block_size'): + for key in ('part_alignment', 'disk_alignment', + 'block_size', 'fs_block_size'): metadata[key] = int(metadata[key]) except KeyError as e: raise InvalidLayout('Metadata is missing required entries: %s' % e) - # Sometimes qemu-img expects disks sizes aligned to 64k - align_bytes = metadata['alignment'] * metadata['block_size'] - if align_bytes < 65536 or align_bytes % 65536 != 0: - raise InvalidLayout('Invalid alignment, 64KB or better required') - - def VerifyLayout(layout_name, layout, base=None): for part_num, part in layout.iteritems(): part['num'] = int(part_num) @@ -136,7 +131,7 @@ def LoadPartitionConfig(options): if part['type'] == 'blank': continue - part.setdefault('alignment', metadata['alignment']) + part.setdefault('part_alignment', metadata['part_alignment']) part['bytes'] = part['blocks'] * metadata['block_size'] part.setdefault('fs_block_size', metadata['fs_block_size']) part.setdefault('fs_blocks', part['bytes'] // part['fs_block_size']) @@ -147,7 +142,7 @@ def LoadPartitionConfig(options): 'Filesystem may not be larger than partition: %s %s: %d > %d' % (layout_name, part_num, part['fs_bytes'], part['bytes'])) - disk_block_count = Align(disk_block_count, part['alignment']) + disk_block_count = Align(disk_block_count, part['part_alignment']) part['first_block'] = disk_block_count part['first_byte'] = disk_block_count * metadata['block_size'] disk_block_count += part['blocks'] @@ -156,7 +151,7 @@ def LoadPartitionConfig(options): # Reserved size for second GPT plus align disk image size disk_block_count += GPT_RESERVED_SECTORS - disk_block_count = Align(disk_block_count, metadata['alignment']) + disk_block_count = Align(disk_block_count, metadata['disk_alignment']) # If this is the requested layout stash the disk size into the global # metadata. Kinda odd but the best place I've got with this data structure. From 0d3a849e2b7117a7d166c5369e70bafbb803dccb Mon Sep 17 00:00:00 2001 From: Michael Marineau Date: Wed, 8 Oct 2014 20:36:28 -0700 Subject: [PATCH 4/4] disk_layout: adjust ROOT partition sizes to fill new alignment The new disk size alignment left too much extra space at the end of the disk which would lead to pointless resizing on first boot. Fill in the extra space so that no more than 1MB is left unused. --- 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 937a3ca40c..77c8048bf4 100644 --- a/build_library/disk_layout.json +++ b/build_library/disk_layout.json @@ -64,7 +64,7 @@ "9":{ "label":"ROOT", "type":"coreos-resize", - "blocks":"4194304", + "blocks":"4302848", "fs_type":"btrfs", "fs_subvolume":"root", "mount":"/" @@ -73,13 +73,13 @@ "vm":{ "9":{ "label":"ROOT", - "blocks":"12582912" + "blocks":"12689408" } }, "vagrant":{ "9":{ "label":"ROOT", - "blocks":"33587200" + "blocks":"33591296" } }, "onmetal":{