리눅스 커널 코딩 스타일

엠스톤 bebop 에서 퍼옴


리눅스 커널 코딩 스타일

리누스 토발즈 작성

(Original english text is LinuxCodingStyle.)

이 짧은 문서는 리눅스 커널을 위한 코딩 스타일을 기술한 것입니다. 코딩 스타일은 very personal한 것이지만, 전 누구에게도 나의 view를 force 하고 싶지 않습니다.
하지만, 이것은 what goes for anything that I have to be able to maintain 이고, 전 다른 대부분의 것에도 이것을 더 좋아합니다.

Please at least consider the points made here.

우선, GNU coding standards 를 프린트한후 읽지 마십시오. Burn them, it's a great symbolic gesture.

Anyway, here goes:

들여쓰기
탭은 8 characters, 그리고 thus indentations 또한 8 characters 입니다. 4(또는 단지 2!) characters 들여쓰기를 하는 것은 PI의 값을 3으로 define하는 것과 유사한 얘깁니다.

Rationale: 들여쓰기에 숨겨진 모든 idea는 어디서 블록 제어를 시작하고 끝낼지를 명확히 정하기 위해서입니다.
 특히 당신이 스크린을 20시간 연속으로 볼때, 당신이 large 들여쓰기를 한다면 들여쓰기의 작용으로 스크린을 보는것이 많이 쉬워지게 될것입니다.

Now, 8-character 들여쓰기가 코드를 너무 오른쪽으로 들어가게 해서 80-character terminal screen에서는 보기가 힘들다고 주장하는 사람들도 있습니다.
해답은 당신이 3 levels 이상의 들여쓰기을 할 필요가 있다면 당신이 잘못한 것이며 당신의 프로그램을 고쳐야 할 것입니다.

요약하자면, 8-char indents는 읽기 쉽게 해주며 당신이 함수들을 깊게 nesting 하는것을 경고해주는 장점도 있습니다. 그 경고를 조심하세요.

중괄호 치기
C Styling에서 언제나 논의에 오르는 또다른 문제는 중괄호 배치입니다. 들여쓰기 크기와는 달리, 하나의 중괄호 치는 방법을 선택해야할 이유는 별로 없지만,
선지자 Kernighan and Ritchie께서 우리에게 보여주셨던 더 좋은 방법은 여는 괄호를 줄 마지막에 놓고, 닫는 괄호는 맨 앞에 놓는 것이다.


if (x is true) {
        we do y
}


그러나 함수의 경우에는 특별히 여는 중괄호가 다음행의 처음에 옵니다.


int function(int x)
{
        body of function
}


전세계의 반대의 사람들은 claimed that this inconsistency is ... well ... inconsistent, 그러나 모든 right-thinking 사람들은
know that (a) K&R are right and (b) K&R are right. 그외에도 함수는 어쨋든 특별합니다.

Note that the closing brace is empty on a line of its own, _except_ in the cases where it is followed by a continuation of the same statement,
ie a "while" in a do-statement or an "else" in an if-statement, like this:


do {
        body of do-loop
} while (condition);
and

if (x  y) {
        ..
} else if (x > y) {
        ...
} else {
        ....
}


Rationale: K&R.

Also, 이러한 brace-placement는 readability는 그대로 유지하면서 empty line의 수를 최소화 시키기까지 합니다.
Thus, as the supply of new-lines on your screen is not a renewable resource (think 25-line terminal screens here), you have more empty lines to put comments on.

Naming
C 는 엄격하고 간소한 언어이며, 당신이 이름지을때도 마찬가지여야 합니다. Modula-2나 Pascal 프로그래머들과는 달리,
C 프로그래머들은 ThisVariableIsATemporaryCounter 같은 cute names를 사용하지 않습니다. C 프로그래머는 그 변수를 "tmp"라고 더 쓰기 쉽게 이름 지을 것이며,
 더 이해하기 어려운 이름은 사용하지 않을 것입니다.

하지만 , mixed-case names들은 나쁜것이지만, 전역변수에 있어서 서술적인 이름은 필수적인 것입니다. 전역변수를 "foo"라고 이름짓는 것은 shooting offense입니다.

GLOBAL 변수들은 (오직 _really_ 필요할 때만 쓰라) 서술적인 이름을 가져야 하며, 그점은 전역 함수들도 마찬가지입니다.
당신이 active users의 수를 세는 함수를 가진다면 당신은 그것을 "count_active_users()"또는 비슷한 이름을 짓지, "cntusr()"같은 이름 으로 짓지는 않을 것입니다.

이름에 타입을 포함시키는것은(Hungarian notation라 불림) brain damaged입니다 - 컴파일러는 어쨋든 타입을 알고 있고 검사할 수 있으며,
그것은 프로그래머만 혼란시킵니다. M$가 버그투성의 프로그램을 만드는것은 당연합니다.

지역 변수의 이름은 짧아야 하며, 적절한 이름이어야 합니다. 만약 당신이 어떤 랜덤한 정수 루프 카운터를 가진다면, 그것은 "i"라고 불러질 것입니다.
그걸 "loop_counter"라고 부르는 것은 오해의 가능성은 없겠지만 비생산적입니다. Similarly, "tmp"도 임시적인 값을 저장해두는데 사용되는 어떤 타입의 변수 이름으로도 사용될수 있습니다.

지역 변수이름이 혼란스러워지는것이 두렵다면, 당신은 function-growth-hormone-imbalance syndrome 라 불리는 다른 문제를 안게 될것이다.
See next chapter.

Functions
함수는 short and sweet 하여야 하며, 한가지만을 해야 합니다. 함수는 하나 또는 두 화면에 가득찰 정도의 텍스트(the ISO/ANSI screen size is 80x24, as we all know) 여야 하며,
한가지를 잘 수행해야 합니다.

The maximum length of a function은 그 함수의 복잡도와 들여쓰기 level에 역비례 합니다.
So, 여러개의 case에서 여러가지의 작은 작업을 하는 단 하나의 긴 case-statement를 가진 함수의 경우, 더 길어도 괜찮습니다.

그러나, 만약 당신에게 복잡한 함수가 있고, less-than-gifted 고등학교 1학년 학생조차 그 함수가 무엇에 대한 것인지를 모를거라 의심이 든다면,
당신은 모든 면에서 면밀히 maximum limit에 충실해야 합니다.
설명적인 이름을 가진 거드는 함수를 사용하세요(만약 당신이 그것이 performance-critical 하고 당신이 한것보다 나아질수 있을 것 같다고 생각한다면,
컴파일러에게 그함수를 인라인으로 할수 있는지 요구할 수 있습니다).

함수의 다른 척도로 지역 변수의 갯수를 들수 있습니다. 지역 변수는 5-10을 초과하지 말아야 하며, 초과한다면 당신은 뭔가 잘못하고 있는것입니다.
다시 생각해보면, 함수는 더 작은 조각으로 쪼갤 수 있습니다. 인간의 두뇌는 일반적으로 7개의 다른 것에 관한 track을 유지하고 있으며,
anyting more and it gets confused. You know you're brilliant, but maybe you'd like to understand what you did 2 weeks from now.

Commenting
주석은 좋은것이지만, 또한 over-commenting의 위험도 가지고 있습니다.
절대 주석으로 당신의 코드가 어떻게 동작하는지 설명하지 마세요
: it's much better to write the code so that the working is obvious, and it's a waste of time to explain badly written code.

Generally, 주석으로 코드가 어떻게 움직이는지가 아니라, 뭘 하는지를 말하고 싶어하세요. 또한, 함수 몸체 내부에 주석을 다는걸 피하도록 하세요
: 함수가 너무 복잡해서 개별적으로 주석을 달아야 할 필요가 있을때, 당신은 아마 잠시 챕터 4로 되돌아가게 될것입니다.
당신은 어떤부분에 something particularly clever(or ugly) 대한 것을 주의나 경고를 하기위한 작은 주석을 달 수 있지만 너무 많이 하지는 말도록 하세요.
대신에 함수의 첫부분에 주석을 달아서, 함수가 무엇을 하고, 함수가 왜 그렇게밖에 못했는지를 말하세요.

실수
That's OK. 우리 모두는 실수를 합니다. 당신은 아마 오랜동안 유닉스 유저의 보조자였던 "GNU emacs"가 당신을 위해 자동으로 생성한 formats C sources에 의한 것이었다고 말하고,
그렇다고 인정하지만, 디폴트로 사용된 값은 원하는 것에 미치지 못합니다 (사실, 그것은 random typing보다 못합니다 - GNU emacs에서의 무한한 타이핑은 절대 좋은 프로그램을 만들어 내지 못할겁니다).

So, 당신은 GNU emacs를 집어치우든지, 아님 그것을 더나은 값으로 바꿀수 있습니다. 후자를 하기위해, 밑의 것들을 당신의 .emacs 파일에 붙일수 있습니다.

(defun linux-c-mode ()
 "C mode with adjusted defaults for use with the Linux kernel."
 (interactive)
 (c-mode)
 (c-set-style "K&R")
 (setq c-basic-offset 8))
이것은 the M-x linux-c-mode command를 정의 할 것입니다. -*- linux-c -*- 를 처음 두 라인에 추가한다면, 당신이 모듈을 hacking할 때 이 모드가 자동으로 발동될 것입니다.
또한, 당신이 /usr/src/linux 에 있는 소스 파일들을 편집할때, 자동으로 linux-c-mode``로 변하기를 원한다면 ``.emacs 파일에 다음을 추가하기를 원할겁니다.

(setq auto-mode-alist (cons '("/usr/src/linux.*/.*\\.[ch]$" . linux-c-mode)
                      auto-mode-alist))
그러나 당신이 emacs로 올바른 formatting을 하는데 실패하더라도, 모든것을 잃는게 아닙니다: "indent"를 사용하세요.

자, 다시, GNU indent는 GNU emacs를 쓰기위해 당신이 몇가지 command line options가 필요한 이유같은 brain dead settings 을 가지고 있습니다.
그러나, 그렇게 나쁜것만은 아닙니다. makers of GNU indent조차 K&R의 권위를 인정해서(GNU 사람들이 나쁜것은 아니고, 단지, 이 일에서만 몇가지 잘못했을 뿐)
"-kr -i8"옵션("K&R, 8 character indents"를 뜻함)만 주면 되기 때문입니다.

"indent"는 많은 옵션을 가지고 있고, 특히 comment re-formatting을 할때 당신은 맨페이지가 보고싶어질 것입니다. 그러나 기억하세요
: "indent"가 나쁜 프로그래밍의 해결법은 아닙니다.

Configuration-files
configuration 옵션들(arch/xxx/config.in, and all the Config.in files)에 있어서, 다소 다른 들여쓰기가 사용됩니다.

코드에선 3 레벨의 들여쓰기가 사용되지만, config-option에 의한 텍스트는 should have an indention-level of 2 to indicate dependencies.
후자의 경우 오직 bool/tristate 옵션만 적용합니다. 다른 옵션에 있어선, common sense만 사용됩니다. 예:


if [ "$CONFIG_EXPERIMENTAL"  "y" ]; then
  tristate 'Apply nitroglycerine inside the keyboard (DANGEROUS)' CONFIG_BOOM
  if [ "$CONFIG_BOOM" ! "n" ]; then
     bool '  Output nice messages when you explode' CONFIG_CHEER
  fi
fi


일반적으로, CONFIG_EXPERIMENTAL 은 안전성이 고려되지 않은 모든 옵션들을 감쌀것입니다. 쓸모없는 데이터로 알려진 모든 옵션들은 (DANGEROUS)로 나타내어질 것이고,
다른 Experimental 옵션들은 (EXPERIMENTAL)로 나타내어질 것입니다.

Data structures
안에서 생성되고 소멸되는 data structure가 단일 스레드 환경 외부에 visibility를 가진다면 그 data structure는 언제나 reference counts를 가져야 합니다.
커널 내부에선, garbage collection 이 존재하지 않으며 (그리고 커널 외부에선 garbage collection 이 느리고 비 효율적입니다),
그것은 당신이 모든 접근에 대하여 절대적으로 reference count를 해야한다는 것을 의미합니다.

Reference counting 은 당신이 locking을 피할 수 있고, 복수의 사용자가 그 자료구조에 병렬적으로 접근할 수 있게 해줍니다
- and not having to worry about the structure suddenly going away from under them just because they slept or did something else for a while.

locking은 reference counting의 대체가 아님을 유념하세요. reference counting이 memory management technique이면,
Locking은 data structures를 coherent하게 유지하는것입니다.

다른 "classes"의 유저들이 존재할때, 많은 data structures는 실제로 두 레벨의 reference counting을 가질 수 있습니다.
The subclass count는 subclass users의 갯수이며, subclass count가 0이 되면 decrements the global count just once.

이런 "multi-reference-counting"의 예를 memory management("struct mm_struct": mm_users and mm_count)와
파일시스템 코드("struct super_block": s_count and s_active)에서 발견할 수 있습니다.

Remember: 다른 스레드가 당신의 data structure를 발견할 수 있고, 당신이 거기에 reference count를 두지 않았다면, you almost certainly have a bug.

by zer0 | 2008/12/01 12:32 | □ Linux | 트랙백 | 덧글(1)
TimeZone 이야기

Global 환경에서 프로그래밍 하기 - Time Zone 이야기

한국에서 많은 분들이 프로그래밍을 하고 있지만 대부분 국내에서만 프로그래밍을 하시는 경우가 많아 글로벌 환경을 고려하여 프로그래밍을 해야 하는 경우 간혹 실수를 하시는 경우가 있습니다. 아무래도 평소 습관대로 프로그래밍을 하시기 때문에 발생되는 문제인데, 하지만 이럴 경우 나중에 큰 낭패를 보게 될 수도 있다고 생각합니다.

그 중 대표적인 것이 바로 Time Zone인데, 우리나라의 경우 단일 시간대에 전 국토가 분포하고 있기 때문에 다른 시간대에 가보는 것은 비행기를 타고 해외여행을 가는 정도밖에 없기 때문에 많은 분들에게 익숙하지 않아 생기는 문제이기도 합니다. 미국이나 러시아 같이 여러 시간대에 걸칠 정도로 넓은 국토를 가진 나라의 개발자들은 어려서부터 Time Zone에 대해 학교에서 배우기 때문에 Time Zone에 대해 상당히 익숙한 편이여서 이런 부분에 대해서는 사전에 고민을 많이 하고 프로그래밍을 하는 것 같습니다.

그렇다면 프로그래밍을 하는데 있어 Time Zone이 왜 문제가 될까요?

이 문제를 이해하기 위해서는 먼저 시간대와 관련된 몇 가지 개념을 알고계셔야 하는데, 시간대와 관련한 중요한 개념은 시스템 타임, 유저 타임 그리고 지리적 타임이 있습니다. 마지막으로 언급된 지리적 타임의 경우 조금 예외적인 경우에 사용되기 때문에 시스템 타임과 유저 타임의 2가지를 위주로 간략하게 설명 드리겠습니다. 시스템 타임은 바로 서버가 운영되는 곳의 Time Zone을 의미하여, 두 번째로 언급한 유저타임은 사용자가 컴퓨터를 사용하는 곳의 Time Zone을 의미합니다. 예를 들어 한국에 서버가 놓여있고, 사용자가 미국에 있는 경우 미국의 사용자가 한국의 서버에 접속해서 일을 하는 것을 가정하시면 앞으로 제가 드릴 설명을 보다 잘 이해하시리라 생각합니다.

위의 예와 같은 경우 사용자가 데이터를 저장한다고 하면 어떤 시간을 기준으로 데이터를 저장해야 하는 것이 가장 바람직할 것인지에 대해 한번 생각하실 필요가 있습니다.

이 문제를 얼핏 생각하면 사용자 테이블에 칼럼 하나을 만들어서 해당 유저의 Time Zone을 기록하고, 데이터를 저장할 시점에 관련 데이터에 시스템 타임을 더해서 기록하면 될 것 같습니다. 하지만, 그렇게 할 경우 사용자가 데이터에 대한 쿼리를 보낼 때마다 시간 부분에 대한 Conversion이 이루어진 상태로 데이터가 검색이 되어야 하며, 이 때 항상 년도와 날짜에 대한 계산이 병행되어서 진행되어야 하는 문제가 발생합니다. 게다가 검색된 데이터를 사용자 기준으로 보여주기 위해서는 사용자에게 보내기 전 사용자 기준의 Time Zone으로 Conversion 해야 하는 작업이 진행되어야 합니다. 그래서, 이렇게 설계를 할 경우 상당히 번거로울 뿐만 아니라 조금만 잘못 생각하면 엉뚱한 데이터를 보여줄 가능성이 매우 높다고 하겠습니다.

또한, 앞서 언급한 문제를 해결하기 위해 시스템 타임과 유저타임을 같이 데이터베이스에 저장하면 쉽게 해결될 것처럼 보이지만 데이터베이스에 저장되어야 하는 데이터가 많을 경우 저장공간을 많이 차지하게 되어 좋은 솔루션이 될 수 없는 경우가 있습니다. 게다가 설사 이렇게 구성을 한다고 하더라도 서버에서 돌아가는 배치작업이 생기는 경우에는 사용자 별로 처리되기가 힘들어 결국 시스템 타임으로 데이터가 저장되는 경우가 발생하며, 이럴 경우 시간처리에 대한 부분이 각기 다르게 처리가 되기 때문에 자칫 실수할 경우 문제가 매우 심각해집니다. 따라서, Time Zone과 관련된 부분은 설계 시 상당한 고려를 해야 하며, 그렇지 않고 개발이 된 경우에는 운영 시 상당한 어려움을 겪을 수 밖에 없게 됩니다.

한국은 이미 여러 부분에서 국제화되어 있고 이러한 변화가 점차 심화될 것이기 때문에 앞으로 국내의 많은 프로그래머 분들이 해외로 나가실 일이 더 많아질 것이라고 생각되는데, 혹시라도 국제화 프로그래밍을 하실 때 제가 드린 이야기를 한번쯤 고려해서 프로그래밍을 하신다면 좀 더 좋지않을까 하는 마음에서 이 글을 써 봅니다.
by zer0 | 2008/11/25 21:12 | 트랙백 | 덧글(1)
스마트 플레이스 류한석님 컬럼 中

히든 챔피언의 성공 비결 10가지

지난 11월 3일 한국무역협회의 주관으로 ‘기업가정신 국제컨퍼런스’가 개최되었습니다. 기업가정신(entrepreneurship)은 시대와 사회에 따라 다르게 정의될 수 있으나, 기본적으로 ‘미래에 대한 통찰력을 갖고서 새로운 것에 과감히 도전하는 혁신적이고 창의적인 정신’이라고 정의 할 수 있습니다. 그리고 기업가정신에는 이윤 창출과 사회적 책임이라는 전제가 깔려있습니다.
 
최근 대기업의 사회적 책임과 벤처기업의 활성화에 대한 시대적 요구가 커짐에 따라, 기업가정신에 대한 관심도 함께 증대되고 있습니다. 그렇지만 기업가정신 국제컨퍼런스의 전반적인 내용은 그리 호의적으로 평가하기 힘들었습니다.
 
기조강연에서 위키피디아의 창립자인 지미 웨일즈는 기업가정신에 대한 내용은 전혀 없이 그저 위키피디아에 대한 소개 내지는 자랑만 했고, 주제 발표에서 노부호 서강대 교수는 “중소기업에 지원해봐야 효과가 없으니 대기업이 중요하며 대기업 규제를 완전 철폐해야 한다”는 신자유주의적 경제논리를 폈습니다. 경제5단체 주도로 개최된 행사라서 중소기업 중심의 사고나 배려는 거의 읽을 수 없었습니다.
 
그렇지만 마지막 발표자로 나선 헤르만 지몬의 강연 덕분에 그나마 이번 컨퍼런스의 주제 의식이 살아날 수 있었습니다. 헤르만 지몬은 ‘히든 챔피언’이라는 서적으로 널리 알려진 경영학자이며, 현재 지몬-쿠퍼앤파트너스를 경영하고 있기도 합니다.
 
헤르만 지몬의 ‘히든 챔피언’ 강연 중 주요 사항들을 제 코멘트와 함께 전달해 드리겠습니다.
 
히든 챔피언(Hidden Champion)이란 세계시장에서 톱3 안에 들면서, 매출이 40억 달러 이하이고, 일반에게 잘 알려지지 않은 기업을 의미합니다. 한마디로 탄탄한 알부자 기업인 것이죠.
 
그가 꼽은 한국의 히든 챔피언들은 절삭공구를 생산하는 YG1(세계시장 1위, 세계시장점유율 60%), 모토사이클 헬멧을 생산하는 HJC(세계시장 1위, 점유율 20%), 완구를 생산하는 오로라월드(세계시장 3위, 점유율 5%), 헤어드라이어를 생산하는 유닉스전자(세계시장 2~3위, 점유율 25%) 등입니다.
 
그는 히든 챔피언들의 성공 비결을 오랫동안 연구했는데, 그가 밝힌 히든 챔피언의 성공 비결, 그리고 그로부터 젊은 기업가들이 배울 점은 다음과 같습니다. (하단의 내용은 독자들이 이해하기 쉽도록 제가 재정리한 것이라서 헤르만 지몬의 강의 내용과는 일부 차이가 있음을 밝힙니다.)
 
1. 그들은 대망을 품고 있다. 야망을 갖고 있다.
 
2. 그들은 단지 한가지 일을 하고, 그것을 다른 어떤 누구보다 더 잘한다.
 
3. 그들은 최상급의 가치를 제공한다. 높은 ‘수평적 통합’과 깊은 ‘밸류 체인’을 통해 유니크한 제품을 생산함으로써, 고객이 그들의 제품이 없이는 아무 것도 할 수 없도록 만든다.

 
높은 수평적 통합과 깊은 밸류 체인이라는 개념이 언뜻 이해가 안되실 듯 한데, 식기세척기를 생산하는 한 업체의 사례를 보시면 이해가 쉬울 겁니다.

 
4. 그들은 탁월한 경쟁력을 바탕으로 글로벌화함으로써, 성장의 부스터를 단다.
 
5. 일반 기업들에 있어 매출액 대비 R&D 지출이 3~4%인데 반해, 히든 챔피언은 6% 수준이며, 그들 중 1/3은 9% 이상을 R&D에 지출한다.

 
그들은 마켓과 기술 양쪽에 지속적인 혁신을 추구합니다. 어려운 시절을 버티고 살아남은 CEO들의 공통점은 바로 “R&D를 사랑하는 것”이라고 합니다.
 
6. 그들은 톱 고객들에 집중한다.
 
그들은 톱 고객을 명확히 정의하고 톱 고객의 요구와 변화에 집중합니다.
 
7. 그들의 전략은 가치에 기반하며 가격에 기반하지 않는다.
 
그들은 오히려 10~15% 높은 가격을 유지하며, 가격 전쟁을 피합니다.
 
8. 그들은 높은 퍼포먼스를 추구하는 문화를 갖고 있다.

즉, 직원들이 자발적으로 열심히 그리고 즐겁게 일하며 높은 성과를 달성하는 문화입니다.
 
9. 그들의 CEO는 원칙을 지키되 디테일에 있어서는 유연성을 갖고 있으며, 큰 조직에서 젊은이와 여성들이 중요한 역할을 맡고 있다.

그들은 능력 위주의 조직 체계를 갖고 있습니다.
 
10. 그들은 보통의 기업들과 다르게 행동하며, 스스로의 철학과 원칙을 갖고서 자신만의 길을 간다.

 
10가지로 정리를 해보았습니다. 이에 대해, 어떻게 보면 뻔한 얘기라고 생각하는 분도 계시겠지만, 분명히 이것에는 성공 DNA의 본질이 담겨 있다고 생각합니다. 물론 주로 제조업 위주의 내용이라서 SW산업, 인터넷산업에는 안 맞는 부분도 있습니다. 그것은 감안해서 판단하세요.
 
끝으로 헤르만 지몬은 한국에 다음과 같은 조언을 했습니다.
 
첫째, 젊은 기업가들이 대망을 가져야 한다는 것.
둘째, 기술적 역량이 핵심이며, 그것에 마케팅과 글로벌라이제이션이 더해져야 한다는 것.
셋째, 대기업은 벤처를 도와야 하며, 분사(spin-off)를 지속적으로 해야 한다는 것.
 
룰을 따르는 것이 아니라, 룰을 만드는 그들. 히든 챔피언의 경쟁력을 통해 배울 점들이 많지 않습니까? 히든 챔피언은 계속 성장을 하여 언젠가는 빅 챔피언이 될 수도 있습니다.

챔피언을 꿈꾸는 분들과 이 글을 함께 나누고 싶습니다.
 
자신의 철학으로 자신만의 길을 가고 있는 멋진 분들을 위하여!
by zer0 | 2008/11/25 12:44 | [ 생 각 ] | 트랙백 | 덧글(0)
IP datagram 재조합에 관하여...

패킷이 잘게 쪼개지는 것은 두 가지로 나뉜다.

1. MTU 보다 큰 데이터를 전송하게 될 경우에 그 크기를 MTU사이즈보다 작게 나누어 보내는 것,
2. IP datagram 의 'IP 데이터' 를 전부 아주 작게 쪼개어 보내는 것. (fragrouter 이용)

1은 맨 처음 패킷에 tcp 헤더가 붙고 그 다음 부턴 ip 헤더와 실제 데이터(payload) 만으로 구성된 패킷을 보내게 된다.
보통의 경우에는 이렇게 된다.

2의 경우는 IP 데이터(ip헤더를 제외한 나머지..) 들을 잘게 쪼개어 보내게 되는데.. 이때 TCP 헤더도 잘게 쪼개어 전송되는 것이 1과 다르다.

IP 의 입장에서는 TCP 헤더 와 payload 는 데이터일 뿐이다.

어쨌든 IP 계층에서 패킷을 재조합 하는 루틴은 커널에 존재한다.

"ip_defag()"

a. ipq 큐에 불완전한 패킷(datagram)이 있다면 취소한다.
   제약조건으로는 timeout : 30s 이 지나면 큐를 해제한다.

b. 기존의 패킷을 찾거나 새로운 ipq 해쉬 큐를 가지고 fragments 를 쌓는다 (세션을 생성한다.)
 
c. fragment 들로부터 새로운 IP Datagram을 재조합한다.

d. ipq의 모든 fragment 를 제거한다.


ip_defrag의 동작은 위와 같다. 먼저 불완전한 패킷이 있다면 삭제, 새로 들어왔는지, 기존의 큐를 가지고 있는지 검사,
마지막패킷까지 완전히 수신하였다면 재조합하며, 큐는 폐기 한다.

그런데 여기서 쪼개진 조각(패킷)들은 sk_buff 의 'end' 포인트 단에 이중 연결 리스트로 fragments sk_buff 를 가지게 된다.
맨 처음 도착한 패킷이 end 포인트 단이 아닌 sk_buff 의 메인 필드들을 사용하며, 그 이후의 것들은 end 포인트단이 연결리스트에 '주렁~주렁?'
매달리게 된다.
(struct  skb_shared_info 의 frag_list 를 이용하면 되시겠다.. frags[ ] 라는 배열로도 접근이 가능하긴한데... sk_buff 타입이 편해서
frag_list  를 이용하였다.)
IP 계층에서는 딱! 이렇게만 해준다..ㅡㅡ;


나머지는 아마도 TCP 가 알아서 해주겠지...(확인은 아직..허헛)
만약에 IP 계층에서 해야 한다면, ip 헤더의 fragments offset 을 이용하여 주렁주렁 매달린 것들을 재조합하여 main sk_buff에 복사하면
된다. 다 복사한뒤 ip checksum 은 채워주고 TCP도 해줘야 한다고 생각하였으나.... TCP 체크를 잘못 계산했는지..오히려 패킷 드랍한다..
젠좡..ㅡㅡ;

안해줘도 무방해서 넘겼다.




by zer0 | 2008/11/10 12:32 | 트랙백 | 덧글(0)
커널 2.4 커널 컴파일 시
커널 2.4 에서 컴파일 된 후 '커널 oops' 발생 할 때가 있다.

VFS ..어쩌구 저쩌구 할 때가 있는데..

CONFIG_BLK_DEV_RAMDISK_SIZE 가 4096 으로 낮게 설정되어 있어서 이런 현상이 발생한다.

사실, make bzImage 했을 때에 마지막 경고 메세지가 아래와 같이 뜨긴 했었지..

kernel img is too Big.... 어쩌구 저쩌구..

또 make menuconfig 에서 File system  -> jounaling file system support 도 함께 확인해 주자.

by zer0 | 2008/11/05 10:04 | □ Linux | 트랙백 | 덧글(0)
< 이전페이지 다음페이지 >