pmbootstrap install: support size_reserve

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
parent d8c84c8912
commit 67e3c5ad1a
No known key found for this signature in database
GPG Key ID: 5AE7F5513E0885CB
5 changed files with 57 additions and 26 deletions

View File

@ -137,8 +137,9 @@ def chroot(args):
if args.install_blockdev:
size_boot = 128 # 128 MB
size_root = 4096 # 4 GB
size_reserve = 2048 # 2 GB
pmb.install.blockdevice.create_and_mount_image(args, size_boot,
size_root)
size_root, size_reserve)
# Run the command as user/root
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))
def install_system_image(args):
def install_system_image(args, size_reserve=0):
"""
:param size_reserve: empty partition between root and boot in MB (pma#463)
"""
# Partition and fill image/sdcard
logging.info("*** (3/5) PREPARE INSTALL BLOCKDEVICE ***")
pmb.chroot.shutdown(args, True)
(size_boot, size_root) = get_subpartitions_size(args)
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:
pmb.install.partition(args, size_boot)
pmb.install.partition(args, size_boot, size_reserve)
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:
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("you have properly configured osk-sdl. More information:")
logging.info("<https://postmarketos.org/osk-port>")
pmb.install.format(args)
pmb.install.format(args, size_reserve)
# Just copy all the files
logging.info("*** (4/5) FILL INSTALL BLOCKDEVICE ***")

View File

@ -54,12 +54,14 @@ def mount_sdcard(args):
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.
:param size_boot: size of the boot partition in MB
:param size_root: size of the root partition in MB
:param size_reserve: empty partition between root and boot in MB (pma#463)
: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])
# 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)
free = round((disk_data.f_bsize * disk_data.f_bavail) / (1024**2))
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)
def create(args, size_boot, size_root):
def create(args, size_boot, size_root, size_reserve):
"""
Create /dev/install (the "install blockdevice").
:param size_boot: size of the boot partition in MB
:param size_root: size of the root partition in MB
:param size_reserve: empty partition between root and boot in MB (pma#463)
"""
pmb.helpers.mount.umount_all(
args, args.work + "/chroot_native/dev/install")
if args.sdcard:
mount_sdcard(args)
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])
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"
device = "/dev/installp2"
if args.full_disk_encryption:
logging.info("(native) format " + device + " (root, luks), mount to " +
mountpoint)
@ -41,12 +43,13 @@ def format_and_mount_root(args):
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
if args.full_disk_encryption:
device = "/dev/mapper/pm_crypt"
else:
device = "/dev/installp2"
# Format
if not args.rsync:
@ -72,7 +75,11 @@ def format_and_mount_pm_crypt(args):
pmb.chroot.root(args, ["mount", device, mountpoint])
def format(args):
format_and_mount_root(args)
format_and_mount_pm_crypt(args)
def format(args, size_reserve):
"""
:param size_reserve: empty partition between root and boot in MB (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)

View File

@ -8,9 +8,10 @@ import pmb.config
import pmb.install.losetup
def partitions_mount(args):
def partitions_mount(args, root_id):
"""
Mount blockdevices of partitions inside native chroot
:param root_id: root partition id (3 with --reserve-space, otherwise 2)
"""
prefix = args.sdcard
if not args.sdcard:
@ -35,22 +36,28 @@ def partitions_mount(args):
prefix + " to be located at " + prefix +
"1 or " + prefix + "p1!")
for i in [1, 2]:
for i in [1, root_id]:
source = prefix + partition_prefix + str(i)
target = args.work + "/chroot_native/dev/installp" + str(i)
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 MB
:param size_reserve: empty partition between root and boot in MB (pma#463)
"""
# Convert to MB and print info
mb_boot = str(round(size_boot)) + "M"
logging.info("(native) partition /dev/install (boot: " + mb_boot +
", root: the rest)")
mb_boot = f"{round(size_boot)}M"
mb_reserved = f"{round(size_reserve)}M"
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"
@ -63,9 +70,16 @@ def partition(args, size_boot):
commands = [
["mktable", "msdos"],
["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"]
]
for command in commands:
pmb.chroot.root(args, ["parted", "-s", "/dev/install"] +
command, check=False)