간혹, 특정 어플리케이션을 설치 후 실행 할 때 라이브러리 경로를 못 찾는 경우가 있다. (특히, 오라클, JAVA 등) 이러한 경우 LD_LIBRARY_PATH가 잘못 설정되어 문제가 되기도 하지만 LD_ASSUME_KERNEL 변수 때문에 발생하기도 한다.

Linux 커널의 Threads 구조 변천사

LD_ASSUME_KERNEL 변수는 Linux 커널의 Threads 라이브러리 구조의 변천사와 관련이 있다. Linux 커널 2.6 버전 이전에는 POSIX Threads에 적합하지 않은 스레드 구조를 가지고 있었으며 Linux Threads를 개선하기 위한 2가지의 프로젝트가 가동 되었다. 그 중 하나는 IBM쪽 개발자들에 의한 NGPT (Next Generation POSIX Threads)이었고 다른 하나는 Redhat 개발자들에 의한 NTPL(Native POSIX Thread Library) 였다.결과적으로 NGPT는 사라지고 NTPL이 Redhat 9이 릴리즈 되면서 소개가 되었다. 하지만, 문제는 여기에서 발생한다.

과거 자체적인 구조의 Threads 라이브러리를 가지고 있던 Linux를 개선하기위해 NTPL이 소개되었지만 기존 소프트웨어와 NTPL이 호환되지 않는 문제점이 발생하였다. 따라서, Redhat 9이 릴리즈 될 무렵에 3가지 구조의 Threads 라이브러리를 제공하게 되었는데

  • /lib/tls/libpthread.so (Kernel 2.4.20 NPTL)
  • /lib/i686/libpthread.so (Kernel 2.4.1의 비교적 최신 LinuxThreads - 32bit 기준)
  • /lib/libpthread.so (Kernel 2.2.5의 오래된 LinuxThreads)

이렇게 3가지의 라이브러리를 제공한 것은 기존의 어플리케이션과 호환성을 위한 것이다. 대부분의 어플리케이션은 DSO(Dynamic Shared Object) 형태로 링커를 통해서 라이브러리를 호출하는 구조이기 때문에 여러 종류의 라이브러리를 제공하는 구조를 취할 수 밖에 없었다.

LD_ASSUME_KERNEL 변수의 의미

어플리케이션이 실행될 때 Dynamic Linker에 의해서 Shared Library를 링크하고 불러들이게 되는데 앞서 이야기한 대로 3가지 구조의 라이브러리가 존재하기 때문에 각 어플리케이션에 적합한 라이브러리를 링크할 필요성이 발생하였다.

※ 일반적으로 별도의 라이브러리를 링크하기 위해서는 LD_LIBRARY_PATH와 같은 변수를 사용한다. 앞서 이야기한 libpthread의 3가지 타입은 특수한 경우이다.

※ Dynamic Library 파일에는 해당 파일이 구동되기 위한 최소한의 OS ABI 버전 정보를 담고 있는데 (.note.ABI-tag로 불리우는 ELF note 섹션) 특정 라이브러리에 대해서 아래와 같은 명령으로 확인해 볼 수 있다. (아래는 RHEL5에서 실행한 결과)

$ eu-readelf -n /lib/libc-2.5.so
Note section [ 1] '.note.ABI-tag' of 32 bytes at offset 0x174:
  Owner          Data size  Type
  GNU                   16  VERSION
    OS: Linux, ABI: 2.6.9

3가지 구조의 라이브러리를 찾아가기 위해서 LD_ASSUME_KERNEL 이란 변수가 사용되게 되었고 이 변수를 해당 라이브러리의 ABI 버전으로 지정하여 적합한 라이브러리를 찾아가도록 지정하는 것이다.

LD_ASSUME_KERNEL의 필요성?

결론적으로 이야기하면 현재의 Linux에서는 보통의 경우 해당 변수가 필요하지 않다. (현재는 GNU C 라이브러리에 NTPL이 완전히 통합되어 있다) 이러한 변수가 필요한 어플리케이션(최신버전의 Oracle에 대해서는 잘 모르기 때문에 확답하긴 어렵지만 적어도 9i 시절의 Oracle의 경우는 해당 변수가 필요하였다) 을 사용해야하는 경우가 아닌이상 필요없는 변수이다.

만약, 필요성이 없음에서 설정되어서 문제를 일으킨다면 간단히 주석처리해버리자. 보통 .bash_profile, .cshrc과 같은 환경설정 파일에 등록되어있을 것이다.

요즘 Linux에서 LD_ASSUME_KERNEL을 사용하면 어떻게 되는지 궁금한 분들은 아래와 같은 명령을 실행해보면 된다.

$ LD_ASSUME_KERNEL=2.4.20 ls

마무리..

어찌보면 추억의 변수명이다. (요즘도 화두가 되는지는 모르겠다) 잊고 있던 변수명인데 오라클을 설치 중에 기본 명령도 안먹는 증상이 발생한다는 문의를 받고 확인하던 중에 발견하고 이 기회에 간단히 정리해 보았다.