을 사용하여 파일의 inode를 찾았습니다 ls -li
. 그런 다음 디스크에서 파일의 시작 블록을 찾았습니다. 나는 이 명령을 사용하여 블록의 내용을 다른 디렉토리에 복사합니다 dd
. 그런 다음 유틸리티 를 사용하여 파일을 파쇄했습니다 shred
. 같은 명령을 다시 실행합니다 shred -uvz -n=10 file1.txt
. dd
파일이 복원되었습니다. 파일이 파쇄된 후에는 00000을 얻어야 합니다. 내가 무엇을 놓치고 있나요?
두 번째 반복에서는 shred -vz -n=10 file2.txt
파일을 삭제하지 않는 대신 실행합니다. 이전과 동일한 단계를 거쳐 다시 dd
명령 및 블록 위치를 사용하여 원본 파일을 복원 할 수 있었습니다 . 그러나 파쇄된 파일의 내용은 와 같이 00000 입니다 hexdump file2.txt
. 내가 무엇을 놓치고 있나요?
답변1
파일 시스템은 해당 블록 장치에 독점적으로 액세스할 수 있어야 합니다. dd
파일 시스템을 마운트할 때 블록 장치에서 직접 작업하면 안 됩니다.
dd
(또는 다른 사용자 공간 프로그램)을 사용하여 블록 장치에서 직접 바이트를 읽으면 읽기가 캐시됩니다. 다시 반복하면 dd
캐시에서 데이터를 읽습니다.
불행하게도 (파일 시스템을 통해) 데이터 쓰기는 이 캐시를 업데이트하지 않습니다. 따라서 캐시의 데이터가 디스크의 데이터를 반영하지 않는 상황이 발생할 수 있습니다.
이런 일이 일어나는 또 다른 예는 TRIM입니다. 블록 장치 데이터가 캐시된 경우 TRIM이 해당 데이터를 제거한 경우에도 캐시에서 데이터를 계속 가져올 수 있습니다. 그렇기 때문에TRIM 테스트 시 캐시를 삭제해야 합니다..
일부 파일로 파일 시스템을 만듭니다.
# truncate -s 10G filesystem.img
# mkfs.ext4 filesystem.img
# losetup --find --show filesystem.img
/dev/loop1
# mount /dev/loop1 loop/
# for n in {000..100} ; do yes $n | dd bs=1M count=1 iflag=fullblock of=loop/$n; done 2> /dev/null
# sync
파일 내용과 물리적 오프셋을 확인하세요.
# hexdump -C loop/042
00000000 30 34 32 0a 30 34 32 0a 30 34 32 0a 30 34 32 0a |042.042.042.042.|
*
00100000
# filefrag -ve loop/042
Filesystem type is: ef53
File size of loop/042 is 1048576 (256 blocks of 4096 bytes)
ext: logical_offset: physical_offset: length: expected: flags:
0: 0.. 255: 44800.. 45055: 256: last,eof
loop/042: 1 extent found
블록 장치에서 읽기:
# dd bs=4096 skip=44800 count=256 if=/dev/loop1 | hexdump -C
00000000 30 34 32 0a 30 34 32 0a 30 34 32 0a 30 34 32 0a |042.042.042.042.|
*
00100000
조각:
# shred -v -n 1 loop/042
shred: loop/042: pass 1/1 (random)...
블록 장치(캐시)에서 읽기:
# dd bs=4096 skip=44800 count=256 if=/dev/loop1 | hexdump -C
00000000 30 34 32 0a 30 34 32 0a 30 34 32 0a 30 34 32 0a |042.042.042.042.|
*
00100000
블록 장치에서 읽기() iflag=nocache
:
# dd bs=4096 skip=44800 count=256 if=/dev/loop1 iflag=nocache | hexdump -C
00000000 30 34 32 0a 30 34 32 0a 30 34 32 0a 30 34 32 0a |042.042.042.042.|
*
00100000
# dd bs=4096 skip=44800 count=256 if=/dev/loop1 iflag=nocache | hexdump -C | head
00000000 59 c2 d8 d4 5a 02 35 15 a1 fb f1 07 ae 53 59 99 |Y...Z.5......SY.|
00000010 5b 47 4f fc 2c e7 d3 db 10 70 c6 72 3e 6f 0b 05 |[GO.,....p.r>o..|
00000020 f5 07 c6 f7 95 64 8b a2 4e 7f 32 4f 0c b1 a3 32 |.....d..N.2O...2|
00000030 18 b5 99 7d 7d 6e 6d d6 b9 36 77 af 30 02 ba 23 |...}}nm..6w.0..#|
00000040 f5 55 a5 b7 01 51 cd 5b 64 c9 29 1f f6 48 23 6c |.U...Q.[d.)..H#l|
dd iflag=nocache
캐시에서만 데이터 삭제뒤쪽에캐시에서 읽혀지므로 새 데이터를 보려면 두 번 수행해야 합니다. 또는 sync; echo 3 > /proc/sys/vm/drop_caches
모든 캐시를 지우거나 직접 I/O를 사용하여 행운을 시험해 볼 수도 있습니다.