8.2. Pakkehåndtering

Pakkebehandling er et ofte etterspurt tillegg til LFS-boken. En pakkebehandler lar deg spore installasjonen av filer som gjør det enkelt å fjerne og oppgradere pakker. En god pakkebehandler vil også håndtere konfigurasjonsfiler spesielt for å beholde brukerkonfigurasjonen når pakken installeres på nytt eller oppgraderes. Før du begynner å lure, NEI—denne delen vil ikke snakke om eller anbefale noen spesiell pakkebehandler. Det den gir er en oppsummering av de fleste populære teknikker og hvordan de fungerer. Den perfekte pakkebehandleren for deg vil kanskje være blant disse teknikkene eller kan være en kombinasjon av to eller flere av disse teknikker. Denne delen nevner kort problemer som kan oppstå ved oppgradering av pakker.

Noen grunner til at ingen pakkebehandler er nevnt i LFS eller BLFS inkludere:

Det er skrevet noen tips om emnet pakkehåndtering. Besøk Hints Project og se om en av dem passer ditt behov.

8.2.1. Oppgraderingsproblemer

En Pakkehåndterer gjør det enkelt å oppgradere til nyere versjoner når de blir utgitt. Generelt kan instruksjonene i LFS og BLFS bøkene brukes til å oppgradere til nyere versjoner. Her er noen punkter du bør være oppmerksom på når du oppgraderer pakker, spesielt på et kjørende system.

  • Hvis Linux kjernen må oppgraderes (for eksempel fra 5.10.17 til 5.10.18 eller 5.11.1), må ikke noe annet bygges om. Systemet vil fortsette å fungere bra takket være den veldefinerte grensen mellom kjernen og brukerområdet. Nærmere bestemt Linux API-deklarasjoner trenger ikke å (og bør ikke bli, se neste element) oppgraderes ved siden av kjernen. Du må starte systemet på nytt for å bruke den oppgraderte kjernen.

  • Hvis Linux API-deklarasjoner eller Glibc må oppgraderes til en nyere versjon, (f.eks. fra glibc-2.31 til glibc-2.32), er det tryggere å gjenoppbygge LFS. Selv om du kanskje kan gjenoppbygge alle pakkene i deres avhengighetsrekkefølge, anbefaler vi ikke det.

  • Hvis en pakke som inneholder et delt bibliotek oppdateres, og hvis navnet på biblioteket endres, vil eventuelle pakker dynamisk koblet til biblioteket måtte kompileres på nytt for å kunne kobles mot det nyere biblioteket. (Merk at det ikke er noen sammenheng mellom pakkeversjon og navnet på biblioteket.) Tenk for eksempel på en pakke foo-1.2.3 som installerer et delt bibliotek med navn libfoo.so.1. Hvis du oppgraderer pakken til en nyere versjon foo-1.2.4 som installerer et delt bibliotek med navn libfoo.so.2. I dette tilfellet, alle pakker som er dynamisk koblet til libfoo.so.1 må kompileres på nytt for å lenke imot libfoo.so.2 for å bruke den nye bibliotekversjonen. Du bør ikke fjerne det forrige biblioteker med mindre alle de avhengige pakkene er rekompilert.

  • Hvis en pakke er (direkte eller indirekte) er knyttet til både de gamle og nye navnene av et delt bibliotek (for eksempel pakken lenker til både libfoo.so.2 og libbar.so.1, mens sistnevnte linker til libfoo.so.3), pakken kan fungere feil fordi de forskjellige revisjonene av det delte biblioteket presenterer uforenlige definisjoner for noen symbolnavn. Dette kan være forårsaket av rekompilering av noen, men ikke alle, pakkene knyttet til et gammelt delt bibliotek etter at pakken som gir det delte biblioteket er oppgradert. For å unngå problemet, må brukere gjenoppbygge hver pakke koblet til et delt bibliotek med en oppdatert revisjon (f.eks. libfoo.so.2 til libfoo.so.3) så snart som mulig.

  • Hvis en pakke som inneholder et delt bibliotek oppdateres, og navnet på biblioteket ikke endres, men versjonsnummeret til bibliotek filen reduseres (f.eks. navnet på biblioteket beholdes ved navn libfoo.so.1, men navnet på bibliotekfilen er endret fra libfoo.so.1.25 til libfoo.so.1.24), bør du fjerne bibliotekfilen fra den tidligere installerte versjonen (libfoo.so.1.25 i dette tilfellet). Ellers, et ldconfig kommando (påkalt av deg selv fra kommandolinjen , eller ved installasjon av en pakke) vil tilbakestille symbolkoblingen libfoo.so.1 til å peke på den gamle bibliotekfilen fordi den ser ut til å ha en nyere versjon, ettersom versjonsnummeret er større. Denne situasjonen kan oppstå hvis du må nedgradere en pakke, eller hvis forfatterne endrer versjonsskjema for bibliotekfiler.

  • Hvis en pakke som inneholder et delt bibliotek oppdateres, og navnet på biblioteket ikke endres, men et alvorlig problem (spesielt en sikkerhetssårbarhet) er fikset, alle programmer som kjører koblet til det delte biblioteket bør startes på nytt. Følgende kommando, kjørt som root etter oppdateringen, vil liste opp hva som bruker de gamle versjonene av disse bibliotekene (erstatt libfoo med navnet på biblioteket):

    grep -l 'libfoo.*deleted' /proc/*/maps | tr -cd 0-9\\n | xargs -r ps u

    Hvis OpenSSH brukes for tilgang til systemet og det er koblet til det oppdaterte biblioteket, må du omstarte sshd tjenesten, deretter logg ut, logg på igjen, og kjør kommandoen igjen for å bekrefte at ingenting fortsatt bruker de slettede bibliotekene.

  • Hvis et binært eller et delt bibliotek overskrives, kan prosessene som bruker koden eller dataene i binærfilen eller biblioteket krasje. Den riktige måten å oppdatere et binært eller et delt bibliotek uten å forårsake at prosessen krasjer er å fjerne den først, og deretter installere den nye versjonen. install kommandoen levert av coreutils har allerede implementert dette og de fleste pakker bruker det til å installere binærfiler og biblioteker. Dette betyr at du ikke vil bli plaget av dette problemet mesteparten av tiden. Imidlertid er installasjonsprosessen for noen pakker (spesielt Mozilla JS i BLFS) bare å overskrive filen hvis den eksisterer og forårsaker et krasj, så det er tryggere å lagre arbeidet ditt og lukke unødvendige kjørende prosesser før du oppdaterer en pakke.

8.2.2. Pakkehåndteringsteknikker

Følgende er noen vanlige pakkehåndteringsteknikker. Før du ta en avgjørelse om en pakkeforvalter, gjør litt undersøkelser på de forskjellige teknikkene, spesielt ulempene ved den spesielle ordningen.

8.2.2.1. Alt er i hodet mitt!

Ja, dette er en pakkehåndteringsteknikk. Noen mennesker finner ikke behovet for en pakkehåndterer fordi de kjenner pakkene inngående og vet hvilke filer som er installert av hver pakke. Noen brukere trenger heller ikke pakkehåndtering fordi de planlegger å gjenoppbygge hele system når en pakke endres.

8.2.2.2. Installer i separate mapper

Dette er en forenklet pakkehåndtering som ikke trenger noe ekstra pakke for å administrere installasjonene. Hver pakke er installert i en egen mappe. For eksempel pakke foo-1.1 er installert i /usr/pkg/foo-1.1 og en symbolkobling er laget fra /usr/pkg/foo til /usr/pkg/foo-1.1. Når en ny versjon foo-1.2 kommer, blir den installert i /usr/pkg/foo-1.2 og den forrige symbolkoblingen erstattes av en symbolkobling til den nye versjonen.

Miljøvariabler som f.eks PATH, LD_LIBRARY_PATH, MANPATH, INFOPATH og CPPFLAGS må utvides til å inkludere /usr/pkg/foo. For mer enn noen få pakker, blir denne ordningen uhåndterlig.

8.2.2.3. Symlink Style Package Management

Dette er en variant av den tidligere pakkehåndteringsteknikken. Hver pakke er installert som i forrige skjema. Men i stedet for å lage symbolkoblingen via et generisk pakkenavn, er hver fil symlinket til /usr hierarkiet. Dette fjerner behovet for å utvide miljøvariablene. Selv om symbolkoblingene kan være opprettet av brukeren for å automatisere opprettelsen, har mange pakkeforvaltere blitt skrevet ved hjelp av denne tilnærmingen. Noen av de populære inkluderer Stow, Epkg, Graft og Depot.

Installasjonen må forfalskes, slik at pakken tror den er installert i /usr skjønt i virkeligheten er den installert i /usr/pkg hierarkiet. Installering på denne måten er vanligvis ikke en triviell oppgave. Tenk for eksempel på at du installerer en pakke libfoo-1.1. Følgende instruksjoner kan gjøre at pakken ikke installeres riktig:

./configure --prefix=/usr/pkg/libfoo/1.1
make
make install

Installasjonen vil fungere, men de avhengige pakkene kan ikke kobles til libfoo som du forventer. Hvis du kompilerer en pakke som lenker mot libfoo, kan du legge merke til at den er koblet til /usr/pkg/libfoo/1.1/lib/libfoo.so.1 i stedet for /usr/lib/libfoo.so.1 som du forventer. Den riktige tilnærmingen er å bruke DESTDIR strategien for å forfalske installasjon av pakken. Dette tilnærmingen fungerer som følger:

./configure --prefix=/usr
make
make DESTDIR=/usr/pkg/libfoo/1.1 install

De fleste pakker støtter denne tilnærmingen, men det er noen som ikke gjør det. For de ikke-kompatible pakkene kan det hende du må installere pakken manuelt , eller du kan finne ut at det er lettere å installere noen problematiske pakker inn i /opt.

8.2.2.4. Tidsstempelbasert

I denne teknikken blir en fil tidsstemplet før installasjonen av pakken. Etter installasjonen, en enkel bruk av find kommandoen med de riktige alternativene kan generere en logg over alle filene som er installert etter at tidsstempelfilen ble opprettet. En pakkebehandler skrevet med denne tilnærmingen er install-log.

Selv om denne ordningen har fordelen av å være enkel, har den to ulemper. Hvis filene under installasjonen er installert med et annet tidsstempel enn gjeldende tid, vil disse filene ikke spores av pakkebehandleren. Dessuten kan denne ordningen bare brukes når én pakke installeres om gangen. Loggene er ikke pålitelige hvis to pakker installeres på to forskjellige konsoller.

8.2.2.5. Sporing av installasjonsskript

I denne tilnærmingen, blir kommandoene som installasjonsskriptene utfører registrert. Det er to teknikker man kan bruke:

LD_PRELOAD miljøvariabelen kan settes til å peke på et bibliotek som skal forhåndslastes før installasjonen. Under installasjonen, sporer dette biblioteket pakkene som blir installert og fester seg til ulike kjørbare filer som f.eks cp, install, mv g sporing av systemets anrop som endrer filsystemet. For å få denne tilnærmingen til å virke, alle kjørbare filer må være dynamisk koblet uten suid- eller sgid-biten. Forhåndsinnlasting av biblioteket kan forårsake noen uønskede bivirkninger under installasjon. Derfor anbefales det at man utfører noen tester for å sørge for at pakkebehandlingen ikke bryter noe og logger alle passende filer.

Den andre teknikken er å bruke strace, som logger alle systemanrop som gjøres under utførelse av installasjonensskriptet.

8.2.2.6. Opprette pakkearkiver

I denne ordningen er pakkeinstallasjonen forfalsket til et separat tre som beskrevet i Symlink pakkebehandlingenen. Etter installasjon, opprettes et pakkearkiv ved hjelp av de installerte filene. Dette arkivet brukes deretter til å installere pakken enten på den lokale maskin eller kan til og med brukes til å installere pakken på andre maskiner.

Denne tilnærmingen brukes av de fleste pakkebehandlere som finnes i kommersielle distribusjoner. Eksempler på pakkeforvaltere som følger dette tilnærmingen er RPM (som for øvrig kreves av Linux Standard Base Specification), pkg-utils, Debian's apt, og Gentoo's Portage system. Et hint som beskriver hvordan du adopterer denne stilen av pakkehåndtering for LFS systemer ligger på https://www.linuxfromscratch.org/hints/downloads/files/fakeroot.txt.

Oppretting av pakkefiler som inkluderer avhengighetsinformasjon er kompleks og er utenfor omfanget av LFS.

Slackware bruker et tar basert system for pakke arkiv. Dette systemet håndterer med vilje ikke pakkeavhengigheter som mer komplekse pakkeforvaltere gjør. For detaljer om Slackware pakkebehandling, se https://www.slackbook.org/html/package-management.html.

8.2.2.7. Brukerbasert administrasjon

Denne ordningen, unik for LFS, ble utviklet av Matthias Benkmann, og er tilgjengelig fra Hints Project. I denne ordningen, er hver pakke installert som en separat bruker i standardplasseringer. Filer som tilhører en pakke identifiseres enkelt med å sjekke bruker-ID. Funksjonene og manglene ved denne tilnærmingen er for komplisert til å beskrive i denne delen. For detaljer, se hintene på https://www.linuxfromscratch.org/hints/downloads/files/more_control_and_pkg_man.txt.

8.2.3. Distribuere LFS på flere systemer

En av fordelene med et LFS system er at det ikke er noen filer som avhenger av plasseringen til filene på et disksystem. Kloning av et LFS bygg til en annen datamaskin med samme arkitektur som basissystemet er like enkelt som å bruke tar på LFS partisjonen som inneholder rotkatalogen (ca. 900MB ukomprimert for en standard LFS bygg), kopiere den filen via nettverksoverføring eller CD-ROM til det nye systemet og utvide den. Fra det tidspunktet må noen få konfigurasjonsfiler endres. Konfigurasjonsfiler som kanskje må oppdateres inkluderer: /etc/hosts, /etc/fstab, /etc/passwd, /etc/group, /etc/shadow, /etc/ld.so.conf, /etc/sysconfig/rc.site, /etc/sysconfig/network, og /etc/sysconfig/ifconfig.eth0.

En tilpasset kjerne må kanskje bygges for det nye systemet avhengig av forskjeller i systemmaskinvare og den originale kjernekonfigurasjonen.

[Note]

Note

Det har vært noen rapporter om problemer ved kopiering mellom lignende, men ikke identiske arkitekturer. For eksempel instruksjonssettet for et Intel-system er ikke identisk med en AMD-prosessor og nyere versjoner av enkelte prosessorer kan ha instruksjoner som ikke er tilgjengelige i tidligere versjoner.

Til slutt må det nye systemet gjøres oppstartbart via Section 10.4, “Bruke GRUB til å sette opp oppstartsprosessen”.