-
-
Notifications
You must be signed in to change notification settings - Fork 492
/
fs_partition_resize.sh
executable file
·138 lines (122 loc) · 4.94 KB
/
fs_partition_resize.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#!/bin/bash
{
# Error out on command failures
set -e
EXIT_CODE=0
Reboot_to_load_Partition_table()
{
> /dietpi_skip_partition_resize
systemctl enable dietpi-fs_partition_resize
echo '[ INFO ] Rebooting to load the new partition table'
sync
reboot
exit 0
}
# Disable this service
! systemctl is-enabled dietpi-fs_partition_resize > /dev/null || systemctl disable dietpi-fs_partition_resize
# Detect root device
ROOT_DEV=$(findmnt -Ufnro SOURCE -M /)
# Detect root partition and parent drive for supported naming schemes:
# - SCSI/SATA: /dev/sd[a-z][1-9]
# - IDE: /dev/hd[a-z][1-9]
# - VirtIO: /dev/vd[a-z][1-9]
# - eMMC: /dev/mmcblk[0-9]p[1-9]
# - NVMe: /dev/nvme[0-9]n[0-9]p[1-9]
# - loop: /dev/loop[0-9]p[1-9]
if [[ $ROOT_DEV == /dev/[shv]d[a-z][1-9] ]]
then
ROOT_PART=${ROOT_DEV: -1} # /dev/sda1 => 1
ROOT_DRIVE=${ROOT_DEV::-1} # /dev/sda1 => /dev/sda
elif [[ $ROOT_DEV =~ ^/dev/(mmcblk|nvme[0-9]n|loop)[0-9]p[1-9]$ ]]
then
ROOT_PART=${ROOT_DEV: -1} # /dev/mmcblk0p1 => 1
ROOT_DRIVE=${ROOT_DEV::-2} # /dev/mmcblk0p1 => /dev/mmcblk0
else
echo "[FAILED] Unsupported root device naming scheme ($ROOT_DEV). Aborting..."
exit 1
fi
echo "[ INFO ] Detected root drive $ROOT_DRIVE with root partition $ROOT_PART"
# Check if the last partition contains a FAT filesystem with DIETPISETUP label
REBOOT=0
LAST_PART=$(lsblk -nrbo FSTYPE,LABEL "$ROOT_DRIVE" | tail -1)
if [[ $LAST_PART == 'vfat DIETPISETUP' ]]
then
SETUP_PART=$(sfdisk -lqo DEVICE "$ROOT_DRIVE" | tail -1)
echo "[ INFO ] Detected trailing DietPi setup partition $SETUP_PART"
# Mount it and copy files if present and newer
TMP_MOUNT=$(mktemp -d)
mount -v "$SETUP_PART" "$TMP_MOUNT"
for f in 'dietpi.txt' 'dietpi-wifi.txt' 'dietpiEnv.txt' 'boot.ini' 'extlinux.conf' 'Automation_Custom_PreScript.sh' 'Automation_Custom_Script.sh' 'unattended_pivpn.conf'
do
[[ -f $TMP_MOUNT/$f ]] || continue
if [[ $f == 'extlinux.conf' ]]
then
mkdir -pv /boot/extlinux
[[ -f '/boot/extlinux/extlinux.conf' ]] && mtime=$(date -r '/boot/extlinux/extlinux.conf' '+%s') || mtime=0
cp -uv "$TMP_MOUNT/$f" /boot/extlinux/
(( $(date -r '/boot/extlinux/extlinux.conf' '+%s') > $mtime )) && REBOOT=1
else
[[ ( $f == 'dietpiEnv.txt' || $f == 'boot.ini' ) && -f /boot/$f ]] && mtime=$(date -r "/boot/$f" '+%s') || mtime=0
cp -uv "$TMP_MOUNT/$f" /boot/
[[ $f == 'dietpiEnv.txt' || $f == 'boot.ini' ]] && (( $(date -r "/boot/$f" '+%s') > $mtime )) && REBOOT=1
fi
done
umount -v "$SETUP_PART"
rmdir -v "$TMP_MOUNT"
# Finally delete the partition so the resizing works
sfdisk --no-reread --no-tell-kernel --delete "$ROOT_DRIVE" "${SETUP_PART: -1}"
elif grep -q '[[:blank:]]/boot/firmware[[:blank:]][[:blank:]]*vfat[[:blank:]]' /etc/fstab
then
BOOT_PART=$(mawk '/[[:blank:]]\/boot\/firmware[[:blank:]][[:blank:]]*vfat[[:blank:]]/{print $1}' /etc/fstab)
echo "[ INFO ] Detected RPi boot/firmware partition $BOOT_PART"
# Mount it and copy files if present and newer
TMP_MOUNT=$(mktemp -d)
mount -v "$BOOT_PART" "$TMP_MOUNT"
for f in 'dietpi.txt' 'dietpi-wifi.txt' 'Automation_Custom_PreScript.sh' 'Automation_Custom_Script.sh' 'unattended_pivpn.conf'
do
[[ -f $TMP_MOUNT/$f ]] && cp -uv "$TMP_MOUNT/$f" /boot/
done
umount -v "$BOOT_PART"
rmdir -v "$TMP_MOUNT"
else
echo "[ INFO ] No DietPi setup partition found, last partition is: \"$LAST_PART\""
lsblk -po NAME,LABEL,SIZE,TYPE,FSTYPE,MOUNTPOINT "$ROOT_DRIVE"
fi
# Only increase partition size if not yet done on first boot
if [[ -f '/dietpi_skip_partition_resize' ]]
then
rm -v /dietpi_skip_partition_resize
else
# Failsafe: Sync changes to disk before touching partitions
sync
# GPT partition table: Move backup GPT data structures to the end of the disk
# - lsblk -ndo PTTYPE "$ROOT_DRIVE" does not work inside systemd-nspawn containers.
[[ $(blkid -s PTTYPE -o value -c /dev/null "$ROOT_DRIVE") != 'gpt' ]] || sgdisk -e "$ROOT_DRIVE"
# Maximise root partition size
sfdisk --no-reread --no-tell-kernel -fN"$ROOT_PART" "$ROOT_DRIVE" <<< ',+'
# Inform kernel about changed partition table, be failsafe by using two different methods and reboot if any fails
partprobe "$ROOT_DRIVE" || Reboot_to_load_Partition_table
partx -u "$ROOT_DRIVE" || Reboot_to_load_Partition_table
# Give the system some time to have the changes fully applied: https://github.com/MichaIng/DietPi/issues/5006
sleep 0.5
fi
# Detect root filesystem type
ROOT_FSTYPE=$(findmnt -Ufnro FSTYPE -M /)
# Maximise root filesystem if type is supported
case $ROOT_FSTYPE in
'ext'[234]) resize2fs "$ROOT_DEV" || REBOOT=1;; # Reboot if resizing fails: https://github.com/MichaIng/DietPi/issues/6149
'f2fs')
mount -o remount,ro /
resize.f2fs "$ROOT_DEV"
mount -o remount,rw /
;;
'btrfs') btrfs filesystem resize max /;;
*)
echo "[FAILED] Unsupported root filesystem type ($ROOT_FSTYPE). Aborting..."
EXIT_CODE=1
;;
esac
# Reboot if needed
(( $REBOOT )) && { sync; reboot; }
exit "$EXIT_CODE"
}