page header photo

NLUUG Voorjaarsconferentie 2017


Geplaatst door gait op 2017-07-11 13:14:14 | Permanente link | Categorie: Open Source, Open Standaarden | Reacties: 0

Ik bezocht de voorjaarsconferentie van de NLUUG, 16 mei jl. en hieronder volgt een impressie. Uit het goed gevulde programma koos ik een paar bijdragen om hieronder aan de orde te stellen in de hoop dat dit voor jou aanleiding is om ook eens zo'n conferentie te bezoeken.

De video-registraties van de lezingen zijn inmiddels beschikbaar.

Jane Stewart Adams :: Simple, Distributed, Scalable

What ants, starlings, and slime mold can teach us about computers. Te midden van de geprojecteerde teksten kwam ineens een video van een zwerm spreeuwen voorbij, daarna de tekst "TCP/IP", en bij die combinatie moest ik denken aan de collision detection in de datalink-laag van het OSI-model (CSMA/CD). Ik zou de presentatie tekort doen als ik deze hier zou samenvatten: bekijk de video!

Cor Nouws :: LibreOffice en Collabora Online

Stel: je wilt LibreOffice gebruiken op een Chromebook. In dat geval kun je het niet als standalone-applicatie gebruiken, zoals op een gewone PC met een gewoon OS: Je bent dan aangewezen op de browser in ChromeOS (of een extensie voor die browser).

Het omgaan met documenten in een browser, en dus impliciet op alle apparaten (smartphones, tablets, Chromebooks, Chromeboxen en die gewone PC) heeft meer om het lijf dan die standalone applicatie met lokale opslag.

In de browser wordt het document als tegels op een canvas gepubliceerd en de directe gebruikersinterface (tekst intikken, selecties) is een transparante laag, die net als de bedieningselementen gemaakt is in JavaScript. Dankzij de LibreOfficeKit kun je hiervoor vrij simpel zelf gebruik maken van een installatie in de private cloud (op je eigen servers), maar je kunt ook mijncloudoffice.nl gebruiken (een puur Nederlandse dienst) of CollaboraCloudSuite.com van het bedrijf Collabora Productivity. Dat bedrijf levert een grote bijdrage aan de LibreOffice-code en het is tevens de drijvende kracht achter LibreOffice Online (95+% van de code).

Verder werkt LibreOffice in de cloud dankzij de integratie met diverse diensten voor documentopslag (ownCloud/Nextcloud, Sealfile, Kolab, Pydio) doordat hierbij het WOPI-protocol gebruikt wordt (Web Application Open Platform Interface).

Authenticatie en autorisatie liggen bij de cloud, voor de samenwerking moet er een authenticatie token naar LibreOffice Online worden gezonden. Omdat je steeds te maken hebt met dat ene backend (die functioneel gelijk is aan de standalone toepassing) profiteer je meteen van de bijbehorende voordelen: bestandsformaatondersteuning, weergave, snelle ontwikkeling en grote functierijkdom e.d.

Michael Boelen :: The Beauty of Simple

Veiligheid versus simpelheid, en waarom simpel goed is.

Pas op: hier volgen een paar simpele quotes:

Quote: "Simplicity --the art of maximizing the amount of work not done-- is essential", Principles behind the Agile Manifesto (2001).

Quote: "Keep it Simple, Stupid", Kelly Johnson, KISS Principle.

Quote: "Simplicity is a prerequisite voor reliability", van Edsger W. Dijkstra, uit "How do we tell truths that might hurt?" 1975.

Nog eentje dan, veel ouder: "Less is more", Robert Browning, Andrea del Sarto, 1885.

Vergelijk eens: de dubbelzijdige afstandsbediening van een Philips- of SONY-TV met die van een Apple TV of van een SHIELD Android TV: een wereld van verschil. Of vergelijk de webshop van HP met die van Apple: bij HP kies je altijd de verkeerde uit het aanbod aan laptops die stuk voor stuk pompeus reclame voor zichzelf maken, bij Apple heb je een paar simpele keuzes.

Michael is de maker van rkhunter (anno 2003) en van Lynis (anno nu) en als je van beide tools de help-teksten door je oogharen bekijkt dan valt het verschil in tekstdichtheid nogal op. Die van rkhunter is 100% compleet, die van Lynis gaat meer richting een 'getting started'-tekst. Die is weliswaar incompleet, maar wel effectiever. Als zo'n tekst je eerste kennismaking met een tool is dan weet je het wel! Het kan dus een stuk simpeler door niet meteen alle opties en commando's te presenteren. En je krijgt nooit een tweede kans voor een eerste indruk.

Hints voor open source projecten:

  • Maak een goede beschrijving en maak een apart stuk "getting started"

  • Werk met fatsoenlijke kleuren

  • Geef in een logfile links naar bijbehorende documentatie, zoals dat bij systemd het geval is

Ed Schouten :: Open Source monitoring met Prometheus: een modern en schaalbaar monitoringsysteem

Een stel Googlers dat inmiddels bij SoundCloud werkt miste BorgMon, het monitoringssysteem van Google, en daarom hebben ze Prometheus gemaakt. Borg en Kubernetes zijn cluster managers: manieren om hele grote kuddes computers als één systeem te zien. Welnu, wat BorgMon voor Borg is, is Prometheus voor Kubernetes.

Prometheus is veel generieker dan Nagios/Icinga: Er is geen sprake van een hiërarchie (networks/hosts/services) maar het werkt met een 2D-database waarin het draait om tijd (horizontaal) en waarden met unieke namen (verticaal). Het draait om meer dan servers en services: je kunt bijvoorbeeld ook het aantal personen in een winkel bijhouden of beurs- of wisselkoersen. De primitieve data types zijn fluctuerende meters en monotoon steigende tellers. De waarden worden per stuk opgeslagen als floating point getal in hun eigen comprimeerde bestand. Vanwege dat floating point aspect kun je als eenheid seconden gebruiken (geen milliseconden) of bytes (geen kilobytes) en met de taal PromQL beschik je over een zeer krachtige taal om te raadplegen en om berekeningen te doen. Je kunt er ook je eigen dashboard mee samenstellen. Kumina (waar Ed werkt) levert z'n bijdrage in de vorm van zogenaamde exporters voor onder meer Postfix, Dovecot, KVM en OpenVPN.

Dat was het weer. De najaarsconferentie wordt gehouden op donderdag 16 november 2017 te Bunnik.

Robinsonizing in C++


Geplaatst door bob op 2017-04-13 13:03:13 | Permanente link | Categorie: Programmeren | Reacties: 0

Wat is er nu leuker dan een blog van AT Computing aan te vangen met een zin die precies dertien a's, drie b's, vijf c's, negen d's, vijfenveertig e's, acht f's, elf g's, drie h's, zesentwintig i's, vijf j's, twee k's, zes l's, drie m's, zevenentwintig n's, drie o's, drie p's, twaalf r's, achtentwintig s's, tweeentwintig t's, vier u's, elf v's, negen w's en vijf z's bevat?

Als je dit zou nagaan, door inderdaad alle letters zorgvuldig te tellen, kom je er achter (wellicht tot je verbijstering) dat het precies klopt. De rest van dit verhaal gaat over hoe je zo'n zin kunt construeren. Dus:

Hoe kun je nou toch een zin construeren die van zichzelf vertelt dat er precies zeven a's, zeven c's, vier d's, achtenveertig e's, zes f's, zes g's, zes h's, eenentwintig i's, vier j's, twee k's, vijf l's, zevenentwintig n's, vijf o's, twee p's, elf r's, achtentwintig s's, eenentwintig t's, vier u's, dertien v's, zeven w's en elf z's in staan?

Immers, als je dit zelf op een kladblaadje probeert kom je er snel achter dat wanneer je één telwoord verandert, er meteen een paar andere niet meer kloppen. En als je die probeert te verbeteren veranderen de aantallen van een boel letters opnieuw. Het grijpt allemaal in elkaar!

De strategie om een kloppende zin te krijgen is wonderlijk. Het idee is als volgt. Je construeert een zin waarin je willekeurig gekozen telwoorden invult, voor elke letter van het alfabet. Die zin is dan weliswaar correct Nederlands, maar inhoudelijk staat er onzin (omdat de aantallen niet kloppen). Deze zin is je uitgangspunt; laten we hem 'the seed' noemen, het zaadje.

Je gaat nu zorgvuldig de letters turven die in deze 'seed' staan. Dat levert je een reeks aantallen op, voor de meeste letters van het alfabet. Je construeert nu opnieuw een zin, maar nu met uitgeschreven telwoorden voor de werkelijk geturfde aantallen. Ook voor deze zin geldt waarschijnlijk dat hij inhoudelijk nog niet klopt, maar de aantallen zijn nu een stuk realistischer.

Dit proces herhaal je. Dus: letters tellen, en opnieuw een zin construeren met de zojuist geconstateerde aantallen.

Hoe kun je nu controleren of een zo geconstureerde zin werkelijk klopt? Eenvoudig: wanneer je de letters weer gaat turven, en je komt op dezelfde aantallen uit als de laatste keer, dan "spreekt de zin de waarheid"!

Je zou deze strategie eenvoudig tot een computerprogramma kunnen omvormen dat al het telwerk en zinnen construeren voor je doet. Maar stop! Niet zo snel. Je vindt lang niet altijd een oplossing! Het komt vaak voor dat je in cirkels blijft lopen, m.a.w. op aantallen komt die je een paar rondes terug al had. Het spreekt voor zich dat je er dan nooit uitkomt. Een computerprogramma moet dus een veiligheidsventiel krijgen, in de vorm van een maximaal aantal pogingen dat we gaan doen voor we besluiten te stoppen. Als we op die manier een reeks pogingen afbreken beginnen we opnieuw met een reeks willekeurig gekozen waarden: een nieuwe seed.

Op basis van deze aanpak heb ik in het verleden diverse implementaties gebouwd. Mijn eerste poging was in 1987 met een BASIC programma op een Tandy TRS-80, een computer met een 1.7 MHz Z80 CPU. Deze implementatie was in staat om 85 zinnen per minuut te analyseren.

Fast-forward naar het heden. Ik heb een C++-implementatie op mijn laptop gebouwd, die ongeveer 4 miljoen pogingen per seconde haalt. We zijn in die dertig jaar dus wel iets vooruit gegaan qua snelheid.

Met behulp van zo'n programma is het interessant om te onderzoeken wat de beste instellingen zijn om gemiddeld genomen zo snel mogelijk kloppende resultaten te krijgen. Een belangrijke parameter is de waarde die ik net al beschreef: na hoeveel pogingen besluit je dat het genoeg is, en dat je opnieuw moet beginnen met een reeks willekeurige telwoorden?

De praktijk heeft uitgewezen uit dat het loont dit getal verrassend klein te houden, bijvoorbeeld tien. Zo klein? Ja, als je na tien pogingen nog geen kloppende zin hebt gevonden, begin dan maar opnieuw. Het is beter om heel vaak vanuit verschillende kanten naar een oplossing toe proberen te werken, in plaats van lang door te blijven ploeteren vanuit een bepaald startpunt. Heb je eenmaal een startwaarde die tot een juiste oplossing zal leiden, dan ben je daar meestal in slechts een paar stappen.

Tenslotte: de strategie die we hier volgen heet Robinsonizing, naar de persoon die dit voor het eerst bedacht. Zinnen waarin alle letters van het alfabet voorkomen heten Pangrams. Deze term kom je ook tegen als je gaat zoeken naar meer informatie over dit soort zelfreferente zinnen. Maar bedenk dat de zinnen die ik hier heb laten zien niet persé alle letters van het alfabet opsommen, en zodoende dus geen zuivere pangrams zijn. Een bekende (Engelse) pangram is bijvoorbeeld: "The quick brown fox jumped over the lazy dog". De kortste Nederlandse die ik ken is: "Doch Bep, vrij sexy qua vorm, zwijgt". Strafpunten voor de eigennaam, natuurlijk, maar toch slechts 28 letters!

Dit is wel een echte pangram en bevat precies acht a's, twee b's, zeven c's, zes d's, eenenvijftig e's, drie f's, vijf g's, zes h's, zeventien i's, drie j's, een k, twee l's, twee m's, drieentwintig n's, een o, drie p's, een q, zeven r's, zesentwintig s's, achttien t's, een u, acht v's, zeven w's, een x, een y en acht z's.

Okee, en dan nu de challenge: wie bouwt een programma dat de snelheid van mijn C++-implementatie overtreft? Mijn laptop heeft een Quad Core 2.3 GHz i5 processor aan boord, dus we moeten wel normaliseren naar die snelheid. Ik gebruik bovendien maar één processorkern. Ik wil mijn implementatie ook best testen op jouw 4 GHz Xeon of zo, om de getallen vergelijkbaar te houden. :-)

Shell variabelen


Geplaatst door martijn_brekhof op 2017-03-03 10:53:42 | Permanente link | Categorie: Systeembeheer | Reacties: 0

Tijdens onze Unix/Linux beginnerscursussen leer je gebruik te maken van de mogelijkheden die de shell je biedt. Hieronder vallen ook het koppelen van processen door middel van een zogeheten pipe en het gebruik van shell variabelen. Nu komt de volgende pipe vaak voor tijdens de cursus:

$ who | wc -l

Hiermee tel je dan het aantal terminals dat er in totaal openstaat. Wanneer vervolgens shell variabelen worden behandeld kijkt men vreemd op wanneer men het volgende probeert op onze CentOS 7 oefenomgeving:

$ MIJNVAR='who | wc -l'
$ $MIJNVAR
$

Geen uitvoer! Hoe kan dat nou?!

Wat er gebeurt is dat de shell bij het tweede commando wel degelijk de variabele MIJNVAR vervangt door zijn waarde: who | wc -l. Echter, nadat de variabele is vervangen door de waarde wordt de regel niet nogmaals geanalyseerd voor speciale tekens. Dus de pipe wordt nooit opgezet en het commando dat wordt uitgevoerd is who met 3 argumenten. Waarvan één argument de optie -l is, dat alleen systeem login processen laat zien. Hierdoor is er geen uitvoer. Zonder de optie -l laat who alleen de ingelogde gebruiker zien.

$ MIJNVAR='who | wc'
$ $MIJNVAR
martijn  pts/13       2009-04-07 15:02 (atcomputing)

NLUUG Najaarsconferentie 2016


Geplaatst door gait op 2017-02-02 13:04:42 | Permanente link | Categorie: Systeembeheer, Open Source, Open Standaarden | Reacties: 0

We leven nu --begin februari-- ongeveer halverwege twee NLUUG-conferenties: op donderdag 17 november 2016 was de najaarsconferentie, op dinsdag 16 mei 2017 is de voorjaarsconferentie. Op de najaarsconferentie kwamen ondermeer de volgende onderwerpen aan bod: Kubernetes, ManageIQ, Next Generation Config Mgmt, Elastic Stack, Logstash 5, LibreSSL.

Uit het goedgevulde programma van de najaarsconferentie koos ik voor deze blog drie lezingen en hoop je daarmee aan te sporen zelf ook eens naar een NLUUG-conferentie te gaan.

De lezing "English locale for the Netherlands (en_NL)" komt aan bod en ik begin met de twee lezingen van

Jim Salter :: "Sanoid - Enterprise Virtualization on a Small Business Budget" en "Move Over, Rsync!"

Q: what is syncoid?

A: it's one of the tools sanoid and syncoid, used to orchestrate the management and replication of ZFS datasets and snapshots.

Snapshot creation and management is really a blast with these two tools.


rsync.net en BorgBackup

Ik ken de spreker van een paar goede blog-items op het gebied van replicatie, ZFS en rsync.net. rsync.net is een dumpen-in-de-cloud-dienstverlener waar je via SSH rechtsreeks met ZFS-data terecht kunt en daarover had Jim op ArsTechnica te melden: rsync.net: ZFS Replication to the Cloud is finally here and it's Fast. Ze hebben een goed tarief, standaard inclusief snapshots, en ze prijzen zichzelf aan met de kreet: als je niet weet wat dit betekent dan is het Niet Voor Jou.

Je bent nog goedkoper uit als je het filesystem-agnostische BorgBackup gebruikt want dan heb je de ZFS-snapshots die rsync.net standaard maakt niet nodig. Je moet wel zelf om dat lagere tarief vragen.

BorgBackup komt in een volgende blog aan de orde.


Het product Sanoid is een platform voor beleidsgerichte omgang met onder meer KVM (virtualisatie), OpenZFS (filesystem met replicatie/redundantie en snapshots), OpenVPN (veilige toegang), Linux (bedrijfssysteem), en Nagios (monitoring).

Aldus maakt het "enterprise" functionaliteit beschikbaar voor het MKB. Bijvoorbeeld: Je maakt lokaal uurlijkse snapshots naar een locale hotspare host, en dagelijkse snapshots naar een host op een andere locatie.

Dit is geen HA (High Availability), dat is niet haalbaar, maar het komt dicht in de buurt.

De monitoring stelt je zelfs in staat om de klant de melden dat er iets kapot is en wat er kapot is -- voordat de klant dat zelf merkt.

Soms zijn het echt kleine dingen die groots uitpakken: je hoeft geen IP-adressen te onthouden want intern wordt het TLD .vpn geserveerd (dat is ook momenteel nog geen gTLD ;-). Pak je het goed aan, dan kun je binnen een minuut herstellen van # rm -rf / --no-preserve-root en zoiets kan ook als je Windows-systeem last heeft van crypto-malware, waaraan natuurlijk ook een Samba-share ten prooi kan vallen. Met Sanoid is de resulterende omgeving groter dan de som der delen: de kracht zit 'm in de beheerbaarheid.

Replicatie gaat met Syncoid. Ook ik voel me op m'n gemak met rsync, met name met het incrementele karakter: je hoeft ongewijzigde bestanden niet opnieuw over te dragen. OK, er komt wel meer metadata aan te pas (zie ook het komende blog over BorgBackup), maar uiteindelijk lijkt het heel efficiënt, zeker als je rsync --inplace gebruikt in combinatie met ZFS. Totdat je ziet hoe je met Syncoid en ZFS hetzelfde doel bereikt in een fractie van de tijd. Dat komt omdat bij ZFS een delta niet bestaat uit complete bestanden maar uit slechts de verschillen op blok-niveau. Daarnaast gebruikt syncoid mbuffer om grote stukken in een geheugenbuffer te lezen en dat te comprimeren met lzop voordat het de lijn over gaat. Ondersteuning voor het met ZFS vergelijkbare BtrFS is gepland.

Sander van Geloven :: "English locale for the Netherlands (en_NL)"

Sander gebruikt FOSS en draagt er ook aan bij. Hij schreef bijvoorbeeld een boek over de weg naar diakritische tekens (Compose Key Sequence Reference Guide 2012, bol.com) en is bij opentaal.nl betrokken bij de Nederlandse versie van Language Tool (dat gaat verder dan spellingcontrole).

Ik had iemand al eens de locale en_DK zien gebruiken en toen ik over en_NL vertelde was de reactie: "dat is toch gewoon een kopie van en_DK?" Nou, nee. Sander liet in zo'n 100 sheets zien dat er meer bij komt kijken.


Weet je wat i18n betekent? En l10n?

Het eerste is internationalisation en gaat over het 'hoe': de software die moeiteloos overweg kan met meerdere talen en regio's. Het tweede is localisation en gaat over het 'wat': die meerdere talen en regio's.


Locales maken deel uit van de GNU C Library (glibc). Er wordt UTF-8 Unicode gebruikt (geen ISO-8859-1, ISO-8859-15, @euro, @latin). Het doel zijn de regionale formaten en notaties voor Nederland: Europese vasteland, niet voor België.

Het merendeel van de categorieën en componenten kan gekopieerd worden uit reeds bestaande locales en daarnaast komt er maatwerk aan te pas. Dan krijg je een Engelstalige locale waarbij diverse zaken volgens de Nederlandse schrijfwijze gerepresenteerd worden.

Uiteindelijk zal een printer dan niet meer tegen je zeggen "PC LOAD LETTER" (Office Space, 1999).

Reeds beschikbaar zijn zo'n 18 locales voor de Engelse taal: samenstellingen van Engels met 1 of meer talen of regionale talen (dialecten).

Sander liet per categorie (bijvoorbeeld LC_PAPER, LC_NUMERIC, LC_MESSAGES) de instellingen zien (bijvoorbeeld respectievelijk 'height', 'grouping', 'yesexpr'), had het over de risico's en de details van de implementatie, legde ons een paar probleemgevallen voor, en is ondertussen aardig op weg de beheerders van glibc zover te krijgen en_NL te adopteren.

Een nadeel van 'nog een locale' is natuurlijk diskruimtebeslag. Het zou van 6488 kB met 4.8 kB toenemen tot 6496 kB. Maar dat is nog steeds 6.4 MB ... Volg de ontwikkelingen op GitHub en onderschrijf de bugzilla reports over glibc

Shell scripts en stdin


Geplaatst door hjt op 2017-01-29 19:01:26 | Permanente link | Categorie: Programmeren | Reacties: 0

Wanneer je een shellscript hebt gemaakt dan heb je daarna ruwweg drie verschillende methoden om het te starten (je mag voor ksh ook bash lezen):

    (1)  ksh < scriptnaam
    (2)  ksh   scriptnaam
    (3)  ./scriptnaam   # nadat chmod +x is gedaan

Onder de motorkap wordt de derde methode technisch gelijkgeschakeld aan de tweede: de gestarte scriptshell ontvangt de naam van het script als eerste argument.

In deze blog bekijken we de subtiele gedragsverschillen tussen de eerste en de tweede methode. Die hebben soms grote gevolgen.

Iedere gebruiker van de UNIX-commandotaal moet goed doordrongen zijn van (en kunnen spelen met) het technische verschil tussen "standaard input" en "argument-list", als twee onderscheiden routes waarlangs een shell-vaderproces informatie naar een startend kindproces toesluist (er is zelfs nog een derde route voor informatie van shell-vader naar kind, het "export-shell-environment", maar die speelt in dit blog-verhaal geen rol).

Kijken we nu naar een commandoregel in dat script.

De scriptshell moet aan dat commando (zijn kindproces) koppelingen leveren voor diens stdin, stdout en stderr. Als de betreffende commandoregel in het script zelf geen expliciete I/O-redirectie aanwijzingen >, <, | bevat, dan maakt de scriptshell kopieen van zijn eigen koppelingen en geeft die aan het kindproces/commando.

In de tweede methode hierboven gaat dat zonder complicaties. Die ksh-scriptshell heeft met grote waarschijnlijkheid je keyboard aan zijn stdin hangen, en scherm aan stdout en stderr, en het is geen probleem om die door te koppelen naar het kind.

Maar in de eerste methode heeft de shell aan zijn stdin de scriptfile gekoppeld. Als hij dat zo ook aan zijn kindproces doorgeeft (dat doet hij inderdaad) dan moet hij maar hopen dat dat kind een beetje voorzichtig met de inhoud van de scriptfile omspringt. Dat gaat niet altijd vanzelf goed.

Maak maar eens een script dat als laatste twee regels bevat:

cat - > /tmp/tempfile.$$
echo Nu is het script klaar

Dit script zal zich heel verschillend gedragen, afhankelijk van of je 'm via methode 1) of methode 2) start!

Bij methode 2) merk je dat het cat-commando aan je toetsenbord komt te hangen. Jij typt input data, vervolgens ^D om die cat weg te jagen, en de laatste echo-regel uit het script wordt vervolgens nog netjes uitgevoerd, met z'n output op het scherm. Als je behalve de ^D geen input-data op je toetsenbord hebt getypt dan blijft de tempfile leeg.

Bij methode 1) zie je dat het cat-commando de hele staart van het script opvreet en naar de tempfile schrijft. Voor dit voorbeeld vind je dus achteraf die laatste echo-commandoregel in de tempfile terug (inclusief het woord 'echo' zelf). Het cat-commando stopt bij EOF met het lezen van de scriptfile; de scriptshell komt weer in beweging, merkt dat aan zijn stdin geen data meer zijn overgebleven (die zijn weggesnoept door de cat), en stopt ook. En in elk geval leest die cat niet van het toetsenbord!

Wanneer je in een script commandoregels opneemt die zo expliciet met stdin werken als de cat - in ons voorbeeld, dan voel je meestal wel nattigheid als ksh < script niet doet wat je wilt. Maar er zijn commando's waar de interactie wat subtieler ligt. Het meest berucht is ssh; er zijn flinke ongelukken gebeurd met scripts die een ssh-commando bevatten, en via methode 1) werden gestart. De staart van dat script kwam dan als input terecht bij het commando dat op de remote machine werd gestart. Zo begrijp je achteraf pas waarom ssh een -n vlag heeft. Want als je die vlag van ssh probeert te snappen door de manpage te lezen dan kom je niet ver.

Nagios en SELinux gaan wél samen


Geplaatst door stefan op 2016-09-29 12:07:02 | Permanente link | Categorie: Systeembeheer | Reacties: 0

Nagios is populaire software voor het monitoren van een IT infrastructuur. Het heeft een lange historie, is zeer bekend en je komt het regelmatig tegen bij verschillende bedrijven die iets met IT infrastructuur doen. Het installeren er van is dan ook welbesproken.

Hulp bij installatie

De installatie van Nagios voor het inrichten van een monitoringsomgeving is een klus welke veelvuldig beschreven staat op internet. Twee van zulke bronnen zijn de Nagios Fedora Quickstart en DigitalOcean - How To Install Nagios 4, en zo nog vele meer. Hartstikke handig dat er zoveel over te vinden is. Alleen in mijn ogen gaat het merendeel van deze bronnen wat kort door de bocht wanneer de installatie plaatsvind op een Linux distributie afkomstig uit de Red Hat schuur. Op dergelijke distributies, zoals RHEL, CentOS of Fedora, wordt doorgaans gebruik gemaakt van een beveiligingsmodel genaamd SELinux. En in veel van de installatiehandleidingen wordt SELinux over het hoofd gezien of simpelweg uitgeschakeld.

Wat doet SELinux?

SELinux zorgt voor strakkere beveiliging van een Linux systeem, t.o.v. de bekende eigenaar, groep en mode permissies, door regels te hanteren die bepalen wat gebruikers en programma's mogen op een systeem. Systeembeheerders willen nog wel eens tegen de schenen van SELinux trappen wanneer ze iets voor elkaar proberen te krijgen op een systeem. Dan slaagt een net geïnstalleerd programma er bijvoorbeeld niet in naar een bepaalde file te schrijven omdat SELinux dat niet toestaat. Dikwijls doordat niet de juiste speciale SELinux rechten zijn toegekend aan een file of directory. Gevolg is dat het vers geïnstalleerde programma dan niet functioneert...

Minder handig

Een snelle oplossing is dan het uitschakelen van SELinux voor het hele systeem. Dan kan door middel van het commando setenforce 0 te geven als root gebruiker. Of meer permanent door in de SELinux configuratie file het beleid op Permissive te zetten in plaats van Enforcing, waardoor overtredingen enkel nog gelogd worden maar niet geblokkeerd. Wat weliswaar handig kan zijn om vervolgens een policy te maken zodat je weer terug kunt naar een Enforcing beleid.

Het uitschakelen van SELinux daar houd ik niet zo van. SELinux wordt niet voor niets standaard actief afgeleverd in een CentOS of Fedora Linux installatie. Het zorgt voor strakkere beveiliging doordat applicaties alleen de rechten krijgen die ze nodig hebben om te draaien. Een applicatie krijgt, min of meer, zijn eigen tuintje. Zolang de applicatie binnen dat tuintje blijft is er niets aan de hand. Maar zodra er geprobeerd wordt om buiten het ingerichtte tuintje te graven staat SELinux voor de poort. Zo kan een applicatie, kwaadwillend of niet, alsnog geen schade aanrichten op plaatsen waar deze applicatie geen toegang tot heeft.

Probleem

Wie een recente versie van Nagios wil gebruiken op een stabiele distributie zoals CentOS, of wie zelf wat wil veranderen aan de standaard configuratie van Nagios, zal deze gaan compileren vanuit de broncode. En dat geldt ook voor de beschikbare Nagios Plugins. Waar je na installatie op een Linux systeem met ingeschakelde SELinux dan tegen aanloopt is een niet-bruikbare Nagios webinterface.

De Nagios webinterface geeft als foutmelding "Unable to get process ID" en verschillende CGI scripts waarmee pagina's worden gegenereerd mogen niet worden uitgevoerd.

Gelukkig is daar wat aan te doen, zonder SELinux uit te schakelen.

Op zoek naar een oplossing

Na installatie vanaf source is Nagios geïnstalleerd in de directory /usr/local/nagios/. Van die directory en onderliggende directories zullen we het SELinux context type nog goed moeten zetten.

Met chcon kan de SELinux security context van files tijdelijk worden aangepast. Dat is alleen wel redelijk "tijdelijk" omdat de security context voor die files weliswaar door chcon wordt aangepast, maar niet wordt opgeslagen als regel in de SELinux configuratie. Mocht er een SELinux context relabeling run voorbij komen dan zal deze de afwijkende security context overschrijven met een context volgens de SELinux configuratie en gaan de "tijdelijke" wijzigingen verloren. Door de configuratie van SELinux uit te breiden is dat te verhelpen. Meer over het permanent maken van de SELinux context configuratie volgt na deze sectie.

Met chcon en wat snuffelen in de audit logs (doorgaans onder /var/log/audit) kun je proberen het probleem op te lossen. Vaak al door geschikte SELinux type context toe te kennen aan de files in kwestie.

Voor de Nagios directory is de context op disk te wijzigen als volgt:

# chcon -R -t httpd_sys_content_t /usr/local/nagios

Nu worden alle onderliggende subdirectories en files, vanwege de -R vlag, voorzien van het SELinux context type dat staat gespecificeerd achter de -t vlag.

Maar we zijn er nog niet. Er staan ook nog CGI scripts in /usr/local/nagios/sbin welke als uitvoerbaar door de webserver moeten worden aangemerkt. Dat kan met het volgende commando:

# chcon -R -t httpd_sys_script_exec_t /usr/local/nagios/sbin/

Probeer nu nogmaals in te loggen op je Nagios webinterface. Nu zou het een werkend geheel moeten zijn. Herstart eventueel je Nagios en Apache daemons mocht je nog tegen problemen aanlopen.

Maak je gebruik van (externe) Nagios commando's, zoals mogelijk via NSCA, dan zul je de var/rw subdirectory ook nog beschrijfbaar moeten maken voor de scripts. Dat kan met:

# chcon -R -t httpd_sys_script_rw_t /usr/local/nagios/var/rw

Hopelijk heb je nu een goed werkende Nagios monitoring en kunnen de wijzingen worden toegevoegd aan de SELinux configuratie.

Een gevonden oplossing implementeren

In de documentatie van Red Hat is te vinden hoe zowel tijdelijke als permanente wijzigingen gemaakt kunnen worden in de SELinux context en configuratie. Veranderingen worden opgelagen in files onder de /etc/selinux/targeted/contexts/files/ directory. Het beheren van SELinux wijzigingen wordt gedaan met een tool genaamd semanage. Dit tool heeft CentOS 7 niet standaard aan boord en zal moeten worden geïnstalleerd. Het package policycoreutils-python bevat de gewenste semanage tool.

# yum install policycoreutils-python

Als de installatie daarvan is gelukt kunnen we semanage gaan gebruiken om de Nagios directories toe te voegen aan de SELinux context lijst. Deze tool lijkt in het gebruik wel wat op chcon. Met de volgende commando's kun je de voorgaande chcon wijzigingen vastleggen in de SELinux configuratie:

# semanage fcontext -a -t httpd_sys_content_t "/usr/local/nagios(/.*)?"
# semanage fcontext -a -t httpd_sys_script_exec_t "/usr/local/nagios/sbin(/.*)?"
# semanage fcontext -a -t httpd_sys_script_rw_t "/usr/local/nagios/var/rw(/.*)?"

Nu zal de SELinux context lijst uitgebreid zijn met deze wijzigingen. Een manier om dat te controleren is door een SELinux context relabel uit te voeren met restorecon. Door de vlag -R mee te geven zal ook deze recursief door de directoryboom lopen en met de -v vlag wordt de tool mondiger en toont de files waarvan de context wordt gewijzigd. Om deze over de Nagios directory te laten lopen:

# restorecon -v -R /usr/local/nagios

Wanneer je nu geen verdere output krijgt worden er geen files aangepast en is de configuratie die je met semanage hebt toegevoegd goed aangekomen.

Nu zou de Nagios omgeving ook moeten blijven werken na een SELinux relabeling run.

Ik hield van Amanda: ik kon er mee lezen en schrijven.


Geplaatst door gait op | Permanente link | Categorie: Systeembeheer, Tips and Tricks | Reacties: 0

Maar ja, voor dat ik het wist vertrok ze en moest ik het met een ander doen.

Via via kreeg ik een date met Rsnapshot en voorwaar: dat werd een waardige vervanger. Dat Amanda vertrok komt hier aan de orde.

Amanda stond voor Advanced Maryland Automatic Network Disk Archiver. Ze maakte in een client/server-model dumps van verschillende client-hosts naar de opslag op de dump-server. Ze deed alles heel gelijkmatig qua tijdsbesteding want na verloop van tijd duurde het maken van een dump —een mengsel van volledige en incrementele dumps— elke nacht ongeveer even lang. Amanda was daarbij zuinig qua data: er werden slechts delta's 'overgehaald'. Dat kon per SSH —naar wens met een forced command— of met haar eigen protocol. Ze deed het met tape-drives en natuurlijk ook met tapewisselaars.

Voor het 'terughalen' van bestanden bood Amanda een interactief commando waarbij je een locatie (padnaam) en een tijdvenster kon instellen. Die interactie was vergelijkbaar met de dump/restore-combo afkomstig uit 4.2BSD. Zodoende kon je eerst vastleggen wat er teruggehaald moest worden en daarna ging Amanda voor je aan de slag. Daarbij werd zonodig om een andere tape gevraagd.

Er werden zogenaamde holdingdisks gebruikt voor tijdelijke opslag: aldus werd het ophalen van data gescheiden van het opslaan op het definitieve medium.

Toen de tapewisselaar het begaf hebben we de schijven niet alleen gebruikt voor de tijdelijke maar ook voor de permanente opslag: die schijven heetten dan 'virtuele tapes' en het wisselen der tapes werd uitbesteed aan het commando ln -s

Maar ja, ook een schijf kan kapot. Sterker: het hele systeem viel uit! We moesten plotseling overstappen op iets anders.

Dat is een ander server geworden met als dumpoplossing Rsnapshot: in vergelijking met Amanda een stuk minder veelzijdig maar voor een niet zo grote site ben je daarmee ook goed af.

Rsnaphot is niet veel meer dan een schil om rsync, waarbij die schil voornamelijk bestaat uit de configuratie van de client hosts, de specificatie van (niet) te dumpen data, het hanteren van de bewaartermijnen en het maken van logs.

Uitgaande van de standaardconfiguratie wordt er 4 maal per dag (hourly), 7 maal per week (daily), 4 maal per maand (weekly) en 12 maal per jaar (monthly) gedumpt.

Rsync wordt dus gebruikt: je beschikt daardoor telkens over een complete directory-boom waarin identieke bestanden slechts eenmaal aanwezig zijn: ze hangen met een of meer harde links in de boom.

Je kunt terug in de tijd door het juiste pad te bewandelen en met wat handige wildcards kun je ook de tijdstempels van vorige versies van je bestand zien.

Doe je een du op al die periodieke directories (tegelijk) dan zie je aan het ruimtebeslag van de nieuwste directory de huidige hoeveelheid data die ook op de client staat en bij de rest van de directories hoeveel er in de tussentijd veranderde, de terugwaartse delta.

Als je de nieuwste directory weggooit levert dat doorgaans niet veel vrije ruimte op: de nieuwe bestanden zijn weg, ongewijzigde bestanden blijven staan.


Op basis van deze informatie is toch wel eens flink op ruimte bespaard.

Het is niet voor niets gebruikelijk logbestanden te roteren. Dit mes snijdt aan twee kanten: de historie wordt beperkt, de historische bestanden worden naar wens gegezipt en je blijft niet zitten met een enorm groot logbestand dat telkens opnieuw gedumpt wordt.

In het onderhavige geval werd er ruimhartig gelogd op een niet-standaard locatie die ontsnapte aan de rotatie. Dat is natuurlijk rechtgezet.


Omdat de overstap naar Rsnapshot onder druk gebeurde worden de lokale clients met NFS geholpen (voor de remote clients wordt deels de bestaande SSH-configuratie gebruikt): de clients exporteren de te dumpen directories en die worden op de dumphost gemount in een bepaalde directory te weten

/hosts_nfs/<client>/

De directory met alle mountpoints

/hosts_nfs/

wordt in z'n geheel gedumpt. Aldus komt het configureren van een nieuwe lokale client neer op het exporteren op de client en het mounten op de dumphost.

Bedenkt dat er exports zijn waarbinnen op de client weer gemount is (geneste mounts). Om te voorkomen dat er van alles mis gaat indien niet alle NFS-mounts in de enige juiste volgorde beschikbaar komen is er iets speciaals gedaan.

nijmegen1:/           on /hosts_nfs/nijmegen1/ROOT
nijmegen1:/usr        on /hosts_nfs/nijmegen1/USR
nijmegen1:/usr/atcomp on /hosts_nfs/nijmegen1/usr/atcomp
nijmegen1:/usr/local  on /hosts_nfs/nijmegen1/usr/local

De aparte behandeling van / ligt voor de hand en onder /usr zitten ook mounts: vandaar / op ROOT en /usr op USR

Overigens worden de mounts in de gaten gehouden door onze Nagios-monitoring: check_nfs zoekt uit of alle NFS-mount in /etc/fstab actief zijn.

Het viel misschien op dat ik ergens in dit verhaal overstapte van verleden naar heden. Ondanks de flitsscheiding verlies ik Amanda niet uit het oog. Ze is zeker bijdetijds, er is veel ontwikkeling en een zeer actieve mailinglist. De schrijver van deze lezenswaardige blog komt regelmatig voorbij.

Dit alles vindt slechts on-site plaats: als de bom valt zijn we alles kwijt. Ergo: off-site opslag is nodig. Dat gebeurt wel maar dat komt in een volgende bijdrage aan de orde.

Gecombineerde authenticatie voor ontvangen en verzenden van e-mail :: Rapportage


Geplaatst door gait op 2016-07-01 15:08:47 | Permanente link | Categorie: Systeembeheer, Tips and Tricks | Reacties: 0

Gecombineerde authenticatie voor IMAP (met Dovecot) en SMTP (met Postfix)

Dit artikel sluit aan op het blogitem "Mailserver howto" van 4 augustus 2015.

Stel: Je wilt authenticatie bij zowel het verzenden als het lezen van e-mail. Voor het lezen gebruik je Dovecot en die verzorgt daarvoor de authenticatie. Omdat de combinatie gangbaar is kun je Postfix gebruik laten maken van die dienst.

Wordt er een bericht verzonden dan spiekt de SMTP-server (Postfix) voor de authenticatie bij de IMAP-server (Dovecot). Hoe de authenticatie bij Dovecot werkt hoeft Postfix niet te weten.

Configureer dit voor Postfix door het volgende in het bestand /etc/postfix/main.cf op te nemen:

smtpd_sasl_type = dovecot
# path to the SASL socket relative to postfix spool directory
# i.e. /var/spool/postfix
# (onafhankelijk van eventuele chroot())
smtpd_sasl_path = private/auth
smtpd_sasl_auth_enable = yes

Bij Dovecot gaat het om twee bestanden in de reeds bestaande configuratie. In het bestand /etc/dovecot/conf.d/10-master.conf zet je:

service auth {
  ...
  # Postfix smtp-auth
  unix_listener /var/spool/postfix/private/auth {
    mode = 0660
    # Assuming the default Postfix user and group
    user = postfix
    group = postfix
  }
  ...
}

Aan het bestand /etc/dovecot/conf.d/10-auth.conf voeg je toe:

  auth_mechanisms = plain login

Postfix Rapportage

Het Perl-script pflogsumm maakt een overzicht van de activiteiten van Postfix.

Je kunt het script aanroepen in een script in /etc/cron.daily/. Het lukte pflogsumm aanvankelijk niet om (ver) terug te kijken omdat het logbestand op dat moment niet zo ver terug in de tijd ging. Dat werd opgelost door de volgorde van de dagelijks uit te voeren acties in de directory etc/cron.daily/ zo aan te passen dat eerst pflogsumm rapport uitbrengt en daarna pas logrotate de /var/log/maillog roteert.

De details die in de rapportage komen kun je tot in detail instellen:

#! /bin/ksh
pflogsumm \
         /var/log/mail.log \
         --bounce_detail 10 \
         -d yesterday \
         --deferral_detail 10 \
         --detail 10 \
         -h 10 \
         --ignore_case \
         --iso_date_time \
         --mailq \
         --problems_first \
         -q \
         --reject_detail 10 \
         --smtp_detail 10 \
         --smtpd_stats \
         --smtpd_warning_detail 10 \
         -u 10 \
         --verbose_msg_detail \
         --verp_mung=2 \
         |
mail -s "Postfix log summaries $(/bin/date --date=yesterday +%Y-%m-%d)" \
         root@mail.com \

Postfix Caching

Eens kwam ik er door die rapportage achter dat een bepaalde ontvangende partij om de haverklap nieuwe verbindingen weigerde omdat er al teveel open waren. Normaal gesproken past Postfix vanzelf caching toe (on demand caching) doch caching afdwingen per bestemming kan ook:

smtp_connection_cache_destinations = mx-host.tld

Dit bleek afdoende.

Over virtualisatie, virtuele machines en containers


Geplaatst door Ad thiers op 2016-05-04 16:22:54 | Permanente link | Categorie: Meta | Reacties: 0

Revolutie of evolutie?

Het is misschien teveel gezegd dat virtualisatie van alle tijden is, maar het heeft in de informatietechnologie zeker een hele lange traditie. Wat voorbeelden:

  • Virtual memory: we zijn er zo aan gewend dat we in moderne operating systemen doen alsof we meer geheugen hebben dan er daadwerkelijk in de vorm van RAM chips in de computer zitten. Als we een ander stukje geheugen willen adresseren dan voorhanden, dan wordt dat netjes vanaf disk ingelezen ('paging'). Bovendien doen we alsof we als eindgebruiker het volledige geheugen van de computer tot onze beschikking hebben, terwijl in werkelijkheid het geheugen verdeeld is met stukjes van alle gebruikers. De afbeelding naar een virtueel stuk aaneengesloten geheugen wordt gedaan door de memory managment unit.
  • Time sharing: je kunt met vele gebruikers / processen een computer delen, terwijl individueel elk proces doet alsof het alleen op die computer loopt. Onzichtbaar voor het proces is het dat het heel vaak van de CPU wordt verwijderd om plaats te maken voor een ander proces. Een proces 'denkt' dus dat ie de hele computer voor zichzelf heeft.
  • Als je er goed over nadenkt is ook de symbolic link een vorm van virtualisatie. In dit geval een virtueel bestand of directory.
  • Ook in netwerkland kennen we virtualisatie, bijvoorbeeld VLANs (Virtual Local Area Network), waarmee we op eenzelfde fysieke infrastructuur doen alsof er een kleiner netwerk is, dat de andere componenent niet ziet. Ook VPN's zijn een vorm van virtualisatie: er wordt een eigen netwerk geveinsd, dat in feite gebruik maakt van (publieke) netwerken.
  • NAS en SAN: ook op het gebied van storage speelt virtualisatie een grote rol. Servers worden gekoppeld met een SAN en krijgen virtuele disks toebedeeld, die feitelijk niet in de servers zitten en bovendien zijn opgebouwd met meerdere fysieke disks in een RAID set.
  • VDI: eindgebruikers kunnen virtuele PC's in het data center draaien en benaderen via een thin-client, tablet of PC. Deze Virtual Desktop Infrastructure (VDI) is voor UNIX- / Linux-gebruikers al heel lang beschikbaar middels het X-Window protocol, VNC en NX. Ook vanuit de Cloud (bijvoorbeeld Azure) worden virtuele desktops aangeboden.

Waarom introduceren we zoveel complexiteit?

Het wordt er qua beheer niet makkelijker op. We moeten ons deze technieken en standaarden aanleren en de infrastructuur onderhouden. Daar moet iets tegenover staan. Wat levert het op? Waarom doen we dit? In het kort: om te ontkoppelen. Daarmee verschaffen we ons flexibiliteit. Als de eerste stappen van de virtualisatie niet gezet waren, dan zaten we nu met computers waarop slechts 1 proces kan draaien.

Virtualisatie verhult de complexiteit van de (boze) buitenwereld. Het stelt ontwikkelaars in staat om hun applicatie voor een relatief eenvoudige omgeving te implementeren, zonder rekening te moeten houden met deze complexiteit.

Virtual Machines

Zo ook met de moderne loten aan de virtualisatieboom: virtual machines (VM's) en containers. Alhoewel, modern, zij bestaan al een hele tijd, maar zijn op dit ogenblik erg in zwang. Met VM's worden, zoals de naam al aangeeft machines (servers / computers) geëmuleerd. Het voordeel is duidelijk: betere benutting van fysieke servers, omdat je er meerdere VM's op kunt hosten. Daarnaast is een groot voordeel, dat je een VM kunt verplaatsen naar een andere fysieke server, eventueel in een ander data center. Met andere woorden: flexibiliteit. Deze vorm van virtualisatie is inmiddels niet meer weg te denken en heeft zijn meerwaarde duidelijk aangetoond.

Containers

Container technologie is m.i. een vorm van applicatie-virtualisatie. In de Windows-wereld kennen we daarvoor AppSense, App-V en ThinApp. Het probleem dat applicatie-virtualisatie oplost is de verstrengeling van de geïnstalleerde applicatie met het OS. Applicatie-virtualisatie ontkoppelt door alle benodigde componenten (libraries, configuratie, executables etc.) te bundelen. Meestal betreft het in deze context applicaties die op de desktop draaien. De term 'bubble' wordt veel gebruikt om de gebundelde componenten aan te geven. In de UNIX- / Linux-wereld wordt meestal de term container gebruikt en zijn de gevirtualiseerde applicaties doorgaans services die op een server draaien. Op dit ogenblik is Docker de belangrijkste speler op het gebied van containers. Met name het gemak om containers te maken en te beheren heeft erg bijgedragen aan de populariteit van Docker. Containers beogen hetzelfde als gevirtualiseerde applicaties op Windows: het ontkoppelen van de applicatie van het OS. Ze kunnen eenvoudig verhuizen naar een andere host, omdat ze alle afhankelijkheden gebundeld hebben en Docker zorgt ervoor dat netwerk-connectiviteit netjes geregeld is.

Gaandeweg worden de populaire virtualisatievormen gemeengoed. Je staat er niet eens meer bij stil dat er weer een virtualisatielaag is gelegd over de oude begrippen. Geen revolutie dus, maar evolutie. Benieuwd wat de volgende virtualisatie-hype gaat worden?!! De toekomst zal het leren...

Sparse files


Geplaatst door hjt op 2016-02-01 19:17:27 | Permanente link | Categorie: Systeembeheer | Reacties: 0

Een weinig bekend fenomeen van UNIX- (en dus Linux-) filesystemen is de z.g. sparse file. Toch kom je de term tegen in de manpages van zeer bekende commando's zoals tar, rsync en zelfs (de Linux-versie van) cp.

Voor de uitleg hiervan is een stukje technische achtergrond nodig.

Als een applicatie een file opent, dan weet de kernel hoeveel bytes op dat moment al in die file zitten: de achtergrens is bekend. Verder houdt de kernel bij op welke plek (byte-positie) in de file die applicatie bezig is. Dat laatste heet de 'seek-pointer'. Applicaties kunnen allerlei manipulaties met die seek-pointer uithalen, maar het eenvoudigste model is dat één seekpointer functioneert per applicatie per file. Als meerdere applicaties tegelijk in dezelfde file bezig zijn dan hebben ze dus in deze situatie elk hun eigen seekpointer (een programmeur kan ook een constructie met een "shared seekpointer" opzetten maar dat komt veel minder vaak voor). Als een applicatie een read- of een write-opdracht op de file loslaat, dan vindt die operatie plaats waar op dat moment de seekpointer (van die applicatie) in die file wijst, en die seekpointer schuift mee. De volgende read of write vindt dus vanzelf plaats waar de vorige ophield.

Maar stel bijvoorbeeld dat je op een stukje uit de file een read-modify-write wilt doen. Dan zou je eerst vanaf het begin moeten lezen totdat de seek-pointer, al schuivend, de gewenste plek bereikt. Vervolgens lees je de te wijzigen bytes, en weer schuift de seek-pointer mee. Als je de gewijzigde bytes vervolgens weer terug wilt schrijven waar ze vandaan kwamen, dan staat de seekpointer dus net voorbij die plek, en dat is niet de bedoeling.

Daarom kan een applicatie met die pointer ook "seeken". Hij kan zeggen: "zet de pointer nu voor mij op positie zus-en-zo, want dadelijk ga ik schrijven (of lezen) en dat wil ik precies op die positie laten plaatsvinden. De "seek"-operatie doet zelf geen byte-transport, maar treft een voorbereiding voor de eerstkomende read of write. Dus: je hebt in files in eerste instantie een sequentieel access-gedrag omdat de seekpointer automatisch meeschuift met reads en writes, maar met deze "seek" krijg je ook een "random access" mogelijkheid.

Een "sparse" stuk in een file ontstaat als een applicatie een "seek" doet naar een plek die een stuk voorbij het einde (op dat moment) van de file ligt. Doet hij daarna een write, dan ontstaat een soort "gat" tussen dat oude einde van de file, en de nieuw-toegevoegde bytes. Als een applicatie op een later moment al lezend in dat gat terecht komt, dan leest hij nul-bytes. Zou hij echter schrijven, dan wordt op dat moment een stukje gat omgevormd tot "echt" gealloceerde diskruimte.

Als je "onder de motorkap" bekijkt hoe een file op een diskoppervlak is gelegd, dan zie je bijna nooit een aaneenliggende reeks disksectoren. Meestal is een file opgedeeld in porties sectoren, en die porties liggen verspreid over het diskoppervlak. De gebruikelijke vakterm hiervoor is "fragmentatie". De portiegrootte wordt gekozen bij het inrichten van het filesysteem (de "block size" parameter bij commando mkfs). In de boekhouding (i-node) van elke file zit een lijst die, op volgorde, aangeeft waar elke portie ligt. Maar in die lijst kan als plaatsaanduiding de waarde '0' voorkomen. Dat betekent dat die betreffende portie nooit "echt" op de disk is geschreven, maar is ontstaan als "gat" door zo'n 'seek' truc. Als een applicatie bytes wil lezen uit dat stuk van de file, dan ziet de kernel die locatiewaarde '0' staan, schudt ter plekke een portie nul-bytes uit zijn mouw, en geeft die aan de lezende applicatie. De applicatie heeft geen enkele mogelijkheid om te zien dat die nul-bytes niet echt van het diskoppervlak komen.

De seek-parameter van het dd-commando geeft een mooie demonstratie:

$  dd if=/dev/urandom of=demofile bs=1000 seek=1000000 count=1
$  ls -l demofile
-rw-rw-r-- 1 hjt all 1000001000 Jan  8 16:46 demofile

Een tipje van de sluier wordt opgelicht met de -s flag van ls:

$  ls -sk demofile
20 demofile

Wow! Deze file is ongeveer 'n Gigabyte groot, en kost 20K ruimte op disk! Je kunt zelfs nog kleiner tegenkomen, want het is afhankelijk van de block size van de betreffende partitie. Vroeger demonstreerde ik zo'n Gigabyte-file wel 'ns op een floppy. De ls -l maakte daar werkelijk indruk.

Hierbij moet je nog weten dat ls -l de databytes van een file telt, inclusief gat(en). Commando ls -s telt gealloceerde diskblokken, maar daarbij tellen de z.g. indirect-blokken mee. Indirect-blokken zijn extensies van de i-node die nodig zijn als de lijst van locaties niet meer in de i-node zelf past.

Voor systeembeheerders is het nuttig om op z'n minst te weten dat het sparse fenomeen bestaat. Als je een backup maakt van een bijna volle partitie dan leest de backup-software ook de nul-bytes uit de gaten mee. Moet de backup later worden teruggeschreven naar een even grote partitie, dan worden die nul-bytes echt geschreven, en kosten dus opeens "echt" disk-oppervlak. Als je pech hebt dan past de backup dus niet meer op de partitie waar hij oorspronkelijk wel vandaan kwam.

Het is daarom altijd verstandig om wat marge te houden in de vullingsgraad van je diskpartities. Het is moeilijk om te achterhalen hoeveel van die sparse gaten op een bepaald moment aanwezig zijn. Standaard UNIX-tools maken ze niet veel, tenzij je er speciaal om vraagt (bijv. bij tar met de -S flag). Maar soms tref je een niet-standaard applicatie die er dol op is om ze te maken.

Wie bedenkt nou zo iets...

De oorsprong ligt in de schaak-hobby van Ken Thompson. Hij was, samen met Dennis Ritchie, de ontwerper van UNIX, maar met zijn Belle-computer ook ooit wereldkampioen computerschaak. Thompson had een bekende encyclopedie van schaakopeningen overgetypt (later is hij zich op eindspelen gaan concentreren), en omgevormd tot een computer database. Daarbij had hij een algoritme bedacht dat aan elke stelling op een schaakbord een uniek nummer toekent. Dat nummer moest de zoek-key voor de database worden. Elk record in zijn database had, in bytes gemeten, dezelfde lengte. Een bloedsnelle manier om bij een gegeven stelling het bijbehorende databaserecord te vinden was dus: bouw de database als een file die bestaat uit alle records gewoon achter elkaar geplaatst, reken bij een gegeven stelling het keygetal uit, reken dan keygetal × recordsize uit, en doe in de file een 'seek' naar die bytepositie.

Maar dit speelde in de tijd dat een 70Mb disk nog zo groot was als een wasmachine, en een 3-fasen stroomaansluiting nodig had. Dus zo'n file als hierboven beschreven zou onmogelijk worden qua diskruimte, omdat het schaakspel zo vreselijk veel mogelijke stellingen kent, dus even zoveel records in de database zou kosten. Maar lang niet alle stellingen kwamen in die openingen-encyclopedie voor. Dus de database was "sparse": ze bevatte in de praktijk heel veel minder records dan in theorie zou kunnen. En toen bedacht Thompson dus, inmiddels al meer dan 40 jaar geleden, deze manier om een heel grote file te maken, die in de praktijk maar weinig echte diskruimte kost. In de toenmalige UNIX-kernel bestond het support hiervoor, ten opzichte van wat er al was, slechts uit een handvol regels code extra. Geniaal! En er zijn nog steeds nuttige toepassingen voor.