Cum se configurează smartphone-uri și PC-uri. Portal informativ
  • Acasă
  • Windows Phone
  • Ce este NFS? Sistem de fișiere de rețea. Protocolul de acces la sistemul de fișiere în rețea

Ce este NFS? Sistem de fișiere de rețea. Protocolul de acces la sistemul de fișiere în rețea

NFS vă permite să partajați directoare pe o mașină Unix. Nesiguranța NFS, și în special NIS, este asociată cu RPC - în ceea ce privește numărul de tot felul de exploit-uri, RPC pare să fie liderul neoficial (cu excepția Sendmail). Deoarece aceste protocoale sunt destinate rețelelor interne, ele vor trebui protejate de utilizatorii „lor”. Deși, înainte de a le folosi, trebuie să decideți dacă sunt cu adevărat necesare.

Într-o rețea de acasă, pot fi destul de utile, dar pe o rețea corporativă, din motive de securitate, este mai bine să găsești o alternativă mai sigură la ele.

Sistem de fișiere NFS.

Sistemul de fișiere în rețea (NFS) a fost dezvoltat de Sun ca mijloc de accesare a fișierelor găzduite pe alte mașini Unix într-o rețea locală. Securitatea nu a fost deloc luată în considerare în proiectarea NFS, ceea ce a cauzat multe vulnerabilități de-a lungul anilor.

NFS poate rula peste TCP sau UDP și folosește un sistem RPC, ceea ce înseamnă că trebuie să ruleze următoarele aplicații vulnerabile: portmapper, nfs, nlockmgr (lockd), rquotad, statd și mountd.

Nu trebuie să porniți NFS - trebuie să găsiți o soluție alternativă. Dacă aveți nevoie de NFS, iată cum să minimizați riscul de a-l folosi.

/ etc / exporturi

Primul pas este să selectați mașinile care își vor exporta sistemele de fișiere. Apoi puteți determina ce mașini au voie să se conecteze la serverele NFS (sau la un server dacă există doar unul) în rețea. Nu trebuie să utilizați NFS pe mașini care sunt conectate direct (direct) la Internet. După selectarea mașinilor, trebuie să selectați directoarele de pe aceste mașini care vor fi exportate.

Directoarele de export sunt definite în fișierul / etc / exports. Formatul fiecărei intrări este simplu: numele directorului, lista utilizatorilor cărora li se permite accesul și modul de acces. De exemplu:

Accesul complet (citire/scriere) la directorul / home / utilizator este permis mașinii cu adresa IP 10.0.0.6. Cel mai bun lucru este să nu acordați acces deplin, ci să vă limitați la acces doar în citire (ro). Pe lângă aceasta, puteți specifica și următoarele opțiuni:

  • Sigur- cererea de montare trebuie să provină de la un port privilegiat (până la 1024). Aceasta înseamnă că comanda mount a fost introdusă de un utilizator cu privilegii root.
  • Root_squash- cererea utilizatorului root va fi tratată ca o solicitare anonimă a utilizatorului. Acest lucru permite cea mai mică deteriorare a sistemului. Această opțiune trebuie să fie activată.
  • All_squash- toate cererile (nu numai de la utilizatorul root) vor fi considerate ca provenind de la un utilizator anonim. Util pentru directoarele exportate public.

Dacă un cracker ca rădăcină obține acces la o mașină căreia i s-a acordat acces rw la directorul specificat în / etc / exports, câștigă control deplin asupra sistemului de fișiere, astfel încât directorul rădăcină (/) nu poate fi exportat și directoarele critice ale sistemului, de exemplu / usr, / bin, / sbin, / lib, / opt și / etc. Directoarele de acasă ale utilizatorilor sunt bune pentru export.

Pe partea clientului, montați sistemul de fișiere partajat cu opțiunea -o nosuid:

# mount -t nfs -o nosuid 10.0.0.3:/home/user/files / mnt / home / frank

Acest lucru va împiedica crackerul cu acces la serverul NFS să obțină acces root la clienți.

Limitarea accesului.

Indiferent de serviciu, trebuie să utilizați IPTables pentru a restricționa accesul la aparat. Acest lucru este deosebit de important în cazul unui server NFS. Când utilizați IPTables, rețineți că demonul NFS folosește portul 2049 / TCP / UDP.

Unele servicii RPC, precum portmapper și NFS, folosesc porturi persistente (113 și respectiv 2049 / tcp / udp), dar alte servicii RPC nu au porturi persistente, ceea ce face dificilă filtrarea pachetelor folosind IPTables. Singurul lucru care se știe este că RPC folosește porturi în intervalul 32768-65535.

Dacă utilizați nucleul 2.4.13 sau o versiune ulterioară, utilizați opțiunea -p<порт>puteți specifica portul exact pentru fiecare serviciu RPC.

Luați în considerare funcția start () din /etc/rc.d/init.d/nfslock folosită pentru a porni nsflock:

start () (

#. Începeți demonii.

dacă ["$ USERLAND_LOCKD"]; atunci

echo -n $ "Se pornește blocarea NFS:"

daemon rpc.lockd

echo -n $ "Se pornește NFS statd:"

daemon rpc.statd

echo [$ RETVAL -eq 0] && atingere / var / atingere / blocare / subsys / nfslock

returnează $ RETVAL)

Pentru a forța demonul statd să folosească un anumit port, puteți utiliza opțiunea -p, de exemplu demonul rpc.statd -p 32800 (sau orice doriți). De asemenea, trebuie să setați portul pentru mountd, nfsd, rquotad - toate sunt rulate din scriptul /etc/rc.d/init.d/nfs:

start () (

# Începeți demonii.

acțiune -n ​​$ „Pornirea serviciilor NFS:” / usr / sbin / exportfs -r

dacă t _x /usr/sbin/rpc.quotad]; apoi echo -n $ „Pornirea cotelor NFS:” daemon rpc.rquotad echo

fi echo -n $ "Se pornește NFS mountd:"

daemon rpc.mountd 3RPCMOUNTDOPTS

echo -n $ "Se pornește demonul NFS:" daemon rpc.nfsd $ RPCNFSDOPTS echo touch / var / blocare / subsys / nfs

Tehnologia de schimbare a portului pentru lockd (nlockmgr) este diferită de cea de mai sus (nu este nevoie să încercați să schimbați fișierul /etc/rc.d/init.d/nfslock - nu va ieși nimic din asta).

Lockd este executat fie ca un modul de nucleu, fie compilat static în nucleu. Pentru a schimba numărul portului, deschideți fișierul / etc / modules și găsiți opțiunile transmise modulului:

opțiuni lockd nlm_udpport = 33000 nlm_tcpport = 33000

Acum că serviciile RPC folosesc porturi statice care sunt cunoscute, trebuie să folosim IPTables. Următorul set de reguli presupune că NFS este singurul server care rulează pe mașină și că numai mașinile listate în fișierul /usr/local/etc/nfsexports.hosts au acces:

IPX = "/ usr / sbin / iptables"

#Șterge toate lanțurile

$ IPT --flush

$ IPT -t nat --flush $ IPT -t mangle --flush $ IPT -X

# Permite traficul loopback $ IPT -A INTRARE -i lo -j ACCEPT $ IPT -A IEȘIRE -o lo -j ACCEPT

# Reguli implicite $ IPT -P INTRARE DROP $ IPT -P IEȘIRE DROP $ IPT -P FORWARD DROP

$ IPT -A INTRARE -m stare -stare INSTALAT, RELATED -j ACCEPT $ IPT -A IEȘIRE -m stare -stare NOU, STABILIT, RELATED -j ACCEPT

# Permite accesul la fiecare computer,

# specificat în /usr/local/etc/nfsexports.hosts

pentru gazdă în „cat /usr/local/etc/nfsexports.hosts”; face $ IPT -I INTRARE -s $ gazdă -p tcp -dport 111 -j ACCEPT

$ IPT -I INTRARE -s $ gazdă -p udp -dport 111 -j ACCEPT

$ IPT -I INTRARE -s $ gazdă -p udp -dport 2049 -j ACCEPT

$ IPT -I INTRARE -s $ gazdă -p tcp --dport 32800 -j ACCEPT

$ IPT -I INTRARE -s $ gazdă -p tcp --dport 32900 -j ACCEPT

$ IPT -I INTRARE -s $ gazdă -p tcp -dport 33000 -j ACCEPT

$ IPT -I INTRARE -s $ gazdă -p tcp --dport 33100 -j ACCEPT

Desigur, acesta este doar un schelet, va trebui să adăugați mai multe reguli: cel puțin activați SSH și setați niște parametri ai nucleului folosind / proc.

Tunnel NFS peste SSH.

Abrevierea NFS înseamnă uneori „No File Security” - aceste trei cuvinte vorbesc de la sine. Prin urmare, este foarte important să securizați traficul NFS. Este ușor să faci asta cu ssh.

Inițial, puteți modifica fișierul / etc / exports pe serverul NFS, astfel încât sistemele de fișiere să fie exportate în nodul local:

Apoi, trebuie să utilizați SSH pentru a redirecționa porturile NFS și mountd. NFS folosește portul 2049 / udp, iar mountd, după cum sa menționat, folosește portul 33000:

# ssh [email protected]-L 200: localhost: 2049 -f somn 120m

# ssh [email protected]-L 200: localhost: 33000 -f somn 120m

Aceste două comenzi oferă utilizatorului un shell interactiv, dar întrucât nu este necesar, SSH execută comanda sleep 120: ne întoarcem la linia de comandă, dar redirecționarea portului va dura încă 2 ore.

Montarea sistemului de fișiere din partea clientului pare foarte neobișnuită:

mount -t nfs -o nosuid port = 200 mountport = 210 nfsserver.test.net:/home/user / mnt / another

Dacă trucurile de tunelizare ssh sunt prea complexe, proiectul SHFS (Shell Filesystem) ( http://shfs.sourceforge.net/ ), ceea ce face posibilă automatizarea întregii proceduri.

După instalare, trebuie să accesați SHFS fie cu comanda mount -t shfs, fie cu noua comandă shfsmount. Sintaxa acestei comenzi este similară cu cea anterioară:

shfsmount [email protected]: / home / user / mnt / user

CFS și TCFS

Sistemul de fișiere criptografice criptează și decriptează în mod transparent traficul NFS utilizând algoritmul DES. În plus, acceptă gestionarea automată a cheilor, ceea ce face ca procesul să fie cât mai transparent posibil pentru utilizator.

Deși conceput pentru SunOS și BSD, CFS este interesant, deoarece pare a fi prima încercare de a codifica transparent fișierele partajate. Sistemul de fișiere criptografice transparent (TCFS) oferă o modalitate și mai transparentă de a cripta traficul NFS.

Pe lângă codificarea datelor, acest sistem de fișiere acceptă verificarea integrității datelor.

Pentru distribuirea fișierelor într-o rețea locală, se pot distinge următoarele tehnologii (se iau în considerare sistemele bazate pe Linux):

  • Network File System (NFS) - un protocol pentru accesul în rețea la sistemele de fișiere;
  • Fișierele transferate prin protocolul Shell (FISH) este un protocol de rețea care utilizează sau RSH pentru a transfera fișiere între computere;
  • Secure SHell FileSystem (SSHFS) - un client de sistem de fișiere pentru montarea dispozitivelor de disc pe sisteme la distanță, folosit pentru a interacționa cu un sistem la distanță SFTP;
  • Samba este un pachet software care vă permite să accesați unități de rețea și imprimante pe diverse sisteme de operare folosind protocolul SMB / CIFS;

Această notă se va concentra asupra NFS.

NFS (sistem de fișiere de rețea) util atunci când trebuie să distribuiți fișiere/directoare tuturor celor din rețea. Accesați transparența folosind NFS Permite clienților să monteze un sistem de fișiere la distanță ca director local, iar sistemele de fișiere pot fi de diferite tipuri. Aceasta înseamnă că orice aplicație client care poate funcționa cu un fișier local poate funcționa la fel de bine cu un fișier conectat de NFS, fără modificări ale programului în sine.

La beneficii NFS pot fi atribuite:

  • reducerea sarcinii procesorului;
  • afișarea resurselor partajate ca directoare obișnuite pe sistem;
  • Disponibil acum NFS v4.1, care a introdus o nouă caracteristică pNFS permițându-vă să paralelizați implementarea partajării fișierelor. Există, de asemenea, o extensie pentru NFS 2 și 3 - WebNFS ceea ce facilitează integrarea în browsere web și face posibilă funcționarea printr-un firewall.

    Schema de lucru NFS protocol.

    Instalarea și configurarea unui server NFS sub Linux

    Verificați dacă sistemul acceptă NFS

    Cat / proc / sisteme de fișiere | grep nfs

    Sub Arch Linux serverul și clientul sunt în același pachet

    Yaourt -S nfs-utils

    Pentru a instala serverul ( nfs-kernel-server) și client ( nfs-comun) sub Ubuntu pachetele necesare

    Sudo apt-get install nfs-kernel-server nfs-common portmap

    Mai departe, în nota pentru IP-ul serverului va fi folosit 192.168.1.100 ... Pentru ca serverului să i se atribuie întotdeauna același IP, este necesar să se specifice distribuția unui anumit IP la o anumită adresă MAC în serverul DHCP (cel mai adesea un router). Sau deschideți serverul DNS local. De exemplu sau.

    Adresa MAC poate fi găsită folosind ifconfig (câmp eter v Arch Linux).

    NFSv4 presupune că există un director rădăcină în care se află deja fișierele de distribuție. De exemplu, / srv / nfs- radacina, / srv / nfs / audio- un director pentru distribuirea muzicii. Dacă nu respectați această nouă directivă în versiune 4 , atunci puteți primi o eroare la conectarea de către client:

    Mount.nfs: acces refuzat de server în timpul instalării 192.168.1.100:/home/proft/torrents

    Dacă tot doriți să utilizați abordarea fără server fără un director rădăcină pentru NFS, apoi la montare de către client, trebuie să specificați în mod explicit versiunea 3

    # pentru comanda mount mount -o "vers = 3" 192.168.1.100:/home/proft/torrents / home / proft / nfs / torrents # pentru fstab 192.168.1.100:/home/proft/torrents / home / proft / nfs / torrents nfs soft, nfsvers = 3 0 0

    voi folosi NFSv4 cu directorul rădăcină în / srv / nfs /și montarea subdirectoarelor folosind mount --bind.

    Să presupunem că vrem

    • distribui un director ~ / torrente Cu rw acces pentru dintre toateîn interiorul rețelei locale;
    • distribui un director ~ / fotografii Cu ro acces pentru gazdă cu IP 192.168.1.101 ;

    Mai întâi, să creăm directorul rădăcină și cele imbricate necesare.

    Sudo mkdir -p / srv / nfs / (torrente, fotografii)

    Montați directoarele existente torrente, fotografii v / srv / nfs.

    # sudo vim / etc / fstab / home / proft / torrents / srv / nfs / torrents none bind 0 0 / home / proft / photos / srv / nfs / photos none bind 0 0

    Hai să edităm / etc / exporturi care descrie toate directoarele partajate

    # sudo vim / etc / exports # format fișier: directorul permit-hosts (opțiuni) / srv / nfs / torrents 192.168.1.1/24(rw,async) / srv / nfs / photos 192.168.1.101 (ro, async)

    Rețineți că nu există spațiu între gazde permiseși (Opțiuni)... Prezența unui spațiu introduce o interpretare diferită a regulilor.

    Optiuni Disponibile:

    • ro (rw) - permite accesul numai în citire (citire/scriere);
    • subtree_check (no_subtree_check) - în unele cazuri, trebuie să exportați nu întreaga secțiune, ci doar o parte a acesteia. În acest caz, serverul NFS ar trebui să efectueze validare suplimentară a solicitărilor clienților pentru a se asigura că aceștia încearcă să acceseze numai fișierele din subdirectoarele corespunzătoare. Un astfel de control al subarborelui ( verificări subarbore) încetinește ușor interacțiunea cu clienții, dar dacă o renunți, pot apărea probleme cu securitatea sistemului. Puteți elimina controlul unui subarboresc folosind opțiunea no_subtree_check... Opțiune subtree_check activarea unor astfel de controale se presupune implicit. Controlul subarborelui poate fi omis dacă directorul exportat coincide cu partiția discului;
    • sync (async) - Indică faptul că serverul ar trebui să răspundă la solicitări numai după ce modificările făcute de acele solicitări sunt scrise pe disc. Opțiune asincron instruiește serverul să nu aștepte ca informațiile să fie scrise pe disc, ceea ce îmbunătățește performanța, dar scade fiabilitatea, deoarece dacă conexiunea este întreruptă sau echipamentul eșuează, este posibilă pierderea datelor;
    • noaccess - interzice accesul la directorul specificat. Poate fi util dacă anterior ați dat acces tuturor utilizatorilor rețelei la un anume director, iar acum doriți să restricționați accesul în subdirector doar la unii utilizatori;
    • no_root_squash - utilizator implicit rădăcină pe computerul client nu va avea aceleași drepturi la directorul de pe server. Această opțiune elimină această limitare;
    • nuhide - NFS nu afișează automat resurse non-locale (de exemplu, montate folosind mount --bind), această opțiune activează afișarea acestor resurse;
    • nesigur - utilizați porturi neprivilegiate (> 1024);

    Lansarea serverului NFS

    # sub archlinux sudo systemctl start rpc-idmapd.service rpc-mountd.service # sub ubuntu sudo /etc/init.d/nfs-kernel-server start

    În viitor, la schimbarea fișierului de configurare, este suficient să-l recitiți cu comanda:

    Sudo exportfs -rav

    Comanda Rpcinfo -p | grep nfs vă permite să verificați dacă serverul a pornit cu succes.

    client Linux

    Instalare

    # pentru archlinux yaourt -S nfs-utils # pentru ubuntu sudo apt-get install portmap nfs-common

    Creați directoare pentru montarea resurselor de rețea torrenteși fotografii

    Mkdir -p ~ / nfs / (torrente, fotografii)

    Pentru montaj manual, executați

    Sudo mount -t nfs -o rw, soft 192.168.1.100:/srv/nfs/torrents / home / proft / nfs / torrents sudo mount -t nfs -o rw, soft 192.168.1.100:/srv/nfs/photos / proft / nfs / fotografii

    Opțiune moale indică anularea în liniște a încercărilor de a conecta mingea după o anumită perioadă de timp (timpul este stabilit de opțiunea retrans). Mai mult in man nfs.

    Această metodă nu este foarte convenabilă, deoarece va trebui să executați aceste comenzi de fiecare dată după repornire. Să facem montarea automată.

    Pentru montarea automată, editați fișierul / etc / fstab

    # sudo vim / etc / fstab 192.168.1.100:/srv/nfs/torrents / home / proft / net / torrents nfs rw, soft 0 0 192.168.1.100:/srv/nfs/photos / home / proft / net / photos nf ro, soft 0 0

    Dar această metodă are și dezavantajele sale, de exemplu, dacă serverul nu este disponibil, atunci încărcarea clientului se poate îngheța din cauza încercărilor de conectare la serverul NFS. Pentru a remedia acest lucru, vedeți mai jos despre AutoFS.

    AutoFS - conectarea automată a resurselor de rețea

    Este posibil să montați o resursă la distanță folosind AutoFS prima dată când este accesat și demontat automat când nu există activitate.

    AutoFS folosește șabloane situate în / etc / autofs... Șablonul principal este numit auto.master, poate indica unul sau mai multe alte șabloane pentru anumite tipuri de media.

    Instalare

    # pentru archlinux yaourt -S autofs # pentru ubuntu sudo apt-get install autofs

    Există mai multe moduri de a specifica modul de montare automată. Eu folosesc asta: in / acasă / profit / nfs este creat automat un director cu numele serverului NFS, în care sunt create automat directoarele disponibile pe server.

    # sudo vim /etc/autofs/auto.master / home / proft / nfs /etc/autofs/auto.nfs --timeout = 60

    Parametru suplimentar pauză setează numărul de secunde după care dispozitivul va fi demontat. Parametru fantomă indică faptul că resursele configurate vor fi întotdeauna afișate și nu numai atunci când sunt disponibile (această opțiune este activată implicit în AutoFS 5)

    Descriem în /etc/autofs/auto.nfs Serverul NFS și directorul rădăcină.

    # sudo vim /etc/autofs/auto.nfs nfsserver 192.168.1.100:/srv/nfs

    Acum la primul apel / home / proft / nfs / torrents partajarea NFS va fi montată automat.

    Să repornim serviciul autofs:

    # sub archlinux sudo systemctl restart autofs # sub ubuntu sudo /etc/init.d/autofs restart

    De asemenea, puteți specifica timpul de așteptare pentru disponibilitatea resursei NFS. Pentru a face acest lucru, trebuie să modificați valorile MOUNT_WAIT.

    # sub archlinux # sudo vim /etc/conf.d/autofs MOUNT_WAIT = 5 # sub ubuntu sudo / etc / default / autofs MOUNT_WAIT = 5

    Forțarea utilizării NFS v3

    In unele cazuri NFSv4 poate fi lent. Pentru a remedia acest lucru, puteți forța utilizarea celei de-a treia versiuni.

    Toată lumea știe că pe sistemele UNIX, un sistem de fișiere este în mod logic o colecție de sisteme de fișiere fizice atașate la un singur punct. Unul dintre cele mai de bază farmece ale unei astfel de organizații, în opinia mea, este capacitatea de a modifica dinamic structura unui sistem de fișiere existent. De asemenea, datorită eforturilor dezvoltatorilor, astăzi suntem capabili să conectăm FS de aproape orice tip și în orice mod convenabil. Vorbind „într-un fel”, vreau în primul rând să subliniez posibilitatea de a opera nucleul OS cu sisteme de fișiere prin conexiuni de rețea.

    Multe protocoale de rețea ne oferă posibilitatea de a lucra cu fișiere de la distanță, fie ele FTP, SMB, Telnet sau SSH. Datorită capacității nucleului, în cele din urmă, de a nu depinde de tipul de FS, putem folosi programul de montare pentru a conecta orice și cum doriți.

    Astăzi vreau să vorbesc despre NFS - Network File System. Această tehnologie permite ca punctele individuale ale sistemului de fișiere de pe un computer la distanță să fie conectate la sistemul de fișiere al computerului local. Protocolul NFS în sine vă permite să efectuați operațiuni cu fișiere destul de rapid, în siguranță și fiabil. Ce altceva mai avem nevoie? :-)

    Ce este necesar pentru ca asta să funcționeze

    Pentru a nu dezvălui mult timp pe tema versiunilor NFS și a suportului acestora în diverse nuclee, vom face imediat presupunerea că versiunea dvs. de kernel este cel puțin 2.2.18. În documentația oficială, dezvoltatorii promit suport deplin pentru funcționalitatea NFS versiunea 3 în acest kernel și mai târziu.

    Instalare

    Pentru a rula serverul NFS pe Ubuntu 7.10 meu - Gutsy Gibbon, trebuia să instalez pachetele nfs-common și nfs-kernel-server. Dacă aveți nevoie doar de un client NFS, nu trebuie să instalați nfs-kernel-server.

    Ajustarea serverului

    După ce toate pachetele sunt instalate cu succes, trebuie să verificați dacă demonul NFS rulează:

    Starea /etc/init.d/nfs-kernel-server

    Dacă demonul nu rulează, trebuie pornit cu comanda

    /etc/init.d/nfs-kernel-server start

    După ce totul a început cu succes, puteți începe să exportați sistemul de fișiere. Procesul în sine este foarte simplu și durează minim.

    Fișierul principal de configurare a serverului NFS se află în / etc / exports și are următorul format:

    Director machine1 (opțiune11, opțiune12) mașină2 (opțiune21, opțiune22)

    director- calea absolută către directorul serverului FS la care doriți să acordați acces

    mașinăX- Numele DNS sau adresa IP a computerului client de la care este permis accesul

    opțiuneaXX- Parametrii de export FS, cei mai des utilizați dintre ei:

    • ro- accesul la fișiere este permis doar pentru citire
    • rw- acces citire/scriere
    • no_root_squash- în mod implicit, dacă vă conectați la un share NFS ca root, serverul, din motive de securitate, pe partea sa va accesa fișierele ca utilizator nimeni. Cu toate acestea, dacă activați această opțiune, atunci fișierele de pe partea serverului vor fi accesate ca root. Aveți grijă cu această opțiune.
    • no_subtree_check- în mod implicit, dacă exportați nu întreaga partiție de pe server, ci doar o parte a sistemului de fișiere, demonul va verifica dacă fișierul solicitat se află fizic pe aceeași partiție sau nu. Dacă exportați întreaga partiție sau punctul de montare al sistemului de fișiere exportat nu afectează fișierele din alte volume fizice, puteți activa această opțiune. Acest lucru vă va oferi o creștere a vitezei serverului.
    • sincronizare- activați această opțiune dacă există probabilitatea unei deconectari bruște sau a unei întreruperi de curent a serverului. Dacă această opțiune nu este activată, riscul de pierdere a datelor atunci când serverul NFS este oprit brusc este mult crescut.

    Deci, să presupunem că vrem să dăm acces ashep-desktop la directorul / var / backups al ashep-laptop. Accesul la director este necesar pentru a copia fișierele de rezervă de pe desktop-ul ashep. Am primit urmatorul fisier:

    / var / copii de rezervă ashep-desktop (rw, no_subtree_check, sync)

    După adăugarea unei linii la / etc / exporturi, trebuie să reporniți serverul NFS pentru ca modificările să aibă efect.

    /etc/init.d/nfs-kernel-server reporniți

    Asta e tot. Puteți începe conectarea sistemului de fișiere exportat pe computerul client.

    Configurarea clientului

    Pe partea clientului, sistemul de fișiere la distanță este montat în același mod ca toate celelalte - cu comanda mount. De asemenea, nimeni nu vă interzice să utilizați / etc / fstab dacă trebuie să vă conectați automat FS-ul când sistemul de operare pornește. Deci, opțiunea cu montare va arăta astfel:

    Mount -t nfs ashep-laptop: / var / copii de rezervă / / mnt / ashep-laptop / copii de rezervă /

    Dacă totul a mers bine și trebuie să vă conectați automat la sistemul de fișiere la distanță la pornire - trebuie doar să adăugați o linie la / etc / fstab:

    Ashep-laptop: / var / backups / mnt / ashep-laptop / backups nfs auto 0 0

    Ce altceva

    Iată o imagine de ansamblu mică și practică a capabilităților NFS. Desigur, aceasta este doar o mică parte din ceea ce poate face NFS. Acest lucru este suficient pentru uz casnic sau mic de birou. Dacă acest lucru nu este suficient pentru tine, recomand să citești în primul rând.

    Iată, ce urmează? Cum vizionez filme și ascult fișierele muzicale descărcate? Chiar trebuie să le inscripționați pe discuri și să le transferați în acest fel pe un computer cu GUI? Sau trebuie să le copiați prin SFTP lent? Nu! NFS vine în ajutor! Nu, aceasta nu este o serie de jocuri de curse, ci un sistem de fișiere de rețea.
    Sistemul de fișiere de rețea (NFS) este un sistem de fișiere de rețea care permite utilizatorilor să acceseze fișiere și directoare situate pe computere la distanță ca și cum fișierele și directoarele ar fi locale. Principalul avantaj al unui astfel de sistem este că stațiile de lucru individuale pot folosi mai puțin spațiul pe disc, deoarece datele partajate sunt stocate pe o mașină separată și sunt disponibile pentru alte mașini din rețea. NFS este o aplicație client/server. Adică, un client NFS trebuie instalat pe sistemul utilizatorului și un server NFS pe computerele care le oferă spațiu pe disc.

    Instalarea și configurarea unui server NFS (192.168.1.2)

    1. Instalați. După ce v-ați conectat prin SSH la computer de către server sau pur și simplu în consola acestuia, introduceți:

    Sudo apt-get install nfs-kernel-server nfs-common portmap

    Aceasta va instala serverul NFS, precum și pachetul portmap necesar.

    2. Configurare. Pentru a configura lista directoarelor pe care dorim să le deschidem și lista cui dorim să le deschidem, editați fișierul / etc / exporturi :

    Sudo nano / etc / exporturi / date 192.168.1.1/24(rw,no_root_squash,async)

    În exemplul de mai sus, am deschis directorul de pe server / date și subdirectoarele sale pentru utilizare partajată de către toate computerele cu IP: 192.168.1.1 - 192.168.1.255 cu drepturi de citire și scriere.

    Alt exemplu:

    / home / serg / 192.168.1.34 (ro, async)

    Acest exemplu face directorul principal al serg-ului utilizatorului disponibil în modul numai citire pentru computerul cu IP 192.168.1.34. Toate celelalte computere din rețea nu vor avea acces la acest director.

    Optiuni Disponibile:

    • ro - permisiunea numai pentru citire. Nu trebuie să-l specificați, deoarece este instalat implicit;
    • rw - oferă clienților acces la scriere;
    • no_root_squash - implicit, utilizatorul root de pe computerul client nu va avea acces la directoarele deschise de pe server. Cu această opțiune, eliminăm această limitare. Din motive de siguranță, cel mai bine este să nu faceți acest lucru;
    • noaccess - interzice accesul la directorul specificat. Poate fi util dacă ați setat anterior accesul pentru toți utilizatorii rețelei la un anumit director, iar acum doriți să restricționați accesul în subdirector doar la unii utilizatori.

    Acum trebuie să reporniți nfs-kernel-server:

    Sudo /etc/init.d/nfs-kernel-server restart

    Daca dupa aceea vrei sa schimbi ceva in fisier / etc / exporturi , apoi pentru ca modificările să aibă efect, trebuie doar să rulați următoarea comandă:

    Sudo exportfs -a

    Tot. Serverul NFS este instalat și configurat. Puteți accesa clientul NFS.

    Instalarea și configurarea clientului NFS

    1. Instalare. Efectuăm următoarele în terminalul computerului care se va conecta:

    Sudo apt-get install portmap nfs-common

    2. Setare. Mai întâi, să creăm un director în care va fi montat folderul la distanță:

    Cd ~ mkdir date

    Puteți monta în două moduri - de fiecare dată manual sau scriind opțiunile de montare într-un fișier / etc / fstab.

    Metoda 1. Montare manuală
    Creați un fișier text pe desktop sau într-un alt folder:

    Nano ~ / desktop \ desktop / nfs-server-connect

    Ii scriem:

    #! / bin / bash sudo mount -t nfs -o ro, soft, intr 192.168.1.2:/data ~ / data

    Îl facem executabil:

    Chmod + x ~ / desktop \ desktop / nfs-server-connect

    Acum, când trebuie să mă conectez la server, rulez acest script în terminal, astfel încât să pot introduce parola pentru sudo.

    Metoda 2. Adăugarea la / etc / fstab
    Deschide / etc / fstab:

    Sudo nano / etc / fstab

    Și adăugați o linie la sfârșitul fișierului:

    192.168.1.2:/data ~ / data nfs rw, hard, intr 0 0

    Atenţie! Înlocuiți 192.168.1.2:/data cu IP-ul sau numele serverului și calea către directorul partajat. Opțiunile de montare pot fi modificate.

    Opțiune greu leagă în mod rigid directorul de pe client la server și, dacă serverul cade, computerul se poate bloca și el. Opțiune moale, după cum sugerează și numele, nu este atât de categoric.

    După salvarea fișierului, puteți monta folderul la distanță.

    Capitolul 29 NFS: Sistemul de fișiere în rețea

    Introducere

    În acest capitol, ne vom uita la Network File System (NFS), o aplicație populară care oferă aplicațiilor client acces transparent la fișiere. Piatra de temelie a NFS este Sun RPC: Remote Procedure Call, pe care îl vom descrie mai întâi.

    Programul client nu necesită instrumente speciale pentru a profita de NFS. Nucleul detectează că fișierul se află pe serverul NFS și generează automat un apel RPC pentru a accesa fișierul.

    Nu vom intra în detaliu asupra modului în care este implementat accesul la fișiere, ci mai degrabă ne vom uita la modul în care sunt utilizate protocoalele Internet, în special UDP.

    Sun Remote Procedure Call

    În cele mai multe cazuri, problemele de programare a rețelei sunt realizate prin scrierea unor programe de aplicație care apelează funcții furnizate de sistem pentru a efectua operațiuni specifice de rețea. De exemplu, o funcție realizează o deschidere TCP activă, alta deschidere TCP pasivă, o a treia trimite date printr-o conexiune TCP, a patra setează opțiuni specifice de protocol (include un cronometru TCP keepalive) și așa mai departe. În secțiunea Interfețe de programare a aplicațiilor din Capitolul 1, am menționat că există două seturi populare de funcții de programare în rețea (API), socket-uri și TLI. API-ul utilizat de client și API-ul utilizat de server pot diferi, la fel ca și sistemele de operare care rulează între client și server. Protocoalele de comunicare și de aplicație determină dacă un anumit client poate comunica cu serverul. Un client Unix scris în C folosind socket-uri ca interfață de programare și TCP ca protocol de comunicație poate comunica cu un server mainframe scris în COBOL folosind alte API-uri și TCP dacă ambele gazde sunt conectate la rețea și ambele au implementări TCP. / IP.

    De obicei, clientul trimite comenzi către server, iar serverul trimite răspunsuri către client. Toate aplicațiile pe care le-am analizat - Ping, Traceroute, demoni de rutare, clienți și servere DNS, TFTP, BOOTP, SNMP, Telnet, FTP, SMTP - sunt toate construite în acest fel.

    RPC, Remote Procedure Call, adoptă o abordare diferită a programării în rețea. Programul client apelează pur și simplu funcții în programul server. Acest lucru se decide din punctul de vedere al programatorului, dar în realitate are loc următoarea secvență de acțiuni.

    1. Când clientul apelează procedura de la distanță, este apelată funcția de pe gazda locală, care este generată de pachetul RPC. Această funcție se numește client stub. client stub împachetează argumentele procedurii într-un mesaj de rețea și trimite mesajul către server.
    2. server stub de pe serverul gazdă primește un mesaj de rețea. Argumentele sunt preluate din mesajul de rețea și se efectuează un apel către o procedură de server scrisă de un programator de aplicații.
    3. Funcția de server returnează controlul stub-ului serverului, care, la rândul său, preia valorile primite, le împachetează într-un mesaj de rețea și trimite mesajul înapoi către stub-ul clientului.
    4. client stub returnează valorile din mesajul de rețea către aplicația client.

    Programarea în rețea care utilizează rutinele de bibliotecă RPC și stub-uri utilizează API-uri (socket-uri sau TLI-uri), dar aplicațiile utilizator (programul client și rutinele de server numite de client) nu accesează niciodată API-ul. Aplicația client trebuie doar să apeleze procedura serverului, cu toate detaliile de implementare ascunse de pachetul RPC, client stub și server stub.

    Pachetele RPC au următoarele beneficii.

    • Programarea devine mai ușoară pentru că nu trebuie să rezolvi problemele de programare în rețea (și dacă trebuie, atunci destul de mult). Programatorii de aplicații scriu pur și simplu programul client și procedurile de server pe care le apelează clientul.
    • Dacă se folosește un protocol nesigur precum UDP, toate detaliile, și anume timeout-uri și retransmisii, sunt gestionate de pachetul RPC. Acest lucru, la rândul său, simplifică aplicația utilizatorului.
    • Biblioteca RPC se ocupă de conversia necesară a argumentelor și a valorilor returnate. De exemplu, dacă argumentele constau din numere întregi și numere în virgulă mobilă, pachetul RPC va gestiona orice diferență între reprezentările client și server ale numerelor întregi și numerelor în virgulă mobilă. Acest lucru facilitează implementarea clienților și a serverelor pentru a opera în medii eterogene.

    Programarea RPC este detaliată în Capitolul 18. Cele mai populare două pachete RPC sunt Sun RPC și pachetul RPC din DCE (Distributed Computing Environment) al Open Software Foundation (OSF). Vom analiza cum este efectuat un apel de procedură, cum arată mesajul returnat și cum acesta se referă la pachetul Sun RPC deoarece acest pachet este utilizat de sistemul de fișiere de rețea Sun RPC versiunea 2 este descrisă în RFC 1057 [Sun Microsystems 1988a].

    Există două arome de Sun RPC. O versiune este construită folosind API-ul socket și funcționează cu TCP și UDP. Celălalt se numește TI-RPC (independent de transport) și este construit folosind API-ul TLI și funcționează cu orice nivel de transport furnizat de kernel. Din punctul nostru de vedere, nu există nicio diferență între cele două, deoarece în acest capitol discutăm doar TCP și UDP.

    Figura 29.1 prezintă formatul unui mesaj de apel de procedură RPC folosind UDP.

    Figura 29.1 Mesaje de apel RPC în format de datagramă UDP.

    Anteturile standard IP și UDP sunt prezentate mai devreme (Figura 3.1 și Figura 11.2). Orice lucru după antetul UDP este determinat de pachetul RPC.

    ID-ul tranzacției (XID - ID-ul tranzacției) este setat de client și returnat de server. Când clientul primește un răspuns, compară XID-ul returnat de server cu XID-ul cererii trimise. Dacă nu se potrivesc, clientul renunță la mesaj și așteaptă să sosească următorul. De fiecare dată când un client emite un nou RPC, acesta schimbă XID-ul. Cu toate acestea, dacă clientul retransmite RPC (dacă nu a fost primit niciun răspuns), XID-ul nu se modifică.

    Variabila apel este 0 pentru apel și 1 pentru răspuns. Versiunea curentă RPC este 2. Următoarele trei variabile, numărul programului, numărul versiunii și numărul procedurii, identifică procedura specifică care trebuie apelată pe server.

    Acreditările identifică clientul. În unele exemple, acest câmp este lăsat necompletat, în timp ce în altele, puteți găsi ID-ul de utilizator digital și ID-ul grupului din care face parte. Serverul poate analiza acreditările și poate decide dacă procesează cererea sau nu. Verifier este utilizat pentru Secure RPC (Secure RPC), care utilizează criptarea DES. Deși câmpurile de autorizare și validare sunt câmpuri de lungime variabilă, lungimea lor este transmisă ca parte a câmpului.

    Urmează parametrii procedurii. Formatul lor depinde de modul în care aplicația definește procedura de la distanță. Cum știe receptorul (server stub) dimensiunea parametrilor? Deoarece este utilizat UDP, dimensiunea parametrilor poate fi calculată ca dimensiunea datagramei UDP minus lungimea tuturor câmpurilor până la câmpul de verificare. Când se folosește TCP în loc de UDP, nu există un concept de lungime fixă, deoarece TCP este un flux de octeți fără separatori de înregistrări. În acest caz, între antetul TCP și XID apare un câmp de lungime de 4 octeți, de la care receptorul știe lungimea apelului RPC în octeți. Acest lucru permite ca un mesaj de apel RPC să fie trimis pe mai multe segmente TCP, dacă este necesar. (DNS folosește o tehnică similară; Exercițiul 4 din capitolul 14.)

    Figura 29.2 prezintă formatul răspunsului RPC. Este trimis de la stub-ul serverului la stub-ul client atunci când procedura de la distanță iese.

    Figura 29.2 Formatul mesajului de răspuns RPC ca datagramă UDP.

    XID-ul apelului este pur și simplu copiat în XID-ul răspunsului. Câmpul de răspuns este 1, care face distincția între o provocare și un răspuns. Câmpul de stare este zero dacă mesajul de apel a fost acceptat. (Mesajul poate fi eliminat dacă numărul versiunii RPC nu este 2 sau dacă serverul nu poate autentifica clientul.) Câmpul de verificare este utilizat în cazul RPC securizat pentru a indica serverul.

    Câmpul de stare de acceptare este zero dacă totul este ok. O valoare diferită de zero poate indica, de exemplu, un număr de versiune nevalid sau un număr de procedură nevalid. Dacă se folosește TCP în loc de UDP, un câmp de lungime de 4 octeți este trimis între antetul TCP și XID, ca și în cazul mesajului de provocare RPC.

    XDR: Reprezentare externă a datelor

    Reprezentarea datelor externe (XDR) este un standard utilizat pentru codificarea valorilor în mesajele de apel și răspuns RPC - câmpurile antet RPC (XID, numărul programului, starea primirii și așa mai departe), parametrii procedurii și rezultatele procedurii. Modul standard de codificare a datelor permite unui client să apeleze o procedură pe un sistem cu o arhitectură diferită. XDR este definit în RFC 1014 [Sun Microsystems 1987].

    XDR definește un număr de tipuri de date și modul exact în care acestea sunt transferate într-un mesaj RPC (ordinea biților, ordinea octeților și așa mai departe). Expeditorul trebuie să construiască mesajul RPC în format XDR, apoi receptorul va converti formatul XDR în reprezentarea sa originală. (În formatul care este acceptat pentru sistemul său.) Vedem, de exemplu, în figurile 29.1 și 29.2, că toate numerele întregi pe care le-am afișat (XID, apel, număr de program și așa mai departe) sunt numere întregi de 4 octeți. Într-adevăr, toate numerele întregi din XDR sunt de 4 octeți. XDR acceptă alte tipuri de date, inclusiv numere întregi fără semn, boolean, numere în virgulă mobilă, matrice cu lungime fixă, matrice cu lungime variabilă și structuri.

    Potrivirea portului

    Programele server RPC care conțin proceduri de la distanță folosesc porturi alocate dinamic mai degrabă decât porturi precunoscute. Acest lucru necesită o formă de „înregistrare” pentru a avea în mod constant informații despre portul alocat dinamic pe care îl folosește un anumit program RPC. În Sun RPC, acest registrator este numit port mapper. (Un port mapper este un server care convertește numerele de program RPC în numere de port de protocol DARPA. Acest server trebuie să ruleze pentru a efectua un apel RPC.)

    Termenul „port” din nume provine de la numerele de port TCP și UDP, caracteristici ale familiei de protocoale Internet. Deoarece TI-RPC rulează peste orice nivel de transport, nu doar TCP și UDP, numele mapperului de porturi pe sistemele care utilizează TI-RPC (SVR4 și Solaris 2.2, de exemplu) a fost convertit în rpcbind. Cu toate acestea, vom continua să folosim mapatorul de porturi mai familiar.

    De fapt, mapatorul de porturi în sine trebuie să aibă un port binecunoscut: portul UDP 111 și portul TCP 111. Un mapator de porturi este doar un program de server RPC. Are numărul de program (100000), numărul de versiune (2), portul TCP 111 și portul UDP 111. Serverele se înregistrează reciproc cu mapatorul de porturi folosind apeluri RPC, iar clienții solicită mapatorul de porturi folosind apeluri RPC. Port mapper oferă patru proceduri de server:

    1. PMAPPROC_SET. Apelat de serverul RPC la pornire pentru a înregistra numărul programului, numărul versiunii și protocolul în mapatorul de porturi.
    2. PMAPPROC_UNSET. Apelat de server pentru a elimina o transformare înregistrată anterior.
    3. PMAPPROC_GETPORT. Apelat de clientul RPC la pornire pentru a obține numărul de port pentru numărul de program, numărul de versiune și protocolul dat.
    4. PMAPPROC_DUMP. Returnează toate elementele (numărul programului, numărul versiunii, protocolul și numărul portului) în baza de date a convertorului de porturi.

    Când pornește programul server RPC și mai târziu când este apelat de programul client RPC, se parcurg următorii pași.

    1. Convertorul de porturi trebuie pornit mai întâi, de obicei la pornirea sistemului. Aceasta creează un punct final TCP și deschide pasiv portul TCP 111. De asemenea, creează un punct final UDP care așteaptă să ajungă o datagramă UDP pe portul UDP 111.
    2. La pornire, programul server RPC creează un punct final TCP și un punct final UDP pentru fiecare versiune acceptată a programului. (Un program RPC poate suporta versiuni multiple. Clientul specifică versiunea necesară atunci când apelează o procedură de server.) Fiecărui punct final i se atribuie un număr de port alocat dinamic. (Nu are nicio diferență dacă numerele de port TCP și UDP sunt aceleași sau diferite.) Serverul înregistrează fiecare program, versiune, protocol și număr de port efectuând un apel de la distanță la procedura de mapare a portului PMAPPROC_SET.
    3. Când pornește programul client RPC, apelează rutina de cartografiere de porturi PMAPPROC_GETPORT pentru a obține numărul de port alocat dinamic pentru programul, versiunea și protocolul dat.
    4. Clientul trimite un mesaj de provocare RPC la numărul portului obținut la pasul 3. Dacă se folosește UDP, clientul trimite pur și simplu o datagramă UDP care conține mesajul de provocare RPC (Figura 29.1) către numărul portului UDP al serverului. Ca răspuns, serverul trimite o datagramă UDP care conține un mesaj de răspuns RPC (Figura 29.2). Dacă TCP este în uz, clientul face o deschidere activă la numărul portului TCP al serverului și apoi trimite un mesaj de apel RPC prin conexiune. Serverul răspunde cu un mesaj de răspuns RPC prin conexiune.

    Programul rpcinfo (8) imprimă toate setările curente ale convertorului de porturi. (Aici este apelată rutina de cartografiere de porturi PMAPPROC_DUMP.) Ieșirea tipică este prezentată mai jos:

    Soare% / usr / etc / rpcinfo -p
    program vers proto port
    100005 1 tcp 702 mountd demon de montare NFS
    100005 1 udp 699 mountd
    100005 2 tcp 702 montat
    100005 2 udp 699 mountd

    100003 2 udp 2049 nfs NFS propriu-zis

    100021 1 tcp 709 nlockmgr Manager de blocare NFS
    100021 1 udp 1036 nlockmgr
    100021 2 tcp 721 nlockmgr
    100021 2 udp 1039 nlockmgr
    100021 3 tcp 713 nlockmgr
    100021 3 udp 1037 nlockmgr

    Putem vedea că unele programe acceptă versiuni multiple și fiecare combinație de număr de program, număr de versiune și protocol are propria sa mapare a numerelor de porturi servite de mapatorul de porturi.

    Ambele versiuni ale demonului de montare pot fi accesate prin același număr de port TCP (702) și același număr de port UDP (699), totuși fiecare versiune a managerului de blocare are propriul număr de port.

    Protocolul NFS

    NFS oferă clienților acces transparent la fișierele și sistemul de fișiere al serverului. Acest lucru este în contrast cu FTP (capitolul 27), care oferă transferuri de fișiere. Folosind FTP, se realizează o copie completă a fișierului. NFS accesează doar porțiunile unui fișier pe care procesul le-a accesat, iar principalul avantaj al NFS este că face acest acces transparent. Aceasta înseamnă că orice aplicație client care poate funcționa cu un fișier local poate funcționa la fel de bine și cu un fișier NFS, fără nicio modificare a programului în sine.

    NFS este o aplicație client-server construită folosind Sun RPC. Clienții NFS accesează fișierele de pe serverul NFS trimițând cereri RPC către server. Acest lucru poate fi implementat folosind procese normale ale utilizatorului - și anume, clientul NFS poate fi un proces utilizator care face apeluri RPC specifice către server, care poate fi și un proces utilizator. Cu toate acestea, NFS este de obicei implementat diferit din două motive. În primul rând, accesul la fișierele NFS trebuie să fie transparent pentru client. Prin urmare, apelurile către clientul NFS sunt efectuate de sistemul de operare client în numele procesului utilizator al clientului. În al doilea rând, serverele NFS sunt implementate în interiorul sistemului de operare pentru a îmbunătăți eficiența serverului. Dacă serverul NFS ar fi un proces utilizator, fiecare cerere client și răspuns de server (inclusiv datele de citit sau scris) ar trebui să treacă printr-un delimitator între nucleu și procesul utilizatorului, care este în general destul de costisitor.

    În această secțiune, ne vom uita la versiunea 2 a NFS așa cum este documentată în RFC 1094 [Sun Microsystems 1988b]. Pentru o descriere mai bună a Sun RPC, XDR și NFS, consultați [X / Open 1991]. Pentru detalii despre utilizarea și administrarea NFS, vezi [Stern 1991]. Specificațiile protocolului NFS versiunea 3 au fost implementate în 1993, despre care vom vorbi într-o secțiune a acestui capitol.

    Figura 29.3 prezintă setările tipice pentru client NFS și server NFS. În această figură, ar trebui să acordați atenție următoarelor.

    1. Clientului nu îi pasă dacă accesează fișierul local sau fișierul NFS. Nucleul detectează acest lucru atunci când fișierul este deschis. După deschiderea fișierului, nucleul transferă toate apelurile către fișierele locale în caseta marcată drept „acces la fișierele locale”, iar toate linkurile către fișierele NFS sunt transferate în caseta „client NFS”.
    2. Clientul NFS trimite cereri RPC către serverul NFS prin modulul TCP/IP. NFS utilizează de obicei UDP, însă implementările mai noi pot folosi TCP.
    3. Serverul NFS primește cereri de la client ca datagrame UDP pe portul 2049. Deși NFS poate funcționa cu un mapator de porturi, care permite serverului să utilizeze porturi alocate dinamic, portul UDP 2049 este codificat în NFS în majoritatea implementărilor.

    Figura 29.3 Setări tipice pentru client NFS și server NFS.

  • Când serverul NFS primește o solicitare de la un client, aceasta este transmisă rutinei locale de acces la fișiere, care oferă acces la discul local de pe server.
  • Poate dura ceva timp pentru ca serverul să proceseze cererile clientului. Chiar și accesarea sistemului de fișiere local poate dura ceva timp. În acest timp, serverul nu dorește să blocheze cererile de la alți clienți care trebuie de asemenea să fie serviți. Pentru a face față acestei situații, majoritatea serverelor NFS sunt pornite de mai multe ori, adică există mai multe servere NFS în interiorul nucleului. Soluția exactă depinde de sistemul de operare. Majoritatea nucleelor ​​Unix nu găzduiesc mai multe servere NFS, ci în schimb pornesc mai multe procese utilizator (numite în mod obișnuit nfsd) care fac un singur apel de sistem și rămân în interiorul nucleului ca proces de nucleu.
  • De asemenea, unui client NFS ia ceva timp pentru a procesa o solicitare de la un proces utilizator de pe gazda clientului. RPC este emis gazdei serverului, după care se așteaptă un răspuns. Pentru ca procesele utilizatorului de pe gazda clientului să utilizeze NFS în orice moment, există mai mulți clienți NFS care rulează în interiorul nucleului clientului. Implementarea exactă depinde și de sistemul de operare. Sistemele Unix folosesc de obicei o tehnică similară cu un server NFS: un proces utilizator numit biod efectuează un singur apel de sistem și rămâne în interiorul nucleului ca proces de nucleu.
  • Majoritatea gazdelor Unix pot funcționa ca client NFS și server NFS, sau ambele. Majoritatea implementărilor pentru PC (MS-DOS) au doar implementări client NFS. Majoritatea mainframe-urilor IBM oferă doar funcționalitate server NFS.

    NFS este cu adevărat mai mult decât un simplu protocol NFS. Figura 29.4 prezintă diferitele programe RPC care sunt utilizate cu NFS.

    Apendice

    Numărul programului

    Versiunea numarul

    Numărul de proceduri

    convertor de porturi
    NFS
    program de montare
    manager de blocuri
    monitor de stare

    Figura 29.4 Diverse programe RPC utilizate în NFS.

    Versiunile prezentate în această figură ca unități se găsesc pe sisteme precum SunOS 4.1.3. Implementările mai noi oferă versiuni mai noi ale unor programe. Solaris 2.2, de exemplu, acceptă și versiunea 3 și 4 a port mapper și versiunea 2 a demonului de montare. SVR4 acceptă și versiunea 3 a convertorului de porturi.

    Daemonul de montare este invocat pe gazda NFS a clientului înainte ca acesta să poată accesa sistemul de fișiere al serverului. Vom descrie mai jos acest proces.

    Managerul de blocare și monitorul de stare permit clientului să blocheze unele dintre fișierele care se află pe serverul NFS. Aceste două programe sunt independente de protocolul NFS deoarece blocarea necesită autentificarea clientului atât pentru gazda client, cât și pentru server, iar NFS în sine este „indiferent”. (Vorbim despre indiferența NFS mai detaliat mai jos.) Capitolele 9, 10 și 11 din [X / Open 1991] documentează procedurile pe care managerul de blocare și monitorul de stare le folosesc pentru a bloca în NFS.

    Descriptori de fișiere

    Unul dintre fundamentele NFS sunt descriptorii de fișiere. Pentru a face referire la un fișier sau un director de pe serverul de obiecte, utilizați opac. Termenul opac înseamnă că serverul creează un descriptor de fișier, îl transmite înapoi clientului, pe care clientul îl folosește apoi atunci când accesează fișierul. Clientul nu se uită niciodată la conținutul descriptorului de fișier - conținutul acestuia este de interes doar pentru server.

    Un client NFS primește un descriptor de fișier de fiecare dată când deschide un fișier care se află de fapt pe serverul NFS. Când un client NFS citește sau scrie în acest fișier (în numele unui proces utilizator), descriptorul fișierului este transmis înapoi serverului. Aceasta indică faptul că fișierul a fost accesat.

    De obicei, un proces personalizat nu funcționează cu descriptori de fișiere. Descriptorii de fișiere sunt schimbați între un client NFS și un server NFS. În versiunea 2 a NFS, descriptorul fișierului este de 32 de octeți, iar în versiunea 3 a crescut la 64 de octeți.

    Serverele Unix stochează de obicei următoarele informații în descriptorul de fișiere: identificatorul sistemului de fișiere (numerele dispozitivelor majore și minore ale sistemului de fișiere), numărul inodului (i-node) (număr unic în sistemul de fișiere), numărul generației inodului (numărul care se schimbă de fiecare dată) inodul este reutilizat pentru un alt fișier).

    Protocolul de montare

    Clientul folosește protocolul de montare NFS pentru a monta sistemul de fișiere al serverului înainte de a accesa fișierele NFS. Acest lucru se întâmplă de obicei când clientul pornește. Ca rezultat, clientul primește un descriptor de fișier pentru sistemul de fișiere al serverului.

    Figura 29.5 descrie secvența de acțiuni pentru un client Unix la executarea comenzii mount (8).

    Figura 29.5 Protocolul de montare utilizat de comanda Unix mount.

    În acest caz, se fac următorii pași.

    1. Când serverul pornește, convertorul de porturi pornește pe el.
    2. După mapatorul de porturi, demonul de montare începe pe server. Acesta creează un punct final TCP și un punct final UDP și atribuie fiecăruia un număr de port alocat dinamic. Apoi înregistrează aceste numere cu mapatorul de porturi.
    3. Clientul rulează comanda mount, care emite un apel RPC către mapatorul de porturi al serverului pentru a obține numărul portului de la demonul mount de pe server. Atât TCP, cât și UDP pot fi utilizate pentru comunicarea între client și mapatorul de porturi, totuși UDP este de obicei utilizat.
    4. Mapatorul de porturi raportează numărul portului.
    5. Comanda mount lansează un apel RPC către demonul mount pentru a monta sistemul de fișiere al serverului. Din nou, pot fi utilizate atât TCP, cât și UDP, totuși UDP este de obicei folosit. Serverul poate valida acum clientul pe baza adresei sale IP și a numărului de port pentru a vedea dacă clientul poate monta sistemul de fișiere specificat.
    6. Daemonul de montare răspunde cu un descriptor de fișier pentru sistemul de fișiere specificat.
    7. Comanda de montare client emite apelul de sistem de montare pentru a lega descriptorul de fișier obținut la pasul 5 la punctul de montare local de pe gazda client. Descriptorul de fișier este stocat în codul clientului NFS și, din acest moment, orice acces de către procesele utilizatorului la fișierele din sistemul de fișiere al serverului va folosi descriptorul de fișier ca punct de plecare.

    O astfel de implementare deleagă întregul proces de montare, cu excepția apelului de sistem de montare pe client, proceselor utilizatorului, nu nucleului. Cele trei programe pe care le-am arătat — comanda mount, port mapper și mount daemon — sunt procese utilizator.

    În acest exemplu, pe host sun (client NFS), comanda

    soare # mount -t nfs bsdi: / usr / nfs / bsdi / usr

    Această comandă montează directorul / usr pe gazda bsdi (server NFS) ca sistem de fișiere local / nfs / bsdi / usr. Figura 29.6 arată rezultatul.

    Figura 29.6 Montarea directorului bsdi: / usr ca / ​​nfs / bsdi / usr pe sun.

    Apoi, la accesarea fișierului /nfs/bsdi/usr/rstevens/hello.c pe clientul sun, fișierul /usr/rstevens/hello.c este accesat pe serverul bsdi.

    Proceduri NFS

    Serverul NFS oferă 15 proceduri, pe care le vom descrie acum. (Numerele utilizate în descriere nu se potrivesc cu numerele procedurii NFS, deoarece le-am grupat după funcție.) Deși NFS a fost conceput pentru a funcționa între diferite sisteme de operare, nu doar sisteme Unix, unele dintre proceduri se bazează pe funcționalitatea Unix, care, la rândul lor, ar putea să nu fie acceptate de alte sisteme de operare (de exemplu, legături rigide, legături simbolice, grupare, permisiuni de execuție și așa mai departe). Capitolul 4 conține mai multe informații despre caracteristicile sistemelor de fișiere, dintre care unele le utilizează NFS.

    1. GETATTR. Returnează atributele fișierului: tipul fișierului (fișier obișnuit, director etc.), drepturi de acces, dimensiunea fișierului, proprietarul fișierului, ora ultimului acces și așa mai departe.
    2. SETATTR. Setează atributele unui fișier. Numai un anumit set de atribute poate fi setat: drepturi de acces, proprietar, proprietar de grup, dimensiune, ora ultimului acces și ora ultimei modificări.
    3. STATFS. Returnează starea sistemului de fișiere: spațiu liber, dimensiune optimă de transfer și așa mai departe. Folosit, de exemplu, de comanda Unix df.
    4. PRIVEȘTE ÎN SUS. „Evaluează” fișierul. Această procedură este apelată de client de fiecare dată când un proces utilizator deschide un fișier care se află pe serverul NFS. Este returnat descriptorul de fișier, împreună cu atributele fișierului.
    5. CITIT. Citește dintr-un fișier. Clientul specifică descriptorul fișierului, offset-ul de pornire al octeților și numărul maxim de octeți de citit (până la 8192).
    6. SCRIE. Scrie într-un fișier. Clientul specifică descriptorul fișierului, offset-ul de pornire al octeților, numărul de octeți de scris și datele de scris.

      Este necesar ca scrierile NFS să fie sincrone (în așteptare). Serverul nu poate răspunde OK până când datele au fost scrise cu succes (și orice alte informații despre fișier care trebuie actualizate) pe disc.

    7. CREA. Creează un fișier.
    8. ELIMINA. Șterge fișierul.
    9. RENUMIRE. Redenumește fișierul.
    10. LEGĂTURĂ. Face un link greu către un fișier. Un hard link este un concept Unix care specifică că un anumit fișier de pe disc poate avea orice număr de puncte de intrare (nume, numite și hard links) care indică acel fișier.
    11. SYMLINK. Creează o legătură simbolică către fișier. O legătură simbolică este un fișier care conține numele altui fișier. Majoritatea operațiunilor care sunt efectuate pe o legătură simbolică (de exemplu, deschiderea) sunt de fapt efectuate pe fișierul către care indică legătura simbolică.
    12. READLINK. Citirea unui link simbolic returnează numele fișierului indicat de linkul simbolic.
    13. MKDIR. Creează un director.
    14. RMDIR. Îndepărtează un director.
    15. READDIR. Citește un director. Folosit, de exemplu, de comanda Unix ls.

    De fapt, numele procedurilor de mai sus încep cu prefixul NFSPROC_, pe care l-am omis.

    UDP sau TCP?

    NFS a fost scris inițial pentru a utiliza UDP și toți furnizorii oferă această capacitate. Cu toate acestea, implementările mai noi acceptă și TCP. Suportul TCP este utilizat pentru a opera pe rețele globale din ce în ce mai rapide. Prin urmare, utilizarea NFS nu se mai limitează la rețelele locale.

    Granițele dintre rețelele locale și cele globale se estompează și toate acestea se întâmplă foarte repede. Timpii de întoarcere variază într-un interval foarte larg, iar revărsările apar din ce în ce mai frecvent. Aceste caracteristici ale rețelelor de arie largă duc la faptul că folosesc din ce în ce mai mult algoritmii pe care i-am considerat pentru TCP - start slow and avoidance of congestion. Deoarece UDP nu oferă nimic similar cu acești algoritmi, aceștia sau similare trebuie să fie încorporate în clientul și serverul NFS, altfel trebuie utilizat TCP.

    NFS peste TCP

    Implementarea Berkeley Net / 2 NFS acceptă atât UDP, cât și TCP. [Macklem 1991] descrie această implementare. Să aruncăm o privire la modul în care diferă NFS față de TCP.

    1. Când serverul pornește, pornește serverul NFS, care face o deschidere activă pe portul TCP 2049, așteptând o solicitare de conectare de la client. Acest lucru se face de obicei în plus față de NFS UDP normal, care ascultă datagramele primite pe portul UDP 2049.
    2. Când un client montează sistemul de fișiere al serverului utilizând TCP, efectuează o deschidere activă pe portul TCP 2049 de pe server. Aceasta stabilește o conexiune TCP între client și server pentru acest sistem de fișiere. Dacă același client montează un alt sistem de fișiere pe același server, se creează o altă conexiune TCP.
    3. Atât clientul, cât și serverul setează opțiunea TCP keepalive la capetele conexiunii (capitolul 23). Acest lucru vă permite să determinați momentul eșecului sau repornirii unuia sau altuia participant la schimb.
    4. Toate aplicațiile de pe client care utilizează sistemul de fișiere al serverului partajează aceeași conexiune TCP pentru acel sistem de fișiere. De exemplu, dacă ar fi în Figura 29.6, ar exista un alt director pe bsdi numit smith sub directorul / usr, accesând fișierele în / nfs / bsdi / usr / rstevens și / nfs / bsdi / usr / smith ar partaja unul și aceeași conexiune TCP.
    5. Dacă clientul detectează că serverul s-a prăbușit sau a repornit (după ce a primit o eroare TCP „conexiune expirată” sau „conexiune închisă de gazdă”), încearcă să se reconnecteze la server. Clientul face o altă deschidere activă pentru a restabili o conexiune TCP pentru acest sistem de fișiere. Orice solicitare de la un client care a expirat la o conexiune anterioară este re-emisă la o nouă conexiune.
    6. Dacă un client se blochează, același lucru se întâmplă cu aplicațiile care rulau înainte de blocare. Când clientul repornește, probabil va remonta sistemul de fișiere al serverului folosind TCP, folosind o conexiune TCP diferită la server. Conexiunea anterioară client-server pentru acest sistem de fișiere este într-o stare pe jumătate deschisă (serverul crede că este încă deschis), totuși, deoarece serverul a setat opțiunea „păstrare în viață”, această conexiune pe jumătate deschisă va fi închisă atunci când Serverul TCP trimite următoarea sondă. „Rămâneți în viață”.

    În timp, alți furnizori plănuiesc să înceapă să accepte NFS prin TCP.

    Exemple NFS

    Să folosim tcpdump pentru a vedea ce rutine NFS sunt invocate de client pentru operațiuni normale cu fișiere. Când tcpdump detectează că o datagramă UDP conține un apel RPC (apelul este 0 în Figura 29.1) cu portul de destinație 2049, decodifică datagrama ca o cerere NFS. De asemenea, dacă o datagramă UDP conține un răspuns RPC (răspunsul este 1 în Figura 29.2) cu un port sursă de 2049, aceasta decodifică datagrama ca răspuns NFS.

    Exemplu simplu: citirea unui fișier

    În primul exemplu, vom copia fișierul, aflat pe serverul NFS, pe terminal folosind comanda cat (1):

    Soare% cat /nfs/bsdi/usr/rstevens/hello.c copiați fișierul pe terminal
    principal ()
    {
    printf ("bună ziua, lume \ n");
    }

    Sistemul de fișiere / nfs / bsdi / usr de pe sun (client NFS) este de fapt sistemul de fișiere / usr de pe bsdi (server NFS), așa cum se arată în Figura 29.6. Nucleul solar detectează acest lucru atunci când pisica deschide un fișier și folosește NFS pentru a accesa fișierul. Figura 29.7 arată rezultatul comenzii tcpdump.

    1 0.0 sun.7aa6> bsdi.nfs: 104 getattr
    2 0.003587 (0.0036) bsdi.nfs> sun.7aa6: raspunde ok 96

    3 0,005390 (0,0018) sun.7aa7> bsdi.nfs: 116 căutare „rstevens”
    4 0.009570 (0.0042) bsdi.nfs> sun.7aa7: răspuns ok 128

    5 0,011413 (0,0018) sun.7aa8> bsdi.nfs: 116 căutare „hello.c”
    6 0.015512 (0.0041) bsdi.nfs> sun.7aa8: raspunde ok 128

    7 0.018843 (0.0033) sun.7aa9> bsdi.nfs: 104 getattr
    8 0.022377 (0.0035) bsdi.nfs> sun.7aa9: raspunde ok 96

    9 0.027621 (0.0052) sun.7aaa> bsdi.nfs: 116 citiți 1024 octeți @ 0
    10 0.032170 (0.0045) bsdi.nfs> sun.7aaa: raspunde ok 140

    Figura 29.7 Comportamentul NFS la citirea unui fișier.

    Comanda tcpdump decodifică o cerere sau un răspuns NFS și tipărește câmpul XID pentru client în loc de numărul portului. Câmpul XID de pe liniile 1 și 2 este 0x7aa6.

    Numele de fișier /nfs/bsdi/usr/rstevens/hello.c este gestionat de funcția deschisă din nucleul clientului, câte un element. Când funcția deschisă ajunge la / nfs / bsdi / usr, detectează că este un punct de montare NFS.

    Pe linia 1, clientul apelează procedura GETATTR pentru a obține atributele directorului serverului pe care clientul le-a montat (/ usr). Această solicitare RPC conține 104 octeți de date, în plus față de anteturile IP și UDP. Răspunsul de pe linia 2 returnează OK și conține 96 de octeți de date, în plus față de anteturile IP și UDP. Putem vedea în această figură că cel mai mic mesaj NFS conține aproximativ 100 de octeți de date.

    Pe linia 3, clientul apelează LOOKUP pe fișierul rstevens și primește un răspuns OK pe linia 4. LOOKUP specifică numele fișierului rstevens și un descriptor de fișier care a fost salvat de kernel când a fost montat sistemul de fișiere la distanță. Răspunsul conține un nou descriptor de fișier care este utilizat în pasul următor.

    Pe linia 5, clientul CAUTĂ fișierul hello.c folosind descriptorul de fișier din linia 4. Primește un descriptor de fișier diferit pe linia 6. Acest nou descriptor de fișier este exact ceea ce clientul folosește pe liniile 7 și 9 pentru a accesa / nfs fișierul /bsdi/usr/rstevens/hello.c. Putem vedea că clientul efectuează o CĂUTARE pe fiecare componentă de nume din calea către fișierul care este deschis.

    Pe linia 7, clientul execută din nou GETATTR, urmat de un READ pe linia 9. Clientul solicită 1024 de octeți începând cu offset-ul 0, dar primește mai puțin de 1024 de octeți de date. (După scăderea dimensiunilor câmpurilor RPC și a altor valori returnate de procedura READ, 38 de octeți de date sunt returnați pe linia 10. Aceasta este exact dimensiunea fișierului hello.c.)

    În acest exemplu, procesul utilizatorului nu este conștient de aceste solicitări și răspunsuri NFS care sunt făcute de nucleu. Aplicația apelează pur și simplu funcția de deschidere a nucleului, care invocă schimbul de 3 cereri și 3 răspunsuri (liniile 1-6), apoi apelează funcția de citire a nucleului, care invocă 2 cereri și 2 răspunsuri (liniile 7-10). Pentru aplicația client, fișierul care se află pe serverul NFS este transparent.

    Exemplu simplu: crearea unui director

    Ca un alt exemplu, schimbați directorul de lucru în directorul de pe serverul NFS și apoi creați un director nou:

    Soare% cd / nfs / bsdi / usr / rstevens schimba directorul de lucru
    soare% mkdir Mail creați un director

    Figura 29.8 arată rezultatul comenzii tcpdump.

    1 0.0 sun.7ad2> bsdi.nfs: 104 getattr
    2 0.004912 (0.0049) bsdi.nfs> sun.7ad2: raspunde ok 96

    3 0.007266 (0.0024) sun.7ad3> bsdi.nfs: 104 getattr
    4 0.010846 (0.0036) bsdi.nfs> sun.7ad3: răspuns ok 96

    5 35.769875 (35.7590) sun.7ad4> bsdi.nfs: 104 getattr
    6 35.773432 (0.0036) bsdi.nfs> sun.7ad4: raspunde ok 96

    7 35.775236 (0.0018) sun.7ad5> bsdi.nfs: 112 căutare „Mail”
    8 35.780914 (0.0057) bsdi.nfs> sun.7ad5: raspunde ok 28

    9 35.782339 (0.0014) sun.7ad6> bsdi.nfs: 144 mkdir „Mail”
    10 35.992354 (0.2100) bsdi.nfs> sun.7ad6: raspunde ok 128

    Figura 29.8 Comportamentul NFS prin schimbarea directorului (cd) în directorul NFS și apoi creând directorul (mkdir).

    La schimbarea directorului, clientul apelează de două ori procedura GETATTR (liniile 1-4). Când creăm un nou director, clientul apelează procedura GETATTR (liniile 5 și 6), apoi LOOKUP (liniile 7 și 8 pentru a verifica dacă nu există un astfel de director), apoi MKDIR pentru a crea directorul (liniile 9 și 10). Un răspuns OK pe linia 8 nu înseamnă că directorul există. Înseamnă pur și simplu că procedura a returnat o anumită valoare. tcpdump nu interpretează valoarea returnată de rutinele NFS. Comanda imprimă pur și simplu OK și numărul de octeți de date din răspuns.

    Indiferenţă

    Una dintre caracteristicile NFS (criticii NFS numesc acest lucru un neg, nu o caracteristică) este că serverul NFS este indiferent. Serverului nu îi pasă ce clienți accesează ce fișiere. Rețineți că nu există nicio procedură de deschidere sau de închidere în lista procedurilor NFS prezentată mai devreme. LOOKUP este similar cu deschiderea, dar serverul nu știe niciodată dacă clientul a accesat fișierul după ce a fost făcută LOOKUP.

    Motivul acestui „comportament leneș” este acela de a facilita recuperarea după un accident de server și repornirea.

    Exemplu: Eroare server

    În exemplul următor, citim un fișier de pe un server NFS când serverul se blochează și repornește. Acest lucru va arăta cum „indiferența” serverului îi permite clientului „să nu știe” că serverul este oprit. Atâta timp cât serverul se blochează și repornește, clientul nu este conștient de problemă, iar aplicația client funcționează la fel ca înainte.

    Pe clientul Sun, am început cat cu un fișier foarte mare ca argument (/ usr / share / lib / termcap pe serverul svr4 NFS), am deconectat cablul Ethernet în timpul transferului, am oprit și repornit serverul și apoi am reconectat cablu. Clientul a fost configurat să citească 1.024 de octeți într-o singură citire NFS. Figura 29.9 arată rezultatul de la tcpdump.

    Rândurile 1-10 corespund cu clientul care deschide fișierul. Această operație seamănă cu cea prezentată în Figura 29.7. Pe linia 11, vedem prima citire (READ) dintr-un fișier de 1024 de octeți de date; răspunsul a revenit pe linia 12. Aceasta continuă până la linia 129 (citirea unui READ de 1024 de octeți și apoi un răspuns OK).

    Pe liniile 130 și 131 vedem două solicitări care au expirat și au fost retransmise pe liniile 132 și 133. Prima întrebare: vedem două solicitări de citire, una începe de la offset 65536 și cealaltă începe de la offset 73728, de ce? Nucleul clientului a determinat că aplicația client citea secvențial și a încercat să obțină blocurile de date din timp. (Majoritatea nucleelor ​​Unix fac această citire înainte.) Nucleul client rulează, de asemenea, mai multe daemoni I/O bloc NFS (procese biod) care încearcă să genereze mai multe cereri RPC în numele clientului. Un demon citește 8192 de octeți începând de la 65536 (în lanțuri de 1024 de octeți), în timp ce alții citesc înainte 8192 de octeți începând de la 73728.

    Retransmisiunile clientului apar pe liniile 130-168. Pe linia 169, vedem că serverul a repornit și a trimis o solicitare ARP înainte de a răspunde la cererea NFS a clientului de la linia 168. Răspunsul la linia 168 este trimis pe linia 171. Solicitările READ ale clientului continuă.

    1 0.0 sun.7ade> svr4.nfs: 104 getattr
    2 0.007653 (0.0077) svr4.nfs> sun.7ade: raspunde ok 96

    3 0,009041 (0,0014) sun.7adf> svr4.nfs: 116 căutare „share”
    4 0.017237 (0.0082) svr4.nfs> sun.7adf: răspuns ok 128

    5 0,018518 (0,0013) sun.7ae0> svr4.nfs: 112 căutare „lib”
    6 0.026802 (0.0083) svr4.nfs> sun.7ae0: răspuns ok 128

    7 0,028096 (0,0013) sun.7ae1> svr4.nfs: 116 căutare „termcap”
    8 0.036434 (0.0083) svr4.nfs> sun.7ae1: raspunde ok 128

    9 0.038060 (0.0016) sun.7ae2> svr4.nfs: 104 getattr
    10 0.045821 (0.0078) svr4.nfs> sun.7ae2: raspunde ok 96

    11 0,050984 (0,0052) sun.7ae3> svr4.nfs: 116 citire 1024 octeți @ 0
    12 0.084995 (0.0340) svr4.nfs> sun.7ae3: raspunde ok 1124

    Citind

    128 3.430313 (0.0013) sun.7b22> svr4.nfs: 116 citire 1024 octeți @ 64512
    129 3.441828 (0.0115) svr4.nfs> sun.7b22: raspunde ok 1124

    130 4.125031 (0.6832) soare.7b23>
    131 4.868593 (0.7436) soare.7b24>

    132 4.993021 (0.1244) sun.7b23> svr4.nfs: 116 citire 1024 octeți @ 65536
    133 5.732217 (0.7392) sun.7b24> svr4.nfs: 116 citire 1024 octeți @ 73728

    134 6.732084 (0.9999) sun.7b23> svr4.nfs: 116 citire 1024 octeți @ 65536
    135 7.472098 (0.7400) sun.7b24> svr4.nfs: 116 citire 1024 octeți @ 73728

    136 10.211964 (2.7399) soare.7b23>
    137 10.951960 (0.7400) soare.7b24>

    138 17.171767 (6.2198) sun.7b23> svr4.nfs: 116 read 1024 bytes @ 65536
    139 17.911762 (0.7400) sun.7b24> svr4.nfs: 116 citire 1024 octeți @ 73728

    140 31.092136 (13.1804) sun.7b23> svr4.nfs: 116 citire 1024 octeți @ 65536
    141 31.831432 (0.7393) sun.7b24> svr4.nfs: 116 read 1024 bytes @ 73728

    142 51.090854 (19.2594) sun.7b23> svr4.nfs: 116 citire 1024 octeți @ 65536
    143 51.830939 (0.7401) sun.7b24> svr4.nfs: 116 citire 1024 octeți @ 73728

    144 71.090305 (19.2594) sun.7b23> svr4.nfs: 116 citire 1024 octeți @ 65536
    145 71.830155 (0.7398) sun.7b24> svr4.nfs: 116 read 1024 bytes @ 73728

    Retransmisii

    167 291.824285 (0.7400) sun.7b24> svr4.nfs: 116 read 1024 bytes @ 73728
    168 311.083676 (19.2594) sun.7b23> svr4.nfs: 116 read 1024 bytes @ 65536

    Serverul a fost repornit

    169 311.149476 (0.0658) arp cine-are soare spune svr4
    170 311,150004 (0,0005) arp răspuns soare-la 8: 0: 20: 3: f6: 42

    171 311.154852 (0.0048) svr4.nfs> sun.7b23: raspunde ok 1124

    172 311.156671 (0.0018) sun.7b25> svr4.nfs: 116 citire 1024 octeți @ 66560
    173 311.168926 (0.0123) svr4.nfs> sun.7b25: raspunde ok 1124
    citind

    Figura 29.9 Un client a citit un fișier când serverul NFS s-a prăbușit și a repornit.

    Aplicația client nu va ști niciodată că serverul s-a prăbușit și a repornit, cu excepția faptului că a existat o pauză de 5 minute între liniile 129 și 171, astfel încât blocarea serverului este transparentă pentru client.

    Pentru a estima durata de expirare a retransmisiei în acest exemplu, imaginați-vă că există doi daemoni client, fiecare cu propriile timeout-uri. Intervalele pentru primul demon (citirea de la offset 65536) sunt aproximativ următoarele (rotunjite la două zecimale): 0,68; 0,87; 1,74; 3,48; 6,96; 13,92; 20,0; 20,0; 20.0 și așa mai departe. Spațierea pentru cel de-al doilea demon (citirea din offset 73728) este exact aceeași. Aceasta înseamnă că acești clienți NFS folosesc timeout-uri care sunt multipli de 0,875 secunde cu o limită superioară de 20 de secunde. După fiecare timeout, intervalul de retransmisie este dublat: 0,875; 1,75; 3,5; 7.0 și 14.0.

    Cât timp va face clientul retransmisii? Clientul are două opțiuni care pot afecta acest lucru. În primul rând, dacă sistemul de fișiere al serverului este montat greu, clientul va retransmite pentru totdeauna, dar dacă sistemul de fișiere al serverului este montat ușor, clientul va anula după un număr fix de retransmisii. De asemenea, în cazul unui hard mount, clientul are o opțiune de a permite utilizatorului să anuleze sau nu retransmisiile eșuate. Dacă la montarea sistemului de fișiere server, gazda client indică că este posibilă întrerupere, iar dacă nu dorim să așteptăm 5 minute pentru ca serverul să se repornească după o eroare, putem introduce caracterul de întrerupere pentru a termina aplicația client. .

    Câteva dintre aceleași proceduri

    Procedurile RPC pot fi executate de server de mai multe ori, dar totuși returnează același rezultat. De exemplu, o rutină de citire NFS. După cum am văzut în Figura 29.9, clientul pur și simplu reemite apelul READ până când primește un răspuns. În exemplul nostru, motivul retransmisiei a fost că serverul s-a defectat. Dacă serverul nu a eșuat și mesajele care conțineau răspunsurile RPC s-au pierdut (deoarece UDP nu este un protocol de încredere), clientul pur și simplu retransmite și serverul efectuează din nou aceeași CITIRE. Aceeași parte a aceluiași fișier este citită din nou și trimisă clientului.

    Acest lucru funcționează deoarece fiecare READ conține un offset de început. Dacă procedura NFS ar cere serverului să citească următorii N octeți ai fișierului, nu ar funcționa. Dacă serverul nu a fost indiferent (această valoare este opusă indiferenței), iar răspunsul este pierdut, iar clientul reemite READ pentru următorii N octeți, rezultatul va fi diferit. Acesta este motivul pentru care procedurile NFS READ și WRITE au un offset de pornire. Clientul este cel care menține starea (offset-ul curent pentru fiecare fișier), nu serverul.

    Din păcate, nu toate operațiunile sistemului de fișiere pot fi efectuate de mai multe ori. De exemplu, imaginați-vă următorii pași: clientul NFS emite o solicitare REMOVE pentru a șterge un fișier; Serverul NFS șterge fișierul și răspunde cu OK; răspunsul serverului este pierdut; Clientul NFS expiră și retransmite cererea; Serverul NFS nu poate găsi fișierul și returnează o eroare; aplicația client primește o eroare care spune că fișierul nu există. Această eroare este returnată aplicației client, iar această eroare conține informații incorecte - fișierul nu a existat și a fost șters.

    Mai jos este o listă de rutine NFS care pot fi executate de mai multe ori: GETATTR, STATFS, LOOKUP, READ, WRITE, READLINK și READDIR. Proceduri care nu pot fi executate de mai multe ori: CREATE, REMOVE, RENAME, LINK, SYMLINK, MKDIR și RMDIR. SETATTR este de obicei executat de mai multe ori, cu excepția cazului în care a fost folosit pentru a trunchia fișierul.

    Deoarece pot exista întotdeauna răspunsuri pierdute în cazul UDP, serverele NFS TREBUIE să aibă o modalitate de a gestiona operațiuni care nu pot fi efectuate de mai multe ori. Majoritatea serverelor au un cache de răspuns recent în care stochează ultimele răspunsuri primite pentru astfel de operațiuni. De fiecare dată când serverul primește o solicitare, mai întâi caută prin cache-ul său, iar dacă se găsește o potrivire, returnează răspunsul anterior în loc să apeleze din nou procedura NFS. [Juszczak 1989] descrie detaliile acestor tipuri de cache.

    O abordare similară a procedurilor de pe servere se aplică tuturor aplicațiilor bazate pe UDP, nu doar NFS. DNS, de exemplu, oferă un serviciu care este utilizat fără durere de mai multe ori. Serverul DNS poate face o solicitare de parser de orice număr, ceea ce nu va duce la rezultate negative (poate, cu excepția faptului că resursele de rețea vor fi ocupate).

    NFS versiunea 3

    În 1994, au fost lansate specificațiile pentru versiunea 3 a protocolului NFS [Sun Microsystems 1993]. Se preconizează că implementările vor deveni disponibile în cursul anului 1994.

    Aici sunt descrise pe scurt principalele diferențe dintre versiunea 2 și versiunea 3. Ne vom referi la ele ca V2 și V3.

    1. Descriptorii de fișiere din V2 sunt o matrice de dimensiune fixă ​​de 32 de octeți. În V3, este o matrice de dimensiune variabilă de până la 64 de octeți. O matrice de lungime variabilă în XDR este definită de un numărător de 4 octeți urmat de octeți reali. Acest lucru reduce dimensiunea descriptorului de fișier în implementări precum Unix, care necesită doar aproximativ 12 octeți, dar permite implementărilor non-Unix să facă schimb de informații suplimentare.
    2. V2 limitează numărul de octeți pe RPC READ sau WRITE la 8192 de octeți. Această limitare nu se aplică în V3, ceea ce, la rândul său, înseamnă că folosind UDP, limitarea va fi doar în dimensiunea datagramei IP (65535 octeți). Acest lucru permite utilizarea pachetelor mari atunci când citiți și scrieți în rețele rapide.
    3. Dimensiunile fișierelor și decalajele inițiale de octeți pentru rutinele de citire și scriere au fost extinse de la 32 la 64 de biți pentru a găzdui fișiere mai mari.
    4. Atributele fișierelor sunt returnate în fiecare apel care ar putea afecta atributele. Acest lucru reduce numărul de apeluri GETATTR solicitate de client.
    5. Scrierile (WRITE-urile) pot fi asincrone, în timp ce în V2 trebuiau să fie sincrone. Acest lucru poate îmbunătăți performanța procedurii WRITE.
    6. A fost eliminată o procedură (STATFS) și au fost adăugate șapte: ACCESS (verificarea permisiunilor fișierelor), MKNOD (crearea unui fișier special Unix), READDIRPLUS (returnează numele fișierelor dintr-un director împreună cu atributele acestora), FSINFO (returnează informații statistice despre sistemul de fișiere), FSSTAT (returnează informații despre sistemul de fișiere dinamic), PATHCONF (returnează informații despre fișierul POSIX.1) și COMMIT (transferă scrierile asincrone efectuate anterior către stocarea persistentă).

    Concluzii scurte

    RPC este o modalitate de a construi o aplicație client-server în așa fel încât clientul să apeleze pur și simplu procedurile de pe server. Toate detaliile rețelei sunt ascunse în stub-urile client și server, care sunt generate pentru aplicații de pachetul RPC și în rutinele bibliotecii RPC. Am arătat formatul mesajelor de provocare și răspuns RPC și am menționat că XDR este folosit pentru a codifica valori, ceea ce permite clienților și serverelor RPC să ruleze pe mașini cu arhitecturi diferite.

    Una dintre cele mai utilizate aplicații RPC este Sun NFS, un protocol eterogen de acces la fișiere care este utilizat pe scară largă pe gazde de aproape toate dimensiunile. Am acoperit NFS și cum folosește UDP sau TCP. Versiunea 2 NFS definește 15 proceduri.

    Accesul clientului la serverul NFS începe cu un jurnal de montare, după care un descriptor de fișier este returnat clientului. Clientul poate accesa apoi fișierele din sistemul de fișiere al serverului folosind acest descriptor de fișier. Numele de fișiere sunt căutate pe server câte un element al numelui și este returnat un nou descriptor de fișier pentru fiecare element. Rezultatul final este un handle al fișierului care a fost accesat și utilizat pentru citiri și scrieri secvențiale.

    NFS încearcă să facă toate procedurile sale independente de numărul de execuții, astfel încât clientul să poată pur și simplu reemite cererea dacă răspunsul este pierdut. Am văzut exemple în acest sens: în cazul în care clientul citea un fișier în timp ce serverul s-a prăbușit și a repornit.

    Exerciții

    În Figura 29.7 am văzut că tcpdump interpretează pachetele ca cereri și răspunsuri NFS și tipărește XID-ul. Poate tcpdump să facă acest lucru pentru orice cereri sau răspunsuri RPC?
  • De ce crezi că programul server RPC de pe sistemele Unix folosește porturi alocate dinamic în loc de cele cunoscute?
  • Clientul RPC a apelat două proceduri de server. Prima procedură a durat 5 secunde pentru a se executa, iar a doua a durat 1 secundă. Clientul are un timeout de 4 secunde. Desenați o diagramă cronologică a ceea ce schimbă clientul și serverul. (Imaginați-vă că nu se pierde timp la trecerea unui mesaj de la client la server și invers.)
  • Ce se întâmplă în exemplul din Figura 29.9 dacă în timp ce serverul NFS era oprit, placa Ethernet a fost scoasă?
  • Când serverul a repornit în Figura 29.9, a procesat cererea începând cu offset-ul 65536 (liniile 168 și 171), apoi a procesat următoarea cerere începând cu offset-ul 66560 (liniile 172 și 173). Ce se întâmplă cu interogarea care începe cu offset 73728 (linia 167)?
  • Când am descris proceduri independente de numărul de execuții NFS, am arătat un exemplu de răspuns REMOVE care s-a pierdut în rețea. Ce se întâmplă în acest caz dacă se folosește TCP în loc de UDP?
  • Dacă serverul NFS utilizează un port alocat dinamic în loc de portul 2049, ce se întâmplă cu clientul NFS atunci când serverul se blochează și repornește?
  • Numerele de porturi rezervate (Capitolul 1, secțiunea Numerele de port) sunt foarte, foarte puține, cu maximum 1023 per gazdă. Dacă un server NFS solicită clienților săi porturi rezervate (care sunt de obicei), iar un client NFS care utilizează TCP montează N sisteme de fișiere pe N servere diferite, clientul trebuie să aibă numere de porturi rezervate diferite pentru fiecare conexiune?
  • Top articole similare