
Att skapa en backup-applikation som fungerar pÄ valfri distribution Àr en utmaning. För att sÀkerstÀlla att Veeam Agent för Linux fungerar pÄ distributioner frÄn Red Hat 6 och Debian 6 till OpenSUSE 15.1 och Ubuntu 19.04 mÄste man lösa en rad problem, sÀrskilt med tanke pÄ att programvaran inkluderar en kÀrnmodul.
Artikeln Àr baserad pÄ material frÄn presentationen pÄ konferensen .
Linux Àr inte bara ett av de mest populÀra operativsystemen. Det Àr i huvudsak en plattform dÀr man kan skapa nÄgot unikt, nÄgot eget. Tack vare detta finns det mÄnga distributioner av Linux, som skiljer sig Ät i uppsÀttningen av programkomponenter. HÀr uppstÄr ett problem: för att programvaran ska fungera pÄ vilken distribution som helst mÄste man ta hÀnsyn till varje distributions specifika egenskaper.
Paketchefer. .deb vs .rpm
LÄt oss börja med det uppenbara problemet med att distribuera produkten för olika distributioner.
Det mest typiska sÀttet att distribuera programvaruprodukter Àr att lÀgga upp ett paket pÄ ett arkiv sÄ att den inbyggda paketchefen i systemet kan installera det dÀrifrÄn.
Men vi har tvÄ populÀra paketformat: rpm och deb. Det betyder att vi mÄste stödja dem alla.
I vÀrlden av deb-paket Àr kompatibilitetsnivÄn förvÄnande. Samma paket installeras och fungerar lika bra bÄde pÄ Debian 6 och Ubuntu 19.04. Standarderna för att bygga paket och arbeta med dem, som infördes i de gamla Debian-distributionerna, förblir aktuella Àven i de trendiga Linux Mint och elementary OS. DÀrför rÀcker det med ett deb-paket för varje hÄrdvaruplattform för Veeam Agent för Linux.
Men i vÀrlden av rpm-paket Àr skillnaderna betydande. För det första, pÄ grund av att det finns tvÄ helt oberoende distributörer, Red Hat och SUSE, som inte behöver kompatibilitet. För det andra har dessa distributörer distributioner med teknisk support och experimentella. Mellan dem behövs inte heller kompatibilitet. Det leder till att vi har olika paket för el6, el7 och el8. Ett separat paket för Fedora. Paket för SLES11 och 12 och ett separat för openSUSE. Det största problemet Àr beroenden och paketnamn.
Beroendeproblem
TyvÀrr har samma paket ofta olika namn i olika distributioner. Nedan finns en ofullstÀndig lista över beroenden för paketet veeam.
För EL7:
För SLES 12:
- libblkid
- libgcc
- libstdc++
- ncurses-libs
- fuse-libs
- file-libs
- veeamsnap = 3.0.2.1185
- libblkid1
- libgcc_s1
- libstdc++6
- libmagic1
- libfuse2
- veeamsnap-kmp = 3.0.2.1185
Som resultat blir beroendelistan unik för distributionen.
Det kan bli vÀrre nÀr en uppdaterad version börjar dölja sig bakom det gamla paketnamnet.
Exempel:
I Fedora 24 har paketet uppdaterats ncurses frÄn version 5 till version 6. VÄr produkt var sammansatt med version 5 för att sÀkerstÀlla kompatibilitet med Àldre distributioner. För att kunna anvÀnda den gamla version 5 av biblioteket pÄ Fedora 24 var vi tvungna att anvÀnda paketet ncurses-compat-libs.
Som ett resultat dyker det upp tvÄ paket för Fedora, med olika beroenden.
Det blir intressantare. Efter en ny uppdatering av distributionen blir paketet ncurses-compat-libs med version 5 av biblioteket otillgÀngligt. För distributören Àr det kostsamt att dra de gamla biblioteken till den nya versionen av distributionen. Efter ett tag upprepades problemet Àven i SUSE-distributioner.
Som ett resultat var vissa distributioner tvungna att överge den explicita beroendet av ncurses-libs, och produkten fick justeras sÄ att den kunde fungera med vilken version av biblioteket som helst.
För övrigt finns det ingen metapaketering i den 8:e versionen av Red Hat python, som refererade till den gamla goda python 2.7. Det finns python2 och python3.
Alternativ till pakethanterare
Problemet med beroenden Àr gammalt och uppenbart. TÀnk bara pÄ Dependency hell.
Att förena olika bibliotek och applikationer sĂ„ att alla fungerar stabilt och inte konfliktar â det Ă€r i grunden den uppgift som varje Linux-distributör försöker lösa.
För att lösa detta problem försöker pakethanteraren Snappy frÄn Canonical. Grundidén Àr: applikationen körs i en isolerad och skyddad sandlÄda frÄn det underliggande systemet. Om applikationen behöver bibliotek följer de med applikationen.
Flatpak gör det ocksÄ möjligt att köra applikationer i sandlÄdan med hjÀlp av Linux Containrar. Idén om sandlÄdan anvÀnds Àven av AppImage.
Dessa lösningar gör att ett paket kan skapas för alla distributioner. I fallet med Flatpak kan installation och körning av applikationen ske Àven utan administratorns vetskap.
Huvudproblemet Àr att inte alla applikationer kan fungera i sandlÄdan. Vissa behöver direkt Ätkomst till plattformen. Jag behöver inte ens nÀmna kÀrnmoduler som Àr strikt beroende av kÀrnan och inte passar in i konceptet av sandlÄdan.
Ett annat problem Àr att de populÀra distributionspetrarna i företagsmiljöer frÄn Red Hat och SUSE Ànnu inte stöder Snappy och Flatpak.
DÀrför finns Veeam Agent for Linux inte pÄ inte .
Avslutningsvis angÄende paketförvaltare vill jag nÀmna att det finns ett alternativ att helt avstÄ frÄn paketförvaltare genom att kombinera binÀra filer och installationsscript i ett paket.
Ett sÄdant bundle möjliggör att skapa ett gemensamt paket för olika distributioner och plattformar, och att produktionen av en interaktiv installationsprocess görs med nödvÀndig anpassning. Jag har stött pÄ sÄdana paket för Linux endast frÄn VMware.
Uppdateringsproblem

Ăven om alla beroendeproblem Ă€r lösta kan programmet fungera olika pĂ„ samma distribution. Problemet ligger i uppdateringarna.
Det finns 3 uppdateringsstrategier:
- Den enklaste - att aldrig uppdatera. StÀllde in servern och glömde den. Varför uppdatera om allt fungerar? Problemen börjar vid första kontakten med supporten. Distributionens skapare stödjer endast den uppdaterade versionen.
- Man kan lita pÄ distributören och stÀlla in automatisk uppdatering. I sÄ fall Àr ett samtal till supporten troligt direkt efter en misslyckad uppdatering.
- Alternativet att manuellt uppdatera först efter att det har testats pÄ testinfrastruktur Àr det mest pÄlitliga, men ocksÄ det dyraste och mest arbetskrÀvande. Inte alla har rÄd med det.
Eftersom olika anvÀndare tillÀmpar olika uppdateringsstrategier, mÄste bÄde den senaste versionen och alla tidigare utgivningar stödjas. Detta komplicerar bÄde utvecklings- och testprocessen och ger mer huvudvÀrk för supporten.
MÄngfald av hÄrdvaruplattformar
Olika hÄrdvaruplattformar Àr ett problem som i stor utstrÀckning Àr specifikt för native-kod. Minst sagt mÄste man bygga binÀrer för varje stödd plattform.
I projektet Veeam Agent for Linux kan vi fortfarande inte stödja nÄgot RISC-relaterat.
Jag kommer inte att gÄ in pÄ det hÀr Àmnet i detalj. Jag kommer bara att ange de grundlÀggande problemen: plattformsberoende typer, som size_t, strukturer och byte order.
Statisk och/eller dynamisk lÀnkning

FrÄgan "Hur man lÀnkar till bibliotek - dynamiskt eller statiskt?" bör diskuteras.
Som regel anvÀnder C/C++-applikationer pÄ Linux dynamisk lÀnkning. Det fungerar utmÀrkt om applikationen Àr byggd specifikt för en viss distribution.
Om mÄlet Àr att tÀcka olika distributioner med en enda binÀrfil, mÄste man anpassa sig efter den Àldsta stödda distributionen. För oss Àr detta Red Hat 6. Den innehÄller gcc 4.4, som inte ens stöder standarden för C++11. .
Vi bygger vÄrt projekt med gcc 6.3, som fullt ut stöder C++14. Naturligtvis, i sÄ fall mÄste vi ta med libstdc++-biblioteket och boost med oss pÄ Red Hat 6. Det enklaste Àr att lÀnka med dem statiskt.
Men tyvÀrr gÄr det inte att lÀnka statiskt med alla bibliotek.
För det första, systembibliotek som libfuse, libblkid mÄste lÀnkas dynamiskt för att sÀkerstÀlla kompatibilitet med kÀrnan och dess moduler.
För det andra finns det en detalj med licenser.
GPL-licensen tillÄter i princip att lÀnka bibliotek enbart med öppen kÀllkod. MIT och BSD tillÄter statisk lÀnkning och tillÄter att inkludera bibliotek i projektet. Men LGPL verkar som inte motsÀger statisk lÀnkning, men krÀver att man tillhandahÄller filer som behövs för lÀnkning till allmÀnheten.
Generellt sett sÀkerstÀller anvÀndningen av dynamisk lÀnkning att man slipper att förse nÄgot.
Byggande av C/C++-applikationer
För att bygga C/C++-applikationer för olika plattformar och distributioner rÀcker det med att vÀlja eller bygga en passande version av gcc och anvÀnda krosskompilatorer för specifika arkitekturer, och samla hela bibliotekssortimentet. Detta arbete Àr fullt genomförbart men ganska besvÀrligt. Och det finns inga garantier för att valt kompilator och bibliotek kommer att ge en fungerande variant.
En uppenbar fördel: infrastrukturen förenklas kraftigt, eftersom hela byggprocessen kan utföras pÄ en och samma maskin. Dessutom Àr det tillrÀckligt att bygga en uppsÀttning binÀrfiler för en arkitektur och man kan paketera dem i paket för olika distributioner. SÄ hÀr byggs paketen för veeam för Veeam Agent för Linux.
I motsats till detta alternativ kan man helt enkelt förbereda en byggfarm, det vill sÀga flera maskiner för kompilering. Varje sÄdan maskin kommer att sÀkerstÀlla att applikationen kompileras och paketet byggs för en specifik distribution och viss arkitektur. I det hÀr fallet sker kompileringen med de verktyg som distributören har förberett. Det innebÀr att steget att förbereda kompilatorn och vÀlja bibliotek faller bort. Dessutom kan byggprocessen enkelt parallelliseras.
Det finns dock en nackdel med ett sÄdant tillvÀgagÄngssÀtt: för varje distribution inom samma arkitektur mÄste man kompilera sin egen uppsÀttning binÀra filer. En annan nackdel Àr att det krÀvs ett stort antal maskiner som behöver underhÄllas, samt att man mÄste avsÀtta mycket diskutrymme och RAM.
PÄ sÄ sÀtt byggs KMOD-paketet för kÀrnmodulen veeamsnap för Red Hat-distributioner.
Open Build Service
Kollegor frĂ„n SUSE har försökt att realisera en slags gyllene medelvĂ€g i form av en sĂ€rskild tjĂ€nst för att kompilera applikationer och bygga paket â .
Det Àr i grunden en hypervisor som skapar en virtuell maskin, installerar alla nödvÀndiga paket i den, utför kompileringen av applikationen och bygger paketet i denna isolerade miljö, efter vilket den virtuella maskinen frigörs.

Den schemalÀggare som implementerats i OpenBuildService kommer sjÀlv att avgöra hur mÄnga virtuella maskiner den kan starta för optimal hastighet vid paketbyggande. Den inbyggda signeringsmekanismen kommer automatiskt att signera paketen och lÀgga upp dem i det inbyggda repositoryt. Det inbyggda versionskontrollsystemet kommer att spara historik över Àndringar och byggen. Det ÄterstÄr bara att lÀgga till sina kÀllkoder i detta system. Det Àr inte ens nödvÀndigt att sjÀlv driva en server; man kan ocksÄ anvÀnda en öppen.
Det finns dock ett problem: en sÄdan kombination passar svÄrt in i den befintliga infrastrukturen. Till exempel behövs inte versionskontroll, vi har redan vÄr egen för kÀllkoder. VÄr signeringsmekanism skiljer sig: vi anvÀnder en sÀrskild server. Repositoryt behövs inte heller.
Dessutom Ă€r stödet för andra distributioner â till exempel Red Hat â ganska bristfĂ€lligt, vilket Ă€r fullt förstĂ„eligt.
En fördel med denna tjÀnst Àr den snabba supporten för den nya versionen av SUSE-distributionen. Innan det officiella tillkÀnnagivandet av releasen lÀggs de nödvÀndiga paketen för byggandet upp i det offentliga arkivet. En ny distribution visas i listan över tillgÀngliga distributioner pÄ OpenBuildService. Vi markerar rutan, och den lÀggs till i byggplanen. PÄ sÄ sÀtt kan tillÀgget av den nya versionen av distributionen göras nÀstan med ett klick.
I vÄr infrastruktur, med hjÀlp av OpenBuildService, byggs hela mÄngfalden av KMP-paket för veeamsnap-modulen för SUSE-distributioner.
Vidare skulle jag vilja fokusera pÄ frÄgor som Àr specifika för kÀrnmoduler.
kernel ABI
Linux-kÀrnmoduler har historiskt spridits i form av kÀllkod. Anledningen Àr att kÀrnans skapare inte belastar sig med att stödja en stabil API för kÀrnmoduler, Àn mindre pÄ binÀr nivÄ, vilket kallas kABI.
För att bygga en modul för det vanilj-kÀrnan krÀvs specifika header-filer för just den kÀrnan, och den kommer endast att fungera pÄ denna kÀrna.
DKMS möjliggör automatisering av byggprocessen för moduler vid kÀrnuppdateringar. Som ett resultat anvÀnder anvÀndare av Debian-arkivet (och dess mÄnga slÀktingar) antingen kÀrnmoduler frÄn distributionsarkivet eller moduler som byggs frÄn kÀllkoden med hjÀlp av DKMS.
Denna situation tillfredsstÀller dock inte sÀrskilt Enterprise-segmentet. Distributörer av propriety-kod vill sprida produkten i form av fÀrdiga binÀrer.
Administratörer vill inte hÄlla utvecklingsverktyg pÄ produktionsservrar av sÀkerhetsskÀl. Distributörer av Enterprise Linux, som Red Hat och SUSE, har beslutat att de kan stödja stabil kABI för sina anvÀndare. Som ett resultat har KMOD-paket för Red Hat och KMP-paket för SUSE uppstÄtt.
Essensen av denna lösning Àr ganska enkel. För en specifik version av distributionen fryses kÀrnans API. Distributören hÀvdar att de anvÀnder just kÀrnan, exempelvis 3.10, och gör endast korrigeringar och förbÀttringar som inte pÄverkar kÀrnans grÀnssnitt, och moduler som byggs för den allra första kÀrnan kan anvÀndas för alla efterföljande utan att behöva kompileras om.
Red Hat hÀvdar att kABI-kompatibilitet gÀller för distributionen under hela livscykeln. Det betyder att en kompilerad modul för RHEL 6.0 (utgÄvan november 2010) ocksÄ ska fungera pÄ version 6.10 (utgÄvan juni 2018). Det Àr nÀstan 8 Är. Naturligtvis Àr detta en ganska komplex uppgift.
Vi har noterat flera fall dÀr modulen veeamsnap slutade fungera pÄ grund av problem med kABI-kompatibilitet.
Efter att modulen veeamsnap, som kompilerades för RHEL 7.0, visade sig vara inkompatibel med kÀrnan frÄn RHEL 7.5, men ÀndÄ laddades och garanterat kraschade servern, avstod vi frÄn att anvÀnda kABI-kompatibilitet för RHEL 7 överhuvudtaget.
För nÀrvarande innehÄller KMOD-paketet för RHEL 7 en byggnad för varje version av utgÄvan och ett skript som sÀkerstÀller att modulen laddas.
SUSE har nÀrmat sig uppgiften med kABI-kompatibilitet pÄ ett mer försiktigt sÀtt. De sÀkerstÀller kABI-kompatibilitet endast inom en servicepack.
Till exempel slÀpptes SLES 12 i september 2014. SLES 12 SP1 kom redan i december 2015, sÄ det gick knappt ett Är. Trots att bÄda utgÄvorna anvÀnder kÀrna 3.12, Àr de kABI-inkompatibla. Det Àr uppenbart att det Àr mycket enklare att upprÀtthÄlla kABI-kompatibilitet under bara ett Är. Ett Ärligt cykel för uppdatering av kÀrnmodul bör inte orsaka problem för modulskaparna.
Som resultat av denna politik frÄn SUSE har vi inte noterat nÄgot problem med kABI-kompatibilitet för vÄr modul veeamsnap. Visserligen Àr antalet paket för SUSE nÀstan en ordning mer.
Patchar och backports
Ăven om distributörerna försöker sĂ€kerstĂ€lla kABI-kompatibilitet och kĂ€rnstabilitet, strĂ€var de ocksĂ„ efter att förbĂ€ttra prestanda och Ă„tgĂ€rda defekter i denna stabila kĂ€rna.
DÀrutöver följer kÀrnutvecklarna för enterprise linux förÀndringar i den vaniljkÀrnan och överför dem till sin "stabila" kÀrna.
Ibland leder detta till nya .
I den senaste utgÄvan av Red Hat 6, i en av de mindre uppdateringarna, kom ett fel in. Det ledde till att modulen veeamsnap garanterat kraschade systemet vid frigöring av en snapshot. Genom att jÀmföra kÀllkoden för kÀrnan före och efter uppdateringen, upptÀckte vi att problemet var en backport. En liknande fix gjordes i den vaniljkÀrnan version 4.19. Men i den vaniljkÀrnan fungerade denna fix korrekt, medan det vid överföringen till "stabila" 2.6.32 uppstod ett problem med spin-locking.
SjÀlvklart, fel hÀnder alla och alltid, men var det vÀrt att dra över koden frÄn 4.19 till 2.6.32, med risk för stabiliteten?.. Jag Àr inte sÀker...
Det vÀrsta Àr nÀr marknadsföring kopplas pÄ dragkampen mellan "stabilitet" "modernisering". Marknadsavdelningen vill ha ett stabilt kÀrnversion av den uppdaterade distributionen, Ä ena sidan, men Ä andra sidan vill de att den ska prestera bÀttre och ha nya funktioner. Det leder till konstiga kompromisser.
NÀr jag försökte kompilera modulen pÄ kÀrna 4.4 frÄn SLES 12 SP3 blev jag förvÄnad över att upptÀcka funktionalitet frÄn vanilj 4.8. Enligt min Äsikt liknar implementeringen av blockin och utgÄng i kÀrna 4.4 frÄn SLES 12 SP3 mer kÀrna 4.8 Àn den tidigare stabila 4.4-versionen frÄn SLES12 SP2. Jag kan inte bedöma hur mycket kod som överfördes frÄn kÀrna 4.8 till SLES-kÀrnan 4.4 för SP3, men jag kan inte kalla kÀrnan för det stabila 4.4.
Det mest frustrerande Àr att man vid skrivning av moduler, som ska fungera bra pÄ olika kÀrnor, inte lÀngre kan lita pÄ kÀrnversionen. Man mÄste ocksÄ ta hÀnsyn till distributionen. Tur att man ibland kan förlita sig pÄ definitioner som dyker upp tillsammans med nya funktioner, men denna möjlighet finns inte alltid.
Som ett resultat vÀxer koden med ursprungliga kompilationsdirektiv.
Det finns ocksÄ patchar som förÀndrar den dokumenterade API:en för kÀrnan.
Jag snubblade över distributionen 5.16 och blev vÀldigt förvÄnad över att se att anropet lookup_bdev i denna version av kÀrnan hade Àndrat parameternas lista.
För att kunna kompilera var jag tvungen att lÀgga till ett skript i makefile som kollar om parametern mask finns i funktionen lookup_bdev.
Underskrift av kÀrnmoduler
Men lÄt oss ÄtergÄ till frÄgan om distribution av paket.
En av fördelarna med stabil kABI Àr att kÀrnmoduler i form av binÀrfil kan signeras. I detta fall kan utvecklaren vara sÀker pÄ att modulen inte har skadats av misstag eller medvetet Àndrats. Detta kan verifieras med kommandot modinfo.
Distributioner frÄn Red Hat och SUSE tillÄter att signaturen pÄ modulen kontrolleras och att den bara laddas om det motsvarande certifikatet Àr registrerat i systemet. Certifikatet Àr en offentlig nyckel som anvÀnds för att signera modulen. Vi distribuerar det som ett separat paket.
Problemet hÀr Àr att certifikat kan antingen vara inbyggda i kÀrnan (de anvÀnds av distributörer), eller mÄste skrivas in i EFI:s icke-flyktiga minne med hjÀlp av ett verktyg. mokutil. Verktyget mokutil vid installation av certifikat krÀvs det att systemet startas om och Àven innan operativsystemets kÀrna laddas upp, erbjuds administratören att godkÀnna laddningen av det nya certifikatet.
SÄledes krÀver tillÀgg av certifikat fysisk Ätkomst till systemet för administratören. Om maskinen Àr placerad nÄgonstans i molnet eller bara i en fjÀrrserver med Ätkomst endast via nÀtverket (till exempel via ssh), kommer det att vara omöjligt att lÀgga till certifikatet.
EFI pÄ virtuella maskiner
Trots att EFI redan lÀnge stöds av nÀstan alla tillverkare av moderkort, kan administratören vid installationen av systemet glömma att tÀnka pÄ behovet av EFI, och den kan vara avstÀngd.
Inte alla hypervisorer stöder EFI. VMWare vSphere stöder EFI frÄn version 5.
Microsoft Hyper-V fick ocksÄ stöd för EFI, frÄn Hyper-V för Windows Server 2012R2.
Men i standardkonfigurationen Àr denna funktionalitet för Linux-maskiner avstÀngd, vilket innebÀr att certifikat inte kan installeras.
I vSphere 6.5 kan alternativet Secure Boot endast stÀllas in i den gamla versionen av webgrÀnssnittet som fungerar via Flash. Web UI i HTML-5 ligger fortfarande lÄngt efter.
Experimentella distributioner
Och till sist ska vi diskutera experimentella distributioner och distributioner utan officiellt stöd. à ena sidan Àr det osannolikt att sÄdana distributioner anvÀnds pÄ servrar i seriösa organisationer. Dessa distributioner har ingen officiell support. DÀrför Àr det inte möjligt att ge teknisk support för produkter pÄ sÄdana distributioner.
Men sÄdana distributioner blir en praktisk plattform för att testa nya experimentella lösningar. Till exempel, Fedora, OpenSUSE Tumbleweed eller instabila versioner av Debian. De Àr ganska stabila. De har alltid nya versioner av program och alltid en ny kÀrna. Om ett Är kan denna experimentella funktionalitet dyka upp i den uppdaterade RHEL, SLES eller Ubuntu.
SÄ om nÄgot inte fungerar pÄ en experimentell distribution Àr det en anledning att utreda problemet och lösa det. Man mÄste vara beredd pÄ att denna funktionalitet snart kommer att dyka upp pÄ anvÀndarnas produktionsservrar.
Den nuvarande listan över officiellt stödda distributioner för version 3.0 kan du studera . Men den verkliga listan över distributioner som vÄr produkt kan fungera pÄ Àr mycket bredare.
Personligen var jag intresserad av experimentet med OS "Elbrus". Efter att ha förbÀttrat paketet veeam installerades och fungerade vÄr produkt. Jag skrev om detta experiment pÄ Habr i .
Och stödet för nya distributioner fortsÀtter. Vi förvÀntar oss att version 4.0 snart slÀpps. En beta-version bör dyka upp snart, sÄ hÄll utkik efter !
KĂ€lla: habr.com
