Month: June 2006

A misztikus public folder replikáció I.


Ez a hosszú írás eredetileg nem ide íródott, de aztán később úgy döntött, hogy visszajön Apucihoz. Pusztán a jobb olvashatóság érdekében szedtem darabokra, egyben valószínűleg igen durva lett volna.

Miről is lesz szó? A csapból évek óta folyik az Active Directory replikációjának boncolgatása. Viszont szó sem esik egy másik nagy replikációs témáról, a nyilvános mappák replikációjáról. Az AD replikáció multimaster replikáció, az adatbázis pedig egy JET alapú adatbázis. Ezzel szemben a public folder replikáció multimaster és JET alapú adatbázisok játszanak benne.

Nocsak. Akkor most ugyanarról beszélünk vagy sem?

Természetesen nem. Az egyik esetben az AD ldap adatbázisa replikálódik, a másik esetben az Exchange Information Store adatbázis egyik adatbázisa. Történelmi okokból a két replikáció működési mechanizmusa még csak véletlenül sem hasonlít egymásra.
Hogy még cifrább legyen a helyzet, a public folderek adatai egy kicsit össze is vannak keverve az adatbázisok között. De erről majd később. Most ugorjunk neki az első témának.

I. Általában a public folderekről

Gondolom, itt nincs túl sok szükség szószaporításra. Akinek volt már postafiókja Exchange szerveren – bármilyenen – és próbálta már azt MAPI kliensen keresztül elérni, pontosan tudja, miről beszélek.
Igen, a folder lista alján található nyilvános mappákról. Ezek egyfajta kollektív tárolóhelyek, mindenféle közösen használt anyagokat szoktak itt tárolni az egyes cégek. Láttam már itt céges telefonkönyvet e-mailbe ágyazott Excel tábla formájában, láttam már különböző szintű vállalati rendelettárat… és végtelen a fantázia szárnyalási tere, hogy mi mindent lehet még ide betenni.

Persze mi műszaki emberek vagyunk, minket sokkal jobban érdekel, hogy hogyan is tárolja mindezt az Exchange szerver. Nos, jelen esetben két különböző helyen tárolódnak adatok: egy részük az Active Directoryban helyezkedik el, más részük pedig az Information Store adatbázisaiban. Az első adatcsoporttal most nem szándékozom túl sokat foglalkozni, ezek az adatok jól érzik magukat a címtárban, boldogan használják annak replikációs szolgáltatásait, köszönik szépen. Ide tartoznak az egyes store-ok paraméterei és konkrét nyilvános mappák meglehetősen sok tulajdonsága is. Például amennyiben az egyes folderekhez smtp címet rendelünk, az a cím is a címtárban rögzül.

1. ábra Public folder smtp címe az Active Directory-ban

(Mondjuk egy pillanatra álljunk meg és gondolkodjunk el, hogyan is működik _egymás mellett_ a kétfajta replikáció: a címtáré és az Information Store-ban tárolt nyilvános mappákké. Megvan? Akkor várjunk egy kicsit, amíg elmúlik a szédülés.)

Jelen írás mindemellett azokra az adatokra fókuszál, melyek az Information Store adatbázisában helyezkednek el.

A legfontosabb, hogy tisztában legyünk az adatok tárolási formájával. Pongyolán fogalmazva, a JET tárolási forma lényege, hogy van egy adatbázis, amelyben ömlesztve találhatók mindenféle adatok és egy másik, ehhez kapcsolódó adatbázis, melyben tömérdek pointer mutat rá a másik adatbázis egyes adataira, értelmezhetővé téve azokat. Ezután egyáltalán nem meglepő, hogy a public folderek tárolását is úgy célszerű elképzelni, hogy van külön a folder hierarchia és van külön a tartalom.

Amíg egy szerverünk van, nincs is különösebb baj. Ott vannak rajta a postafiók adatbázisok (melyiken mennyi) és emellett ott van az egy darab MAPI oldalról elérhető public folder adatbázis. (Több, ha megfeszülünk sem lehet.) A hierarchia és a tartalom egy szerveren figyel, az élet szép – és legfőképpen egyszerű. Nagyobb cégeknél viszont teljesen normális, hogy több Exchange szerverük van, esetenként egymástól meglehetősen távoli telephelyeken is. A felhasználói postafiókokkal nincs probléma, azok nyilván azokon a szervereken lesznek, amelyeket a konkrét felhasználók gyors hálózaton keresztül érnek el. De mi legyen a public folderekkel? Valamennyit itt is lehet szeparálni, amennyiben léteznek telephely specifikus folderek… de ez általában csak kis hányad. Marad az, hogy a public foldereket le kell tükrözni mind a központi, mind a telephelyi Exchange szerverekre. (Ez mellékhatásként egyben a rendelkezésre állást is növeli. Egyet fizet, kettőt kap.)

Vizsgáljuk meg, mit is jelent ez a kifejezés, hogy ‘letükrözni’? Le kell tükröznünk a hierarchiát? Nekünk ugyan nem. Az ugyanis olyan, mint az Alien nyála: áteszi magát még a saválló acélmenyezeten is. Amennyiben a folderek jogosultságát nem piszkáljuk, a folderszerkezetet – hierarchiát – minden telephelyen egyformán látni fogják. A tartalom… az már egy másik történet. Itt már mi szabályozhatjuk, hogy mi történjen. Ha akarjuk, letükrözzük. Ekkor ha valaki el akar olvasni egy nyilvános mappában lévő levelet, azt a helyi Exchange szerverről fogja megkapni. Alapértelmezetten biztos lehet benne, hogy ez a levél 15 percen belül friss. Persze nem kötelező tükröznünk. Biztos vannak olyan mappák, melyeket szökőévente használnak egyes telephelyeken. Ilyenkor rábízzuk magunkat az Exchange belső mechanizmusaira: ha nem találja meg a tartalmat azon a szerveren, amelyiken a felhasználó postafiókja van, ki fogja nyomozni, hogy melyik másik szerveren van belőle példány és onnan adja ki. Végül előfordulhat olyan eset, hogy a telephelyen csak szökőévente használnának egy foldert és akkor is tilos nekik: ilyenkor a két Exchange szerver közötti konnektoron egyszerűen le kell tiltani a public folder tartalmak elérhetőségének a közlekedését.

2. ábra Public folder referral tiltása

Közeledünk a cikk fő témájához. Akik üzemeltetnek többszerveres Exchange organizációt, tudják, hogy a tükrözés, vagy nevezzük mostantól népszerűbb nevén – a replikáció – egyáltalán nem olyan kezes bárány, mint ahogy a tankönyvek írják. Sőt. Megismerve a működési mechanizmusát, egyből Pratchett Korongvilágának sárkányai jutottak eszembe: azok a lények annyira bonyolult működésűek voltak, hogy csoda, hogy egyáltalán éltek.

II. A replikáció közelebbről

Meglehetősen száraz anyag fog következni: bemutatom a replikációban résztvevő szereplőket és a köztük lévő viszonyokat.

Magát a public folder replikációt az Information Store szolgáltatás menedzseli, azon belül is a Public Folder Replication Agent, becenevén PFRA. (Természetesen a replikációs üzenetek szállítását nem ő végzi – azért a mindenkori szállítási mechanizmus felel. Minden másért a PFRÁ-t kell ütni.)

A különböző szervereken található azonos foldereket replikáknak nevezzük.

3. ábra Egy konkrét nyilvános mappa replika listája

Az AD replikáció és a PF replikáció között időnként találhatunk hasonlóságot: az egyik ilyen az, hogy az időbélyeg egyik esetben sem domináns. Az AD replikáció esetében az ún USN érték hordozza a fontos információt, PF replikáció esetén pedig a Change Number, röviden CN.
Ez a következőképpen épül fel: <is -GUID>-counter. Gondolom, nem kell magyaráznom, mindegyik szerver Information Store szolgáltatása objektumként szerepel a címtárban és mint ilyen, van neki egy GUID értéke. A számláló pedig egy szerverhez kötődő, monoton növekvő érték. Amikor bármit változtatnak valamelyik lokálisan tárolt nyilvános mappabéli elemen, akkor a számláló értéke eggyel nő. Az így keletkező CN kötődik hozzá a megváltoztatott objektumhoz és lesz egyben a változás azonosítója is. (Amikor létrejön az objektum, az is egy változás – azaz már születése pillanatában mindenki kap egy CN értéket.)

Ez azért önmagában kevés. Létezik egy olyan fogalom, hogy Message State Information. Minden változáshoz rendelhető egy ilyen csomag. Három fő eleme van:

  • CN: change number
  • Predecessor change list: Ez egy lista. Azokat a CN értékeket tartalmazza, melyek már korábban kötődtek az illető objektumhoz. Figyelem, itt azok a CN értékek is megtalálhatók, melyek más szervereken keletkeztek!
  • Időbélyeg

A Message State Information elemek szerverek között utaznak.

Mindemellett a replikáció adminisztrálásához szükség van lokális információtárolásra is, erre valók az ún. Replication State táblázatok. Durván úgy kell elképzelni, mintha a Message State információkból egy olyan Excel táblát építenénk fel minden szerveren, amelyikben replikánként külön sora van az objektumoknak.

A CN értékeket általában össze szokták kapni egy csokorba. Ezt a csokrot CNset-nek nevezzük. Egy konkrét folder összes objektumának CNset csokrát pedig státusz információnak.

Fontos tisztáznunk, hogy mit tartunk a replikáció elemi egységének. Ez az egység az objektum – azaz ha egy objektum bármelyik tulajdonságának az értéke megváltozik, akkor a teljes objektum utazik. Egész konkrétan:

  • Hierarchia esetén pl. létrehozunk egy új könyvtárat vagy megváltoztatjuk egy könyvtár egyik tulajdonságát, – mondjuk a nevét -, akkor a könyvtárobjektum tokkal-vonóval, összes tulajdonságával együtt fog résztvenni a replikációs folyamatban.
  • Tartalom esetén új üzenet létrehozása, meglévő üzenet tulajdonságának megváltoztatása egyaránt azt fogja okozni, hogy az üzenet – az összes tulajdonságával együtt – részt fog venni a replikációban. (Értelemszerűen az összes tulajdonságba az elem tartalma is beleértendő.)

Látható, hogy a replikációs mechanizmus igazából sok kisméretű objektum replikációja esetén érzi jól magát. Ha nagyméretű csatolások vannak a levelekben, és valaki bármilyen apróságot is megváltoztat egy levél objektumon, az egész üzenet fog utazni, böszme csatolásával együtt.

A replikációs csomagokat a következőképpen kell elképzelni. A PFRA elkészíti a Message State információs táblát, ehhez hozzácsapja a megváltozott objektumot, a folder státusz információit, az egészet elkódolja, majd rávési a címzett nevét és továbbpasszolja a szállító mechanizmusnak. A kódolás base64 algoritmussal történik és úgy hívják, hogy TNEF (Transport Neutral Encapsulated Format). Az eredmény az oly hőn szeretett winmail.dat csatolás a levélben.

A felsorolás végére hagytam a legfontosabb táblázatot. Akármilyen replikációs lépés is történik, arról bejegyzés kerül az eseménynapló applikációs logjába – feltéve, hogy érzékenyre van állítva a logolás. Az események ‘type’ paramétere utal arra, hogy mi is volt a replikációs lépés.

Type Magyarázat
0x2: hierarchia A hierarchia egyik elemének replikációja történt meg.
0x4: tartalom A tartalom egyik elemének replikációja történt meg.
0x8: backfill igénylés Hiányzó elem (hierarchia/tartalom) pótlásának igénye.
0x80000002 (hierarchia) v. 0x80000004 (tartalom): backfill válasz Hiányzó elemek elküldése.
0x10: státusz Egy folder teljes CNset-jének elküldése egy replika felé (hierarchia/tartalom)
0x20: státusz igénylés Egy replikabeli folder teljes CNset-jének megigénylése.

Ez egy nagyon fontos táblázat. Aki tényleg érteni szeretné a későbbieket, addig ne is olvasson tovább, amíg egy firkálólapra fejből nem tudja reprodukálni ezt a táblát.
Amikor nyomozni kell, hogy mi is történt, ezekkel a számokkal fogunk dolgozni.

Most pedig menjünk végig egy egyszerű replikációs folyamaton, lépésről lépésre.

1. Béla módosít egy elemet a nyilvános mappában. (Ez a változás azon a szerveren fog megtörténni, amelyiken Bélának a személyes postafiókja is van. Amennyiben azon nincs meg a public folder elem, akkor az a szerver fog játszani, amelyikről Béla beolvasta az elemet.)

2. Az illetékes szerveren futó PFRA észleli a változást.

3. A következő replikációs ciklusban (alapértelmezésben 15 perc, egyébként pedig a konkrét public folder store tulajdonságlapján állítható) a PFRA megvizsgálja, hogy létezik-e a megváltoztatott elemnek replikája.

4. A PFRA kioszt egy CN-t és hozzárendeli az objektumhoz.

5. A PFRA elkészíti a replikációs csomagocskát. Ez objektumonként tartalmazza a Message State információs táblát és magát az objektumot. Emellé odacsomagolja még a feladó folder státusz információját is.
A levélforgalom csökkentése miatt egy csomagba nem csak egy változás adatai kerülhetnek bele. Hierarchia változások nagyon jól elvannak egymás mellett, hasonlóan az egy folderhez tartozó tartalomváltozások is. Hierarchia változás nem keveredhet egy csomagon belül tartalomváltozással. Hasonlóan különböző folderekhez tartozó tartalomváltozások sem keverhetők. (Ekkor egy csomagon belül két státusz információ menne.)

6. A PFRA ráírja a csomagra a címzett nevét és feladja. Akárhány replika is létezik, ő csak egy példányban adja fel a csomagot – a többiről már az Exchange szállítási mechanizmusa gondoskodik. A PFRA olyan szinten megbízik ebben a mechanizmusban, hogy minden visszajelzési igény nélkül be is vési a maga kis táblázatába, hogy az illető replikák szinkronban vannak.
Az applikációs logba bekerül egy 0x2 vagy 0x4 típusú bejegyzés, amennyiben érzékenyre van állítva a logolás.

4. ábra Replikációs csomag elküldésére utaló 0x2 bejegyzés az applikációs logban

7. A fogadó szerver PFRA szolgáltatása kicsomagolja a csomagot. Az applikációs logba bekerül egy 0x2 vagy 0x4 típusú bejegyzés.

8. A PFRA elemzi a Message State információs táblák értékét és ez alapján eldönti, mely elemeket kell módosítania a saját lokális adatbázisában.

9. A PFRA elvégzi a módosításokat.

10. A PFRA adminisztrál: átvezeti a módosításokat a saját Replication State táblázatában. A státusz információkban lévő CNset alapján leellenőrzi, hogy a folderre vonatkozóan minden objektumból tényleg a legfrisebb verzióval rendelkezik-e? Amennyiben nem, akkor pánikba esik és a backfill folyamatért szalajt. (Lásd később.)

Ezzel megvolt az alapozás. Holnap folytatom.

Korrekciók

  1. A korábban emlegetett IIFP… szép eszköz, jó eszköz, de az ingyenességén esett egy kis folt. Egyedül Windows2003 Server Enterprise verzióra hajlandó települni – tehát akinél éppen nem dohog egy ilyen a gépházban, annak bizony zsebbe kell nyúlni.
  2. A szintén korábban említett kukoricaprósza… hogy én mennyire balek vagyok. Most, utólag tudtam meg, hogy azt, amit én elkanalazgattam, még ki kellett volna sütni olajban. Akkor lett volna belőle kukoricaprósza… azaz lepény.

Remek parti volt

Előzmények:
Május végén voltam egyfajta természetgyógyásznál, akitől kaptam egyfajta speciális kezelést. Állítása szerint ezáltal az elkövetkező negyven napban ellenállóbb lettem az éjszakai fájásokkal szemben – viszont ebbe a negyven napba be kell iktatnom egy tíznapos méregtelenítő kúrát. Ennek az a lényege, hogy csak speciális ételeket ehetek (hajdinakása, köleskása, kukoricakása, barnarizs nyák), méghozzá egy nap csak egyfajtát. Inni ásványvizet vagy koffeinmentes teát lehet, azokból viszont sokat. Mivel június végén Horvátországba megyünk, így ahogy visszaértünk a bécsi kirándulásról, már dobtam is fel a platnira a hajdinát.

Egyvalamit felejtettem ki a számításaimból: azt, hogy Barnának elmaradt május végén az egri születésnapi partija. Márpedig ez minden évben nagy, összevont buli szokott lenni. Szüleim csörögtek ránk, hogy ugye megyünk? Mit lehet erre mondani? Barnának névnap/születésnap, az apjának születésnap, a kölykök meg egyébként is rég látták egymást… persze, hogy megyünk.

Anyám természetesen kitett magáért. Szombat kora délelőtt hurkával, sült kolbásszal és fasírtgombócokkal várt minket. Az egész előteret belengte a csemege uborka aromával keveredett sült kolbász illat. Ebédre húsleves volt, kijevi módra töltött rántott hússal, opcionálisan fokhagymásan lesütött hússal. Ebéd közben bontottak egy üveg bort, utána pedig jöttek a torták: egy diabetikus torta öcsém fiának és egy nagyobb joghurttorta a többieknek. Vacsorára anyám sütött egy nagy adag túrós süteményt, olyan tiroli rétes féleséget. Estefelé még beállított sógórnőm testvére, hoztak egy tepsi lúdlábszerű sütit. Mindezen kaják kint maradtak az étkezőasztalon, csipegetésre csábítva az arrajárókat.
Mindemellett apám előrelátóan már reggel behűtötte a sört, az esti meccshez.
Csak megjegyzem, a fentebb elsoroltak egytől-egyig a kedvenceim. Szemben azzal a kukoricaprószával, melyet végül egész nap kanalazgattam, meglehetősen savanyú képpel.
Innentől, úgy érzem, bármilyen kísértésnek ellent tudok állni.

 

 

Csinálj úgy, mint a lovak!

Ma kukoricaprósza van soron. Ez egy olyan tejbegríz jellegű anyag, csak teljesen sötétbarna.
Mivel utazunk Egerbe, át kellett lapátolnom valami jól zárható edénybe.
Rögvest meg is kérdeztem Nejtől, hogy szerinte mibe szedhetném ezt ki.
– Vödörbe? – kérdezett vissza kedvesen életem társa.

Extreme vásárlás

A gyereknek mp3 lejátszó kellett a névnapjára. Igaz, volt neki discman-je, de az nagy és már egyébként sem sikk. Az ajándék pénzével ő rendelkezik, tehát ha ez kell neki, akkor legyen. Végülis találtam neki egy jófajtát, Creative Labs Zen Nova 512 lett kinézve az Extreme Digital katalógusában.
Itt követtem el az első hibát. Pedig sejthettem volna, hogy gáz lesz, mivel ebből az üzletből én még sosem jöttem ki elégedetten, még akkor sem, amikor sikerült megvennem, amit akartam.

Intermezzo: Legutóbb például ugyanennek a csemetének digitális fényképezőgép kellett. Végigálltam egy hosszú sort a Mamutban, majd végigálltam egy másik hosszú sort a pénztárnál, ahol közölték, hogy bankkártyával nem lehet fizetni. Mehettem automatát keresni valahol, majd utána állhattam újra be a hosszú sorba. Arról nem is beszélve, hogy a hitelkártyám éppen fel volt töltve, de a bankkártyámat ez a kivétel mínuszba vitte.
Reklamáltam.
– Hogy képzelik, hogy nem lehet bankkártyával fizetni? – kérdeztem a pénztárost.
– Nem én találtam ki, ne velem veszekedjen.
Itt ki kellett oktatnom a hölgyet, hogy kettőnk kapcsolatában ő képviseli a cégét és igenis, ha valami bajom van velük, akkor rajta vezetem le a mérgemet. Tessék szolgálati úton továbbítani.
– A weblapunkon lehet észrevételt tenni, írja meg oda – bökte ki.
– Meg is írom. De nem ott – nyugtattam meg.

No, elmentem megint a Mamutba. Az előttem lévő hölgy hosszú időre vette ígénybe az eladó türelmét. Az enyémet nem, mert nekem már az első pár perc után elfogyott.
Végül sorra kerültem.
– Mp3 lejátszó, Creative Labs, Zen, Nova, 512, sötétkék – soroltam. Gondoltam, hogy kiállítják a számlát és már mehetek is.
– Nincs. Csak zöld van – közölte némi billentyűkattogtatás után az eladó.
– Sötét?
– Világos.
– Köszönöm, az nem kell.
– A Visegrádi utcában van.
– Meddig vannak nyitva?
– Hatig.
– Mennyi most az idő?
– Öt negyven.
– Akkor ennek már lőttek.
– Dehogyis. A villamos negyedóra alatt ott van.
– Ne bolondozzon már. Esélytelen.
Ezzel eljöttem. Holnap úgyis lesz dolgom a Nyugati körül, majd beugrok érte.

A következő napon már óvatosabb voltam: indulás előtt felhívtam a központi számukat.
– Mp3 lejátszó, Creative Labs, Zen, Nova, 512, sötétkék – közöltem a telefonkagylóval.
– Igen van.
– Melyik üzletükben?
– Mindegyikban.
– Na ne. Tegnap zárás előtt voltam a Mamutban, azt mondták, hogy nincs.
– Azóta kaptak árut.
– Aha. Köszönöm.

Ettől függetlenül a Visegrádi utcába mentem.
– Mp3 lejátszó, Creative Labs, Zen, Nova, 512, sötétkék – mondtam, miután az előttem álló hapi alaposan megtárgyalta a fényképezés rejtelmeit az előadóval.
Kattogtatás.
– Nincs – nézett fel a hapi.
– Ne csinálja már. Egy órája kérdeztem meg a központot, akkor még volt.
– Igen, de azóta elfogyott.
Dühösen elindultam kifelé, aztán az ajtóból visszafordultam.
– Meg tudná mondani, mely üzleteikben van még?
– Persze. Az Erzsébet körútiban és a Mamutban. Ne rakassak félre egyet?
– Ne.

Ez utóbbi válasz kis magyarázatra szorul. Ekkor ugyanis már kezdtem ideges lenni. Egyáltalán nem voltam biztos benne, hogy a továbbiakban náluk akarok vásárolni, de ha esetleg igen, akkor sem tudtam, melyik üzletükbe menjek.
Így kisétáltam a villamos megállóig és a villamosra bíztam a döntést. A Duna felől jött az első.
A villamoson azért elmélkedtem a balszerencséről: mennyi esélye van, hogy pont abban az egy üzletben fogy el egy órán belül a cucc, amelyiket kiválasztottam? A többiben ugyanis még volt, legalábbis az előadó szerint.

Bementem az újabb üzletbe. Előttem kis család fényképezőgépet vásárolt, apuka részletesen faggatta az eladót (nem tudom, nem igaz, hogy értékesebb gépnél nem lehet előtte az Interneten tájékozódni…), anyuka idegesen feszengett, a két apró gyerek pedig ordítva próbálta lebontani a boltot. Külön emelte a hangulatot egy idősebb hapi, aki sokáig úgy nézett ki, hogy elém akar furakodni, de később kiderült, hogy csak a pultot akarta tanulmányozni.
Végül sorrakerültem.
– Mp3 lejátszó, Creative Labs, Zen, Nova, 512, sötétkék – közöltem blazírtan.
Ismerős kattogtatás.
– Sajnos nincs.
– Na ne csinálja. Húsz perccel ezelőtt voltam egy másik üzletükben. Ott mondták, hogy Önöknél még van!
– Igen. De azóta elfogyott.
Innen már úgy jöttem ki, hogy bebasztam az ajtót. Ezt így utólag már bánom.

Metró, ismét a Mamut. A tegnapi eladó fogadott.
– Mp3 lejátszó, Creative Labs, Zen, Nova, 512 – morogtam.
Felnézett.
– Sötétkék – tettem hozzá.
Szemmel láthatóan megismert.
– Azt az információt kaptam, hogy nemrég kaptak árut – fűztem hozzá, hogy ne nézzen teljesen hülyének.
Kattogtatás.
– Tényleg – derült fel az arca – Lesz még valami más?

Ennyi volt. Még végigélvezhettem a készpénzes vásárlás örömeit, de végre a kezemben volt a cucc. Itt már nem kötöttem bele a pénztáros csajsziba, pedig kedvem lett volna felhívni a figyelmét, hogy már a vevőit korbáccsal kezelő Metró üzletlánc is régen bevezette a kártyás fizetés lehetőségét… lassan ideje lenni már nekik is lejönniük a fáról.
Ember, nagyértékű árukat forgalmazó műszaki üzletlánc kártyafizetés nélkül… több, mint nonszensz.

Este átadtuk az ajándékot. Végülis megérdemelte a srác, egész évben jó teljesítményt nyújtott.
A legszebb persze az, hogy fogalma sincs róla, mi munka volt megszerezni ezt a cuccot.

© 2026 MiVanVelem

Theme by Anders NorénUp ↑