[Unix Bug?] stat의 file size가 이상합니다.
글쓴이: 김경태 / 작성시간: 화, 2003/12/30 - 3:03오후
#include <sys/stat.h> #include <unistd.h> #include <errno.h> char * path = "/opt/SongSoft/Log/ssf.cnx"; void main(void) { struct stat buf; long size; int flag; while(1) { sleep(3); <=== 주목 size = buf.st_size; flag = lstat(path, &buf); if(flag == -1 || errno == 2) printf("file does not exit\n"); else printf("org:%d, new:%d\n", size, buf.st_size); if ( size > buf.st_size ) exit(0); } }
<내용>
위 프로그램은 아시겠지만 특정 파일의 사이즈를 측정하고 그 사이즈를
보여주는 프로그램입니다.
그런데 sleep(3)에 해당하는 곳에 usleep(1000)과 같이 작은 시간을
입력하고 stat 사이즈를 측정하면서 동시에 ssf.cnx 파일에 한 라인을
attach하는 경우에 stat에서 나오는 사이즈가 커져야 정상인데 오히려
더 작은 값이 나옵니다.
그런데 sleep(3)처럼 상대적으로 큰 값을 삽입하게 되면 이런 현상은
생기지 않습니다.
<질문>
과연 이것은 Unix System Call인 stat의 버그일까요? 아니면 뭔가 코
드 자체에 문제가 있는 것일까요?
만약 이것이 Unix System Call인 stat의 버그라면 어떻게 하면 이 문제
를 회피할 수 있을까요?
현명한 고수님들의 높으신 의견 부탁드립니다.
참고:
여기에 예시된 ssf.cnx 파일은 log 파일로 text base로 되어 있습니다.
OS는 sol5에 CPU는 sparc입니다.
Forums:
lstat(2)을 쓰신 이유가 뭔지 궁금하군요.symbolic l
lstat(2)을 쓰신 이유가 뭔지 궁금하군요.
symbolic link로 된 log file이면, st_size가 커지지 않는게 정상이겠죠.
stat(2)을 써 보시기 바랍니다.
그리고 "void main(void)"는 표준에 위배됩니다. "int main(void)"나 "main()"을 쓰세요.
C FAQ: http://www.eskimo.com/~scs/C-faq/top.html
Korean Ver: http://cinsk.github.io/cfaqs/
stat도 마찬가지입니다.
lstat이나 stat이나 결국은 마찬가지입니다.
이미 stat으로 해봤는데 제대로 동작하지 않아서 어쩔수 없이 lstat으로 사용
하였는데 그래도 똑같은 현상이 생기는 군요.
그리고 대상파일이 symbolic link되지는 않았습니다.
그럼 답변 감사드리면서, 보다 더 좋은 의견이 계신 분이 있다면 답변 부탁 드
리겠습니다.
그럼 건강하시고 행복하십시요.
Re: [Unix Bug?] stat의 file size가 이상합니다.
발 담갔다. 이제 익숙해 지는길만이..
[재답변]"stat bug현상에 대한 질문에 답변드립니다."
인용:
그런데 sleep(3)에 해당하는 곳에 usleep(1000)과 같이 작은 시간을
입력하고 stat 사이즈를 측정하면서 동시에 ssf.cnx 파일에 한 라인을
attach하는 경우에 stat에서 나오는 사이즈가 커져야 정상인데 오히려
더 작은 값이 나옵니다.
동시에라고 하셨는데, 어떻게 테스트하셨나요?
가능하시다면 스크랩좀 해서 올려보세요.
---------------------------------------------------------------------------
저 프로그램을 돌리면서 해당하는 파일을 vi로 열고 yy & p로 한라인을
붙여줍니다.
그때에 나오는 프로그램상의 수치가 정상적이면 더 커져야 하는데 오히
려 더 작아지는 경우가 있습니다.
수치가 작아져서 나오는 경우는 주로 sleep의 단위를 줄이게 되면 더 잦
게 나타납니다.
즉 100번 정도 test했을 때,
1. sleep(3) -> 관찰된 바 없음
2. sleep(1) -> 30번 정도에 한번정도 관찰됨
3. usleep(1000) -> 절반정도의 빈도로 관찰됨
----------------------------------------------------------------------------
인용:
과연 이것은 Unix System Call인 stat의 버그일까요? 아니면 뭔가 코
드 자체에 문제가 있는 것일까요?
매우 빈번히 사용되는 시스템 콜로 stat의 버그일 가능성은 희박하다고 봅니다.
--------------------------------------------------------------------------------
제가 보기에는 Sun OS에서 file system의 정보를 update하는 시간이
조금 걸리기 때문에 그런 이유로 중간에 stat을 이용하여 size 정보를 보
려고 시도하면 잘못된 사이즈가 return 되는 것으로 판단됩니다.
이런 의미라면 오히려 stat system call 자체보다는 Sun OS의 버그라고
봐야 할 것 같네요.
정상적이라면 OS상에서 file system 정보를 update하는 동안에는 file
system의 정보를 읽어들이는 system call(lstat, stat)의 행위를 막도록
locking 알고리즘을 통하여 처리해야 하지 않나 생각합니다.
--------------------------------------------------------------------------------
인용:
만약 이것이 Unix System Call인 stat의 버그라면 어떻게 하면 이 문제
를 회피할 수 있을까요?
1. 다른 방식으로 파일사이즈를 구한다. (이를테면 open lseek close)
2. 라이브러리를 업데이트한다.
파일 사이즈를 감시하는 이유가 무엇입니까? 용도는?
--------------------------------------------------------------------------------
1 에 대한 대답.
물론 가능합니다만, 첫째로 open은 stat보다 훨씬 느린 system call이라는
것은 잘 아시리라 생각합니다.
굳이 빠른 system call을 놔두고 더 느린 system call을 선호할 이유는 없는
것 같습니다.
둘째로 번잡합니다.
단지 file size를 구하기 위해서 세개의 시스템 콜을 사용한다는 것은 code의
지저분함을 증가시키는 행위가 되겠지요.
2 에 대한 대답
library를 업데이트한다고 될까요?
단지 stat을 여러번 사용하는 문제라면 library간의 locking 문제이므로 library
의 bug fatch를 통하여 해결하겠지만 이런 경우는 현상으로 볼때 OS와system
call과의 문제로서 library fatch로서는 해결될 수 없는 성질의 문제가 아닐까하
는 생각이 듭니다.
파일 사이즈를 감시하는 이유
간단한 이유입니다. log file size에 변화가 생기면, 즉 log file에 log가 쌓이면
이 로그를 read ->parsing 과정을 통하여 가공된 데이타를 시스템 정보 파악
에 쓰려고 하는 겁니다.
그러므로 가급적 실시간에 가깝게 log 처리가 이루어져야만 시스템 정보가 실
시간에 가깝게 처리되는 것입니다.
----------------------------------------------------------------------------------
친절하고 자상한 관심에 감사의 뜻을 표하며, 저의 답변이 stat에 대한 bug 현
상 파악에 일조하게 되기를 바랍니다.
그럼 늘 건강하시고 행복하십시요. ^^;
에디터로 파일을 열어서 저장하게 되면 파일을 처음부터 새로 쓸겁니다.
에디터로 파일을 열어서 저장하게 되면 파일을 처음부터 새로 쓸겁니다.
따라서 파일을 디스크에 쓰는 순간에는 당연히 원래 파일보다 작은게 정상 아닐까 싶군요.
파일에 라인을 덧붙이는 프로그램을 따로 만들어서 테스트해야 원하는 결과를 얻을 수 있을것 같군요.
저도 krisna님이 말씀이 맞다고 봅니다. stat(2)에 버그가 있다
저도 krisna님이 말씀이 맞다고 봅니다. stat(2)에 버그가 있다고 생각되진 않네요.
cat >ssf.cnx 와 같이 해 놓고,
프로그램을 실행시키시고,
cat한 터미널에서 문자를 입력해 보세요.
참고로, 제가 테스트했을 때는 usleep(1000) 으로 했을때도
아무런 이상이 없었습니다. (FreeBSD 5-current, Redhat Linux 9)
(buf.st_size를 while loop이전에 0으로 초기화해주긴 했습니다.)
----
Let's shut up and code.
Re: [재답변]"stat bug현상에 대한 질문에 답변드립니다.&q
이게 문제네요 --;;
vi로 한라인 붙이고 저장하면 파일을 처음부터 만들겠죠
천천히 체크하면 운이 좋아서 파일이 다 저장된 다음에 체크가 되는것이지만, 자주 체크하면 vi가 저장하는 중간에 체크해서 이상한 값이 나오는 것입니다. 솔찍히 말해서 stat에 버그가 있으면 sun os가 지금까지 어떻게 남아있겠습니까 --;;
프로그래밍하면서 뭔가 잘못되면, 자기 자신의 실수를 생각해봐야죠 --;; 물론 라이브러리가 잘못되었을수도 있지만 stat같은 것은 잘못될 리가 없습니다.
차라리 select나 poll을 이용하여ro로 open하고 fd가 갱
차라리 select나 poll을 이용하여
ro로 open하고 fd가 갱신되는 것을 채크하는 방식은 안될까요?
아니면, log를 생성하는 프로그램의 소스를 수정할 수 있다면,
log가 발생할 때
signal을 log checker에게 날리는 것이 보다 효과적일 것 같구요.
There is no spoon. Neo from the Matrix 1999.
Re: [재답변]"stat bug현상에 대한 질문에 답변드립니다.&a
검색해 보시면 님과 같이 로그파일 감시에 관한 논의가 있습니다. 찾아보십시요.
syslogd 을 고려해 보십시요.
(syslog() 불편하신다면 로그 받을 데몬을 직접 작성해 쓰셔도.. 전달은 ipc, socket, etc 저장은 파일?, DB?, 또다른 로그서버? 등등..)
$tail -f 옵션 같은 것들이 님이 생각하시고 계신 감시 방법과 동일합니다. 소스를 살펴보십시요.
(어떤 프로그램의 로그인지 밝혀 주셨으면 좀더 나은 답변이 되었을겁니다만..)
발 담갔다. 이제 익숙해 지는길만이..
[quote="지리즈"]차라리 select나 poll을 이용하여ro로
http://bbs.kldp.org/viewtopic.php?t=2409&highlight=%B7%CE%B1%D7%C6%C4%C0%CF+%B0%A8%BD%C3
읽어보시면 아시겠지만, 불가능하다는군요.
일반적인 화일을 select 할일이 없어서 생각도 못해봤었는데, 저글 보고 알았습니다.. 역시 고 레벨로 가면 다른 레벨에서 접근하는군요. --;
발 담갔다. 이제 익숙해 지는길만이..
상황이 된다면, fam같은걸 써도 될 듯 하네요 :)File Alte
상황이 된다면, fam같은걸 써도 될 듯 하네요 :)
File Alteration Monitor 입니다.
http://oss.sgi.com/projects/fam/
위치는 여기이고요
[답변]"fopen으로 한줄만 attach하니 문제가 해결되었네요&
1. stat test용 코드
2. file에 attach하는 코드
test 결과
2를 이용하여 file attach하면서 1을 통하여 감시하는 경우
org:112660, new:112660
org:112660, new:112660
.
.
.
org:112660, new:112746
org:112746, new:112746
.
.
.
org:112746, new:112746
org:112746, new:112832
org:112832, new:112832
.
.
.
org:112832, new:112918
org:112918, new:112918
.
.
.
org:112918, new:112918
이상과 같이 stat이 올바른 결과를 return 하였습니다.
vi 를 이용하여 open하고 yy & p를 이용하여 attach, 1을 통하여 감시
org:113262, new:113262
org:113262, new:113262
org:113262, new:113262
org:113262, new:113262
org:113262, new:113262
org:113262, new:113262
org:113262, new:113262
org:113262, new:113262
org:113262, new:113262
org:113262, new:45056
retray: org:113262, new:45056
retray 1second: org:113262, new:113348
attach 세번째에 위와 같은 메시지가 나오면서 exit
결론
위에서 보는 대로 vi로 yy & p로 하게 되면 vi 프로그램에서 file의 처음부
터 다시 write 하는 관계로 file I/O가 일어나는 시간동안 일시적으로 파일
사이즈가 작아지는 현상이 생기는 것으로 보여집니다.
반대로 fopen을 이용하여 line을 apend하는 경우는 stat에서 제대로 된
정보를 보여주는 관계로 stat을 이용한 파일 사이즈 감시가 원할히 이루
어지는 것을 발견했습니다.
그러므로 stat에 대한 저의 잘못된 생각은 시스템 콜에 대한 버그가 아닌,
사소한 test 방식의 오해로부터 비롯되었음을 알게 되었습니다.
고수님들의 자상한 교훈으로부터 많은 것을 배우게 되었고, 새로운 사실을
깨닫게 되어 매우 기쁘게 생각합니다.
<모쪼록 건강하시고 새해에도 복 많이 받으시기를 바랍니다.>
또다른 질문:
tail -f로 파일을 감시하는 경우 vi를 통한 file attatch 의 경우 file size가
작아짐에도 불구하고 반드시 새로 attach된 line 내용만을 뿌려주게 되어
있습니다.(실험 결과)
새로 attach된 내용을 뿌려주기 위해서는 before size > after size 인 경
우는
1. fclose(fp)
2. fopen(path)
3. while ( fp != EOF)
{
fgets(string, fp);
fputs(string, fp);
}
와 같이 해줘야 할텐데 vi로 yy & p로 해주는 경우와 같이 일시적으로 파
일사이즈가 작아지는 경우에 어떻게 대처를 했기에 새로 attach된 내용만
볼수 있는 것인지 그것이 매우 궁금하네요.
혹시 아시는 분이 계시다면 좋은 가르침 주신다면 감사하겠습니다.
Re: [답변]"fopen으로 한줄만 attach하니 문제가 해결되었
심심해서 소스(GNU textutil, tail.c)를 뒤져 보았는데..
fstat + lseek가 해답인 것 같습니다.
테스트는 안해보았습니다.
ps. 오늘 쉬시는 분 안계신가요? 우리만 쉬나? 대신 크리스마스때 야근했음. ㅎㅎ
There is no spoon. Neo from the Matrix 1999.
Re: [답변]"fopen으로 한줄만 attach하니 문제가 해결되었
interrupt 가 있을 때 다시 읽어 줍니다.
do
{
result = read(fd, buf, count);
}
while (result < 0 && (errno == EINTR));
댓글 달기