4k Block device support
Adds support for the block device size to be asserted for the purpose of writing out new images, which may be critical for operators with hardware which requires logical blocks which are 4096 bytes long. Change-Id: I5c16a042eacfbb94a905b93a0eb9fbc73de0a890
This commit is contained in:
parent
e89f59393a
commit
2df6d9b914
@ -38,10 +38,16 @@ def image_delete(filename):
|
||||
os.remove(filename)
|
||||
|
||||
|
||||
def loopdev_attach(filename):
|
||||
def loopdev_attach(filename, block_size):
|
||||
if str(block_size) not in ['512', '4096']:
|
||||
logger.warning("Block device size is set to %s, only 512 and "
|
||||
"4096 has been tested.", block_size)
|
||||
logger.info("loopdev attach")
|
||||
logger.debug("Calling [sudo losetup --show -f %s]", filename)
|
||||
block_device = exec_sudo(["losetup", "--show", "-f", filename])
|
||||
log_msg = ("Calling [sudo losetup --sector-size %s --show -f %s]"
|
||||
% (str(block_size), filename))
|
||||
logger.debug(log_msg)
|
||||
block_device = exec_sudo(["losetup", "--sector-size", str(block_size),
|
||||
"--show", "-f", filename])
|
||||
# [:-1]: Cut of the newline
|
||||
block_device = block_device[:-1]
|
||||
logger.info("New block device [%s]", block_device)
|
||||
@ -85,6 +91,12 @@ class LocalLoopNode(NodeBase):
|
||||
self.image_dir = config['directory']
|
||||
else:
|
||||
self.image_dir = default_config['image-dir']
|
||||
if 'DIB_BLOCK_SIZE' in os.environ:
|
||||
self.block_size = os.environ['DIB_BLOCK_SIZE']
|
||||
elif 'block_size' in config:
|
||||
self.block_size = config['block_size']
|
||||
else:
|
||||
self.block_size = 512
|
||||
self.filename = os.path.join(self.image_dir, self.name + ".raw")
|
||||
|
||||
def get_edges(self):
|
||||
@ -98,7 +110,7 @@ class LocalLoopNode(NodeBase):
|
||||
self.add_rollback(image_delete, self.filename)
|
||||
image_create(self.filename, self.size)
|
||||
|
||||
block_device = loopdev_attach(self.filename)
|
||||
block_device = loopdev_attach(self.filename, self.block_size)
|
||||
self.add_rollback(loopdev_detach, block_device)
|
||||
|
||||
if 'blockdev' not in self.state:
|
||||
|
@ -95,6 +95,8 @@ class Partitioning(PluginBase):
|
||||
|
||||
def _create_mbr(self):
|
||||
"""Create partitions with MBR"""
|
||||
# NOTE(TheJulia): This is funcitonally incompatible with block/sector
|
||||
# sizing other than 512 bytes.
|
||||
with MBR(self.image_path, self.disk_size, self.align) as part_impl:
|
||||
for part_cfg in self.partitions:
|
||||
part_name = part_cfg.get_name()
|
||||
@ -127,7 +129,10 @@ class Partitioning(PluginBase):
|
||||
def _create_gpt(self):
|
||||
"""Create partitions with GPT"""
|
||||
|
||||
cmd = ['sgdisk', self.image_path]
|
||||
# Use the loopback via device_path, as using the file means the
|
||||
# partitioning is exposed to sector sizing of the OS, not of the
|
||||
# underlying "device" provided by the loopback.
|
||||
cmd = ['sgdisk', self.device_path]
|
||||
|
||||
# This padding gives us a little room for rounding so we don't
|
||||
# go over the end of the disk
|
||||
|
@ -63,7 +63,7 @@ class TestGPT(tc.TestGraphGeneration):
|
||||
node.create()
|
||||
|
||||
# check the parted call looks right
|
||||
parted_cmd = ['sgdisk', self.image_path,
|
||||
parted_cmd = ['sgdisk', '/dev/loopX',
|
||||
'-n', '1:0:+8M', '-t', '1:EF00', '-c', '1:ESP',
|
||||
'-n', '2:0:+8M', '-t', '2:EF02', '-c', '2:BSP',
|
||||
'-n', '3:0:+1006M', '-t', '3:8300', '-c', '3:Root Part']
|
||||
|
19
diskimage_builder/elements/block-device-efi-4k/README.rst
Normal file
19
diskimage_builder/elements/block-device-efi-4k/README.rst
Normal file
@ -0,0 +1,19 @@
|
||||
================
|
||||
Block Device EFI
|
||||
================
|
||||
|
||||
This provides a block-device configuration for the ``vm`` element to
|
||||
get a single-partition disk suitable for EFI booting on a block device
|
||||
which uses a native 4KiB sector size. This is important because GPT
|
||||
partitioning relies on sector boundry placement and the GPT disk partition
|
||||
table always starts on the second sector of the disk.
|
||||
|
||||
Note on x86 this provides the extra `BIOS boot partition
|
||||
<https://en.wikipedia.org/wiki/BIOS_boot_partition>`__ and a EFI boot
|
||||
partition for maximum compatability.
|
||||
|
||||
This element requires ``mkfs.vfat`` command to be available on the build
|
||||
system, usually included in the dosfstools OS package.
|
||||
|
||||
Furthermore, the sector size created by this element will not be compatible
|
||||
with devices using 512 byte sectors.
|
@ -0,0 +1,30 @@
|
||||
- local_loop:
|
||||
name: image0
|
||||
block_size: 4096
|
||||
- partitioning:
|
||||
base: image0
|
||||
label: gpt
|
||||
partitions:
|
||||
- name: ESP
|
||||
type: 'EF00'
|
||||
size: 500MiB
|
||||
mkfs:
|
||||
type: vfat
|
||||
mount:
|
||||
mount_point: /boot/efi
|
||||
fstab:
|
||||
options: "defaults"
|
||||
fsck-passno: 2
|
||||
- name: BSP
|
||||
type: 'EF02'
|
||||
size: 8MiB
|
||||
- name: root
|
||||
type: '8300'
|
||||
size: 100%
|
||||
mkfs:
|
||||
type: ext4
|
||||
mount:
|
||||
mount_point: /
|
||||
fstab:
|
||||
options: "defaults"
|
||||
fsck-passno: 1
|
@ -0,0 +1 @@
|
||||
block-device
|
@ -0,0 +1,10 @@
|
||||
#
|
||||
# Arch gate
|
||||
#
|
||||
|
||||
if [[ "ppc64 ppc64le ppc64el" =~ "$ARCH" ]]; then
|
||||
echo "block-device-efi is not supported on Power; use block-device-gpt or block-device-mbr"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
export DIB_BLOCK_DEVICE=efi
|
@ -216,6 +216,22 @@ size
|
||||
directory
|
||||
(optional) The directory where the image is created.
|
||||
|
||||
block_size
|
||||
(optional) Defaults to 512 bytes. Usable to set a different logical block
|
||||
size, or in loopback context sector size, which will govern how partitioning
|
||||
and filesystem utilities will interact with the device and ultimately the
|
||||
block layout on disk.
|
||||
Examples: 512, 4096.
|
||||
This option is critical if you have block devices which natively operate
|
||||
with 4KiB block sizes and need to craft an image to use boot from those
|
||||
devices using a GPT partition table. This setting can also be asserted
|
||||
using a DIB_BLOCK_SIZE environment variable which may be useful for
|
||||
users who need to craft similar, but different block size images without
|
||||
the need to separately maintain different block device YAML documents.
|
||||
Please keep in mind, with larger block sizes, total disk image sizes
|
||||
*and* partition sizes on the disk image will need to be perfectly
|
||||
divisible by the block size being asserted.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
@ -0,0 +1,10 @@
|
||||
---
|
||||
features:
|
||||
- |
|
||||
Adds the ability for diskimage-builder to create images with different
|
||||
block sizes. By default, this remains at the default of 512 bytes,
|
||||
but some newer devices require 4096 bytes to be used, which impacts
|
||||
the overall layout rendering 512 byte images incompatible. This setting
|
||||
can also be asserted and overridden using the ``DIB_BLOCK_SIZE``
|
||||
environment variable, but alternatively exists as a new ``block_size``
|
||||
parameter for ``local_loop`` section in block device YAML documents.
|
Loading…
Reference in New Issue
Block a user