Prelink
The glibc upstream has removed prelink support in glibc-2.35, so support for prelinking cannot be kept. The core package sys-devel/prelink explained below, is no longer available from the Gentoo ebuild repository since Feb 23, 2022. See bug #579374 or bug #726062 for details.
이 안내서에서는 Portage 2.0.46 이상의 버전에서 지원하는 prelink를 어떻게 사용할 수 있는지 알려줍니다.
도입부
Prelink가 무엇이고, 어떻게 도움을 받을 수 있나요?
대부분의 일반 프로그램은 공유 라이브러리를 활용합니다. 이들 공유 라이브러리는 실행 시간에 메모리로 불러와야 하며 다양한 심볼 참조를 해석해야 합니다. 대부분의 작은 프로그램은 동적 연결을 매우 빠르게 처리합니다. 그러나 C++로 작성한 프로그램이고 수많은 라이브러리 의존성을 지녔다면, 동적 연결에 상당한 시간이 필요할 수 있습니다.
대부분의 시스템에서는, 라이브러리가 자주 바뀌지 않으며 프로그램을 실행할 때, 프로그램과의 연결 처리가 동시에 일어납니다. Prelink는 실행 파일에 미리 연결하는 것처럼 실행 파일에 연결하고 상태를 저장하는 장점을 취합니다.
사전 연동 처리는 프로그램의 시작 시간을 줄일 수 있습니다. 예컨대, 보통의 KDE 프로그램을 불러오는 시간은 최대 50% 가량 줄일 수 있습니다. 이 과정의 관리상 실행 파일에 미리 연결하기 위해 업그레이드한 라이브러리를 매번 사전 연동 처리를 위해 prelink를 다시 실행하기만 하면 됩니다.
prelink는 보안 강화 젠투에서 동작하지 않습니다. 각각의 프로젝트에서 공유 라이브러리의 주소 공간 대입을 바꾸려 하기 때문입니다. 다만 -R 옵션을 붙여서 prelink를 실행하면 강화 보호 차원에서 제공하는 라이브러리 기반 주소를 임의로 지정합니다.
요약
- 놀랍게도 바이너리와 동적 라이브러리와의 사전 연동은
prelink
를 실행하면 됩니다. 바이너리를 좀 더 빠르게 실행할 수 있게 바꿉니다. - 프로그램에 동적 라이브러리를 사전 연동한 후 의존 라이브러리가 바뀌면, 프로그램과 사전 연동을 다시 처리해야하며, 그렇지 않으면 속도상 이득을 잃게 됩니다. 이는 곧, 라이브러리를 업데이트하는 포티지로 꾸러미를 업데이트할 때마다 매번 사전 연동을 다시 처리해야 한다는 얘기입니다.
- 바이너리가 바뀌면 완전히 되돌릴 수 있습니다.
prelink
에 실행 취소 기능이 있습니다. - 포티지 현재 버전에서는
prelink
로 바이너리의 MD5sum과 mtime을 바꿔 처리할 수 있습니다. - make.conf 파일에서
FEATURES="prelink"
값을 설정할 필요가 없습니다. 포티지에서는 선연결 바이너리를 찾을 수 있으면 선연결을 자동으로 지원합니다.
prelink 설정
프로그램 설치
먼저 prelink
도구를 설치해야 합니다. 이머지 과정에서는 시스템에서 안전하게 사전 연동을 할 수 있게 자동으로 검증합니다.
root #
emerge --ask prelink
테스트에 실패하는 문제로 prelink 이머지 중에 수많은 사람이 오류를 만납니다. 테스트는 안전을 이유로 실시하지만, 테스트를 비활성화하면 prelink의 동작이 정의되지 않습니다. 이머지 오류는 보통 핵심 꾸러미, binutils, gcc, glibc에만 관련이 있습니다. 이들 꾸러미를 순서대로 다시 이머지해보십시오.
prelink
에 오류가 나타난다면 자체적으로 컴파일하고 시험( ./configure; make; make check ) 해보십시오. 치명적 오류가 발생하는 경우 시험 디렉터리에서 *.log 파일을 살펴볼 수 있습니다. 해당 로그 파일에 쓸만한 실마리가 나타날 수 있습니다.다른 시스템에서도 나타나는 이머지 오류를 재현하는 단계를 안다면, 버그질라 를 방문하여 이미 보고한 문제점이 아니라면 보고해주십시오.
시스템 준비
또한 CFLAGS/CXXFLAGS에 -fPIC를 설정하지 않았는지 확인하십시오. 설정했다면 해당 옵션을 빼고 시스템 전체를 빌드해야합니다.
설정
env-update를 실행하면 어떤 파일을 사전 연동 처리할 지 언급하는 /etc/prelink.conf 파일을 만듭니다.
root #
env-update
불행하게도 컴파일한 binutils 이전 버전에서는 사전 연동을 취할 수 없습니다. 대부분 프로그램은 미리 컴파일 한 상태로, /opt 경로에 바이너리 전용 꾸러미로 들어옵니다. 다음 파일은 해당 경로의 파일에 대해 사전 연동 처리할 수 없게 합니다.
PRELINK_PATH_MASK="/opt"
콜론을 사용하여 디렉터리 목록을 추가하거나 줄일 수 있습니다.
사전 연동
prelink 사용법
/etc/prelink.conf 에 주어진 디렉터리의 모든 바이너리를 미리 연동하려면 다음 명령을 사용합니다.
root #
prelink -amR
디스크 여분 용량이 부족할 때 전체 시스템에 대한 사전 연동 처리할 경우 바이너리가 잘릴 수 있는 현상이 보입니다. 결과적으로 시스템이 나가리가 납니다. file 또는 readelf 명령으로 바이너리 파일의 상태를 확인하십시오. 아니면, df -h 으로 미리미리 하드 드라이브의 여분 용량을 확인하십시오.
설명할 옵션: | |
---|---|
-a | "All": 모든 바이너리에 대한 사전 연동 처리 |
-m | 가상 메모리 영역을 보존합니다. 사전 연동할 라이브러리가 많을 경우 필요합니다. |
-R | Random -- 주소 정렬을 임의대로 처리합니다. 버퍼 오버플로우에 대비하여 보안성을 개선합니다. |
자세한 내용은 man prelink를 참고하십시오.
Prelink 크론 작업
sys-devel/prelink-20060213
이후 버전은 /etc/cron.daily/prelink에 크론 작업을 설치합니다. 활성화하려면 /etc/conf.d/prelink 설정 파일을 편집하십시오. 직접 명령을 실행하는 대신 매일 백그라운드에서 필요한 대로 prelink를 실행합니다.
prelink 실행 후 KDE 속도 개선
사전 연동을 실시하면 KDE 로딩 시간이 기가막히게 줄어들 수 있습니다. KDE에게 사전 연동 처리했음을 알리면 KDE 가동 속도를 올리는 kdeinit
(더이상 필요하지 않음) 로딩을 비활성화합니다.
/etc/env.d/*kdepaths*에서 KDE_IS_PRELINKED=1
를 설정하여 사전 연동 처리 여부를 알려주십시오.
사전 연동 제거
사전 연동 상태를 바꾸려 한다면 prelink를 머지 취소하기 전에 /etc/cron.daily 와 /etc/conf.d/prelink 에서 크론 작업에 대한 사전 연동을 제거해야합니다. 다음 모든 바이너리에 대한 사전 연동 관계를 제거해야합니다:
root #
prelink -au
마지막으로 prelink
꾸러미 자체를 제거하십시오:
root #
emerge -c prelink
알려진 문제와 해결 방안
이 문제는 모든 오브젝트 파일에 -fPIC 옵션을 빼고 공유 라이브러리를 제대로 컴파일하지 않았기 때문에 일어납니다.
해결하지 못했거나 해결할 수 없는 라이브러리는 다음과 같습니다:
- winex를 포함하는 wine 꾸러미의 라이브러리. MS 윈도우 실행 파일에 대한 사전 링크 처리로는 속도가 늘어나지 않습니다.
- media-video/mjpegtools의 라이브러리, /usr/lib/liblavfile-1.6.so.0 .
- Nvidia OpenGL 라이브러리 /usr/lib/opengl/nvidia/lib/libGL.so.*. PIC를 지원하지 않고 컴파일 했기 때문에 성능 문제가 있습니다.
문제가 나타난 라이브러리가 안보인다면 CFLAGS에 -fPIC
옵션을 넣어 적당히 패치하십시오.
시스템을 사전 연동 할 때 일부 바이너리가 더 이상 동작하지 않습니다
glibc는 100% 정적 바이너리만 있다고 간주하지 않습니다. glibc로 바이너리 정적 컴파일을 한다면, 여전히 다른 시스템 파일에 의존할 수도 있습니다. Dick Howell의 설명을 살펴보겠습니다:
"모든 파일을 다운로드하여 대상 시스템의 로컬 라이브러리에 의존하는 요소가 없다고 치자. 리눅스에선 불행하게도 GLIBC를 쓰지 않으면 답이 없을거다. 다양한 인증 데이터베이스, 네트워크 정보, 기타 등등에 접근하는"libnss"(어떤 사람은 네트워크 보안 시스템이라고 하는데 네임 서비스 전환 라이브러리임)가 있다. 애플리케이션 프로그램을 실제 머신의 네트워크 환경과는 별개로 설정한다고 치자. 괜찮게 보이긴 하지만 GLIBC에서 라이브러리를 불러오는데 문제가 일어난다. 개별 머신에서 설정했기에 "libnss"에 정적으로 연동할 수도 없다. 여기서 문제는, 다른 GLIBC 라이브러리에 주로 정적으로 연결하는 ... 분명히 말해서 "libpthread"라든가, "libm", "libc" 이런 라이브러리, 그리고 "libnss"의 비호환 함수를 호출하는 과정에서 오는 것 같다."
Prelink가 "prelink: dso.c:306: fdopen_dso: Assertion `j == k' failed." 메시지에서 멈춤
알려진 문제이며, 이 곳을 비슷하게 살펴볼 수 있습니다. 사전 연동은 UPX 형식으로 압축한 실행 파일에 대응할 수 없습니다. prelink-20021213에서는 사전 연동을 진행할 때 실행 파일을 숨겨두는 방법 외에는 문제를 해결할 방법이 없습니다. 이 문제를 쉽게 해결하는 방법은 위 부분을 참고하십시오.
grsecurity를 사용하는데 prelink가 동작하지 않는 것 같네요.
임의처리 mmap() 기반 환경을 사용하는 grsecurity 환경의 시스템에서 사전 연동을 처리하려면 /lib/ld-2.3.*.so에 대한 randomized mmap() base를 꺼야합니다. chpax 유틸리티로 해결할 수 있지만, 파일을 사용하지 않을 때(복구 CD로 부팅했을 경우) 처리해야합니다.
"prelink: Can't walk directory tree XXXX: Too many levels of symbolic links" 오류가 뜨면서 Prelink가 동작하지 않음
심볼릭 링크를 깊숙하게 중첩했습니다. 심볼릭 링크가 심볼릭 링크 자신을 가리키는 경우에 일어나는 일입니다. /usr/lib/lib -> lib 는 흔한 일입니다. 이 문제를 수정하려면 심볼릭 링크를 직접 만들거나 app-misc/symlinks 꾸러미에서 제공하는 유틸리티를 사용하면 됩니다:
root #
emerge symlinks
root #
symlinks -drv /
마무리
사전 연동 과정을 수행하면 상당히 많은 프로그램의 시작 속도를 확실하게 끌어올릴 수 있습니다. 지원 항목은 포티지에 내장했습니다. 사전 연동 과정은 어떤 여러가지 문제에 봉착했을 때 바이너리에 대한 사전 연동 상태를 언제든 되돌릴 수 있어 안전합니다. glibc 또는 사전 연동한 다른 라이브러리를 업데이트 할 때 prelink 를 실행해야 함을 기억해두십시오! 무탈을 빕니다!
This page is based on a document formerly found on our main website gentoo.org.
The following people contributed to the original document: Stefan Jones, John P. Davis, Jorge Paulo, Erwin, nightmorph
They are listed here because wiki history does not allow for any external attribution. If you edit the wiki article, please do not add yourself here; your contributions are recorded on each article's associated history page.