mirror of
https://github.com/ps5-linux/ps5-linux-image.git
synced 2026-07-16 01:50:40 +00:00
92 lines
3.9 KiB
Bash
92 lines
3.9 KiB
Bash
#!/bin/bash
|
|
# Grows the root partition + filesystem to fill the disk on first boot.
|
|
# Self-disables after success.
|
|
#
|
|
# Uses sfdisk + partx + resize2fs (all in util-linux + e2fsprogs, both
|
|
# present in the minimal Arch/SteamOS base). Earlier versions called
|
|
# growpart from cloud-utils — but that package isn't in the SteamOS
|
|
# recovery image, so the unit failed with "growpart: command not found"
|
|
# and rootfs stayed at the dd'd image size (~14 GB) on any disk larger
|
|
# than that.
|
|
set -e
|
|
|
|
ROOT_DEV=$(findmnt -no SOURCE /)
|
|
DISK="/dev/$(lsblk -ndo PKNAME "$ROOT_DEV")"
|
|
|
|
# PS5 M.2 drive appear as /dev/nvme*. Do not modify partition table,
|
|
# because it contains m2_init PS5 offset. Only USB drive (/dev/sd*)
|
|
# are safe for automatic grow root partition.
|
|
if [[ "$(basename "$DISK")" == nvme* ]]; then
|
|
echo "grow-rootfs: M.2 detected, skipping"
|
|
systemctl disable grow-rootfs.service
|
|
exit 0
|
|
fi
|
|
|
|
PART_NUM=$(cat /sys/class/block/$(basename "$ROOT_DEV")/partition)
|
|
|
|
# Our images dd at their built size (~14 GB) onto a much larger USB. The GPT
|
|
# backup header is therefore at byte ~built-size, not at end of disk. Move
|
|
# the backup header to end-of-disk first so partition table growth works.
|
|
sgdisk -e "$DISK"
|
|
|
|
# If a previous flash left behind partitions BEYOND our rootfs + boot pair
|
|
# (e.g. a stale `linux-home` partset at part 3 from a prior SteamOS install
|
|
# on the same drive), the partition extend refuses to grow into the space
|
|
# already claimed by the leftover partition. Delete every partition with a
|
|
# number higher than 2 — we only ever create partitions 1 (rootfs) + 2 (boot).
|
|
# Important: sgdisk only rewrites the on-disk GPT; we must ALSO drop those
|
|
# stale entries from the kernel's in-memory partition table via partx -d,
|
|
# or BLKPG_RESIZE_PARTITION below returns EBUSY because the kernel still
|
|
# thinks sda1 would have to grow into space owned by phantom sda3.
|
|
for n in $(parted -ms "$DISK" print 2>/dev/null \
|
|
| awk -F: 'NR>2 && $1+0>2 {print $1}'); do
|
|
sgdisk -d "$n" "$DISK" 2>/dev/null || true
|
|
partx -d --nr "$n" "$DISK" 2>/dev/null || true
|
|
done
|
|
|
|
# sfdisk `,+` extends partition $PART_NUM to consume all available free
|
|
# space. Works on a mounted/live partition because sfdisk only rewrites
|
|
# the GPT entry (kernel re-read of the partition table comes next).
|
|
echo ",+" | sfdisk --no-reread -N "$PART_NUM" "$DISK"
|
|
|
|
# Make the kernel pick up the new partition size without unmounting via
|
|
# BLKPG_RESIZE_PARTITION. partx -u also uses BLKPG, but on some images
|
|
# (notably SteamOS recovery loop-mounted btrfs) partx returns an error
|
|
# updating the mounted partition; the direct ioctl is more reliable.
|
|
python3 - "$DISK" "$PART_NUM" <<'PY'
|
|
import sys, os, fcntl, ctypes, subprocess
|
|
disk, pno = sys.argv[1], int(sys.argv[2])
|
|
out = subprocess.run(["sfdisk","--bytes","-q","-l",disk],
|
|
capture_output=True, text=True, check=True).stdout
|
|
start = sectors = None
|
|
for line in out.splitlines():
|
|
if line.startswith(f"{disk}{pno} ") or line.startswith(f"{disk}p{pno} "):
|
|
f = line.split()
|
|
start, sectors = int(f[1]), int(f[3])
|
|
break
|
|
if start is None:
|
|
sys.exit(f"could not parse partition {pno} from sfdisk -l {disk}")
|
|
class P(ctypes.Structure):
|
|
_fields_=[("start",ctypes.c_longlong),("length",ctypes.c_longlong),
|
|
("pno",ctypes.c_int),("devname",ctypes.c_char*64),
|
|
("volname",ctypes.c_char*64)]
|
|
class A(ctypes.Structure):
|
|
_fields_=[("op",ctypes.c_int),("flags",ctypes.c_int),
|
|
("datalen",ctypes.c_int),("data",ctypes.c_void_p)]
|
|
p = P(start=start*512, length=sectors*512, pno=pno)
|
|
a = A(op=3, flags=0, datalen=ctypes.sizeof(p), data=ctypes.addressof(p))
|
|
fd = os.open(disk, os.O_RDONLY)
|
|
try:
|
|
fcntl.ioctl(fd, 0x1269, a) # BLKPG, BLKPG_RESIZE_PARTITION
|
|
finally:
|
|
os.close(fd)
|
|
PY
|
|
|
|
# Belt-and-suspenders: also try partx in case BLKPG via python failed.
|
|
partx -u --nr "$PART_NUM" "$DISK" 2>/dev/null || true
|
|
|
|
# Online ext4 grow.
|
|
resize2fs "$ROOT_DEV"
|
|
|
|
systemctl disable grow-rootfs.service
|