I / O 오류를 일으키는 특수 파일


13

필수 SQLite DB 파일을 읽지 못하면 (I / O 오류로 인해) 소프트웨어가 예상대로 반응하는지 자동으로 테스트하고 싶습니다. 정확히 며칠 전에 클라이언트에서 일어났습니다. 수동으로 수정했지만 이제는 자동 코드를 작성하여 수정하고 손상된 파일에 액세스하여 테스트해야합니다.

유닉스의 모든 것이 파일이기 때문에, 나는 파일을 읽으려고 할 때 항상 (/ dev와 같은) I / O 오류를 일으키는 특수 파일이있을 수 있다고 생각했습니다.

유사한 파일 (imo)은 다음과 같습니다.

  • /dev/full 작성하려고하면 항상 "장치에 남은 공간이 없습니다"라고 표시됩니다.
  • /dev/null/dev/zero

그래서 나는 그런 파일이 있어야한다고 가정했지만 아직 찾지 못했습니다.

누구든지 원하는 결과 (의도적으로 결함이있는 파티션 이미지, LD_PRELOAD를 사용하여 open () 주위 래퍼)를 얻을 수있는 그러한 파일이나 다른 방법을 알고 있습니까?
가장 좋은 방법은 무엇입니까?


내가 아는 한 Linux에는 읽을 때 SIGIO를 제공하는 특수 파일이 없습니다. 마지막으로 SIGIO를 받았을 때는 USB 스틱이 실제 물리적 용량보다 훨씬 큰 용량을 선언했기 때문입니다. 아마도 그럴 가능성이 있습니까?
lgeorget

흠, 나는 중간에 어딘가에서
잘릴

SIGIO는 오류가 없다는 것을 의미하지는 않습니다. 프로그램에서 select () 또는 poll ()을 호출하는 대신 비 차단 IO가 가능하다는 알림을 요청할 수 있습니다.
psusi

물론이지, 네 말이 맞아 SIGIO를 작성했지만 EIO ​​오류 코드를 생각하고있었습니다. 그러나 아마도 OP도? 읽는 데 실패하면 왜 SIGIO가됩니까?
lgeorget

오, 나는 질문에서 같은 실수를했다 ... 그것을 편집 ...
mreithub

답변:


8

또는 대상을 사용하여 오류를 시뮬레이션 dmsetup하는 장치 매퍼 장치를 만드는 데 사용할 수 있습니다 .errorflakey

dmsetup create test --table '0 123 flakey 1 0 /dev/loop0'

여기서 123은 장치의 길이이며 섹터 단위이며 / dev / loop0은 오류를 시뮬레이트하려는 원래 장치입니다. 오류의 경우 항상 오류를 반환하므로 후속 인수가 필요하지 않습니다.


1
해당 명령에서 두 가지 이상의 오류가 발견되었습니다. 누락 된 장치 이름, 인용 오타 및 "1 0 / dev / null"은 무엇을 의미합니까?
Hauke ​​Laging 2013 년

@ HaukeLaging, 아, 그래, 나는 이름을 생략하고 어떻게 든 틀린 인용을 쳤다. 1 0 / dev / null은 장치 / dev / null이 지원하는 오프셋 0에서 시작하여 하나의 대상을 의미합니다. flakey에는 필요하지만 분명히 error에 대해서는 선택적입니다.
psusi

그것은 "선택적"이 아니라 단순히 무시되는 것 같습니다. 로 확인할 수 있습니다 dmsetup table test. 당신은 foo bar뒤에 쓸 수도 있습니다 error; 신경 쓰지 않으므로 삭제해야합니다.
Hauke ​​Laging 2013 년

@HaukeLaging, 편집했습니다.
psusi

답변 주셔서 감사합니다, 나는 지금 갈 방법입니다 생각합니다. 내가 가진 유일한 사소한 문제는 루트 액세스가 필요하다는 것입니다. 그러나 어쨌든 또는 저수준의 것들이 필요하다고 생각합니다 ... (시간이 있으면 LD_PRELOAD 아이디어를 파헤 치겠습니다).
mreithub

14

Stack Overflow 및 Server Fault에 대해서는 이미 많은 답변이 있지만 일부 기술이 누락되었습니다. 보다 쉽게 ​​사용할 수 있도록 VM / Linux 블록 장치 / Linux 파일 시스템 / Linux 사용자 공간 라이브러리 I / O 결함 주입 메커니즘 목록이 있습니다.

보너스 사실 : SQLite에는 오류를 시뮬레이션하기위한 VFS 드라이버가 있으므로 테스트 범위를 넓힐 수 있습니다.

관련 :


5

당신은 원하는 오류 분사 I / O에 대한 메커니즘을.

Linux의 경우 사전 설정이 필요하지 않고 비정상적인 오류 (EIO "입력 / 출력 오류"가 아니라 ESRCH "이러한 프로세스 없음")를 생성하는 방법이 있습니다.

cat /proc/1234/mem

여기서 1234는 테스트중인 프로세스와 동일한 사용자로 실행되는 프로세스의 PID이지만 해당 프로세스 자체는 아닙니다. 크레딧하는 rubasov 에 대한 생각/proc/$pid/mem.

프로세스 자체의 PID를 사용하는 경우 EIO를 얻을 수 있지만 프로세스 메모리에 매핑되지 않은 영역에서 읽는 경우에만 가능합니다. 첫 번째 페이지는 매핑되지 않으므로 파일을 순차적으로 읽지 만 파일 중간을 직접 찾는 데이터베이스 프로세스에는 적합하지 않습니다.

루트로 더 설정 하면 장치 매퍼활용하여 유효한 섹터와 불량 섹터가있는 파일을 만들 수 있습니다.

또 다른 방법은 작은 FUSE 파일 시스템 을 구현하는 것 입니다. EIO는 사용자 공간 파일 시스템 드라이버가 잘못했을 때의 기본 오류 코드이므로 달성하기 쉽습니다. 모두 파이썬 바인딩 예제 시작하기로 빠르게 주로 거울 엄선 된 장소에있는 파일 만 주입하는 EIO 기존의 파일 시스템을 작성할 수 있습니다 온다. petardfs ( article ) 와 같은 기존 파일 시스템 이 있습니다. 상자에서 얼마나 잘 작동하는지 모르겠습니다.

또 다른 방법은 LD_PRELOAD래퍼입니다. 기존의 것은 Libfiu (사용자 공간의 결함 주입)입니다. POSIX API 호출을 오버로드하는 라이브러리를 미리로드하여 작동합니다. 간단한 지시어 나 임의의 C 코드를 작성하여 정상적인 동작을 무시할 수 있습니다.


Libfiu는 정말로 유망한 것으로 보입니다 (그리고 그것은 데비안 저장소에 있습니다). 큰 답변, 감사합니다, +1
mreithub

1

장치 파일을 "I / O 오류가있는 파일"로 사용하면 문제가 훨씬 더 쉽습니다. 내 제안은 일반 파일에 이러한 오류가있는 경우입니다.

> dd if=/dev/zero of=/path/to/ext2.img bs=10M count=10
> losetup /dev/loop0 /path/to/ext2.img
> blockdev --getsz /dev/loop0
204800
> echo "0 204800 linear /dev/loop0 0" | dmsetup create sane_dev
> mke2fs /dev/mapper/sane_dev # ext2 reicht
> mount -t ext2 /dev/mapper/sane_dev /some/where
> dd if=/dev/zero of=/some/where/unreadable_file bs=512 count=4
> hdparm --fibmap /some/where/unreadable_file
/mnt/tmp/unreadable_file:
 filesystem blocksize 1024, begins at LBA 0; assuming 512 byte sectors.
 byte_offset  begin_LBA    end_LBA    sectors
           0       2050       2053          4
> umount /dev/mapper/sane_dev
> dmsetup remove sane_dev
> start_sector=$((204800-2053-1))
> echo $'0 2053 linear /dev/loop0 0\n2053 1 error\n2054 '"${start_sector} linear /dev/loop0 2054" | 
>   dmsetup create error_dev
> mount -t ext2 /dev/mapper/error_dev /some/where
> cat /some/where/unreadable_file # 3rd sector of file is unreadable
cat: /some/where/unreadable_file: Input/output error

오류없이 ( dd .. seek=...) 파일에서 단일 섹터를 읽을 수 없기 때문에 약간 혼란 스럽다는 것을 인정해야합니다 . 아마도 미리 읽기 문제 일 수 있습니다.


파일 시스템의 블록 크기는 4096 바이트 이상이므로 파일이 작더라도 여러 섹터에 걸쳐 있습니다.
Anon

1

이런 종류의 목적을 위해 만들어진 CharybdeFS를 사용할 수 있습니다.

PetardFS와 같은 패스 스루 퓨즈 파일 시스템이지만 훨씬 더 구성 가능합니다.

CharybdeFS 쿡북을 참조하십시오 : http://www.scylladb.com/2016/05/02/fault-injection-filesystem-cookbook/

데이터베이스를 테스트하기에 충분히 발전했습니다.


당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.