삭제된 파일에 대한 파일 핸들을 열면 하드 드라이브가 가득 차는 것처럼 보이는 이유

삭제된 파일에 대한 파일 핸들을 열면 하드 드라이브가 가득 차는 것처럼 보이는 이유

그래서 간단히 말해서, 나는 많은 파일을 열고 그 안에 데이터를 쓴 다음 파일 핸들을 제대로 닫지 않고 파일을 삭제하는 (파이썬) 프로그램을 작성했습니다. 잠시 후 디스크 공간 부족으로 인해 프로그램이 중지됩니다.

더 이상 존재하지 않는 파일이 많아 cannot create temp file for here-document: No space left on device"bash 의 자동 완성이 실패합니다 .lsof -nP +L1

내 프로그램을 종료한 후 모든 파일 핸들이 닫히고 디스크 공간이 다시 "사용 가능"해지며 모든 것이 정상입니다.

왜 이런 일이 발생합니까? 디스크 공간은 물리적으로 채워지지 않습니다. 아니면 파일 핸들 수가 제한되어 있습니까?

답변1

Unix에서 파일을 삭제하면 해당 데이터에 대한 명명된 참조만 제거됩니다(따라서 시스템 호출 이름 unlink/ unlinkat대신 delete). 데이터 자체를 공개하려면 해당 데이터에 대한 다른 참조가 없어야 합니다. 참고문헌은 다음과 같은 방법으로 얻을 수 있습니다:

  1. 이 데이터는 더 이상 파일 시스템에서 참조되어서는 안 됩니다( st_nlink0이어야 함). 이는 하드 링크에서 발생할 수 있습니다. 그렇지 않으면 파일 시스템에서 계속 액세스할 수 있는 동안 데이터를 삭제합니다.
  2. 이 데이터는 열린 파일 핸들에서 더 이상 참조될 수 없습니다(Linux에서는 커널의 상관 관계가 0이어야 합니다) struct file. f_count그렇지 않으면 파일 핸들(또는 Linux에서)을 읽거나 쓰는 방식으로 데이터에 계속 /proc/pid/fd액세스하거나 변경할 수 있으므로 계속해서 어딘가에 저장해야 합니다.

이 두 가지 조건이 충족되면 데이터가 공개될 수 있습니다. 상황이 조건 #2를 위반했으므로 파일 핸들이 여전히 열려 있습니다. 파일 핸들이 닫힐 때까지 데이터는 다른 곳으로 갈 곳이 없기 때문에 디스크에 계속 저장됩니다.

일부 프로그램에서는 이를 사용하여 데이터 정리를 단순화하기도 합니다. 예를 들어, 중간 작업을 위해 일부 대용량 데이터를 디스크에 저장해야 하지만 이를 다른 사람과 공유할 필요가 없는 프로그램을 상상해 보세요. 파일을 연 다음 즉시 삭제하면 종료 시 정리되었는지 걱정할 필요 없이 파일을 사용할 수 있습니다. 열린 파일 설명자 참조 횟수는 close(fd)종료 시 자연스럽게 0으로 떨어지고 다음과 같은 경우 관련 공간이 해제됩니다. 프로그램이 정상적으로 종료됩니다.

발각

파일 설명자에 의해 아직 열려 있는 삭제된 파일은 다음을 lsof사용하여 찾을 수 있습니다.

% lsof -nP +L1
COMMAND     PID  USER   FD   TYPE DEVICE SIZE/OFF NLINK      NODE NAME
pulseaudi  1799 cdown    6u   REG    0,1 67108864     0      1025 /memfd:pulseaudio (deleted)
chrome    46460 cdown   45r   REG   0,27   131072     0    105357 /dev/shm/.com.google.Chrome.gL8tTh (deleted)

st_nlink값이 1보다 작은 열려 있는 모든 파일이 나열됩니다 .

덜다

귀하의 경우에는 프로세스를 종료하여 파일 핸들을 닫을 수 있습니다. 이는 가능하다면 좋은 해결책입니다.

이것이 가능하지 않은 경우 Linux에서는 파일 설명자가 지원하는 데이터에 액세스하여 /proc/pid/fd파일이 삭제된 경우에도 크기 0으로 자를 수 있습니다.

: > "/proc/pid/fd/$num"

응용 프로그램이 이후에 해당 파일 설명자를 사용하여 수행하는 작업에 따라 응용 프로그램은 아래에서 이와 같이 데이터가 변경되는 것에 대해 다양한 정도의 분노를 느낄 수 있습니다.

파일 설명자가 방금 유출되어 다시 액세스할 수 없다고 확신하는 경우 gdb를 사용하여 닫을 수도 있습니다. 먼저 lsof -nP +L1또는 를 사용하여 ls -l /prod/pid/fd관련 파일 설명자 번호를 찾은 후 다음을 수행하십시오.

% gdb -p pid --batch -ex 'call close(num)'

귀하의 질문에 대한 이유는 아니지만 다른 질문에 대답하려면 다음을 수행하십시오.

파일 [설명자] 수가 제한되어 있습니까?

파일 설명자 수제한되어 있지만 여기서 직면하는 제한은 아닙니다. "장치에 남은 공간 없음"은 ENOSPC파일 시스템의 공간이 부족할 때 생성되는 것입니다. 파일 설명자 제한에 도달하면 EMFILE("열린 파일이 너무 많음"으로 표시되는 프로세스 수준 부족 strerror) 또는 ( "시스템에 열려 있는 파일이 너무 많음"으로 ENFILE표시되는 시스템 수준 부족 ) 메시지가 표시됩니다. strerror프로세스 수준 소프트 제한은 를 통해 확인할 수 ulimit -Sn있으며 시스템 수준 제한은 를 통해 확인할 수 있습니다 /proc/sys/fs/file-max.

답변2

(현재 삭제된) 파일에 대한 핸들을 보유하고 있는 한, (핸들을 보유하고 있는 프로세스에서) 해당 데이터에 계속 액세스할 수 있습니다. 이 데이터는 저장할 장소가 필요합니다.

관련 정보