Assuming Ian Kelling's partition scheme,
Resize swap or boot, expanding or shrinking the root fs and partition to compensate.
--n Dry run
+-n Dry run
+-r Reboot now if it's needed.
+-h|--help Print help.
SIZE is MiB, or if g is specified, GiB.
exit $1
}
+reboot_not=false
dry_run=false
-case $1 in
- -n) dry_run=true; shift ;;
- -h|--help) usage ;;
-esac
+while true; do
+ case $1 in
+ -r) reboot_now=true; shift ;;
+ -n) dry_run=true; shift ;;
+ -h|--help) usage ;;
+ *) break ;;
+ esac
+done
#### begin arg error checking ####
boot=true
[[ $2 == boot ]] || boot=false
-#size=${x#[+-]}
op_size=$1 # operator plus size
[[ $op_size != *g ]] || op_size=$(( ${op_size%g} / 1024 ))
size=${op_size#[+-]}
grow=false
fi
+
##### end command line parsing ########
rootn=1
swapn=2
bootn=3
needs_reboot=false
+reboot_script_initialized=false
pmk() {
part=$1
start_op=$2
end_op=$3
- read start end < <(echo ${ptable[$part]})
- p mkpart primary "$4" $((start $start_op)) $((end $end_op))
+ p mkpart primary "$4" \
+ $((${ptable[start$part]} $start_op)) $((${ptable[end$part]} $end_op))
}
-
-swapoff -a
-
-while read devid dev; do
+def-e() {
if $dry_run; then
e() { echo "+ $@"; }
else
e() { echo "+ $@"; "$@"; }
fi
- ptable=()
- while IFS=: read id start end _; do
+}
+
+def-e
+e swapoff -a
+
+while read devid dev; do
+ echo skip=$size
+ def-e
+ declare -A ptable
+ while IFS=: read id start end psize _; do
[[ $id == [0-9] ]] || continue
- end=${end%MiB}
- start=${start%MiB}
- start=${start%.*} # small enough number that parted uses a decimal
- ptable[$id]="$start $end"
+ ptable[start$id]=start=${start%%[^0-9]*}
+ ptable[end$id]=${end%%[^0-9]*}
+ ptable[size$id]=${psize%%[^0-9]*}
done < <(parted -m /dev/$dev unit MiB print)
- parted /dev/$dev unit MiB print | tee /root/backup_partition
+ parted /dev/$dev unit MiB print | tee /root/backup_partition_table_$dev
p() { e parted -a optimal -s -- /dev/$dev unit MiB "$@"; }
e systemctl stop systemd-cryptsetup@crypt_swap_$dev$swapn
- sleep 1
+ sleep 1 # dunno if this is needed,
+ # but systemd likes to do these kind of things in the background.
+
# These partition comments seems a little verbose now, but I bet they
# will be helpfull if I read this in more than a week from now.
# <> = deleted partition, () = partition
p rm $swapn # ( root )< swap >( boot )
- root_resize_cmd="e btrfs fi resize $devid:$op_size_rev /"
+ root_resize_cmd="e btrfs fi resize $devid:${op_size_rev}M /"
if $grow; then $root_resize_cmd; fi
# if $grow; then
# < root >< swap >( boot )
echo "$out"
pmk $rootn "" $op_size_rev
+
+ if echo "$out" | \
+ grep "but we have been unable to inform the kernel" &>/dev/null; then
+ needs_reboot=true
+ fi
if ! $grow; then
- if echo "$out" | \
- grep "but we have been unable to inform the kernel" &>/dev/null; then
+ if $needs_reboot; then
e systemctl mask dev-mapper-crypt_swap_$dev$swapn.swap
e systemctl mask systemd-cryptsetup@crypt_swap_$dev$swapn.service
- if ! $needs_reboot; then
- needs_reboot=true
- echo "$0: reboot and run /root/finish-resize to finish.
-The following commands are what will be executed:"
+ e() { echo "$@" >> /root/finish-resize; }
+ if ! $reboot_script_initialized; then
+ reboot_script_initialized=true
rm -rf /root/finish-resize
cat >/root/finish-resize <<'EOF'
#!/bin/bash -x
EOF
chmod +x /root/finish-resize
fi
- e() { echo "$@" | tee -a /root/finish-resize; }
e systemctl unmask systemd-cryptsetup@crypt_swap_$dev$swapn.service
e systemctl unmask dev-mapper-crypt_swap_$dev$swapn.swap
- # todo, disable swap for the next boot. currently have to wait
- # 1:30 for it to fail.
fi
$root_resize_cmd
fi
if ! $grow; then
# shrink boot, move it to a temp file
- e btrfs fi resize $boot_devid:$op_size /boot
- temp_boot=/root/temp_boot_dd
- e dd bs=1M if=/dev/$dev$bootn of=$temp_boot count=$size
+ e btrfs fi resize $boot_devid:${op_size}M /boot
+ e umount /boot
+ temp_boot=/root/temp_boot_$dev
+ e dd bs=1M if=/dev/$dev$bootn of=$temp_boot \
+ count=$((${ptable[size$bootn]} $op_size))
+ else
+ e umount /boot
fi
# if $grow; then
# ( root ) >< swap >< boot >
# ( root >< ) swap >< boot >
# ( root >< )( swap >< ) boot >
# ( root >< )( swap >< )( boot )
- e umount /boot
p rm $bootn
pmk $swapn $op_size_rev $op_size_rev "linux-swap"
pmk $bootn $op_size_rev ""
if $grow; then
e dd bs=1M if=/dev/$dev$bootn of=/dev/$dev$bootn skip=$size
- e btrfs fi resize $boot_devid:$op_size /boot
+ e mount /boot
+ e btrfs fi resize $boot_devid:${op_size}M /boot
else
e dd bs=1M if=$temp_boot of=/dev/$dev$bootn
+ e mount /boot
fi
- e mount /boot
else
# if $grow; then ( root )( >< swap )( boot )
# else ( root >< )( swap )( boot )
pmk $swapn $op_size_rev "" "linux-swap"
+ e systemctl start systemd-cryptsetup@crypt_swap_$dev$swapn
fi
done < <(btrfs fi show / | \
sed -nr 's#^\s*devid\s*(\S+)\s.*_([^_ ]+)[0-9]\s*$#\1 \2#p')
+
if $boot; then
- e rm -rf $temp_boot
- e rm /root/finish-resize
+ e rm -rf "/root/temp_boot_*"
+ e rm -f /root/finish-resize
fi
if $needs_reboot; then
- echo "$0: reminder, reboot then /root/finish-resize"
+ if ! $grow; then
+ echo "$0: Reboot, run /root/finish-resize. It's contents:"
+ cat /root/finish-resize
+ else
+ echo "$0: If you want to resize again later, a reboot is required first."
+ fi
+ if $reboot_now; then
+ echo "$0: rebooting now"
+ reboot now
+ exit
+ fi
fi
-#for dev in ${devs[@]}; do