Na szóval.. A mostani alkalomra a fuser nevű parancsot néztem ki magamnak.. Sokat nem kell róla mondani: Általános ismérve, hogy ha egy FS nyitva van, akkor ezt szoktuk meghívni, hogy megnézzük mi is fogja. Nézzük, hogy ezt a funkciót a kernel térből hogy is lehetne elérni:
Első körben kell nekünk egy mount point.. Az én esetemben ez a /opt/IBM lesz, mert miért ne :)
Első körben a kontroll teszt: Nézzük, hogy a rendszer mit is tud róla:
Szupi.. Na akkor nézzük ugyan ezt a kernel térben. A módszer az alábbi dióhéjban:test_server@root:/ # fuser -cux /opt/IBM /opt/IBM: 1130574c(root) 1253494c(root)
- Meg kell keresni az adott mount point memória pointerjét
- Ezt a pointert használva megnézni az elérhető I-node bejegyzések pointereit, majd leválogatni amire van bármiféle hivatkozás
- A leválogatott hivatkozásokat alapul véve meg kell nézni, hogy melyiknek mi a Gnode (generic node structure) szegmense
- Ezen segmensekből már le tudjuk válogatni, hogy melyiknek milyen thread a szülője, amiből meg direkt megtalálhatjuk a thread-hez rendelt PID-et.
A valóságban:
Első körben ugye a mount-hoz tartozó cím kell. Annyi probléma van, hogy a mount-ot kikérve ilyen összevisszaságot kapunk:
És így tovább.. Ez persze felvet 2 gondot:(0)> mount GFS DATA TYPE FLAGS 1 F10001001D6868B0 014D4D60 F1000100206D2080 JFS2 DEVMOUNT ... /dev/hd4 mounted over / 2 F10001001D686950 014D4D60 F1000100206A4480 JFS2 DEVMOUNT ... /dev/hd2 mounted over /usr 3 F10001001D6869F0 014D4D60 F1000100206FB080 JFS2 DEVMOUNT ... /dev/hd9var mounted over /var 4 F10001001D686810 014D4D60 F1000100206FC880 JFS2 DEVMOUNT ... /dev/hd3 mounted over /tmp
- Komolyan végig kell mindent böngésszek, úgy hogy közben kifolyik a szemem?
- Miért nem lehet ezt 1 sorban kirakni, hogy legalább greppelni lehessen rá?
Persze azért annyira mégse rossz a helyzet, csak kicsit bűvészkedni kell az awk-al, és nyomban meglesz az ami nekünk kell:
(0)> mount |awk '{a[NR]=$0} /\/opt\/IBM$/ {print a[NR],a[NR-1]}' ... /dev/IBMlv mounted over /opt/IBM 14 F100010020684550 014D4D60 F1000100226C2C80 JFS2 DEVMOUNT
Ugye hogy így szebb.. Na szóval megvan a pointerünk (F100010020684550). Akkor kérjük le milyen i-node bejegyzések vannak alatta:
Na itt egy újabb probléma.. Mi ez a sok szám, és mit jelentenek? Nos A válasz a következő:(0)> mount F100010020684550 |grep -E "DIR|REG|SOCK" |tail -5 648 F1000100241643E8 0 F1000100241640B0 F100010020684550 DIR 649 F1000100240E03E8 0 F1000100240E00B0 F100010020684550 DIR 650 F100010024092FE8 1 F100010024092CB0 F100010020684550 REG 651 F10001002411B7E8 2 F10001002411B4B0 F100010020684550 DIR 652 F1000100226D2FE8 1 F1000100226D2CB0 F100010020684550 DIR ROOT
- Az első és második oszlop lényegében ugyan azt takarja. Az első az index-szám, a második pedig a VFS_VNODE pointer.
- A 3. szám egy úgy nevezett counter. Ez mutatja, hogy hány kernel thread használja éppen az adott VFS_VNODE-ot.
- A 4. lesz a VFS_VNODE-hoz tartozó GNODE.
- Az 5.-et most bocs de kihagyom, mert érdektelen jelen szempontból
Ami nekünk ezek közül kell, az azok a GNODE regiszterek, amelyeknek COUNT-ja nagyobb mint 0. Ezt kb az alábbi scriptelési módszerrel tudjuk előhozni:
(0)> mount F100010020684550|grep -E "DIR|REG|SOCK" |awk ' { if ($3 != "0") print }' 154 F100010036F6A3E8 1 F100010036F6A0B0 F100010020684550 REG 157 F100010036F3A3E8 1 F100010036F3A0B0 F100010020684550 REG 160 F100010036F99FE8 1 F100010036F99CB0 F100010020684550 REG 163 F100010036F69FE8 1 F100010036F69CB0 F100010020684550 REG 266 F100010036FA6FE8 1 F100010036FA6CB0 F100010020684550 REG 556 F1000100244D2FE8 1 F1000100244D2CB0 F100010020684550 REG 557 F1000100243B57E8 1 F1000100243B54B0 F100010020684550 REG 558 F1000100244CC3E8 1 F1000100244CC0B0 F100010020684550 REG 559 F1000100244EBBE8 1 F1000100244EB8B0 F100010020684550 REG 560 F1000100243B0BE8 1 F1000100243B08B0 F100010020684550 REG 561 F1000100244CB7E8 1 F1000100244CB4B0 F100010020684550 REG 562 F1000100244A93E8 1 F1000100244A90B0 F100010020684550 REG 563 F1000100244C8BE8 1 F1000100244C88B0 F100010020684550 REG 652 F1000100226D2FE8 1 F1000100226D2CB0 F100010020684550 DIR ROOT
Egy baj van - Ez a lista helyenként iszonyat nagy.. Itt se épp rövid.. A problémám meg az, hogy az itt található GNODE ID-kat kéne mind végigjárjam az alábbi módon:
3.-ra csak ráhibáztam az egyikre, de persze ezt így egyesével végigjátszani valami halál.. Mindenesetre ha megvan a pvproc cím, akkor abból már az egyik process-t meg is találhatjuk:(0)> gnode F1000100243B08B0 |grep gn_seg gn_seg........ 00000000000086A6 (0)> scb 2 00000000000086A6 |grep pvproc pvproc pointer (pvproc) : 0000000000000000 (0)> gnode F1000100244C88B0 |grep gn_seg gn_seg........ 00000000000246AD (0)> scb 2 00000000000246AD |grep pvproc pvproc pointer (pvproc) : 0000000000000000 (0)> gnode F100010036F99CB0 |grep gn_seg gn_seg........ 00000000000732D8 (0)> scb 2 00000000000732D8 |grep pvproc pvproc pointer (pvproc) : F100070F00045000
Bingo.. 1130574 az egyik PID amint fentebb is láttunk.. Na de akkor hogy is lehet ezt normálisan végignézni, úgy hogy az összes GNODE ID-t végigjátsszuk? Hát, a szomorú hír, hogy a kdb nem tud belső scriptelést, így a shell-re kell támaszkodjunk, ami meg egy részről iszonyat erőforrás zabáló, más részről meg a sok fork miatt ágyúval verébre módszer is. Annyi segítségünk mondjuk van, hogy a kdbnek van '-script' kapcsolója, ami pont az ilyen munkákat igyekszik megkönnyíteni, de azért ez még mindig kevés az optimális működéshez.(0)> proc F100070F00045000 |grep ^pvproc pvproc+045000 276 java ACTIVE 011404E 0132076 0000000030588400 0 0013 (0)> hcal 011404E Value hexa: 0011404E Value decimal: 1130574
Ebből kiindulva már nem nehéz megtalálni azt amire végső soron pályázunk (viszalépés kdb-be, majd.. )test_server@root:/ # for GN_SEG in $( > for GNODE_ID in $(echo mount F100010020684550|kdb -script |grep -E "DIR|REG|SOCK" |awk ' { if ($3 != "0") print }') > do > echo gnode $GNODE_ID|kdb -script|awk '/gn_seg/ {print $NF}' > done) > do > echo scb 2 $GN_SEG |kdb -script|awk '/pvproc/ {print}' > done|sort -u|grep -v 0000000000000000 pvproc pointer (pvproc) : F100070F00045000 pvproc pointer (pvproc) : F100070F0004C800
(0)> proc F100070F00045000 |grep ^pvproc pvproc+045000 276 java ACTIVE 011404E 0132076 0000000030588400 0 000E (0)> hcal 011404E Value hexa: 0011404E Value decimal: 1130574 (0)> proc F100070F0004C800 |grep ^pvproc pvproc+04C800 306 sh ACTIVE 0132076 0000001 0000000008466400 0 0001 (0)> hcal 0132076 Value hexa: 00132076 Value decimal: 1253494
1130574, 1253494. Amiket fentebb is láttunk.. Sőt, még azt is tudjuk, hogy egy sh, meg egy java processről van szó :)
Ha ne adj isten lusták vagyunk visszamenni a fenti script után a kdb-be, akkor némi kis módosítással nyomban ki is lehet kérni az ID-ket:
test_server@root:/ # MOUNT=$(echo mount |kdb -script|awk '{a[NR]=$0} /\/opt\/IBM$/ {print a[NR-1]}'|awk '{print $2}') test_server@root:/ # for PVPROC in $( > for GN_SEG in $( > for GNODE_ID in $(echo "mount $MOUNT" |kdb -script|grep -E "DIR|REG|SOCK" |awk ' { if ($3 != "0") print $4}') > do > echo gnode $GNODE_ID|kdb -script|awk '/gn_seg/ {print $NF}' > done) > do > echo scb 2 $GN_SEG |kdb -script|awk '/pvproc/ {print $NF}' > done|sort -u|grep -v 0000000000000000) > do > echo proc $PVPROC|kdb -script|grep ^pvproc > done pvproc+045000 276 java ACTIVE 011404E 0132076 0000000030588400 0 0017 pvproc+04C800 306 sh ACTIVE 0132076 0000001 0000000008466400 0 0001
# Mint fent említettem: A módszer csak azokra a GNODE-okra működik aminek a countere (aktív thread-je) nagyobb mint 0. Ez azért problémás, mert ha egy process használ egy file-t, de az épp nem aktív (írás nélküli file, pl tail esetén), akkor ez a módszer is hibádzik. További probléma, hogy a submount-okat (amik szintén fogják az FS-t umount esetén) szintén nem képes kijelezni, szóval nyugodtan tekintsétek ezt is amolyan érdekességnek, tekintve, hogy mind a fuser, mind az lsof bőven alkalmasabb ezeknek a megkeresésére (általában - volt amikor ez a módszer talált meg nekem egy olyan thread-et, amiről más program sose hallott)
Van modszer egy process cmdline-janak kinyeresere (Linux: /proc/PID/cmdline)?
VálaszTörlésEz foleg altalaban azert kerdes, mert oke, hogy egy PID meg egy processz nev (java) meghataroz egy konkret stuffot, de mennyivel szebb mar, ha ki tudod jelezni, hogy a Tivoli Manager van olyan galad, es fogja az illeto FS-t.
/proc/$PID/cmdline az nincs, viszont van procfs AIX alatt is. Jelen esetben én a /proc/$PID/psinfo-ra hagyatkoznék ha ilyen igényem lenne (igaz mondjuk, hogy az is azt hiszem csak 80 karakterik írja ki az argumentumokat).
VálaszTörlésAmúgy meg ha megvan a pid, akkor simán lehet 'ps -fp $PID'-el nézni a process-t.
Ez se mostani valasz, megis most olvasom el eloszor. Figy, nem lehetne ilyen last comments blokkot kipakolni oldalra? Annyira nem latszik, jon ilyen... :-)
VálaszTörlésParancsolj :) Oldalt, legalul megtalálható az utolsó 3 komment (max 100 karakterig levágva) :) Tekintve, hogy havonta 1-2 bejegyzés kerül csak ki, így remélem, hogy a 3 bőven elég is lesz
VálaszTörlésnice! Koszi.
Törlésgrep -E "DIR|REG|SOCK" |awk ' { if ($3 != "0") print }'
VálaszTörlésEz mar majdnem olyan rossz, mintha cat is lenne benne.
awk '$6 ~ /DIR|REG|SOCK/ { if ($3 != "0") print }'
Nem eleg, hogy amugy is egy fork bomb az egesz script :-) meg sulyosbitod, ami amugy is.
Az mar csak hab a tortan, hogy az egeszet meg lehetne irni AWK-ban is, ekkor persze kicsit cinkesebb a sor processzalas, (tobbet kell hozza gepelni), de ha scriptet csinalnek belole, lehet megrne egybol AWK-ba tolni. Es a forkok szama a felere csokkenne, ami nem elhanyagolhato.