| Linux From Scratch - Version 12.1-systemd | ||
|---|---|---|
| Chapter 8. Installing Basic System Software | ||
| 이전 | 위로 / 처음으로 | 다음 |
| 개요 | Man-pages-6.06 |
패키지 관리는 LFS Book에 자주 요청되는 기능입니다. 패키지 관리자는 파일 설치를 추적하여 패키지를 쉽게 제거하고 업그레이드할 수 있게 해줍니다. 또한 좋은 패키지 관리자는 패키지를 재설치하거나 업그레이드할 때 사용자 구성을 유지하기 위해 구성 파일을 특별히 처리합니다. 이 섹션에서는 특정 패키지 관리자에 대해 이야기하거나 추천하지 않습니다. 다만 가장 많이 사용되는 기술과 그 작동 방식에 대해 소개할 뿐입니다. 여러분에게 가장 적합한 패키지 관리자는 이러한 기법 중 하나이거나 두 가지 이상의 기법을 조합한 것일 수도 있습니다. 이 섹션에서는 패키지를 업그레이드할 때 발생할 수 있는 문제에 대해 간략하게 언급합니다.
LFS 또는 BLFS에 패키지 관리자가 언급되지 않은 몇 가지 이유는 다음과 같습니다.
패키지 관리 주제에 대한 몇 가지 힌트가 있습니다. 힌트 프로젝트를 방문하여 어떤 솔루션이 여러분의 필요에 맞는지 확인하세요.
패키지 관리자를 사용하면 최신 버전이 출시될 때 쉽게 업그레이드할 수 있습니다. 일반적으로 LFS 및 BLFS 책에 있는 지침을 사용하여 최신 버전으로 업그레이드할 수 있습니다. 다음은 특히 실행 중인 시스템에서 패키지를 업그레이드할 때 주의해야 할 몇 가지 사항입니다.
libfoo.so.1인 공유 라이브러리를 설치하는 foo-1.2.3 패키지를 생각해 봅시다. 이 패키지를 libfoo.so.2라는 이름의 공유 라이브러리를 설치하는 최신 버전 foo-1.2.4로 업그레이드한다고 가정합니다. 이 경우, 새 라이브러리 버전을 사용하려면 libfoo.so.1에 동적으로 링크된 모든 패키지를 다시 컴파일하여 libfoo.so.2에 링크해야 합니다. 모든 종속 패키지가 다시 컴파일될 때까지 이전 라이브러리를 제거해서는 안 됩니다. libfoo.so.2와 libbar.so.1 모두에 링크되어 있고 후자는 libfoo.so.3에 링크되어 있는 경우) 공유 라이브러리의 다른 개정판이 일부 기호 이름에 호환되지 않는 정의를 제시하므로 패키지가 오작동할 수 있습니다. 이 문제는 공유 라이브러리를 제공하는 패키지가 업그레이드된 후 이전 공유 라이브러리에 연결된 패키지의 일부(전부는 아님)를 다시 컴파일할 때 발생할 수 있습니다. 이 문제를 방지하려면 사용자는 공유 라이브러리에 연결된 모든 패키지를 가능한 한 빨리 업데이트된 버전(예: libfoo.so.2에서 libfoo.so.3으로)으로 다시 빌드해야 합니다. libfoo.so.1이지만 라이브러리 파일 이름은 libfoo.so.1.25에서 libfoo.so.1.24로 변경됨) 이전에 설치된 버전(이 경우 libfoo.so.1.25)에서 라이브러리 파일을 제거해야 합니다. 그렇지 않으면 명령줄에서 직접 호출하거나 일부 패키지를 설치하여 호출한 ldconfig 명령이 심볼릭 링크 libfoo.so.1이 이전 라이브러리 파일을 가리키도록 재설정되므로 버전 번호가 더 큰 “최신” 버전인 것처럼 보입니다. 패키지를 다운그레이드해야 하거나 작성자가 라이브러리 파일의 버전 관리 체계를 변경하는 경우 이러한 상황이 발생할 수 있습니다. grep -l 'libfoo.*deleted' /proc/*/maps | tr -cd 0-9\\n | xargs -r ps u
다음은 몇 가지 일반적인 패키지 관리 기법입니다. 패키지 관리자를 결정하기 전에 다양한 기법, 특히 각 기법의 단점에 대해 조사해 보세요.
네, 이것은 패키지 관리 기법입니다. 어떤 사람들은 패키지를 잘 알고 있고 각 패키지가 어떤 파일을 설치하는지 알고 있기 때문에 패키지 관리자가 필요하지 않습니다. 패키지가 변경될 때마다 전체 시스템을 다시 빌드할 계획이기 때문에 패키지 관리가 필요 없는 사용자도 있습니다.
이 방법은 패키지를 관리하기 위한 특별한 프로그램이 필요 없는 간단한 패키지 관리 기법입니다. 각 패키지는 별도의 디렉터리에 설치됩니다. 예를 들어 패키지 foo-1.1은 /opt/foo-1.1에 설치되고 /opt/foo에서 /opt/foo-1.1로 심볼릭 링크가 만들어집니다. 새 버전 foo-1.2가 나오면 /opt/foo-1.2에 설치되고 이전 심볼릭 링크는 새 버전에 대한 심볼릭 링크로 대체됩니다.
PATH, MANPATH, INFOPATH, PKG_CONFIG_PATH, CPPFLAGS, LDFLAGS와 같은 환경 변수와 구성 파일 /etc/ld.so.conf는 /opt/foo-x.y의 해당 하위 디렉터리를 포함하도록 확장해야 할 수 있습니다.
이 방식은 BLFS 책에서 매우 큰 패키지를 설치하여 쉽게 업그레이드할 수 있도록 하는 데 사용됩니다. 패키지를 몇 개 이상 설치하면 이 체계를 관리할 수 없게 됩니다. 그리고 일부 패키지(예: Linux API 헤더 및 Glibc)는 이 체계에서 제대로 작동하지 않을 수 있습니다. 이 체계를 시스템 전체에 사용하지 마세요.
이 방식은 이전 패키지 관리 기법의 변형된 방식입니다. 각 패키지는 이전 방식과 동일하게 설치됩니다. 그러나 일반 패키지 이름을 통해 심볼릭 링크를 만드는 대신 각 파일을 /usr 계층 구조로 심볼릭 링크합니다. 이렇게 하면 환경 변수를 확장할 필요가 없습니다. 심볼릭 링크는 사용자가 직접 만들 수도 있지만, 많은 패키지 관리자가 이 방식을 사용하여 심볼릭 링크 생성을 자동화합니다. 널리 사용되는 몇 가지로는 Stow, Epkg, Graft, Depot 등이 있습니다.
설치 스크립트를 속여야 하므로 실제로는 /usr/pkg 계층 구조에 설치되어 있지만 패키지는 /usr에 설치되었다고 생각합니다. 이러한 방식으로 설치하는 것은 일반적으로 간단한 작업이 아닙니다. 예를 들어 libfoo-1.1 패키지를 설치한다고 가정해 보겠습니다. 다음 명령어를 사용하면 패키지가 제대로 설치되지 않을 수 있습니다.
./configure --prefix=/usr/pkg/libfoo/1.1
make
make install
설치는 작동하지만 종속 패키지가 예상대로 libfoo에 링크되지 않을 수 있습니다. libfoo에 링크하는 패키지를 컴파일하면 예상대로 /usr/lib/libfoo.so.1이 아닌 /usr/pkg/libfoo/1.1/lib/libfoo.so.1에 링크되어 있는 것을 볼 수 있습니다. 올바른 접근 방식은 DESTDIR 변수를 사용하여 설치를 지시하는 것입니다. 이 방법은 다음과 같이 작동합니다.
./configure --prefix=/usr
make
make DESTDIR=/usr/pkg/libfoo/1.1 install
대부분의 패키지는 이 방법을 지원하지만 일부 패키지는 지원하지 않습니다. 호환되지 않는 패키지의 경우 수동으로 패키지를 설치해야 하거나 문제가 있는 일부 패키지를 /opt에 설치하는 것이 더 쉬울 수 있습니다. 이 기법에서는 패키지를 설치하기 전에 파일에 타임스탬프를 찍습니다. 설치 후 적절한 옵션과 함께 find 명령을 사용하면 타임스탬프 파일이 생성된 후 설치된 모든 파일의 로그를 생성할 수 있습니다. 이 방식을 사용하는 패키지 관리자는 install-log입니다.
이 방식은 간단하다는 장점이 있지만 두 가지 단점이 있습니다. 설치 중에 파일이 현재 시간이 아닌 다른 타임스탬프로 설치되면 패키지 관리자가 해당 파일을 추적할 수 없습니다. 또한 이 방식은 패키지가 한 번에 하나씩 설치될 때만 사용할 수 있습니다. 두 개의 다른 콘솔에서 두 개의 패키지가 동시에 설치되는 경우 로그는 신뢰할 수 없습니다.
이 접근 방식에서는 설치 스크립트가 수행하는 명령이 기록됩니다. 두 가지 기법을 사용할 수 있습니다.
설치 전에 미리 로드할 라이브러리를 가리키도록 LD_PRELOAD 환경 변수를 설정할 수 있습니다. 설치하는 동안 이 라이브러리는 cp, install, mv 등 다양한 실행 파일에 자신을 첨부하고 파일 시스템을 수정하는 시스템 호출을 추적하여 설치 중인 패키지를 추적합니다. 이 접근 방식이 작동하려면 모든 실행 파일이 suid 또는 sgid 비트 없이 동적으로 링크되어야 합니다. 라이브러리를 미리 로드하면 설치 중에 원치 않는 부작용이 발생할 수 있습니다. 따라서 몇 가지 테스트를 수행하여 패키지 관리자가 아무 것도 깨뜨리지 않고 적절한 파일을 모두 로깅하는지 확인하는 것이 좋습니다.
또 다른 방법은 설치 스크립트를 실행하는 동안 이루어진 모든 시스템 호출을 기록하는 스트레이스를 사용하는 것입니다.
이 방식에서는 앞서 심볼릭 링크 스타일 패키지 관리 섹션에서 설명한 대로 패키지 설치가 별도의 트리로 위조됩니다. 설치가 완료되면 설치된 파일을 사용하여 패키지 아카이브가 생성됩니다. 그런 다음 이 아카이브를 사용하여 로컬 머신 또는 다른 머신에 패키지를 설치합니다.
이 접근 방식은 상용 배포판에 있는 대부분의 패키지 관리자에서 사용됩니다. 이 접근 방식을 따르는 패키지 관리자의 예로는 RPM(리눅스 표준 기본 사양(LSB)에 따라 요구됨), pkg-utils, 데비안의 apt, 젠투의 포티지 시스템 등이 있습니다. LFS 시스템에 이러한 스타일의 패키지 관리 방식을 채택하는 방법을 설명하는 힌트 에서 확인할 수 있습니다.
종속성 정보를 포함하는 패키지 파일을 만드는 것은 복잡하며 LFS의 범위를 벗어납니다.
Slackware는 패키지 아카이브에 tar 기반 시스템을 사용합니다. 이 시스템은 의도적으로 더 복잡한 패키지 관리자처럼 패키지 종속성을 처리하지 않습니다. 자세한 내용은 Slackware 패키지 관리를 참조하세요.
LFS에 고유한 이 체계는 Matthias Benkmann이 고안한 것으로, Hints 프로젝트에서 사용할 수 있습니다. 이 방식에서는 각 패키지가 표준 위치에 별도의 사용자로 설치됩니다. 패키지에 속한 파일은 사용자 ID를 확인하여 쉽게 식별할 수 있습니다. 이 접근 방식의 특징과 단점은 이 섹션에서 설명하기에는 너무 복잡합니다. 자세한 내용은 힌트를 참조하세요.
LFS 시스템의 장점 중 하나는 디스크 시스템의 파일 위치에 따라 달라지는 파일이 없다는 것입니다. 기본 시스템과 동일한 아키텍처를 가진 다른 컴퓨터에 LFS 빌드를 복제하려면 루트 디렉터리(기본 LFS 빌드의 경우 압축되지 않은 약 900MB)가 포함된 LFS 파티션에 tar를 사용하고 네트워크 전송 또는 CD-ROM/USB 스틱을 통해 해당 파일을 새 시스템으로 복사하고 확장하기만 하면 됩니다. 그 후 몇 가지 구성 파일을 변경해야 합니다. 업데이트해야 할 수 있는 구성 파일은 다음과 같습니다: /etc/hosts, /etc/fstab, /etc/passwd, /etc/group, /etc/shadow 및 /etc/ld.so.conf.
시스템 하드웨어와 원래 커널 구성의 차이에 따라 새 시스템에 사용자 지정 커널이 필요할 수 있습니다.
참고
유사하지만 동일하지 않은 아키텍처 간에 복사할 때 문제가 발생한다는 보고가 있었습니다. 예를 들어, 인텔 시스템의 명령어 세트는 AMD 프로세서의 명령어와 동일하지 않으며, 일부 프로세서의 최신 버전은 이전 버전에서 사용할 수 없는 명령어를 제공할 수 있습니다.
마지막으로 10.4절 "GRUB을 사용하여 부팅 프로세스 설정"을 통해 새 시스템을 부팅 할 수 있도록 설정해야 합니다.