main/postmarketos-initramfs: use loop device for subpartitions
This reworks the subpartition init to use loop devices instead of
kpartx/dm mappings. This allows us to use the same logic for resizing
as we do for other partitioning schemes (and refactors that code a bit).
This also helps duranium, because systemd tooling (repart, sysupdate,
gpt-auto-generator) can't properly handle GPT subpartitions exposed via
kpartx dm mappings, but works correctly with loop devices created with
partition scanning enabled.
After this change, subpartitions show up as loop devices, e.g.:
$ ls /dev/loop*
/dev/loop0p1
/dev/loop0p2
There *should* be no impact to existing installs.
This also drops the dependency on multipath-tools, which seems to have
been added years ago as a workaround for installing kpartx (like maybe
multipath-tools used to provide kpartx?), see 7573f5fce4. Anyways, we
don't use anything in this pkg in the initramfs AFAIK.
Signed-off-by: Clayton Craft <craftyguy@postmarketos.org>
Part-of: <https://gitlab.postmarketos.org/postmarketOS/pmaports/-/merge_requests/7932>
This commit is contained in:
parent
fd38701c35
commit
86bdb82116
5 changed files with 59 additions and 65 deletions
|
|
@ -5,7 +5,7 @@
|
|||
/sbin/blkid
|
||||
/usr/bin/iskey
|
||||
/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
|
||||
|
|
|
|||
|
|
@ -7,7 +7,6 @@
|
|||
/usr/lib/udev/rules.d/60-persistent-input.rules
|
||||
/usr/lib/udev/rules.d/60-persistent-storage.rules
|
||||
/usr/lib/udev/rules.d/64-btrfs.rules
|
||||
/usr/lib/udev/rules.d/66-kpartx.rules
|
||||
/usr/lib/udev/rules.d/70-mouse.rules
|
||||
/usr/lib/udev/rules.d/70-touchpad.rules
|
||||
/usr/lib/udev/rules.d/80-drivers.rules
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
# Co-Maintainer: Clayton Craft <clayton@craftyguy.net>
|
||||
maintainer="Casey Connolly <kcxt@postmarketos.org>"
|
||||
pkgname=postmarketos-initramfs
|
||||
pkgver=3.8.12
|
||||
pkgver=3.9.0
|
||||
pkgrel=0
|
||||
pkgdesc="Base files for the postmarketOS initramfs / initramfs-extra"
|
||||
url="https://postmarketos.org"
|
||||
|
|
@ -28,8 +28,8 @@ depends="
|
|||
iskey
|
||||
kmod
|
||||
libinput-libs
|
||||
losetup
|
||||
lz4
|
||||
multipath-tools
|
||||
parted
|
||||
postmarketos-fde-unlocker
|
||||
postmarketos-mkinitfs>=2.2
|
||||
|
|
@ -117,12 +117,12 @@ sha512sums="
|
|||
22cdd663c8d153781284511140b7c994cd60f0231a2819dafa67f5a11e2963ac6e392e8f7a9e3b75e7fe5d6d7b0b5e262e1ff1a695637354a124560a5ec3ed8d 00-default.modules
|
||||
ace852ba267b3408998970df6042603c8bec1d033066d1c30ed65f1be955fee8644b57882898f10228ec43b912f8f03718b34ddd741b431e5a5c2e76f060a494 00-default-extra.modules
|
||||
9c0e8f6f61d5da191e03a1aa9d5d0ceb5baf1eae6dbb9bfb0af59817783525119ac8394b135f303f7b6434a3eab0b49185fb90379e06823db847a4999c75ce33 00-initramfs-base.dirs
|
||||
9b5f5bc68ede0b06b85260d9ad301892e7b45ebad7e78300be17c8a55e3fdf392b3302587bd47011ce52f213e034a0cb49d0a2b96ab012fb5dce0514f4575aa7 00-initramfs-base.files
|
||||
3c021f6ede0c13469097a8aaeb15810baf2f3be52e10928f3475ac3568d855e3ab8e747b960d47ac6af6f7f223fca5e7da12098810502e0dae55aaf6bf4f293c 00-initramfs-extra-base.files
|
||||
26e391a2c45e4317549153630d7398f01cf374d9a95e2587f0f7153017c50b6640950af60eab3b3fcadef2e8826295445ac1f45567716d3bd5d12e9c87df599b 00-initramfs-base.files
|
||||
cc4db00caba184ad78062505415b3dadb8a32a94fe8484e4860bb6e63cd8700c8450066ce1242c496d9f063234bbab0fa40668f9c5112f3baeee30c5d405a1eb 00-initramfs-extra-base.files
|
||||
e90596540805662211bd2a2e427ce7cc38f6a30023267f902e23f2bae136b6cd8f4f4716b8fb611be9d671a964edd2ecce03fa32bc8024e29b8375b0097fde0c init.sh
|
||||
8b0f15b84795588822a8b07b1e43ef0034da5f982ab92f0e7d3b9359fc61121f3f961006ba7d3f98f16d127d37ba833926654831b39e2df83d7384eebc786d3d init_functions.sh
|
||||
3fd828e3ae67df2c3c1de9a0c2cdd087a4bc2a34029035b3fb74d410c9b46fd37b7e908eacdd65ee88b41cadb950a14f2b7c75c32bee413acbf5382dd5d1f7f2 init_functions.sh
|
||||
6b4881f9b43c90ebcc70d7b7a192d26a2e3ce01c43b8536fe900c2ffaf74ef035803b9aa083e7a9d5c49c75be8ba6ff22997a037ae4f399e6ee5e1978c4b3f9c init_2nd.sh
|
||||
de14f6f678856ae316f28c003a6293a383aa6b7cbb19951b981430eb0e3b91d0634dedf62d29d105845b6e172daa18e6b6e45e03342d72ae806ca611a1236d18 init_functions_2nd.sh
|
||||
61acb470a163fb50ad46752781b5ccc5dba6db9170e4250b4dcdfc7572d0316a7a36bc5a383026887a7a59364ee30917790e429b3fce9de590543d1d8410589c init_functions_2nd.sh
|
||||
675e7d5bee39b2df7d322117f8dcaccc274d61beaf4d50ead19bbf2109446d64b1c0aa0c5b4f9846eb6c1c403418f28f6364eff4537ba41120fbfcbc484b7da7 mdev.conf
|
||||
ba3275a9af788c7c782322a22a0f144d5e50e3498ea6886486a29331f23ae89cd32d500a3635cfa7cab369afba92edc18aeca64ccbf0cd589061cce23d15b46c unudhcpd.conf
|
||||
"
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
@ -356,6 +358,10 @@ mount_subpartitions() {
|
|||
[ -e "$x" ] && android_parts="$android_parts $x"
|
||||
done
|
||||
|
||||
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..."
|
||||
|
|
@ -366,26 +372,30 @@ mount_subpartitions() {
|
|||
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"
|
||||
local part_count
|
||||
part_count="$(parted -s "$partition" print 2>/dev/null | grep -c '^ [0-9]')"
|
||||
# It's probably the right "disk" if it has 2 partitions on it
|
||||
if [ "$part_count" -eq 2 ]; then
|
||||
echo "Mount subpartitions of $partition"
|
||||
SUBPARTITION_DEV="$partition"
|
||||
# shellcheck disable=SC2086
|
||||
SUBPARTITION_LOOP="$(losetup $losetup_args "$partition")"
|
||||
if [ -z "$SUBPARTITION_LOOP" ]; then
|
||||
echo "WARNING: failed to create loop device for $partition"
|
||||
SUBPARTITION_DEV=""
|
||||
continue
|
||||
;;
|
||||
*)
|
||||
continue
|
||||
;;
|
||||
esac
|
||||
fi
|
||||
# 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
|
||||
[ -n "$SUBPARTITION_LOOP" ] && losetup -vd "$SUBPARTITION_LOOP"
|
||||
SUBPARTITION_DEV=""
|
||||
SUBPARTITION_LOOP=""
|
||||
fi
|
||||
done
|
||||
if [ "$(get_uptime_seconds)" -ge $(( attempt_start + wait_seconds )) ]; then
|
||||
echo "ERROR: failed to mount subpartitions!"
|
||||
|
|
|
|||
|
|
@ -31,42 +31,23 @@ resize_root_partition() {
|
|||
return
|
||||
fi
|
||||
|
||||
# Only resize the partition if it's inside the device-mapper, which means
|
||||
# that the partition is stored as a subpartition inside another one.
|
||||
# In this case we want to resize it to use all the unused space of the
|
||||
# external partition.
|
||||
if [ -z "${partition##"/dev/mapper/"*}" ] || [ -z "${partition##"/dev/dm-"*}" ]; then
|
||||
# Get physical device
|
||||
if [ -n "$SUBPARTITION_DEV" ]; then
|
||||
partition_dev="$SUBPARTITION_DEV"
|
||||
else
|
||||
partition_dev=$(dmsetup deps -o blkdevname "$partition" | \
|
||||
awk -F "[()]" '{print "/dev/"$2}')
|
||||
fi
|
||||
if has_unallocated_space "$partition_dev"; then
|
||||
echo "Resize root partition ($partition)"
|
||||
# unmount subpartition, resize and remount it
|
||||
kpartx -d "$partition"
|
||||
parted -f -s "$partition_dev" resizepart 2 100%
|
||||
kpartx -afs "$partition_dev"
|
||||
else
|
||||
echo "Not resizing root partition ($partition): no free space left"
|
||||
fi
|
||||
local resize_dev="" check_dev="" partnum=2
|
||||
|
||||
# Always resize if using subpartitions, which means the partition
|
||||
# is stored as a nested GPT inside another partition. In this case we want to
|
||||
# resize the GPT so the inner root partition can make use of all the available
|
||||
# space.
|
||||
if [ -n "$SUBPARTITION_LOOP" ]; then
|
||||
#
|
||||
resize_dev="$SUBPARTITION_LOOP"
|
||||
check_dev="$SUBPARTITION_LOOP"
|
||||
# Resize the root partition (non-subpartitions). Usually we do not want
|
||||
# this, except for QEMU devices and non-android devices (e.g.
|
||||
# PinePhone). For them, it is fine to use the whole storage device and
|
||||
# so we pass PMOS_FORCE_PARTITION_RESIZE as kernel parameter.
|
||||
elif [ "$force_partition_resize" = "y" ]; then
|
||||
partition_dev="$(echo "$partition" | sed -E 's/p?2$//')"
|
||||
if has_unallocated_space "$partition_dev"; then
|
||||
echo "Resize root partition ($partition)"
|
||||
parted -f -s "$partition_dev" resizepart 2 100%
|
||||
partprobe
|
||||
else
|
||||
echo "Not resizing root partition ($partition): no free space left"
|
||||
fi
|
||||
|
||||
check_dev="$(echo "$partition" | sed -E 's/p?2$//')"
|
||||
resize_dev="$check_dev"
|
||||
# Resize the root partition (non-subpartitions) on Chrome OS devices.
|
||||
# Match $deviceinfo_cgpt_kpart not being empty instead of cmdline
|
||||
# because it does not make sense here as all these devices use the same
|
||||
|
|
@ -74,17 +55,21 @@ resize_root_partition() {
|
|||
# second, because these devices have an additional kernel partition
|
||||
# at the start.
|
||||
elif [ -n "$deviceinfo_cgpt_kpart" ]; then
|
||||
partition_dev="$(echo "$partition" | sed -E 's/p?3$//')"
|
||||
if has_unallocated_space "$partition_dev"; then
|
||||
echo "Resize root partition ($partition)"
|
||||
parted -f -s "$partition_dev" resizepart 3 100%
|
||||
partprobe
|
||||
else
|
||||
echo "Not resizing root partition ($partition): no free space left"
|
||||
fi
|
||||
|
||||
check_dev="$(echo "$partition" | sed -E 's/p?3$//')"
|
||||
resize_dev="$check_dev"
|
||||
partnum=3
|
||||
else
|
||||
echo "Unable to resize root partition: failed to find qualifying partition"
|
||||
return
|
||||
fi
|
||||
|
||||
# Resize if needed
|
||||
if has_unallocated_space "$check_dev"; then
|
||||
echo "Resize root partition ($partition)"
|
||||
parted -f -s "$resize_dev" resizepart "$partnum" 100%
|
||||
partprobe
|
||||
else
|
||||
echo "Not resizing root partition ($partition): no free space left"
|
||||
fi
|
||||
}
|
||||
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue