System > Inne

Jak zmienić lokalizację zapasowej tablicy GPT?

(1/1)

overcq:
Mam już dość długo używany dysk HDD. I od niedawna, od czasu ostatniej modyfikacji tablicy partycji, pojawia się taki komunikat po uruchomieniu

--- Kod: ---
fdisk -l /dev/sda
The backup GPT table is corrupt, but the primary appears OK, so that will be used.

--- Koniec kodu ---
Po czym następuje poprawne wyświetlenie zawartości tablicy partycji.
Skopiowałem drugi sektor dysku programem “dd” i sprawdziłem, co znajduje się w 8 bajtach pod adresem 0x20 czyli “Backup LBA”, zgodnie z Wikipedią. I jest tam adres 0x74706daf, który wskazuje prawdopodobnie na ostatni sektor dysku albo nawet poza dysk.

Czy jest jakieś narzędzie, które pozwala zmienić lokalizację zapasowej tablicy GPT, tak by była w nie uszkodzonym sektorze (lub w granicach dysku) bez konieczności ponownej instalacji systemu?

Paweł Kraszewski:
Robisz odwrotnie do tego, co napisałem Zielonemu:

Instrukcja jest tutaj i tutaj.

W skrócie:

1. gdisk /dev/nvme0n1
2. Powinno pojawić się, że główna tablica (main) jest "OK" a zapasowa tablica (backup) ma "ERROR"
3. Dajesz polecenie r (recovery)
4. Wybierasz opcję d (use main GPT header) (tu jest różnica względem problemu Zielonego - ty masz dobry main, on miał dobry backup)
5. Poleceniem p wyświetlasz odzyskaną tablicę.
6. Jak wszystko jest ok, poleceniem w zapisujesz odzyskaną tablicę na dysk.

overcq:
Problem był w tym, że zapasowa tablica partycji nie mogła być zapisana na dysk z powodu błędu zapisu sektora.

Rozwiązałem to ręcznie: przesunąłem (skopiowałem z podstawowej) zapasową tablicę partycji wstecz o kilkadziesiąt sektorów w obszarze nie używanym przez ostatnią partycję na dysku (jest taki obszar ok. 700 kB), zmodyfikowałem ‘header’ zapasowej tablicy partycji, w którym ustawiłem nową lokalizację tablicy partycji i sumę kontrolną ‘headera’.

Wykorzystałem następujący skrypt, gdzie “binary-read” i “binary-write” to programy pakietu binary-change:

--- Kod: shell ---
#!/bin/bash
#*******************************************************************************
trap 'rm "$header" "$header_crc32" "$table"' EXIT
header="$( mktemp )"
header_crc32="$( mktemp )"
table="$( mktemp )"
#===============================================================================
dd if=/dev/sda of="$header" bs=512 skip=1 count=1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
header_sector=$( binary-read -f "$header" -p 0x20 -l -s 8 )
table_sector=$(( $header_sector - 32 - 32 ))
partition_last_sector=$( fdisk -l /dev/sda | tail -n 2 | head -n 1 | sed -e 's`^[^ ][^ ]*  *[0-9][0-9]*  *\([0-9][0-9]*\).*$`\1`' )
if [ $header_sector -le $partition_last_sector -o $table_sector -le $partition_last_sector ]; then
    echo 'Header or table sector too low'
    exit 1
fi
binary-write -f "$header" -p 0x10 -l -s 4 -d 0 -p 0x30 -l -s 8 -d $(( $table_sector - 1 ))
dd if="$header" of="$header_crc32" bs=92 count=1
crc32=$( crc32 "$header_crc32" )
binary-write -f "$header" -p 0x10 -l -s 4 -d 0x$crc32
dd if="$header" of=/dev/sda bs=512 seek=1
#~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
dd if=/dev/sda of="$table" bs=512 skip=2 count=32
binary-write -f "$header" -p 0x10 -l -s 4 -d 0 -p 0x18 -l -s 8 -d $header_sector -p 0x20 -l -s 8 -d 1 -p 0x48 -l -s 8 -d $table_sector
dd if="$header" of="$header_crc32" bs=92 count=1
crc32=$( crc32 "$header_crc32" )
binary-write -f "$header" -p 0x10 -l -s 4 -d 0x$crc32
dd if="$header" of=/dev/sda bs=512 seek=$header_sector
dd if="$table" of=/dev/sda bs=512 seek=$table_sector
gdisk -l /dev/sda
#*******************************************************************************

--- Koniec kodu ---

Nawigacja

[0] Indeks wiadomości

Idź do wersji pełnej