BLOG ARTICLE 리눅스 | 1 ARTICLE FOUND

  1. 2008/09/03 open 과 fopen에 대한 고찰 (4)

프로그래밍을 할때 file 을 write 할때 open 과 fopen의 차이를 아는사람은 그리많지
않다고 생각한다.

임베디드 셋탑에서 NFS 에서 mount 해서 프로그래밍을 하는도중
아주 재밌는 CASE를 발견했다.

나만 몰랐나 -_-...

pBuffer에 데이타가 있다고 가정하고

FILE    *fl;

fl = fopen(pDstFile,"wb");

while(1)
     write(pBuffer,8192,1,fl);

fclose(fl);


이 코드가 죽는다.--- 정말 하루종일 삽질했다.
NFS에 무한적으로 write 를 반복하다 보면 불규칙한 시점에 커널 패닉이 나버린다.

고심끝에 fopen 을 open 과 write 로 대치하고 가장중요한거
open 할때 O_DSYNC 이옵션을 줘야한다.

NFS 가 어차피 네트워크로 전송하는거니 싱크가 중요하다.

O_DSYNC
Write I/O operations on the file descriptor complete as defined by synchronised I/O data integrity completion

언제나 느끼는 거지만 해답은 레퍼런스에 있다.

저 처럼 울트라 삽질하지 마시고...
YOUR COMMENT IS THE CRITICAL SUCCESS FACTOR FOR THE QUALITY OF BLOG POST
  1. Favicon of http://mytears.org/ BlogIcon 정태영 2009/02/26 03:49  댓글주소  수정/삭제  댓글쓰기

    위 코드는 좀 이상한데요? write 시스템 콜은 파일 포인터를 인자로 받지 않습니다. man 2 write 를 통해 확인해보면 write 시스템 콜의 원형이 다음과 같음을 알 수 있습니다.

    ssize_t write(int fd, const void *buf, size_t count);

    open으로 열었을땐 write로 쓰고, close로 닫아줘야할테고, fopen으로 열었으면 fwrite로 쓰고 fclose로 닫아줘야겠죠. ;)

    흠 사실 파일시스템은 사용자 영역에서 transparent하기 때문에 fopen, fwrite, fclose등을 쓰면 문제가 없어야할 것 같은데, 그 임베디드 시스템의 버그라고 볼 순 없는건가요?

    더군다나 fopen, fwrite 등을 사용할 경우 buffered I/O를 하는 것으로 알고 있는데...

    • Favicon of http://hidori.com BlogIcon hidori 2009/03/04 13:01  댓글주소  수정/삭제

      예 맞습니다. 위코드는 잘못된거구요. write 나 fwrite 둘다 죽습니다.
      핵심은 sync 옵션을 줘서 open을 하는것이지요. ^^

      임베디드 시스템의 버그는 아니구요. 요는 NFS로 네트워크마운트를 했기때문에 로컬파일이 아니라 네트워크 파일시스템이지요.

      문제는 빠른속도로 write가 이루어지면 NFS 가 속도를 따라가지를 못하고 오류가 나는거 같습니다.

      그래서 open할때 싱크를 맞춰서 사용하게 옵션을 주지요.

      이 버그때문에 정말 죽는줄 알았습니다.

  2. Favicon of http://mytears.org/ BlogIcon 정태영 2009/03/21 14:38  댓글주소  수정/삭제  댓글쓰기

    시스템의 버그라고 생각하는 것은 libc function 들을 사용할 경우 (fopen,fread,fwrite,fclose) 그 하위 레이어는 모두 감춰져 있기 때문에 저런 문제가 발생할 수 있다면 (nfs 하의 파일들은) libc 측에서 자동으로 D_SYNC옵션과 함께 open했어야 한다고 생각하기 때문입니다.

    D_SYNC등은 타이밍이나 순서에 민감하다거나 한 경우를 위한 옵션이지 특정 상황에서 필수적으로 사용해야하는 옵션이 아니거든요.

    만약 nfs를 통해 asynchronous mode로 많은 데이타가 오간다고 커널 패닉이 일어난다면 그건 커널 버그죠. 사용자가 예외 상황을 만들어낸다고 커널이 죽어서는 안된다고 생각합니다.

    느린 네트웍 아래서 nfs가 사용된다고 커널이 죽으면 느린 하드를 사용할 경우 커널이 죽는다는 것과 다를 게 없죠.

    저런 문제가 반복해서 발생한다면 mount option에 sync 를 넣어두는게 좋을 것 같네요.

  3. Favicon of http://hidori.com BlogIcon hidori 2009/03/25 11:06  댓글주소  수정/삭제  댓글쓰기

    그렇죠.. 결국은 mount 할때 sync를 주나 , open할때 sync를 주나 같은
    맥락의 이야기가 되는데요.

    커널버그라고 해도 사실 커널버그를 수정한다는건 배보다 배꼽이 더크죠^^
    그리고 느린하드와 네트워크환경은 조금 다른이야기로 생각됩니다.

    느린하드는 어찌됐건 느려도 싱크가 맞지만 네트워크상황은 위의옵션이 아니면
    싱크가 맞지않거든요.

    대부분의 경우는 어싱크로도 문제가 없지만 저같은경우는 하나TV처럼
    http 프로그레시브 다운로드 & Play중에 생긴문제거든요.

    아무튼 이러면서 하나둘 배워나가는거죠. 덧글 감사합니다.^^