Что на самом деле означают эти ошибки и что может быть их причиной?

Что на самом деле означают эти ошибки и что может быть их причиной?

Это уже второй раз, когда я получаю эту ошибку при запуске 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).

Я взглянул на код badblocksCygwin:

https://github.com/tytso/e2fsprogs/blob/v1.45.4/misc/badblocks.c#L463

https://github.com/cygwin/cygwin/tree/01c253a4c58b6c1da01615431bdc4c88fcba48ea/newlib/libc/syscalls/syswrite.c

https://github.com/cygwin/cygwin/tree/01c253a4c58b6c1da01615431bdc4c88fcba48ea/newlib/libc/reent/writer.c

И у меня получилось вот что:

[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 для обнаружения поврежденных секторов и восстановления читаемой информации, анализируя физические ошибки диска на всем диске.

Связанный контент