삭제 된 파일 다시 연결


33

때때로 사람들은 자신이하지 말아야 할 파일을 삭제합니다. 장기간 실행되는 프로세스에서 여전히 파일이 열려 있고, catting하여 데이터를 복구하는 /proc/<pid>/fd/N것만으로는 충분하지 않습니다. ln에 매직 옵션을 실행하여 삭제를 "실행 취소"할 수 있으면 충분할 것입니다. 그러면 inode 번호 (lsof를 통해 복구)에 다시 연결할 수 있습니다.

최소한 커서가있는 인터넷 검색 으로이 작업을 수행 할 수있는 Linux 도구를 찾을 수 없습니다.

무엇을 얻었습니까, serverfault?

EDIT1 : 파일을 캐터링하는 /proc/<pid>/fd/N것이 충분하지 않은 이유 는 여전히 파일을 열어 둔 프로세스가 여전히 파일에 쓰고 있기 때문입니다. 삭제는 파일 시스템 네임 스페이스에서 inode에 대한 참조를 제거합니다. 내가 원하는 것은 참조를 다시 만드는 방법입니다.

EDIT2 : 'debugfs ln'은 작동하지만 원시 파일 시스템 데이터를 차단하기 때문에 위험이 너무 높습니다. 복구 된 파일은 또한 일관되지 않습니다. 링크 수가 0이며 링크를 추가 할 수 없습니다. /proc/<pid>/fd/Nfs를 손상시키지 않고 데이터에 액세스하는 데 사용할 수 있기 때문에이 방법으로 더 나쁩니다 .

답변:


14

ln에 매직 옵션을 실행하여 삭제를 "실행 취소"할 수 있으면 충분할 것입니다. 그러면 inode 번호 (lsof를 통해 복구)에 다시 연결할 수 있습니다.

이 awesomeness에이 소개되었다 ln에서 V8.0 와 (GNU /로 coreutils) -L|--logical원인이 옵션을 ln역 참조하는 /proc/<pid>/fd/<handle>첫 번째. 그래서 간단한

ln -L /proc/<pid>/fd/<handle> /path/to/deleted/file

삭제 된 파일을 다시 연결하기에 충분합니다.


7
작동하지 않습니다. 파일이 삭제되면 실패합니다.
Random832

1
아뇨. 나는 이것을 정기적으로 사용하여 삭제되었지만 여전히 열린 파일을 복원합니다. 그러나 새 파일이 파일이 삭제되기 직전의 파일 시스템동일한 파일 시스템/path/to/deleted/file 에 있는지 확인해야합니다 . 그렇지 않으면 실제로 실패합니다. (당신은 이전 경로를 얻을 수 있습니다 )ls -l /proc/<pid>/fd/<handle>
tnimeu

2
이러한 종류의 기능 ( 이 질문 및 답변 참조 )은 보안 위험 으로 구체적으로 거부 되었습니다 ([특권 프로세스를 중심으로 프로세스에 사용자가 소유하지만 다른 방법으로는 액세스 할 수없는 읽기 전용 파일 핸들을 제공하는 프로세스를 중심으로하는 보안 체계로] 거부 됨) ]; 나는 그것을 시도했다 (작은 C 프로그램으로 관련 시스템 호출을 직접 사용하지만) 작동하지 않았다.
Random832

7
물론 솔루션을 게시하기 전에 이것을 테스트했으며 그 당시에는 실제로 효과가있었습니다. 내가 알지 못하는 것은 tmpfs파일 시스템 에서만 작동 하지만 예를 들어 작동 하지 않는다는 것입니다 ext3. 또한이 기능 은 2.6.39에서 완전히 비활성화되었습니다 ( 커밋 참조) . 따라서이 솔루션은 더 이상 커널 2.6.39 이상에서 작동하지 않으며 이전 버전에서는 파일 시스템에 따라 다릅니다.
tnimeu

7
@tnimeu ln -L는 나를 위해 작동하지 않습니다. 삭제 된 파일이 있는데 원래 경로로 다시 연결하려고했습니다. ln나에게 ln: failed to create hard link /my/path/file.pdf => /proc/19674/fd/16: No such file or directory. 그러나 예를 들어 성공적으로 할 수 있습니다cat /proc/19674/fd/16
Eugene Beresovsky

13

당신이 이미 많이 이해하는 것처럼 들리므로 자세한 내용은 다루지 않겠습니다. inode를 찾는 방법은 여러 가지가 있으며 일반적으로 STDOUT을 cat 및 redirect 할 수 있습니다. 사용할 수 있습니다 debugfs. 다음에서이 명령을 실행하십시오.

ln <$INODE> FILENAME

파일 시스템의 백업이 있는지 확인하십시오. 나중에 fsck를 실행해야 할 것입니다. 나는 여전히 inode에 쓰여진 상태에서 이것을 성공적으로 테스트했으며 역 참조 된 inode에 대한 새로운 하드 링크를 만드는 데 효과적입니다.

파일이 ext3에서 열리지 않은 파일과 연결이 해제되면 데이터가 손실됩니다. 이것이 얼마나 일관되게 사실인지 확실하지 않지만 대부분의 데이터 복구 경험은 ext2에 있습니다. ext3 FAQ에서 :

Q : ext3 파티션에서 삭제 된 파일을 어떻게 복구 (삭제 취소) 할 수 있습니까? 실제로는 할 수 없습니다! Andreas Dilger 개발자는 다음과 같이 말했습니다.

충돌 후 ext3이 안전하게 링크 해제를 재개 할 수 있도록하기 위해 실제로는 inode에서 블록 포인터를 0으로 만드는 반면, ext2는 이러한 블록을 블록 비트 맵에서 사용되지 않는 것으로 표시하고 inode를 "삭제됨"으로 표시하고 블록을 떠납니다. 포인터 만.

당신의 유일한 희망은 삭제 된 파일의 일부를 "그 리핑"하고 최선을 다하는 것입니다.

이 질문에는 관련 정보도 있습니다.

Linux 서버에서 빈 파일로 큰 파일을 덮어 썼습니다. 기존 파일을 복구 할 수 있습니까?


댓글이 관련이 없어 삭제되었습니다.
mdpc

1
삭제되었지만 여전히 열려있는 파일의 경우 inode에서 포인터를 0으로 만들지 않을 것이라고 생각합니다. 또한 debugfs에서 "ln"을 사용하는 대신 "undel"을 사용하여 inode 참조 카운트가 올바르게 업데이트됩니다.
Mark Wagner

나는 앰 보보와 같이 언급하려고하지 않았다. 성능을 테스트하지 않았습니다. 나는 언어를 명확히했다.
워너

영리하지만 파일 시스템이 손상되었습니다. :)
mbac32768

시나리오를 설명 할 때 유일한 솔루션입니다. rw에 마운트되고 활발하게 기록되는 낮은 수준에서 파일 시스템을 조작하면 거의 모든 시나리오에서 손상이 발생할 수 있습니다.
워너

8

당신이 보았던 debugfs 방식은 실제로 작동하지 않으며 재부팅 후에는 파일이 저널로 인해 자동으로 삭제되며 최악의 경우 파일 시스템을 휴지통에 넣어 "재부팅주기"를 초래할 수 있습니다. Right Solution (TM)은 VFS 수준에서 삭제 취소를 수행하는 것입니다 (실제로 모든 현재 Linux 파일 시스템에서 작업 할 경우 추가 이점이 있음). LKML에 나타날 때마다 시스템 콜 방식 (flink)이 중단되었으므로 가장 좋은 방법은 모듈 + ioctl입니다.

이 접근법을 구현하고 합리적으로 작고 깨끗한 코드를 가진 프로젝트는 fdlink입니다 ( ubuntu maverick의 커널로 테스트 한 버전의 경우 https://github.com/pkt/fdlink.git ). 그것으로, 모듈을 삽입 한 후 (sudo insmod flink_dev.ko) "./flinkapp / proc // fd / X / my / link / path"를하면 정확히 원하는대로 할 수 있습니다.

vfs-undelete.sourceforge.net의 포워드 포트 버전도 사용할 수 있지만 원래 이름으로 자동으로 다시 연결할 수도 있지만 fdlink의 코드는 더 간단하고 잘 작동하므로 선호합니다.


3

나는 당신이 원하는 것을 정확하게하는 방법을 모르겠지만, 내가 할 일은 :

  • 다른 프로세스에서 파일 RO를 엽니 다
  • 원래 프로세스가 종료 될 때까지 기다리십시오.
  • 열린 FD의 데이터를 파일로 복사

이상적이지는 않지만 가능합니다. 다른 옵션은 link명령을 사용하여 debugfs를 사용하는 것이지만 프로덕션 시스템에서는 무섭습니다!


debugfs link 명령은이 사용 사례를 전혀 지원하지 않습니다.
mbac32768

tldp.org/HOWTO/Ext2fs-Undeletion-11.html에서 제안합니다. 나는 그것을 시도하지 않았지만 그것은 합리적 인 것 같습니다.
Bill Weiss

link내 테스트에서 작동하지 않았지만 작동했습니다 ln.
워너

3

오늘도 같은 문제가 발생했습니다. 내가 생각해 낼 수있는 최선은

% tail -n +0 -f /proc/<pid>/fd/<fd> /path/to/deleted_file

프로세스가 종료 될 때까지 tmux / screen 세션에서


2
허용 된 답변과 같이 원본 파일에 연결하면 작동합니다.
Chris S

1
이 질문에 대한 답변이 없습니다. 어떤 답변을 하시겠습니까?
Hamman Samuel

>삭제 된 파일로의 리디렉션 ( ) 이 필요하지 않습니까?
ncasas

1

흥미로운 질문입니다. 면접에서 면접관이 같은 질문을했습니다. 내가 그에게 말한 것은 이것을 할 수있는 쉬운 방법이 없었으며 일반적으로 시간과 노력을 들일 가치가 없다는 것이었다. 나는 그 에게이 문제에 대한 해결책이 무엇이라고 생각하는지 물어 보았습니다 ....

  1. 파일이 삭제 된 경우에도 여전히 표시되므로 프로세스의 디스크에서 inode 번호를 찾으려면 lsof를 사용하십시오. 키는 여전히 열려 있다는 것입니다.
  2. 파일 시스템 디버거를 통해이를 기반으로 파일 시스템에서 정보를 추출하십시오.

/ proc / <pid> / fd / N에서 데이터를 잘 추출 할 수는 있지만 내가하려는 것은 아닙니다.
mbac32768

1

Sleuthkit icat을 사용하십시오 .

sudo icat /dev/rdisk1s2 5484287 > accidentally_deleted_open_file

이것은 운영 체제의 파일 시스템 기능을 무시하고 디스크 바이트를 직접 구문 분석하여 작동합니다.
Flimm

0

협박 도구없이 저에게 도움이되는 빠른 솔루션 :

1) / proc에서 직접보고 프로세스 + fd를 찾으십시오.

ls -al /proc/*/fd/* 2>/dev/null | grep {filename}

2) 그런 다음 @nickray와 비슷한 기술을 pv던졌습니다.

tail -c +0 -f /proc/{procnum}/fd/{fdnum} | pv -s {expectedsize} > {recovery_filename}

완료되면 Ctrl-C를 사용해야 할 수도 있지만 ( ls /proc/{procnum}/fd/{fdnum}파일이 더 이상 존재하지 않음을 알려줍니다) 정확한 크기를 바이트 단위로 알고 있으면 pv -S카운트에 도달했을 때 파일을 종료 할 수 있습니다.

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