[완료] 다중 프로세스에서 동시에 mkdir수행시 directory가 순간적으로 file로 인식되는 문제......

ssenk의 이미지

아래와 같은 작업 흐름:
1) 하나의 프로그램이 병렬로 수행되어야 함.
2) 작업 결과 directory를 만들어야 함.
3) directory가 존재하는지 검사 하고 mode가 directory인지 검사. (directory가 아니면 error)
4) 존재하지 안으면 mkdir() 호출, 존재하면 skip

3) 수행중 error로 빠져나가는 프로세스 발생:
1년여 동작하던 병렬처리방식 이었는데 이번에 3)번 수행중 error가 리턴되어 당혹 스럽습니다.

개발서버에서 같은 error를 유발 시키기위해 여러가지 시도를 하였지만 발생하지는 않고 OS source를 trace해 보았지만
딱히 잡아내기 힘드네요.

이 분야 고수님들의 경험담을 듣고 싶습니다....

김성진의 이미지

고도의 추상화, 극도의 구체화, 에디슨을 그리워하다.

고도의 추상화, 극도의 구체화, 에디슨을 그리워하다.

김성진의 이미지

3번 작업을 하기전에 file lock을 잡으시고 수행하세요.

4번 작업을 끝나면, file lock을 푸시구요.

동시성 제어를 명시적으로 해 주시는 것이 여러모로 유리합니다.

병렬이라는 의미가 동시성제어를 하지 않아야 한다는 것은 아니겠지요?

고도의 추상화, 극도의 구체화, 에디슨을 그리워하다.

고도의 추상화, 극도의 구체화, 에디슨을 그리워하다.

ssenk의 이미지

lock을 잡을 대상이 마땅치 않군요... 아직 존재하지 않는 디렉토리이고
또, 시스템 모듈이 아니라 Application모듈중 업무 중심적인 모듈이어서
임의로 파일을 생성하거나 /tmp에 기록하는 것에 제한이 있어서...;;

누구나 이해할 수 있고 별도의 자원을 사용하지 않는 방법을 고민 중입니다.

욕지행

욕지행

bushi의 이미지

OS, 커널버전 좀 적어주세요.
리눅스겠죠 ?

sys_mkdir() -> vfs_mkdir()
sys_stat() -> vfs_stat()

vfs_mkdir() 은 inode 가 아니라 dentry 에 대해 mutex lock 을 합니다.
vfs_stat() 은 별 다른 절차없이 inode 정보를 바로 읽어냅니다.

결국 sys_mkdir() 도중에 preemption 이 일어나서 sys_stat() 이 불리면 괴롭다는건데...
파일 시스템 개별적으로 좀 차이가 있긴 하지만, 대부분 S_IFDIR 을 세트하는 부분이 오뉴월 소불x 늘어지듯 그렇게 축축 늘어져있지는 않습니다.

어찌됐건 sys_mkdir() 이 preemptable 한 system call 인지는 모르겠습니다.
확인해보시려면 vfs_mkdir() 안에서 current->thread_info->preempt_count 값을 찍어보시면 됩니다.

0 이 아닌 양의 정수라면 not preemptable 입니다.
이 경우라면... preemption 외에 다른 문제가 있다는 거겠지요.
하여간 커널의 fs sub-system 이 좀 허술하긴 하네요.

ssenk의 이미지

OS는 Solaris인데요...

>> 확인해보시려면 vfs_mkdir() 안에서 current->thread_info->preempt_count 값을 찍어보시면 됩니다.
확인해보는 간단한 source좀 알려주세요^^

욕지행

욕지행

bushi의 이미지

solaris 라면 잊으세요.
리눅스 커널의 preemtion 일 경우를 적어드렸습니다. vfs_mkdir() 은 리눅스 커널 fs sub-system 의 일부입니다.
2.4 + preemptive patch 와 2.6 native preemption 이 몇몇 system call 에 대해 조금 틀리기 때문에, 혹시 리눅스라면 확인해보시는 게 좋을 것 같아 적었습니다.

kalstein의 이미지

mkdir 함수자체는 system call이므로...atomic operation임을 OS 차원에서 보장합니다. 굳이 '이런 디렉토리가 있나없나?'를 본담에 create하시는 이유가 궁금하네요. 바로 mkdir()을 호출한 다음, 에러가 나면 그에대한 (에러가 리턴시에 errno로 어떤종류의 에러인지 판별이 가능합니다) 예외처리를 하시는 편이 깔끔해 보입니다.


------------------------------------------
Let`s Smart Move!!
http://kalstein.tistory.com/

ssenk의 이미지

kalstein님 의견이 명쾌하겠네요.... 아~ 제의도는 이미 있으면 안만들겠다는 의도 였는데 님 의견에 동의합니다.

....
....
....

if (mkdir(dir, mode))
{
switch (errno)
{
case EEXIST:
if (isnotdir(dir)) error_exit("%s is file, not direcotry\n", dir);
break;
default:
error_exit("%s make error; [%d] %s\n", dir, errno, strerror(errno));
break;
}
}

....
....
....

뭐 이런식의 에러 처리면 무난히 수행 되겠네요...

욕지행

욕지행

댓글 달기

Filtered HTML

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

BBCode

  • 텍스트에 BBCode 태그를 사용할 수 있습니다. URL은 자동으로 링크 됩니다.
  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param>
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.

Textile

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • You can use Textile markup to format text.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Markdown

  • 다음 태그를 이용하여 소스 코드 구문 강조를 할 수 있습니다: <code>, <blockcode>, <apache>, <applescript>, <autoconf>, <awk>, <bash>, <c>, <cpp>, <css>, <diff>, <drupal5>, <drupal6>, <gdb>, <html>, <html5>, <java>, <javascript>, <ldif>, <lua>, <make>, <mysql>, <perl>, <perl6>, <php>, <pgsql>, <proftpd>, <python>, <reg>, <spec>, <ruby>. 지원하는 태그 형식: <foo>, [foo].
  • Quick Tips:
    • Two or more spaces at a line's end = Line break
    • Double returns = Paragraph
    • *Single asterisks* or _single underscores_ = Emphasis
    • **Double** or __double__ = Strong
    • This is [a link](http://the.link.example.com "The optional title text")
    For complete details on the Markdown syntax, see the Markdown documentation and Markdown Extra documentation for tables, footnotes, and more.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 사용할 수 있는 HTML 태그: <p><div><span><br><a><em><strong><del><ins><b><i><u><s><pre><code><cite><blockquote><ul><ol><li><dl><dt><dd><table><tr><td><th><thead><tbody><h1><h2><h3><h4><h5><h6><img><embed><object><param><hr>

Plain text

  • HTML 태그를 사용할 수 없습니다.
  • web 주소와/이메일 주소를 클릭할 수 있는 링크로 자동으로 바꿉니다.
  • 줄과 단락은 자동으로 분리됩니다.
댓글 첨부 파일
이 댓글에 이미지나 파일을 업로드 합니다.
파일 크기는 8 MB보다 작아야 합니다.
허용할 파일 형식: txt pdf doc xls gif jpg jpeg mp3 png rar zip.
CAPTCHA
이것은 자동으로 스팸을 올리는 것을 막기 위해서 제공됩니다.