A következő címkéjű bejegyzések mutatása: AIX. Összes bejegyzés megjelenítése
A következő címkéjű bejegyzések mutatása: AIX. Összes bejegyzés megjelenítése

2014. szeptember 28., vasárnap

WTF - Megváltozott filerendszer mount pointok migrálás után

Aki már migrált valaha bármilyen régebbi rendszert bármilyen újra, az kb tudhatja hogy változatosabbnál változatosabb csapdákba futhat bele az ember időnként. Ez most se volt másként...

Adott egy régi Power4es szerver amin épp egy 5.2es AIX futkározik. Tekintve hogy ez a HW már jó ideje nem támogatott, sok helyet is foglal, meg amúgy is lassú, így fent az a döntés született, hogy konszolidálni kéne a szervert egy modernebb Power7es infrastruktúrába.
Hogy hogyan is? Hát van több fajta megoldás, csak tudni kell kiválasztani melyik a legcélravezetőbb:
- Live Partition Mobility: Ha a forrás és a cél rendszerek mind szépen virtualizálva vannak, és a szükséges feltételek mind adottak, akkor kiesés nélkül át lehet költöztetni az LPARt 2 fizikai rendszer között
- Lift and Shift: Ha a rendszer és az adatok is külső SAN-on vannak, akkor minimális leállás után át lehet zónázni a LUN-okat egy másik gépre és ott használni őket.
- Backup and restore: Ez esetben minimum a rendszer belsős lemezekre lett telepítve, így annak költöztetése csak egy mksysb backup segítségével megoldható, amit a távoli gépen aztán vissza lehet tölteni (akár WPAR-ba is). Ha mázlink van, akkor az adatok SAN-on helyezkednek el, így a specifikus LUN-okat át lehet simán zónázni a cél géphez; ha viszont nincs mázlink, akkor ezt is hálózaton keresztül valahogy át kell juttatni a cél gép felé (savevg, GLVM, vagy sima tar+ssh pipe)
- Rebuild from scratch: Ebben az esetben az alap rendszert (illetve opcionálisan a Middleware, Applikációt is) teljesen nulláról építjük újra, majd a szolgáltatáshoz szükséges további adatot átemeljük a forrás rendszerről és beillesztjük az újonnan felépített struktúrába.

Lehet meglepő, de régebbi rendszereknél az utóbbi sokszor a legcélravezetőbb, mivel ezeknél valószínű nem csak a rendszer régi, hanem annak komponensei is, így egy-egy ilyen migráció kiváló alkalmat ad arra, hogy az ember végre kidobálja a régi legacy szutykokat, és egy támogatott megoldással helyettesítse őket.

Ebben az esetben a legcélravezetőbbnek az utolsó 2 megoldás keveréke bizonyult a legjobbnak: Az alaprendszert nem volt értelme átköltöztetni, a régi -már nem támogatott- middleware komponenseket egy részét szerencsére volt lehetőség támogatottra cserélni, más komponenseket viszont simán át lehetett emelni a régi rendszerről a szükséges LUN-ok újrazónázásával.

A tényleges lépésekre most nem térek ki, -a bejegyzés szempontjából érdektelenek- egyet kivéve: Miután a LUN-okat az ember átzónázza Volume Groupot ismét be kell importálni a rendszerbe, hogy az adathoz hozzá lehessen férni. A folyamat részeként a teljes LVM struktúra importálódik a fájlrendszerekkel egyetemben. Igen ám, de volt egy kisebb probléma.. Az importálás után a legtöbb fájlrendszer szépen vissza is került a helyére, viszont volt 1-2 aminek a mount pointja megváltozott (ettől eltekintve az adat szépen a helyén volt). A kérdés adott volt: Miért?

No, a technikai része a blog bejegyzésnek kb. innen indul :)) Lássuk mi és hogy zajlik le egy ilyen importálás során:
- Az importálás során az importvg szépen felolvassa a megjelölt diszk VGDA adatait
- A VGDA adatok alapján ellenőrzi a VG-hez szükséges PV-k elérhetőségét (PVID alapján), illetve összeveti azok VGDA adatait (VG_ID) a többi PV-n találhatóakkal.
- Amennyiben az összes PV elérhető, és a VGDA is konzisztensen azonos adatot mutat, úgy felolvassa a teljes LVM struktúrát
- A struktúra része az adott LV-k definiciói (típus, név, méret, upper bound), azok elhelyezkedése (LP/PP-k elhelyezkedése PV-re lebontva), illetve 1-2 további metaadat (létrehozási idő, utolsó módosítási idő, label, vfs specifikus adatok)
- Miután a teljes struktúrát feltérképezte létrehozza a szükséges bejegyzéseket az ODM-ben, illetve a /etc/filesystems-ben, majd ezek alapján aktiválja a VG-t

Nem tudom kinek tűnik fel, de fájlrendszer specifikus adatokat az importvg nem olvas fel, még is módosítja a /etc/filesystems file-t.. Hogy van ez?

Na igen. Itt van a kutya elásva. Igaz, hogy FS specifikus adatot nem olvas fel, viszont nem is kell neki: A metaadatokban ott van minden amire szüksége van ahhoz, hogy egy fájlrendszert mountolni lehessen.

Itt egy pelda a /home FS (hd1 LV) LVM descriptorának elejéről:

3D8220000 41495820 4C564342 00006A66 73320000 |AIX LVCB..jfs2..| # LVM Control Block, LV type 3D8220010 00000000 00000000 00000000 00000000 |................| 3D8220020 00000000 00000000 00003030 63306164 |..........00c0ad| # LV serial ID 3D8220030 31653030 30303463 30303030 30303031 |1e00004c00000001| 3D8220040 34320068 64310000 00000000 00000000 |42.hd1..........| 3D8220050 00000000 00000000 00000000 00000000 |................| 3D8220060 00000000 00000000 00000000 00000000 |................| 3D8220070 00000000 00000000 00000000 00000000 |................| 3D8220080 00000053 756E204E 6F762031 30203231 |...Sun Nov 10 21| # Creation date 3D8220090 3A30393A 34382032 3031330A 00000000 |:09:48 2013.....| 3D82200A0 00576564 204A756C 20323320 30393A31 |.Wed Jul 23 09:1| # Last modification date 3D82200B0 353A3338 20323031 340A0000 00000030 |5:38 2014......0| 3D82200C0 41443145 34433030 00796D63 00790020 |AD1E4C00.ymc.y. | 3D82200D0 00010001 2F686F6D 65000000 00000000 |..../home.......| # Label 3D82200E0 00000000 00000000 00000000 00000000 |................| 3D82200F0 00000000 00000000 00000000 00000000 |................| 3D8220100 00000000 00000000 00000000 00000000 |................| 3D8220110 00000000 00000000 00000000 00000000 |................| 3D8220120 00000000 00000000 00000000 00000000 |................| 3D8220130 00000000 00000000 00000000 00000000 |................| 3D8220140 00000000 00000000 00000000 00000000 |................| 3D8220150 00000000 7666733D 6A667332 3A6C6F67 |....vfs=jfs2:log| # VFS data 3D8220160 3D2F6465 762F6864 383A6D6F 756E743D |=/dev/hd8:mount=| 3D8220170 74727565 3A636865 636B3D74 7275653A |true:check=true:| 3D8220180 766F6C3D 2F686F6D 653A6672 65653D66 |vol=/home:free=f| 3D8220190 616C7365 3A71756F 74613D75 73657271 |alse:quota=userq| 3D82201A0 756F7461 2C67726F 75707175 6F746100 |uota,groupquota.|

Mielőtt valaki nekem ugrik, hogy de ezek fájlrendszer adatok: Nem, az 8000(h) blokkal arrébb van:

3D8228000 4A324653 00000002 00000000 527FF623 |J2FS........R..#| 3D8228010 00000000 00000000 00000000 00002F68 |............../h| 3D8228020 6F6D6500 00000000 00000000 00000000 |ome.............|

Jó. De ha ott megtalálható az adat, akkor miért nem az alapján dolgozik az importvg? A válasz erre nagyon egyszerű: Mert ott az se a mount point :)

De akkor várjunk csak egy pillanatot.. Itt van 2 olyan példa is, ahol egyértelműen látszik, hogy ott van a /home, de ez mégse a mount point? Hülyén hangzik, mi? :)) Nézzünk egy másik példát, és akkor már talán tisztább lesz. Legyen a példa a /var/adm/ras/livedump filerendszer (livedump LV):

LVM descriptor eleje:

1BC220000 41495820 4C564342 00006A66 73320000 |AIX LVCB..jfs2..| # LVM Control Block, LV type 1BC220010 00000000 00000000 00000000 00000000 |................| 1BC220020 00000000 00000000 00003030 63306164 |..........00c0ad| # LV serial ID 1BC220030 31653030 30303463 30303030 30303031 |1e00004c00000001| 1BC220040 3432006C 69766564 756D7000 00000000 |42.livedump.....| 1BC220050 00000000 00000000 00000000 00000000 |................| 1BC220060 00000000 00000000 00000000 00000000 |................| 1BC220070 00000000 00000000 00000000 00000000 |................| 1BC220080 00000053 756E204E 6F762031 30203231 |...Sun Nov 10 21| # Creation date 1BC220090 3A30393A 35302032 3031330A 00000000 |:09:50 2013.....| 1BC2200A0 0053756E 204E6F76 20313020 32313A31 |.Sun Nov 10 21:1| # Last modification date 1BC2200B0 313A3530 20323031 330A0000 00000030 |1:50 2013......0| 1BC2200C0 41443145 34433030 00796D6D 00790020 |AD1E4C00.ymm.y. | 1BC2200D0 00040001 2F766172 2F61646D 2F726173 |..../var/adm/ras| # Label 1BC2200E0 2F6C6976 6564756D 70000000 00000000 |/livedump.......| 1BC2200F0 00000000 00000000 00000000 00000000 |................| 1BC220100 00000000 00000000 00000000 00000000 |................| 1BC220110 00000000 00000000 00000000 00000000 |................| 1BC220120 00000000 00000000 00000000 00000000 |................| 1BC220130 00000000 00000000 00000000 00000000 |................| 1BC220140 00000000 00000000 00000000 00000000 |................| 1BC220150 00000000 7666733D 6A667332 3A6C6F67 |....vfs=jfs2:log| # VFS data 1BC220160 3D2F6465 762F6864 383A6D6F 756E743D |=/dev/hd8:mount=| 1BC220170 74727565 3A616363 6F756E74 3D66616C |true:account=fal| 1BC220180 73653A71 756F7461 3D6E6F00 00000000 |se:quota=no.....| 1BC220190 00000000 00000000 00000000 00000000 |................| 1BC2201A0 00000000 00000000 00000000 00000000 |................| 1BC2201B0 00000000 00000000 00000000 00000000 |................| 1BC2201C0 00000000 00000000 00000000 00000000 |................| 1BC2201D0 00000000 00000000 00003433 64393432 |..........43d942| 1BC2201E0 62342E31 31000000 00000000 00000000 |b4.11...........| 1BC2201F0 00000000 00000000 00000000 00000000 |................|

FS descriptor eleje:

1BC228000 4A324653 00000002 00000000 527FF62C |J2FS........R..,| 1BC228010 00000000 00000000 00000000 00002F76 |............../v| 1BC228020 61722F61 00000000 00000000 00000000 |ar/a............|

Na, ki veszi észre mi a hiba az utóbbi példában? :) Igen, az FS descriptorban lévő adat nem egyezik meg az LVM descriptorban lévő labellel. Hogy miért? Azért mert az FS descriptorban lévő adat csak 6 karakter hosszú minden eseteben.
Jó, következő kérdés: Ennek így mi értelme? Nos, az AIX a boot folyamán ezt a 6 karaktert használja a boot során (Step 2, nem összekeverni az rc2-vel!) hogy visszaellenőrizze az FS-t adatait (felmerült már bárkiben, hogy a rendszer indításához szükséges fájlrendszerek mount pointja miért olyan rövid mindig? :))
Na jó.. Innentől a kérdés már csak az, hogy a mount pointok akkor hol vannak letárolva? Hát ez az.. A /etc/filesystems file alatt. És csak ott. Minden más csak "tájékoztató jellegű", kb. mint a MÁV menetrendje.

Visszatérve az eredeti szálra már látszik, hogy milyen csapdáról beszéltem: Az importálás során ezek a definíciók nem elérhetőek a /etc/filesystems alatt, az FS descriptorra se lehet támaszkodni ilyenkor, így hát marad az LVM descriptorban lévő Label.
Igen ám, de mi van akkor ha valaki megváltoztatja egy FS mount pointját és ehhez nem a megfelelő chfs parancsot használja, hanem manuálisan szerkeszti a /etc/filesystems filet? Pontosan.. Inkonzisztencia.. Minden szépen működni is fog egészen addig, amíg az ember egy ehhez hasonló VG importot nem akar végrehajtani (hisz a rendszer minden boot során ezen file alapján fogja bootolni a filerendszereket), amikor is az importvg/recreatevg neme egyszerűséggel felülvágja a /etc/filesystems-ben található adatokat a Label-ben található adatokkal.

Jó.. már értem.. Azt hiszem.. Hogy tudok meggyőződni arról, hogy nálam ilyen nem fordul elő?
A legegyszerűbben az lslv kimenetéből tudod megnézni a Label-t. Ha abban a szerencsétlen helyzetben találod magad, hogy nem tudod lslv-vel lekérdezni az LV-ket, de a diszkek még elérhetőek (és nem akarsz egy importvg-t megkockáztatni), akkor ezzel a kis scripttel le tudod kérni direktben a diszkekről a label-eket:

Példa kimenet:

# read_labels_directly_from_disk.sh hdisk0 hdisk0 / smallvg / 64 MB PP size ******************* ....primary_bootlv.............................. / hd5 - 64 MB / 1 (220000) / hdisk0 ....None........................................ / hd6 - 512 MB / 104 (19C220000) / hdisk0 ....None........................................ / hd8 - 64 MB / 206 (334220000) / hdisk0 ..../........................................... / hd4 - 192 MB / 207 (338220000) / hdisk0 .#../usr........................................ / hd2 - 2240 MB / 210 (344220000) / hdisk0 ..../var........................................ / hd9var - 256 MB / 241 (3C0220000) / hdisk0 ..../tmp........................................ / hd3 - 768 MB / 245 (3D0220000) / hdisk0 ..../home....................................... / hd1 - 64 MB / 247 (3D8220000) / hdisk0 ..../opt........................................ / hd10opt - 384 MB / 248 (3DC220000) / hdisk0 ..../admin...................................... / hd11admin - 128 MB / 250 (3E4220000) / hdisk0 ..../var/adm/ras/livedump....................... / livedump - 256 MB / 112 (1BC220000) / hdisk0 ....None........................................ / dumplv - 1280 MB / 479 (778220000) / hdisk0 ....None........................................ / dumplv2 - 1280 MB / 269 (430220000) / hdisk0

# Érdekesség: A módszer kicsit más és más VG típusonként, így aki érdeklődik a tényleges struktúra után, az nyugodtan kukkantson bele a scriptbe :) (kis matek tudás azért nem fog ártani)

2014. június 10., kedd

Amikor RAMBO kifogy a RAMbó..

Egy újabb nap, egy újabb kihívás.. Legalább is ezt mondják a hangok odafent. Gyakorlatilag az irodába beérkezve az alábbi "köszöntő" fogad: "A szerver nem elérhető, csinálj valamit!". Jaj de jó, ismét valami ami elé hulla fáradtan le lehet ülni, hogy aztán még jobban lefárasszam magam. Na mindegy, nézzük miből élünk..

Ránézek a szerverre: pingelni lehet, barmiféle kapcsolatot nyitni viszont nem.
HMC-ről nyitott virtual konzolról megvizsgálva a kérdést se jobb a helyzet, csupán a temérdek "unable to fork" hibaüzenet igazolja az eddigi teóriát, hogy bizony itt elfogyott a gép alól a fizikai memória, és még csak azért van életben, mert a paging space-ből még maradt valami ahova ki lehet lapozni azt a kevés memória területet amit a rendszer képes volt felszabadítani.

Mit lehet ilyenkor tenni? A lehetőségeink lényegében az alábbi 3 opcióra korlátozódnak:
- Imádkozunk, hogy a terhelés egy idő után megszűnik, és felszabadul annyi memória, hogy a szervert ismét életképes állapotba lehessen hozni
- Várni hogy az OOM killer végre működésbe lépjen, vagy hogy a rendszer összeessen magától
- Manuálisan újraindítani az egész mindenséget és behúzni +1 strigulát a service outage rubrika mellé

A kérdés már csak az, hogy a 3 opció közül melyik az, amelyik számunkra ÉS a customer számára is elfogadható. Jó, beszélgessünk el a customerrel, hogy akkor mi és hogyan, illetve próbáljunk meg rájönni, hogy melyik opciót is érdemes választani. Valami ilyesmit képzeljetek el:
- A szerviz számára fontos a szerver?
- Naná hogy az, production szerver, 7x24ben elérhetőnek kéne lennie
- A fontosabb szolgáltatás(ok) elérhető(ek)?
- Hááát ami azt illeti igen, csak épp lassú mint a fene.
/* tehát nincs szerviz kiesés, ami azt jelenti, hogy a fontosabb programok még a memóriában elvannak valahogy és onnan még tudnak úgy-ahogy működni is*/
A fontosabb dolgok hála az égnek mennek, de például az utóbbi 4 beütemezett job failed-re futott /* naná, valószínű el se tudott indulni */
- A nem elérhető részek mennyire business kritikusak?
- Hát.. Kis kiesés még belefér, de hosszútávon már komoly problémákat okoz ha a jobok nem futnak le.
- Tudnak e olyan jobról ami ebbe az idő-ablakba lett ütemezve, és esetleg erősen erőforrás igényes lehet?
- Nem, azok a hétvégére vannak csak beütemezve
- Jó. Tehát a szerviz még elérhető, bár funkcionálisan korlatozott. Mivel jelenleg nem tudunk a rendszerről barmit lekérni, így sajna megbecsülni se tudjuk hogy ez a hibajelenség tartós avagy ideiglenes e. A rendszer teljes újraindításával biztosan vissza tudjuk állítani a rendet, viszont az a szolgáltatás ideiglenes, ám teljes kiesésével is jár. Kérdés hogy ez a szerviz szempontjából elfogadható e, vagy inkább várjunk még egy kis időt, hogy hátha magától megszűnik a magas memória terhelés?
- Hát.. A szolgáltatás szempontjából a helyzet nem kritikus, viszont így nem is lehet a rendszert adminisztrálni. A következő fontos job kb 2 óra múlva indulna. Ha az se tud lefutni, az már komoly pénzbeli veszteség lenne a cégnek. Kb mennyi időt vesz igénybe a teljes rendszer újraindítása?
- Az újraindítás viszonylag gyorsan megvan, a visszaellenőrzések viszont eltartanak egy minimum 20 percig. Számoljunk 30 percet mindenre biztos ami biztos.
- Rendben. Akkor még kb 1 órát tudunk várni, és akkor még lesz 30 percünk az esetleges hibaelhárításra. Ha addig se jön helyre a szerver, akkor indítsák újra.

Ok.. Kapott a szerver 1 óra haladékot, hogy bebizonyítsa milyen fából is faragták. Közben azért érdemes elgondolkodni, hogy mi is mehet épp végbe az AIX mélyebb bugyraiban (kernel szinten):
- A rendszer már kidobált minden nem szükséges adatot a fizikai memóriából (temporary cache már tuti nincs, ami még kell és kilapozható az meg már biztosan a paging space-en található)
- Ettől függetlenül a fizikai memóriában nincs szabad hely, ergo új process-t se lehet nyitni/forkolni. /* épp ezért nem is lehet belépni a gépre, mivel ott is minimum egy új shell-t kéne forkolnia a rendszernek */
- Azok a processek amik már a memóriában vannak még képesek funkcionálni /* ezért is képes a szolgáltatás még úgy ahogy életben maradni */
- A rendszer folyamatosan törekszik kiszolgálni a bejövő memória igényeket, illetve fizikai memóriát felszabadítani további page-ek kilapozásával.
- Amennyiben az egységnyi idő alatt bejövő memória kérések száma magasabb mint amit a rendszer adott idő alatt fel tud szabadítani, akkor lényegében egy meglehetősen kellemetlen hógolyó effektus következik be, mivel a futó program által kért memória terület biztosan valami adat számára lett kikérve, - amit a rendszer viszont ilyen esetekben hajlamos gyorsan ki is lapozni - ami viszont csak tovább rontja a helyzetet, mivel a diszken lévő paging sebessége kb egy kerékbilincses csigáéhoz hasonlítható a fizikai memóriához képest => ilyen helyzetben a nagy paging space csak a haláltusát hosszabbítja meg, de ténylegesen nem segít semmit /* főleg ha a process még később vissza is akar olvasni valamit amit a rendszer ma előzőleg kilapozott */
- Ez az állapot addig fennáll amíg az elérhető virtuális (!) memória le nem csökken egy bizonyos szintig: Amikor az elérhető virtualis memory page-ek száma eléri az VMO npswarn értékét (4k-ban tessek számolni), akkor a rendszer kiküld mindenkinek egy SIGDANGER signalt, hogy lehetőséget adjon a processeknek konzisztensen leállni (már ha fel vannak készítve arra hogy az ilyen signal-al kezdjenek valamit). Amennyiben a memória kihasználtság ez után eléri a VMO npskill értékét (vagy mert a programok ignorálták a signalt, vagy mert nem bírtak időben leállni), akkor a kernel szisztematikusan elkezdi legyilkolászni a legfiatalabb processeket amikre "engedélyé van": Ez kb annyit jelent, hogy a process owner UID-ja nincs felsorolva a VMO nokilluid listáján /* alapból pl a 0as UID van ott, ami annyit jelent, hogy a root neve alatt futó processeket a rendszer nem fogja legyilkolni */
- Amennyiben a rendszer nem képes ezzel a módszerrel se memóriát felszabadítani akkor a paging space teljes felhasználása után egy garantált system crash következik, amit aztán egy automatikus restart követ.

A fenti példából azért látszik, hogy van olyan forgatókönyv is, amikor a szerviz számára fontos programot a rendszer nemes egyszerűséggel legyilkolja (már ha a hozza köthető UID nincs rajta a nokilluid listán), ami kb csak 1 fokkal jobb csak a teljes újraindításnál :)
#Megjegyzés - ez azt is jelenti, hogy a fenti VMO paraméterek finomhangolásával amúgy simán életben is lehet tartani egy gépet restart nélkül, csak akkor készüljünk fel arra, hogy időnként 1-2 programot lehet újra kell majd indítgatni.

Eltelt 1 óra.. Sajnos a rendszer nem volt képes visszarángatni magát a valóságba, így az ügyfél kérésére azt újra kellett indítani. Na jó.. de hogyan? Ne tessek félre érteni, nem az a kérdés, hogy milyen paranccsal, vagy min keresztül (HMC azért jó ha van :)). A kérdés inkább arra irányul, hogy azonnal újra kell e indítani mindent, vagy esetleg adunk a rendszernek még 1-2 percet hogy ha már eddig eljutott akkor dobjon már egy system dumpot is, amiből esetleg később még tudunk vizsgálódni. Ismerve a managementet, az utóbbi garantáltan megfontolandó (még akkor is ha nem azonnal indul újra az LPAR), tekintve, hogy biztosan el fog hangzani az a kérdés, hogy "Jó, de mi tömte tele a memóriát?"

# Jó tanács: Mielőtt a Windows-on nevelkedett adminok nekiállnának azonnal újraindítani 1-1 gépet, inkább tanulják meg az alábbi parancsot használni HMC-ről:
chsysstate -m $MACHINE -r lpar -o dumprestart -n $PARTITION

Kb 5-10 percbe telt mire a gép mindent kidumpolt a memóriából, majd elkezdte szépen újraindítani a rendszert, amit gyors program indítgatások és visszaellenőrzések követtek, így a szerviz ismét teljesen elérhető lett és a customer számára kritikus job is le tudott futni minden gond nélkül.. Éljen.. An other success story, good job, well done, champaign.. Na jó, nem egészen..
További kb 1-1,5 órán át még ment a beszélgetés illetve az összefoglalók írása, miután elhangzott customer oldalról az a kérdés amire előzőleg egy meglehetősen nagy fogadást mertem volna kötni: "Ki tudjuk deríteni, hogy mi okozta ezt? Vagy van valami módszer arra, hogy ezt megelőzzük?"
Látjátok, mondtam én :)

Mázlira a dump device-al, és annak beállításaival semmi gond nem volt (dump compression bekapcsolva, dump device mérete megfelelő) és volt is elég hely ahhoz, hogy a dumpot kimásolva egy fájlrendszerre, majd kitömörítve el lehessen kezdeni analizálni, hogy végül is mi a franc volt a géppel.
Persze ahhoz hogy ezt megválaszoljuk azért nem árt tudni, hogy mi is helyezkedik el a memóriában. A teljesség igénye nélkül itt egy kis összefoglaló:
- A kernel számára lefoglalt memória terület (erre szoktak még System occupied memory néven is hivatkozni, ami magában foglalja magát a kernelt (és annak moduljait), a kernel heap-et, a shared memory szegmenseket, memory buffert, kernel cache-t, és a shared library-knak fenntartott memória területet)
- Fájlrendszer cache /* AIX esetében ez JFS, JFS2, NFS cache-t jelent */
- Különböző HW-ek számára fenntartott caching area
- Processek indító binárisainak (futó process binárisa kötelezően a fizikai memóriában helyezkedik el) és esetleges privát library-knek fenntartott memória terület
- A processek számára fenntartott privát memória területek (minden processnek saját memória terület, saját virtuális memória címzéssel)

Kezdjük is azzal ami a legtöbb problémát szokta okozni: Azok a fránya programok. Csak hogy szemléltessem hogy mennyire (nem)vicces tud egy ilyen nyomozás lenni, már itt leszegezem hogy ennek vizsgálatára nyomban 3 különböző módszer van, amik mind mást-mást néznek (ergo más-más eredményt is produkálnak) ... csak hogy az ember élete egyszerű legyen ...
- a kdb-nek van beépített svmon parancsa, ami meglehetősen jól visszaadja az aktuális állapotot, viszont bizonyos helyzetekben hajlamos nem működni. Naná hogy ez is pont egy olyan helyzet:
(0)> svmon * Pid Command Inuse Pin Pgsp Virtual 64-bit Mthrd LPage [kdb_read_mem] no real storage @ F10013AE4747FF70

- Minden process-től ki lehet kérni az éppen lefoglalt fizikai és paging lapokat (nvpages és npsblks értékek) a proc alparancs segítségével, viszont összehasonlítva egy (működő) svmon kimenetével egyértelműen látható, hogy ez nem a ténylegesen lefoglalt összes virtuális memóriát adja vissza, hanem annak csak egy részét (az svmon kimenetéből csupán a working storage és shared library data összegét vagyunk képesek így megállapítani; a heapet, illetve a kernel segment-eket nem). További kellemetlenség, hogy ezt minden egyes processre meg kell vizsgálni, ami vagy egy script formájában történhet meg, vagy sok, türelmesen beírogatott proc es grep parancsok kombinációjával /* a script lassú, kézzel meg még lassabb - marad a script */
# for i in $(echo 'proc *' |kdb dump_file_copy|awk '{print $1}') > do > echo "proc $i" |kdb dump_file_copy |awk '/ nvpages/ || /^pvproc/ {print $3}' | \ > awk 'NR == 1 { printf("%s", $0); } NR != 1 { printf(" %s", $0); } END { printf("\n") }' > done |sort -r -k2 |sed "s/://g" |head -10 java 000000000001F7FC -> ~ 503.9 MB java 000000000001545D -> ~ 340.3 MB java 0000000000007A43 -> ~ 122.2 MB java 00000000000065F0 -> ~ 101.9 MB kuxagent 00000000000024A1 -> ~ 36.6 MB java 0000000000001951 -> ~ 25.3 MB k07agent 000000000000140F -> ~ 20 MB cimserve 0000000000001088 -> ~ 16.5 MB kulagent 0000000000000C37 -> ~ 12.2 MB aixdp_da 0000000000000C02 -> ~ 12 MB
# Megjegyzés - már itt látható, hogy még így is lesznek később problémáink a processek pontos behatárolásával, tekintve, hogy a "java" process rohadtul nem mondja meg, hogy a JVM-en belül mi futott. Erre később még visszatérünk.

- az scb alparancs segítségével is ki lehet kérni az nvpage-eket (process azonosítóra szűrve), itt viszont már a rendszerhez rendelt page-ek is listázva lesznek, ergo szerintem ez a leghasználhatóbb módszer (már ha az svmon valamiért nem működne), plusz az előzőhöz képest jóval gyorsabb is az alap vizsgalat (mivel a page-eket egy körben le tudjuk kérni), viszont itt az is bejön, hogy 1 process több page-et is használhat (már ha többszálusított programról beszélünk), így ezt a vizsgálat során külön figyelembe kell venni. Ezen felül a szűrt processekre (mondjuk top10) így is kell egy extra fork a proc alparanccsal, szóval hiába gyorsabb, attól még azért eléggé macerás így is:
# PVPROC_=""; VPGS_="0" # echo "scb -c 6 0" |kdb dump_file_copy |grep -v 0000000000000000 |grep -w W |awk '{print $10,$7}' |sort | \ > awk '{gsub ("MB","")}{if ($2 ~ "GB") {sub ("GB","");print $1,$2*1024,$3} else {print}}' | while read PVPROC VPGS > do > if [ "${PVPROC}" == "${PVPROC_}" ] > then > VPGS="$(echo ${VPGS_}+${VPGS} |bc)" > else > echo "${PVPROC_} ${VPGS_} ${PGSP_}" > fi > PVPROC_="${PVPROC}" > VPGS_="${VPGS}" > done| sort -rn -k2 |head -10|while read PROC VPGS PGSP > do > printf "%-15s %-15s %-15s\n" \ > $(echo "proc $PROC"|kdb dump_file_copy |awk '/^pvproc/ {printf ("%d %s", "0x"$5, $3)}') "${VPGS} MB" > done 15597570 java 571.6 MB 7274716 java 374.1 MB 4653250 java 271.1 MB 14745724 java 102.9 MB 0 swapper 83.7 MB 3866808 rmcd 61.6 MB 6094860 java 50.3 MB 10354744 kuxagent 38.0 MB 8192024 cimserve 31.5 MB 6946818 k07agent 22.5 MB

Szupi.. akkor most már van valami hozzávetőleges fogalmunk is arról, hogy mi mennyit zabált. nézzük mennyi memória is alt rendelkezésre:
(0)> vmstat |grep "total lru frames" total lru frames (4K units) : 00000000000E53E0 3.6GB
Őőőőőő.. Állj.. A számok valahogy nem stimmelnek: Ha megnézzük, akkor az top10 process is csak kb 1.6 GB-ot volt képes lefoglalni, ami közel sincs a teljes 3.6 GB-hoz (HW cache nélkül). Ami azt jelenti, hogy valamit vagy nagyon sikerült benézni, vagy máshol van Lessie elásva. 1 lépés előre, 3 lépés vissza, kezdjük elölről, de most inkább kezdjük a vizsgálódást magasabb szintről és csak utána menjünk alacsonyabb szintekre:

Fizikai memória (poolonként lebontva - mázlira itt csak 1 pool volt)
(0)> memp * VMP MEMP NB_PAGES FRAMESETS NUMFRB F1000F0009540000 00 000 000E7440 000 001 002 003 000008D4 ^^^^^^^^ ^^^^^^^^ 3700.25 MB 8.8 MB
3700 MB (3.6 GB) fizikai memória összesen, ebből 8,8 MB szabad a dump pillanatában. Eddig stimmt. Nézzük a paginget
(0)> vmker |grep pgsp |egrep "^total|^free" total pgsp blks (numpsblks) : 001A8000 -> 6784 MB free pgsp blks (psfreeblks) : 0010DDE4 -> 4317.8 MB
6.625 GB paging, ebből közel 4.2 GB szabad. Eddig is klappol a történet.
(0)> vmstat |egrep "total perm frames|wlm_hw_pages|vm_nonsys|total perm frames|vm_syspgs" # 'system' pages (vm_syspgs) : 00000000000E2844 3.5GB # non-'system' pages (vm_nonsys) : 00000000000041F8 66.0MB total perm frames (4K units) : 0000000000000187 1.5MB Total unmanaged mem (wlm_hw_pages): 00018BC0 395.8MB
Na jó, itt kicsit sok dolog van, beismerem. Nézzük őket szépen sorjában
- 'system' pages / vm_syspgs - Emlékeztek még a fent említett "kernel-számára fenntartott memória terület"-re? Na ez az :)
- non-'system' pages / vm_nonsys - Fizikai memórián belül azon processekhez tartozó lapok mennyisége amik nem lettek kilapozva a paging space-re
- total perm frames - fájlrendszer cache (JFS, JFS2, NFS)
- Total unmanaged mem / wlm_hw_pages - A szinten fent emlegetett HW cache area.

Na itt már látszik, hogy nem mi vagyunk a hülyék, hanem a rendszer tényleg nagyon élszált, tekintve hogy a fizikai memóriában szinte csak system lapok voltak, a többi meg vagy HW cache, vagy applikáció, egy nagyon kevés FS cache, illetve 1 kis rész ami ezen a query-n nem látszik. Továbbá az is simán látszik, hogy a fenti svmon/proc/scb mérésünk semmit nem ér, ha nem látjuk, hogy mennyi memória terület is lett kilapozva abból amit az applikáció tényleg lefoglalt. Az viszont tuti, hogy a kernelnek nem kéne ennyit lefoglalnia, szóval nézzünk már rá, hogy mi a franc is zabált annyit:
(0)> scb -c 6 100 |grep 0000000000000000 |sort -rn -k4 |head -15 00A14A W 64K 256.0MB 256.0MB 0.0MB 256.0MB 0.0MB 0000 0000000000000000 KHEAP SYS 00A148 W 64K 256.0MB 256.0MB 0.0MB 256.0MB 0.0MB 0000 0000000000000000 KHEAP SYS 00A147 W 64K 256.0MB 256.0MB 0.0MB 256.0MB 0.0MB 0000 0000000000000000 KHEAP SYS 00A146 W 64K 256.0MB 256.0MB 0.0MB 256.0MB 0.0MB 0000 0000000000000000 KHEAP SYS 00A145 W 64K 256.0MB 256.0MB 0.0MB 256.0MB 0.0MB 0000 0000000000000000 KHEAP SYS 00A144 W 64K 256.0MB 256.0MB 0.0MB 256.0MB 0.0MB 0000 0000000000000000 KHEAP SYS 00A143 W 64K 256.0MB 256.0MB 0.0MB 256.0MB 0.0MB 0000 0000000000000000 KHEAP SYS 00A142 W 64K 256.0MB 256.0MB 0.0MB 256.0MB 0.0MB 0000 0000000000000000 KHEAP SYS 00A149 W 64K 255.8MB 255.7MB 0.0MB 255.8MB 0.0MB 0000 0000000000000000 KHEAP SYS 00A023 W 64K 206.7MB 203.4MB 0.0MB 206.8MB 0.1MB 0000 0000000000000000 KHEAP SYS 00A00E W 64K 187.8MB 53.8MB 0.0MB 188.0MB 0.2MB 0000 0000000000000000 KHEAP SYS 00A14B W 64K 154.1MB 153.9MB 0.0MB 154.1MB 0.0MB 0000 0000000000000000 KHEAP SYS 00E000 W 64K 130.0MB 130.0MB 0.0MB 130.0MB 0.0MB 0000 0000000000000000 MBUF SYS 00A111 W 64K 122.8MB 0.8MB 0.0MB 122.9MB 0.1MB 0000 0000000000000000 KHEAP SYS 00A01C W 64K 87.3MB 86.9MB 0.0MB 87.3MB 0.1MB 0000 0000000000000000 KHEAP SYS
Hat én itt 2 dolgot latok: Rohadt sok Kernel heap-et, meg egy kevéske memory buffert.. Ami azt jelenti, hogy az elején valóban nem benézés esete forgott fent, hanem a rendszer tényleg "Mind megette" játékot játszott, ami viszont némi kis keresgélés után nyomban ki is derül miért:
IV53587: XMGC NOT TRAVERSING ALL KERNEL HEAPS. APPLIES TO AIX 7100-03 14/04/17 PTF PECHANGE

És igen... Persze hogy a rendszer pont ezen az szinten fut:
# oslevel -s 7100-03-01-1341
Customer értesít, állapot elmagyaráz (csak amolyan konyhanyelven, mert az halál biztos, hogy nem akarok 2 órán keresztül arról magyarázkodni -egy jó esetben félig technikus emberkének - hogy az AIX hogyan is manageli a memóriát a motorháztető alatt), következő maintenance window lefoglal, change előkészít, rendszer frissítés a hétvégére beütemez, hátradől, virtuális vállveregetés, a rendszergazda megpihen.
Megpihenne.. Legalább is ha nem baxná az ideg, hogy mi a jó büdös francért kellett kb 2-3 órán át a kernel dumpot túrnia és a fejét vakarnia amikor különböző okoknál fogva valami vagy nem működött, vagy nem azt az eredményt adta amit az ember várna tőle. Mit csinál ilyenkor a (jó)rendszer gazda? Füles be, elkezd valami kódolós zenét hallgatni majd elkezdi az egész francos memória checket lescriptelni, hogy legközelebb már 5 perc alatt meglegyen az, amivel most órákat szívott.
És mivel jófej rendszergazda tudja milyen xar amikor mások is ilyenekkel szívnak, így inkább úgy dönt, hogy szabadon elérhetővé teszi az egészet, szóval ha ne adj isten más is hasonló aljasságokra adná a fejet, az használja szeretettel az alábbi kis scriptecskét arra hogy valami támpontot kapjon a rendszer állapotáról egy sikeres dump után:
https://drive.google.com/file/d/0BzMqRqSWTAToNjdCbUNXd1ZGeVU

A gyengébbek kedvéért azért azt kiemelném hogy az ilyen jellegű outputot is a helyén kell kezelni, ergo akinek nincs tapasztalata ilyen jellegű debugolásokban, annak inkább azt ajánlom, hogy max a scriptet olvasgassa, és próbálja meg megérteni hogy mi és hogy működik mielőtt teljesen vakon megbízna egy netről letöltött scriptben/parancsban :D

Csak úgy a hova tartás végett: a script jelenlegi verziója ilyen outputot generált a fent említett dumpból:
# kdb_memory_check.sh -d dump_file_copy -t 10 Available physical memory: 0.215% (8.828 from 4096 MB ) HW pages: 395.750 MB (9.661% of total memory) FS cache: 1.527 MB (.037% of total memory) Processes occupied memory: 64.441 MB (1.573% of total memory) System occupied memory: 3624.265 MB (88.483% of total memory) Kernel Heap: 3320 MB (91.606% of system memory) Available paging space: 63.648% (4317.890 from 6784 MB) Additional details: SIGDANGER level: 54272 SIGKILL level: 13568 minperm percent: 3.0% maxperm percent: 90.0% maxclient percent: 90.0% Top 10 memory consumer(s) (based on nvpages) Process Name PID Virtual Pages Paged pages java 15597570 571.6 569.9 java 7274716 374.1 372.2 java 4653250 271.1 270.7 java 14745724 102.9 102.3 swapper 0 83.7 24.8 rmcd 3866808 61.6 61.1 java 6094860 50.3 49.8 kuxagent 10354744 38.0 36.8 cimserve 8192024 31.5 31.3 k07agent 6946818 22.5 20.6
Ami a process neveket illeti.. Hát az tényleg a szívás kategóriába tartozik: logikus lenne, hogy a parancs argumentumait is megtaláljuk a memóriában (hisz itt van a /proc alatt, ami meg teljesen memória rezidens), a probléma viszont az, hogy ezt minden process saját maga manageli a saját kis memória területen belül (pontosabban mondva a process-nek fenntartott Guardpage-en belül; a procfs-en belül a psargs meg erre a memória címre mutat), így azt a kernel dumpból nem fogjuk tudni kinyerni direktben...
Viszont ha mázlink van és megmaradt a process név+PID páros valamelyik bufferban/cache-benm akkor simán megpróbálhatunk ezekre rá-greppelni a dumpon belül és megszerezni a teljes process nevet, annak minden argumentumával együtt :)

Na és ezzel tényleg ennyi.. It's Now Safe to Turn Off Your Computer. Legalább is amíg a következő nagy "kihívás" nem köszön be..

2014. február 9., vasárnap

Gondosan Levezényelhető Vontatott Migráció (GLVM)

Nem tudom ti hogy vagytok vele, de én személy szerint szeretem ha kollégák néha érdekes elméleti kérdésekkel lepnek meg. *

* Bár néha én lepem meg őket olyan furcsa kérdésekkel, mint "Hogy lehet ütemezni egy jobot cronban úgy, hogy az adott hónap 6. hetének szombatján fusson le 02:00-kor szerver idő szerint". Eddig még kevesen jöttek rá a megoldásra :)

Ezen bejegyzést egyik kolléga kérdése ihlette, aki annak szeretett volna utána járni, hogy egy támogatott rendszert hogy lehetne a leghatékonyabban migrálni (mozgatni) 2 GEO lokáció között (legyen az ország, vagy akár kontinens).
A feltételek természetesen a szokásosak (mint minden migrációnál):
- Lehetőség szerint a szolgáltatások elérhetőségét maximalizáljuk (avagy fordítva: a kiesés legyen minimális)
- A migráció emberi időn belül legyen kész (tegnapra, mert a customernek mindig minden tegnapra kell - az is amire ma még nem is gondolt)
- A migráció a meglévő eszközökkel elvégezhető legyen ("Nem veszünk semmit!")
- Elsőre sikerülnie kell mindennek (mert azt nem köszönöd meg amit kapsz ha esetleg mégsem... )

Arra viszonylag gyorsan rájöttünk, hogy lehetőség egy csomó van, de ezeket az igényeket nem elégíti egyik se teljes mértékben:
- Szerviz leállít, majd az adatot hálózaton keresztül áttolni a cél gépre valamilyen mentés formájában (filerendszer, vagy blokk (FS/LV/VG) szinten - utóbbi kötelező ha van RAW kötet is a forrás gépen) -> A szolgáltatásban nagy a kiesés, az adat mozgatása időigényes (mennyi idő áttolni 2 TB-ot 2 kontinens között? :)), illetve hálózati hiba esetén az egészet lehet elölről kezdeni
- Szerviz leállít, majd a gépet fizikailag átköltöztetni a cél helyre és ott beüzemelni -> körülményes és a fene se akar fuvarozni/megreptetni egy szervert, főleg hogy lehet nem is szükségszerűen kivitelezhető (törpék próbálkozhatnak a sokból 1 virtuális gépet kibányászni csákánnyal a gépből, de félek hogy nem fog menni) - bár tény és való, hogy egy csomó merevlemezzel megrakott teherautó/repülőgép sávszélességét nem szabad lebecsülni.
- Csinálni egy konzisztens mentést a meglévő adatokról, azt valahogy eljuttatni a célgépre, majd a különbségeket szinkronizálni hálózaton keresztül egy szerviz leállítás után -> Elméletileg még kivitelezhető is lenne, de sok a buktató (ha file szinten akarja az ember csinálni, akkor minden megváltozott file-t át kell teljesen tölteni ismét (mondjuk rsync-el) - ez esetben a szinkronizálás a megváltozott adatmennyiség és a hálózat sebességének a függvénye ; blokk szintű szinkronizálásnál meg semmit nem nyerünk, tekintve, hogy az összehasonlításhoz a teljes adatmennyiséget ismét át kell küldeni (csak hogy össze tudjuk hasonlítani, hogy hol a különbség) - különben is.. csináljon ilyet az akinek 2 anyja van!)

Anno a beszélgetésünk itt kb abban is maradt (főként mert volt más tenni való), de ez a probléma úgy szöget ütött a fejemben, és mint ahogy az lenni szokott munka után (szabadidőben) jött a felismerés, miszerint az egész problémát teljesen rossz oldalról közelítettük meg: Teljesen felesleges a célgépen lévő adatot egybe kezelni, amikor azt külön lehet bontani rendszerre, illetve minden másra.
Persze a kérdés jogos: És ez miért olyan nagy különbség? A válasz pedig az, hogy míg a rendszer a rootvg-n helyezkedik el, addig a futtatott szerviz azon kívül (általában valami appvg-ben) és hogy-hogy nem az utóbbi foglalja a hely többségét (a rootvg általában megáll 30 GB alatt, feltételezve hogy valaki barom nem telepítette a rootvg-be az middleware-t meg az applikációt is (aki ilyet tesz az ne csodálkozzon, ha egy bizonyos hozzátartozója gyakran csuklik)).
Ha ez még mindig nem elégséges indok, akkor felhívom a figyelmet arra, hogy míg a rootvg bootolható kell legyen, addig az appvg véletlenül se, ami viszont nyomban lehetővé teszi egy viszonylag ritkán használt technika alkalmazását amit úgy hívnak hogy GLVM.

Aki esetleg még nem találkozott ezzel a technológiával annak az alábbi leírások átfutását javaslom: 1 2 3 4

Amit kiemelnék:
- Kliens <-> szerver alapú megvalósítás
- A technológiára a PowerHA_XD meglehetősen komolyan épít, viszont a technológia része az alap AIX-nek is(bár gyárilag nem települ, viszont megtalálható a telepítő lemezen)
- A technológia lehetővé teszi 1 PV (lényegében diszk) megosztását hálózaton keresztül (kb mint egy iSCSI)
- A GLVM a távoli diszk elérését vezérli, ezen felül minden mást az AIX-os LVM managel le, mint egy normál PV esetében (Kiegészítésként azért meg kell jegyezni, hogy a GLVM-nek is van egy pár megkötése az LVM-en belüli VG-k/LV-k beállításait illetően (mint például a superstrict allocation policy))

Na akkor innen indul a buli. A migráció innentől fogva a következő fázisokra osztható fel:
1) A cél szerverhez előre ki kell allokálni a megfelelő mennyiségű (és méretű) PV-ket, amit aztán a forrás gép számára RPV-n keresztül elérhetővé kell tenni
2) A forrás oldalon ezeket a diszkeket fel kell konfigurálni, majd betolni a non-rootvg(k) alá.
3) Amint a szükséges mennyiségű extra tárhely elérhető a VG-ken belül (2x annyi, mint amekkora eredetileg volt) gond nélkül el is kezdhetjük tükrözni a VG(ke)t bármiféle kiess nélkül (az adatmennyiség mértékétől függően ez eltarthat egy darabig)
4) Miután a tükrök felépültek (és szépen szinkronban is vannak) lényegében szabad az út a migrálás elkezdéséhez, csupán a pontos időt kell leegyeztetni a customerrel
5) Amikor is eljön a nagy nap, akkor a forrás oldalon annyi a dolgunk, hogy rootvg-ről készítünk egy mksysb backupot (ezt mondjuk még mindig kénytelenek leszünk áttolni a hálózaton keresztül aznap), majd leállítunk mindent, megtörjük az elkészített tükröt, és lekapcsoljuk a gépet
6) A cél oldalon pedig vissza kell állítsuk az mksysb-nket (preferáltan egy NIM szerver bevonásával), majd a tükör lokális példányából visszaépíteni a non-rootvg adatait
7) Amennyiben szükséges, úgy még 1-2 utó konfigurációs munkát el lehet végezni (igényeknek megfelelően), aztán mindent lehet is szépen visszaindítani

Nézzük meg akkor ezeket a lépéseket közelebbről is:

1) RPV szerver allokáció
A diszk allokálást nem fogom részletezni, a diszkek kiajánlásába viszont érdemes kicsit belemenni. Tekintve, hogy alapértelmezetten a szükséges csomagok nincsenek telepítve, így mindenki kapja elő a 6.1/7.1es alap telepítő DVD/CD-ket és telepítse fel a 'glvm.rpv' bff csomagot (ebben megtalálhatóak a glvm.rpv.server, glvm.rpv.client, glvm.rpv.util LPP csomagok).
Amint ez megvan, meg kell adjuk az RPV szerverünk nevét. Ezt a smitty rpvservername_edit_dialog (fastpath), avagy a smitty rpvserver / Remote Physical Volume Server Site Name Configuration / Define/Change/Show Remote Physical Volume Server Site Name menüpontja alatt tehetjük meg Ha ez megvan, akkor el is kezdhetjük kiallokálni a diszkjeinket a smitty rpvserveradd_select (fastpath), avagy a smitty rpvserver / Add Remote Physical Volume Servers menüpont alatt
Physical Volume Identifiers 000dd32daa568b07 * Remote Physical Volume Client Internet Address [1.2.3.4] Configure Automatically at System Restart? [yes] Start New Devices Immediately? [yes]
# A 'Remote Physical Volume Client Internet Address'-nél a távoli gép IP-je kell, viszont azért én azt is hozzátenném, hogy az IP DNS neve legyen feloldható is (vagy DNS szerver, vagy /etc/hosts alapján)

Parancssori alternatíva (ha tudunk minden adatot (rpvs_pvid, client_addr)):
/usr/sbin/mkdev -c rpvserver -s rpvserver -t rpvstype -a rpvs_pvid=000dd32daa568b07 -a client_addr=1.2.3.4 -a auto_online=y

Ezt mint mondtam el kell játsszuk az összes migrálásra szánt PV-re, viszont itt azért felhívnám a figyelmet arra, hogy hiába rendelünk 1-1 rpvserver-t minden egyes diszkhez, az AIX attól még nem foglalja le az original diszket, így simán előfordulhat, hogy véletlenül (oda nem figyelés), vagy csak más kollégák "segítsége" miatt a diszket más kezdi el időközben használni, így én azt is javasolnám, hogy valahogy ezeket a diszkeket jelöljük meg (vagy rendev-vel nevezzük át őket, vagy simán csak hozzunk létre rajtuk egy VG-t (pl. migrationvg1 - ezzel is feltüntetve, hogy a diszkek a migrációhoz lesznek felhasználva)

2) RPV kliens konfiguráció és VG extension
Felkonfigurálni a kiosztott diszkeket se lesz nehezebb, mint kiosztani őket, bár a 6192es portot lehet át kell engedni a szerver és a kliens között a tűzfalon. Ha a glvm.rpv.client csomagot még nem telepítettük, akkor itt az ideje, ellenkező esetben smitty rpvclientadd_select_ip (fastpath) avagy a smitty rpvclient / Add Remote Physical Volume Clients menü alatt fel is vehetjük az első pontban kiosztott diszkeket.
Remote Physical Volume Server Internet Address 2.3.4.5 Remote Physical Volume Local Internet Address 1.2.3.4 Physical Volume Identifiers 000dd32daa568b07 I/O Timeout Interval (Seconds) [180] Start New Devices Immediately? [yes]
Parancssori alternatíva (ha tudunk minden adatot (pvid, server_addr, local_addr)):
/usr/sbin/mkdev -c disk -s remote_disk -t rpvclient -a pvid=000dd32daa568b070000000000000000 -a server_addr=2.3.4.5 -a local_addr=1.2.3.4 -a io_timeout=180

Ahogy az rpvserver-eket is külön-külön kellett kiosztani, így az rpvclient-eket is egyesével kell felkonfiguráljuk.
Ha sikerült mindegyiket szépen berángatni, akkor még vissza van az, hogy az új diszkeket betoljuk a VG alá.
Alapjáraton ugye erre egy sima 'extendvg $VG $HDISK' elég lenne, viszont mivel hogy itt egy teljes tükröt akarunk csinálni, így mielőtt még ebbe bárki belefogna melegen ajánlanám, hogy nézze meg, hogy minden diszk bele fog e férni a VG alá (Ha a MAX PVs /2 kissebb, mint a "TOTAL PVs" akkor garantáltan nem fog beleférni ; Ez mellett még figyeljük arra is, hogy a MAX PPs per PV * PP SIZE se érje el a diszkünk aktuális méretét (különben nem fog bele férni a VG-be)). Amennyiben itt problémába ütközünk, úgy simán előfordulhat, hogy a VG-nél factor-t kell állítani, vagy a VG-t át kell konvertálni (BigVG-be avagy ScalableVG-be attól függően hogy épp milyen VG-nk van, viszont azt tessék észben tartani, hogy Normal - BigVG konverziót lehet online csinálni (már ha nem Concurrent VG-nk van), míg Scalable-be csak offline (varyoffvg után) tudnánk, így itt még némi extra outage befigyelhet).
Amennyiben ilyen problémába nem ütközünk bele, úgy simán mehet az extendvg.

# Megjegyzés: Ha előzőleg a diszkekre létrehoztunk egy külön VG-t (hogy megjelöljük a diszkeket), úgy az extendvg-nél szükség lesz a -f kapcsolóra, de ez esetben figyelmesen járjunk el és bizonyosodjunk meg róla, hogy tényleg jó diszket piszkálunk, mielőtt egy rossz diszk VGDA-ját vágnánk felül.

3) VG tükör létrehozás
Itt jön most az, hogy tükrözni kéne, ugye :) Ha ezt eszetlenül meg is kíséreljük ebben a fázisban, akkor a legtöbb esetben szembe is jön ez a hiba:
# mirrorvg appvg 0516-404 allocp: This system cannot fulfill the allocation request. There are not enough free partitions or not enough physical volumes to keep strictness and satisfy allocation requests. The command should be retried with different allocation characteristics. 0516-1517 mklvcopy: Failed to create a valid partition allocation. 0516-842 mklvcopy: Unable to make logical partition copies for logical volume. 0516-1199 mirrorvg: Failed to create logical partition copies for logical volume applv. 0516-1200 mirrorvg: Failed to mirror the volume group.
Noh kérem, ez azért van mert mint fentebb említettem a GLVM azért megkövetel 1-2 LV beállítást, mielőtt az RPV-t ténylegesen a VG részeként kezelné. A szükséges beállítások a következők:
- A szerver IP címe itt se árt ha feloldható (reverse DNS lookup), így -ahogy azt már fentebb is kiemeltem- érdemes az IP-t a /etc/hosts alá felvenni.
- A VG alatt lévő összes LV allocation policy-je Superstrict kell legyen. Ezt a 'chlv -s s -u 32 $LV' paranccsal tudjuk online állítani
# Megjegyzés: a -u 32 az upperbound limitet jelöli, ami több PV-n szétterülő LV-k esetén lehet nagyobb is mint 32; viszont nincs értelme magasabbra állítani, mint a VG-ben lévő PVk száma.
- Az VG alatt lévő összes LV inter-policy-je legyen minimumon. Ezt a 'chlv -e m $LV' paranccsal online tudjuk állítani

Ha ezek megvannak, akkor kezdhetjük is a tükrözést, bár itt felhívnám a figyelmet arra, hogy mivel meglehetősen sok adatot készülünk áttolni a hálózaton, így érdemes elgondolkodni azon, hogy pontosan hogy is akarjuk a mirrort összehozni:
- Minden LV-t külön-külön (esetleg csoportokban) tükrözünk meg az 'mklvcopy -s s $LV 2 $HDISK' paranccsal (ez esetben a hálózati terhelést megpróbálhatjuk korlátozni a szerviz időn kívülre némileg, bár ha egy LV mirror-t elindítottunk, akkor azt onnan ne akarja senki se leállítani :) Továbbá érdemes szem előtt tartani, hogy az mklvcopy az előtérben fut, így a console-unk egy ideig valószínű használhatatlan lesz (már amíg a türközés be nem fejeződik)
- A teljes VG-t egyben a mirrorvg paranccsal (ez esetben javasolnám a -S kapcsoló használatát azon oknál fogva, mert így a mirror a háttérben fog folyni, és nem fogja megakasztani az lsvg, lslv parancsokat (mivel nem lesz konstans lock a VGDA-n). Ez a módszer akkor jó, ha az rpvserver, rpvclientek által használt hálózat szeparált a customer networktől, így a hálózati kommunikáció nagyon nem fog bezavarni az ügyfél ügyes-bajos dolgaiba.

Bármelyik módszer mellett is döntünk, arra azért legyünk felkészülve, hogy egy jó ideig el fog tartani a folyamat. Kb az alábbi dolgok befolyásolják a szükséges időt:
- Hálózati sávszélesség (ha van valami izmosabb gigabites kapcsolat, vagy esetleg valami link-aggregation akkor a jumbo-frame-ekkel itt garantáltan jól járunk). Ha viszont Virtualizált a network, akkor készüljünk fel, hogy a PVID-ra ráakaszkodott más LPAR-ok is beleszólhatnak a játékba (illetve vice-versa: a mi kliens LPAR-unk is beleszólhat az ő játékaikba :))
- Kliens oldali I/O terheltség (attól függően hogy az alkalmazások mennyire pörgetik a diszkeket)
- Kliens/szerver oldali I/O adatátviteli sebesség

Érdemes a tényleges mirror előtt egy tesztet csinálni, ha ki is akarjuk deríteni hogy pontosan milyen sebességet is tudunk elérni a 2 gép között, hogy legalább hozzávetőlegesen meg tudjuk becsülni a szükséges időt a tükör felépítéséhez.

4) Checkpoint, VG tükör fenntartása
A tükör felépültét, illetve épségét az 'lsvg -l $VG ' paranccsal tudjuk a legkönnyebben monitorozni -> ha az összes LV open/syncd-be van (és az PPs száma dupla az LPs-nek) akkor örülhetünk, mert az adat mozgatás nagyja már meg is volt, ráadásul úgy hogy eddig (elméletben) 1 perc kiesés nem volt. Itt az ideje lebeszélni a customerrel, hogy pontosan mikor is lehet a szervert költöztetni.
Amennyiben a megállapodott időpont a nem túl közeli jövőben lenne, úgy figyeljünk arra, hogy a tükör ép is maradjon (ne nagyon indítgassunk újra dolgokat, illetve imádkozzunk, hogy ne nagyon legyen hálózati probléma). Amennyiben a kapcsolat ideiglenesen bármilyen oknál fogva time out-ra futna, akkor a hálózati hiba elhárítása után az rpvclient-eket manuálisan kell ismét felhúzzuk, majd a tükröt helyre állítsuk (immár kevesebb időbe fog telni, mint egy full remirror, de azért ez is eltarthat egy darabig).
Azt viszont tessék észben tartani, hogy ettől a ponttól kezdve minden diszkre történő írás mind a 2 oldalon kell érvényesüljön, így a hálózat képes lehet az I/O loadot némileg visszafogni (szóval nagyon I/O write intenzív alkalmazás lehet hogy nem fogja magát túl jól érezni egy ilyen környezetben)

5) Létrehozott tükör felhasználása/megtörése
Ha eljött az idő a migrálásra, akkor először is győződjünk meg róla, hogy a tükör/tükrök még mindig jó állapotban vannak, ez után készítsünk a rootvg-ről egy mksysb-t (ha 6.1 TL9, vagy 7.1 TL3 SP1-en avagy afölött vagyunk, akkor a -T kapcsolóval egy meglehetősen probléma mentes backup készíthető, hála a snapshotingnak :)), amit aztán másoljunk át a hálózaton keresztül a távoli NIM szerverre.
Ha ez megvan, akkor választás előtt állunk: Mit is akarunk kezdeni a felépített tükrünkkel? 2 féle lehetőség adódik ugyan is:
- Megtörhetjük a tükröt a splitvg paranccsal
- Felhasználhatjuk a tükör felét a recreatevg paranccsal

A 2 módszer célja kb azonos, viszont a kivitelezés merőben eltér egymástól, így érdemes belemenni, hogy melyiknél mire is kell számoljunk:

a) A splitvg esetén (ajánlom a -i kapcsolót) az RPV diszkekre készített mirror copy-t le tudjuk választani az eredeti VG-ről, ezzel egy új (és szép konstans) VG-t hozva létre. Az új VG nevét mi állítjuk be, viszont az esetleges LV név és FS mount ütközést elkerülendő az AIX automatikusan hozzá fog csapni minden LV-hez egy fs prefixet (tehát lv01-ből lesz egy fslv01), illetve az eredeti mount point helyett a /fs/$ORIGINAL_MOUNT lesz az alapértelmezett mount (/app/log helyett /fs/app/log). Ez kapásból azt is jelenti, hogy:
- Ezeket a változásokat a cél helyen majd vissza kell kézzel csináljuk
- Az LV név változtatás bizonyos helyzetekben lehet macerás lesz, főleg ha van olyan LV a VG alatt ami alapjáraton 15 karakter hosszú (default maximum) ami a splitvg eredménytelen lefutását eredményezi (tekintve, hogy a splitvg nem lesz képes a prefixel megtoldani az LV nevet). Ezeket az LV-ket még a splitvg előtt át kell így nevezni, ám ha az érintett LV pont egy RAW kötet/container, akkor ott komoly problémáink lehetnek (tekintve, hogy az adatbázisok hajlamosak a /dev/$LV_NAME-re ráakaszkodni, ergo amíg az adatbázis az LV-t használja, addig nem is lehet azt átnevezni)

b) A recreatevg esetén a tükröt nem a forrás oldalon törjük meg, hanem a cél szerver oldalon -> a recreatevg képes a tükör feléből visszaépíteni a VG-t (immáron mirroring nélkül), ami annyiból jó, hogy (ha jól van felparaméterezve) nem kell szöszölni az LV nevek és FS mount pointok utólagos állítgatásával a cél oldalon, viszont cserébe ha valamilyen oknál fogva vissza szeretnénk állni az eredeti szerverre, akkor abban a problémában fogjuk magunkat találni, hogy mivel a recreatevg belenyúlt a VGDA-ba (és új vg_id-t generált), így a source oldalon felépített tükrünk nem hogy törött lesz, hanem egyenesen használhatatlan (amit egy újabb recreatevg-vel tudunk csak helyrepofozni, immár ismét tükör nélkül, ergo az egész játékot lehet kezdeni elölről).
Továbbá érdemes megjegyezni, hogy ha ezt a módszert szeretnénk használni, akkor érdemes a Quorum-ot is kikapcsolni a 'chvg -Qn $VG' parancsal :)

Én személy szerint eléggé megbarátkoztam már a recreatevg-vel ahhoz, hogy különösebb szív problémák nélkül merjem használni, de az aki inkább a biztosabb konzisztencia irányába szeretne elmenni, az inkább ne ezt a módszert használja.

Miután sikerült eldöntenünk, hogy melyik módszer mellett tesszük le a voksunkat (én maradok a recreatevg-nél :)) szépen mountoljuk le a filerendszereinket, tegyük a VG-t varyoffba, és biztos ami biztos még engedjünk el egy 'sync;sync;sync'-et hogy minden konzisztens is legyen. Ezután a forrás gépet lényegében le lehet állítani.

6) Migráció véglegesítése a cél gépen.
Miután a NIM szerverről visszatöltöttük az előzőleg elkészült mksysb-t, már csak annyi a dolgunk, hogy visszarángassuk az appvg-(in)ket az ODM-be. Ehhez első körben el kell távolítsuk az rpvserver device-okat, majd attól függően hogy az 5. pontban melyik módszer mellett döntöttünk használhatjuk ..
.. az importvg-t: ez esetben elég ha az importvg-nek egy diszket megadunk (importvg -y $VGNAME $HDISK) , a parancs automatikusan kiolvassa a VG-t alkotó diszkek PVID-ját, és végigellenőrzi, hogy mind megtalálható e a rendszer alatt, majd beimportálja a VG-t a rendszer alá. Ne felejtsük el visszaállítani az eredeti mount pointokat, illetve LV neveket (plusz az FS-ek loglv nevét) ez után
.. a recreatevg-t: ez esetben nekünk kell kézzel megadni, hogy a VG mely diszkekből épül fel pontosan (recreatevg -y $VGNAME -Y NA -L / -f $HDISK1 $HDISK2 $HDISKN). A sikeres futtatás után a rendszer egy új VG-t épít fel a VGDA-ban elérhető adatok alapján, amit aztán további módosítások után szabadon is használhatunk

***********************
Ezzel a módszerrel (optimális esetben) pár óra kieséssel megoldható egy szerver költöztetés, úgy hogy az előkészületeket már jóval a költöztetés kezdete előtt megkezdi az ember. A módszernek persze ára van, cserébe a customer dédelgetett szolgáltatása (némi kis performance veszteség árán) képes folyamatosan üzemelni és ellátni a "kritikus" (!!!) feladatait.

2013. augusztus 10., szombat

"Még jőni kell, még jőni fog egy jobb core.." - Népköltés..

Majd 3 hónap.. Ennyi ideje nem írtam erre e blogra semmit..
Nem azért mert szabadságon voltam, vagy mert elfelejtettem.. Egyszerűen nem volt miről írni ami erre a blogra tartozott volna (az, hogy hogyan lehet Monitoringot migrálni, meg HMC-t 4.4-rol 7.7re felupgrade-elni nem olyan jó alapanyag higgyétek el), vagy pedig szimplán olyan természetű volt amit a jelenlegi szerződésem nem enged meg (pedig jó lenne írni egy cikket róla.. ki tudja, majd 1x talán).
Hiába, ez van ha az ember nem foglalkozhat a hétköznapi adminisztrációval, hanem csak "project tevékenységekkel"

Ami azt illeti, a mostani téma se olyan nagy eresztés, de gondoltam azért még valakinek így is jól jöhet még ez.

Na szóval a helyzet: Adott egy core file a rendszeren (VIO szerver), ráadásul meglehetősen nagy méretben:

server@root # ls -l /core
-rw------- 1 root system 829566976 Jul 27 19:45 core
Igen, ez egy majd 800 MB-os darab, ráadásul a / FS alatt, amit a rendszer adminok nem véletlenül utálnak, legfőképp VIO szervereken.
A feladat: kideríteni, hogy:
- Mi dobta a core-t
- Miért dobta az a valami azt :)

Az első kérdésre alap esetben azt mondanám, hogy az errpt-ben nézzünk körbe, viszont most pont sikerült egy olyan helyzetbe bele fussak, ahol az errpt (más hibák miatt) már rotálódott, szóval más utat kell találni ennek kiderítésére. Sebaj, van 2 módszer is amit lehet használni:

1) - strings parancs: kicsit ügye fogyott, de azért még jól használható arra, hogy 1-2 környezeti adatot megismerjünk :)
server@root # strings /core | grep ^_=
 _=/opt/IBM/ITM/aix523/va/bin/kvaagent
 _=nY
 _=/usr/bin/grep
 _=/u
 _=/u
Ebből persze még nem lehet sok mindent levonni, de az a /opt/IBM/ITM/aix523/va/bin/kvaagent igen kecsegtetően néz ki.

2) - lquerypv: Az ember nem is gondolná mennyire de hasznos tud lenni ez a kis parancs, pedig meglehetősen sokoldalú, ha tudjuk mit és hol is keressünk :) Jelen esetben a 6E0 cím az ami minket foglalkoztat, ugyan is AIX alatt a core file-on belül mindig ezen a címen kell legyen az aktuális bináris neve, ami a core-t dobta:
server@root # lquerypv -h /core 6E0 16
 000006E0 61697844 61746150 726F7669 6465722D |aixDataProvider-|
 000006F0 36310000 00000000 00000000 00000000 |61..............|
aixDataProvider-61.. Ez persze nem sokat mond egy átlagos embernek, aki viszont dolgozott már ITM6 alatt VA agent-el az tudhatja, hogy ez az a process ami a kvaagent alatt fut szinte mindig, ergó jó nyomon járunk.

Nézzük a 2. kérdésre a választ.. Hogy került oda az a core.. Nos, ennek megállapításához több dolog is kell:
- Az aktuális bináris ami a core-t dobta (nem baj, azt az első lépésben már megtaláltuk, max a pontos helyét nem tudjuk még, de azt egy find se perc alatt megmondja :)
- DBX parancs azonos kernel és futtatókörnyezetben (Ez se gáz, max használjuk azt a gépet ahol az issue előjött :))
- Némi kis tudás, hogy mit is kéne nézni ...
- .. Illetve hogy hogy is kéne értelmezni..
Na haladjunk sorban, aztán meglássuk meddig jutunk..
- Na szóval, első pont: Az aktuális binárisunk.. Rövid find keresés, majd meg is találjuk a /opt/IBM/ITM/aix523/va/bin/aixDataProvider-61 alatt.
- Második pont: A dbx parancs a bos.adt.debug csomag része, ha nincs fent a gépen, akkor vagy feltesszük, vagy keresünk egy másik gépet ami megfelel a fenti kritériumoknak. Jelen esetben nekem épp fent volt a csomag :)
- Harmadik pont. Na itt jön a vicces rész. 1x is be kell hívjuk a core-t a dbx debuggerbe, majd meg kell néznünk hol is akadt el, aztán abból kitotózni, hogy mi volt a gond.
Kezdésként hívjuk be a dbx-et ay adott core file-ra:
server@root #  dbx /opt/IBM/ITM/aix523/va/bin/aixDataProvider-61 /core
 Type 'help' for help.
 warning: The core file is truncated. You may need to increase the ulimit
 for file and coredump, or free some space on the filesystem.
 [using memory image in /core]
 reading symbolic information ...warning: no source compiled with -g 
 
 Segmentation fault in . at 0x100286cc ($t1)
 0x100286cc (???) 7cc5212e stwx r6,r5,r4
Majd nézzük meg hol is hasaltunk el (where parancs):
(dbx) where
 get_diskstats() at 0x100286cc
 adp_get_diskstats(0x2ff21804) at 0x10005a88
 dt_CollectDiskData(0x3052a680, 0x30321748) at 0x1002d6a8
 dt_CollectData(0x3052a680, 0x30321748) at 0x10031b74
 itmTranslator(0x0) at 0x10032834
 main(0x1, 0x2ff21e40) at 0x1000619c
Na ez a legtöbb embernek nem mond semmit a kód ismerete nélkül (nyugi, az adminoknak se), viszont tökéletes kiinduló alap, hogy megnézzük, hogy ismert stack-ről van e szó (IBM jó szokása, hogy sokszor mellékelnek stack példát az ismert bugokhoz, így csak a stack ismeretével is el lehet indulni valamerre (Ha meg nem találunk semmit, akkor is rossz esetben a stack-el nyitni lehet egy PMR-t és hivatalos segítséget kérni).

Esetünkben mondhatni mázlink van: A 'get_diskstats adp_get_diskstats dt_CollectDiskData dt_CollectData itmTranslator site:ibm.com' google keresőszavak meglehetősen sok találatot adnak. A legjobb találat azt hiszem ez az oldal ahol 4 helyen is szinte azonos stack van (minimális eltérésekkel), így már csak arra kell rájöjjünk, hogy az oldalon említett IF0004 (version 6.2.2.2 FP4) valóban megoldja e a problémát. Ehhez persze nem árt tudni, hogy most épp milyen szinten van a progink :)

Erre ITM6 alatt 2 verzió van:
- Ha az UX agent is telepítve van, akkor /opt/IBM/ITM/aix526/ux/bin/itmver.sh script segítségével ki lehet kérni bármelyik agent verzió számát (sajna ez az én VIO-mon nem volt fent)
- A /opt/IBM/ITM/registry/ mappa alatt lévő file-ből ki lehet nézni a verziót direktben (grep a VRMF stringre) :)
server@root #  # grep VRMF /opt/IBM/ITM/registry/vaaix*.ver
 VRMF = 06220102
Jelen esetben ez a következőt jelenti: version 06.2.2.01.02 -> 6.2.2.1 FP02.

Bingó. /* Nem véletlenül standard policy az, hogy frissíts ha teheted, mert a hibák nagyja már esélyes, hogy javítva van */

2013. május 16., csütörtök

Corrupt system dump - Nem bírja a rendszer, szívjál még egyszer..

Sajnos az elmúlt időszakban inkább project jellegű munkákkal kellett foglalkozzak (ami inkább a tervezési munkálatokat fed le), mint sem tényleges rendszer üzemeltetéssel (ami meg az esetleges hibák debugolását), így el kellett telnie némi kis időnek, míg valami fincsi problémára rá tehettem a kezem.
Most viszont végre sikerült valami kellemesbe is belekóstolnom :)

A történet előzménye röviden a következő: Adott egy nem épp up-to-date AIX rendszer, ami hirtelen dobott egy hátast, plusz a hozzá járó kernel dumpot, és ki kéne deríteni, hogy pontosan mi a fene lehetett a háttérben (az applikáció eléggé nem szereti a magasabb AIX levelt, így mielőtt ráböföghetném, hogy "AIX-et kéne frissíteni wazze" még be kell bizonyítanom, hogy valóban az AIX volt e a ludas). Tekintve, hogy az ilyen jellegű vizsgálódások annyira nem állnak tőlem távol, így örömmel kezdtem neki a probléma megoldásának, bár az örömöm nem tartott sokáig..

Kezdésként nézzük a helyzetet:
# oslevel -s
5300-08-02-0822
// No igen.. Ennek a TL-nek a hivatalos supportja még 2010 Áprilisában járt le, ráadásul még 2010 Májusban kiadtak hozzá az SP10-et. Ez az SP még 2008ban jött ki, szóval gondolhatjátok, hogy milyen régi applikáció futhat rajta, ami miatt még az AIX-et se merik upgrade-elni..
# errpt | head -3
IDENTIFIER TIMESTAMP  T C RESOURCE_NAME  DESCRIPTION
67145A39   0325114513 U S SYSDUMP        SYSTEM DUMP
F48137AC   0325114213 U O minidump       COMPRESSED MINIMAL DUMP

Jó.. Szóval legalább az alapok meg vannak.. Nézzük, hogy mire számítsunk:
# errpt -aj 67145A39
---------------------------------------------------------------------------
LABEL:          DUMP_STATS
IDENTIFIER:     67145A39

Date/Time:       Mon Mar 25 11:45:00 NFT 2013
Sequence Number: 900224
Machine Id:      00CD98ED7C00
Node Id:         application_server
Class:           S
Type:            UNKN
Resource Name:   SYSDUMP         

Description
SYSTEM DUMP

Probable Causes
UNEXPECTED SYSTEM HALT

User Causes
SYSTEM DUMP REQUESTED BY USER

        Recommended Actions
        PERFORM PROBLEM DETERMINATION PROCEDURES

Failure Causes
UNEXPECTED SYSTEM HALT

        Recommended Actions
        PERFORM PROBLEM DETERMINATION PROCEDURES

Detail Data
DUMP DEVICE
/dev/dumplv
DUMP SIZE
            2147483136
TIME
Mon Mar 25 11:40:12 2013
DUMP TYPE (1 = PRIMARY, 2 = SECONDARY)
           2
DUMP STATUS
          -2
ERROR CODE
           0
DUMP INTEGRITY
This dump may be unusable - The alloc_kheap component is missing. 
This dump may be unusable - The alloc_other component is missing. 
This dump is incomplete - The end-of-dump component is missing. 

FILE NAME

PROCESSOR ID
           0
Tehát a rendszer váratlanul megállt, de a keletkezett dump nem teljes.. Innen indul a kihívás..

Tekintve, hogy van egy minidump-unk, így legalább abban reménykedhetünk, hogy abból ki tudunk valamit hámozni. Erre a legegyszerűbb az mdmprpt parancs.
# mdmprpt 
MINIDUMP VERSION 4D32
***************************************************
64-bit Kernel, 108 Entries

Last Error Log Entry: 
         Error ID: 9AA1914A      Resource Name: SYSVMM 
         Detail Data: 0000000042000000 00007FFFFFFFD080 
        F10001005DDD11F0 FFFFFFFFFFFFFFF3

This minidump is corrupted
Meg se lepődök.. Tekintve, hogy a dump-unk incomplete, így nem is vártam konzisztens dump-ot, bár a corrupt dump azt jelenti, hogy esélyünk nincs ezt az entry-t ellenőrizni. Egyedül annyi derül ki, hogy az utolsó jegyzett hiba a 9AA1914A error ID-ra mutat, ami a SYSVMM-hez köthető. Gyors segítség: VMM - Virtual Memory Manager, így innentől már sejthető, hogy itt valami memória művelethez köthető dolgon csúszott meg a rendszer. De azért nézzük meg, hogy a 9AA1914A error ID mit is takar a valóságban:
# grep -i 9AA1914A /usr/include/sys/errids.h
#define ERRID_DSI_MEMOVLY    0x9aa1914a /* A kernel memory overlay has been detected */
Memory overlay - teljesen fedi a VMM hatáskörét, úgy hogy eddig ez rendben is van.. Na de hogyan tovább? Ja igen.. Van még egy dumpunk. Ezt mentsük le a dump device-ról amíg lehet, aztán nézzük meg mit találunk benne:
# dd if=/dev/dumplv of=/dump_check/sysdump bs=4096 count=2147483136
// Itt megállnék egy pillanatra: Normális esetben a dump compression be van kapcsolva, ami azt jelenti, hogy a kiszedett dump-ot még ki is kéne tömöríteni a dmpuncompress paranccsal, jelen esetben viszont erre nem volt szükség, mivel a dump compression ezen a gépen nem volt bekapcsolva. Innentől lehet tippelni, hogy miért is nem fért el a dump, és hogy én ez miatt mennyire de boldog voltam.
# kdb /dump_check/sysdump
The specified kernel file is a 64-bit kernel
sysdump mapped from @ 700000000000000 to @ 70000007ffffe00
Preserving 1411195 bytes of symbol table
First symbol __mulh
Component Names:
 1)  minidump [2 entries]
 2)  dmp_minimal [9 entries]
 3)  dump_pad53 [1 entries]
 4)  proc [4101 entries]
 5)  thrd [7291 entries]
 6)  rasct [1 entries]
 7)  ldr [2 entries]
 8)  iplcb [1 entries]
 9)  errlg [3 entries]
10)  mtrc [98 entries]
11)  lfs [1 entries]
12)  bos [4 entries]
13)  ipc [7 entries]
Premature end of data in dump file.
Component Dump Table has 11523 entries
           START              END 
0000000000001000 0000000003E04050 start+000FD8
F00000002FF47600 F00000002FFDC940 __ublock+000000
000000002FF22FF4 000000002FF22FF8 environ+000000
000000002FF22FF8 000000002FF22FFC errno+000000
F100070F00000000 F100070F10000000 pvproc+000000
F100070F10000000 F100070F18000000 pvthread+000000
PFT:
PVT:
id....................0002
raddr.....0000000002000000 eaddr.....F200800090000000
size..............00080000 align.............00001000
valid..1 ros....0 fixlmb.1 seg....0 wimg...2
Unable to establish context with current thread
Unable to establish context with current thread
Unable to find kdb context
Dump analysis on CHRP_SMP_PCI POWER_PC POWER_6 machine with 32 available CPU(s)  (64-bit registers)
Processing symbol table...
.......................done
        ERROR: Unable to acess nfs_syms
(0)> where
Unable to establish context with current thread
Unable to establish context with current thread
[kdb_read_mem] no real storage @ F1000100100EE800
Unable to establish context with current thread
Unable to establish context with current thread
Unable to find kdb context
(0)> f
Unable to establish context with current thread
Unable to establish context with current thread
[kdb_read_mem] no real storage @ F1000100100EE800
Unable to establish context with current thread
Unable to establish context with current thread
Unable to find kdb context
(0)> stat
SYSTEM_CONFIGURATION:
CHRP_SMP_PCI POWER_PC POWER_6 machine with 32 available CPU(s)  (64-bit registers)

SYSTEM STATUS:
sysname... AIX
nodename.. application_server
release... 3
version... 5
build date May 12 2008
build time 23:42:11
label..... 0820A_53N
machine... 00CD98ED7C00
nid....... CD98ED7C
time of crash: Mon Mar 25 11:39:02 2013
age of system: 124 day, 7 hr., 56 min., 32 sec.
xmalloc debug: enabled
Debug kernel error message: A program has tried to store to freed or redzoned xmalloc memory.
Address at fault was 0xF10001005DDD11F0
Na akkor röviden: Az alap parancsok mind elhullanak azon oknál fogva, mert a dump-unk nem teljes, amúgy meg annyit tudunk meg mint előzőleg - memória kezelési gubancok vannak a háttérben.

Egy dolog viszont ott van amit talán lehet használni: a CDT adatok (component-dump tables), amit a kdb az elején jelzett is. Ami nekünk kelhet az jelen esetben a minidump, vagy az errlg tábla, tekintve, hogy ezek még talán tartalmazhatnak valami kis támpontot, hogy merre tovább.

Első körben én a minidump-ra koncentráltam:
(0)> cdt 1
Dump table entries in CDT:

CDT ENTRY VMHANDLE       ALIAS        ADDRESS LENGTH   NAME
  1     1 kernel             0000000002B1AA50 00000046 md head
  1     2 kernel             0000000002F1E9FC 00000E60 minidump
Tekintve, hogy a dump is tartalmazza a minidump-ot, így első körben az volt a tervem, hogy azt fogom kiszedni onnan, majd használható állapotba hozni, viszont egy részről ez -mint utólag kiderült- nem volt kivitelezhető (az okokat most nem tárgyalom), így más útvonalon kellett elinduljak
// Az minidump-al való mókolást szerintem majd egy külön blogban tárgyalom ha lesz rá érdeklődés

Mázlimra az AIX-nek van 1-2 beépített parancsa bizonyos típusú adatok kinyerésére a dump file-okból, csak ezeket valamiért a dokumentációk nem nagyon emlegetik. Az egyik ilyen parancs a dmp_minimal (ami még véletlenül sincs dokumentálva), a másik pedig az errdead (ami még úgy ahogy dokumentált).
Előző célja, hogy az elérhető minidump-ot kinyerje a dump file-ból, és megpróbálja azt értelmezni, utóbbi pedig a boot során keletkezett error logok kinyerésére használható a dump file-ból.
#  /usr/lib/ras/dmprtns/dmp_minimal /dump_check/sysdump|tail -15
traceback:
 iar:0000b920 unknown
  lr:002f7eac slock+148
addr:002f806c slock+308
addr:000090c4 unknown
addr:044901f8 store_packet+70
addr:04490880 pcd_output[DS]+98
addr:044473f8 en_output+1218
addr:0430974c ip_output_post_fw+1f50
addr:04309b04 ip_output+100
addr:0433bb44 tcp_output+2404
addr:0436d2a0 tcp_usrreq+17a8
addr:00223760 sosend+c88
addr:0023b2b8 send+4e0
addr:00003814 unknown
Na, legalább van egy stack-ünk. Megerősítésként azért nem árt átnézni az error logot is. Ehhez simán extractoljuk ki az error logot a dump-ból, majd adjuk oda az errpt-nek:
# /usr/lib/errdead -i ./errpt_out /dump_check/sysdump 
# errpt -i errpt_out
IDENTIFIER TIMESTAMP  T C RESOURCE_NAME  DESCRIPTION
9AA1914A   0325113913 P S SYSVMM         INVALID MEMORY REFERENCE
77EED6D9   0325113913 U S SYSALLOC       Deferred-free or redzoned memory read
Hoppá. Emlékszik még valaki a 9AA1914A-es hibakódra? Igen, ez az amire az mdmprpt is panaszkodott. Legalább ez az infó is megvan akkor. Sajna azonban a 9AA1914A-es error logban nem sok használható infó van, viszont annál több a 77EED6D9-esben:
# errpt -i errpt_out -aj 77EED6D9
---------------------------------------------------------------------------
LABEL:          XM_READ_FREE
IDENTIFIER:     77EED6D9

Date/Time:       Mon Mar 25 11:39:02 NFT 2013
Sequence Number: 1
Machine Id:      00CD98ED7C00
Node Id:         application_server
Class:           S
Type:            UNKN
Resource Name:   SYSALLOC        

Description
Deferred-free or redzoned memory read

Probable Causes
LOADABLE SOFTWARE MODULE
SOFTWARE DEVICE DRIVER
OPERATING SYSTEM

Failure Causes
MEMORY ALLOCATION ERROR

        Recommended Actions
        PERFORM PROBLEM DETERMINATION PROCEDURES
        CONTACT YOUR LOCAL IBM SERVICE REPRESENTATIVE

Detail Data
Stack Trace
slock+11C
slock+304
[90C0]
store_packet+6C
pcd_output[DS]+94
en_output+1214
ip_output_post_fw+1F4C
ip_output+FC
tcp_output+2400
tcp_usrreq+17A4
sosend+C84
send+4DC
[3810]
-errSTKfrm-
Mint látható, a 2 parancs által szerzett stack kb azonos (annyi különbséggel, hogy az errpt az ismeretlen hívások helyére valami -nekünk irreleváns- címet illesztett be), így nyugodtak lehetünk, hogy jó nyomon járunk.

Jó, de innen hova tovább? Azt nem tudjuk megnézni, hogy a regiszterekben milyen adat volt, a forráskódhoz nem férünk hozzá, hogy tudjuk minek és hol is kéne pontosan lennie, csupán egy stack állapotunk van. Ez miatt általában azt szoktam mondani, hogy tessék utána járni, hogy van e olyan APAR, ami hasonló, vagy (ami még jobb) azonos stack-et produkál e, ugyan is ekkor szinte biztosak lehetünk, hogy abba a bug-ba sikerült belebotlanunk, de még hasonlót se találtam ami ilyesmi stack-et írt volna le (a 2 unknown hívás meg pláne nem segít semmit).

Na innentől általában egyenes út a software call felé, de szinte biztos, hogy ilyen dump-al ők se tudnak sokat kezdeni, plusz mivel enyhén outdated AIX level-t futtatunk, így csuklóból közölnék, hogy ez a verzió nem támogatott, illetve ajánlatos lenne azonnal update-elni, mivel azóta már jó pár javítás kijött, és hátha valamelyik erre is megoldást nyújtana.

// Itt akár be is fejezhetném ezt a blog bejegyzést, ugyan is technikailag már sok újdonságot nem fogok leírni, viszont akit érdekel a teljes történet, annak azért leírom, hogy hogy is folytatódik ez a kis történet.

Na szóval. A probléma ezzel a felállással innentől az, hogy az ember 2 szék között a pad alá kerül rövid úton, úgy hogy ez így nem játszható.
Van azonban még 1 kis aranyágacska, amin el lehet indulni: A stackben látható pcd_output hívás nem része a standard AIX hívásoknak, így kis kutakodás után sikerült kideríteni, hogy azt egy extended kernel module biztosítja, ami az IBM RealSecure Server-hez (aka ISS) tartozik, ami akkor szintúgy bekavarhat, úgy hogy ennek a szálnak is utána kell járni.

// Megjegyzés: az ISS egy extra védelmi réteget húz a hálózati kommunikáció elé, és monitorozza a hálózati forgalmat. Ha valami gyanúsat észlel, akkor azt elvileg képes megfogni, így biztosítva némi IDS funkcionalitást. Az outdated AIX verzióra való tekintettel ennek jelenléte még teljesen érthető is..

Első körben a kérdés az, hogy milyen modul biztosítja azt a hívást.. 2 lehetőség van ennek kiderítésére: Vagy rátámaszkodunk a naming convention-re, és azt mondjuk, hogy a pcd_output hívás valószínű valami pcd szerű driver hozza, vagy megnézzük, hogy az ISS csomagban van e, és ha igen, akkor milyen driverek vannak a csomagon belül.
# lslpp -l |grep ISS
  ISSXss.ServerSensor        7.0.0.0  COMMITTED  IBM RealSecure ServerSensor
  ISSXss.ServerSensor        7.0.0.0  COMMITTED  IBM RealSecure ServerSensor
  
# lslpp -f ISSXss.ServerSensor |grep driver
/usr/lib/drivers/
/usr/lib/drivers/pcd.ext
Na.. Így már biztosabbak lehetünk a dolgunkban. Következő kérdés, hogy a modul valóban be volt e töltve a dump pillanatában.. Irány vissza a kdb-be, majd listázzuk ki a betöltött modulokat, és szűrjünk arra amit találtunk:
(0)> lle -k |grep pcd.ext
  9 03EDDB00 0448C000 00016150 00080252 /usr/lib/drivers/pcd.ext
Bingo.. Tehát be volt töltve. Innentől akkor már csak az a kérdés, hogy ez okozta e a hibát, avagy az AIX. 100%-ra pontosan persze nem tudjuk megmondani, de azt azért érdemes megnézni, hogy az ISS-ünk is outdated-e.

Na itt kezdődött a következő problémám.. A hivatalos IBM javítások között a legfrissebb verzió a 7.0.42.2, a rendszeren viszont semmiféle utalás nincs a pontos verzióra nézve, csupán a csomag 7.0.0.0-ás verziószáma, ami viszont véletlenül se használható támpont.
A végleges megoldás végül az lett, hogy leszedtem a javítást az IBM FixCentral oldaláról, kicsomagoltam a base64 encode-olt telepítőt (így kaptam egy BFF csomagot), abból kibontottam a tényleges file-okat, és összehasonlítottam a checksum értékeket a rendszeren lévőkkel: Egyeztek -> Tehát ebből a programból legalább a legfrissebb verzió volt telepítve a gépre.

// Ez úton is üzenném minden programozónak, hogy valami nyamvadt verziózást rakjatok már bele a programotokba, különben lehetetlen lesz lekövetni, hogy épp mikor kell frissíteni az adott szoftvert.

Tehát a felállás innentől a következő: Van egy program, aminek a kernel module-ja szinte biztos, hogy szerepet kapott a hibában, viszont az a jelenlegi legfrissebb verzió, ergo vagy sikerült egy olyan bugba belebotlani, amire még vagy nincs javítás, vagy még nem is ismert, vagy tényleg az AIX outdated státusza okozta a galibát, és kompatibilitási hibával állunk szemben. Utóbbit sajna biztosra meg nem lehet mondani, mivel a hivatalos dokumentum véletlenül se taglalja, hogy van e TL/SP függősége, így nem maradt más hátra, mint közölni a customerrel, hogy nagy eséllyel tényleg frissíteni kéne az AIX-et (Minimum felrakni a legutolsó Service packot ehhez a TL-hez; azt az applikáció nagyobb eséllyel éli túl, mint mondjuk egy TL upgrade-et), bekapcsolni a dump compression-t, és ha az után is előjön a probléma, akkor újabb SW call-t nyitni. Ha ez nem kivitelezhető, akkor sorry, de ez egy olyan known risk amivel együtt kell majd élnie.

2013. március 3., vasárnap

"Mondanám hogy szőke, de sötét mint az éjszaka"

Azt hiszem írtam már ezen a blogon párszor, hogy az ember egy idő tán meglehetősen magasra emeli a mércét ha arról van szó, hogy min is lepődik meg X évnyi pályafutás után de sose mondja senki, hogy még ilyenkor se tudja kiverni semmi a biztosítékot.. Avagy amikor az ember azt hinné, hogy mélyebbre már nem lehet süllyedni, de valaki még is megtalálja a Mariana-árok mélyén a dugót, kihúzza azt, és a lezúduló víztömeg őt is magával ragadja..

Azok a pillanatok amikor az emberi hülyeség extra adag szorgalommal párosul.
Na ez is egy ilyen volt..

A történet ott kezdődik, hogy a /app_fs filerendszer elérhetetlenné vált a rendszeren, és valaki meg (hogy hogy nem) szerette volna viszont látni. Az ember ilyenkor megnézi az alap dolgokat (nincs e overmount, elérhető e a VG egyáltalán, mountolva van e az FS), majd konstatálja, hogy valami tényleg nem kerek:
server1:root:[/] # mount |grep -c /app_fs
0
server1:root:[/] # lsvg -l appvg |grep applv       
applv              jfs2       320     320     1    closed/syncd  /app_fs
server1:root:[/] # lslv -l applv
applv:/app_fs
PV                COPIES        IN BAND       DISTRIBUTION  
hdisk7            320:000:000   27%           000:089:089:089:053 
server1:root:[/] # lsvg -p appvg
appvg:
PV_NAME           PV STATE          TOTAL PPs   FREE PPs    FREE DISTRIBUTION
hdisk2            active            319         0           00..00..00..00..00
hdisk3            active            1599        0           00..00..00..00..00
hdisk4            active            799         0           00..00..00..00..00
hdisk5            active            959         0           00..00..00..00..00
hdisk6            active            319         32          00..00..00..00..32
hdisk7            missing           447         127         90..00..00..00..37
Őő... Jaj... Na szóval.. Van az FS, ami épp closed-ban van (ez meg is magyarázza hova tűnt a filerendszer :)), ami épp a hdisk7en terül el, ami meg kopp hiányzik az lsvg szerint.. AIX mit tud minderről?
server1:root:[/] # lsdev -Cc disk
hdisk0 Available  Virtual SCSI Disk Drive
hdisk1 Available  Virtual SCSI Disk Drive
hdisk2 Available  Virtual SCSI Disk Drive
hdisk3 Available  Virtual SCSI Disk Drive
hdisk4 Available  Virtual SCSI Disk Drive
hdisk5 Available  Virtual SCSI Disk Drive
hdisk6 Available  Virtual SCSI Disk Drive
hdisk7 Available  Virtual SCSI Disk Drive

server1:root:[/] # lspv |grep appvg
hdisk5          00c3b9f4e1709f60                    appvg           active
hdisk2          00c5effd70395ab2                    appvg           active
hdisk3          00c5effd7c2e18d2                    appvg           active
hdisk4          00c3b9f4aeed3ccd                    appvg           active
hdisk7          00c3b9f4b2a59c9b                    appvg           active
hdisk6          00c3b9f47a309de6                    appvg           active
Él és virul, minden szép, akkor meg mi a fene? Olvassunk már rá a VGDA-ra...
server1:root:[/] # for i in $(lsvg -p appvg |awk '/hdisk/{print $1}');do echo "$i \c";readvgda /dev/$i|grep vg_id;done    
hdisk2 vg_id:           00c5effd00004c000000010da807da15
hdisk3 vg_id:           00c5effd00004c000000010da807da15
hdisk4 vg_id:           00c5effd00004c000000010da807da15
hdisk5 vg_id:           00c5effd00004c000000010da807da15
hdisk6 vg_id:           00c5effd00004c000000010da807da15
hdisk7 vg_id:           00c5effd00004c0000000110796187ae
őőő.. What?? Na szóval.. van egy PV, elérhető, elvileg része a VG-nek, gyakorlatilag meg nem (más a vg_id)... Kis gondolkodás hogy is lehet ez, majd szembejött a megvilágosodás hangos kürt szóval: Ezt a PV-t valaki más is használatba vette!

Tekintve, hogy Virtual diszk, így spuri a VIO-hoz, majd gyors lekérdezések után elő is jött a bűnös probléma:
padmin:vios:[/home/padmin] $ lsmap -all |grep -p hdisk108
VTD                   server2_hdisk4
Status                Available
LUN                   0x8700000000000000
Backing device        hdisk108
Physloc               U7311.D20.0637FDC-P1-C02-T1-W5005076801302EA8-L19000000000000

VTD                   server1_hdisk7
Status                Available
LUN                   0x8400000000000000
Backing device        hdisk108
Physloc               U7311.D20.0637FDC-P1-C02-T1-W5005076801302EA8-L19000000000000
És valóban.. És akkor mit csinál a másik gépen a PV?
server2:root:[/] # lspv
hdisk0          00c3b9f42b11232e                    rootvg          active 
hdisk1          00c3b9f4724a36f5                    rootvg          active 
hdisk2          00c5effd70926735                    dbvg        active 
hdisk3          00c3b9f418b7da43                    dbvg        active 
hdisk4          00c3b9f4b2a59c9b                    dbvg        active 
hdisk5          00c3b9f47715582b                    dbvg        active 
Na most alapjáraton ilyenkor jut eszembe tanult kollégám szava járása miszerint: "Some people just need a hug... around their neck... with a rope."

Egy óriási mázlink volt csak.. Ez:
server2:root:[/] # lspv -l hdisk4
server2:root:[/] # 
Tehát.. Ott a másik szerver, valaki idióta kiassignolta ugyan azt a LUN-t neki, majd berakta egy másik VG-be, ami felül is vágta a VGDA-t, de mákunkra nem használja ezen felül semmire, így a PV-n lévő adat a VGDA-t leszámítva sértetlen.

# Azt azért jegyezzük meg, hogy valaminek az ilyen nagyságrendű elcseszése is igen nagy erőfeszítésbe telik, ugyan is mind a VIO szerver, mind az AIX közli, hogy "Ez mintha már használatban lenne, úgy hogy ha biztos vagy a dolgodban, akkor a -force-ot add még meg a parancshoz" ergo 2x is szorgalmas hülyének kell lennie valakinek, hogy ezt összehozza..

Na jó.. akkor a kérdés már csak az, hogy hogy is varázsoljuk vissza a PV-t a helyére..
A hivatalos megoldás kb annyi, hogy "Reméljük van backupod az FS-ről, mert az FS-t/LV-t törölni kell, kiszedni a PV-t mind a 2 VG-ből (a 2. szerveren menni fog, az eredetin csak félig), szedd le a VIO-ról a LUN zónázást, majd aztán extendvg-vel rakd vissza a PV-t az eredeti VG-be, hozd létre a filerendszert, aztán backupból töltsd vissza az adatokat".

Na ez pont az amit nem akarunk :) (Meg ez a blog bejegyzés se született volna akkor meg).. A mi célunk, hogy az adatokat élve visszaszerezzük. A hogyan már jobb kérdés. Ami tiszta az az, hogy az új VG-ben nem maradhat a PV, úgy hogy onnan szedjük ki, aztán meg a VIO-ról szedjük le a LUN allokációt, hogy csak a source szerveren legyen a PV elérhető.

A következő "elméleti" lépés pedig az lenne, hogy rakjuk vissza a VGDA-t az érintett PV alá..
Ennek kivitelezése némi kis elméleti háttérismeretet igényel:
- AIX alatt minden VG felépítése azonos (az elmélet legalább is, a kivitelezésben vannak némi eltérések)
- Minden VG-ben lévő PV tartalmazza a VGDA-t (A PV elején), amely leírja, hogy a VG alatt pontosan milyen PVID-jű diszkek találhatók, azokon belül melyik PV-n milyen LV-k (és milyen kiosztásban) helyezkednek el, van e LV tükrözés (mirroring), és hasonló úri huncutságok.
- Ergo a dolog szépsége, hogy mindenki tud többé kevésbé mindenkiről mindent, 1-2 dolgot leszámítva, és csak 1-2 alapvető dolog különbözik

# Megjegyzem azért, hogy van a VGDA-ban 1-2 olyan adat is, ami meglehetősen szemétnek minősül és PV-nként eltérhet, de azokkal most nem fogok foglalkozni
Na szóval a feladat a következő: Fogjunk a VG-ből egy egészséges diszket, pakoljuk át a VGDA-ját a hibás PV-re, írjuk át azt ami PV specifikus, aztán imádkozzunk, hogy minden menni fog

!!! Had ne mondjam, hogy ez a módszer véletlenül és semmilyen körülmény között sem támogatott hivatalosan, így ha valakinek van IBM-es szerződése az inkább nyisson PMR-t ha tényleg fontos adatról van szó!!!

Akkor kezdjük az első lépést.. VGDA átmásolás.. Hogy ezt meg tudjuk csinálni 1x is tudnunk kell a VGDA méretét, ez viszont VG típusonként más, úgy hogy tudni kell a VG típusát is :) Ehhez kell egy VG-n belüli PV, amin még minden rendben van, legyen ez mondjuk a hdisk2 (mert csak, amúgy bármelyik másik jó lenne)
server1:root:[/] # readvgda /dev/hdisk2 |grep type
.....    readvgda_type: smallvg
vgtype:         0

# Némi kis segítség a VGDA méretének megállapításában:
# Small VG: 17x 128K
# Big VG: 71x 128K
# Scalable: 548x 128K

Jó.. Most hogy tudjuk mi és merre csináljunk egy backupot a jelenlegi VGDA-ról (igen, amit előzőleg nulláztunk, de akkor is legyen lehetőség visszaállítani ami volt), aztán vágjuk is felül :)
server1:root:[/] # dd if=/dev/hdisk7 of=/tmp/hdisk7.smallvg.vgda.save bs=128K count=17
17+0 records in
17+0 records out
server1:root:[/] # dd if=/dev/hdisk2 of=/dev/hdisk7 bs=128K count=17
17+0 records in
17+0 records out
A következő egyedi azonosító a PV ID-ja lenne (nem összekeverendő a PVID-val), ami megmondja, hogy az adott diszk hányadik is a VG-n belül. Ehhez első körben meg kell keresni, hogy az adott adat hol is tárolódik (VG-nként máshol, de mindig az LVM leíró környékén). Én általában az első 1000 szektorcsoportot keresem végig:
server1:root:[/] # lquerypv -h /dev/hdisk2 0 1000 |grep LVM
00000E00   5F4C564D 00C5EFFD 00004C00 0000010D  |_LVM......L.....|
Szupi.. Tehát 0E00 körül keződidik az LVM leíró része.
Akkor most nézzük meg mi van azon a környéken:
server1:root:[/] # lquerypv -h /dev/hdisk2 e00 40
00000E00   5F4C564D 00C5EFFD 00004C00 0000010D  |_LVM......L.....|
00000E10   A807DA15 00001074 00000832 00000088  |.......t...2....|
00000E20   000008C2 013FFEFF 00000100 00010019  |.....?..........|  
00000E30   00000008 00000080 000008BA 001E0000  |................|
Na most ebből lehet nem sok derül ki annak aki nem tudja mit keressen, de ha összenézzük ugyan ezt a többi diszk VGDA-jával, akkor remélhetőleg már könyebben rájön mindenki hol is van a kutya elásva:
server1:root:[/] # for i in $(lsvg -p appvg |grep -v hdisk7 |awk '/hdisk/{print $1}');do echo $i;lquerypv -h /dev/$i e00 40;done
hdisk2
00000E00   5F4C564D 00C5EFFD 00004C00 0000010D  |_LVM......L.....|
00000E10   A807DA15 00001074 00000832 00000088  |.......t...2....|
00000E20   000008C2 013FFEFF 00000100 00010019  |.....?..........|  <= '0001' a 0x0E2C címnél
00000E30   00000008 00000080 000008BA 001E0000  |................|
hdisk3
00000E00   5F4C564D 00C5EFFD 00004C00 0000010D  |_LVM......L.....|
00000E10   A807DA15 00001074 00000832 00000088  |.......t...2....|
00000E20   000008C2 063FFEFF 00000100 00020019  |.....?..........|  <= '0002' a 0x0E2C címnél
00000E30   00000008 00000080 000008BA 001E0000  |................|
hdisk4
00000E00   5F4C564D 00C5EFFD 00004C00 0000010D  |_LVM......L.....|
00000E10   A807DA15 00001074 00000832 00000088  |.......t...2....|
00000E20   000008C2 031FFEFF 00000100 00030019  |................|  <= '0003' a 0x0E2C címnél
00000E30   00000008 00000080 000008BA 001E0000  |................|
hdisk5
00000E00   5F4C564D 00C5EFFD 00004C00 0000010D  |_LVM......L.....|
00000E10   A807DA15 00001074 00000832 00000088  |.......t...2....|
00000E20   000008C2 03BFFEFF 00000100 00040019  |................|  <= '0004' a 0x0E2C címnél
00000E30   00000008 00000080 000008BA 001E0000  |................|
hdisk6
00000E00   5F4C564D 00C5EFFD 00004C00 0000010D  |_LVM......L.....|
00000E10   A807DA15 00001074 00000832 00000088  |.......t...2....|
00000E20   000008C2 013FFEFF 00000100 00050019  |.....?..........|  <= '0005' a 0x0E2C címnél
00000E30   00000008 00000080 000008BA 001E0000  |................|
Ha megfigyelitek, akkor az VGDA leírók ezen része szinte teljesen egyezik, kivétel a 0x0E2D címen lévő érték, ami szépen növekszik 1től 5ig.. Na most ha még emlékeztek a post elejére, akkor 6 PV volt hivatalosan ebben a VG-ben:
server1:root:[/] # readvgda /dev/hdisk2 |grep pv_id |cat -n
     1  pv_id:          00c5effd7c2e18d2
     2  pv_id:          00c5effd70395ab2
     3  pv_id:          00c3b9f4aeed3ccd
     4  pv_id:          00c3b9f4e1709f60
     5  pv_id:          00c3b9f47a309de6
     6  pv_id:          00c3b9f4b2a59c9b 
Tehát, a PV ID (!=PVID) a hiányzó diszkünknél a 6os lesz, amit vissza is kéne írni a megfelelő pontra.. dd-vel ez megoldható, de ahhoz decimálisan tudnunk kell a pontos poziciót:
server1:root:[/] # echo "ibase=16; E2D" |bc
3629
3629.. Jó. Akkor írjuk is be a helyére a megfelelő értéket:
server1:root:[/] # echo "\06" | dd of=/dev/hdisk7 bs=1 count=1 seek=3629
1+0 records in
1+0 records out
Ez után jön akkor a tényleges PVID. Ha még emlékeztek, akkor erre anno mutattam is egy módszert, amit ismét elő is szedek, és visszaírom az eredetileg a PV-n lévő PVID-t:

A script maga:
server1:root:[/] # cat /tmp/chpvid.sh
#!/usr/bin/ksh
pvid=$1
disk=$2
set -A a `echo $pvid|\
awk ' {
 for (f=1; f <= length($0); f=f+2) {
 print "ibase=16\nobase=8\n"toupper(substr($0,f,2))
 }
}'|\
bc 2>/dev/null`
/usr/bin/echo "\0"${a[0]}"\0"${a[1]}"\0"${a[2]}"\0"${a[3]}"\0"\
${a[4]}"\0"${a[5]}"\0"${a[6]}"\0"${a[7]}"\0\0\0\0\0\0\0\0\c"|\
dd bs=1 seek=128 of=/dev/$disk
A futtatás módja:
server1:root:[/] # sh /tmp/chpvid.sh 00c3b9f4b2a59c9b hdisk7
16+0 records in
16+0 records out
Visszaellenőrzés:
server1:root:[/] # od -A n -j 128 -N 8 -x /dev/hdisk7
         00c3 b9f4 b2a5 9c9b
VGDA ellenőrzés:
server1:root:[/] # for i in $(lsvg -p appvg |awk '/hdisk/{print $1}');do echo "$i \c";readvgda /dev/$i|grep vg_id;done    
hdisk2 vg_id:           00c5effd00004c000000010da807da15
hdisk3 vg_id:           00c5effd00004c000000010da807da15
hdisk4 vg_id:           00c5effd00004c000000010da807da15
hdisk5 vg_id:           00c5effd00004c000000010da807da15
hdisk6 vg_id:           00c5effd00004c000000010da807da15
hdisk7 vg_id:           00c5effd00004c000000010da807da15
Még mielött tényleg bármit is csinálnánk nézzük meg, hogy minden tényleg úgy van ahogy volt:
server1:root:[/] # lsvg -p appvg
appvg:
PV_NAME           PV STATE          TOTAL PPs   FREE PPs    FREE DISTRIBUTION
hdisk2            active            319         0           00..00..00..00..00
hdisk3            active            1599        0           00..00..00..00..00
hdisk4            active            799         0           00..00..00..00..00
hdisk5            active            959         0           00..00..00..00..00
hdisk6            active            319         32          00..00..00..00..32
hdisk7            missing           447         127         90..00..00..00..37
Aztán térdre imára, és varyon-oljuk vissza a VG-t:
server1:root:[/] # varyonvg appvg
server1:root:[/] # lsvg -p appvg
appvg:
PV_NAME           PV STATE          TOTAL PPs   FREE PPs    FREE DISTRIBUTION
hdisk2            active            319         0           00..00..00..00..00
hdisk3            active            1599        0           00..00..00..00..00
hdisk4            active            799         0           00..00..00..00..00
hdisk5            active            959         0           00..00..00..00..00
hdisk6            active            319         32          00..00..00..00..32
hdisk7            active            447         127         90..00..00..00..37

Hoppá... alakul a molekula :) Nézzük mi van szeretett filerendszerünkel:
server1:root:[/] # mount /app_fs
Replaying log for /dev/applv.
mount: /dev/applv on /app_fs_rest: Unformatted or incompatible media
The superblock on /dev/applv is dirty.  Run a full fsck to fix.
Na jó.. ez várható volt.. Adjuk meg amit kér:
server1:root:[/] # fsck /dev/applv
The current volume is: /dev/applv
Primary superblock is valid.
*** Phase 1 - Initial inode scan
*** Phase 2 - Process remaining directories
*** Phase 3 - Process remaining files
*** Phase 4 - Check and repair inode allocation map
*** Phase 5 - Check and repair block allocation map
File system is clean.
Superblock is marked dirty; FIX? y
All observed inconsistencies have been repaired.
Aztán próbáljuk meg újra:
server1:root:[/] # mount /app_fs
server1:root:[/] # 
Profit :))

2013. január 29., kedd

Mickey egér, HACMP, meg a többiek..

Némileg úgy érzem most magam, mint ahogy régen a BBC stábja érezhette magát, amikor is 1946ban (állítólag, bár egyesek szerint ez is kacsa) ismét ott folytatták az ominózus Mickey Mouse történetet, ahol anno 1939 Szeptember 1.-jén abbahagyták.

Ok, némileg túlzó a kép, de azért nekem is volt 1-2 komolyabb harcom az elmúlt 1-2 hónapban, munkahely váltás, költözés külföldre, meg ami vele jár.. Szóval nem volt eseménytelen az elmúlt időszak, ami sajna a blog rovására is ment láthatólag.
Na de viszont most megpróbálom azt amit anno a BBC-sek is - folytatni ahol abbamaradt minden, mintha misem történt volna..

Na szóval.. Aktuális problémánk tárgya egy HACMP-s node, ahol a clcomdES daemon fölött elkezdtek körözni a keselyűk, ugyan is ránézésre halottnak nézett ki..
Az AIX kommandó az újraélesztést megkezdte, de a beteg nem reagált a kezelésre:
[server:root:/home/root:] lssrc -s clcomdES
Subsystem         Group            PID          Status 
 clcomdES         clcomdES                      inoperative
[server:root:/home/root:] startsrc -s clcomdES
0513-059 The clcomdES Subsystem has been started. Subsystem PID is 7033284.
[server:root:/home/root:] 
[server:root:/home/root:] lssrc -s clcomdES   
Subsystem         Group            PID          Status 
 clcomdES         clcomdES                      inoperative
Az orvosi lapot átnézve kiderült, hogy betegünk valószínű még is él, csak vagy kómába esett, vagy önmagán kívül van:
[server:root:/:] tail -1 /var/hacmp/clcomd/clcomd.log 
Mon Jan 28 15:03:18 2013: bind (../../../../../../../src/43haes/usr/sbin/cluster/clcomd/clcomd.c:5533): Address already in use
Persze minderről a hatóságok semmit nem tudtak..
[server:root:/var/hacmp/clcomd:] ps -ef |grep clcom 
    root 5480538 7143926   0 15:05:31  pts/1  0:00 grep clcom 
.. csak annyit, hogy a clcomdES által gyakran használt erőforrásokat valami tényleg épp fogja:
# Kis magyarázat: a clcomdES által használt default port a 6191
[server:root:/var/hacmp/clcomd:] netstat -Aan |grep 6191 |grep LISTEN
f10006000243c398 tcp4       0      0  *.6191             *.*                LISTEN
Ilyenkor általában csak odasétál az ember az illetékes besúgóhoz, megkéri hogy mondja már meg ki jár rá a dugi csokira, de szomorúan kell konstatáljuk, hogy halvány lila fogalma nincs:
[server:root:/var/hacmp/clcomd:] rmsock f10006000243c398 tcpcb
getprocdata: malloc failed
Na jó... Ha a szokványos eszközök nem mennek, akkor tényleg muszáj lesz nekünk is bemocskolnunk a kezünk, és megnézni hogy a Disc-réten mi ROMolhatott el..

Kezdjük is a kernellel, ha már a gyanúsítgatásnál tartunk ("Ahol a kormány, ott van a gáz.."). Aki olvasta eddig a blogomat annak ez a fordulat azt hiszem nem lesz komolyabb meglepetés :)
Akinek még is, annak javaslom az itt emlegetett módszerek és parancsok áttanulmányozását a folytatás előtt

Na szóval.. a netstat megsúgta nekünk, hogy a f10006000243c398-es dugi csokira jár rá a kis szellemünk, úgy hogy kezdjünk el az után nyomozni első körben:
[server:root:/var/hacmp/clcomd:] kdb
(0)> ns
Symbolic name translation off
(0)> si f10006000243c398 tcpcb |grep ACTIVE
F100070F01012000 16456*clcomd   ACTIVE 004812E 0031166 00000003184E1400   0 0014

(0)> proc F100070F01012000 |head
              SLOT NAME     STATE      PID    PPID          ADSPACE  CL #THS

F100070F01012000 16456 clcomd   ACTIVE 004812E 0031166 00000003184E1400   0 0014
Hoppá.. Tehát a socketet még is csak egy clcomd fogja, de akkor miért nem vették észre a nyomozó kollégák??
(0)> hcal 004812E
Value hexa: 0004812E          Value decimal: 295214

[server:root:/:] ps -fp 295214
     UID     PID    PPID   C    STIME    TTY  TIME CMD
       -  295214       -   -                     - <exiting>
Ja kérem.. Ez itt egy megrendezett öngyilkossággal egybekötött biztosítási csalás.. Na keressük meg a cinkosokat:
(0)> proc F100070F01012000 |grep THREAD
THREAD..... threadlist :F100070F10807300 
THREAD..... threadcount:00000014  ........... active     :00000002

(0)> th F100070F10807300 |head
                SLOT NAME     STATE    TID PRI   RQ CPUID  CL  WCHAN

F100070F10807300 32883  ZOMB  0731E3 03C    0         0  

NAME................ 
WTYPE............... WZOMB    
.................tid :00000000000731E3  ......tsleep :FFFFFFFFFFFFFFFF
...............flags :00000000  ..............flags2 :00000000
...........pmcontext :00000000
DATA.........pvprocp :F100070F01012000 
Hoppá.. Nekromancia, vagy mifene? Ki mozgatja a szálakat?
(0)> th F100070F10807300 |grep prev 
LINKS.....prevthread :F100070F10008C00 
LINKS.....prevthread :0000000000000000

(0)> th F100070F10008C00 |head
F100070F10008C00  140 clcomd   SLEEP 08C029 03C    4         0  F100070F010121B8 
Jó.. 1 megvan.. Vannak még?
(0)> th -n clcomd
                SLOT NAME     STATE    TID PRI   RQ CPUID  CL  WCHAN

F100070F10007C00  124 clcomd   SLEEP 07C0ED 03C    4         0  F1000110129D9A70 01125380 
F100070F10008C00  140 clcomd   SLEEP 08C029 03C    4         0  F100070F010121B8 
Aham.. szóval 2 fő process, 1-1 threaddel.. Na és ők épp mit csinálnak?
(0)> f F100070F10008C00
pvthread+008C00 STACK:
[0005EEF4]ep_sleep+000128 (0000000000056DA0, A0000000000090B2 [??])
[0014384C]kexitx+000F6C (??)
[0015AAD8]kexit+000080 ()
[kdb_get_virtual_memory] no real storage @ FFFFFFFF3FFFE40

(0)> f F100070F10007C00
pvthread+007C00 STACK:
[002FF8C0]slock+0006A4 (00000000002E0268, 80000000000090B2 [??])
[00009558].simple_lock+000058 ()
[002CB3D0]j2_rename+000188 (??, ??, ??, ??, ??, ??, ??)
[00408C34]vnop_rename+0002B4 (??, ??, ??, ??, ??, ??, ??)
[0046A8F4]rename+00030C (??, ??)
[0486570C]my_rename+0001C4 (0000000020023728, 00000000200C149C)
[00003810].svc_instr+000110 ()
[kdb_get_virtual_memory] no real storage @ 200C0FD8
[10013190]log_printf+0002FC (00000000, 00000000, 00000000, 00000000,
   00000000, 00000000, 00000000, 00000000)
Az egyik épp ki akar lépni, de azért még vár egy kicsit (tapsra talán, meg nem mondom), de a másik már érdekesebb: Ott a jelek szerint épp valami JFS2-es FS alatt volt valami átnevezősdi, ami valahogy még is csak megbicsaklott..
És hiába tűnt ez az elején HACMP hibának, a bizonyítékok alapján ez inkább tűnik AIX issue-nak.. A pénz csak pénz, a stack az meg csak stack na..
Azok alapján meg az ügy erősen hajaz az alábbi hibák egyikére:
- IZ96928
- IZ40258
Na most ha megnézitek, akkor azért ezek a bűnügyi megelőző kezelések nem épp a legfrissebben szabadult bűnözőkre lettek kitalálva (avagy jó régi patchekről van szó).. Úgy hogy ha már itt tartunk nézzük már meg, hogy ezt a drágát melyik korból szalajthatták?
[server:root:/:] oslevel -s
5300-08-08-0943
Jah.. Jó.. Ez a TL/SP még anno 2009 Novemberében lett kiadva.. Az se ma volt.. Had ne mondjam azóta mennyi fix kijött, jah meg az 5.3as AIX hivatalos supportja is lejárt 2012 Áprilisában.
Na szóval itt rendesen el vannak egyesek maradva.. És hiába kérdezik meg az SWG-sek (software group) hogy tuti minden patch fent van e, attól még a hülye AIX admin csak abból főzhet amit a konyhában talál (amíg ki nem derül, hogy a Műanyag tálba lévő melegítendő kaját lehet még sem a sütőn kellett volna megpróbálni felmelegíteni).

Tanulság: Ha tetszik, ha nem tessék már azokat a rohadt rendszereket frissíteni (és nem csak a security miatt)