해결책이 있을 수도 있고 없을 수도 있는 흥미로운 문제가 있지만 가능하다면 하나 갖고 싶습니다.
Solaris에서는 열린 로그 파일이 제거되었으며 프로세스가 실행되는 동안 파일이 계속 채워지지만 이제 다른 모든 도구(예: 등 cat
) 에서 액세스할 수 없습니다 tail
.
모든 것을 계속 실행하면서 디렉터리의 항목을 해당 파일로 복원하는 방법이 있습니까?
답변1
가능하지만 몇 가지 해킹 및 제한 사항이 있습니다(루트 액세스가 필요함).
먼저 로그 파일을 작성하기 위해 애플리케이션에서 사용 중인 파일 설명자를 찾은 다음 이전 로그 파일 위치에 기호 링크를 만들고 파일 /proc 항목을 가리킵니다. 예:
ln -s /var/tmp/file.log /proc/12345/fd/3
첫 번째 제한은 파일이 프로세스에 의한 쓰기용으로만 열려 있는 경우 해당 권한으로 인해 권한이 없는 사용자가 해당 내용을 읽을 수 없다는 것입니다. 그러나 file_dac_read 권한이 있는 루트 및 사용자는 영향을 받지 않습니다. 또는 tail
Giles가 그의 의견에서 제안한 것처럼 프로세스를 사용하여 파일 내용을 복사할 수 있습니다 . 예를 들어:
tail -c +1 -f /proc/12345/fd/5 > /var/tmp/file.log
두 번째 문제는 프로세스가 종료되거나 종료될 때 전체 파일 내용이 손실되거나( ln -s
) 일부( )가 손실된다는 것입니다.tail -c 1 -f
해결 방법은 이 이벤트를 모니터링하고 실제로 닫기를 호출하기 전에 파일을 백업하는 프로그램을 사용하는 것입니다.
이를 수행할 수 있는 도구는 dtrace, truss, mdb 또는 dbx입니다.
다음은 Solaris 10에서 dtrace를 사용한 개념 증명입니다.
#!/bin/ksh
#
# This dtrace script is monitoring a file descriptor for a given process
# and copy its content to the given path when the file is closed.
#
pid=${1:?"$0: Usage: pid fd path"}
fd=${2:?}
path=${3:?}
[[ -f $path ]] && { echo "$path exists"; exit 1; }
dtrace -w -n '
syscall::close:entry
/pid=='$pid' && arg0=='$fd'/
{
stop();
system("cp /proc/%d/fd/%d %s",pid,arg0,"'"$path"'");
system("prun %d",pid);
exit(0);
}'