pmbootstrap install: support size_reserve (MR 1946)

Create an empty partition between boot and root. This will be used by
the on-device installer, as explained in detail here:
https://wiki.postmarketos.org/wiki/On-device_installer
This commit is contained in:
Oliver Smith 2020-06-06 19:05:11 +02:00 committed by Bart Ribbers
parent 5fbc95c3c2
commit a97ec615ad
No known key found for this signature in database
GPG Key ID: 699D16185DAFAE61
5 changed files with 57 additions and 26 deletions

View File

@ -137,8 +137,9 @@ def chroot(args):
if args.install_blockdev: if args.install_blockdev:
size_boot = 128 # 128 MiB size_boot = 128 # 128 MiB
size_root = 4096 # 4 GiB size_root = 4096 # 4 GiB
size_reserve = 2048 # 2 GiB
pmb.install.blockdevice.create_and_mount_image(args, size_boot, pmb.install.blockdevice.create_and_mount_image(args, size_boot,
size_root) size_root, size_reserve)
# Run the command as user/root # Run the command as user/root
if args.user: if args.user:

View File

@ -366,17 +366,22 @@ def sanity_check_sdcard(device):
raise RuntimeError("{} is read-only, is the sdcard locked?".format(device)) raise RuntimeError("{} is read-only, is the sdcard locked?".format(device))
def install_system_image(args): def install_system_image(args, size_reserve=0):
"""
:param size_reserve: empty partition between root and boot in MiB (pma#463)
"""
# Partition and fill image/sdcard # Partition and fill image/sdcard
logging.info("*** (3/5) PREPARE INSTALL BLOCKDEVICE ***") logging.info("*** (3/5) PREPARE INSTALL BLOCKDEVICE ***")
pmb.chroot.shutdown(args, True) pmb.chroot.shutdown(args, True)
(size_boot, size_root) = get_subpartitions_size(args) (size_boot, size_root) = get_subpartitions_size(args)
if not args.rsync: if not args.rsync:
pmb.install.blockdevice.create(args, size_boot, size_root) pmb.install.blockdevice.create(args, size_boot, size_root,
size_reserve)
if not args.split: if not args.split:
pmb.install.partition(args, size_boot) pmb.install.partition(args, size_boot, size_reserve)
if not args.split: if not args.split:
pmb.install.partitions_mount(args) root_id = 3 if size_reserve else 2
pmb.install.partitions_mount(args, root_id)
if args.full_disk_encryption: if args.full_disk_encryption:
logging.info("WARNING: Full disk encryption is enabled!") logging.info("WARNING: Full disk encryption is enabled!")
@ -386,7 +391,7 @@ def install_system_image(args):
logging.info("FDE by re-running the install command without '--fde' until") logging.info("FDE by re-running the install command without '--fde' until")
logging.info("you have properly configured osk-sdl. More information:") logging.info("you have properly configured osk-sdl. More information:")
logging.info("<https://postmarketos.org/osk-port>") logging.info("<https://postmarketos.org/osk-port>")
pmb.install.format(args) pmb.install.format(args, size_reserve)
# Just copy all the files # Just copy all the files
logging.info("*** (4/5) FILL INSTALL BLOCKDEVICE ***") logging.info("*** (4/5) FILL INSTALL BLOCKDEVICE ***")

View File

@ -54,12 +54,14 @@ def mount_sdcard(args):
raise RuntimeError("Aborted.") raise RuntimeError("Aborted.")
def create_and_mount_image(args, size_boot, size_root, split=False): def create_and_mount_image(args, size_boot, size_root, size_reserve,
split=False):
""" """
Create a new image file, and mount it as /dev/install. Create a new image file, and mount it as /dev/install.
:param size_boot: size of the boot partition in MiB :param size_boot: size of the boot partition in MiB
:param size_root: size of the root partition in MiB :param size_root: size of the root partition in MiB
:param size_reserve: empty partition between root and boot in MiB (pma#463)
:param split: create separate images for boot and root partitions :param split: create separate images for boot and root partitions
""" """
@ -79,7 +81,7 @@ def create_and_mount_image(args, size_boot, size_root, split=False):
pmb.chroot.root(args, ["rm", img_path]) pmb.chroot.root(args, ["rm", img_path])
# Make sure there is enough free space # Make sure there is enough free space
size_mb = round(size_boot + size_root) size_mb = round(size_boot + size_reserve + size_root)
disk_data = os.statvfs(args.work) disk_data = os.statvfs(args.work)
free = round((disk_data.f_bsize * disk_data.f_bavail) / (1024**2)) free = round((disk_data.f_bsize * disk_data.f_bavail) / (1024**2))
if size_mb > free: if size_mb > free:
@ -113,16 +115,18 @@ def create_and_mount_image(args, size_boot, size_root, split=False):
args.work + "/chroot_native" + mount_point) args.work + "/chroot_native" + mount_point)
def create(args, size_boot, size_root): def create(args, size_boot, size_root, size_reserve):
""" """
Create /dev/install (the "install blockdevice"). Create /dev/install (the "install blockdevice").
:param size_boot: size of the boot partition in MiB :param size_boot: size of the boot partition in MiB
:param size_root: size of the root partition in MiB :param size_root: size of the root partition in MiB
:param size_reserve: empty partition between root and boot in MiB (pma#463)
""" """
pmb.helpers.mount.umount_all( pmb.helpers.mount.umount_all(
args, args.work + "/chroot_native/dev/install") args, args.work + "/chroot_native/dev/install")
if args.sdcard: if args.sdcard:
mount_sdcard(args) mount_sdcard(args)
else: else:
create_and_mount_image(args, size_boot, size_root, args.split) create_and_mount_image(args, size_boot, size_root, size_reserve,
args.split)

View File

@ -23,9 +23,11 @@ def format_and_mount_boot(args):
pmb.chroot.root(args, ["mount", device, mountpoint]) pmb.chroot.root(args, ["mount", device, mountpoint])
def format_and_mount_root(args): def format_and_mount_root(args, device):
"""
:param device: root partition on install block device (e.g. /dev/installp2)
"""
mountpoint = "/dev/mapper/pm_crypt" mountpoint = "/dev/mapper/pm_crypt"
device = "/dev/installp2"
if args.full_disk_encryption: if args.full_disk_encryption:
logging.info("(native) format " + device + " (root, luks), mount to " + logging.info("(native) format " + device + " (root, luks), mount to " +
mountpoint) mountpoint)
@ -41,12 +43,13 @@ def format_and_mount_root(args):
raise RuntimeError("Failed to open cryptdevice!") raise RuntimeError("Failed to open cryptdevice!")
def format_and_mount_pm_crypt(args): def format_and_mount_pm_crypt(args, device):
"""
:param device: root partition on install block device (e.g. /dev/installp2)
"""
# Block device # Block device
if args.full_disk_encryption: if args.full_disk_encryption:
device = "/dev/mapper/pm_crypt" device = "/dev/mapper/pm_crypt"
else:
device = "/dev/installp2"
# Format # Format
if not args.rsync: if not args.rsync:
@ -72,7 +75,11 @@ def format_and_mount_pm_crypt(args):
pmb.chroot.root(args, ["mount", device, mountpoint]) pmb.chroot.root(args, ["mount", device, mountpoint])
def format(args): def format(args, size_reserve):
format_and_mount_root(args) """
format_and_mount_pm_crypt(args) :param size_reserve: empty partition between root and boot in MiB (pma#463)
"""
root_dev = "/dev/installp3" if size_reserve else "/dev/installp2"
format_and_mount_root(args, root_dev)
format_and_mount_pm_crypt(args, root_dev)
format_and_mount_boot(args) format_and_mount_boot(args)

View File

@ -8,9 +8,10 @@ import pmb.config
import pmb.install.losetup import pmb.install.losetup
def partitions_mount(args): def partitions_mount(args, root_id):
""" """
Mount blockdevices of partitions inside native chroot Mount blockdevices of partitions inside native chroot
:param root_id: root partition id
""" """
prefix = args.sdcard prefix = args.sdcard
if not args.sdcard: if not args.sdcard:
@ -35,22 +36,28 @@ def partitions_mount(args):
prefix + " to be located at " + prefix + prefix + " to be located at " + prefix +
"1 or " + prefix + "p1!") "1 or " + prefix + "p1!")
for i in [1, 2]: for i in [1, root_id]:
source = prefix + partition_prefix + str(i) source = prefix + partition_prefix + str(i)
target = args.work + "/chroot_native/dev/installp" + str(i) target = args.work + "/chroot_native/dev/installp" + str(i)
pmb.helpers.mount.bind_file(args, source, target) pmb.helpers.mount.bind_file(args, source, target)
def partition(args, size_boot): def partition(args, size_boot, size_reserve):
""" """
Partition /dev/install and create /dev/install{p1,p2} Partition /dev/install and create /dev/install{p1,p2,p3}:
* /dev/installp1: boot
* /dev/installp2: root (or reserved space)
* /dev/installp3: (root, if reserved space > 0)
:param size_boot: size of the boot partition in MiB :param size_boot: size of the boot partition in MiB
:param size_reserve: empty partition between root and boot in MiB (pma#463)
""" """
# Convert to MB and print info # Convert to MB and print info
mb_boot = str(round(size_boot)) + "M" mb_boot = f"{round(size_boot)}M"
logging.info("(native) partition /dev/install (boot: " + mb_boot + mb_reserved = f"{round(size_reserve)}M"
", root: the rest)") mb_root_start = f"{round(size_boot) + round(size_reserve)}M"
logging.info(f"(native) partition /dev/install (boot: {mb_boot},"
f" reserved: {mb_reserved}, root: the rest)")
filesystem = args.deviceinfo["boot_filesystem"] or "ext2" filesystem = args.deviceinfo["boot_filesystem"] or "ext2"
@ -63,9 +70,16 @@ def partition(args, size_boot):
commands = [ commands = [
["mktable", "msdos"], ["mktable", "msdos"],
["mkpart", "primary", filesystem, boot_part_start + 's', mb_boot], ["mkpart", "primary", filesystem, boot_part_start + 's', mb_boot],
["mkpart", "primary", mb_boot, "100%"], ]
if size_reserve:
commands += [["mkpart", "primary", mb_boot, mb_reserved]]
commands += [
["mkpart", "primary", mb_root_start, "100%"],
["set", "1", "boot", "on"] ["set", "1", "boot", "on"]
] ]
for command in commands: for command in commands:
pmb.chroot.root(args, ["parted", "-s", "/dev/install"] + pmb.chroot.root(args, ["parted", "-s", "/dev/install"] +
command, check=False) command, check=False)