O que esses erros realmente significam e o que pode estar causando-os?

O que esses erros realmente significam e o que pode estar causando-os?

Esta é a segunda vez que recebo este erro ao executar o badblocks, aproximadamente 2 anos depois da última vez, e a grande maioria dos fatores, desde hardware (cabos, etc.) até software (a instalação do próprio sistema operacional) foram alterados visto que, sendo os únicos fatores comuns relevantes Cygwino badblockspróprio programa, é altamente provável que o problema esteja entre eles.


Ao executar badblocksno modo destrutivo (ou seja, com o -wswitch), recebo o erro:

Valor estranho (4294967295) em do_writerrors

...em cada estágio de gravação dos padrões na unidade.

Pelo que sei, parece que recebo esse erro apenas ao executar o comando com o último bloco especificado relatado por 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)

Como pode ser visto, isso também resulta em um falso positivo de um bloco defeituoso, enquanto esse suposto bloco defeituoso não pode ser encontrado em lugar nenhum via CrystalDiskInfo:

insira a descrição da imagem aqui

Neste ponto, a unidade foi zerada várias vezes e gravou badblocksem seus últimos blocos dezenas de vezes, portanto, houve muitas oportunidades para os valores SMART terem detectado um setor defeituoso no bloco, 1953525168se existisse.

O que esses erros realmente significam e o que pode estar causando-os?

Responder1

Embora harrymc possa ter lhe dado o núcleo da minha resposta (isto 4294967295é, -1como unsigned int), ele não explicou melhor por que badblockssimplesmente não "reconhece" isso como -1(ou seja, por que o erro de "valor estranho" com uma versão Cygwin dele no Windows ).

Dei uma olhada no código do 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

E eu descobri isso:

[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 ~]$ 

Basicamente, isso quer dizer que, se você deseja interpretar uma variável não assinada (que pode ser usada intencionalmente para armazenar um valor assinado) como uma variável assinada, você deve interpretar com seu próprio tamanho, mas não com o tamanho de outra variável que você irá coloque seu valor em.

Não estou exatamente familiarizado com programação, mas como você pode ver, a (_ssize_t)conversão do tipo reent/writer.cprovavelmente está errada. Se assumirmos _write()que é do inttipo (ou qualquer tipo assinado), essa conversão de tipo é redundante. Se assumirmos _write()que é do unsigned inttipo, então a conversão de tipo necessária deve ser (int). (Para constar, ele é necessário apenas porque estamos "expandindo" seu valor para a _ssize_t(ou seja ret). Uma comparação como essa (an_unsigned_int == -1)pode funcionar muito bem, AFAIK.)

Embora eu deva dizer que isso é apenas meu palpite, já que eu realmente não sei sobre os _write()usos do Cygwin (como se isso tem alguma coisa a ver comesse, e em caso afirmativo, se a documentação é simplesmente uma porcaria). Mas penso que é um caso válido para umarelatório de erro, o que pode fazer com que você descubra mais.

Atualizar:Essepoderia ser o commit que introduz a "regressão" (como você pode ver, _ssize_tseria baseado em __SIZE_TYPE__(que está essencialmente size_tde acordo com a mensagem do commit). Provavelmente acabaria sendo unsigned longquando o Cygwin fosse de 64 bits, baseado emesseeesse), então aposto que você não conseguirá reproduzir o problema com o Cygwin de 32 bits (ou seja, mesmo no Windows de 64 bits). Talvez valha a pena mencionar queum commit ainda anteriorprovavelmente uma vez "consertado". É por isso que chamo isso de "regressão".

Atualização 2: e sim, estou certo: insira a descrição da imagem aqui Talvez agora eu deva adquirir o Visual Studio e verificar _write()(e talvez write()) um pouco...

PS Você não deve se deparar com o erro "valor estranho" se estiver fazendo um teste somente leitura no "último bloco + 1" como _read()retornaria 0, ao contrário do _write()que retornaria -1e seria definido errnocomo ENOSPC, quando "tenta ler no final do arquivo" (a unidade).

Responder2

O valor decimal 4294967295, em hexadecimal FFFFFFFF, é simplesmente -1representado como um número inteiro não assinado de 32 bits. Este é um código de erro de API comum e não tem outro significado. O utilitário badblocksé muito básico, escrito há décadas por Linus Torvalds, que apenas grava dados e os lê de volta.

Contagem de setor incorrigível denota o número de setores defeituosos que o firmware do disco detectou, mas não conseguiu realocar para setores bons porque esses setores não puderam ser lidos. O firmware desistiu de tentar realocar esses setores.

Portanto, existem 459 setores detectáveis ​​que o firmware detectou, mas não é capaz de remapear.

O disco está, sem dúvida, em fase terminal.

Se você deseja salvar o disco e não se importa com seu conteúdo, você pode tentar formatá-lo profundamente, para reescrever e renovar todos os setores bons, enquanto marca como ruins os setores que o firmware não pode tocar. Um utilitário do fabricante é preferível aqui. O Cygwin deve ser evitado, pois seus utilitários Linux não garantem uma boa integração com o Windows.

O Página de suporte DiamondMax sugere o utilitário de disco bastante recente Versão do DiscWizard: 23.0.17160, que talvez pudesse fazer o formato profundo. Este é um utilitário do Windows.

Se o disco em questão for o disco do sistema Windows, talvez seja necessário executar o utilitário a partir de um disco de inicialização do Windows PE ou de um disco de recuperação como Win10PEx64 modificado de Bob.Omb. Você também pode usar um Disco de recuperação inicializável baseado no Windows PE como BootCD PE de Hiren. Em caso de emergência, você pode tentar formatar o disco a partir de uma inicialização do Linux Live.


(Adição para a postagem reescrita)

A resposta acima foi aparentemente aceita pelo autor da postagem dois anos antes de ser escrita e o disco ser substituído. Esta parte é sobre o novo disco.

O novo disco está em perfeito estado e sem nenhum defeito, mas os badblocks apresentam uma mensagem de erro.

Badblocks é um utilitário antigo, escrito por Linus Torvalds, talvez antes mesmo de o Linux existir. Tudo o que ele faz é criar um arquivo temporário, gravar nele até que o fim do espaço seja encontrado e depois reler os dados. Como teste de disco, é péssimo e apenas "testa" o espaço livre no disco.

Além disso, ele está sendo executado no Cygwin e nem mesmo no Windows, portanto, sua compreensão dos códigos de erro retornados pelo Windows é extremamente duvidosa. Ele nem consegue relatar o código de erro real, em vez disso sempre relata um -1 código de erro. Não há como imaginar qual seria o resultado da tentativa do Cygwin de traduzir um código de erro da API do Windows para o que ele imagina ser o código de erro equivalente do Linux.

Francamente, eu ignoraria esse erro espúrio como sem sentido, provavelmente apenas vindo do mal-entendido do código de retorno "sem mais espaço", mal compreendido pelos badblocks ou pelo Cygwin. Os dados retornados pelo firmware SMART são muito mais objetivos.

Na postagem Equivalente a badblocks no Windows ou DOS diversas sugestões foram oferecidas, todas muito melhores que badblocks, pois testam todo o disco e não apenas o espaço livre.

Uma boa alternativa é chkdsk /r, que usa o utilitário Windows chkdsk para localizar setores defeituosos e recuperar informações legíveis, analisando erros de disco físico em todo o disco.

informação relacionada