2. Hogyan mûködik ?

2.1. Memóriakezelés, többfeladatos mûködés

A Linux - a DOS-tól eltérõen - valódi többfeladatos (multitask) operációs rendszer. Kihasználva az Intel 80386 processzor nyújtotta fejlett tár és taszkkezelési lehetõségeket, valódi idõosztásos környezetet biztosít. A 386-os processzor többféle üzemmódjai közül a Linux a "supervisor" üzemmódot használja a kernel, az operációs rendszer mag futtatására, ebben az üzemmódban a kernelnek hozzáférése van a gép összes fizikai erõforrásához, a felhasználói folyamatok (processzek) pedig ún. "user" üzemmódban futnak. A 386-os processzoron lehetõség van több, egymástól független "user" módú ún. taszk definiálására, amelyek egymástól védettek, nem tudják egymás és a felügyelõ kernel memória- területét kiolvasni vagy módosítani, és a gép közvetlen hardver erõforrásaihoz sincs hozzáférésük (a valóságban ez úgy mûködik, hogy "user" módban csak a processzor utasításkészletének egy része hajtható végre, nem megengedett utasítás végrehajtásának kísérletekor vagy nem megendegett memóriacímre hivatkozáskor a vezérlés hibaüzenettel visszakerül a supervisor módban futó felügyelõ programhoz, vagyis a kernelhez). Így biztosítható az egyes felhasználói programok egymástól való védelme. Mivel az egyes folyamatoknak a gép fizikai erõforrásaihoz (pl. winchester, képernyõ) sincs közvetlen hozzáférésük, bármilyen perifériamûveletet csak a kernel meghívása útján végezhetnek, így mód nyílik peldául biztonságos file-rendszer megvalósítására is. Nincs az a trükk, amivel az egyik felhasználó el tudna olvasni olyan adatot, amihez nincs engedélyezett hozzáférése - amennyiben persze a biztonsági rendszerben nincsenek programozói hibák és a rendszer konfigurációja megfelelõ. Az emberi gyarlóságot nem tekintve a Linux biztonságos többfelhasználós operációs rendszernek tekinthetõ.

A kernel teljes mértékben, fizikai szinten hozzáfér a gép erõforrásaihoz. Fizikai, a lehetõ legalacsonyabb szinten kezeli is a hardvert, a legnagyobb teljesítmény elérése érdekében. A boot-olást (rendszer betöltést) kivéve egyáltalán nem használja a BIOS-t: ennek oka, hogy a BIOS programja a DOS figyelembevételével készült, és nem alkalmas multitaszk operációs rendszer futtatására.

Memóriakezelésében szintén kihasználja a 386 által nyújtott lehetõségeket: lapozásos virtuális memóriakezelést használ, ahol a fizikai memóriát kiegészíthetjük a winchesterrõl vett virtuális memóriával (page vagy swap terület). A teljes memóriát lapokra osztja, ezen virtuális lapokat rendeli hozzá az egyes folyamatokhoz, és gondoskodik róla, hogy az éppen szükséges lapok a fizikai memóriában legyenek. Itt kell megemlíteni, hogy a Linux használja a virtuális tárkezelés mindkét (gyakran összekevert) fajtáját, a lapozást (paging) és a tárcserét (swapping) is. Lapozásnál folyamatoktól függetlenül, a rendszer arra ügyel, hogy a szükséges lapok a fizikai memóriában legyenek, ha azok esetleg diszken vannak, akkor gondoskodik memóriába olvasásukról, illetve a ha a fizikai memória teli van, akkor a ritkábban használt lapokat a diszkre írja. Tárcserénél pedig a rendszer figyelemmel kíséri az egyes folyamatok aktivitását is, es ha szabad memóriára van szükség, egy inaktív folyamat egészét háttértárra írja, felszabadítva ezzel a folyamat által használt összes fizikai memóriát. A Linux a két módszer keverékét használja: amíg bõvében van a memóriának, csak egyes lapokat lapoz ki/be, de például ha úgy látja, hogy egy folyamat hosszú ideje inaktív, és nem csak egy-két lapnyi memóriára van szükség, akkor az adott folyamathoz tartozó összes fizikai lapot diszkre menti.

2.2. Automatikus diszk-gyorsítótár

Szorosan kapcsolódik a memória-lapkezelés mechanizmusához a Linux buffer cache kezelési módszere: a buffer cache a Unix rendszerek diszk- eléréshez használt gyorsítótárja, amelyet a kernel kezel, mivel minden folyamat csak és kizárólag a kernel meghívásával végezhet diszkmûveletet. Linuxban a buffer cache mérete dinamikusan, a rendszer- terheléstõl függõen változik: mindig az éppen szabad fizikai memória egészét erre a célra használja. A diszk-irások is a buffer cache-n keresztül történnek: minden írás elõször a cache memóriába kerül, és vagy egy megadott idõ elteltével iródik ki diszkre, vagy pedig akkor, ha a rendszer számára "elegendõ" kiírnivaló összegyûlt. Ezért fontos az, hogy a megfelelõ shutdown procedúra (a rendszer "lelövése", leállítása) végrehajtása nélkül soha ne kapcsoljuk ki a gépet: kikapcsolás elõtt mindig szükséges a diszk tartalmának szinkronizálása a memóriában lévõ állapottal, a nyitott file-ok lezárása - ezen lépések elmulasztása esetén kikapcsoláskor a diszk tartalma helytelen lehet, információk, egész file-ok veszhetnek el. Ugyanez történhet persze áramszünet vagy más hiba esetén is: ez az az ár, amit a Unix filerendszer által nyújtott nagyobb teljesítményért fizetnünk kell. A Unix-ok általában (így a Linux is) rendelkeznek funkciókkal az esetleges információvesztés minimalizálására, illetve a korrekt file-rendszer visszaállítására - tulajdonképpen egy átlagos Linux rendszerben váratlan rendszerösszeomláskor maximum csak a legutóbbi 30 másodperc munkája veszhet el - nagyon kicsi valószínûségû extrém esetektõl eltekintve. De az ilyen adatvesztés veszélye minden, a diszk- írást bufferelõ rendszerben fennáll.

2.3. Fejlett memóriakezelési technikák

2.3.1 A "demand paging" módszer

A fejlett memóriakezelés lehetõvé teszi további, a teljesítményt növelõ megoldások használatát is: ezek egyike az ún. "demand paging", ami azt jelenti, hogy egy futtatható file végrahatjtásakor nem az egész file töltõdik be a memóriába, hanem mindig csak azok a lapjai, amelyekre a végrehajtás során éppen szükség van: gondoljunk csak bele, minden programnak vannak olyan részei (inicializálás, hibakezelõ részek), amelyek csak egyszer, vagy éppenséggel egyszer sem futnak le - ezeket aztán vagy soha be sem tölti a rendszer a memóriába, vagy pedig miután lefutottak, rögtön fel is szabadítja az általuk elfoglalt területet.

2.3.2. Megosztott programkönyvtárak

Többfeladatos mûködés esetén, amikor egyszerre több program tartózkodik a fizikai memóriában, hasznos a Linuxban szintén használt "osztott könyvtár" (shared library) mechanizmus, vagy más néven a dinamikus (futásidejû) programösszefûzés (link). Alapötlete az, hogy mivel mindegyik program C-ben iródott és ugyanabban a környezetben fordult le, ezért valószínûleg lesz egy csomó olyan függvény (például a képernyõkezelõ könyvtári függvények) amelyeknek kódja minden programban ugyanaz, és felesleges minden programmal együtt a memóriába tölteni õket, elég csak egyszer - csak a programok tudják, hol keressék a memóriában ezeket a függvényeket. Így minden programba elég egy "csonk"- nak (stub) nevezett programrészlet beépítése, amelyik a dinamikus linker segítségével gondoskodik a megfelelõ függvény megtalálásáról illetve memóriába töltésérõl, amennyiben az még nem lenne betöltve.

2.3.3. A copy-on-write mechanizmus

Még egy memóriakezelési finomság van, amelyet Unix rendszerekben elõszeretettel használnak: ez pedig az úgynevezett copy-on-write (irásnál másold) mechanizmus, amely a következõképpen mûködik: multitaszkos operációs rendszerben gyakran lehet arra szükség, hogy bizonyos memória- lapokat több folyamat között megosszunk, vagy a legtipikusabb példa: Unix-ban új folyamat létrehozása mindig egy másik folyamat memóriájának lemásolásával történik. Mivel viszont egy memórialapra "többfelõl", több folyamat memóriatérképébõl tudunk hivatkozni, nem is kell azt a lapot lemásolni, csak elhelyezni az ugyanarra a lapra mutató hivatkozásokat a megfelelõ helyeken. Mivel a memóriamásolás meglehetõsen idõigényes dolog, ezzel kritikus helyen (a felhasználó szemszögébõl holtidõnek számító folyamat-létrehozáskor) sok idõt takaríhatunk meg, és most már csak arra kell vigyáznunk, hogy ha az ugyanarra a lapra hivatkozó több folyamat közül valamelyik módosítani akarja a lapot, (mivel mindegyik folyamat azt hiszi, a memórialap csak az övé) akkor készítsünk csak annak a folyamatnak a számára másolatot, amelyet aztán módosíthat kedve szerint.

2.4. A folyamatok ütemezése

Mivel egy processzoron kell konkurrensen több feladatot végrehajtania, az operációs rendszernek, ezért valamilyen formában meg kell osztania a rendelekzése álló CPU idõt az egyes folyamatok között. A Unix rendszerek (így a Linux is) a preemptív idõosztásos ütemezés módszerét alkalmazzák, ami azt jelenti, hogy a rendelkezésre álló idõt felosztja egyenlõ részekre, és ezekbõl az egyenlõ idõszeletekbõl juttat - a folyamat prioritásának megfelelõen - többet vagy kevesebbet az adott folyamatnak. Az egyes folyamatok prioritása természetesen állítható. Az ütemezés preemptív volta annyit jelent, hogy amikor az adott folyamat számára kijelölt idõszelet letelt, a kernel megszakítja a folyamat futását és más folyamatnak adja át a vezérlést - nincs tehát mód arra, hogy egy folyamat a végtelenségig magánál tartsa a vezérlést, és megakadályozza a többi folyamat futását. Linuxban az ütemezés alapegysége az 1/100 másodperc.

Nem szabad azonban egy fontos dologról megfeledkeznünk: A Unix nem valós- idejû (real-time) operációs rendszer, ami annyit jelent, hogy ha több folyamat fut egyszerre, és az egyiktõl elkerül a vezérlés, akkor valamekkora (rendszerint nagyon rövid) idõ múlva vissza is fogja majd kapni - a két aktív (futó) állapot közti idõre azonban nincs szigorú felsõ korlát. Az esetek 99.9999999 százalékában ez az idõ (még egy leterhelt - de nem indokolatlanul túlterhelt rendszeren is) pár tized másodperc - azonban soha nem mondhatjuk, hogy biztosan csak ennyi. Ezt a tényt pontos és rövid idõzítéseket használó programoknál nem árt szem elõtt tartani.

2.5. Többfelhasználós mûködés

2.5.1. A terminál koncepció

A Linux, eltérõen a PC-n eddig megszokott operációs rendszerektõl, nem csak többfeladatos, ahol egy felhasználó egyidejûleg több programot futtathat (mint például a MS-Windows és az OS/2), hanem többfelhasználós is, vagyis egyidejûleg több felhasználó használhatja ugyanazt a rendszert, és mindegyikük akár több programot is futtathat. Ennek megvalósításához azonban szükség van néhány új fogalom, koncepció bevezetésére: Rögtön elsõ problémaként jelentkezik az, hogy egy PC-nek csak egy billentyûzete, és (kevés kivételtõl eltekintve) csak egy monitora van, amit értelemszerûen egyszerre csak egyvalaki használhat. A Unix filozófia minden egyes bejelentkezett felhasználóhoz hozzárendel egy egy úgynevezett terminált: egy terminál pedig egy billentyûzet + megjelenítõ egység (leggyakrabban szöveges display) együttesét jelenti. Az adott Unixos géphez legközvetlenebbül csatolt terminált (Linux esetén a gép saját billentyûzetét és monitorát) konzol terminálnak (console terminal) nevezzük, ez abból a szempontból kitüntett, hogy bizonyos rendszeradminisztrációs feladatok csak innét hajthatók végre. További terminálok csatolhatók még a géphez soros vonalon (ez a legõsibb Unixos megoldás, egy terminálemulációs szoftver és egy soros kábel segítségével akár kidobandó XT-inket is egyszerûen soros terminállá alakíthatjuk, illetve direkt erre a célra készült terminálokhoz manapság már fillérekért hozzájuthatunk). De köthetünk soros vonalra modemet is: ekkor a felhasználói terminál a telefonvonal "túlsó végén" lesz, távolról is elérhetõvé téve rendszerünket.

A hálózaton vagy grafikus felületen keresztül bejelentkezett felhasználókhoz ún. pszeudo-terminálokat rendel a rendszer, ahol is a billentyûzet és a képernyõ annak a gépnek a billentyûzetéhez és képernyõjéhez rendelõdik, amely elõtt a felhasználó ül. A terminálok megnevezése a szakzsargonban tty (angolul betûzve ejtik), illetve a pszeudo-termináloké pty vagy ttyp, a Linux ez utóbbi megnevezést használja. Minden Unix rendszer többféle, képességeik alapján osztályozható terminált képes kezelni: mivel nem alakult ki egységes szabvány, és a nagygépek hõskorában sokféle gyártó sokféle terminált gyártott, ezért a Unix rendszereket általában felkészítik a sornyomtató tipusú, sorüzemmódú, kurzor-címzésre nem képes termináloktól kezdve a modernebb, színkezelésre és akár ANSI grafikára képes terminálokig bezárólag sokféle termináltípus kezelésére. Az egyes terminálokat gyártó és típusra utaló megnevezéssel azonosítják: Amennyiben csak kozolról használjuk gépünket, elég annyit tudni hogy a konzol terminál azonosítója "console".

2.5.2. Az egyes felhasználók megkülönböztetése

Az egyes felhasználók azonosítására a "login név" (account, témaszám) rendszert használja a Unix: minden felhasználónak van egy (maximum 8 karakter hosszú, konvenció szerint kisbetûvel irott) azonosítója, és ehhez tartozik a maximum 8-16 karakter hosszú jelszó. A finomabb hozzáférés hierarchia kialakítása érdekében a felhasználókat csoportokba (groups) oszthatjuk: minden felhasználónak van egy elsõdleges csoportja (pl. student), és ezen kívül tartozhat még más csoportokhoz is (pl. texusers). A csoportneveket is konvenció szerint kisbetûvel írják. Belsõleg a rendszer minden egyes felhasználóhoz az egyedi felhasználó- néven kívul még egy numerikus felhasználó és (esetleg több) csoport- azonosítót rendel (UID - user identification és GID - group identification). Léteznek kitüntetett felhasználónevek is, illetve legalább egy, amelyik minden rendszeren megvan: ez a "root" felhasználó, a rendszergazda azonosítója, aki felelõs az adott rendszer karbantartásáért és üzemeltetéséért, és akinek a rendszeren "mindent szabad": õ az, akinek a rendszer egészéhez hozzáférése van. Fel kell itt hívni a figyelmet egy kialakult, de elkerülendõ rossz gyakorlatra: sokan, akik csak egyedül használják Linuxos gépüket, minden tevékenységüket "root" hozzáférési jogokkal végzik, mondván, hogy így jobban hozzáférnek a rendszerhez, nem kell mindenféle korlátozásokkal veszõdniük. Nem érdemes ezt a gyakorlatot folytatni, mert egy jól bekonfigurált rendszerben normál (nem privilegizált) felhasználókent is kényelmesen elérhetünk minden szolgáltatást, amire hétköznapi felhasználás során szükségünk lehet - viszont figyelmetlenséggel vagy elgépeléssel sokkal kisebb kárt tudunk okozni. Egy root jogokkal kiadott hibás vagy át nem gondolt utasítás egy pillanat alatt az egész rendszerünket jóvátehetetlenül tönkreteheti. Megjegyzendõ még, hogy "root"-tal ekvivalens felhasználót akár többet is hozhatunk létre, az összes olyan felhasználó, akinek UID-je 0 (felhasználó létrehozásakor ezt megadhatjuk) root-tal ekvivalens lesz, de általában nem érdemes ezt tennünk: egy rendszeren éppen elég egy darab teljhatalmú felhasználó.

2.6. A file-okról

2.6.1. A Unix file koncepció

Mielõtt továbblépnénk, feltétlenül szükséges megismerkednünk még egy, az egész rendszert átható szervezõ elvvel: ez pedig a file koncepció. Unixban ugyanis (túlzás nélkül) az égvilágon minden file. Definíció szerint (kissé tudományosan) a file olyan "kommunikációs végpont", ahova vagy byte-folyamot (byte stream) tudunk írni, vagy byte-folyamot tudunk onnét olvasni (esetleg mindkettõt). Fileként kezelhetõ tehát a billentyûzet (csak olvasható), a szöveges képernyõ (csak írható), a nyomtató, de még a fizikai memória tartalma is (!). A gépben lévõ winchester szektorait (ha nem csak egyes file-okat akarunk elérni) is egy speciális file olvasásával illetve irásával érhetjük el, ugyanígy az hálózati eszközöket is a file-kezelés szabályainak megfelelõen használhatjuk. Ez utóbbi három esetben persze szükség van a megfelelõ jogosultságokra: a fizikai memória tartalmát vagy direktben a winchester szektorait "mezei" felhasználó nem láthatja. Ezt a file-orientált szervezésmódot (amely tulajdonképpen egy Unix rendszer fõ szervezõ ereje) folyamatosan érdemes észben tartanunk: ha egyszer kellõen átláttuk logikáját, sok addig bonyolultnak, lehetetlennek tartott mûvelet roppant egyszerûvé válik.

2.6.2. A file-rendszer struktúrája

A Unix file rendszere a DOS-hoz hasonló könyvtár rendszerû (helyesebben szólva a DOS hasonlít a Unixhoz), azzal a különbséggel, hogy itt nincsenek különbözõ meghajtók, hanem a rendszerben lévõ minden file-t egy gyökérkönyvtárból kiindulva (ennek jelölése / könyvtár) elérhetünk. Fontos külõnbség még, hogy a Unix file-nevek nem a DOS-ból ismert 8+3 szabály szerint formálódnak: egy file-név maximum 255 karakter hosszú lehet, és tetszõleges karaktert tartalmazhat (vigyázat, tartalmazhat nem nyomtatható, nem gépelhetõ karaketereket is! Gonoszul elnevezett file- okkal sok bosszúságot okozhatunk magunknak és felhasználótársainknak.) Fontos külõnbség továbbá, hogy a Unix (nem csak file-nevekben, mindenhol) különbséget tesz kis- és nagybetû között (case sensitive). Az ALMA, Alma,alma,almA tehat mind-mind különbözõ file-okat jelentenek. Mivel file-névben pont is lehet, ezért Unixban is adhatunk kiterjesztéseket file- oknak: ezek azonban a rendszer számára semmilyen jelentéssel nem bírnak: csak a felhasználók eligazodását segíti elõ, ha betartjuk a megfelelõ file-nevezési konvenciókat. Azt sem a file-névbõl tudja meg a rendszer, hogy például az adott file futtatható-e vagy sem: a következõ részben látni fogjuk, mibõl is derül ez ki. Elõtte azonban még egy fontos dolgot tisztáznunk kell: hogyan valósul meg az, hogy a gépben több fizikai eszköz van (floppy, esetleg több winchester) és mégis az összes file-ot egy könyvtárstruktúrában látjuk ? Úgy történik, hogy van egy kitüntetett diszk (vagy partíció, esetleg ramdisk) amelyen a gyökér könyvtár ( / könyvtár) található, és a többi úgynevezett filesystem-et (filesystem-nek Unix alatt az egy diszken,partíción, egy rendszerbe szervezett file-ok összességét nevezzük) pedig a file-rendszer valamely alkönyvtárába lehet beilleszteni (mounting, igazán jó magyar terminológia mindezidáig nem született rá). Tehát ha van például egy /mnt/floppy alkönyvtárunk a rendszerben, es van egy floppy diszkünk, amelyen lévõ filesystem-ben a /alma, /narancs és a /alma/starking könyvtárak vagy file-ok vannak, akkor a floppy "felmount-olása" után a /mnt/floppy/alma, /mnt/floppy/narancs és a /mnt/floppy/alma/starking könyvtárakat vagy file- okat fogjuk látni. Láttuk azt is, hogy Unixban az egyes könyvtárak szeparálására a DOS \ (backslash) karakterével ellentétben a / -t (slash) használják. Nem érdemes eltéveszteni, mert amint késõbb látni fogjuk, a backslash karakternek is megvan a saját szerepe.

Unixban kétféleképpen adhatunk meg file elérési útvonalat, ez hasonlít a DOS-nál megszokottra: abszolút módon, a gyökérkönyvtárból indulva, amikor az elérési út neve / -rel kezdõdik, vagy relatív módon, például ../../alma/starking, ami azt jelenti, hogy az aktuális könyvtárból lépjünk felfelé kettõt, és onnét lépjünk az alma könyvtárba, ha a starking-ot akarjuk megtalálni.

2.6.3. Többféle file-rendszer kezelése

A Linux képes arra, hogy többféle fizikai és logikai szervezésû filesystem-et egy könyvtárszerkezetben kezeljen: támogatja többféle Unix-os filesystem formátum mellett a DOS FAT filerendszert, tudja olvasni az OS/2 HPFS file-okat, ismeri a CD-s fileformátumokat, és tudja kezelni a TCP/IP hálózat felett mûködõ hálózati file-rendszert az NFS-t is.

2.6.4. További érdekességek a file-rendszerrõl. A link

Még két Unix-os specialitásról kell beszélnünk: az egyik az, hogy abból hogy /mnt/floppy/narancs, nem derül ki, hogy ez a narancs egy könyvtár-e vagy egy file - ennek eldöntéséhez a file neve egyedül nem elég. A másik specialitás ismertetéséhez kicsit jobban bele fogunk mászni a Unix filerendszerek rejtelmeibe. A tárgyalt sajátosság a "link", az a tulajdonság, hogy egy file-nak egyszerre több neve is lehet: több néven is tudunk ugyanarra a file-ra hivatkozni (pl. megcsinálhatjuk, hogy a /gyumolcs/alma és a /holnap/reggeli file-nevek fizikailag ugyanarra a file-ra mutassanak). Ez pedig úgy lehetséges, hogy egy Unix filesystem-ben minden egyes file-hoz tartozik egy inode -nak nevezett rekord, amely tartalmazza a file nevét, létrehozásának dátumát és minden egyéb, a file-lal kapcsolatos adatot, kivéve a file tartalmát - többek között azt az információt is, hogy fizikailag a diszk melyik szektorában kezdõdik az a file. Létrehozhatunk egy újabb inode-ot, amelyben a file neve más, de a kezdõ szektor száma azonos: és máris két helyrõl hivatkozhatunk ugyanarra a file-ra. Törléskor pedig mindaddig csak az inode-okat töroljük, amíg el nem érünk az utolsóhoz, amikor már csak egy darab inode címzi meg a file-ot: ennek törlésekor szabadítjuk fel a file által elfoglalt diszkhelyet. Az ilyen típusú linket hard link-nek nevezzük, és van egy hátránya: csak ugyanazon a diszken illetve partíción lévõ file-ra tudunk ilyet létrehozni, mert az inode-on belül nem tudunk mondjuk egy cserélhatõ floppy vagy CDROM szektorszámaira hivatkozni - egy másik diszkrõl. Ezért találták ki az ún. szimbolikus vagy soft-linket, amely szintén egy link, de úgy mûködik, hogy a link maga egy speciális file, amiben a hivatkozott file neve van. Itt általában érdemes relatív nevekkel dolgozni, így késõbb egész könyvtárszerkezetek, részfák másolásakor, mozgatásakor kevesebb problémába ütközünk. Mozgatás alatt az is értendõ, ha az adott filesystem-et a könyvtárstruktúra egy más pontjára illesztjük be!

Láthattuk, hogy a .. itt is a szülõ könyvtárra hivatkozás, a . pedig logikusan az aktuális könyvtárra utal. Unixban (mint minden), a könyvtárak is file-ként jelennek meg - ennek az is az elõnye, hogy a könyvtár neve, a könyvtárban lévõ . file és a könyvtár közvetlen alkönyvtáraiban lévõ .. hivatkozások mind-mind ugyanarra az inode-ra, a könyvtár inode-jára mutató hard linkek. Ugye milyen logikus?

Ennyi elméleti alapozás után már éppen itt az ideje, hogy billentyûzetet ragadjunk, és elkezdjük egy Linux rendszer felfedezését a gyakorlatban is!

Tovább...