Merge pull request #33 from marineam/repair-corruption
Fix gptprio to properly detect and repair corruption
This commit is contained in:
commit
87dfbf34c4
4 changed files with 63 additions and 6 deletions
|
@ -91,7 +91,7 @@ grub_find_next (const char *disk_name,
|
||||||
if (!gpt)
|
if (!gpt)
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
if (!(gpt->status & GRUB_GPT_BOTH_VALID))
|
if ((gpt->status & GRUB_GPT_BOTH_VALID) != GRUB_GPT_BOTH_VALID)
|
||||||
if (grub_gpt_repair (dev->disk, gpt))
|
if (grub_gpt_repair (dev->disk, gpt))
|
||||||
goto done;
|
goto done;
|
||||||
|
|
||||||
|
|
|
@ -649,7 +649,7 @@ grub_gpt_write (grub_disk_t disk, grub_gpt_t gpt)
|
||||||
{
|
{
|
||||||
/* TODO: update/repair protective MBRs too. */
|
/* TODO: update/repair protective MBRs too. */
|
||||||
|
|
||||||
if (!(gpt->status & GRUB_GPT_BOTH_VALID))
|
if ((gpt->status & GRUB_GPT_BOTH_VALID) != GRUB_GPT_BOTH_VALID)
|
||||||
return grub_error (GRUB_ERR_BAD_PART_TABLE, "Invalid GPT data");
|
return grub_error (GRUB_ERR_BAD_PART_TABLE, "Invalid GPT data");
|
||||||
|
|
||||||
grub_dprintf ("gpt", "writing primary GPT to %s\n", disk->name);
|
grub_dprintf ("gpt", "writing primary GPT to %s\n", disk->name);
|
||||||
|
|
|
@ -66,8 +66,9 @@ prio_uuid[3]="1aa5a658-5b02-414d-9b71-f7e6c151f0cd"
|
||||||
prio_uuid[4]="8aa0240d-98af-42b0-b32a-ccbe0572d62b"
|
prio_uuid[4]="8aa0240d-98af-42b0-b32a-ccbe0572d62b"
|
||||||
|
|
||||||
create_disk_image () {
|
create_disk_image () {
|
||||||
|
size=$1
|
||||||
rm -f "${img1}"
|
rm -f "${img1}"
|
||||||
dd if=/dev/zero of="${img1}" bs=512 count=1 seek=100 status=none
|
dd if=/dev/zero of="${img1}" bs=512 count=1 seek=$((size - 1)) status=none
|
||||||
${sgdisk} \
|
${sgdisk} \
|
||||||
-n 1:0:+1 -c 1:ESP -t 1:ef00 \
|
-n 1:0:+1 -c 1:ESP -t 1:ef00 \
|
||||||
-n 2:0:+1 -c 2:A -t 2:"${prio_type}" -u 2:"${prio_uuid[2]}" \
|
-n 2:0:+1 -c 2:A -t 2:"${prio_type}" -u 2:"${prio_uuid[2]}" \
|
||||||
|
@ -76,6 +77,35 @@ create_disk_image () {
|
||||||
"${img1}" >/dev/null
|
"${img1}" >/dev/null
|
||||||
}
|
}
|
||||||
|
|
||||||
|
wipe_disk_area () {
|
||||||
|
sector=$1
|
||||||
|
size=$2
|
||||||
|
dd if=/dev/zero of="${img1}" bs=512 count=${size} seek=${sector} conv=notrunc status=none
|
||||||
|
}
|
||||||
|
|
||||||
|
is_zero () {
|
||||||
|
sector=$1
|
||||||
|
size=$2
|
||||||
|
cmp -s -i $((sector * 512)) -n $((size * 512)) /dev/zero "${img1}"
|
||||||
|
}
|
||||||
|
|
||||||
|
check_is_zero () {
|
||||||
|
sector=$1
|
||||||
|
size=$2
|
||||||
|
if ! is_zero "$@"; then
|
||||||
|
echo "$size sector(s) starting at $sector should be all zero"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
|
check_not_zero () {
|
||||||
|
sector=$1
|
||||||
|
size=$2
|
||||||
|
if is_zero "$@"; then
|
||||||
|
echo "$size sector(s) starting at $sector should not be all zero"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
}
|
||||||
|
|
||||||
fmt_prio () {
|
fmt_prio () {
|
||||||
priority=$(( ( $1 & 15 ) << 48 ))
|
priority=$(( ( $1 & 15 ) << 48 ))
|
||||||
|
@ -93,10 +123,10 @@ set_prio () {
|
||||||
check_prio () {
|
check_prio () {
|
||||||
part="$1"
|
part="$1"
|
||||||
expect=$(fmt_prio $2 $3 $4)
|
expect=$(fmt_prio $2 $3 $4)
|
||||||
result=$(LANG=C ${sgdisk} -i "${part}" "${img1}" \
|
result=$(LANG=C ${sgdisk} -i "${part}" "${img1}" 2>&1 \
|
||||||
| awk '/^Attribute flags: / {print $3}')
|
| awk '/^Attribute flags: / {print $3}')
|
||||||
if [[ "${expect}" != "${result}" ]]; then
|
if [[ "${expect}" != "${result}" ]]; then
|
||||||
echo "Partition ${part} has attributes ${result}, not ${expect}" >&2
|
echo "Partition ${part} has attributes ${result:-??}, not ${expect}"
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
@ -133,6 +163,33 @@ create_disk_image 100
|
||||||
set_prio 2 3 2 1
|
set_prio 2 3 2 1
|
||||||
check_prio 2 3 2 1
|
check_prio 2 3 2 1
|
||||||
|
|
||||||
|
# Check gptprio works without modifying the disk when no update is required.
|
||||||
|
# Leaves any existing corruption as is, repairing in the OS is better.
|
||||||
|
create_disk_image 100
|
||||||
|
set_prio 2 1 0 1
|
||||||
|
wipe_disk_area 99 1
|
||||||
|
check_next 2 1 0 1
|
||||||
|
check_is_zero 99 1
|
||||||
|
|
||||||
|
create_disk_image 100
|
||||||
|
set_prio 2 1 0 1
|
||||||
|
wipe_disk_area 1 1
|
||||||
|
check_next 2 1 0 1
|
||||||
|
check_is_zero 1 1
|
||||||
|
|
||||||
|
# When writes do need to be made go ahead and perform the repair.
|
||||||
|
create_disk_image 100
|
||||||
|
set_prio 2 1 1 0
|
||||||
|
wipe_disk_area 99 1
|
||||||
|
check_next 2 1 0 0
|
||||||
|
check_not_zero 99 1
|
||||||
|
|
||||||
|
create_disk_image 100
|
||||||
|
set_prio 2 1 1 0
|
||||||
|
wipe_disk_area 1 1
|
||||||
|
check_next 2 1 0 0
|
||||||
|
check_not_zero 1 1
|
||||||
|
|
||||||
# Try two partitions before falling before falling back to a third
|
# Try two partitions before falling before falling back to a third
|
||||||
create_disk_image 100
|
create_disk_image 100
|
||||||
set_prio 2 3 3 0
|
set_prio 2 3 3 0
|
||||||
|
|
|
@ -53,7 +53,7 @@ case "${grub_modinfo_target_cpu}-${grub_modinfo_platform}" in
|
||||||
esac
|
esac
|
||||||
img1="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
|
img1="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
|
||||||
img2="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
|
img2="`mktemp "${TMPDIR:-/tmp}/tmp.XXXXXXXXXX"`" || exit 1
|
||||||
trap "rm -f '${img1}' '${ing2}'" EXIT
|
trap "rm -f '${img1}' '${img2}'" EXIT
|
||||||
|
|
||||||
create_disk_image () {
|
create_disk_image () {
|
||||||
size=$1
|
size=$1
|
||||||
|
|
Loading…
Reference in a new issue