Compare commits
9
Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
b4aed77e58 | ||
|
|
71cd0d66b4 | ||
|
|
5a89f02432 | ||
|
|
80516ba181 | ||
|
|
0022ba277f | ||
|
|
acd2f0c57e | ||
|
|
2588d5370f | ||
|
|
4de256ea48 | ||
|
|
2b03a8bd35 |
No files matched your search
@@ -5,7 +5,7 @@ maintainer="Casey Connolly <kcxt@postmarketos.org>"
|
||||
_flavor="postmarketos-qcom-sdm845"
|
||||
pkgname=linux-$_flavor
|
||||
pkgver=6.16.7
|
||||
pkgrel=3
|
||||
pkgrel=999
|
||||
pkgdesc="Mainline Kernel fork for SDM845 devices"
|
||||
arch="aarch64"
|
||||
_carch="arm64"
|
||||
@@ -85,6 +85,6 @@ package() {
|
||||
|
||||
sha512sums="
|
||||
803d2cf85b248c3da41a9c9178d69d211eccf5d1adb72acd5343e09cbb65782f727e579939287c91712c69a862bed7344a0e2bc893c2791a971b6fed95ec6f1a linux-sdm845-6.16.7-r0.tar.gz
|
||||
57f744a06dd664d6ba7efec82ab1d8101d5b83dce424a388df95467183aa7c2d2fabf3a9e34271cd00e28eb731b74ef09e9613384765cf6eff7a6e2bd27b2c1d config-postmarketos-qcom-sdm845.aarch64
|
||||
b6bac51d8eb626eb861c934d89a1ad81dc7cbc32d5d8f9418f051334ed4ef5f817719cb45b82c6837b034961026ceaa524ed98772a52a5e029575792007c7425 config-postmarketos-qcom-sdm845.aarch64
|
||||
fbd04f5f429ca1067dadb4209d5279e5fd3cfb4a5ae5957e8e189488109a6cf44d27aa1f38cceb78e1cc360d3020b0c4342ca768243eb6ba7460093a1306b98c 0001-arm64-dts-qcom-sdm845-xiaomi-beryllium-Fix-compatibl.patch
|
||||
"
|
||||
+21
-6
@@ -2,17 +2,18 @@
|
||||
# Automatically generated file; DO NOT EDIT.
|
||||
# Linux/arm64 6.16.7 Kernel Configuration
|
||||
#
|
||||
CONFIG_CC_VERSION_TEXT="Alpine clang version 21.1.2"
|
||||
CONFIG_CC_VERSION_TEXT="Alpine clang version 21.1.8"
|
||||
CONFIG_GCC_VERSION=0
|
||||
CONFIG_CC_IS_CLANG=y
|
||||
CONFIG_CLANG_VERSION=210102
|
||||
CONFIG_CLANG_VERSION=210108
|
||||
CONFIG_AS_IS_LLVM=y
|
||||
CONFIG_AS_VERSION=210102
|
||||
CONFIG_AS_VERSION=210108
|
||||
CONFIG_LD_VERSION=0
|
||||
CONFIG_LD_IS_LLD=y
|
||||
CONFIG_LLD_VERSION=210102
|
||||
CONFIG_LLD_VERSION=210108
|
||||
CONFIG_RUSTC_VERSION=0
|
||||
CONFIG_RUSTC_LLVM_VERSION=0
|
||||
CONFIG_CC_CAN_LINK=y
|
||||
CONFIG_CC_HAS_ASM_GOTO_OUTPUT=y
|
||||
CONFIG_CC_HAS_ASM_GOTO_TIED_OUTPUT=y
|
||||
CONFIG_TOOLS_SUPPORT_RELR=y
|
||||
@@ -2264,7 +2265,9 @@ CONFIG_DM_THIN_PROVISIONING=y
|
||||
# CONFIG_DM_INIT is not set
|
||||
# CONFIG_DM_UEVENT is not set
|
||||
# CONFIG_DM_FLAKEY is not set
|
||||
# CONFIG_DM_VERITY is not set
|
||||
CONFIG_DM_VERITY=y
|
||||
# CONFIG_DM_VERITY_VERIFY_ROOTHASH_SIG is not set
|
||||
# CONFIG_DM_VERITY_FEC is not set
|
||||
# CONFIG_DM_SWITCH is not set
|
||||
# CONFIG_DM_LOG_WRITES is not set
|
||||
CONFIG_DM_INTEGRITY=y
|
||||
@@ -8173,7 +8176,19 @@ CONFIG_PSTORE_PMSG=y
|
||||
CONFIG_PSTORE_RAM=y
|
||||
# CONFIG_PSTORE_BLK is not set
|
||||
# CONFIG_UFS_FS is not set
|
||||
# CONFIG_EROFS_FS is not set
|
||||
CONFIG_EROFS_FS=m
|
||||
# CONFIG_EROFS_FS_DEBUG is not set
|
||||
CONFIG_EROFS_FS_XATTR=y
|
||||
CONFIG_EROFS_FS_POSIX_ACL=y
|
||||
CONFIG_EROFS_FS_SECURITY=y
|
||||
CONFIG_EROFS_FS_BACKED_BY_FILE=y
|
||||
CONFIG_EROFS_FS_ZIP=y
|
||||
# CONFIG_EROFS_FS_ZIP_LZMA is not set
|
||||
# CONFIG_EROFS_FS_ZIP_DEFLATE is not set
|
||||
# CONFIG_EROFS_FS_ZIP_ZSTD is not set
|
||||
# CONFIG_EROFS_FS_ZIP_ACCEL is not set
|
||||
# CONFIG_EROFS_FS_ONDEMAND is not set
|
||||
# CONFIG_EROFS_FS_PCPU_KTHREAD is not set
|
||||
CONFIG_NETWORK_FILESYSTEMS=y
|
||||
CONFIG_NFS_FS=y
|
||||
# CONFIG_NFS_V2 is not set
|
||||
|
||||
@@ -0,0 +1,93 @@
|
||||
# Maintainer: Clayton Craft <clayton@craftyguy.net>
|
||||
pkgname=postmarketos-duranium
|
||||
pkgver=1
|
||||
pkgrel=0
|
||||
pkgdesc="Configuration files for building and booting immutable postmarketOS images"
|
||||
url="https://postmarketos.org"
|
||||
options="!check" # no tests
|
||||
depends="
|
||||
f0rmz
|
||||
losetup
|
||||
sfdisk
|
||||
shadow
|
||||
tar
|
||||
unl0kr
|
||||
"
|
||||
# x86: f0rmz
|
||||
arch="noarch !x86"
|
||||
license="GPL-3.0-or-later"
|
||||
replaces="systemd" # For overwriting tmpfiles.d/{opt,var}.conf
|
||||
|
||||
_source644="
|
||||
usr/lib/repart.d/00-esp.conf
|
||||
usr/lib/repart.d/10-usr-verity-sig.conf
|
||||
usr/lib/repart.d/11-usr-verity.conf
|
||||
usr/lib/repart.d/12-usr.conf
|
||||
usr/lib/repart.d/20-usr-verity-sig.conf
|
||||
usr/lib/repart.d/21-usr-verity.conf
|
||||
usr/lib/repart.d/22-usr.conf
|
||||
usr/lib/repart.d/30-root.conf
|
||||
usr/lib/systemd/system-preset/80-duranium.preset
|
||||
usr/lib/systemd/system/systemd-veritysetup@usr.service.d/10-skip-usr-verified.conf
|
||||
usr/lib/sysupdate.d/10-usr-verity-sig.transfer
|
||||
usr/lib/sysupdate.d/11-usr-verity.transfer
|
||||
usr/lib/sysupdate.d/12-usr.transfer
|
||||
usr/lib/sysupdate.d/20-uki.transfer
|
||||
usr/lib/sysusers.d/10-pmos-user.conf
|
||||
usr/lib/tmpfiles.d/opt.conf
|
||||
usr/lib/tmpfiles.d/var.conf
|
||||
usr/share/f0rmz/f0rmz.conf.d/firstboot.conf
|
||||
usr/share/initramfs/init_functions_immutable.sh
|
||||
usr/share/mkinitfs/files-extra/10-duranium-base.files
|
||||
usr/share/mkinitfs/modules-extra/10-duranium-base.modules
|
||||
"
|
||||
|
||||
_source755="
|
||||
usr/bin/do-factory-reset
|
||||
etc/profile.d/99-local-bin.sh
|
||||
"
|
||||
|
||||
# Avoid filename based checksum conflicts by including the whole path:
|
||||
# https://gitlab.alpinelinux.org/alpine/abuild/-/issues/10013
|
||||
flatpath() {
|
||||
local i
|
||||
for i in $@; do
|
||||
echo "rootfs-$i" | sed s./.-.g
|
||||
done
|
||||
}
|
||||
source="$(flatpath $_source440 $_source600 $_source644 $_source755)"
|
||||
|
||||
package() {
|
||||
for i in $_source644; do
|
||||
install -Dm644 "$srcdir/$(flatpath "$i")" "$pkgdir/$i"
|
||||
done
|
||||
for i in $_source755; do
|
||||
install -Dm755 "$srcdir/$(flatpath "$i")" "$pkgdir/$i"
|
||||
done
|
||||
}
|
||||
|
||||
sha512sums="
|
||||
b0f320f2ea81c29fa9030abac998e725e098c74bb2ffb76ee2711da4c88615ad46a0e5359b98198648879551781580a0128b57a2ef1ca6a3e03448b01f533065 rootfs-usr-lib-repart.d-00-esp.conf
|
||||
be7f90bd96fcad6ccf2b434a4b9ce9bc620b63558df0eddd088d86bcbeb778ff097b6d7db0a021d4322bb2ff908eb65f41840e10b11a479e15986a0b02331bf0 rootfs-usr-lib-repart.d-10-usr-verity-sig.conf
|
||||
8dab35b6c5b61936a8a5f7c6872efe77550f70603a90286c874e9b3c12b25214823c89dd32517b0733110a2f92d0908d0adb6a7bff68f83163d2882e4167b4f6 rootfs-usr-lib-repart.d-11-usr-verity.conf
|
||||
a2ebcf35620a8c2dcd06dff50b6d17b02e8b688f98c6f7e1bb9727733df20742669cb3926a003ccdb1091bc8a337fdc39cc774de509f1b155f3bd3b45a86f8ef rootfs-usr-lib-repart.d-12-usr.conf
|
||||
9aa66e6472ce58da316357c61b8a1538d0d8829f6568ec404efc58ea7ad5d06f5f806cb7e1bf726eb9941181971d0f7131c34a446a52eedc96f3388d1c31c18f rootfs-usr-lib-repart.d-20-usr-verity-sig.conf
|
||||
1c452cec92a07859e7bed68ea6b67143d9329446db36eb4aa796424609cc6d96ad2e19d8be53bba776fc2efa75b02c87ec7557eaf233926afd1609611f38a81a rootfs-usr-lib-repart.d-21-usr-verity.conf
|
||||
f1833d1627640a30dcb7aebc4ad4296c00f1799168712bf556e54ce74f7e56002b0a37e42ea20bfd10a02d32a9e7b7750c6e8d1b957c416903cd6e1bb19d25c6 rootfs-usr-lib-repart.d-22-usr.conf
|
||||
ee77d7903f108ef3566ca99091e95aeefc70f19930fe635b6110c71566225beb9675356162628efeb5d4c5cc6e386127035d8c34fdbe5ca28b123b69f4e15ddc rootfs-usr-lib-repart.d-30-root.conf
|
||||
52a0cddde45bf17e7a7274b804ec818bf7a471ec6fe365931f8e14e2f7279111e9724cbd9941c66ee638e92ecb3579a269e75912130590fc4856bd00b7b86a23 rootfs-usr-lib-systemd-system-preset-80-duranium.preset
|
||||
d8de011bdaa98045b23fe37540663371602bb48f75314343c60faab39e7cd4f336ace6eddde745517bb99d8b5f3bf40d78584bd3535375b5f5fc9c7ae03de315 rootfs-usr-lib-systemd-system-systemd-veritysetup@usr.service.d-10-skip-usr-verified.conf
|
||||
2e4d532a0d996d8e68007b6036b4564ca3d654dd91cadd80ed904536d0c3ed1e019b4081f7bdb6d128e695cacfe6949bfb20c074b95d10ef25f948f8eb307e24 rootfs-usr-lib-sysupdate.d-10-usr-verity-sig.transfer
|
||||
2dbe55c05b8237ad85c4f333a8c02eec26aad14032f159830696ad9b9c6442d624b0190b2e6780e4b8aed590eb12d0c7454d39ab739e55d420300cdba2a78f58 rootfs-usr-lib-sysupdate.d-11-usr-verity.transfer
|
||||
14df73dfc786a249b300f8998b1f51301834cf058b65c95701b1350f112d2c3deed3b8db9ba439bd90537cef533f148d187bd73961707dca12ef84735e2d5595 rootfs-usr-lib-sysupdate.d-12-usr.transfer
|
||||
4ffb2be01cb033c1282b6661052250937e1ac457cec3900b075d0dcdf59de7dcb2eb927c39db0e96468a90b03fed0a4e6db0d99f62d714c31a29d4684e79751f rootfs-usr-lib-sysupdate.d-20-uki.transfer
|
||||
fa1c3dd727fd20d16d18695d58dd10ec335d64ece00152346c84ae750ed5ade8faf5ba11747135d79972dd1a3f4f1ab496ae9425ebcf7232a4203ca9396fa7e0 rootfs-usr-lib-sysusers.d-10-pmos-user.conf
|
||||
0779c6d5959aef0e325adb69f3e0720a3f271f474c0f14e9c830f015c923c432d07222a24ce722a3ea58670d2eff3536d45bcaf7ae848b587676f1586a348e0e rootfs-usr-lib-tmpfiles.d-opt.conf
|
||||
7d98cb314472d7db64599c8abfc2e21ef6437b0c5bf407f0c21a42ec2f14f660fb3aef64c99a13aada124a822a85d8e4a6674838d1fe07719774331121d5414b rootfs-usr-lib-tmpfiles.d-var.conf
|
||||
4aa9c49faa69f66750eec519762fbf85715a9ce0882764b4dece795e391bead4dd6a02a5773e3a81382a8405f57a1e2f70fce31ae6e54c5182c9f2baf30993dd rootfs-usr-share-f0rmz-f0rmz.conf.d-firstboot.conf
|
||||
5549b0745a15ba4a11769cb2adf29695ddea1f16823b73f3ada5e85e4caecdf3f9fd2295ac95f0fdf9ef72e737ea058dc90e2a81b268b04d1993a0033053e9c2 rootfs-usr-share-initramfs-init_functions_immutable.sh
|
||||
38d93277341c9f21b28b1b6167fefa73377dbec61e4c8fdb56d8cb5688ce231371e6366a284074cdf64e90f46b893a70a64e98cc478f86f5f984d7db26bf53eb rootfs-usr-share-mkinitfs-files-extra-10-duranium-base.files
|
||||
99325a25d1a588923bf55c9c803ea6aa8d7b7e82b929e4edafc47b39630d0c229bda89ea3afff1adde4136c2378ffb8ef24a4edbac015032975f40edcbad74ed rootfs-usr-share-mkinitfs-modules-extra-10-duranium-base.modules
|
||||
97bce380b5c4019aafad6f52856586ffaa4e17efd83f61f133e197bd833a35140406d206f572fb38444c42051b0d1dc789f44313aaf63bf0d4028499cc942b7e rootfs-usr-bin-do-factory-reset
|
||||
765797421f9123cdcf85e1496d01884cce1c8c304d15369b7eee32a8fc5abcd860dc5856c0d493f1cd3c6ad2a0ccdc4d6ba7d2ae356f0fc824dc16cdb84ebf37 rootfs-etc-profile.d-99-local-bin.sh
|
||||
"
|
||||
@@ -0,0 +1 @@
|
||||
export PATH="$PATH:$HOME/.local/bin"
|
||||
@@ -0,0 +1,84 @@
|
||||
#!/bin/sh
|
||||
# Factory reset script for postmarketOS
|
||||
# Sets EFI variable to trigger factory reset on next boot
|
||||
|
||||
set -e
|
||||
|
||||
# Check if running as root
|
||||
if [ "$(id -u)" -ne 0 ]; then
|
||||
echo "Error: This script must be run as root" >&2
|
||||
echo "Try: doas $0" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# EFI variable path
|
||||
EFIVAR_PATH="/sys/firmware/efi/efivars/FactoryReset-8cf2644b-4b0b-428f-9387-6d876050dc67"
|
||||
|
||||
# Check if EFI variables are available
|
||||
if [ ! -d "/sys/firmware/efi/efivars" ]; then
|
||||
echo "Error: EFI variables not available (not booted with UEFI?)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Check if factory reset is supported by checking for repart configs
|
||||
if ! systemd-repart --can-factory-reset >/dev/null 2>&1; then
|
||||
echo "Error: Factory reset not supported (no partitions marked FactoryReset=yes)" >&2
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Warn user and ask for confirmation
|
||||
echo "WARNING: This will erase all user data and reset the system to factory defaults!"
|
||||
echo "This action cannot be undone."
|
||||
echo
|
||||
printf "Are you sure you want to continue? (yes/no): "
|
||||
read -r response
|
||||
|
||||
case "$response" in
|
||||
yes|YES)
|
||||
echo "Proceeding with factory reset..."
|
||||
;;
|
||||
*)
|
||||
echo "Factory reset cancelled."
|
||||
exit 0
|
||||
;;
|
||||
esac
|
||||
|
||||
# Remove existing EFI variable if it exists
|
||||
if [ -f "$EFIVAR_PATH" ]; then
|
||||
echo "Removing existing FactoryReset variable..."
|
||||
# Clear immutable attribute if set
|
||||
if ! chattr -i "$EFIVAR_PATH"; then
|
||||
echo "Warning: Failed to clear immutable attribute, removal may fail" >&2
|
||||
fi
|
||||
if ! rm "$EFIVAR_PATH"; then
|
||||
echo "Error: Failed to remove existing EFI variable" >&2
|
||||
echo "Try manually: chattr -i $EFIVAR_PATH && rm $EFIVAR_PATH" >&2
|
||||
exit 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create EFI variable
|
||||
# Format: 4-byte attributes (0x07 = NON_VOLATILE | BOOTSERVICE_ACCESS | RUNTIME_ACCESS) + "yes"
|
||||
echo "Creating FactoryReset EFI variable..."
|
||||
if printf '\x07\x00\x00\x001\x00\x00\x00' > "$EFIVAR_PATH"; then
|
||||
echo "Factory reset EFI variable set successfully."
|
||||
echo "System will factory reset on next boot."
|
||||
echo
|
||||
printf "Reboot now? (yes/no): "
|
||||
read -r reboot_response
|
||||
|
||||
case "$reboot_response" in
|
||||
yes|YES)
|
||||
echo "Rebooting..."
|
||||
reboot
|
||||
;;
|
||||
*)
|
||||
echo "Factory reset is scheduled for next boot."
|
||||
echo "Run 'reboot' when ready to perform the reset."
|
||||
;;
|
||||
esac
|
||||
else
|
||||
echo "Error: Failed to set EFI variable" >&2
|
||||
echo "Check if EFI variables are writable and try again" >&2
|
||||
exit 1
|
||||
fi
|
||||
@@ -0,0 +1,6 @@
|
||||
[Partition]
|
||||
Type=esp
|
||||
Format=vfat
|
||||
CopyFiles=/boot:/
|
||||
SizeMinBytes=1G
|
||||
SizeMaxBytes=1G
|
||||
@@ -0,0 +1,4 @@
|
||||
[Partition]
|
||||
Type=usr-verity-sig
|
||||
Label=%M_%A_vts
|
||||
CopyBlocks=auto
|
||||
@@ -0,0 +1,4 @@
|
||||
[Partition]
|
||||
Type=usr-verity
|
||||
Label=%M_%A_vty
|
||||
CopyBlocks=auto
|
||||
@@ -0,0 +1,4 @@
|
||||
[Partition]
|
||||
Type=usr
|
||||
Label=%M_%A_usr
|
||||
CopyBlocks=auto
|
||||
@@ -0,0 +1,5 @@
|
||||
[Partition]
|
||||
Type=usr-verity-sig
|
||||
Label=_empty
|
||||
SizeMinBytes=16K
|
||||
SizeMaxBytes=16K
|
||||
@@ -0,0 +1,4 @@
|
||||
[Partition]
|
||||
Type=usr-verity
|
||||
Label=_empty
|
||||
NoAuto=1
|
||||
@@ -0,0 +1,4 @@
|
||||
[Partition]
|
||||
Type=usr
|
||||
Label=_empty
|
||||
NoAuto=1
|
||||
@@ -0,0 +1,7 @@
|
||||
[Partition]
|
||||
Type=root
|
||||
Format=btrfs
|
||||
SizeMinBytes=1G
|
||||
Weight=20000
|
||||
FactoryReset=yes
|
||||
Label=pmOS_root
|
||||
@@ -0,0 +1,2 @@
|
||||
enable systemd-sysupdate.timer
|
||||
enable systemd-sysupdated.service
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
[Unit]
|
||||
# This is the patch that the pmOS initramfs creates the mapping
|
||||
ConditionPathExists=!/dev/mapper/usr-verified
|
||||
@@ -0,0 +1,15 @@
|
||||
[Transfer]
|
||||
ProtectVersion=%A
|
||||
|
||||
[Source]
|
||||
Type=url-file
|
||||
Path=https://duranium.postmarketos.org/images/%M_%W_%w/
|
||||
MatchPattern=%M_%W_%w_@v.usr-%a-verity-sig.@u.raw.zst
|
||||
|
||||
[Target]
|
||||
Type=partition
|
||||
Path=auto
|
||||
MatchPattern=%M_@v_vts
|
||||
MatchPartitionType=usr-verity-sig
|
||||
PartitionFlags=0
|
||||
ReadOnly=1
|
||||
@@ -0,0 +1,15 @@
|
||||
[Transfer]
|
||||
ProtectVersion=%A
|
||||
|
||||
[Source]
|
||||
Type=url-file
|
||||
Path=https://duranium.postmarketos.org/images/%M_%W_%w/
|
||||
MatchPattern=%M_%W_%w_@v.usr-%a-verity.@u.raw.zst
|
||||
|
||||
[Target]
|
||||
Type=partition
|
||||
Path=auto
|
||||
MatchPattern=%M_@v_vty
|
||||
MatchPartitionType=usr-verity
|
||||
PartitionFlags=0
|
||||
ReadOnly=1
|
||||
@@ -0,0 +1,15 @@
|
||||
[Transfer]
|
||||
ProtectVersion=%A
|
||||
|
||||
[Source]
|
||||
Type=url-file
|
||||
Path=https://duranium.postmarketos.org/images/%M_%W_%w/
|
||||
MatchPattern=%M_%W_%w_@v.usr-%a.@u.raw.zst
|
||||
|
||||
[Target]
|
||||
Type=partition
|
||||
Path=auto
|
||||
MatchPattern=%M_@v_usr
|
||||
MatchPartitionType=usr
|
||||
PartitionFlags=0
|
||||
ReadOnly=1
|
||||
@@ -0,0 +1,19 @@
|
||||
[Transfer]
|
||||
ProtectVersion=%A
|
||||
|
||||
[Source]
|
||||
Type=url-file
|
||||
Path=https://duranium.postmarketos.org/images/%M_%W_%w/
|
||||
MatchPattern=%M_%W_%w_@v.efi
|
||||
|
||||
[Target]
|
||||
Type=regular-file
|
||||
Path=/EFI/Linux
|
||||
PathRelativeTo=boot
|
||||
MatchPattern=%M_%W_%w_@v+@l-@d.efi \
|
||||
%M_%W_%w_@v+@l.efi \
|
||||
%M_%W_%w_@v.efi
|
||||
Mode=0600
|
||||
TriesLeft=3
|
||||
TriesDone=0
|
||||
InstancesMax=2
|
||||
@@ -0,0 +1,6 @@
|
||||
g audio - -
|
||||
g input - -
|
||||
g netdev - -
|
||||
g plugdev - -
|
||||
g video - -
|
||||
g wheel - -
|
||||
@@ -0,0 +1,5 @@
|
||||
# Populate /opt from factory defaults
|
||||
# The 'C' directive copies if destination doesn't exist (works since /opt is empty on first boot)
|
||||
|
||||
# Copy entire /opt structure from factory on first boot
|
||||
C /opt - - - - /usr/share/factory/opt
|
||||
@@ -0,0 +1,16 @@
|
||||
# Populate /var from factory defaults
|
||||
# The 'C' directive copies if destination doesn't exist (works since /var is empty on first boot)
|
||||
|
||||
# Copy entire /var structure from factory on first boot
|
||||
C+ /var - - - - /usr/share/factory/var
|
||||
|
||||
# Additional runtime directories that may not exist in factory
|
||||
d /var/run 0755 root root -
|
||||
L /run - - - - /var/run
|
||||
|
||||
# Ensure critical runtime directories exist
|
||||
d /var/log/journal 2755 root systemd-journal -
|
||||
d /var/log/journal/%m 2755 root systemd-journal -
|
||||
d /var/tmp 1777 root root -
|
||||
d /var/cache 0755 root root -
|
||||
d /var/lib 0755 root root -
|
||||
@@ -0,0 +1,23 @@
|
||||
[intro]
|
||||
title=Welcome to postmarketOS!
|
||||
body=The next few screens will assist you with setting up your device.
|
||||
|
||||
[form.username]
|
||||
type=text
|
||||
label=Username
|
||||
required=true
|
||||
|
||||
[form.password]
|
||||
type=password
|
||||
label=Login Password
|
||||
required=true
|
||||
|
||||
[form.fde_password]
|
||||
type=password
|
||||
label=Data Encryption Password. Leave empty to disable, not recommended!
|
||||
required=false
|
||||
|
||||
[form.hostname]
|
||||
type=text
|
||||
label=Device Name
|
||||
required=false
|
||||
@@ -0,0 +1,728 @@
|
||||
#!/bin/busybox ash
|
||||
# This file will be in /init_functions_immutable.sh inside the initramfs.
|
||||
# shellcheck disable=SC3043
|
||||
|
||||
USR_PARTITION=""
|
||||
VERITY_PARTITION=""
|
||||
BOOT_DEVICE=""
|
||||
|
||||
# Mount EFI vars
|
||||
setup_efivarfs() {
|
||||
if mountpoint -q /sys/firmware/efi/efivars; then
|
||||
info "efivars already mounted"
|
||||
return 0
|
||||
fi
|
||||
info "Mounting efivars"
|
||||
modprobe efivarfs || true
|
||||
mount -t efivarfs efivarfs /sys/firmware/efi/efivars || true
|
||||
}
|
||||
|
||||
# Extract the ESP *partition* UUID from EFI's LoaderDevicePart variable
|
||||
# Uses: (none)
|
||||
# Sets: uuid variable via output parameters
|
||||
# $1: variable name to store ESP partition UUID
|
||||
get_esp_partition_uuid_from_efi() {
|
||||
local result="$1"
|
||||
local efi_var uuid
|
||||
|
||||
setup_efivarfs
|
||||
efi_var="$(ls /sys/firmware/efi/efivars/LoaderDevicePartUUID-*)"
|
||||
|
||||
if [ ! -e "$efi_var" ]; then
|
||||
echo "ERROR: LoaderDevicePartUUID not found - not booted via EFI or efivarfs failed?"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Read UUID, skip first 4 bytes (EFI attributes), convert to lowercase
|
||||
# https://docs.kernel.org/filesystems/efivarfs.html
|
||||
uuid=$(dd if="$efi_var" bs=1 skip=4 2>/dev/null | tr -d '\0' | tr '[:upper:]' '[:lower:]')
|
||||
info "Found ESP UUID: $uuid"
|
||||
|
||||
# Set the result
|
||||
if [ -n "$result" ]; then eval "$result=\"$uuid\""; fi
|
||||
}
|
||||
|
||||
# Get boot device from EFI LoaderDevicePartUUID variable
|
||||
# Sets: BOOT_DEVICE
|
||||
# Returns: 1 if EFI variable not found or invalid, 0 on success
|
||||
find_boot_device() {
|
||||
local part_uuid device
|
||||
|
||||
# If we have subpartitions, the boot device is the partition containing them
|
||||
if [ -n "$SUBPARTITION_DEV" ]; then
|
||||
BOOT_DEVICE="$SUBPARTITION_DEV"
|
||||
info "Using subpartition container as boot device: $BOOT_DEVICE"
|
||||
return 0
|
||||
fi
|
||||
|
||||
if ! get_esp_partition_uuid_from_efi part_uuid; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
info "Searching for boot device with uuid: $part_uuid"
|
||||
|
||||
show_splash "Waiting for boot device..."
|
||||
|
||||
for _ in $(seq 1 30); do
|
||||
# Find device with matching PARTUUID
|
||||
device="$(readlink -f "/dev/disk/by-partuuid/$part_uuid")"
|
||||
if [ -b "$device" ]; then
|
||||
device="$(basename "$device")"
|
||||
parent_path="/sys/class/block/$device/.."
|
||||
info "Searching parent path: $parent_path"
|
||||
if [ -d "$parent_path" ]; then
|
||||
BOOT_DEVICE="/dev/$(basename "$(readlink -f "$parent_path")")"
|
||||
if [ -n "$BOOT_DEVICE" ] && [ "$BOOT_DEVICE" != "/dev/" ]; then
|
||||
info "Found boot device: $BOOT_DEVICE"
|
||||
return 0
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
info "Boot device not found yet, trying again in 1 second..."
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo "ERROR: boot device not found after 30 seconds"
|
||||
return 1
|
||||
}
|
||||
|
||||
factory_reset_requested() {
|
||||
# TODO: In systemd 258 this variable will be `FactoryResetRequest`
|
||||
local efi_var="/sys/firmware/efi/efivars/FactoryReset-8cf2644b-4b0b-428f-9387-6d876050dc67"
|
||||
[ -e "$efi_var" ] || return
|
||||
|
||||
# Read value (skip 4-byte EFI attributes)
|
||||
local value
|
||||
value="$(dd if="$efi_var" bs=1 skip=4 2>/dev/null | tr -d '\0')"
|
||||
info "Factory reset EFI var value: $value"
|
||||
[ "$value" = "1" ] || [ "$value" = "yes" ] || [ "$value" = "true" ]
|
||||
}
|
||||
|
||||
# Run systemd-repart to initialize A/B partition layout on GPT-partitioned block
|
||||
# devices, creating B-slot partitions sized to match A-slot
|
||||
# NOTE: This does *not* support subpartitioned devices!
|
||||
# $1: optional path to luks keyfile for encrypting partition
|
||||
# Uses: USR_PARTITION, VERITY_PARTITION
|
||||
# Sets: (none)
|
||||
# Returns: 1 on error, else 0
|
||||
run_repart() {
|
||||
local keyfile="$1"
|
||||
set -x
|
||||
|
||||
# HACK: Symlink os-release --> initrd-release. Ideally this would be handled by
|
||||
# mkinitfs config, but there's a bug preventing that from working correctly,
|
||||
# so for now let's do this. Using -f because if the bug is fixed, we don't want
|
||||
# the initramfs init to fail if the script hasn't been updated yet to remove
|
||||
# this hack.
|
||||
# https://gitlab.postmarketos.org/postmarketOS/postmarketos-mkinitfs/-/issues/50
|
||||
#
|
||||
# Repart will not enable factory reset logic unless this file exists, to prove
|
||||
# it's running in the initramfs.
|
||||
ln -sf /usr/lib/os-release /etc/initrd-release
|
||||
|
||||
export TMPDIR=/tmp
|
||||
# Disable discarding blocks while formatting, otherwise it can take like 10
|
||||
# minutes to format a 1TB partition with BTRFS on a fast NVMe!
|
||||
export SYSTEMD_REPART_MKFS_OPTIONS_BTRFS="--nodiscard"
|
||||
|
||||
# Calculate slot B partition sizes for repart. Look at their slot A counterparts
|
||||
# to get the size that they should be. This is better than hardcoding some
|
||||
# totally made up size (e.g. 20GB) and hoping it's enough for an update to it.
|
||||
mkdir -p /run/repart.d/22-usr.conf.d
|
||||
mkdir -p /run/repart.d/21-usr-verity.conf.d
|
||||
mkdir -p /run/repart.d/12-usr.conf.d
|
||||
mkdir -p /run/repart.d/11-usr-verity.conf.d
|
||||
|
||||
# Need usr partitions for size calculations
|
||||
wait_partition "usr" "find_usr_partition"
|
||||
wait_partition "verity" "find_usr_verity_partition"
|
||||
|
||||
# Get A-slot sizes
|
||||
usr_size="$(blockdev --getsize64 "$USR_PARTITION")"
|
||||
verity_size="$(blockdev --getsize64 "$VERITY_PARTITION")"
|
||||
|
||||
info "Using usr partition size: $usr_size"
|
||||
info "Using usr verity partition size: $verity_size"
|
||||
|
||||
# Create size override drop-ins
|
||||
# Note: This sets limits for existing partitions too because repart likes to
|
||||
# try and grow existing A-slot partitions if the B-slot partitions don't exist
|
||||
# when repart runs.
|
||||
cat > /run/repart.d/22-usr.conf.d/10-runtime-size.conf <<-EOF
|
||||
[Partition]
|
||||
SizeMinBytes=${usr_size}
|
||||
SizeMaxBytes=${usr_size}
|
||||
EOF
|
||||
cat > /run/repart.d/12-usr.conf.d/10-runtime-size.conf <<-EOF
|
||||
[Partition]
|
||||
SizeMinBytes=${usr_size}
|
||||
SizeMaxBytes=${usr_size}
|
||||
EOF
|
||||
cat > /run/repart.d/21-usr-verity.conf.d/10-runtime-size.conf <<-EOF
|
||||
[Partition]
|
||||
SizeMinBytes=${verity_size}
|
||||
SizeMaxBytes=${verity_size}
|
||||
EOF
|
||||
cat > /run/repart.d/11-usr-verity.conf.d/10-runtime-size.conf <<-EOF
|
||||
[Partition]
|
||||
SizeMinBytes=${verity_size}
|
||||
SizeMaxBytes=${verity_size}
|
||||
EOF
|
||||
|
||||
# NOTE: when repart detects it is running in the initramfs, it will assume
|
||||
# root=sysroot and read configuration from there. Since /sysroot is not mounted
|
||||
# yet and the filesystem that backs it hasn't been created/populated yet (that's
|
||||
# the point of repart), we need to tell repart to use the repart.d config in the
|
||||
# initramfs by specifying root=/
|
||||
repart_args="--no-pager --dry-run=no --root=/ "
|
||||
if [ -n "$keyfile" ]; then
|
||||
repart_args="$repart_args --key-file=$keyfile"
|
||||
fi
|
||||
info "Running systemd-repart with args: $repart_args"
|
||||
|
||||
local target_device="$BOOT_DEVICE"
|
||||
if [ -n "$SUBPARTITION_DEV" ]; then
|
||||
target_device="$(losetup -j "$BOOT_DEVICE" -O NAME --noheadings)"
|
||||
if [ -z "$target_device" ]; then
|
||||
echo "ERROR: SUBPARTITION_DEV set but no loop device found"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
if ! systemd-repart $repart_args "$target_device"; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
partprobe
|
||||
udevadm settle --timeout=30
|
||||
}
|
||||
|
||||
# Show an interactive UI to let the user configure the system and report the
|
||||
# values
|
||||
# Uses: (none)
|
||||
# Sets: firstboot_username, firstboot_hostname, firstboot_password,
|
||||
# firstboot_fde_password
|
||||
# Returns: (none)
|
||||
get_firstboot_config() {
|
||||
# Make sure the splash doesn't interfere
|
||||
hide_splash
|
||||
|
||||
local output
|
||||
output=$(f0rmz)
|
||||
if [ -n "$output" ] && echo "$output" | grep -q "username="; then
|
||||
while IFS= read -r line; do
|
||||
key="${line%%=*}"
|
||||
value="${line#*=}"
|
||||
case "$key" in
|
||||
username)
|
||||
firstboot_username="$value" ;;
|
||||
hostname)
|
||||
firstboot_hostname="$value" ;;
|
||||
password)
|
||||
firstboot_password="$value" ;;
|
||||
fde_password)
|
||||
firstboot_fde_password="$value" ;;
|
||||
esac
|
||||
done <<-EOF
|
||||
$output
|
||||
EOF
|
||||
else
|
||||
echo "ERROR: running f0rmz configuration UI failed!"
|
||||
fail_halt_boot
|
||||
fi
|
||||
|
||||
[ -z "$firstboot_hostname" ] && firstboot_hostname="pmOS"
|
||||
}
|
||||
|
||||
# Create dm-verity mapping for /usr partition
|
||||
# Uses: USR_PARTITION, VERITY_PARTITION, usrhash
|
||||
# Sets: (none)
|
||||
# $1: variable name to store verity device path
|
||||
# Returns: 1 if verity setup fails, 0 on success
|
||||
setup_verity_mapping() {
|
||||
local result="$1"
|
||||
local verity_device="/dev/mapper/usr-verified"
|
||||
|
||||
# Wait for both partitions to be available
|
||||
wait_partition "usr" "find_usr_partition"
|
||||
wait_partition "verity" "find_usr_verity_partition"
|
||||
|
||||
# Set up dm-verity mapping
|
||||
# shellcheck disable=SC2154
|
||||
if ! veritysetup open "$USR_PARTITION" usr-verified "$VERITY_PARTITION" "$usrhash"; then
|
||||
echo "ERROR: Unable to create verity mapping for /usr"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Set the result
|
||||
if [ -n "$result" ]; then eval "$result=\"$verity_device\""; fi
|
||||
}
|
||||
|
||||
# Mount verity-protected /usr partition
|
||||
# Uses: USR_PARTITION, VERITY_PARTITION, usrhash
|
||||
# Sets: (none)
|
||||
# Returns: 1 if verity setup or mount fails, 0 on success
|
||||
mount_usr_verified() {
|
||||
local device_path
|
||||
|
||||
# Set up dm-verity mapping
|
||||
if ! setup_verity_mapping device_path; then
|
||||
return 1
|
||||
fi
|
||||
|
||||
info "Using verified usr partition mapped at: $device_path"
|
||||
|
||||
modprobe erofs || true
|
||||
|
||||
# Mount /usr read-only
|
||||
mkdir -p /sysroot/usr
|
||||
if ! mount -t auto -o ro "$device_path" /sysroot/usr; then
|
||||
echo "ERROR: Unable to mount verified /usr"
|
||||
return 1
|
||||
fi
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Handle systemd-repart for first boot/factory reset
|
||||
# Uses: BOOT_DEVICE, USR_PARTITION, VERITY_PARTITION, firstboot_fde_password
|
||||
# Sets: PMOS_ROOT (after partition creation)
|
||||
# Returns: 1 if repart fails, 0 on success
|
||||
setup_first_boot_partitions() {
|
||||
local disk_mb usr_mb verity_mb ab_needed_mb required_mb min_root_mb
|
||||
local root_part_num repart_args
|
||||
|
||||
info "Searching for usr + verity partitions"
|
||||
wait_partition "usr" "find_usr_partition"
|
||||
wait_partition "verity" "find_usr_verity_partition"
|
||||
# Calculate A/B usr+verity + root space needed
|
||||
disk_mb=$(($(blockdev --getsize64 "$BOOT_DEVICE") / 1024 / 1024))
|
||||
usr_mb=$(($(blockdev --getsize64 "$USR_PARTITION") / 1024 / 1024))
|
||||
verity_mb=$(($(blockdev --getsize64 "$VERITY_PARTITION") / 1024 / 1024))
|
||||
ab_needed_mb=$((usr_mb * 2 + verity_mb * 2))
|
||||
min_root_mb=5120 # 5GB
|
||||
required_mb=$((ab_needed_mb + min_root_mb))
|
||||
|
||||
info "Disk space analysis:"
|
||||
info " Disk: ${disk_mb}MB"
|
||||
info " USR: ${usr_mb}MB, Verity: ${verity_mb}MB"
|
||||
info " A/B slots need: ${ab_needed_mb}MB"
|
||||
info " Root needs: ${min_root_mb}MB"
|
||||
info " Total required: ${required_mb}MB"
|
||||
|
||||
if [ $disk_mb -lt $required_mb ]; then
|
||||
echo "ERROR: Disk too small. Need ${required_mb}MB, have ${disk_mb}MB"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Remove any existing root partition, so that it can be recreated with optional encryption
|
||||
unset PMOS_ROOT && find_root_partition
|
||||
info "Existing root partiton (if found): $PMOS_ROOT"
|
||||
root_part_num="$(blkid -p -s PART_ENTRY_NUMBER -o value "$PMOS_ROOT")"
|
||||
if [ -n "$root_part_num" ]; then
|
||||
info "Removing existing root partition"
|
||||
if ! parted -s "$BOOT_DEVICE" rm "$root_part_num"; then
|
||||
echo "ERROR: Unable to prepare disk for first boot setup"
|
||||
return 1
|
||||
fi
|
||||
fi
|
||||
|
||||
# Create runtime repart config based on user choices
|
||||
mkdir -p /run/repart.d
|
||||
local keyfile=""
|
||||
if [ -n "$firstboot_fde_password" ]; then
|
||||
info "FDE enabled for new root partition"
|
||||
# Copy base config and add encryption
|
||||
cp /usr/lib/repart.d/30-root.conf /run/repart.d/
|
||||
cat >> /run/repart.d/30-root.conf <<- EOF
|
||||
Encrypt=key-file
|
||||
EOF
|
||||
# Create key file for repart
|
||||
printf "%s" "$firstboot_fde_password" > /tmp/luks.key
|
||||
chmod 0600 /tmp/luks.key
|
||||
keyfile="/tmp/luks.key"
|
||||
fi
|
||||
|
||||
if ! run_repart "$keyfile"; then
|
||||
echo "ERROR: systemd-repart failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Find the newly created root partition
|
||||
unset PMOS_ROOT && find_root_partition
|
||||
info "Found new root partition: $PMOS_ROOT"
|
||||
if [ -z "$PMOS_ROOT" ]; then
|
||||
echo "ERROR: Root partition not found after repart"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Unlock automatically if encrypted, since we already have the passphrase
|
||||
if [ -n "$firstboot_fde_password" ] && [ -f /tmp/luks.key ]; then
|
||||
info "Unlocking new root partition"
|
||||
if ! cryptsetup open --key-file=/tmp/luks.key "$PMOS_ROOT" root; then
|
||||
echo "ERROR: Failed to unlock encrypted root partition"
|
||||
return 1
|
||||
fi
|
||||
PMOS_ROOT="/dev/mapper/root"
|
||||
fi
|
||||
|
||||
# Clean up key file
|
||||
rm -f /tmp/luks.key
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Create user account and run systemd-firstboot
|
||||
# Uses: firstboot_* variables from get_firstboot_config
|
||||
# Sets: (none)
|
||||
# Returns: 1 if user setup fails, 0 on success
|
||||
setup_first_boot_system() {
|
||||
# Manually copy user/group files from factory, we want to append to these
|
||||
info "Creating skeleton /etc with user/group databases from factory"
|
||||
mkdir -p /sysroot/etc
|
||||
for f in passwd group shadow; do
|
||||
if ! cp -a /sysroot/usr/share/factory/etc/"$f" /sysroot/etc/; then
|
||||
echo "ERROR: Failed to copy factory $f file"
|
||||
return 1
|
||||
fi
|
||||
done
|
||||
|
||||
# useradd later will automatically add the new user to these files if they exist beforehand
|
||||
touch /sysroot/etc/subuid
|
||||
touch /sysroot/etc/subgid
|
||||
|
||||
# Run systemd-firstboot
|
||||
echo "Setting up system configuration..."
|
||||
if ! systemd-firstboot --root=/sysroot \
|
||||
--keymap=us \
|
||||
--locale=en_US.UTF-8 \
|
||||
--timezone="UTC" \
|
||||
--hostname="$firstboot_hostname"; then
|
||||
echo "ERROR: systemd-firstboot failed"
|
||||
return 1
|
||||
fi
|
||||
|
||||
echo "Creating user account..."
|
||||
# Create user account
|
||||
if ! useradd --root /sysroot \
|
||||
--comment "Default User" \
|
||||
--create-home \
|
||||
--user-group \
|
||||
--shell /bin/ash \
|
||||
--groups audio,input,netdev,plugdev,video,wheel,render \
|
||||
"$firstboot_username"; then
|
||||
echo "ERROR: Failed to create user account"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Set password for user account
|
||||
info "Configuring user password"
|
||||
if ! echo "$firstboot_username:$firstboot_password" | chpasswd -R /sysroot; then
|
||||
echo "ERROR: Failed to set user password"
|
||||
return 1
|
||||
fi
|
||||
|
||||
# Save user's name for future generators
|
||||
echo "$firstboot_username" > /sysroot/etc/default_user
|
||||
|
||||
# Lock root account
|
||||
info "Locking root account"
|
||||
echo "root:!" | chpasswd -e -R /sysroot
|
||||
|
||||
# Create essential symlinks
|
||||
info "usr merge \o/"
|
||||
ln -s /usr/bin /sysroot/bin
|
||||
ln -s /usr/sbin /sysroot/sbin
|
||||
ln -s /usr/lib /sysroot/lib
|
||||
|
||||
return 0
|
||||
}
|
||||
|
||||
# Handle first boot scenario
|
||||
# Uses: BOOT_DEVICE, USR_PARTITION, VERITY_PARTITION
|
||||
# Sets: PMOS_ROOT (via setup_first_boot_partitions)
|
||||
# Returns: calls fail_halt_boot on error, 0 on success
|
||||
handle_first_boot() {
|
||||
echo "No root partition found - performing first boot setup"
|
||||
show_splash "Preparing for first boot..."
|
||||
|
||||
# Get configuration values from user
|
||||
get_firstboot_config
|
||||
|
||||
echo "Creating partitions"
|
||||
show_splash "Preparing disk..."
|
||||
|
||||
# Create partitions and unlock if encrypted
|
||||
if ! setup_first_boot_partitions; then
|
||||
show_splash "ERROR: Failed to partition disk"
|
||||
fail_halt_boot
|
||||
fi
|
||||
|
||||
# Mount root partition (os-release won't exist yet, that's OK)
|
||||
try_mount_root_partition
|
||||
case $? in
|
||||
0) # Success, continue
|
||||
;;
|
||||
3) # Missing os-release, expected for first boot
|
||||
info "Root partition not populated yet, and that's OK"
|
||||
;;
|
||||
*) # Other error
|
||||
show_splash "ERROR: Failed to mount root partition"
|
||||
echo "ERROR: Failed to mount root partition"
|
||||
fail_halt_boot
|
||||
;;
|
||||
esac
|
||||
|
||||
info "Mounting verified usr partition"
|
||||
if ! mount_usr_verified; then
|
||||
show_splash "ERROR: Failed to mount usr partition"
|
||||
fail_halt_boot
|
||||
fi
|
||||
|
||||
# Setup user account and system configuration
|
||||
show_splash "Configuring system..."
|
||||
echo "Configuring system"
|
||||
if ! setup_first_boot_system; then
|
||||
show_splash "ERROR: Failed to setup user account"
|
||||
fail_halt_boot
|
||||
fi
|
||||
|
||||
echo "First boot setup complete"
|
||||
show_splash "First boot setup complete"
|
||||
}
|
||||
|
||||
# Resolve the given partuuid to a block device
|
||||
# $1: partition UIUD to resolve
|
||||
# Returns: path to block device, else empty string if not found
|
||||
find_part_by_uuid() {
|
||||
local uuid="$1"
|
||||
local path=/dev/disk/by-partuuid/"$uuid"
|
||||
|
||||
if [ -L "$path" ]; then
|
||||
readlink -f "$path"
|
||||
return
|
||||
fi
|
||||
|
||||
# Check nested partition table if we have subpartitions
|
||||
if [ -n "$SUBPARTITION_DEV" ]; then
|
||||
local partnum
|
||||
partnum="$(sfdisk -d "$SUBPARTITION_DEV" 2>/dev/null | grep -i "uuid=$uuid" | sed -n 's/.*p\([0-9]\+\) :.*/\1/p')"
|
||||
if [ -n "$partnum" ]; then
|
||||
echo "/dev/mapper/$(basename "$SUBPARTITION_DEV")p${partnum}"
|
||||
return
|
||||
fi
|
||||
fi
|
||||
|
||||
echo ""
|
||||
}
|
||||
|
||||
# Change a UUID in the form XXXXXXXXXXXXX... to XXXXXXXX-XXXX-XXXX-...
|
||||
format_raw_uuid(){
|
||||
local raw="$1"
|
||||
local ret
|
||||
|
||||
# NOTE: parts are extracted below one at a time to help with code
|
||||
# readability
|
||||
ret="$(echo "$raw" | cut -c1-8)"
|
||||
ret="$ret-$(echo "$raw" | cut -c9-12)"
|
||||
ret="$ret-$(echo "$raw" | cut -c13-16)"
|
||||
ret="$ret-$(echo "$raw" | cut -c17-20)"
|
||||
ret="$ret-$(echo "$raw" | cut -c21-32)"
|
||||
|
||||
echo "$ret"
|
||||
}
|
||||
|
||||
# Search for a /usr partition using usrhash
|
||||
# Uses: usrhash
|
||||
# Sets: USR_PARTITION
|
||||
# $1: variable name to store result
|
||||
# Returns: 0 always
|
||||
find_usr_partition() {
|
||||
# $1: variable to set result to
|
||||
local result="$1"
|
||||
local usr_uuid_raw usr_uuid
|
||||
|
||||
if [ -z "$USR_PARTITION" ]; then
|
||||
# Extract first 128 bits (32 hex chars) for /usr partition UUID
|
||||
# shellcheck disable=SC2154
|
||||
usr_uuid_raw="$(echo "$usrhash" | cut -c1-32)"
|
||||
usr_uuid="$(format_raw_uuid "$usr_uuid_raw")"
|
||||
|
||||
USR_PARTITION="$(find_part_by_uuid "$usr_uuid")"
|
||||
fi
|
||||
|
||||
# Set the result, since using a subshell prevents us from caching
|
||||
if [ -n "$result" ]; then eval "$result=\"$USR_PARTITION\""; fi
|
||||
}
|
||||
|
||||
# Search for a /usr verity partition using usrhash
|
||||
# Uses: usrhash
|
||||
# Sets: VERITY_PARTITION
|
||||
# $1: variable name to store result
|
||||
# Returns: 0 always
|
||||
find_usr_verity_partition() {
|
||||
# $1: variable to set result to
|
||||
local result="$1"
|
||||
local verity_uuid_raw verity_uuid
|
||||
|
||||
if [ -z "$VERITY_PARTITION" ]; then
|
||||
# Extract last 128 bits (32 hex chars) for verity partition UUID
|
||||
verity_uuid_raw="$(echo "$usrhash" | cut -c33-64)"
|
||||
verity_uuid="$(format_raw_uuid "$verity_uuid_raw")"
|
||||
|
||||
VERITY_PARTITION="$(find_part_by_uuid "$verity_uuid")"
|
||||
fi
|
||||
|
||||
# Set the result, since using a subshell prevents us from caching
|
||||
if [ -n "$result" ]; then eval "$result=\"$VERITY_PARTITION\""; fi
|
||||
}
|
||||
|
||||
# Get the appropriate root GPT type for the booted arch
|
||||
get_root_partition_uuid() {
|
||||
# shellcheck disable=SC2154
|
||||
case "$deviceinfo_arch" in
|
||||
x86_64) echo "4f68bce3-e8cd-4db1-96e7-fbcaf984b709" ;;
|
||||
x86) echo "44479540-f297-41b2-9af7-d131d5f0458a" ;;
|
||||
aarch64) echo "b921b045-1df0-41c3-af44-4c6f280d3fae" ;;
|
||||
armv7|armhf) echo "69dad710-2ce4-4e3c-b16c-21a1d49abed3" ;;
|
||||
riscv64) echo "72ec70a6-cf74-40e6-bd49-4bda08e8f224" ;;
|
||||
*) echo "" ;; # Unsupported arch
|
||||
esac
|
||||
}
|
||||
|
||||
# Use GPT type to find the appropriate root partition on the booted block device
|
||||
find_root_on_boot_device() {
|
||||
local root_uuid
|
||||
root_uuid="$(get_root_partition_uuid)"
|
||||
|
||||
[ -z "$root_uuid" ] && return 1
|
||||
|
||||
set -x
|
||||
# For subpartitions, search the nested partition table
|
||||
if [ -n "$SUBPARTITION_DEV" ]; then
|
||||
local partnum
|
||||
partnum="$(sfdisk -d "$SUBPARTITION_DEV" 2>/dev/null | grep -i "type=$root_uuid" | sed -n 's/.*p\([0-9]\+\) :.*/\1/p')"
|
||||
if [ -n "$partnum" ]; then
|
||||
echo "${SUBPARTITION_LOOP}p${partnum}"
|
||||
return
|
||||
fi
|
||||
else
|
||||
# Check each partition on the boot device
|
||||
local partition
|
||||
for partition in "$BOOT_DEVICE"*; do
|
||||
if blkid -p -s PART_ENTRY_TYPE "$partition" | grep -qi "$root_uuid"; then
|
||||
echo "$partition"
|
||||
return
|
||||
fi
|
||||
done
|
||||
fi
|
||||
}
|
||||
|
||||
# Limit USB storage transfer size to work around dm-verity corruption issue
|
||||
# See: https://gitlab.postmarketos.org/postmarketOS/duranium/-/issues/1
|
||||
# Uses: BOOT_DEVICE
|
||||
# Sets: (none)
|
||||
# Returns: 0 always
|
||||
limit_usb_transfer_size() {
|
||||
local device_name sysfs_path device_path
|
||||
device_name="$(basename "$BOOT_DEVICE")"
|
||||
sysfs_path="/sys/block/$device_name/queue/max_sectors_kb"
|
||||
device_path="/sys/block/$device_name/device"
|
||||
|
||||
if [ ! -L "$device_path" ]; then
|
||||
info "Not setting max_sectors_kb: device path not found"
|
||||
return
|
||||
fi
|
||||
|
||||
# Check if device symlink contains /usb, indicating it's a usb device. This
|
||||
# seems like a safe assumption to make, and it prevents us from applying this
|
||||
# workaround for non-usb devices.
|
||||
if ! readlink -f "$device_path" | grep -q "/usb"; then
|
||||
info "Not setting max_sectors_kb: not a USB device"
|
||||
return
|
||||
fi
|
||||
|
||||
if [ ! -f "$sysfs_path" ]; then
|
||||
info "Not setting max_sectors_kb: sysfs file not found"
|
||||
return
|
||||
fi
|
||||
|
||||
echo 32 > "$sysfs_path"
|
||||
info "Applied USB workaround: set max_sectors_kb=32 for $device_name"
|
||||
return
|
||||
}
|
||||
|
||||
# Handle immutable boot with A/B updates and factory reset
|
||||
# Uses: usrhash
|
||||
# Sets: BOOT_DEVICE, USR_PARTITION, VERITY_PARTITION, PMOS_ROOT
|
||||
# Returns: calls fail_halt_boot on error, 0 on success
|
||||
handle_immutable_boot() {
|
||||
# Check usrhash length, fail fast (should be 64 hex characters = 256 bits)
|
||||
if [ ${#usrhash} -ne 64 ]; then
|
||||
show_splash "ERROR: Unable to boot immutable image!"
|
||||
echo "ERROR: usrhash should be 64 hex characters (256 bits)"
|
||||
fail_halt_boot
|
||||
fi
|
||||
|
||||
setup_efivarfs
|
||||
|
||||
# Make sure loop is loaded, else repart falls back to using a file and it's
|
||||
# buggy
|
||||
modprobe loop
|
||||
|
||||
if ! find_boot_device; then
|
||||
show_splash "ERROR: Unable to find required EFI variable"
|
||||
fail_halt_boot
|
||||
fi
|
||||
|
||||
limit_usb_transfer_size
|
||||
|
||||
set -x
|
||||
# Factory reset handling
|
||||
if factory_reset_requested; then
|
||||
show_splash "Factory resetting device..."
|
||||
echo "Factory reset requested - deleting partitions"
|
||||
|
||||
if ! run_repart; then
|
||||
show_splash "ERROR: Factory reset failed"
|
||||
echo "ERROR: systemd-repart failed"
|
||||
fail_halt_boot
|
||||
fi
|
||||
|
||||
# Treat this as a "first boot" since partitions were cleared
|
||||
handle_first_boot
|
||||
return
|
||||
fi
|
||||
set +x
|
||||
|
||||
# Try normal boot
|
||||
info "Trying normal bootup"
|
||||
find_root_partition
|
||||
if [ -z "$PMOS_ROOT" ]; then
|
||||
info "No root partition found, proceeding to first boot setup"
|
||||
|
||||
handle_first_boot
|
||||
return
|
||||
fi
|
||||
|
||||
info "Root partition found: $PMOS_ROOT"
|
||||
unlock_root_partition
|
||||
if ! try_mount_root_partition; then
|
||||
info "Unable to mount root, it was not populated, proceeding to first boot setup"
|
||||
# Clean up
|
||||
if mountpoint -q /sysroot; then
|
||||
umount /sysroot
|
||||
fi
|
||||
cryptsetup close /dev/mapper/root || true
|
||||
|
||||
handle_first_boot
|
||||
return
|
||||
fi
|
||||
|
||||
info "Root mounted, proceeding with normal boot"
|
||||
if ! mount_usr_verified; then
|
||||
show_splash "ERROR: Unable to mount OS data"
|
||||
fail_halt_boot
|
||||
fi
|
||||
}
|
||||
+15
@@ -0,0 +1,15 @@
|
||||
/usr/bin/systemd-firstboot
|
||||
/usr/bin/systemd-repart
|
||||
/usr/lib/repart.d
|
||||
/usr/sbin/mkfs.btrfs
|
||||
/usr/sbin/sfdisk
|
||||
/usr/sbin/losetup
|
||||
/usr/sbin/useradd
|
||||
/usr/sbin/veritysetup
|
||||
/usr/share/initramfs/init_functions_immutable.sh:/init_functions_immutable.sh
|
||||
/usr/share/systemd/kbd-model-map
|
||||
/usr/share/zoneinfo/
|
||||
# Note: initrd-release is used to signal to repart that it's running in an
|
||||
# initramfs environment. If we don't convince it, then it won't let us do
|
||||
# factory resetting.
|
||||
/usr/lib/os-release:/etc/initrd-release
|
||||
+3
@@ -0,0 +1,3 @@
|
||||
dm-verity
|
||||
efivarfs
|
||||
erofs
|
||||
@@ -4,7 +4,7 @@
|
||||
/etc/unudhcpd.conf
|
||||
/sbin/blkid
|
||||
/usr/bin/unudhcpd
|
||||
/usr/sbin/kpartx
|
||||
/usr/sbin/losetup
|
||||
/usr/share/deviceinfo/deviceinfo
|
||||
/usr/share/initramfs/init_functions.sh:/init_functions.sh
|
||||
/usr/share/initramfs/init.sh:/init
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
# Co-Maintainer: Clayton Craft <clayton@craftyguy.net>
|
||||
maintainer="Casey Connolly <kcxt@postmarketos.org>"
|
||||
pkgname=postmarketos-initramfs
|
||||
pkgver=3.8.11
|
||||
pkgver=3.9.0
|
||||
pkgrel=0
|
||||
pkgdesc="Base files for the postmarketOS initramfs / initramfs-extra"
|
||||
url="https://postmarketos.org"
|
||||
@@ -28,6 +28,7 @@ depends="
|
||||
iskey
|
||||
kmod
|
||||
libinput-libs
|
||||
losetup
|
||||
lz4
|
||||
multipath-tools
|
||||
parted
|
||||
@@ -111,12 +112,12 @@ package() {
|
||||
sha512sums="
|
||||
9d1358886fc2d3eac27c13b11e998458da41ac222c1bfa986ae948970419775b5488ab8b8404a6aa0e21c47717316aa9717b5d5ddc53ec610ad875328ea18e9f 00-default.modules
|
||||
9c0e8f6f61d5da191e03a1aa9d5d0ceb5baf1eae6dbb9bfb0af59817783525119ac8394b135f303f7b6434a3eab0b49185fb90379e06823db847a4999c75ce33 00-initramfs-base.dirs
|
||||
e268094cbd25e063fdab2226f8cf93885bd8b90455991a53296231a3401a03669440333025ca44b2a8459df98787a5725f7b227ccb9750f8fcad17ef58ba21a1 00-initramfs-base.files
|
||||
229910dc50758e079ef35210891825d950c9266e3dc11ac1b420f32ceb552cbced282ee03d4674f94238b6e3688cdef9391b18b9b311fc548f051fb95d4210d2 00-initramfs-base.files
|
||||
1bb1930cb5bdb60a074195f772dc015b827487a3efd0d68b51ade52164b6371a756249753fbbdc56e975d18f24ada6a1339ea204d2d8fe7ecd95d7aec8647161 00-initramfs-extra-base.files
|
||||
e90596540805662211bd2a2e427ce7cc38f6a30023267f902e23f2bae136b6cd8f4f4716b8fb611be9d671a964edd2ecce03fa32bc8024e29b8375b0097fde0c init.sh
|
||||
05d1ec265f6ca5c4073e0f985729905fdd8f8e11d64bd099f7c50f172827614dd43193399e04d5405edf20248223494b884319d3cc866a32033fb5c313c6e226 init_functions.sh
|
||||
6b4881f9b43c90ebcc70d7b7a192d26a2e3ce01c43b8536fe900c2ffaf74ef035803b9aa083e7a9d5c49c75be8ba6ff22997a037ae4f399e6ee5e1978c4b3f9c init_2nd.sh
|
||||
de14f6f678856ae316f28c003a6293a383aa6b7cbb19951b981430eb0e3b91d0634dedf62d29d105845b6e172daa18e6b6e45e03342d72ae806ca611a1236d18 init_functions_2nd.sh
|
||||
a625447092b7c14b759acda96fe2c311500d621bc54d7e6d809f5cd4ba03018051e0d2f3937fe2abc43955aac5410ab8f706cf259ebcc34a80bf788fad2a4176 init.sh
|
||||
977f024cef32c391dc6c556dbfdecb8c18be3e74ae8476e6b3c5152e555c228a5bf48845f5e693ee3c0d8320ec819593184925d77659034fb7c55772071f77d8 init_functions.sh
|
||||
2ca09c293d631a22c5e7861f9f74de82743b61755de619b8ddd88d2f8a09ba12dba06d6a1c8494a82730e9f63d100bd233fb85e27a3cb6004950a50cb263e6da init_2nd.sh
|
||||
70600706cd8eb18cc990a4e4e286807873a5e0369124c28f0ee511876411535911d073367c959cad8452a72a4750741d49208fa9d1a2ee4c73e968171c5e3523 init_functions_2nd.sh
|
||||
675e7d5bee39b2df7d322117f8dcaccc274d61beaf4d50ead19bbf2109446d64b1c0aa0c5b4f9846eb6c1c403418f28f6364eff4537ba41120fbfcbc484b7da7 mdev.conf
|
||||
ba3275a9af788c7c782322a22a0f144d5e50e3498ea6886486a29331f23ae89cd32d500a3635cfa7cab369afba92edc18aeca64ccbf0cd589061cce23d15b46c unudhcpd.conf
|
||||
"
|
||||
@@ -24,6 +24,10 @@ trap 'reboot -f' TERM
|
||||
# provide a default for os-release's VERSION in case the file doesn't exist
|
||||
VERSION="${VERSION:-unknown}"
|
||||
|
||||
if [ -f /init_functions_immutable.sh ]; then
|
||||
. /init_functions_immutable.sh
|
||||
fi
|
||||
|
||||
# This is set during packaging and is used when triaging bug reports
|
||||
INITRAMFS_PKG_VERSION="<<INITRAMFS_PKG_VERSION>>"
|
||||
|
||||
|
||||
@@ -8,6 +8,9 @@
|
||||
# The set -a in init.sh only exports variables, not functions
|
||||
. /init_functions.sh
|
||||
. /init_functions_2nd.sh
|
||||
if [ -f /init_functions_immutable.sh ]; then
|
||||
. /init_functions_immutable.sh
|
||||
fi
|
||||
|
||||
# Handle halt/poweroff/reboot
|
||||
# Signals from busybox/halt.c
|
||||
@@ -50,19 +53,23 @@ mount_subpartitions
|
||||
|
||||
run_hooks /hooks-extra
|
||||
|
||||
wait_root_partition
|
||||
delete_old_install_partition
|
||||
resize_root_partition
|
||||
unlock_root_partition
|
||||
resize_root_filesystem
|
||||
mount_root_partition
|
||||
resize_filesystem_after_mount /sysroot
|
||||
if is_immutable_boot; then
|
||||
handle_immutable_boot
|
||||
else
|
||||
wait_root_partition
|
||||
delete_old_install_partition
|
||||
resize_root_partition
|
||||
unlock_root_partition
|
||||
resize_root_filesystem
|
||||
mount_root_partition
|
||||
resize_filesystem_after_mount /sysroot
|
||||
|
||||
# Mount boot partition into sysroot if needed since some
|
||||
# old installations don't have a proper /etc/fstab file. See #2800
|
||||
if [ -z "$(cat /sysroot/etc/fstab | grep -v "#" | tr -d '[:space:]')" ]; then
|
||||
wait_boot_partition
|
||||
mount_boot_partition /sysroot/boot "rw"
|
||||
# Mount boot partition into sysroot if needed since some
|
||||
# old installations don't have a proper /etc/fstab file. See #2800
|
||||
if [ -z "$(cat /sysroot/etc/fstab | grep -v "#" | tr -d '[:space:]')" ]; then
|
||||
wait_boot_partition
|
||||
mount_boot_partition /sysroot/boot "rw"
|
||||
fi
|
||||
fi
|
||||
|
||||
init="/sbin/init"
|
||||
@@ -102,6 +109,7 @@ done
|
||||
# with /dev/log in there.
|
||||
rm /dev/log 2>/dev/null || true
|
||||
|
||||
|
||||
# shellcheck disable=SC2093
|
||||
exec switch_root /sysroot "$init"
|
||||
|
||||
|
||||
@@ -7,6 +7,7 @@
|
||||
PMOS_BOOT="${PMOS_BOOT:-}"
|
||||
PMOS_ROOT="${PMOS_ROOT:-}"
|
||||
SUBPARTITION_DEV="${SUBPARTITION_DEV:-}"
|
||||
SUBPARTITION_LOOP="${SUBPARTITION_LOOP:-}"
|
||||
|
||||
CONFIGFS="/config/usb_gadget"
|
||||
CONFIGFS_ACM_FUNCTION="acm.usb0"
|
||||
@@ -18,6 +19,7 @@ deviceinfo_name="${deviceinfo_name:-}"
|
||||
deviceinfo_codename="${deviceinfo_codename:-}"
|
||||
deviceinfo_create_initfs_extra="${deviceinfo_create_initfs_extra:-}"
|
||||
deviceinfo_no_framebuffer="${deviceinfo_no_framebuffer:-}"
|
||||
deviceinfo_rootfs_image_sector_size="${deviceinfo_rootfs_image_sector_size:-}"
|
||||
|
||||
# Does word start with prefix?
|
||||
startswith() {
|
||||
@@ -99,6 +101,11 @@ parse_cmdline_item() {
|
||||
# shellcheck disable=SC2034
|
||||
log_info=y
|
||||
;;
|
||||
usrhash)
|
||||
# used by init_2nd.sh which sources this script.
|
||||
# shellcheck disable=SC2034
|
||||
usrhash="$value"
|
||||
;;
|
||||
[![:alpha:]_]* | [[:alpha:]_]*[![:alnum:]_]*)
|
||||
# invalid shell variable, ignore it
|
||||
;;
|
||||
@@ -260,6 +267,10 @@ info() {
|
||||
echo "$@"
|
||||
}
|
||||
|
||||
is_immutable_boot() {
|
||||
[ -n "$usrhash" ]
|
||||
}
|
||||
|
||||
mount_proc_sys_dev() {
|
||||
# mdev
|
||||
mount -t proc -o nodev,noexec,nosuid proc /proc || echo "Couldn't mount /proc"
|
||||
@@ -342,6 +353,7 @@ setup_dynamic_partitions() {
|
||||
}
|
||||
|
||||
mount_subpartitions() {
|
||||
set -x
|
||||
# skip if ran already (unmerged -extra)
|
||||
if [ -n "$PMOS_ROOT" ] && [ -n "$PMOS_BOOT" ]; then
|
||||
return
|
||||
@@ -352,36 +364,43 @@ mount_subpartitions() {
|
||||
[ -e "$x" ] && android_parts="$android_parts $x"
|
||||
done
|
||||
|
||||
local loopdev
|
||||
local losetup_args="--show -Pfv --direct-io=on"
|
||||
if [ -n "$deviceinfo_rootfs_image_sector_size" ]; then
|
||||
losetup_args="$losetup_args --sector-size $deviceinfo_rootfs_image_sector_size"
|
||||
fi
|
||||
attempt_start=$(get_uptime_seconds)
|
||||
wait_seconds=10
|
||||
echo "Trying to mount subpartitions for $wait_seconds seconds..."
|
||||
find_root_partition
|
||||
while [ -z "$PMOS_ROOT" ]; do
|
||||
# For immutable boot, root partition may not exist yet (first boot), but boot
|
||||
# partition with ESP will. Break early if we find either to avoid timeout.
|
||||
while [ -z "$PMOS_ROOT" ] && [ -z "$PMOS_BOOT" ]; do
|
||||
partitions="$android_parts $(grep -v "loop\|ram" < /proc/diskstats |\
|
||||
sed 's/\(\s\+[0-9]\+\)\+\s\+//;s/ .*//;s/^/\/dev\//')"
|
||||
for partition in $partitions; do
|
||||
# Skip whole disks - only check partitions and logical device-mapper devices for subpartitions
|
||||
[ -e "/sys/class/block/$(basename "$partition")/partition" ] || [ -d "/sys/class/block/$(basename "$partition")/dm" ] || continue
|
||||
case "$(kpartx -l "$partition" 2>/dev/null | wc -l)" in
|
||||
2)
|
||||
echo "Mount subpartitions of $partition"
|
||||
SUBPARTITION_DEV="$partition"
|
||||
kpartx -afs "$partition"
|
||||
# Ensure that this was the *correct* subpartition
|
||||
# Some devices have mmc partitions that appear to have
|
||||
# subpartitions, but aren't our subpartition.
|
||||
find_root_partition
|
||||
if [ -n "$PMOS_ROOT" ]; then
|
||||
break
|
||||
fi
|
||||
kpartx -d "$partition"
|
||||
SUBPARTITION_DEV=""
|
||||
continue
|
||||
;;
|
||||
*)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
local part_count
|
||||
part_count="$(parted -s "$partition" print 2>/dev/null | grep -c '^ [0-9]')"
|
||||
if [ "$part_count" -ge 2 ]; then
|
||||
echo "Mount subpartitions of $partition"
|
||||
SUBPARTITION_DEV="$partition"
|
||||
local loopdev
|
||||
loopdev="$(losetup $losetup_args "$partition")"
|
||||
SUBPARTITION_LOOP="$loopdev"
|
||||
# Ensure that this was the *correct* subpartition
|
||||
# Some devices have mmc partitions that appear to have
|
||||
# subpartitions, but aren't our subpartition.
|
||||
find_root_partition
|
||||
find_boot_partition
|
||||
if [ -n "$PMOS_ROOT" ] || [ -n "$PMOS_BOOT" ]; then
|
||||
break
|
||||
fi
|
||||
[ -n "$loopdev" ] && losetup -vd "$loopdev"
|
||||
SUBPARTITION_DEV=""
|
||||
SUBPARTITION_LOOP=""
|
||||
fi
|
||||
done
|
||||
if [ "$(get_uptime_seconds)" -ge $(( attempt_start + wait_seconds )) ]; then
|
||||
echo "ERROR: failed to mount subpartitions!"
|
||||
@@ -408,7 +427,7 @@ pretty_dm_path() {
|
||||
|
||||
# Prints the path to the partition if found, or nothing.
|
||||
find_partition() {
|
||||
# $1: UUID of partition if known
|
||||
# $1: UUID of partition or filesystem on the partition, if known
|
||||
# $2: path to partition
|
||||
# $3: label of partition
|
||||
# $4: additional blkid token to check (e.g TYPE=crypto_LUKS)
|
||||
@@ -422,10 +441,24 @@ find_partition() {
|
||||
if [ -n "$uuid" ]; then
|
||||
partition="$(blkid --uuid "$uuid")"
|
||||
if [ -z "$partition" ]; then
|
||||
# Don't fall back to anything if the given UUID wasn't
|
||||
# found, it might show up later but if not we should
|
||||
# error out.
|
||||
return
|
||||
# Try to find by PARTUUID in nested partition table if we have subpartitions and
|
||||
# doing immutable boot. We have to use sfdisk here to search partition UUIDs
|
||||
# since those don't seem to be exposed by blkid
|
||||
if [ -n "$SUBPARTITION_DEV" ] && is_immutable_boot; then
|
||||
# Get partition number from nested GPT
|
||||
local partnum
|
||||
partnum="$(sfdisk -d "$SUBPARTITION_DEV" 2>/dev/null | grep -i "uuid=$uuid" | sed -n 's/.*p\([0-9]\+\) :.*/\1/p')"
|
||||
if [ -n "$partnum" ]; then
|
||||
partition="/dev/mapper/$(basename "$SUBPARTITION_DEV")p${partnum}"
|
||||
fi
|
||||
fi
|
||||
|
||||
if [ -z "$partition" ]; then
|
||||
# Don't fall back to anything if the given UUID wasn't
|
||||
# found, it might show up later but if not we should
|
||||
# error out.
|
||||
return
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
|
||||
@@ -466,7 +499,11 @@ find_root_partition() {
|
||||
# mount_subpartitions() must get executed before calling
|
||||
# find_root_partition(), so partitions from b) also get found.
|
||||
if [ -z "$PMOS_ROOT" ]; then
|
||||
PMOS_ROOT="$(find_partition "$root_uuid" "$root_path" "pmOS_root" "TYPE=crypto_LUKS")"
|
||||
if is_immutable_boot; then
|
||||
PMOS_ROOT="$(find_root_on_boot_device)"
|
||||
else
|
||||
PMOS_ROOT="$(find_partition "$root_uuid" "$root_path" "pmOS_root" "TYPE=crypto_LUKS")"
|
||||
fi
|
||||
fi
|
||||
|
||||
# Set the result, since using a subshell prevents us from caching
|
||||
@@ -485,6 +522,9 @@ find_boot_partition() {
|
||||
PMOS_BOOT="/sysroot/boot"
|
||||
mount --bind /sysroot/boot /boot
|
||||
else
|
||||
if is_immutable_boot; then
|
||||
get_esp_partition_uuid_from_efi boot_uuid
|
||||
fi
|
||||
PMOS_BOOT="$(find_partition "$boot_uuid" "$boot_path" "pmOS_boot")"
|
||||
fi
|
||||
fi
|
||||
@@ -675,56 +715,86 @@ has_unallocated_space() {
|
||||
head -n1 | grep -qi "free space"
|
||||
}
|
||||
|
||||
mount_root_partition() {
|
||||
# Mount root partition to /sysroot with error handling
|
||||
# Uses: rootfsopts
|
||||
# Sets: partition and type variables via output parameters
|
||||
# $1: variable name to store partition path
|
||||
# $2: variable name to store filesystem type
|
||||
# Returns: 0 on success, 1 if unsupported filesystem, 2 if mount fails, 3 if no /etc/os-release
|
||||
try_mount_root_partition() {
|
||||
# Don't mount root if it is already mounted
|
||||
if mountpoint -q /sysroot; then
|
||||
return
|
||||
fi
|
||||
|
||||
local partition
|
||||
local partition_var="$1"
|
||||
local type_var="$2"
|
||||
local partition_path fs_type
|
||||
|
||||
find_root_partition partition
|
||||
find_root_partition partition_path
|
||||
|
||||
echo "Mount root partition ($partition) to /sysroot (read-write) with options ${rootfsopts#,}"
|
||||
type="$(get_partition_type "$partition")"
|
||||
info "Detected $type filesystem"
|
||||
echo "Mount root partition ($partition_path) to /sysroot (read-write) with options ${rootfsopts#,}"
|
||||
fs_type="$(get_partition_type "$partition_path")"
|
||||
info "Detected $fs_type filesystem"
|
||||
|
||||
case "$type" in
|
||||
btrfs|ext4|f2fs|xfs)
|
||||
;;
|
||||
*)
|
||||
echo "ERROR: Detected unsupported '$type' filesystem ($partition)."
|
||||
show_splash "ERROR: unsupported '$type' filesystem ($partition)\\nhttps://postmarketos.org/troubleshooting"
|
||||
fail_halt_boot
|
||||
;;
|
||||
case "$fs_type" in
|
||||
btrfs|ext4|f2fs|xfs) ;;
|
||||
*) return 1 ;;
|
||||
esac
|
||||
|
||||
if ! modprobe "$type"; then
|
||||
info "Unable to load module '$type' - assuming it's built-in"
|
||||
if ! modprobe "$fs_type"; then
|
||||
info "Unable to load module '$fs_type' - assuming it's built-in"
|
||||
fi
|
||||
|
||||
# btrfs may be using multiple backing block devices, scan for the rest of them
|
||||
if [ "$type" = "btrfs" ]; then
|
||||
if [ "$fs_type" = "btrfs" ]; then
|
||||
btrfs device scan
|
||||
fi
|
||||
|
||||
if ! mount -t "$type" -o rw"$rootfsopts" "$partition" /sysroot; then
|
||||
echo "ERROR: unable to mount root partition!"
|
||||
show_splash "ERROR: unable to mount root partition\\nhttps://postmarketos.org/troubleshooting"
|
||||
fail_halt_boot
|
||||
if ! mount -t "$fs_type" -o rw"$rootfsopts" "$partition_path" /sysroot; then
|
||||
return 2
|
||||
fi
|
||||
|
||||
if [ -e /sysroot/.stowaways/pmos/etc/os-release ]; then
|
||||
umount /sysroot
|
||||
|
||||
mkdir /stowaway
|
||||
mount -t "$type" -o rw"$rootfsopts" "$partition" /stowaway
|
||||
mount -t "$fs_type" -o rw"$rootfsopts" "$partition_path" /stowaway
|
||||
mount --bind /stowaway/.stowaways/pmos/ /sysroot
|
||||
fi
|
||||
|
||||
if ! [ -e /sysroot/etc/os-release ]; then
|
||||
show_splash "ERROR: root partition does not contain a root filesystem\\nhttps://postmarketos.org/troubleshooting"
|
||||
fail_halt_boot
|
||||
# This also explicitly checks if os-release is a symlink, since -e can fail if
|
||||
# it exists but is a broken symlink (e.g. the usr partition isn't mounted yet)
|
||||
if ! [ -e /sysroot/etc/os-release ] && ! [ -L /sysroot/etc/os-release ]; then
|
||||
return 3
|
||||
fi
|
||||
|
||||
if [ -n "$partition_var" ]; then eval "$partition_var=\"$partition_path\""; fi
|
||||
if [ -n "$type_var" ]; then eval "$type_var=\"$fs_type\""; fi
|
||||
}
|
||||
|
||||
# Mount root partition to /sysroot (wrapper with error handling)
|
||||
# Uses: (none)
|
||||
# Sets: (none)
|
||||
# Returns: calls fail_halt_boot on error, 0 on success
|
||||
mount_root_partition() {
|
||||
local partition type
|
||||
if ! try_mount_root_partition partition type; then
|
||||
local ret=$?
|
||||
case $ret in
|
||||
1)
|
||||
echo "ERROR: Detected unsupported '$type' filesystem ($partition)."
|
||||
show_splash "ERROR: unsupported '$type' filesystem ($partition)\\nhttps://postmarketos.org/troubleshooting"
|
||||
fail_halt_boot ;;
|
||||
2)
|
||||
echo "ERROR: unable to mount root partition!"
|
||||
show_splash "ERROR: unable to mount root partition\\nhttps://postmarketos.org/troubleshooting"
|
||||
fail_halt_boot ;;
|
||||
3)
|
||||
echo "ERROR: root partition does not contain a root filesystem"
|
||||
show_splash "ERROR: root partition does not contain a root filesystem\\nhttps://postmarketos.org/troubleshooting"
|
||||
fail_halt_boot
|
||||
esac
|
||||
fi
|
||||
}
|
||||
|
||||
|
||||
@@ -45,10 +45,15 @@ resize_root_partition() {
|
||||
fi
|
||||
if has_unallocated_space "$partition_dev"; then
|
||||
echo "Resize root partition ($partition)"
|
||||
# unmount subpartition, resize and remount it
|
||||
kpartx -d "$partition"
|
||||
# find and detach the backing loop device
|
||||
loopdev=$(losetup -j "$partition_dev" -O NAME --noheadings)
|
||||
[ -n "$loopdev" ] && losetup -vd "$loopdev"
|
||||
parted -f -s "$partition_dev" resizepart 2 100%
|
||||
kpartx -afs "$partition_dev"
|
||||
local losetup_args="--show -Pfv --direct-io=on"
|
||||
if [ -n "$deviceinfo_rootfs_image_sector_size" ]; then
|
||||
losetup_args="$losetup_args --sector-size $deviceinfo_rootfs_image_sector_size"
|
||||
fi
|
||||
losetup $losetup_args "$partition_dev"
|
||||
else
|
||||
echo "Not resizing root partition ($partition): no free space left"
|
||||
fi
|
||||
|
||||
Reference in new issue
Block a user