5 # shows function args when: shopt -s extdebug
6 local -i argc_index
=0 arg frame i start
=${1:-1} max_indent
=8 indent
9 if [[ $
(shopt -p extdebug
) == *-s* ]]; then
13 for ((frame
=0; frame
< ${#FUNCNAME[@]}-1; frame
++)); do
14 argc
=${BASH_ARGC[frame]}
16 ((frame
< start
)) && continue
17 if (( ${#BASH_SOURCE[@]} > 1 )); then
18 source="${BASH_SOURCE[frame+1]}:${BASH_LINENO[frame]}:"
20 indent
=$
((frame-start
+1))
21 indent
=$
((indent
< max_indent ? indent
: max_indent
))
22 printf "%${indent}s↳%sin \`%s" '' "$source" "${FUNCNAME[frame]}"
24 for ((i
=argc_index-1
; i
>= argc_index-argc
; i--
)); do
25 printf " %s" "${BASH_ARGV[i]}"
34 set -E; shopt -s extdebug
38 echo "${BASH_SOURCE[1]}:${BASH_LINENO[0]}:in \`$BASH_COMMAND' returned $err"
40 echo "$0: exiting with code $err"
49 [[ $EUID == 0 ]] || sudo
"$BASH_SOURCE" "$@"
53 Usage: ${0##*/} [-n] +/-SIZE[g] swap|boot
55 Assuming Ian Kelling's partition scheme,
56 Resize swap or boot, expanding or shrinking the root fs and partition to compensate.
60 SIZE is MiB, or if g is specified, GiB.
62 If using multiple devices, SIZE is applied to each device, so total change is
72 -n) dry_run
=true
; shift ;;
76 #### begin arg error checking ####
78 if [[ $# != 2 ]]; then
79 echo "$0: error: expected 2 arguments"
83 if [[ $1 != [+-][0-9]* ]]; then
84 echo "$0: error: bad 1st arg: $1"
88 if ! which parted
&>/dev
/null
; then
89 echo "$0: error: install parted"
93 case $2 in swap|boot
) : ;; *) echo "$0: error: bad 2nd arg"; usage
1 ;; esac
95 #### end arg error checking ####
99 [[ $2 == boot
]] || boot
=false
102 op_size
=$1 # operator plus size
103 [[ $op_size != *g
]] || op_size
=$
(( ${op_size%g} / 1024 ))
106 if [[ $op_size == +* ]]; then
107 op_size_rev
=-$size # rev = reverse
114 ##### end command line parsing ########
125 read start end
< <(echo ${ptable[$part]})
126 p mkpart primary
"$4" $
((start
$start_op)) $
((end
$end_op))
132 while read devid dev
; do
136 e
() { echo "+ $@"; "$@"; }
139 while IFS
=: read id start end _
; do
140 [[ $id == [0-9] ]] ||
continue
143 start
=${start%.*} # small enough number that parted uses a decimal
144 ptable
[$id]="$start $end"
145 done < <(parted
-m /dev
/$dev unit MiB print
)
146 parted
/dev
/$dev unit MiB print |
tee /root
/backup_partition
147 p
() { e parted
-a optimal
-s -- /dev
/$dev unit MiB
"$@"; }
148 e systemctl stop systemd-cryptsetup@crypt_swap_
$dev$swapn
150 # These partition comments seems a little verbose now, but I bet they
151 # will be helpfull if I read this in more than a week from now.
152 # <> = deleted partition, () = partition
153 p
rm $swapn # ( root )< swap >( boot )
155 root_resize_cmd
="e btrfs fi resize $devid:$op_size_rev /"
156 if $grow; then $root_resize_cmd; fi
158 # < root >< swap >( boot )
159 # ( root ) >< swap >( boot )
161 # < root >< swap >( boot )
162 # ( root >< ) swap >( boot )
164 out
=$
(p
rm $rootn 2>&1)
167 pmk
$rootn "" $op_size_rev
170 grep "but we have been unable to inform the kernel" &>/dev
/null
; then
171 e systemctl mask dev-mapper-crypt_swap_
$dev$swapn.swap
172 e systemctl mask systemd-cryptsetup@crypt_swap_
$dev$swapn.service
173 if ! $needs_reboot; then
175 echo "$0: reboot and run /root/finish-resize to finish.
176 The following commands are what will be executed:"
177 rm -rf /root
/finish-resize
178 cat >/root
/finish-resize
<<'EOF'
181 trap 'echo "$0:$LINENO:error: \"$BASH_COMMAND\" returned $?"' ERR
183 chmod +x
/root
/finish-resize
185 e
() { echo "$@" |
tee -a /root
/finish-resize
; }
186 e systemctl unmask systemd-cryptsetup@crypt_swap_
$dev$swapn.service
187 e systemctl unmask dev-mapper-crypt_swap_
$dev$swapn.swap
188 # todo, disable swap for the next boot. currently have to wait
189 # 1:30 for it to fail.
194 boot_devid
=$
(btrfs
fi show
/boot | \
195 sed -rn "s#^\s*devid\s+(\S+)\s.*$dev[0-9]#\1#p")
198 # shrink boot, move it to a temp file
199 e btrfs
fi resize
$boot_devid:$op_size /boot
200 temp_boot
=/root
/temp_boot_dd
201 e
dd bs
=1M
if=/dev
/$dev$bootn of
=$temp_boot count
=$size
204 # ( root ) >< swap >< boot >
205 # ( root )( >< swap ) >< boot >
206 # ( root )( >< swap )( >< boot )
208 # ( root >< ) swap >< boot >
209 # ( root >< )( swap >< ) boot >
210 # ( root >< )( swap >< )( boot )
213 pmk
$swapn $op_size_rev $op_size_rev "linux-swap"
214 pmk
$bootn $op_size_rev ""
217 e
dd bs
=1M
if=/dev
/$dev$bootn of
=/dev
/$dev$bootn skip
=$size
218 e btrfs
fi resize
$boot_devid:$op_size /boot
220 e
dd bs
=1M
if=$temp_boot of
=/dev
/$dev$bootn
224 # if $grow; then ( root )( >< swap )( boot )
225 # else ( root >< )( swap )( boot )
226 pmk
$swapn $op_size_rev "" "linux-swap"
228 done < <(btrfs
fi show
/ | \
229 sed -nr 's#^\s*devid\s*(\S+)\s.*_([^_ ]+)[0-9]\s*$#\1 \2#p')
233 e
rm /root
/finish-resize
236 if $needs_reboot; then
237 echo "$0: reminder, reboot then /root/finish-resize"
240 #for dev in ${devs[@]}; do