이러한 오류는 실제로 무엇을 의미하며 오류의 원인은 무엇입니까?

이러한 오류는 실제로 무엇을 의미하며 오류의 원인은 무엇입니까?

지난 번 오류로부터 약 2년 후에 이 오류가 실행되는 것은 이번이 두 번째이며 badblocks하드웨어(케이블 등)에서 소프트웨어(운영 체제 자체 설치)에 이르기까지 대부분의 요소가 변경되었습니다. 관련 공통 요소는 Cygwin프로그램 badblocks자체뿐이므로 문제가 둘 사이에 있을 가능성이 매우 높습니다.


badblocks파괴 모드(예: 스위치 사용)에서 실행할 때 -w오류가 발생합니다.

do_writerrors의 이상한 값(4294967295)

...드라이브에 패턴을 쓰는 각 단계에서.

내가 알 수 있는 한, 다음에서 보고한 지정된 마지막 블록을 사용하여 명령을 실행할 때만 이 오류가 발생하는 것 같습니다 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를 통해 찾을 수 없습니다.

여기에 이미지 설명을 입력하세요

이 시점에서 드라이브는 여러 번 0으로 설정되었고 마지막 몇 블록에 수십 번 썼습니다. 따라서 SMART 값이 블록에 불량 섹터 가 있는 경우 badblocks불량 섹터를 선택할 수 있는 기회가 많았습니다 .1953525168

이러한 오류는 실제로 무엇을 의미하며 오류의 원인은 무엇입니까?

답변1

4294967295harrymc가 내 답변의 핵심( 예 -1: ) 을 제공했을 수도 있지만 왜 단순히 "인식"하지 않는지 (예: Windows에서 Cygwin 빌드에서 "이상한 값" 오류가 발생하는 이유)에 대해서는 unsigned int더 이상 설명하지 않았습니다. ).badblocks-1

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). (기록을 위해 값을 _ssize_t(즉 ) 로 "확장"하기 때문에 필요합니다 ret. (an_unsigned_int == -1)AFAIK와 같은 비교는 잘 작동할 수 있습니다.)

이것은 단지 내 추측일 뿐이라고 말해야 하지만 Cygwin 사용에 대해 잘 모르기 때문에 _write()(예: 이것이 다음과 관련이 있는지 여부)이것, 그렇다면 문서가 그저 쓰레기인지 여부). 그러나 나는 그것이 타당한 사례라고 생각한다.버그 보고서, 이를 통해 자세한 내용을 알아볼 수 있습니다.

업데이트:이것"회귀"를 도입하는 커밋일 수 있습니다(보시다시피 기본적으로 커밋 메시지에 따른 것입니다 _ssize_t) . 이는 Cygwin이 64비트일 때 끝날 가능성이 높습니다.__SIZE_TYPE__size_tunsigned long이것그리고이것), 따라서 32비트 Cygwin에서는(64비트 Windows에서도) 문제를 재현할 수 없을 것이라고 장담합니다. 그건 언급할 가치가 있겠네요훨씬 더 이른 커밋아마도 한 번 "고정"했을 것입니다. 그래서 나는 그것을 '회귀'라고 부른다.

업데이트 2: 그리고 네, 제 말이 맞습니다: 여기에 이미지 설명을 입력하세요 이제 Visual Studio를 가져와서 잠시 확인해야 할 것 _write()같습니다 .write()

PS "마지막 블록 + 1"에서 읽기 전용 테스트를 _read()return 으로 수행하는 경우 " 0이상한 값" 오류 가 발생 하면 안 됩니다 _write().-1errnoENOSPC파일 끝에서 읽으려고 합니다." (운전).

답변2

10진수 값 4294967295(hex) 은 FFFFFFFF단순히 -1부호 없는 32비트 정수로 표시됩니다. 이는 일반적인 API 오류 코드이며 다른 의미는 없습니다. 이 유틸리티는 badblocks매우 기본적이며 수십 년 전에 Linus Torvalds가 작성했으며 데이터를 기록하고 다시 읽는 작업만 수행합니다.

수정할 수 없는 섹터 수 디스크 펌웨어가 감지했지만 해당 섹터를 읽을 수 없어 양호한 섹터로 재배치할 수 없는 불량 섹터 수를 나타냅니다. 펌웨어는 이러한 섹터를 재배치하려는 시도를 포기했습니다.

따라서 펌웨어가 감지했지만 다시 매핑할 수 없는 459개의 검색 불가능한 섹터가 있습니다.

디스크는 의심할 여지없이 최종 단계에 있습니다.

디스크를 복구하고 내용에 관심이 없다면 딥 포맷을 시도하여 모든 양호한 섹터를 다시 쓰고 갱신하는 동시에 펌웨어가 건드릴 수 없는 섹터를 불량으로 표시할 수 있습니다. 여기서는 제조업체의 유틸리티를 사용하는 것이 좋습니다. Cygwin은 Linux 유틸리티가 Windows 통합을 보장하지 않으므로 피해야 합니다.

그만큼 DiamondMax 지원 페이지 아주 최근의 디스크 유틸리티를 제안합니다 디스크 마법사 버전: 23.0.17160, 아마도 딥 포맷을 수행할 수 있을 것입니다. 이것은 Windows 유틸리티입니다.

문제의 디스크가 Windows 시스템 디스크인 경우 Windows PE 부팅 디스크 또는 다음과 같은 복구 디스크에서 유틸리티를 실행해야 할 수도 있습니다. Bob.Omb의 수정된 Win10PEx64. 당신은 또한 부팅 가능한 Windows PE 기반 복구 디스크 ~와 같은 Hiren의 BootCD PE. 긴급 상황에서는 Linux Live 부팅에서 디스크 포맷을 시도할 수 있습니다.


(다시 작성한 게시물에 대한 추가)

위의 답변은 글이 작성되고 디스크가 교체되기 2년 전에 포스터에서 승인된 것으로 보입니다. 새로운 디스크에 관한 부분입니다.

새 디스크는 완벽한 모양이고 결함이 없지만 badblocks는 하나의 오류 메시지를 표시합니다.

Badblocks는 아마도 Linux가 존재하기 전에 Linus Torvalds가 작성한 고대 유틸리티입니다. 이것이 하는 일은 임시 파일을 생성하고 공간 끝에 도달할 때까지 파일에 쓴 다음 데이터를 다시 읽는 것뿐입니다. 디스크 테스트로서는 매우 형편없으며 디스크의 여유 공간만 "테스트"합니다.

또한 Windows가 아닌 Cygwin에서 실행되고 있으므로 Windows에서 반환된 오류 코드에 대한 이해가 매우 의심스럽습니다. 실제 오류 코드를 보고할 수도 없고 대신 항상 -1 오류 코드로 보고합니다. Cygwin이 Windows API 오류 코드를 동등한 Linux 오류 코드라고 생각하는 것으로 변환하려고 시도한 결과가 어떻게 될지 상상할 방법이 없습니다.

솔직히 말해서, 나는 이 가짜 오류를 의미 없는 것으로 무시할 것입니다. 아마도 "더 이상 공백 없음" 반환 코드에 대한 오해, 즉 badblocks나 Cygwin에 의해 오해된 것일 수도 있습니다. SMART 펌웨어에서 반환된 데이터는 훨씬 더 중요합니다.

게시물에서 Windows 또는 DOS의 불량 블록과 동일 몇 가지 제안이 제안되었는데, 모두 배드 블록보다 훨씬 낫습니다. 여유 공간뿐만 아니라 전체 디스크를 테스트하기 때문입니다.

한 가지 좋은 대안은 chkdsk /rWindows 유틸리티를 사용하는 것입니다. chkdsk 전체 디스크의 물리적 디스크 오류를 분석하여 불량 섹터를 찾아 읽을 수 있는 정보를 복구합니다.

관련 정보