Am citit în cărți de text că Unix / Linux nu permite legături hard către directoare, dar permite legături soft. Este pentru că, atunci când avem cicluri și dacă creăm legături dure și, după un timp, ștergem fișierul original, acesta va indica o anumită valoare de gunoi?

Dacă ciclurile au fost singurul motiv pentru care nu permitem legături dure, atunci de ce sunt legăturile ușoare către directoare permis?

Comentarii

  • Unde ar trebui să indice ..? Mai ales după îndepărtarea link-ului dur către acesta director, în directorul indicat de ..? Trebuie să indice undeva.
  • .. nu ‘ nu trebuie să existe fizic pe orice unitate. Este ‘ este sistemul de operare ‘ țineți evidența directorului de lucru curent, oricum, deci ar trebui să fie relativ simplu să păstrați și o listă de inoduri asociate fiecărui proces

cwd și faceți referire la aceasta atunci când vede o utilizare a... Desigur, asta ar însemna că ar trebui create linkuri simbolice având în vedere acest lucru, dar trebuie să aveți grijă să nu rupeți linkurile simbolice și nu cred că ‘ cred că regula suplimentară ar fi faceți-le inutile.

  • Îmi place această explicație . Concis și ușor de citit și / sau de parcurs.
  • Răspuns

    Aceasta este doar o idee proastă, deoarece există nu este nicio modalitate de a face diferența dintre o legătură dură și un nume original.

    Permiterea legăturilor dure către directoare ar rupe structura grafică aciclică direcționată a sistemului de fișiere, creând eventual bucle de directoare și subarborii de directoare suspendate, care ar faceți fsck și orice alte arborele de fișiere predispuse la erori.

    Mai întâi, pentru a înțelege acest lucru, să vorbim despre inoduri. Datele din sistemul de fișiere sunt păstrate în blocuri de pe disc, iar acele blocuri sunt colectate împreună de un inod. Puteți considera că inodul este fișierul. Inodelor le lipsește totuși nume de fișiere. Acolo intră linkurile.

    Un link este doar un indicator către un inod. Un director este un inod care deține legături. Fiecare nume de fișier dintr-un director este doar un link către un inod. Deschiderea unui fișier în Unix creează, de asemenea, un link, dar acesta este un tip diferit de link (nu este un link numit).

    O legătură dură este doar o intrare de director suplimentar care indică acel inod. Când ls -l, numărul după permisiuni este numărul de linkuri numit. Majoritatea fișierelor obișnuite vor avea un singur link. Crearea unui nou link către un fișier va face ca ambele nume de fișiere să indice același inod. Notă:

    % ls -l test ls: test: No such file or directory % touch test % ls -l test -rw-r--r-- 1 danny staff 0 Oct 13 17:58 test % ln test test2 % ls -l test* -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 % touch test3 % ls -l test* -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 -rw-r--r-- 1 danny staff 0 Oct 13 17:59 test3 ^ ^ this is the link count 

    Acum, puteți vedea clar că nu există o legătură dură. O legătură dură este aceeași cu un nume obișnuit. În exemplul de mai sus, test sau test2, care este fișierul original și care este legătura dură? Până la sfârșit, nu poți spune cu adevărat (chiar și după marcaje de timp), deoarece ambele nume indică același conținut, același inod:

    % ls -li test* 14445750 -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test 14445750 -rw-r--r-- 2 danny staff 0 Oct 13 17:58 test2 14445892 -rw-r--r-- 1 danny staff 0 Oct 13 17:59 test3 

    -i semnalizatorul către ls vă arată numerele inode la începutul liniei. Rețineți cum test și test2 au același număr de inod, dar test3 are altul.

    Acum, dacă ți-ar fi permis să faceți acest lucru pentru directoare, două directoare diferite în puncte diferite din sistemul de fișiere ar putea indica același lucru. De fapt, un subdir ar putea indica înapoi către bunicul său, creând o buclă.

    De ce este această buclă o preocupare ? Pentru că atunci când parcurgeți, nu există nicio modalitate de a detecta că faceți o buclă (fără a ține evidența numerelor de inod în timp ce traversați). Imaginați-vă că scrieți comanda du, care trebuie să recurse prin subdirecte pentru a afla despre utilizarea discului. Cum ar ști du n a lovit o buclă? du ar trebui să facă doar pentru a finaliza această sarcină simplă.

    Simlinkurile sunt cu totul diferite, în că sunt un tip special de „fișier” pe care multe API-uri de sisteme de fișiere tind să le urmeze automat. Rețineți că un link simbolic poate indica o destinație inexistentă, deoarece indică după nume și nu direct către un inod. Acest concept nu are sens cu legăturile rigide, deoarece simpla existență a unei „legături rigide” înseamnă că fișierul există.

    Deci, de ce poate du link-uri simbolice ușor și nu linkuri hard? Am putut vedea mai sus că link-urile hard nu pot fi distinse de intrările de director obișnuite. Totuși, link-urile simbolice sunt speciale, detectabile și pot fi închise! linkul simbolic este un link simbolic și îl omite complet!

    % ls -l total 4 drwxr-xr-x 3 danny staff 102 Oct 13 18:14 test1/ lrwxr-xr-x 1 danny staff 5 Oct 13 18:13 test2@ -> test1 % du -ah 242M ./test1/bigfile 242M ./test1 4.0K ./test2 242M . 

    Comentarii

    • Allowing hard links to directories would break the directed acyclic graph structure of the filesystem.Puteți explica mai multe despre problema legată de cicluri folosind link-uri dure? De ce este în regulă legăturile simbolice
    • Se pare că au permis acest lucru pe Mac adăugând detectarea ciclului la apelul de sistem link () și refuzând să vă permită să creați o legătură directă de director dacă ar crea un ciclu . Pare a fi o soluție rezonabilă.
    • @psusi mkdir -p a / b; nocheckln c a; mv c a / b; – nocheckln există un ln teoretic care nu verifică argumentele de directoare și trece doar la legătură și, deoarece nu se face un ciclu, suntem cu toții buni în crearea ‘ c ‘. apoi mutăm ‘ c ‘ în ‘ a / b ‘, iar un ciclu este creat din a / b / c – > a / – linkul de verificare () nu este suficient de bun
    • Ciclurile sunt foarte rele. Windows are această problemă cu ” joncțiuni ” care sunt directoare de legătură dură. Dacă aplicați în mod accidental permisiuni pentru întregul dvs. profil, acesta descoperă o serie de joncțiuni care creează un ciclu infinit. Recurgerea prin directoare se repetă până când limitele de lungime a căii o opresc.
    • @WhiteWinterWolf, conform acestui link, au adăugat în mod specific suport pentru aceasta pentru mașina timpului, dar numai rădăcina are voie să o facă: superuser.com/questions/360926/…

    Răspuns

    Puteți utiliza bind mount pentru a simula directoare de legătură dură

    sudo mount --bind /some/existing_real_contents /else/dummy_but_existing_directory sudo umount /else/dummy_but_existing_directory 

    Răspuns

    Cu excepția punctelor de montare, fiecare director are un singur părinte: ...

    O modalitate de a pwd este să verificați dispozitivul: inode pentru „.” și „..”. Dacă sunt la fel, ați ajuns la rădăcina sistemului de fișiere. În caz contrar, găsiți numele directorului curent în părinte, împingeți-l pe un teanc și începeți să comparați „../”. cu „../ ..”, apoi „../../.” cu „../../ ..”, etc. Odată ce ați lovit rădăcina, începeți să apară și să tipăriți numele din stivă. Acest algoritm se bazează pe faptul că fiecare director are un singur și unul dintre părinți.

    Dacă au fost permise legături rigide către directoare, pe care dintre părinți multipli ar trebui să .. să îl indice? Acesta este un motiv convingător pentru care nu sunt permise legăturile rigide către directoare.

    Linkurile simulare către directoare nu cauzează această problemă. Dacă un program dorește, ar putea face o lstat() pe fiecare parte a căii și să detecteze când se întâlnește o legătură simbolică. Algoritmul pwd va returna adevărata cale absolută pentru un director țintă. Faptul că există o bucată de text undeva (link-ul simbolic) care indică directorul țintă este aproape irelevantă. Existența unui astfel de link simbolic nu creează o buclă în grafic.

    Comentarii

    • Nu sunt atât de sigur despre acest lucru. Dacă ne gândim că .. este un fel de hardlink virtual către părinte, nu există niciun motiv tehnic pentru care ținta linkului poate avea doar un alt link către acesta. pwd ar trebui doar să utilizeze un alt algoritm pentru a rezolva calea.

    Răspuns

    Îmi place să mai adaug câteva puncte despre această întrebare. Legăturile dure pentru directoare sunt permise în Linux, dar într-un mod restricționat.

    Un mod în care putem testa acest lucru este când listăm conținutul unui director, găsim două directoare speciale „.” și „..”. După cum știm „.” indică același director și „..” indică directorul părinte.

    Deci, permite să creăm un arbore director în care „a” este directorul părinte care are directorul „b” drept copil.

     a `-- b 

    Notați inodul directorului „a”. Și când facem un ls -la din directorul „a” putem vedea că „.” directorul indică, de asemenea, același inod.

    797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 a 

    Și aici putem constata că directorul „a” are trei legături dure. Acest lucru se datorează faptului că inodul 797358 are trei legături dure în numele „.” în directorul „a” și numele ca „..” în directorul „b” și unul cu numele „a” itslef.

    $ ls -ali a/ 797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 . $ ls -ali a/b/ 797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 .. 

    Deci, aici putem înțelege că hardlink-urile sunt disponibile pentru ca directoarele să se conecteze doar cu directoarele părinte și copil. Și astfel un director fără un copil va avea doar 2 hardlink, și astfel directorul „b” va avea doar două hardlink.

    Un motiv pentru care legătura dură a directoarelor a fost împiedicată în mod liber ar fi evitarea buclelor de referință infinite care va confunda programele care traversează sistemul de fișiere.

    Deoarece sistemul de fișiere este organizat ca arbore și ca arborele nu poate avea referință ciclică, ar fi trebuit evitat.

    Comentarii

    • Exemplu bun. Mi-a eliminat îndoiala. Deci, aceste cazuri sunt tratate într-un mod special pentru a evita buclele infinite. dreapta?
    • Deoarece avem o modalitate limitată de a permite link-uri rigide pentru directoare, adică ” .. ” și „. ” nu vom ajunge la o buclă infinită și, prin urmare, nu am avea nevoie de metode speciale pentru a le evita, deoarece acestea nu se vor întâmpla:)

    Răspuns

    Niciunul dintre următoarele nu este motivul real al interzicerii legăturilor dure către directoare; fiecare problemă este destul de ușor de rezolvat:

    • ciclurile din structura arborelui provoacă o traversare dificilă
    • mai mulți părinți, deci care este „real”?
    • colectare gunoi sistem de fișiere

    Motivul real real (așa cum sugerează @ Thorbjørn Ravn Andersen) vine când ștergeți un director care are mai mulți părinți, din directorul indicat de ..:

    La ce ar trebui să indice acum ..?

    Dacă directorul este șters din părintele său, dar numărul de legături al acestuia este încă mai mare decât 0 atunci trebuie să existe ceva, undeva care să indice încă spre el. Nu puteți „lăsa .. arătând spre nimic; o mulțime de programe se bazează pe .., astfel încât sistemul ar trebui să traverseze întregul sistem de fișiere până când găsește primul lucru care indică directorul șters, doar pentru a actualiza ... Fie asta, fie sistemul de fișiere ar trebui să mențină o listă de toate directoarele care indică un director conectat direct.

    Oricum ar fi, acesta ar fi un cheltuieli generale de performanță și o complicație suplimentară pentru metadatele și / sau codul sistemului de fișiere, astfel încât proiectanții au decis să nu o permită.

    Comentarii

    • Este ușor de rezolvat și ‘: păstrați o listă a părinților unui director copil, pe care îl actualizați când adăugați sau eliminați un link către copil. Când ștergeți părintele canonic (ținta copilului ‘ s

      ), actualizați .. pentru a indica unul dintre ceilalți părinți din listă.

    • Sunt de acord. Nu știința rachetelor de rezolvat. Dar, totuși, este o cheltuială de performanță și ar ocupa puțin spațiu suplimentar în metadatele sistemului de fișiere și ar adăuga complicații. Astfel, designerii au optat pentru o abordare simplă și rapidă – nu permiteți ‘ să permită linkuri către directoare rigide. >

    încalcă semantica și comportamentele stabilite „, totuși acestea sunt încă permise. De aceea, unele comenzi au nevoie de opțiuni pentru a controla dacă sunt urmate legăturile sym (de exemplu -L în find și cp). Când urmează un program ‘ .. ‘ există o confuzie suplimentară, de unde diferența de ieșire de la pwd și / bin / pwd după parcurgerea unui link sim. Nu există ” răspunsuri Unix „; doar decizii de proiectare. Acesta se învârte în jurul a ceea ce devine ” .. ” așa cum am afirmat în răspunsul meu. Din păcate, ‘ .. ‘ nu este ‘ chiar menționat în răspuns că toți ceilalți votează atât de înșelător.

  • BTW, eu ‘ nu spun că ‘ sunt în favoarea legăturilor dure la dir. Deloc. Nu ‘ nu vreau ca munca mea de zi să fie mai grea decât este deja.
  • ‘ nu este ceea ce POSIX spune, dar IMO ‘ .. ‘ nu ar fi trebuit să fie niciodată un concept de sistem de fișiere, mai degrabă rezolvat sintactic pe căi, astfel încât a/.. ar însemna întotdeauna .. Așa funcționează adresele URL, btw. ‘ este browserul care ‘ rezolvă ‘ .. ‘ înainte de a ajunge chiar la server. Și funcționează excelent.
  • Răspuns

    Crearea hardlink-ului pe directoare nu ar putea fi reversibilă. Să presupunem că avem:

    /dir1 ├──this.txt ├──directory │ └──subfiles └──etc 

    L-am conectat la /dir2.

    Deci /dir2 conține acum toate aceste fișiere și directoare

    Ce se întâmplă dacă mă răzgândesc? Nu pot „doar rmdir /dir2 (deoarece nu este gol)

    Și dacă șterg recursiv în /dir2. .. va fi șters și din /dir1!

    IMHO este „un motiv suficient de mare pentru a evita acest lucru!

    Editați:

    Comentariile sugerează eliminarea directorului făcând rm .Dar rm într-un director care nu este gol eșuează și acest comportament trebuie să rămână, indiferent dacă directorul este legat sau nu. Deci, nu îl puteți „rm să-l deconectați. Ar necesita un argument nou pentru rm, doar pentru a spune” dacă directorul inode are un număr de referințe> 1, apoi deconectați doar directorul „.

    Care, la rândul său, încalcă un alt principiu de cea mai mică surpriză: înseamnă că eliminarea unui hardlink pe care tocmai l-am creat nu este același cu eliminarea a unui hardlink normal de fișier …

    Voi reformula fraza mea: fără o dezvoltare ulterioară, crearea hardlink-ului ar fi nereturnabilă (deoarece nicio comandă curentă nu ar putea gestiona eliminarea fără a fi incoerentă cu comportamentul curent)

    Dacă permitem mai multă dezvoltare pentru a face față cazului, numărul de capcane și riscul de pierdere a datelor „Nu sunteți suficient de conștienți de modul în care funcționează sistemul, o astfel de dezvoltare implică, este IMHO un motiv suficient pentru a restricționa legăturile pe directoare.

    Comentarii

    • Asta nu ar trebui să fie o problemă. Cu cazul dvs., atunci când creăm hardlink către dir2, trebuie să facem hardlink la tot conținutul din dir1 și, prin urmare, dacă redenumim sau ștergem dir2, doar un link suplimentar către inode este șters. Și acest lucru nu ar trebui să afecteze dir1 și conținutul său, deoarece există cel puțin un link (dir1) către inod.
    • Argumentul dvs. este incorect. L-ați deconecta, nu faceți rm -rf. Și dacă numărul de linkuri ajunge la 0, atunci sistemul ar ști că poate șterge tot conținutul.
    • Că ‘ este mai mult sau mai puțin toate rm face oricum dedesubt (deconectați). A se vedea: unix.stackexchange.com/questions/151951/… Aceasta nu este cu adevărat ‘ nu este o problemă, mai mult decât în cazul fișierelor conectate. Deconectarea elimină doar referința numită și scade numărul de legături. Faptul că rmdir nu a câștigat ‘ t șterge directoare care nu sunt goale este irelevant – nu ar ‘ nu faceți asta pentru dir1. Hardlink-urile nu sunt ‘ t copii ale datelor, sunt același fișier real, prin urmare ” șterge ” fișierul dir2 ar șterge listarea directorului pentru dir1. Ar trebui întotdeauna să deconectați.
    • Nu îl puteți ‘ pur și simplu să îl deconectați ca un fișier normal, deoarece rm pe un director nu ‘ t deconectați-l dacă ‘ nu este gol. Consultați Editare.

    Răspuns

    Aceasta este o explicație bună. În ceea ce privește „Care dintre părinții multipli ar trebui .. să arate?” o soluție ar fi ca un proces să își mențină calea completă wd, fie ca inode, fie ca un șir. inodurile ar fi mai robuste, deoarece numele pot fi schimbate. Cel puțin în vremurile de demult, exista un inod in-core pentru fiecare fișier deschis, care era incrementat de fiecare dată când un fișier era deschis, decrementat la închidere. Când ajungea la zero, depozitul către care arăta ar fi eliberat. Când fișierul nu mai era deschis de nimeni, acesta (copia in-core) va fi abandonat. Aceasta ar menține calea ca validă dacă un alt proces ar muta un director într-un alt director în timp ce subdirectorul se afla în calea altui proces. Similar cu modul în care puteți șterge un fișier deschis, dar acesta este pur și simplu eliminat din director, dar totuși deschis pentru orice procese care îl au deschis.

    Directoarele de conectare dură erau permise liber în Bell Labs UNIX, cel puțin V6 și V7, nu știți despre Berkeley sau mai târziu. Nu este necesar niciun steag. Ați putea face bucle? Da, nu faceți asta. Este foarte clar ce faci dacă faci o buclă. Olanda ar trebui să exersezi legarea nodurilor în jurul gâtului în timp ce aștepți rândul tău de paracadism dintr-un avion, dacă ai celălalt capăt agățat convenabil de un cârlig pe capul gros.

    Ce Speram că astăzi am făcut legătura între casă și casă pentru a putea avea / casă / administrare disponibilă, indiferent dacă / casă era sau nu acoperită cu un automat de acasă, acea montare automată având o legătură simbolică numită administrare la / lhome / administ. Acest lucru îmi permite să am un cont administrativ care funcționează indiferent de starea sistemului meu principal de fișiere de acasă. Acesta este ESTE un experiment pentru Linux, dar cred că am învățat la un moment dat pentru SunOS bazat pe UCB că montările automate se fac la nivelul șirului ascii. Este greu de văzut cum s-ar putea face altfel ca un strat deasupra oricărui FS arbitrar.

    Am citit în altă parte că. și .. nu mai sunt fișiere în director. Sunt sigur că există motive întemeiate pentru toate acestea și că o mare parte din ceea ce ne place (cum ar fi posibilitatea de a monta NTFS) este posibil datorită acestor lucruri, dar o parte din eleganța UNIX a fost în implementare.Beneficiile, cum ar fi generalitatea și maleabilitatea pe care le-a oferit această eleganță, i-au permis să fie atât de robuste și să reziste timp de patru decenii. Pe măsură ce pierdem implementările elegante, în cele din urmă va deveni ca Windows (sper să mă înșel!). Cineva ar crea apoi un nou sistem de operare care se bazează pe principii elegante. Ceva la care sa te gandesti. Poate că mă înșel, nu sunt (evident) familiarizat cu implementarea actuală. Este uimitor, deși cât de aplicabilă este înțelegerea de 30 de ani pentru Linux … de cele mai multe ori!

    Comentarii

    • Cred, deși s-ar putea să mă înșel, că . și .. nu sunt legături solide în sistemul de fișiere, pentru sistemele de fișiere moderne. Cu toate acestea, driverul sistemului de fișiere le falsifică. Aceste sisteme de fișiere sunt cele care opresc directoare de legătură dură. Pentru sistemele de fișiere vechi era posibil (dar periculos). Pentru a face ceea ce încercați, uitați-vă la mount --bind, consultați și mount --make… și poate containere.

    Răspuns

    Din ceea ce am adunat, motivul principal este că este util să poți schimba numele directorilor fără a încurca programele care rulează director de lucru pentru a face referire la alte fișiere. Să presupunem că utilizați Wine pentru a rula ~/.newwineprefix/drive_c/Program Files/Firefox/Firefox.exe și că ați dorit să mutați întregul prefix la ~/.wine. Dacă, dintr-un motiv ciudat, Firefox accesa drive_c/windows făcând referire la ../../windows, redenumind ~/.newwineprefix implementările .. care țin evidența directorului părinte ca șir de text în loc de inod.

    Stocarea inodului unui singur director părinte trebuie să fie mai simplă decât încercarea pentru a ține evidența fiecărei căi, atât ca șir de text, cât și ca o serie de inoduri.

    Un alt motiv este că se comportă greșit Aplicațiile pot fi capabile să creeze bucle. Aplicațiile purtătoare ar trebui să poată verifica dacă inodul directorului în care este mutat este același cu inodul oricăruia dintre directoarele imbricate în care este mutat, la fel cum nu puteți muta un director în sine, dar acest lucru s-ar putea să nu fie pusă în aplicare la nivel de sistem de fișiere.

    Un alt motiv ar putea fi faptul că, dacă ați putea lega directoare directoare, ați dori să împiedicați legăturile hard un director pe care nu l-ați putea modifica. find are considerente de securitate, deoarece este folosit pentru a șterge fișierele create de alți utilizatori din directoarele temporare, ceea ce poate cauza probleme dacă un utilizator schimbă un director real pentru un link simbol în timp ce find invocă o altă comandă. A putea lega directoare importante ar obliga un administrator să adauge teste suplimentare la find pentru a nu le afecta. (Ok, deja nu se poate face acest lucru pentru fișiere, deci acest motiv este nevalid.)

    Un alt motiv este acela că stocarea inodului directorului părinte poate oferi o redundanță suplimentară în caz de corupție sau deteriorare a sistemului de fișiere. doream ca .. să enumere toate directoarele părinte care fac legătura directă cu acesta, astfel încât un părinte diferit, arbitrar, ar putea fi găsit cu ușurință dacă cel curent este deconectat, nu numai că încalci ideea că legăturile sunt egale, trebuie să schimbați modul în care sistemul de fișiere stochează și folosește inodurile. Programele tratează căile ca o serie (uniq ue la fiecare hardlink) de inoduri de director ar evita acest lucru, dar nu veți obține redundanța în caz de deteriorare a sistemului de fișiere.

    Lasă un răspuns

    Adresa ta de email nu va fi publicată. Câmpurile obligatorii sunt marcate cu *