With recent rework in postmarketos-initramfs, we no longer need to mount
the /boot partition in the initramfs (assuming initramfs-extra is not
used). On devices that boot without accessing the boot file system (e.g.
Android boot images, fastboot, ...), that makes it possible to install
postmarketOS on a single (potentially encrypted) partition that contains
both root (/) and /boot files.
This avoids the extra complexity of the subpartition setup we usually use
on such devices, and also avoids having to flash two partitions (when using
--split to avoid the subpartitions).
Add a --single-partition option to pmbootstrap install that allows
installing postmarketOS in this mode. For now this is just an option that
must be selected explicitly, in the future we could choose to make this the
default for Android-based devices with a large enough boot partition.
Part-of: https://gitlab.postmarketos.org/postmarketOS/pmbootstrap/-/merge_requests/2512
This adds support for using an environment variable to set the FDE
passphrase, allowing us to automate image creation when using FDE.
The method used here was borrowed from how we set the password with when
using the --password arg: write to a temp file, call something in the
chroot to read/use it, then remove it.
Part-of: https://gitlab.postmarketos.org/postmarketOS/pmbootstrap/-/merge_requests/2538
After setting "-T big", we still saw some images failing with "out of
space" errors in bpo, such as "v24.12:samsung-espresso10:xfce4".
I've looked at /etc/mke2fs.conf to figure out what exactly gets
configured with "-T big". What I did not realize is that the inode
ratio gets bigger by going from small -> big, big -> huge, but with a
larger ratio FEWER inodes will be created (see man mkfs.ext4, -i
bytes-per-inode).
In /etc/mke2fs.conf in Alpine edge:
[defaults]
…
blocksize = 4096
inode_size = 256
inode_ratio = 16384
[fs_types]
…
small = {
blocksize = 1024
inode_ratio = 4096
}
floppy = {
blocksize = 1024
inode_ratio = 8192
}
big = {
inode_ratio = 32768
}
huge = {
inode_ratio = 65536
}
news = {
inode_ratio = 4096
}
…
So I've tried out half the ratio value we get with "big" now, 16384.
With that we finally seem to have:
* Enough inodes for small UIs (console, none) as well as big UIs with
lots of files (xfce4, plasma-desktop, ...)
* We don't directly specify an inode count (-N) anymore as we did
earlier, which had problems with small images as the inode count would
be too large for the given image size (pmb#2572).
Test builds with various images:
Filesystem Inodes Used Available Use% Mounted on
master:postmarketos-trailblazer:none:
/dev/installp2 35440 5111 30329 14% /mnt/install
master:postmarketos-trailblazer:console:
/dev/installp2 47232 8713 38519 18% /mnt/install
master:pine64-pinebookpro:plasma-desktop:
/dev/installp2 276352 100607 175745 36% /mnt/install
v24.12:samsung-espresso10:xfce4:
/dev/installp2 80960 51150 29810 63% /mnt/install
So the most Use% I could get is 63% with this, leaving a nice margin for
the future.
Using "-N" to set a specific inode count caused errors:
* With 100K, we got "out of space" errors when creating images for
bigger UIs with many small files like:
pine64-pinebookpro:plasma-desktop
* With 1M (current value), we got "out of space" for small images like:
postmarketos-trailblazer:console
Use "-T big" instead to set the usage-type that is closest to how we
expect the filesystem to be used, once it is flashed to the user's
device and resized. This will indirectly set the bytes-per-inode. I've
verified that building both the big
pine64-pinebookpro:plasma-desktop and small
postmarketos-trailblazer:console (and even with UI=none) works with
this change.
I've verified that building both the small image works with this.
From the mkfs.ext4 man page:
-T usage-type[,...]
Specify how the file system is going to be used, so that mke2fs
can choose optimal file system parameters for that use. The
usage types that are supported are defined in the configuration
file /etc/mke2fs.conf. The user may specify one or more usage
types using a comma separated list.
If this option is is not specified, mke2fs will pick a single
default usage type based on the size of the file system to be
created. If the file system size is less than 3 megabytes,
mke2fs will use the file system type floppy. If the file system
size is greater than or equal to 3 but less than 512 megabytes,
mke2fs(8) will use the file system type small. If the file
system size is greater than or equal to 4 terabytes but less
than 16 terabytes, mke2fs(8) will use the file system type big.
If the file system size is greater than or equal to 16
terabytes, mke2fs(8) will use the file system type huge.
Otherwise, mke2fs(8) will use the default file system type
default.
Fixes: d0d7c2d4 ("pmb.install.format: set ext4 usage-type to big")
Fixes: issue 2572
Make 10x the amount of inodes available for ext4 partitions when using
"pmbootstrap install" without the "--disk" argument so we won't run out
for sure. The previous value was not enough in some edge cases. We do
need to set this as the default is not enough either.
Fixes: issue 2568
Introduce a Deviceinfo class and use it rather than the dictionary. This
gives us sweet sweet autocomplete, and lays the foundation for having a
proper deviceinfo validator in the future.
Additionally, continue refactoring out args...
Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
Cease merging pmbootstrap.cfg into args, implement a Context type to let
us pull globals out of thin air (as an intermediate workaround) and rip
args out of a lot of the codebase.
This is just a first pass, after this we can split all the state that
leaked over into Context into types with narrower scopes (like a
BuildContext(), etc).
Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
We use a custom verbose log level in pmbootstrap, unfortunately it isn't
possible to correctly type this due to some limitations in the logging
library [1], [2].
Given that our usecase is fairly simple, we can just wrap the module
with our own so we only have to tell mypy to ignore the error once
instead of at every callsite.
[1]: https://github.com/cryptax/droidlysis/issues/15
[2]: https://github.com/python/typing/discussions/980
Signed-off-by: Caleb Connolly <caleb@postmarketos.org>
Introduce a new module: pmb.core to contain explicitly typed pmbootstrap
API. The first component being Suffix and SuffixType. This explicitly
defines what suffixes are possible, future changes should aim to further
constrain this API (e.g. by validating against available device
codenames or architectures for buildroot suffixes).
Additionally, migrate the entire codebase over to using pathlib.Path.
This is a relatively new part of the Python standard library that uses a
more object oriented model for path handling. It also uses strong type
hinting and has other features that make it much cleaner and easier to
work with than pure f-strings. The Chroot class overloads the "/"
operator the same way the Path object does, allowing one to write paths
relative to a given chroot as:
builddir = chroot / "home/pmos/build"
The Chroot class also has a string representation ("native", or
"rootfs_valve-jupiter"), and a .path property for directly accessing the
absolute path (as a Path object).
The general idea here is to encapsulate common patterns into type hinted
code, and gradually reduce the amount of assumptions made around the
codebase so that future changes are easier to implement.
As the chroot suffixes are now part of the Chroot class, we also
implement validation for them, this encodes the rules on suffix naming
and will cause a runtime exception if a suffix doesn't follow the rules.
Why
Btrfs has some goodness (snapshots, switching between different rw snapshot)
which plays particularly well with certain "subvolume layouts".
What
This MR seeks to implement such a layout, namely a flat btrfs layout,
where the top level subvolume (i.e. the btrfs filesystem/partition itself)
remains unmounted in all situations,
except when making changes to direct child subvolumes of the filesystem.
- rename all subvols to follow the common @* btrfs subvol naming scheme.
- add subvol @root, because roots home directory shouldn't be rolled back.
- make subvol @var not Copy-on-Write (nodatacow) to avoid write
- multiplication on logs, VMs, databases, containers and flatpaks.
- add subvol @snapshots because that lets us change the root subvol to a
read-write snapshot of @ without affecting snapshots.
- add subvol @srv because it contains data for Web and FTP servers,
which shouldn't roll back together with root subvol.
- add subvol @tmp because we don't want to snapshot temporary files.
This subvol remains unmounted on the device,
unless conditions as laid out in pmaports!4737 are met.
- add check and error for btrfs when using rsync installation.
Stock bootloader on these devices boots kernel (it is intended to boot
kernel, but i place secondary bootloader there) from special ChromeOS
kernel partition on special GPT which is created with cgpt utility.
This MR adds initial support for it introducing new deviceinfo options:
- cgpt_kpart - path to file to be flashed to ChromeOS partition;
- cgpt_kpart_start - offset from the start in sectors;
- cgpt_kpart_size - partition size in sectors.
For example:
deviceinfo_cgpt_kpart="/usr/share/u-boot/google-peach-pit/u-boot-dtb.img.kpart"
deviceinfo_cgpt_kpart_start="8192"
deviceinfo_cgpt_kpart_size="32768"
cgpt requires start and size values of partition, so these values
are calculated for each partition.
Reserved size and on-device installer are not yet supported.
Reference: https://archlinuxarm.org/platforms/armv7/samsung/samsung-chromebook
"Keeping track of which partition number is what is hard to understand now.
I think this should be refactored, so we have it defined only in one
place, and easy to read. Since this merge request increases the complexity
of the partitions again, let's do it here before merging." - Oliver
Co-Authored-By: Oliver Smith <ollieparanoid@postmarketos.org>
Do not attempt to install with a filesystem that is not supported by the
initramfs code in the checked out pmaports branch.
Previously we would have increased the pmaports.cfg version and require
that new version by pmbootstrap, however this will break compatibility
with release branches where we won't roll out this feature (v20.05).
Therefore don't change the version, but add a new
"supported_root_filesystems" key to pmaports.cfg, which defaults to
"ext4".
Related: https://postmarketos.org/pmaports.cfg
Install specific filesystem tools right before they are needed, instead
of installing all filesystem tools that we might need beforehand. This
is in preparation to support f2fs.
Co-Authored-By: Oliver Smith <ollieparanoid@postmarketos.org>
Add comments to two functions, that if they are changed, the logic also
needs to be updated in ondev-preapre-internal-storage.sh of
postmarketos-ondev.git.
Change 'cryptsetup luksFormat' arguments to use --use-random instead of
--use-urandom. urandom is not recommended for the generation of long-term
cryptographic keys, as it may generate weak keys in low entropy
situations.
format_and_mount_root() => format_luks_root():
* Rename to reflect what it's actually doing
* Move the FDE check from format_luks_root to the only caller
* Make arguments to "cryptsetup luksFormat" more readable
format_and_mount_pm_crypt() => format_and_mount_root():
* Rename to reflect what it's actually doing
* Don't overwrite device if doing FDE; instead provide the proper device
in the caller
The old function names were for historic reasons, early on it was only
possible to create encrypted installations with pmbootstrap.
While at it, also remove unnecessary "#!/usr/bin/env python3" in files
that only get imported, and adjust other empty/comment lines in the
beginnings of the files for consistency.
This makes files easier to read, and makes the pmbootstrap codebase more
consistent with the build.postmarketos.org codebase.
This fixes#1845 without breaking #1717 (closed). The amount of inodes
only needs to be explicitly set when we don't know the size of the
filesystem before hand, for example when using fastboot or Heimdall. In
all other cases it's actually better to let it figure out automatically
how many inodes is set.
On my 16GB sdcard the amount of available inodes got increased by 10
times (from ~100K to ~1M).
This drops the --apparent-size parameter when calculating the size
required for rootfs, which seemed to return a size that was too small
for some devices. This also includes specifying the number of inodes to
support when formatting rootfs.
Fixes#1717