Een software RAID met vinum

Tim Hemel <tim@n2it.net>

Wat is vinum?

Vinum is een zogenaamde volume manager, waarmee je filesystems kan maken, zonder dat het systeem weet welke devices daar bij horen. Stel je bent een ISP, en je hebt een /home directory gemaakt voor al je users. Nu blijk je zo succesvol te zijn (je draait immers FreeBSD) dat de schijf te klein blijkt voor het aantal gebruikers dat je hebt. In dat geval kun je met vinum meerdere schijven "aan elkaar plakken" en het hele zaakje toch gewoon op /home mounten. Dit heet een concatenated filesystem.

Een ander voorbeeld: Stel je hebt een aantal SCSI disks in je systeem. Het voordeel van SCSI is dat meerdere disks min of meer tegelijkertijd kunnen worden benaderd. Zou het niet mooi zijn als een file verspreid kon worden over meerdere disks, zodat je reads en writes sneller lijken te gaan? Ook dat kan met vinum, met een zogenaamd striped filesystem.

Of, je hebt een aantal disks, en je wilt belangrijke data opslaan. Nu zijn er wel hardware RAID controllers die dat voor je oplossen, maar vinum kan het ook in software. Natuurlijk is een hardware raid controller sneller, maar deze is ook stukken duurder. Door met vinum een RAID-5 filesystem te maken blijft je data bewaard als er een disk uitvalt.

Vinum wordt geïmplementeerd als een kernel loadable module (kld) en wordt geladen voordat de filesystems (anders dan het root filesystem) worden gemount. Je kunt dus eventueel je /usr partitie op een vinum filesystem zetten.

Vinum organisatie

Een vinum filesystem kan worden opgebouwd uit meerdere partities. Vinum noemt deze partities drives. Drives worden gekoppeld aan zogenaamde subdisks. Deze subdisks worden weer gegroepeerd in zogenaamde plexes. Een plex heeft een bepaalde organisatie; deze organisatie bepaalt op welke manier de data wordt opgeslagen: geconcateneerd, striped of met het raid-5 systeem. Vinum biedt ook de mogelijkheid om data te mirroren, oftewel het bijhouden van meerdere kopie"en van dezelfde data. Daarom heeft vinum ook nog eens zogenaamde volumes, waaraan een of meer plexes gekoppeld kunnen worden.

Voor een volume wordt uiteindelijk een device aangemaakt in /dev/vinum/.

                       /dev/da0e
                           ^
                           |
                        mapped to
                           |
                      vinum drive   drive  drive
                           |          |      |
                           `----------+------'
                                      |
                                    plex
                                      |   ,--- other plexes
                                     volume

Het maken van de partities

Allereerst zorg je dat je de partities voor je vinum filesystems maakt, dit gaat het makkelijkst met /stand/sysinstall. Ik heb 5 scsi disks, da0-4, en op elke disk heb ik de volgende partities aangemaakt (ik laat alleen da0 zien):

/dev/da0b : 32m swap       (ik wil graag parallel kunnen swappen over scsi,
                            dus maak ik een kleine swappartitie aan)
/dev/da0e : 1g UFS         (dit is voor het concatenated filesystem)
/dev/da0f : de rest, 7692m (dit is voor de RAID)

Voor striped en raid5 drives is het handig te weten hoe groot je partities zijn in sectoren. Een sector is 512 bytes (meestal, volgens de handleiding). In dit geval was da0f 15753552 sectors groot. Je kunt dit zien tijdens het disklabelen, en anders kun je het opvragen met disklabel -r.

De reden is dat vinum de eerste 265 (geen typo, dus echt 265) sectors van de drive gebruikt om configuratie-informatie op te slaan. De subdisks kunnen dus geen gebruik maken van deze sectors.

Op een concatenated plex is het niet van belang hoe groot de subdisks zijn, maar op een striped of raid5 plex is het belangrijk dat alle subdisks even groot zijn.

De partities hebben van sysinstall het fstype "4.2BSD" gekregen. Vinum wil echter dat de partities het fstype "vinum" hebben. Dit is handig, omdat je dan niet per ongeluk de verkeerde partitie gebruikt voor vinum, met alle nadelige gevolgen van dien. We moeten het fstype dus veranderen van 4.2BSD naar vinum. We doen dat als volgt:

disklabel -e -r da0

We krijgen dan onze favoriete $EDITOR voor onze neus, en in het onderste gedeelte veranderen we de fstypes van da0e en da0f in vinum:

    :                                                          :
    :                                                          :
8 partitions:
#        size   offset    fstype   [fsize bsize bps/cpg]
  b:    65536        0      swap                        # (Cyl.    0 - 4*)
  c: 17916240        0    unused        0     0         # (Cyl.    0 - 1115*)
  e:  2097152    65536     vinum                        # (Cyl.    4*- 134*)
  f: 15753552  2162688     vinum                        # (Cyl.  134*- 1115*)

Als je vergeet het fstype te veranderen, dan zegt vinum "Inappropriate file type or format". Omdat de "Introduction to Vinum" niet echt goed beschreef dat vinum het fstype anders wilde zien, heb ik een aantal keren fouten gemaakt. Door maar van alles te proberen kan er van alles mis gaan; ik heb diverse malen moeten rebooten na een kernel panic, een enkele keer moest ik de machine hard resetten. Maar dat is de prijs van nieuwsgierigheid. Gelukkig stond er nog niets belangrijks op de schijven.

Ook is het belangrijk dat de geometry van je SCSI schijven goed staat. Ik heb wat geëxperimenteerd met disklabel en sysinstall, en als je geometry eenmaal fout staat, is het erg moeilijk om deze weer goed te zetten (misschien dat ik, omdat ik alle kernel panics beu was, niet goed nadacht). Een reboot hielp, waarna ik de schijf die lastig deed over zijn geometry goed kon fdisken en labelen. Waardoor de geometry van de schijf was veranderd weet ik niet, maar het zou iets te maken kunnen hebben met het kiezen van een te grote subdisk.

Bij nader inzien had het ook kunnen liggen aan een rare combinatie van SCSI kabels en een on-board Adaptec controller. Ik heb meer SCSI problemen ondervonden (machine hing bij ls -lR op de raid vinum partitie), die werden opgelost door een andere SCSI kabel.

Vinum configuratie

Allereerst moeten we vinum vertellen welke drives we hebben, dus we maken een tekstbestandje aan met daarin:

	drive cat0 device /dev/da0e
	drive cat1 device /dev/da1e
	drive cat2 device /dev/da2e
	drive cat3 device /dev/da3e
	drive cat4 device /dev/da4e
	drive raid0 device /dev/da0f
	drive raid1 device /dev/da1f
	drive raid2 device /dev/da2f
	drive raid3 device /dev/da3f
	drive raid4 device /dev/da4f

Het is handig om dit in een bestand vinum_drives (of iets dergelijks) te zetten. Als vinum een configuratie tweemaal leest, maakt het alles ook twee maal aan. Als je nog aan het experimenteren bent met config files, is het makkelijk om zaken zoveel mogelijk te scheiden. Voor de exacte syntax van de config files verwijs ik naar vinum(8).

Concatenated filesystem configuratie

Het maken van een geconcateneerd filesystem is het eenvoudigst. Het enige wat we hoeven te doen is het maken van een configuratiebestand met daarin:

	# The concatenated filesystem
	volume concat
	  plex org concat
	    sd length 0 drive cat0
	    sd length 0 drive cat1
	    sd length 0 drive cat2
	    sd length 0 drive cat3
	    sd length 0 drive cat4

Een lengte van 0 betekent dat vinum pakt wat het kan pakken. Dit is handig als je met partities van verschillende groottes werkt en het maakt je vinum configuratie portable.

RAID-5 filesystem configuratie

Een raid5 configuratie is iets lastiger, we moeten naast de plexdefinitie ook nog vertellen hoe groot de stripes op het filesysteem gaan worden (raid5 is een speciale vorm van striping), en we moeten vertellen hoe groot de subdisks gaan worden. De stripe size is optimaal tussen 256k en 512k, ik heb hier gekozen voor 512k. De man page vinum(8) geeft specifiekere informatie over de grootte van je stripes. Nu is het handig om te weten hoeveel sectors je beschikbaar hebt op je drive, dus zonder de eerste 265 sectors die door vinum gebruikt worden. Een te grote subdisk leidde bij mij tot problemen, en misschien ook wel tot het veranderen van de disk geometry op de eerste drive (raid0)! Vinum zelf gaf daarna aan dat 200% van de disk in gebruik was en dat er min zoveel bytes beschikbaar waren. Na alles hersteld te hebben en kleinere subdisks gekozen te hebben deed alles het volgens het boekje.

	# The RAID filesystem
	# 15753552 sectors on disk, with 265 sectors off, it is 15753287
	volume raid
	  plex org raid5 512k
	    sd length 15753287s drive raid0
	    sd length 15753287s drive raid1
	    sd length 15753287s drive raid2
	    sd length 15753287s drive raid3
	    sd length 15753287s drive raid4

Inlezen van de configuratie

Nu de configuratie af is, kunnen we kijken wat vinum er van denkt:

vinum create -v myvinum.conf

myvinum.conf is de configuratiefiles. Met meerdere files moet het commando meerdere keren gegeven worden, een keer voor elke file.

Als vinum nu niet klaagt, kunnen we de volumes initialiseren en de filesystems aanmaken. Als vinum wel klaagt, dan is er iets mis met de config file. In dat geval moet je vanuit vinum het het commando resetconfig gebruiken. Omdat dit commando gevaarlijke gevolgen kan hebben, moet je de letterlijke tekst NO FUTURE intypen. Vinum ruimt dan zijn interne configuratie op, en ook in /dev/vinum wordt grote schoonmaak gehouden. Omdat ik mijn partities nog niet van het fstype vinum had gemaakt (ik ben nieuwsgierig en probeer soms gewoon dingen uit als ik iets niet zeker weet) gaf resetconfig soms aanleiding tot een kernel panic (double fault) als ik meteen erna weer een create commando gaf.

Aanmaken van nieuwe filesystems

De volgende stap in de tutorials die ik gelezen heb was het aanmaken van een nieuw filesystem, dus doen we dat:

	newfs -v /dev/vinum/rconcat

Dit werkt prima. Op de server waarop ik vinum heb geïnstalleerd hebben we een vijftal LEDjes bevestigd waarmee we de activiteit op de SCSI disks kunnen zien; een newfs geeft een leuk effect, net als in oude films waarin een computer te zien is. Het is ook nuttig om te zien of een disk het heeft begeven.

Als we hetzelfde newfs commando echter proberen op het raid volume, dan krijgen we een I/O error. Dat is vreemd, want volgens de tutorials zou dit niet mogen. Na wat zoeken in de manpages zien we echter de volgende tekst verstopt:

   init [-w] plex

         vinum init initializes a plex by writing zeroes to all its sub-
         disks.  This is the only way to ensure consistent data in a plex.
         You must perform this initialization before using a RAID-5 plex.
         It is also recommended for other new plexes.  vinum initializes
         all subdisks of a plex in parallel.  Since this operation can
         take a long time, it is normally performed in the background.  If
         you want to wait for completion of the command, use the -w (wait)
         option.  vinum prints a console message when the initialization
         is complete.

Aha! We moeten dus eerst het init commando uitvoeren voordat we mogen newfs-en! Tja, de tutorials hadden het inderdaad nog niet over raid5 plexes, maar alleen over concat en striped plexes. Goed, gelukkig is er niks gecrashd, alleen een lichte admin-panic.

Vanuit vinum zeggen we dus:

	vinum -> init -v raid.p0

Dit duurt een flinke poos, omdat alle parity blocks geschreven moeten worden (waarschijnlijk, ik weet te weinig van vinum om dit zeker te weten). De SCSI disk LEDjes geven een nog mooier effect dan het concatenated volume. Het init commando draait echter in de achtergrond, dus je moet niet alvast gaan newfs-en, maar wachten tot init klaar is. Eventueel kun je de -w optie meegeven zodat vinum wacht tot de initialisatie compleet is. De sysadmin kan intussen make coffee uitvoeren.

Als init klaar is, mogen we eindelijk newfs -v /dev/vinum/rraid typen. Dit duurt ook flink lang, dus nog een aantal keer make coffee kan geen kwaad.

Mounten van vinum devices

Nu we filesystems hebben gemaakt, kunnen we ze mounten:

	mount /dev/vinum/concat /mnt

werkt, en in fstab kunnen we het volgende zetten:

	/dev/vinum/raid   /safe  ufs  rw  2  2

Vergeet alleen niet vinum op te starten als je boot (door alle trots om het werkend te krijgen was ik dit inderdaad vergeten): fsck wil /dev/vinum/raid checken, maar omdat vinum niet geladen is, vind fsck dit niet leuk. Je moet daarom even het volgende toevoegen in /etc/rc.conf:

	start_vinum="YES"
	vinum_drives="/dev/da0 /dev/da1 /dev/da2 /dev/da3 /dev/da4"

Na een reboot zou alles moeten werken.

Oh ja, de swap partities op de disk heb ik ook gewoon in de fstab gezet:

	/dev/da0b  none  swap  sw  0  0

After Party

Inmiddels draait vinum al een tijdje zonder problemen. Na een stroomstoring was er niks aan de hand met het raid filesystem, maar het concatenated filesystem wilde toch wel even handmatig gefsckt worden.

Meer informatie