various changes for libreboot having no pxe
[automated-distro-installer] / fresize
diff --git a/fresize b/fresize
index f08f4a6fa2c3a2eff6edc79dc9650675f5783d6e..f41e6fbecdadc250010598f2e36d0a4791180da3 100755 (executable)
--- a/fresize
+++ b/fresize
@@ -46,14 +46,16 @@ errcatch() {
 
 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.
@@ -72,7 +74,7 @@ EOF
 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
@@ -110,8 +112,15 @@ boot=true
 [[ $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
@@ -121,7 +130,6 @@ else
     grow=false
 fi
 
-
 ##### end command line parsing ########
 
 rootn=1
@@ -130,12 +138,22 @@ bootn=3
 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() {
@@ -150,6 +168,17 @@ 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
@@ -158,10 +187,16 @@ while read devid dev; do
         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.
 
@@ -209,15 +244,17 @@ EOF
         $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
@@ -235,11 +272,11 @@ EOF
         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
@@ -248,8 +285,7 @@ EOF
         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
@@ -270,4 +306,3 @@ if $needs_reboot; then
         exit
     fi
 fi
-