From 099bdf30b9c73c6924e632e174a5e988972301df Mon Sep 17 00:00:00 2001 From: Scott Moser Date: Wed, 5 Sep 2018 22:32:39 -0400 Subject: [PATCH] growpart: fix bug when resizing a middle partition with sgdisk. Added a test and made growpart output consistent between sgdisk and sfdisk resizers. Thanks to Fred De Backer. LP: #1706751 bzr-revno: 331 diff --git a/bin/growpart b/bin/growpart index 4947ede..2700365 100755 --- a/bin/growpart +++ b/bin/growpart @@ -327,7 +327,9 @@ resize_sfdisk() { >"${new_out}" || fail "failed to change size in output" - change_info="partition=${PART} start=${pt_start} old: size=${pt_size} end=${pt_end} new: size=${new_size},end=${max_end}" + change_info="partition=${PART} start=${pt_start}" + change_info="${change_info} old: size=${pt_size} end=${pt_end}" + change_info="${change_info} new: size=${new_size} end=${max_end}" if [ ${DRY_RUN} -ne 0 ]; then echo "CHANGE: ${change_info}" { @@ -436,6 +438,8 @@ resize_sgdisk() { pt_end=$(awk '$1 == '"${PART}"' { print $3 }' "${pt_data}") && [ -n "${pt_end}" ] || fail "${dev}: failed to get end sector" + # sgdisk start and end are inclusive. start 2048 length 10 ends at 2057. + pt_end=$((pt_end+1)) pt_size="$((${pt_end} - ${pt_start}))" # Get the last usable sector @@ -475,9 +479,9 @@ resize_sgdisk() { # Calculate the new size of the partition new_size=$((${pt_max} - ${pt_start})) - old="old: size=${pt_size},end=${pt_end}" - new="new: size=${new_size},end=${pt_max}" - change_info="${dev}: start=${pt_start} ${old} ${new}" + change_info="partition=${PART} start=${pt_start}" + change_info="${change_info} old: size=${pt_size} end=${pt_end}" + change_info="${change_info} new: size=${new_size} end=${pt_max}" # Backup the current partition table, we're about to modify it rq sgd_backup $wouldrun sgdisk "--backup=${GPT_BACKUP}" "${DISK}" || @@ -492,7 +496,7 @@ resize_sgdisk() { # - set the partition GUID # - set the partition name rq sgdisk_mod $wouldrun sgdisk --move-second-header "--delete=${PART}" \ - "--new=${PART}:${pt_start}:${pt_max}" \ + "--new=${PART}:${pt_start}:$((pt_max-1))" \ "--typecode=${PART}:${code}" \ "--partition-guid=${PART}:${guid}" \ "--change-name=${PART}:${name}" "${DISK}" && diff --git a/test/test-growpart-fsimage-middle b/test/test-growpart-fsimage-middle new file mode 100755 index 0000000..4f2dfbf --- /dev/null +++ b/test/test-growpart-fsimage-middle @@ -0,0 +1,74 @@ +#!/bin/bash +# +# Create a disk image where a partition other than the last is grown. +# brought up under bug 1706751, where we had an off-by-one error +# when resizing with sgdisk. + +set -e + +TEMP_D="" + +rq() { + local out="${TEMP_D}/out" + "$@" > "$out" 2>&1 || { echo "FAILED:" "$@"; cat "$out"; return 1; } +} +fail() { echo "FAILED:" "$@" 1>&2; exit 1; } + +setup_img() { + local img_fp="$1" img="" + img=$(basename "$img_fp") + sfdisk "${img_fp}" <"$err" > "$out"; then + cat "$err" "$out" + fail "[resizer=$resizer] growpart failed" + fi + echo "==== after ====" + ( cd "${TEMP_D}" && sfdisk --dump "${img##*/}" ) + echo + echo "==== after sgdisk ===" + ( cd "${TEMP_D}" && sgdisk --print "${img##*/}" ) + echo "==== growpart-stderr ===" + cat "$err" + echo "==== growpart-stdout ====" + cat "$out" + [ "$(cat $out)" = "$expected" ] || { + fail "[resizer=$resizer] output ^^^ did not match expected vvv:${CR}$expected" + } +done + +# vi: ts=4 noexpandtab -- 2.17.2