Это уже второй раз, когда я получаю эту ошибку при запуске badblocks
, с разницей примерно в 2 года с последнего раза, и подавляющее большинство факторов, от оборудования (кабели и т. д.) до программного обеспечения (установка самой операционной системы), с тех пор изменились, и единственными общими факторами являются Cygwin
и badblocks
сама программа, что делает весьма вероятным, что проблема заключается в них.
При запуске badblocks
в деструктивном режиме (т.е. с переключателем -w
) я получаю ошибку:
Странное значение (4294967295) в do_writerrors
...на каждом этапе записи шаблонов на диск.
Насколько я могу судить, эта ошибка возникает только при запуске команды с указанным последним блоком, о котором сообщается fdisk -l
:
$ fdisk -l /dev/sda
Disk /dev/sda: 931.5 GiB, 1000204886016 bytes, 1953525168 sectors
Units: sectors of 1 * 512 = 512 bytes
Sector size (logical/physical): 512 bytes / 512 bytes
I/O size (minimum/optimal): 512 bytes / 512 bytes
$ badblocks -b 512 -vws /dev/sda 1953525168 1953525168
Checking for bad blocks in read-write mode
From block 1953525168 to 1953525168
Testing with pattern 0xaa: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: 1953525168ne, 0:00 elapsed. (0/0/0 errors)
done
Testing with pattern 0x55: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: done
Testing with pattern 0xff: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: done
Testing with pattern 0x00: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: done
Pass completed, 1 bad blocks found. (1/0/0 errors)
$ badblocks -b 512 -vws /dev/sda 1953525168 1950000000
Checking for bad blocks in read-write mode
From block 1950000000 to 1953525168
Testing with pattern 0xaa: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: 1953525168ne, 0:49 elapsed. (0/0/0 errors)
done
Testing with pattern 0x55: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: done
Testing with pattern 0xff: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: done
Testing with pattern 0x00: Weird value (4294967295) in do_writerrors)
done
Reading and comparing: done
Pass completed, 1 bad blocks found. (1/0/0 errors)
Как можно заметить, это также приводит к ложному срабатыванию плохого блока, тогда как этот предполагаемый плохой блок нигде не обнаруживается с помощью CrystalDiskInfo:
На этом этапе диск был обнулён несколько раз, а badblocks
его последние блоки были записаны десятки раз, поэтому у значений SMART было достаточно возможностей обнаружить плохой сектор в блоке, 1953525168
если таковой имелся.
Что на самом деле означают эти ошибки и что может быть их причиной?
решение1
Хотя harrymc, возможно, дал вам основу моего ответа (то есть 4294967295
как -1
) unsigned int
, он не объяснил далее, почему badblocks
просто не «распознает» его как -1
(т. е. почему возникает ошибка «странного значения» при сборке Cygwin на Windows).
Я взглянул на код badblocks
Cygwin:
https://github.com/tytso/e2fsprogs/blob/v1.45.4/misc/badblocks.c#L463
И у меня получилось вот что:
[tom@archlinux ~]$ cat test.c
#include <stdio.h>
unsigned int eh() {
return -1;
}
int main() {
long got;
got = eh();
printf("%ld\n", got);
got = (long) eh();
printf("%ld\n", got);
got = (int) eh();
printf("%ld\n", got);
}
[tom@archlinux ~]$ cc test.c
[tom@archlinux ~]$ ./a.out
4294967295
4294967295
-1
[tom@archlinux ~]$
По сути, это означает, что если вы хотите интерпретировать беззнаковую переменную (которая может быть намеренно использована для хранения знакового значения) как знаковую, вы должны интерпретировать ее с ее собственным размером, а не с размером другой переменной, в которую вы собираетесь поместить ее значение.
Я не очень хорошо разбираюсь в программировании, но, как вы видите, (_ssize_t)
приведение типа, reent/writer.c
вероятно, неверно. Если мы предполагаем, _write()
что имеет int
тип (или любой знаковый тип), такое приведение типа избыточно. Если мы предполагаем, _write()
что имеет unsigned int
тип, то необходимое ему приведение типа должно быть (int)
. (Для справки, оно необходимо только потому, что мы «расширяем» его значение до a _ssize_t
(т.е. ret
). Сравнение типа (an_unsigned_int == -1)
могло бы работать просто отлично, AFAIK.)
Хотя должен сказать, что это всего лишь мои догадки, так как я на самом деле не знаю об _write()
использовании Cygwin (например, имеет ли это какое-либо отношение кэтот, и если да, то является ли документация просто дерьмом). Но я думаю, что это весомый случай дляотчет об ошибке, что может помочь вам узнать больше.
Обновлять:Этотможет быть коммит, который вводит «регрессию» (как вы можете видеть, _ssize_t
будет основан на __SIZE_TYPE__
(что по сути size_t
соответствует сообщению коммита). Скорее всего, это произойдет, unsigned long
когда Cygwin станет 64-битным, на основеэтотиэтот), поэтому я готов поспорить, что вы не сможете воспроизвести проблему с 32-битным Cygwin (даже на 64-битной Windows, конечно). Возможно, стоит упомянуть, чтоеще более раннее совершениенаверное, когда-то "исправили". Вот почему я называю это "регрессом".
Обновление 2: и да, я прав:
Возможно, теперь мне стоит скачать Visual Studio и немного проверить _write()
(а может быть и )...write()
P.S. Вы не должны сталкиваться с ошибкой "странное значение", если вы выполняете тест только для чтения на "последнем блоке + 1", поскольку он _read()
вернет 0
, в отличие от _write()
того, который вернет -1
и установится errno
в ENOSPC
, когда он "пытается прочитать конец файла" (привод).
решение2
Десятичное значение 4294967295
в шестнадцатеричном формате FFFFFFFF
просто -1
отображается как беззнаковое 32-битное целое число. Это распространенный код ошибки API, и он не имеет другого значения. Утилита badblocks
очень простая, написанная несколько десятилетий назад Линусом Торвальдсом, которая только записывает данные и считывает их обратно.
Количество неисправимых секторов обозначает количество плохих секторов, которые микропрограмма диска обнаружила, но не смогла переместить в хорошие сектора, поскольку эти сектора не могли быть прочитаны. Микропрограмма отказалась от попыток переместить эти сектора.
Итак, имеется 459 непокрытых секторов, которые прошивка обнаружила, но не может переназначить.
Диск, несомненно, находится в терминальной фазе.
Если вы хотите спасти диск и вас не волнует его содержимое, вы можете попробовать выполнить его глубокое форматирование, чтобы перезаписать и обновить все хорошие сектора, при этом отметив как плохие те сектора, которые прошивка не может затронуть. Здесь предпочтительнее утилита от производителя. Cygwin следует избегать, так как его утилиты Linux не гарантируют хорошую интеграцию с Windows.
The Страница поддержки DiamondMax предлагает довольно недавнюю утилиту для работы с дисками Версия DiscWizard: 23.0.17160, который, возможно, сможет сделать глубокое форматирование. Это утилита Windows.
Если рассматриваемый диск является системным диском Windows, вам может потребоваться запустить утилиту с загрузочного диска Windows PE или с такого аварийного диска, как Модифицированный Bob.Omb Win10PEx64. Вы также можете использовать Загрузочный диск восстановления на основе Windows PE такой как Hiren's BootCD PE. В крайнем случае вы можете попробовать отформатировать диск из загрузки Linux Live.
(Дополнение к переписанному посту)
Вышеуказанный ответ, по-видимому, был принят автором за два года до того, как он был написан, и диск был заменен. Эта часть о новом диске.
Новый диск в идеальном состоянии и не имеет дефектов, однако badblocks выдает одно сообщение об ошибке.
Badblocks — древняя утилита, написанная Линусом Торвальдсом, возможно, даже до появления Linux. Все, что она делает, — создает временный файл, записывает в него данные до тех пор, пока не будет достигнут конец пространства, а затем перечитывает данные. Как тест диска она ужасна и только «тестирует» свободное место на диске.
Кроме того, он работает на Cygwin, а не даже на Windows, поэтому его понимание возвращаемых Windows кодов ошибок крайне сомнительно. Он даже не может сообщить реальный код ошибки, вместо этого всегда сообщая -1
код ошибки. Невозможно представить, что будет, если Cygwin попытается перевести код ошибки API Windows в то, что он считает эквивалентным кодом ошибки Linux.
Честно говоря, я бы проигнорировал эту единственную ложную ошибку как бессмысленную, вероятно, просто происходящую от непонимания кода возврата "no-more-space", неправильно понятого либо badblocks, либо Cygwin. Данные, возвращаемые прошивкой SMART, гораздо более уместны.
В посте Эквивалент плохих блоков в Windows или DOS Было предложено несколько вариантов, и все они намного лучше, чем badblocks, поскольку они проверяют весь диск, а не только свободное пространство.
Хорошей альтернативой является chkdsk /r
, которая использует утилиту Windows
chkdsk
для обнаружения поврежденных секторов и восстановления читаемой информации, анализируя физические ошибки диска на всем диске.