image: use correct deviceinfo value for device sector size

This commit is contained in:
InsanePrawn 2023-04-30 03:29:52 +02:00
parent 33e1214aef
commit edcad72f7a
5 changed files with 45 additions and 39 deletions

View file

@ -11,7 +11,7 @@ from distro.package import LocalPackage
from packages.pkgbuild import Pkgbuild, _pkgbuilds_cache, discover_pkgbuilds, get_pkgbuild_by_path, init_pkgbuilds from packages.pkgbuild import Pkgbuild, _pkgbuilds_cache, discover_pkgbuilds, get_pkgbuild_by_path, init_pkgbuilds
from utils import read_files_from_tar, color_str from utils import read_files_from_tar, color_str
from .deviceinfo import DeviceInfo, parse_deviceinfo from .deviceinfo import DEFAULT_IMAGE_SECTOR_SIZE, DeviceInfo, parse_deviceinfo
DEVICE_DEPRECATIONS = { DEVICE_DEPRECATIONS = {
"oneplus-enchilada": "sdm845-oneplus-enchilada", "oneplus-enchilada": "sdm845-oneplus-enchilada",
@ -69,7 +69,7 @@ class Device(DictScheme):
result["package_path"] = self.package.path if self.package else None result["package_path"] = self.package.path if self.package else None
return DeviceSummary(result) return DeviceSummary(result)
def parse_deviceinfo(self, try_download: bool = True, lazy: bool = True): def parse_deviceinfo(self, try_download: bool = True, lazy: bool = True) -> DeviceInfo:
if not lazy or 'deviceinfo' not in self or self.deviceinfo is None: if not lazy or 'deviceinfo' not in self or self.deviceinfo is None:
# avoid import loop # avoid import loop
from packages.build import check_package_version_built from packages.build import check_package_version_built
@ -96,8 +96,16 @@ class Device(DictScheme):
assert info.arch assert info.arch
assert info.arch == self.arch assert info.arch == self.arch
self['deviceinfo'] = info self['deviceinfo'] = info
assert self.deviceinfo
return self.deviceinfo return self.deviceinfo
def get_image_sectorsize(self, **kwargs) -> Optional[int]:
"""Gets the deviceinfo_rootfs_image_sector_size if defined, otherwise None"""
return self.parse_deviceinfo(**kwargs).get('rootfs_image_sector_size', None)
def get_image_sectorsize_default(self, **kwargs) -> int:
return self.get_image_sectorsize(**kwargs) or DEFAULT_IMAGE_SECTOR_SIZE
def check_devicepkg_name(name: str, log_level: Optional[int] = None): def check_devicepkg_name(name: str, log_level: Optional[int] = None):
valid = True valid = True

View file

@ -5,7 +5,7 @@ import copy
import logging import logging
import os import os
from typing import Any, Mapping, Optional from typing import Mapping, Optional
from config.state import config from config.state import config
from constants import Arch from constants import Arch
@ -15,6 +15,8 @@ PMOS_ARCHES_OVERRIDES: dict[str, Arch] = {
"armv7": 'armv7h', "armv7": 'armv7h',
} }
DEFAULT_IMAGE_SECTOR_SIZE = 512
class DeviceInfo(DictScheme): class DeviceInfo(DictScheme):
arch: Arch arch: Arch
@ -24,10 +26,12 @@ class DeviceInfo(DictScheme):
chassis: str chassis: str
flash_pagesize: int flash_pagesize: int
flash_method: str flash_method: str
rootfs_image_sector_size: Optional[int]
@classmethod @classmethod
def transform(cls, values: Mapping[str, str], validate: bool = True, allow_extra: bool = True, type_hints: Optional[dict[str, Any]] = None): def transform(cls, values: Mapping[str, Optional[str]], **kwargs):
return super().transform(values, validate=validate, allow_extra=allow_extra) kwargs = {'allow_extra': True} | kwargs
return super().transform(values, **kwargs)
# Variables from deviceinfo. Reference: <https://postmarketos.org/deviceinfo> # Variables from deviceinfo. Reference: <https://postmarketos.org/deviceinfo>
@ -115,7 +119,7 @@ deviceinfo_chassis_types = [
] ]
def sanity_check(deviceinfo: dict[str, str], device_name: str): def sanity_check(deviceinfo: dict[str, Optional[str]], device_name: str):
try: try:
_pmos_sanity_check(deviceinfo, device_name) _pmos_sanity_check(deviceinfo, device_name)
except RuntimeError as err: except RuntimeError as err:
@ -129,7 +133,7 @@ def sanity_check(deviceinfo: dict[str, str], device_name: str):
f"{err}") f"{err}")
def _pmos_sanity_check(info: dict[str, str], device_name: str): def _pmos_sanity_check(info: dict[str, Optional[str]], device_name: str):
# Resolve path for more readable error messages # Resolve path for more readable error messages
path = os.path.join(config.get_path('pkgbuilds'), 'device', device_name, 'deviceinfo') path = os.path.join(config.get_path('pkgbuilds'), 'device', device_name, 'deviceinfo')
@ -194,7 +198,7 @@ def _pmos_sanity_check(info: dict[str, str], device_name: str):
f" and try again: {path}") f" and try again: {path}")
def parse_kernel_suffix(deviceinfo: dict[str, str], kernel: str = 'mainline') -> dict[str, str]: def parse_kernel_suffix(deviceinfo: dict[str, Optional[str]], kernel: str = 'mainline') -> dict[str, Optional[str]]:
""" """
Remove the kernel suffix (as selected in 'pmbootstrap init') from Remove the kernel suffix (as selected in 'pmbootstrap init') from
deviceinfo variables. Related: deviceinfo variables. Related:
@ -240,7 +244,7 @@ def parse_deviceinfo(deviceinfo_lines: list[str], device_name: str, kernel='main
:param device: defaults to args.device :param device: defaults to args.device
:param kernel: defaults to args.kernel :param kernel: defaults to args.kernel
""" """
info = {} info: dict[str, Optional[str]] = {}
for line in deviceinfo_lines: for line in deviceinfo_lines:
line = line.strip() line = line.strip()
if line.startswith("#") or not line: if line.startswith("#") or not line:
@ -258,12 +262,12 @@ def parse_deviceinfo(deviceinfo_lines: list[str], device_name: str, kernel='main
# Assign empty string as default # Assign empty string as default
for key in deviceinfo_attributes: for key in deviceinfo_attributes:
if key not in info: if key not in info:
info[key] = "" info[key] = None
info = parse_kernel_suffix(info, kernel) info = parse_kernel_suffix(info, kernel)
sanity_check(info, device_name) sanity_check(info, device_name)
if 'arch' in info: if 'arch' in info:
arch = info['arch'] arch = info['arch']
info['arch'] = PMOS_ARCHES_OVERRIDES.get(arch, arch) info['arch'] = PMOS_ARCHES_OVERRIDES.get(arch, arch) # type: ignore[arg-type]
dev = DeviceInfo.fromDict(info) dev = DeviceInfo.fromDict(info)
return dev return dev

View file

@ -58,6 +58,7 @@ class DictScheme(Munch):
def transform( def transform(
cls, cls,
values: Mapping[str, Any], values: Mapping[str, Any],
*,
validate: bool = True, validate: bool = True,
allow_extra: bool = False, allow_extra: bool = False,
type_hints: Optional[dict[str, Any]] = None, type_hints: Optional[dict[str, Any]] = None,
@ -251,7 +252,7 @@ class DictScheme(Munch):
return result return result
def update(self, d: Mapping[str, Any], validate: bool = True): def update(self, d: Mapping[str, Any], validate: bool = True):
Munch.update(self, type(self).transform(d, validate)) Munch.update(self, type(self).transform(d, validate=validate))
def __init_subclass__(cls): def __init_subclass__(cls):
super().__init_subclass__() super().__init_subclass__()

View file

@ -85,10 +85,8 @@ def cmd_flash(
device_image_path = get_image_path(device, flavour) device_image_path = get_image_path(device, flavour)
deviceinfo = device.parse_deviceinfo() deviceinfo = device.parse_deviceinfo()
sector_size = sector_size or deviceinfo.flash_pagesize sector_size = sector_size or device.get_image_sectorsize_default()
method = method or deviceinfo.flash_method method = method or deviceinfo.flash_method
if not sector_size:
raise Exception(f"Device {device.name} has no flash_pagesize specified")
if what not in FLASH_PARTS.values(): if what not in FLASH_PARTS.values():
raise Exception(f'Unknown what "{what}", must be one of {", ".join(FLASH_PARTS.values())}') raise Exception(f'Unknown what "{what}", must be one of {", ".join(FLASH_PARTS.values())}')

View file

@ -274,30 +274,31 @@ def partition_device(device: str):
raise Exception(f'Failed to create partitions on {device}') raise Exception(f'Failed to create partitions on {device}')
def create_filesystem(device: str, blocksize: int = 4096, label=None, options=[], fstype='ext4'): def create_filesystem(device: str, blocksize: Optional[int], label=None, options=[], fstype='ext4'):
# blocksize can be 4k max due to pagesize """Creates a new filesystem. Blocksize defaults"""
blocksize = min(blocksize, 4096)
if fstype.startswith('ext'):
# blocksize for ext-fs must be >=1024
blocksize = max(blocksize, 1024)
labels = ['-L', label] if label else [] labels = ['-L', label] if label else []
cmd = [ cmd = [f'mkfs.{fstype}', '-F', *labels]
f'mkfs.{fstype}', if blocksize:
'-F', # blocksize can be 4k max due to pagesize
'-b', blocksize = min(blocksize, 4096)
str(blocksize), if fstype.startswith('ext'):
] + labels + [device] # blocksize for ext-fs must be >=1024
blocksize = max(blocksize, 1024)
cmd += [
'-b',
str(blocksize),
]
cmd.append(device)
result = run_root_cmd(cmd) result = run_root_cmd(cmd)
if result.returncode != 0: if result.returncode != 0:
raise Exception(f'Failed to create {fstype} filesystem on {device} with CMD: {cmd}') raise Exception(f'Failed to create {fstype} filesystem on {device} with CMD: {cmd}')
def create_root_fs(device: str, blocksize: int): def create_root_fs(device: str, blocksize: Optional[int]):
create_filesystem(device, blocksize=blocksize, label='kupfer_root', options=['-O', '^metadata_csum', '-N', '100000']) create_filesystem(device, blocksize=blocksize, label='kupfer_root', options=['-O', '^metadata_csum', '-N', '100000'])
def create_boot_fs(device: str, blocksize: int): def create_boot_fs(device: str, blocksize: Optional[int]):
create_filesystem(device, blocksize=blocksize, label='kupfer_boot', fstype='ext2') create_filesystem(device, blocksize=blocksize, label='kupfer_boot', fstype='ext2')
@ -447,10 +448,7 @@ def cmd_build(
pkgbuilds |= set(filter_pkgbuilds(packages_extra, arch=arch, allow_empty_results=True, use_paths=False)) pkgbuilds |= set(filter_pkgbuilds(packages_extra, arch=arch, allow_empty_results=True, use_paths=False))
build_packages(pkgbuilds, arch, try_download=not no_download_pkgs) build_packages(pkgbuilds, arch, try_download=not no_download_pkgs)
deviceinfo = device.parse_deviceinfo() sector_size = sector_size or device.get_image_sectorsize()
sector_size = sector_size or deviceinfo.flash_pagesize
if not sector_size:
raise Exception(f"Device {device.name} has no flash_pagesize specified")
image_path = block_target or get_image_path(device, flavour.name) image_path = block_target or get_image_path(device, flavour.name)
@ -459,7 +457,7 @@ def cmd_build(
logging.info(f'Creating new file at {image_path}') logging.info(f'Creating new file at {image_path}')
create_img_file(image_path, f"{rootfs_size_mb}M") create_img_file(image_path, f"{rootfs_size_mb}M")
loop_device = losetup_rootfs_image(image_path, sector_size) loop_device = losetup_rootfs_image(image_path, sector_size or device.get_image_sectorsize_default())
partition_device(loop_device) partition_device(loop_device)
partprobe(loop_device) partprobe(loop_device)
@ -512,10 +510,7 @@ def cmd_inspect(profile: Optional[str] = None, shell: bool = False, sector_size:
device = get_profile_device(profile) device = get_profile_device(profile)
arch = device.arch arch = device.arch
flavour = get_profile_flavour(profile).name flavour = get_profile_flavour(profile).name
deviceinfo = device.parse_deviceinfo() sector_size = sector_size or device.get_image_sectorsize_default()
sector_size = sector_size or deviceinfo.flash_pagesize
if not sector_size:
raise Exception(f"Device {device.name} has no flash_pagesize specified")
chroot = get_device_chroot(device.name, flavour, arch) chroot = get_device_chroot(device.name, flavour, arch)
image_path = get_image_path(device, flavour) image_path = get_image_path(device, flavour)