errcatch
-[[ $EUID == 0 ]] || sudo "$BASH_SOURCE" "$@"
+[[ $EUID == 0 ]] || exec sudo "$BASH_SOURCE" "$@"
usage() {
cat <<EOF
Usage: ${0##*/} [OPTIONS] +/-SIZE[g] swap|boot
-Assuming Ian Kelling's partition scheme,
-Resize swap or boot, expanding or shrinking the root fs and partition to compensate.
+Assuming Ian Kelling's partition scheme, Resize swap or boot, expanding
+or shrinking the root fs and partition to compensate. If it changes
+the partition tables incorrectly, the originals are stored in
+/root/backup_partition_table_<device_names>.
-n Dry run
-r Reboot now if it's needed.
reboot_not=false
dry_run=false
-temp=$(getopt -l opt o "$@") || usage 1
+temp=$(getopt -l help rnh "$@") || usage 1
eval set -- "$temp"
while true; do
case $1 in
[[ $2 == boot ]] || boot=false
op_size=$1 # operator plus size
-[[ $op_size != *g ]] || op_size=$(( ${op_size%g} / 1024 ))
-size=${op_size#[+-]}
+if [[ $op_size == *g ]]; then
+ op_size=${op_size%g}
+ size=${op_size#?}
+ op=${op_size%size}
+ size=$(( ${size} * 1024 ))
+ op_size=$op$size
+else
+ size=${op_size#?}
+fi
if [[ $op_size == +* ]]; then
op_size_rev=-$size # rev = reverse
grow=false
fi
-
##### end command line parsing ########
rootn=1
needs_reboot=false
reboot_script_initialized=false
-pmk() {
+pmk() { # partition make
part=$1
start_op=$2
end_op=$3
- p mkpart primary "$4" \
- $((${ptable[start$part]} $start_op)) $((${ptable[end$part]} $end_op))
+ fs_type="$4"
+
+ # This fails outside a vm, but actually succeeds. also prints this
+ # message:
+ # Error: Partition(s) 2 on /dev/sda have been written, but
+ # we have been unable to inform the kernel of the change, probably
+ # because it/they are in use. As a result, the old partition(s)
+ # will remain in use. You should reboot now before making further
+ # changes.
+
+ p mkpart primary "$fs_type" \
+ $((${ptable[start$part]} $start_op)) $((${ptable[end$part]} $end_op)) ||:
}
def-e() {
e swapoff -a
while read devid dev; do
+ if [[ $dev != /dev/mapper/* ]]; then
+ # older oses, it points to /dev/dm-x
+ dev=$(dmsetup info $dev | sed -rn 's/^\s*Name:\s*(\S*)/\1/p')
+ else
+ dev=${dev#/dev/mapper/}
+ fi
+ dev=${dev#crypt_dev_}
+ r='-part[0-9]*$'
+ [[ $dev =~ $r ]] ||:
+ dev=${dev%$BASH_REMATCH}
+ devpath=/dev/disk/by-id/$dev
echo skip=$size
def-e
declare -A ptable
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_table_$dev
- p() { e parted -a optimal -s -- /dev/$dev unit MiB "$@"; }
- e systemctl stop systemd-cryptsetup@crypt_swap_$dev$swapn
+ done < <(parted -m $devpath unit MiB print)
+ parted $devpath unit MiB print | tee /root/backup_partition_table_$dev
+ p() { e parted -a optimal -s -- $devpath unit MiB "$@"; }
+ unit=systemd-cryptsetup@crypt_dev_$dev-part$swapn
+ # note systemctl show can test if a unit exists.
+ e systemctl stop $unit || [[ $? == 5 ]] # fail due to not loaded
+ # there is a bug in jessie. this and the .swap unit are
+ # generated from /etc/fstab, and it escapes - to x2d, then doesn't escape it
+ # when looking for the file to use as swap. so, no swap is working on jessie
+ # right now.
sleep 1 # dunno if this is needed,
# but systemd likes to do these kind of things in the background.
$root_resize_cmd
fi
if $boot; then
+ # non by-id path, to match what btrfs fi show will tell us
+ boot_dev_path=$(readlink -f $devpath-part$bootn)
boot_devid=$(btrfs fi show /boot | \
- sed -rn "s#^\s*devid\s+(\S+)\s.*$dev[0-9]#\1#p")
+ sed -rn "s#^\s*devid\s+(\S+)\s.*$boot_dev_path#\1#p")
if ! $grow; then
# shrink boot, move it to a temp file
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 \
+ e dd bs=1M if=$boot_dev_path of=$temp_boot \
count=$((${ptable[size$bootn]} $op_size))
else
e umount /boot
pmk $bootn $op_size_rev ""
if $grow; then
- e dd bs=1M if=/dev/$dev$bootn of=/dev/$dev$bootn skip=$size
+ e dd bs=1M if=$boot_dev_path of=$boot_dev_path skip=$size
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 dd bs=1M if=$temp_boot of=$boot_dev_path
e mount /boot
fi
else
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')
+done < <(btrfs fi show / | sed -nr 's#^\s*devid\s*(\S+).* path (.*)$#\1 \2#p')
if $boot; then
exit
fi
fi
-