Jak RPC funguje?
V tomto textu se nebudeme zabývat konkretní specifikací komunikačního
protokolu RPC mezi klientem a serverem, přesto si však nastíníme
dostačující popis funkce.
Pokud chce server poskytovat služby, resp. procedury, založené na RPC, je nezbytné
aby dokázal okolí propagovat, co a jakým způsobem nabízí. Tuto základní
úlohu plní démon tzv. portmapper neboli RPC library dispatcher,
u kterého server-side programy registrují (1 - viz schéma níže) své procedury.
Proceduře takto registrované je portmapperem přidělen
přístupový TCP/IP port, na který se pak klienti mohou obracet
se svými požadavky. Nabízí se zde ihned otázka, jakým způsobem se klient
doví, na kterém portu má příslušnou proceduru hledat. Odpovědí na snadě je,
že mu to prozradí portmapper (3)(4), který je pevně spojen s TCP/IP portem 111.
V Linuxu se program na mapování portů nazývá /sbin/portmap nebo /usr/sbin/rpc.portmap.
Kromě toho, že je třeba zajistit, aby se mapovač automaticky spouštěl při startu systému, není třeba
žádná další konfigurace.
Základní princip jsme si tedy nastínili, ovšem tak jednoduché to ve skutečnosti
není. Je zde spousta nezbytností, které je třeba zajistit. Jako první si uveďme
potřebu se nějak dohodnout na tom jak procedury jednoznačně identifikovat.
Firma Sun spravuje seznam tzv. čísel programů, které identifikují
kolekci procedur, a snaží se tak předcházet situacím, kdy by dva různě orientované
programy využívající RPC mohli používat stejné identifikace svých poskytovaných
procedur. Rozsah čísel programů pod správou Sun je 0-1fffffff. Rozsah
20000000-3fffffff je pak poskytnut k volnému využití.
V režii vývojářů jednoznačně identifikovatelných programů je pak
stanovení čísel procedur a jejich verzí. Tyto tři čísla
reprezentují jednoznačnou identifikaci vzdálené procedury a jsou využívána
zejména během procesu registrace u portmapperu a při dotazování klienta
na přístupový port procedury, na němž naslouchá tzv. spojka (stub).
Seznam definující přiřazení názvů služeb k číslům programů je obvykle uložen
v souboru /etc/rpc, jehož část ukazuje následující výpis, kde
si můžete všimnout jaké je programové číslo NFS.
#ident "@(#)rpc 1.11 95/07/14 SMI" /* SVr4.0 1.2 */
#
# rpc
#
portmapper 100000 portmap sunrpc rpcbind
rstatd 100001 rstat rup perfmeter rstat_svc
rusersd 100002 rusers
nfs 100003 nfsprog
ypserv 100004 ypprog
mountd 100005 mount showmount
ypbind 100007
walld 100008 rwall shutdown
yppasswdd 100009 yppasswd
etherstatd 100010 etherstat
rquotad 100011 rquotaprog quota rquota
Příkazem rpcinfo -p se pak také můžete portmapperu zeptat, jaké
služby pod jeho správou běží. Výstupem může
být něco takového:
program vers proto port
100000 2 tcp 111 portmapper
100000 2 udp 111 portmapper
100011 1 udp 749 rquotad
100011 2 udp 749 rquotad
100005 1 udp 759 mountd
100005 1 tcp 761 mountd
100005 2 udp 764 mountd
100005 2 tcp 766 mountd
100005 3 udp 769 mountd
100005 3 tcp 771 mountd
100003 2 udp 2049 nfs
100003 3 udp 2049 nfs
Spojka se vyskytuje jak na straně serveru tak i klienta. Na straně klienta
se stará zejména o kódování (marshalling nebo též serializing)
argumentů, případně pomocných objektů, pokud se jedná o volání odkazem,
a o uskutečnění přenosu, čili odeslání (5)
dotazu, čekání na přijetí odpovědi a její zpětné dekódování (unmarshalling
nebo též deserializing). O (de)kódování si povíme později.
Na straně serveru se spojky starají o přijetí dotazu, jeho dekódování,
volání příslušné procedury (6) s danými parametry, převzetí výsledku, jeho
kódování a zaslání odpovědi klientovi (7).
Ještě poznamenejme, že patrně v zájmu snazší implementace zavedla firma Sun konvenci,
že všechny vzdálené procedury mají právě jeden vstupní parametr,
a právě jeden výstupní parametr. Zdá-li se vám to příliš omezující, vězte, že
pokud by bylo zapotřebí předat více parametrů, mohou být zabaleny do jedné
datové struktury a předány vzdálené proceduře prostřednictvím jednoho ukazatele,
která musí být samozřejmě v rámci vzdáleného volání přenesena na server.
eXternal Data Representation (XDR)
Jak už jsme zmínili výše, je pro potřeby předání dat mezi klientem a serverem
nutno tato data kódovat, resp. zpracovat do podoby, které budou rozumět
obě strany, zejména pokud se jedná o jiné počítačové architektury,
kdy by např. chyba v určení velikosti integeru nebo endianitě mohla
způsobit nežádoucí chyby.
Firma Sun pro implementaci a realizaci svého RPC mechanismu využívá
standardu XDR, který je popsán v RFC 1832.
Standard XDR tedy definuje jednotný způsob reprezentace přenášených dat,
nezávislý na konkrétní architektuře jejich odesilatele i příjemce. Kromě
toho je součástí XDR také jazyk pro nezávislý popis těchto dat. Po stránce
implementační souvisí s tímto standardem také konkrétní konverzní rutiny,
které mají nejčastěji formu knihovních rutin, a jsou obvykle označovány jak
XDR filtry.
NFS ver. 1 | - prototypová verze, která nebyla nikdy použita. |
NFS ver. 2 | - první distribuovaná verze
- ačkoliv byla tato verze podporována již od jádra verze 1.2, budete potřebovat
jádro alespoň verze 2.2.18 pokud chcete kombinovat Linux NFS s NFS ostatních OS,
používat spolehlivé zamykání souborů, nebo updatovat na NFS verze 3.
- přidává podporu Secure RPC (autentizace, šifrování). |
NFS ver. 3 | - pro plnou funkcionalitu této verze je potřeba jádra verze alespoň 2.4, zejména tedy pokud chcete mít možnost pracovat se soubory většími než 2GB. |
NFS ver. 4 | - zahrnuje např. podporu kopírování a
přesouvání souborů i s jejich metainformacemi. Navíc také podporu
silnější bezpečnosti, kombinovaných operací, klientské mezipaměti
a internacionalizace.
|
Jak NFS funguje?
Jak už víme, je NFS postaveno na bázi RPC služeb. Budeme-li chtít připojit
adresář na disku vzdáleného stroje, použijeme známého programu mount,
kterému sdělíme parametrem -t nfs, že jej chceme zpřístupnit
ze vzdáleného stroje. Například, chceme-li připojit adresář /exports/home/novak
nacházející se na stroji zeus tak, aby byl přístupný lokálně přes
/home/novak, pak to učiníme takto:
$ mount -t nfs zeus:/exports/home/novak /home/novak
Příkaz mount se pokusí pomocí RPC procedur spojit s připojovacím démonem mountd,
který běží na počítači zeus. Samozřejmě po úspěšné autentizaci a předání
komunikačního klíče pak již služby jádra klienta samozřejmě rozpoznávají, zda-li mají
data získávat lokálně nebo pomocí RPC volat vzdálené procedury, které to za ně učiní.
Konfigurace NFS
Pro používání NFS, jak je patrno z předchozího textu, je potřeba mít v jádru
zahrnutou podporu NFS. Zda-li náš systém podporuje NFS zjistíme v souboru
/proc/filesystems a nebo se můžeme pokusit připojit nějaký
vlastní lokální adresář.
Na straně klienta
Konfigurace NFS na straně klienta je poměrně snadná. Výše jsme si uvedli jeden
ze způsobu připojení vzdáleného souborového systému, ovšem výhodnější je
pro tyto potřeby definovat si záznamy v /etc/fstab.
Některé užitečné volby programu mount:
rsize=n wsize=n |
tyto volby určují velikost datagramu, které budou použity pro operace
čtení a zápis. Implicitně 1kB. |
timeo=n |
Specifikuje v desetinách sekundy, jak dlouho bude klient čekat na splnění
požadavku. Implicitně 0.7 sekundy. |
hard |
Pokud selže požadavek na server, pak, pokud není zadána volba intr,
nelze klientský program ukončit. Ten svou činnost obnoví poté, co server
začne být opět funkční. Zabraňuje se tak porušení struktury souborů. |
soft |
Opak volby hard. Silně se nedoporučuje používat tuto volbu v případech,
kdy nechceme, aby řízení přešlo na jinou aplikaci, dokud nejsou všechna data odeslána.
(Např. v případě zpracování adresáře elektronické pošty.)
|
intr |
Tato volba povolí signálům přerušit volání systému NFS. |
bg |
Připojení na pozadí. Je-li první pokus o připojení neúspěšný (např. spadlý server),
přesune se proces na pozadí a bude se dál pokoušet o připojení. Tento parametr
je výhodné používat pro připojení, která jsou součástí spouštěcího procesu.
Proces spouštění tak není ohrožen, nepodaří-li se připojit sdílené diskové oddíly. |
retrans=r |
Hodnota r představuje maximální počet pokusů o připojení v systémech
s měkkým připojením. |
Na straně serveru
Pro konfiguraci NFS serveru je potřeba mít běžící démony:
rpc.portmap,
rpc.nfsd, rpc.mountd, rpc.lockd, rpc.statd a rpc.rquotad.
rpc.portmap |
bez něj by nám NFS nefungovalo. |
rpc.nfsd |
jde o hlavní část síťového souborového systému NFS, která zpracovává jednotlivé požadavky. |
rpc.mountd |
je-li dán požadavek na připojení diskového oddílu, kontroluje, zda má klient
odpovídající přístupová práva. Informace o právech jsou uloženy kde jinde než
v /etc/exports. |
rpc.statd |
tento démon zajišťuje uzamykání souborů v prostředí klient-server. |
rpc.lockd |
démon rpc.statd používá démona rpc.lockd k zajištění
obnovy zámků na spadlých systémech. |
rpc.rquotad |
zajišťuje rozhraní mezi NFS a správcem kvót. |
Zda-li vám běží zjistíte pomoci rpcinfo -p.
Pokud nikoliv pak (a samozřejmě máte NFS server nainstalovaný)
pak:
$ /etc/rc.d/init.d/nfs start
nebo
$ service nfs start
Konfigurace se provádí v souboru /etc/exports,
kde jsou specifikovaný komu a za jakých podmínek je umožněno co připojit.
Jeho formát je následující:
directory machine1(option11,option12,...) machine2(option21,option22,...) ...
Kde directory určuje adresář, který má být sdílen, machineX
jsou jména či IP adresy stanic klientů NFS a optionYY jsou
volby resp. přístupová práva, která jsou daným klientům k tomuto adresáři
přiděleny. Místo IP či názvu stroje lze také použít identifikaci sítě,
kdy se za IP uvede lomítko a maska sítě.
Volby mohou být některé z následujících:
ro |
pouze pro čtení. |
rw |
pro čtení i zápis. |
noaccess |
klientovi bude odepřen přístup do všech podadresářů daného adresáře.
Tímto způsobem jsme schopni povolit přístup třeba např. do všech podadresářů
adresáře /data vyjma /data/jen_pro_karla. |
no_root_squash |
root připojující se z klienta bude rootem i na exportovaném svazku. |
no_subtree_check |
pokud se připojuje celý svazek, pak tato volba urychlí připojení. |
squash_uids=uid_list |
uid_list je čárkami oddělený seznam UID uživatelů, kterým
chcete odepřít přístup. Je možné použít také rozsahy např. squash_uids=100-200,301 |
squash_gids=gid_list |
obdobně jako v případě squash_uids=uid_list |
Příklad /etc/exports:
/usr/local 192.168.10.2(ro) 192.168.10.5(rw)
/home 192.168.0.0/255.255.255.0(rw,no_root_squash)
/export/fun *.lab.fi.muni.cz(ro)
Demon mountd je obvykle informován o tom, které adresáře jsou jeho
prostřednictvím připojeny k daným hostům. Tyto informace lze získat pomocí
programu showmount.
Pokud chcete, aby se případné změny v /etc/exports projevily bez
nutnosti restartovat NFS server, použijte příkazu exportfs.
Použít ho můžete mimojiné také k ručnímu nastavení sdílení bez nutnosti
měnit /etc/exports.
Použít můžete následujících voleb:
-a |
exportuje všechny záznamy v souboru /etc/exports. |
-r |
opětovně exportuje všechny záznamy v souboru /etc/exports. |
-u client:/dir/to/mount |
neexportovat adresář /dir/to/mount pro klienta client. |
-o options |
zde je možné zadávat stejné volby, jaké se používají v /etc/exports.
Budou se však vztahovat k souborovému systému určenému v příkazovém řádku exportfs. |
-v |
bude vypisovat, co dělá. |
Chcete-li například exportovat adresář /export/stuff pro klientskou
stanici hera s právy pro čtení a zápis a no_root_squash
napište
$ exportfs -o rw,no_root_squash hera:/export/stuff
Ke zvýšení bezpečnosti a omezení přístupu k exportovaným svazkům slouží také soubory
/etc/hosts.allow a /etc/hosts.deny.
Literatura
- RFCs 1049, 1813, 2054, 2055, 2224, 2623, 2624, 3530
- nfs(5), exports(5), mount(8), fstab(5), nfsd(8), lockd(8), statd(8), rquotad(8), mountd(8), exportfs(8), showmount(8)
- www.tldp.org/HOWTO/ - NFS HOWTO
- nfs.sourceforge.net
- www.earchiv.cz - Seriál: Co je čím ... v počítačových sítích - NFS
Automount
Konfigurace Autofs
Automount je démon, který zajišťuje automatické připojování a odpojování
svazků. Je spouštěn skriptem /etc/rc.d/init.d/autofs.
Autofs je implementován v prostoru jádra, takže je potřeba mít v jádře jeho podporu
zakompilovánu. Autofs podporují všechny jádra 2.2 a výše.
Používá konfigurační soubor /etc/auto.master, jehož formát je:
mount_point map_type:map_name options
kde mount_point je místo připojení, map_type jedno
z file, program, yp, nisplus nebo hesiod, map_name
jméno mapovacího souboru (o něm později) a options jsou nepovinné volby (např.
--timeout=n určující po kolika sekundách se má
daný souborový systém odpojit po posledním použití).
Příklad /etc/auto.master:
/usr/mnt /etc/auto.misc --timeout=60
Příklad auto.misc určeného v /etc/auto.master:
kernel -ro,soft,intr ftp.kernel.org:/pub/linux
boot -fstype=ext2 :/dev/hda1
floppy -fstype=vfat :/dev/fd0
Je patrno, že položka /usr/mnt v auto.master nedefinuje
mountpoint, ale obecně množinu mountpointů, které jsou definovány v souboru
určeného druhou položkou, v našem případě /etc/auto.misc.
Soubor /etc/auto.misc, jak vidno, se skládá z řádků, kde jednotlivé
položky po řadě představují: mountpoint (v našem případě např. /usr/mnt/floppy),
volby připojení a to, co chceme připojit. Všimněme si prvního řádku, kde
se jedná o připojení přes NFS.
Konfigurace Amd
Jiným oblíbeným automounterem je Amd. Konfiguruje se v souboru /etc/amd.conf.
Aby se změny v tomto konfiguračním souboru projevily ihned, je třeba Amd restartovat.
Může vypadat následovně:
/defaults opts:=rw;type=nfs
# where you have your home directory
home type:=nfs;rhosts:=home;rfs:=/home
# where you have your incoming emails
mail type:=nfs;rhosts:=mail;rfs:/var/spool/mail
# Replace with the server you have access to
server1 type:=nfs;rhosts:=server1;rfs:=/server1
kde první položka představuje mountpoint v adresáři, který definujete
parametrem -a dir při spouštění Amd démona. Obvykle je to adresář
/.automount. Ostatní položky na řádku definují co a jak se má
k danému mountpointu připojovat.
Pokud démon Amd běží, pak se svazky připojují jakmile se je pokusíte
zpřístupnit např. příkazem ls /.automount/home/karel. Po určité
časové prodlevě, po které nebyl svazek zpřístupněn, se opět automaticky
odpojí. Tímto způsobem se tedy snadno řeší připojování třeba domovského adresáře,
při přihlášení uživatele, a odpojení při jeho odhlášení.
Literatura
- autofs(5), autofs(8), automount(8), auto.master(5), amd.conf(5), amd
- www.tldp.org/HOWTO/ - Automount HOWTO