linuxfromscratch:12.1:072-package_management

차이

문서의 선택한 두 판 사이의 차이를 보여줍니다.

차이 보기로 링크

양쪽 이전 판 이전 판
다음 판
이전 판
linuxfromscratch:12.1:072-package_management [2024/06/10 15:51] – [8.2.1. 업그레이드 문제] baecylinuxfromscratch:12.1:072-package_management [2024/06/15 11:13] (현재) – [8.2.3. 여러 시스템에 LFS 배포하기] baecy
줄 28: 줄 28:
   * 패키지가 공유 라이브러리의 이전 이름과 새 이름 모두에 (직간접적으로) 링크되어 있는 경우(예: 패키지가 ''libfoo.so.2''와 ''libbar.so.1'' 모두에 링크되어 있고 후자는 ''libfoo.so.3''에 링크되어 있는 경우) 공유 라이브러리의 다른 개정판이 일부 기호 이름에 호환되지 않는 정의를 제시하므로 패키지가 오작동할 수 있습니다. 이 문제는 공유 라이브러리를 제공하는 패키지가 업그레이드된 후 이전 공유 라이브러리에 연결된 패키지의 일부(전부는 아님)를 다시 컴파일할 때 발생할 수 있습니다. 이 문제를 방지하려면 사용자는 공유 라이브러리에 연결된 모든 패키지를 가능한 한 빨리 업데이트된 버전(예: ''libfoo.so.2''에서 ''libfoo.so.3''으로)으로 다시 빌드해야 합니다. \\ \\    * 패키지가 공유 라이브러리의 이전 이름과 새 이름 모두에 (직간접적으로) 링크되어 있는 경우(예: 패키지가 ''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''이 이전 라이브러리 파일을 가리키도록 재설정되므로 버전 번호가 더 큰 "최신" 버전인 것처럼 보입니다. 패키지를 다운그레이드해야 하거나 작성자가 라이브러리 파일의 버전 관리 체계를 변경하는 경우 이러한 상황이 발생할 수 있습니다. \\ \\    * 공유 라이브러리가 포함된 패키지가 업데이트되었는데 라이브러리 이름은 변경되지 않고 라이브러리 파일의 버전 번호가 감소하는 경우(예: 라이브러리 이름은 여전히 ''libfoo.so.1''이지만 라이브러리 파일 이름은 ''libfoo.so.1.25''에서 ''libfoo.so.1.24''로 변경됨) 이전에 설치된 버전(이 경우 ''libfoo.so.1.25'')에서 라이브러리 파일을 제거해야 합니다. 그렇지 않으면 명령줄에서 직접 호출하거나 일부 패키지를 설치하여 호출한 **ldconfig** 명령이 심볼릭 링크 ''libfoo.so.1''이 이전 라이브러리 파일을 가리키도록 재설정되므로 버전 번호가 더 큰 "최신" 버전인 것처럼 보입니다. 패키지를 다운그레이드해야 하거나 작성자가 라이브러리 파일의 버전 관리 체계를 변경하는 경우 이러한 상황이 발생할 수 있습니다. \\ \\ 
-  * 공유 라이브러리가 포함된 패키지가 업데이트되고 라이브러리 이름은 변경되지 않았지만 심각한 문제(특히 보안 취약점)가 수정된 경우 공유 라이브러리에 연결된 실행 중인 모든 프로그램을 다시 시작해야 합니다. 업데이트가 완료된 후 //root//로 실행하는 다음 명령은 해당 라이브러리의 이전 버전을 사용하는 프로세스를 나열합니다(//libfoo//를 라이브러리 이름으로 바꾸세요). \\ <code lang=bash>grep -l 'libfoo.*deleted' /proc/*/maps | tr -cd 0-9\\n | xargs -r ps u</code> \\ 시스템에 액세스하는 데 OpenSSH를 사용 중이고 업데이트된 라이브러리에 연결되어 있는 경우, sshd 서비스를 다시 시작한 다음 로그아웃하고 다시 로그인한 후 앞의 명령을 다시 실행하여 삭제된 라이브러리를 사용하는 것이 없는지 확인해야 합니다. \\ \\ **systemd** 데몬(PID 1로 실행 중)이 업데이트된 라이브러리에 연결되어 있는 경우 //root// 사용자로 **systemctl daemon-reexec**을 실행하여 재부팅하지 않고도 다시 시작할 수 있습니다. \\ \\+  * 공유 라이브러리가 포함된 패키지가 업데이트되고 라이브러리 이름은 변경되지 않았지만 심각한 문제(특히 보안 취약점)가 수정된 경우 공유 라이브러리에 연결된 실행 중인 모든 프로그램을 다시 시작해야 합니다. 업데이트가 완료된 후 //root//로 실행하는 다음 명령은 해당 라이브러리의 이전 버전을 사용하는 프로세스를 나열합니다(//libfoo//를 라이브러리 이름으로 바꾸세요). \\ <code bash>grep -l 'libfoo.*deleted' /proc/*/maps | tr -cd 0-9\\n | xargs -r ps u</code> \\ 시스템에 액세스하는 데 OpenSSH를 사용 중이고 업데이트된 라이브러리에 연결되어 있는 경우, sshd 서비스를 다시 시작한 다음 로그아웃하고 다시 로그인한 후 앞의 명령을 다시 실행하여 삭제된 라이브러리를 사용하는 것이 없는지 확인해야 합니다. \\ \\ **systemd** 데몬(PID 1로 실행 중)이 업데이트된 라이브러리에 연결되어 있는 경우 //root// 사용자로 **systemctl daemon-reexec**을 실행하여 재부팅하지 않고도 다시 시작할 수 있습니다. \\ \\
   * 실행 프로그램이나 공유 라이브러리를 덮어쓰면 해당 프로그램이나 라이브러리의 코드나 데이터를 사용하는 프로세스가 충돌할 수 있습니다. 프로세스 충돌을 일으키지 않고 프로그램이나 공유 라이브러리를 업데이트하는 올바른 방법은 먼저 해당 프로그램이나 라이브러리를 제거한 다음 새 버전을 설치하는 것입니다. coreutils에서 제공하는 **install** 명령은 이미 이 기능을 구현하고 있으며 대부분의 패키지는 이 명령을 사용하여 바이너리 파일과 라이브러리를 설치합니다. 따라서 대부분의 경우 이 문제로 인해 어려움을 겪지 않을 것입니다. 하지만 일부 패키지(특히 BLFS의 SpiderMonkey)의 설치 프로세스는 파일이 있는 경우 해당 파일을 덮어쓰기 때문에 충돌이 발생할 수 있습니다. 따라서 패키지를 업데이트하기 전에 작업을 저장하고 실행 중인 불필요한 프로세스를 닫는 것이 더 안전합니다.   * 실행 프로그램이나 공유 라이브러리를 덮어쓰면 해당 프로그램이나 라이브러리의 코드나 데이터를 사용하는 프로세스가 충돌할 수 있습니다. 프로세스 충돌을 일으키지 않고 프로그램이나 공유 라이브러리를 업데이트하는 올바른 방법은 먼저 해당 프로그램이나 라이브러리를 제거한 다음 새 버전을 설치하는 것입니다. coreutils에서 제공하는 **install** 명령은 이미 이 기능을 구현하고 있으며 대부분의 패키지는 이 명령을 사용하여 바이너리 파일과 라이브러리를 설치합니다. 따라서 대부분의 경우 이 문제로 인해 어려움을 겪지 않을 것입니다. 하지만 일부 패키지(특히 BLFS의 SpiderMonkey)의 설치 프로세스는 파일이 있는 경우 해당 파일을 덮어쓰기 때문에 충돌이 발생할 수 있습니다. 따라서 패키지를 업데이트하기 전에 작업을 저장하고 실행 중인 불필요한 프로세스를 닫는 것이 더 안전합니다.
  
줄 35: 줄 35:
 ==== 8.2.2. 패키지 관리 기법 ==== ==== 8.2.2. 패키지 관리 기법 ====
  
-다음은 몇 가지 일반적인 패키지 관리 기법입니다. 패키지 관리자를 결정하기 전에 다양한 기법, 특히 각 기법의 단점에 대해 조사해 보세요.+다음은 몇 가지 일반적인 패키지 관리 기법입니다. 패키지 관리자를 결정하기 전에 다양한 기법, 특히 각 기법의 단점에 대해 조사해 보세요. \\ \\ 
  
 === 8.2.2.1. 모든 것이 내 머릿속에 있다! === === 8.2.2.1. 모든 것이 내 머릿속에 있다! ===
  
-네, 이것은 패키지 관리 기법입니다. 어떤 사람들은 패키지를 잘 알고 있고 각 패키지가 어떤 파일을 설치하는지 알고 있기 때문에 패키지 관리자가 필요하지 않습니다. 패키지가 변경될 때마다 전체 시스템을 다시 빌드할 계획이기 때문에 패키지 관리가 필요 없는 사용자도 있습니다.+네, 이것은 패키지 관리 기법입니다. 어떤 사람들은 패키지를 잘 알고 있고 각 패키지가 어떤 파일을 설치하는지 알고 있기 때문에 패키지 관리자가 필요하지 않습니다. 패키지가 변경될 때마다 전체 시스템을 다시 빌드할 계획이기 때문에 패키지 관리가 필요 없는 사용자도 있습니다. \\ \\
  
 === 8.2.2.2. 별도의 디렉터리에 설치 === === 8.2.2.2. 별도의 디렉터리에 설치 ===
줄 47: 줄 47:
 PATH, MANPATH, INFOPATH, PKG_CONFIG_PATH, CPPFLAGS, LDFLAGS와 같은 환경 변수와 구성 파일 /etc/ld.so.conf는 /opt/foo-x.y의 해당 하위 디렉터리를 포함하도록 확장해야 할 수 있습니다. PATH, MANPATH, INFOPATH, PKG_CONFIG_PATH, CPPFLAGS, LDFLAGS와 같은 환경 변수와 구성 파일 /etc/ld.so.conf는 /opt/foo-x.y의 해당 하위 디렉터리를 포함하도록 확장해야 할 수 있습니다.
  
-이 방식은 BLFS 책에서 매우 큰 패키지를 설치하여 쉽게 업그레이드할 수 있도록 하는 데 사용됩니다. 패키지를 몇 개 이상 설치하면 이 체계를 관리할 수 없게 됩니다. 그리고 일부 패키지(예: Linux API 헤더 및 Glibc)는 이 체계에서 제대로 작동하지 않을 수 있습니다. 이 체계를 시스템 전체에 사용하지 마세요.+이 방식은 BLFS 책에서 매우 큰 패키지를 설치하여 쉽게 업그레이드할 수 있도록 하는 데 사용됩니다. 패키지를 몇 개 이상 설치하면 이 체계를 관리할 수 없게 됩니다. 그리고 일부 패키지(예: Linux API 헤더 및 Glibc)는 이 체계에서 제대로 작동하지 않을 수 있습니다. 이 체계를 시스템 전체에 사용하지 마세요. \\ \\ 
  
 === 8.2.2.3. 심볼릭 링크 스타일 패키지 관리 === === 8.2.2.3. 심볼릭 링크 스타일 패키지 관리 ===
줄 54: 줄 54:
  
 설치 스크립트를 속여야 하므로 실제로는 /usr/pkg 계층 구조에 설치되어 있지만 패키지는 /usr에 설치되었다고 생각합니다. 이러한 방식으로 설치하는 것은 일반적으로 간단한 작업이 아닙니다. 예를 들어 libfoo-1.1 패키지를 설치한다고 가정해 보겠습니다. 다음 명령어를 사용하면 패키지가 제대로 설치되지 않을 수 있습니다. 설치 스크립트를 속여야 하므로 실제로는 /usr/pkg 계층 구조에 설치되어 있지만 패키지는 /usr에 설치되었다고 생각합니다. 이러한 방식으로 설치하는 것은 일반적으로 간단한 작업이 아닙니다. 예를 들어 libfoo-1.1 패키지를 설치한다고 가정해 보겠습니다. 다음 명령어를 사용하면 패키지가 제대로 설치되지 않을 수 있습니다.
-<code lang=bash>+<code bash>
 ./configure --prefix=/usr/pkg/libfoo/1.1 ./configure --prefix=/usr/pkg/libfoo/1.1
 make make
줄 60: 줄 60:
 </code> </code>
 설치는 작동하지만 종속 패키지가 예상대로 libfoo에 링크되지 않을 수 있습니다. libfoo에 링크하는 패키지를 컴파일하면 예상대로 /usr/lib/libfoo.so.1이 아닌 /usr/pkg/libfoo/1.1/lib/libfoo.so.1에 링크되어 있는 것을 볼 수 있습니다. 올바른 접근 방식은 DESTDIR 변수를 사용하여 설치를 지시하는 것입니다. 이 방법은 다음과 같이 작동합니다. 설치는 작동하지만 종속 패키지가 예상대로 libfoo에 링크되지 않을 수 있습니다. libfoo에 링크하는 패키지를 컴파일하면 예상대로 /usr/lib/libfoo.so.1이 아닌 /usr/pkg/libfoo/1.1/lib/libfoo.so.1에 링크되어 있는 것을 볼 수 있습니다. 올바른 접근 방식은 DESTDIR 변수를 사용하여 설치를 지시하는 것입니다. 이 방법은 다음과 같이 작동합니다.
-<code lang=bash>+<code bash>
 ./configure --prefix=/usr ./configure --prefix=/usr
 make make
 make DESTDIR=/usr/pkg/libfoo/1.1 install make DESTDIR=/usr/pkg/libfoo/1.1 install
 </code> </code>
-대부분의 패키지는 이 방법을 지원하지만 일부 패키지는 지원하지 않습니다. 호환되지 않는 패키지의 경우 수동으로 패키지를 설치해야 하거나 문제가 있는 일부 패키지를 /opt에 설치하는 것이 더 쉬울 수 있습니다.+대부분의 패키지는 이 방법을 지원하지만 일부 패키지는 지원하지 않습니다. 호환되지 않는 패키지의 경우 수동으로 패키지를 설치해야 하거나 문제가 있는 일부 패키지를 /opt에 설치하는 것이 더 쉬울 수 있습니다. \\ \\
  
 === 8.2.2.4. 타임스탬프 기반 === === 8.2.2.4. 타임스탬프 기반 ===
줄 71: 줄 71:
 이 기법에서는 패키지를 설치하기 전에 파일에 타임스탬프를 찍습니다. 설치 후 적절한 옵션과 함께 find 명령을 사용하면 타임스탬프 파일이 생성된 후 설치된 모든 파일의 로그를 생성할 수 있습니다. 이 방식을 사용하는 패키지 관리자는 install-log입니다. 이 기법에서는 패키지를 설치하기 전에 파일에 타임스탬프를 찍습니다. 설치 후 적절한 옵션과 함께 find 명령을 사용하면 타임스탬프 파일이 생성된 후 설치된 모든 파일의 로그를 생성할 수 있습니다. 이 방식을 사용하는 패키지 관리자는 install-log입니다.
  
-이 방식은 간단하다는 장점이 있지만 두 가지 단점이 있습니다. 설치 중에 파일이 현재 시간이 아닌 다른 타임스탬프로 설치되면 패키지 관리자가 해당 파일을 추적할 수 없습니다. 또한 이 방식은 패키지가 한 번에 하나씩 설치될 때만 사용할 수 있습니다. 두 개의 다른 콘솔에서 두 개의 패키지가 동시에 설치되는 경우 로그는 신뢰할 수 없습니다.+이 방식은 간단하다는 장점이 있지만 두 가지 단점이 있습니다. 설치 중에 파일이 현재 시간이 아닌 다른 타임스탬프로 설치되면 패키지 관리자가 해당 파일을 추적할 수 없습니다. 또한 이 방식은 패키지가 한 번에 하나씩 설치될 때만 사용할 수 있습니다. 두 개의 다른 콘솔에서 두 개의 패키지가 동시에 설치되는 경우 로그는 신뢰할 수 없습니다. \\ \\
  
 === 8.2.2.5. 설치 스크립트 추적 === === 8.2.2.5. 설치 스크립트 추적 ===
줄 79: 줄 79:
 설치 전에 미리 로드할 라이브러리를 가리키도록 LD_PRELOAD 환경 변수를 설정할 수 있습니다. 설치하는 동안 이 라이브러리는 cp, install, mv 등 다양한 실행 파일에 자신을 첨부하고 파일 시스템을 수정하는 시스템 호출을 추적하여 설치 중인 패키지를 추적합니다. 이 접근 방식이 작동하려면 모든 실행 파일이 suid 또는 sgid 비트 없이 동적으로 링크되어야 합니다. 라이브러리를 미리 로드하면 설치 중에 원치 않는 부작용이 발생할 수 있습니다. 따라서 몇 가지 테스트를 수행하여 패키지 관리자가 아무 것도 깨뜨리지 않고 적절한 파일을 모두 로깅하는지 확인하는 것이 좋습니다. 설치 전에 미리 로드할 라이브러리를 가리키도록 LD_PRELOAD 환경 변수를 설정할 수 있습니다. 설치하는 동안 이 라이브러리는 cp, install, mv 등 다양한 실행 파일에 자신을 첨부하고 파일 시스템을 수정하는 시스템 호출을 추적하여 설치 중인 패키지를 추적합니다. 이 접근 방식이 작동하려면 모든 실행 파일이 suid 또는 sgid 비트 없이 동적으로 링크되어야 합니다. 라이브러리를 미리 로드하면 설치 중에 원치 않는 부작용이 발생할 수 있습니다. 따라서 몇 가지 테스트를 수행하여 패키지 관리자가 아무 것도 깨뜨리지 않고 적절한 파일을 모두 로깅하는지 확인하는 것이 좋습니다.
  
-또 다른 방법은 설치 스크립트를 실행하는 동안 이루어진 모든 시스템 호출을 기록하는 스트레이스를 사용하는 것입니다.+또 다른 방법은 설치 스크립트를 실행하는 동안 이루어진 모든 시스템 호출을 기록하는 스트레이스를 사용하는 것입니다. \\ \\
  
 === 8.2.2.6. 패키지 아카이브 만들기 === === 8.2.2.6. 패키지 아카이브 만들기 ===
줄 89: 줄 89:
 종속성 정보를 포함하는 패키지 파일을 만드는 것은 복잡하며 LFS의 범위를 벗어납니다. 종속성 정보를 포함하는 패키지 파일을 만드는 것은 복잡하며 LFS의 범위를 벗어납니다.
  
-Slackware는 패키지 아카이브에 tar 기반 시스템을 사용합니다. 이 시스템은 의도적으로 더 복잡한 패키지 관리자처럼 패키지 종속성을 처리하지 않습니다. 자세한 내용은 [[https://www.slackbook.org/html/package-management.html|Slackware 패키지 관리]]를 참조하세요.+Slackware는 패키지 아카이브에 tar 기반 시스템을 사용합니다. 이 시스템은 의도적으로 더 복잡한 패키지 관리자처럼 패키지 종속성을 처리하지 않습니다. 자세한 내용은 [[https://www.slackbook.org/html/package-management.html|Slackware 패키지 관리]]를 참조하세요. \\ \\
  
 === 8.2.2.7. 사용자 기반 관리 === === 8.2.2.7. 사용자 기반 관리 ===
줄 106: 줄 106:
 </WRAP> </WRAP>
  
-마지막으로 [[.:167-using_grub_to_set_up_the_boot_process|10.4절 "GRUB을 사용하여 부팅 프로세스 설정하기"]]를 통해 새 시스템을 부팅할 수 있도록 설정해야 합니다.+마지막으로 [[.:167-using_grub_to_set_up_the_boot_process|10.4절 "GRUB을 사용하여 부팅 프로세스 설정"]]을 통해 새 시스템을 부팅 할 수 있도록 설정해야 합니다.
  
  
  • linuxfromscratch/12.1/072-package_management.1718034716.txt.gz
  • 마지막으로 수정됨: 2024/06/10 15:51
  • 저자 baecy