336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

0123


뭐가 어찌되었던 처음으로 실려본 내 사진과 글들

그리고 자세잡는것부터 표정까지 모든게 어려웠던 사진 모델되기...

12월호에 실린다는데 무척 궁금하기만 할뿐

ㅋㅋㅋ









'끄적임' 카테고리의 다른 글

영광의 11월  (0) 2008.12.12
2008 공개 SW 공모대전 대상받던날  (0) 2008.12.11
Going to San Francisco  (1) 2008.11.09
100달러 지폐의 가치 -좋은생각 中...  (0) 2008.05.26
너에게 묻는다 - 안도현  (0) 2008.05.20
336x280(권장), 300x250(권장), 250x250, 200x200 크기의 광고 코드만 넣을 수 있습니다.

미국 도착후 첫 수업은 테드와 시작 되었다.

테드는 File system 분야의 Maintainer이고 현제 IBM을 다니고 있으며 Linux FoundationCTO(Chief Technology Officer)로 취임이 예정되어 있을정도로 실력이 뛰어난 programmer 였고 그의 세미나를 듣는다는 사실에 몹시 흥분이 되었다.

 

처음으로 그가 말한 내용은 kernel 영역에서의 효율적인 interfaceuser 영역에서의 효율적인 interface를 제작하는 방법이었다.

그중에서도 리눅스 기본 규격(LSB, linux standard base)라는것이 있는데 이는 OS의 핵심부분인 커널에 여러 툴이나 기능이 부가된 배포 패키지의 형태로 유통이 되는데 이는 누구나 자유로이 작성이 가능하기 때문에, 개인이나 그룹, 기업 등이 작성한 패키지들이 전세계에 무수히 많이 존재하고 있다. LSB는 이들의 호환성을 확보하여 이들 팩키지용으로 작성된 어플리케이션 소프트가 다른 환경에서도 작동할 수 있도록 환경을 정비하기 때문에, Linux관련 개발자나 기업 등이 모여서 API나 라이브러리의 기본셋, 상호운용을 위한 지침을 정하는 것을 말한다.

 

다음으로 설명한 내용은 APIABI에 대한 내용이었다.

API를 이용하면 시스템콜을 직접 호출하지 않기 때문에 하드웨어에 의존적인 코드가 하나도 없기때문에 결국 API는 이식성을 위한 운영체제의 표준을 제공하는 수단이라고 정의할 수 있다. , API가 소스코드 수준의 호환성을 제공한다면 ABI는 바이너리 수준에서 호환성을 제공하고 ABI는 바이트 순서, 레지스터 사용, 시스템 콜 호출 방식, 링킹, 오브젝트 코드 포맷 등에 대한 규격을 제공한다. 이를테면, 시스템콜을 호출할 때 어떤 레지스터를 사용할 것인지, 오브젝트 코드 포맷을 ELF로 할 것인지를 결정하는 것이었고 이러한 규약이 정해져야 바이너리 호환을 제공할 수 있다는 내용이었다. , 앞으로는 windows에서처럼 이런 ABI를 많이 신경써야할 것이라는 추측도 덧붙여 설명하였다.


그리고 세미나 내용중 가장 중요한 내용중의 하나인 
Symbolic versioning
을 설명하였다.
과거의 단순한 공유 라이브러리 구현 때문에 겪었던 호환성 문제를 해결하는 방법이었다.
개념은 이해하기 쉬운데 하나의 라이브러리를 갖고 있고 그 라이브러리를 공유한다고 가정하자 하지만 프로그램이 printf()를 호출하려 할 때 작동 방식은 약간 복잡하다.
동적 링크 시스템 보다 정적 링크 시스템에서 프로세스가 더 간단하다. 정적 링크 시스템에서, 생성된 코드는 함수에 대한 레퍼런스를 처리한다. 링커는 이 레퍼런스를 함수를 로딩했던 실제 주소로 교체한다. 따라서 결과 바이너리 코드는 올바른 주소를 적재적소에 갖게 되는 것이다. 그런 다음, 코드가 실행되면 관련 주소로 점프(jump)한다. 프로그램의 어떤 지점에서 실제로 레퍼런스 되는 객체들에서만 링크할 수 있기 때문에 관리가 간단하다.
하지만 대부분의 공유 라이브러리들은 동적으로 링크 된다. 이것이 의미하는 바는 크다. 함수가 호출될 때 실제로 어떤 주소에 그 함수가 있게 될지 미리 예견할 수 없다.
동적 링커(dynamic linker)는 링크 된 각 함수에 대해 상당량의 작업을 수행할 수 있기 때문에 대부분의 링커들은 게으르다. 이들은 함수가 호출될 때 그 작업을 실제로 끝낸다. C 라이브러리에는 천 개 이상의 외부에 보여지는 심볼들과, 거의 삼천 개 이상의 로컬 심볼 들이 있다. 많은 시간을 절약할 수 있다.
작동 방법은 Procedure Linkage Table (PLT)이다. 이것은 프로그램이 호출하는 모든 함수를 나열하고 있는 프로그램의 테이블이다. 프로그램이 시작되면 PLT는 각 함수용 코드를 포함하여 함수를 로딩했던 주소에 대한 런타임 링커를 쿼리한다. 그런 다음 테이블의 모든 엔트리를 채우고 그곳으로 옮겨간다. 각 함수가 호출될 때 PLT의 엔트리는 로딩된 함수로 단순히 직접 점프한다.
하지만 여분의 인다이렉션 레이어를 남겨둔다는 것을 기억해야 한다. 각 함수 호출은 점프를 통해 테이블로 바뀐다.
또, 호환성은 관계만을 위한 것은 아니다.
링크하는 것으로 완료한 라이브러리는 이것이 호출하는 코드와 호환되도록 해야 한다. 정적으로 링크 된 실행파일이 있다면 변경될 것이 없다. 동적 링크라면 보장 못한다.
이때, 버전 숫자러 해결이 가능하다. 프로그램이 라이브러리로 링크 되면 버전 숫자를 갖게 된다. 동적 링커는 매칭(matching) 버전 숫자를 검사할 수 있다. 라이브러리가 변경되면 버전 숫자는 맞지 않을 것이고 프로그램은 새로운 버전의 라이브러리로 링크 되지 않을 것이다. 하지만 동적 링크의 강력한 장점들 중 하나는 버그를 픽스하는데 있다. 라이브러리에서 버그를 픽스하고 그 픽스를 활용하기 위해 많은 프로그램들을 재컴파일 할 필요가 없다면 참 좋은 것이다. 가끔은 새 버전으로 링크해야 할 때도 있다.
불행히도 새로운 버전으로 링크해야 하는 경우도 있고, 어떤 경우는 오래된 버전을 구수해야 한다. 해결책은 있다. 두 종류의 버전 숫자이다.

    메이저 넘버(major number)는 라이브러리 버전들 간 잠재적 비호환성을 나타낸다.
    마이너 넘버(minor number)는 버그 픽스들만을 나타낸다.

대부분의 경우 같은 메이저 넘버와 더 높은 마이너 넘버를 가진 라이브러리를 로딩하는 것이 안전하다; 높은 메이저 넘버를 가진 라이브러리를 로딩하는 것은 안전하지 못하다.
사용자들이 라이브러리 넘버와 업데이트를 트래킹하지 않도록 하려면 시스템은 많은 심볼릭 링크들이 있어야 한다. 일반적일 패턴은 다음과 같다.
libexample.so
는 다음으로 링크 된다.
libexample.so.N
이 시스템에서 N은 가장 높은 메이저 버전 숫자이다.
지원되는 모든 메이저 버전 넘버들은,
libexample.so.N
다음으로 링크 된다.
libexample.so.N.M
M은 가장 큰 마이너 버전 넘버이다.
따라서 -lexample을 링커에 지정하면 최근 버전에 대한 심볼릭 링크인 libexample.so를 찾는다. 한편, 기존 프로그램이 로딩되면 libexample.so.N을 로딩할 것이다. N은 원래 링크 되었던 버전이다.
디버그 하기 위해서는 우선 컴파일 방법을 알아야 한다!
공유 라이브러리로 문제들을 디버깅하기 위해서는 이들이 어떻게 컴파일 되는지를 알아두는 것도 유용하다.
전통적인 정적 라이브러리에서, 생성된 코드는 일반적으로 .a로 끝나는 이름을 가진 라이브러리 파일로 바인딩 되고 링커로 전달된다. 동적 라이브러리에서, 라이브러리 파일의 이름은 일반적으로 .so로 끝난다. 파일 구조는 약간 다르다.
일반적인 정적 라이브러리는 ar 유틸리티에서 만들어진 포맷에 있다. 이는 기본적으로 매우 단순한 아카이브 프로그램으로서 tar 와 비슷하지만 더 단순하다. 반면 공유 라이브러리들은 일반적으로 보다 복잡한 파일 포맷으로 저장된다.
현대적인 리눅스 시스템에서, 이는 일반적으로 ELF 바이너리 포맷((Executable and Linkable Format)을 의미한다. ELF에서, 각 파일은 하나의 ELF 헤더, 0 또는 세그먼트 그리고 0 또는 몇몇 섹션 등으로 구성된다. 세그먼트는 파일의 런타임 실행에 필요한 정보를 포함하고 있고, 섹션에는 링크와 재배치를 위한 중요한 데이터가 포함된다. 전체 파일에서 각 바이트는 한번에 단 한 섹션을 차지한다. 하지만 섹션에 들어가지 않은 고아 바이트가 있을 수 있다. 일반적으로 유닉스 실행파일에서 한 개 이상의 섹션들은 하나의 세그먼트에 둘러 쌓인다.
ELF 포맷은 애플리케이션과 라이브러리를 위한 스팩을 갖고 있다. 이 라이브러리 포맷은 객체 모듈의 아카이브 보다 훨씬 더 복잡하다.
링커는 심볼에 대한 레퍼런스들을 통해 소팅하면서 그들이 어떤 라이브러리들을 발견했는지를 기록한다. 정적 라이브러리에서 온 심볼들은 최종 실행파일에 추가된다; 공유 라이브러리에서 온 심볼들은 PLT에 놓여지고 PLT에 대한 레퍼런스들이 만들어진다. 일단 이 작업들이 수행되면 결과 실행 파일들은 런타임 시 로딩 될 라이브러리에서 검색할 심볼 리스트를 갖게 된다.
런타임 시, 애플리케이션은 동적 링커를 로딩한다. 사실, 동적 링커 자체는 공유 라이브러리들과 같은 종류의 버저닝을 사용한다. 예를 들어, SUSE Linux 9.1에서 /lib/ld-linux.so.2파일은 /lib/ld-linux.so.2.3.3에 대한 심볼릭 링크이다. 반면 /lib/ld-linux.so.1을 찾는 프로그램은 새 버전을 사용하려고 하지 않는다.
동적 링커는 재미있는 작업을 수행해야 한다. 프로그램이 원래 어떤 라이브러리(그리고 어떤 버전)에 링크 되었는지를 찾아서 이들을 로딩한다. 라이브러리 로딩은 다음으로 구성된다.

    찾기(시스템 상의 여러 디렉토리들 중 하나에 있을 수 있다)
    프로그램의 어드레스 공간으로 매핑하기
    라이브러리에 필요한 제로 메모리 블록 할당하기
    라이브러리의 심볼 테이블 attach하기

이 프로세스의 디버깅은 쉬운 일이 아니다. 여러 유형의 문제들을 경험하게 된다. 예를 들어, 동적 링커가 기존 라이브러리를 찾지 못하면 프로그램 로딩에 실패하게 된다. 원하는 모든 라이브러리를 찾았지만 심볼을 찾지 못하면 이 역시 실패한다. (하지만 그 심볼로 레퍼런스를 시도할 때까지 작동하지 않을 수도 있다)—이것은 일반적으로 드문 경우이고, 심볼이 없다면 초기 링크 때 공지된다.
동적 링커 검색 경로 변경하기
프로그램을 링크할 때, 런타임 시 검색할 추가 경로를 지정할 수 있다. gcc에서 문법은 -Wl,-R/path이다. 프로그램이 이미 링크 되었다면 환경 변수 LD_LIBRARY_PATH를 설정하여 이 작동을 변경할 수 있다. 일반적으로 이것은 애플리케이션이 시스템 디폴트의 일부가 아닌 경로를 검색하려고 할 때에만 필요하다. 대부분의 리눅스 시스템에서는 드문 경우이다. 이론상으로는 Mozilla 사용자들은 이 경로 세트로 컴파일 된 바이너리를 배포했지만 실행 파일을 시작하기 전에 라이브러리 경로를 적절히 설정하는 래퍼 스크립트를 배포하는 것을 더 선호한다.
라이브러리 경로 설정은 두 애플리케이션들이 비 호환 버전의 라이브러리를 요구하는 드문 경우에 대안을 제공할 수 있다. 특별한 버전의 라이브러리를 사용하여 디렉토리에서 한 개의 애플리케이션 검색을 갖는데 래퍼 스크립트가 사용될 수 있다. 최상의 솔루션이라고는 볼 수 없지만 어떤 경우에는 이보다 더 나은 것이 없다.
많은 프로그램에 경로를 추가해야 하는 급박한 경우라면 시스템의 디폴트 검색 경로를 변경할 수 있다. 동적 링커는 /etc/ld.so.conf를 통해 제어된다. 여기에는 기본적으로 검색할 디렉토리 리스트가 포함되어 있다. LD_LIBRARY_PATH에서 지정된 모든 경로는 ld.so.conf에 나열된 경로에 앞서 검색된다. 따라서 사용자들은 이들 설정을 오버라이드 할 수 있다.
대부분의 사용자들은 시스템 디폴트 라이브러리 검색 경로를 변경할 이유가 없다; 일반적으로 환경 변수는 검색 경로를 변경하는데 더 알맞다. 툴킷의 라이브러리들과 링크하는 것 또는 새로운 버전의 라이브러리에 대해 프로그램을 테스트 하는 경우가 그 예이다.
공유 라이브러리 문제를 해결하는 한 가지 유용한 툴은 ldd이다. 이 이름은 list dynamic dependencies의 앞 글자를 딴 것이다. 이 프로그램은 주어진 실행 파일 또는 공유 라이브러리를 찾아서 로딩해야 하는 공유 라이브러리가 무엇이고 어떤 버전이 사용되는 지를 파악한다.

마지막으로 테드가
Maintainer로 제작한 ext4에 대한 설명이다.
리눅스에는 다양한 파일시스템을 지원하는데 몇몇은 다른 운영체제를 위해 개발된 네트워크 파일 시스템이나 파일 시스템에 특화되어 있다. 하지만 놀랍게도 많은 파일 시스템이 리눅스 전용 파일 시스템으로 쓰인다. 루트와 시스템 디렉터리는 전용 파일시스템에 위치한다. 현재 이런 부류에 속하는 전용 파일 시스템은 ext2, ext3, ReiserFS, XFS, JFS, btrFS 등이 있다. 하지만 파일 시스템 설계와 개발이 계속 진행중이며, 현재 개발중인 가장 중요한 리눅스 전용 파일시스템은 ext4로, 리눅스 전용으로 개발되었던 원래 파일 시스템(ext)의 네번째 개정판이다.
리눅스 커널의 창시자인 리누즈 토발즈외에도 많은 커널 개발자들이 ext4가 ext3 보다 안전등 여러면에서 우려를 하였고 반대를 하였기 때문에 ext4는 ext3를 기반으로 개선하거나 더욱더 기능을 추가시킨 라이브러리이다.
새로운 기능을 ext3에 추가하면서 다음과 같은 여러가지 문제점이 나타났다.
    몇몇 새로운 기능은 과거 하위 호환성을 깨버린다.
    ext3코드는 점점 더 복잡해지고 유지보수가 어려워진다.
    변경 내역은 아주 안정적인 ext3를 안정돼지 못한 상태로 만들어 버릴지도 모른다.
이런 이유로 인해, 개발자들은 2006년 중순에 ext4개발을 ext3로 뷴리하기로 결정하였고, 분리 시점 이후로 ext4는 계속해서 작업이 진행되었지만, 큰 호흥을 얻지 못하다가 커널 2.6.19가 발표되면서, ext4는 주류 커널에 모습을 드러냈다.
ext4 파일시스템의 장점으로는
   
ext3는 32테라바이트 파일 시스템과 2테라바이트 파일을 지원하지만 실제로는 아키텍처와 시스템 설정에 따라 제약이 좀 더 커진다. 보통 2테라바이트 파일 시스템과 16기가바이트 파일까지 낮아진다. 반면에 ext4는 1024페타바이트(1엑사바이트) 파일 시스템16테라바이트 파일을 지원한다. 이는 평균적인 데스크톱 컴퓨터나 서버에서 (아직!) 중요하지 않을지도 모르지만, 대규모 디스크 배열을 사용하는 관리자에게는 중요하다.
    extents는 디스크 파일 기술자의 효율성을 개선하는 방법으로 특히 큰 파일을 삭제할 때 완료 시간을 줄인다.
    응용 프로그램이 실제로 사용하기 전에 디스크 공간을 할당할 필요가 있다면, 대다수 파일 시스템은 아직 사용하지 않은 디스크 공간에 0을 기록하는 방법으로 선행 할당 작업을 수행한다. ext4는 이런 작업 없이도 선행 할당이 가능하므로 몇몇 데이터베이스와 멀티미디어 도구 성능을 개선한다.
    ext4는 마지막 순간까지 디스크 공간 할당을 지연하므로 성능을 개선한다.
    ext3에서 하위 디렉터리를 단지 3만 2000개만 만들 수 있었지만 ext4에서는 제한이 없다.
    ext4는 저널 자료에 체크섬을 추가해 안정성과 성능을 개선했다.
    ext3에서 과도한 단편화가 일어나지 않음에도 불구하고 파일 저장 과정에서 어느 정도 단편화는 피하기 어렵다. ext4는 온라인 조각 모음을 제공해 전반적인 성능을 개선한다.
    ext4는 fsck가 점검 과정에서 사용하지 않는 부분을 건너뛰도록 자료 구조를 추가했으므로 시스템 점검 속력을 높인다
    ext3를 포함한 대다수 파일 시스템은 초 단위로 타임스탬프 자료를 기록한다. ext4는 나노초 단위로 정밀도를 높였다.
현재 개발중이기 때문에 검색이외의 부분은 ext3와 성능이 비슷하거 조금 앞서는 수준이고 Maintainer인 테드조차 확실한 원인파확을 못 했을 정도로 쉽지 않은 일이지만 2009년 초 Fedora10에 Built-in 될 예정이라 한다.

+ Recent posts