Ho letto nei libri di testo che Unix / Linux non consente collegamenti fisici a directory ma consente collegamenti software. È perché, quando abbiamo cicli e se creiamo hard link, e dopo un po cancelliamo il file originale, questo punterà a qualche valore di spazzatura?
Se i cicli fossero lunica ragione per non consentire i link fisici, allora perché i soft link alle directory consentito?
Commenti
cwd e fare riferimento a questo quando rileva un uso di..
. Ovviamente, ciò significherebbe che i collegamenti simbolici dovrebbero essere creati tenendo presente questo, ma devi già stare attento a non interrompere i collegamenti simbolici e non ‘ penso che la regola aggiuntiva lo farebbe renderli inutili.
Risposta
Questa è solo una cattiva idea, perché non è un modo per distinguere tra un hard link e un nome originale.
Consentire hard link a directory interromperebbe la struttura del grafo aciclico diretto del filesystem, creando possibilmente loop di directory e sottoalberi di directory penzolanti make fsck
e qualsiasi altro file tree walker soggetto a errori.
Per prima cosa, per capirlo, parliamo di inode. I dati nel filesystem sono conservati in blocchi sul disco e quei blocchi sono raccolti insieme da un inode. Puoi pensare allinode come al file. Gli Inode non hanno nomi di file, però. È qui che entrano in gioco i link.
Un link è solo un puntatore a un inode. Una directory è un inode che contiene collegamenti. Ogni nome di file in una directory è solo un collegamento a un inode. Anche lapertura di un file in Unix crea un collegamento, ma è un diverso tipo di collegamento (non è un collegamento denominato).
Un collegamento fisico è solo una voce di directory aggiuntiva che punta a quellinode. Quando ls -l
, il numero dopo le autorizzazioni è il conteggio dei collegamenti denominati. La maggior parte dei file normali avrà un collegamento. La creazione di un nuovo collegamento fisico a un file farà sì che entrambi i nomi dei file puntino allo stesso inode. Nota:
% 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
Ora, puoi vedere chiaramente che non esiste un collegamento fisico. Un collegamento fisico è uguale a un nome normale. Nellesempio precedente, test
o test2
, qual è il file originale e qual è lhard link? Alla fine, non puoi davvero dirlo (anche per timestamp) perché entrambi i nomi puntano allo stesso contenuto, lo stesso inode:
% 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
Il -i
flag to ls
mostra i numeri di inode allinizio della riga. Nota come test
e test2
ha lo stesso numero di inode, ma test3
ne ha uno diverso.
Ora, se ti fosse consentito fai questo per le directory, due directory diverse in punti diversi del filesystem potrebbero puntare alla stessa cosa. In effetti, una sottodirectory potrebbe puntare al nonno, creando un ciclo.
Perché questo ciclo è preoccupante ? Perché quando stai attraversando, non cè modo di rilevare che stai andando in loop (senza tenere traccia dei numeri di inode mentre attraversi). Immagina di scrivere il comando du
, che deve ricorrere alle sottodirectory per scoprire lutilizzo del disco. Come farebbe du
a sapere dove n ha colpito un loop? È soggetto a errori e richiede molta contabilità che du
dovrebbe fare, solo per portare a termine questo semplice compito.
I collegamenti simbolici sono una bestia completamente diversa, in che sono un tipo speciale di “file” che molte API di file filesystem tendono a seguire automaticamente. Nota, un collegamento simbolico può puntare a una destinazione inesistente, perché punta per nome e non direttamente a un inode. Questo concetto non ha senso con gli hard link, perché la semplice esistenza di un “hard link” significa che il file esiste.
Allora perché du
può occuparsi di collegamenti simbolici facilmente e non collegamenti fisici? Siamo stati in grado di vedere sopra che i collegamenti reali non sono distinguibili dalle normali voci di directory. Tuttavia, i collegamenti simbolici sono speciali, rilevabili e ignorabili! du
nota che symlink è un link simbolico e lo ignora completamente!
% 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 .
Commenti
-
Allowing hard links to directories would break the directed acyclic graph structure of the filesystem
.Puoi spiegare di più sul problema con i cicli che utilizzano collegamenti fisici? Perché va bene con i collegamenti simbolici - Sembra che lo abbiano consentito sui Mac aggiungendo il rilevamento del ciclo alla chiamata di sistema link () e rifiutandosi di consentire la creazione di un collegamento fisico alla directory se creasse un ciclo . Sembra essere una soluzione ragionevole.
- @psusi mkdir -p a / b; nocheckln c a; mv c a / b; – il nocheckln cè un ln teorico che non controlla gli argomenti della directory e passa solo al collegamento, e poiché non viene eseguito alcun ciclo, siamo tutti bravi a creare ‘ c ‘. quindi spostiamo ‘ c ‘ in ‘ a / b ‘ e viene creato un ciclo da a / b / c – > a / – il check-in di link () non è abbastanza buono
- I cicli sono molto pessimi. Windows ha questo problema con i ” giunzioni ” che sono directory di collegamento fisico. Se applichi accidentalmente le autorizzazioni allintero profilo, scopre una serie di giunzioni che creano un ciclo infinito. Ricorrendo attraverso le directory ricorre fino a quando i limiti di lunghezza del percorso non lo fermano.
- @WhiteWinterWolf, secondo questo collegamento, hanno aggiunto specificamente il supporto per la macchina del tempo, ma solo root può farlo: superuser.com/questions/360926/…
Risposta
Puoi utilizzare bind mount per simulare directory con hard link
sudo mount --bind /some/existing_real_contents /else/dummy_but_existing_directory sudo umount /else/dummy_but_existing_directory
Risposta
Con leccezione dei punti di montaggio, ogni directory ha un solo genitore: ..
.
Un modo per pwd
è controllare il dispositivo: inode per “.” e “..”. Se sono uguali, hai raggiunto la radice del file system. Altrimenti, trova il nome della directory corrente nel genitore, inseriscilo in una pila e inizia a confrontare “../.” con “../ ..”, poi “../../.” con “../../ ..”, ecc. Una volta raggiunto il root, inizia a visualizzare e stampare i nomi dallo stack. Questo algoritmo si basa sul fatto che ogni directory ha uno e un solo genitore.
Se i collegamenti fisici alle directory fossero consentiti, quale dei più genitori dovrebbe ..
puntare? Questo è un motivo convincente per cui i collegamenti fisici alle directory non sono consentiti.
I collegamenti simbolici alle directory non causano questo problema. Se un programma lo desidera, potrebbe eseguire un lstat()
su ogni parte del percorso e rilevare quando viene incontrato un collegamento simbolico. Lalgoritmo pwd
restituirà il vero percorso assoluto per una directory di destinazione. Il fatto che ci sia un pezzo di testo da qualche parte (il collegamento simbolico) che punta alla directory di destinazione è praticamente irrilevante. Lesistenza di un tale collegamento simbolico non crea un ciclo nel grafico.
Commenti
- Non ne sono così sicuro. Se pensiamo a
..
come una sorta di hardlink virtuale al genitore, non vi è alcuna ragione tecnica per cui la destinazione del collegamento può avere solo un altro collegamento ad esso.pwd
dovrebbe semplicemente utilizzare un algoritmo diverso per risolvere il percorso.
Risposta
Vorrei aggiungere qualche altro punto su questa domanda. Gli hard link per le directory sono consentiti in Linux, ma in modo limitato.
Un modo per verificarlo è quando elenchiamo il contenuto di una directory troviamo due directory speciali “.” e “..”. Come sappiamo “.” punta alla stessa directory e “..” punta alla directory padre.
Quindi creiamo un albero di directory dove “a” è la directory padre che ha la directory “b” come figlia.
a `-- b
Annota linode della directory “a”. E quando eseguiamo un ls -la
dalla directory “a” possiamo vederlo “.” anche la directory punta allo stesso inode.
797358 drwxr-xr-x 3 mkannan mkannan 4096 Sep 17 19:13 a
E qui possiamo scoprire che la directory “a” ha tre collegamenti fisici. Questo perché linode 797358 ha tre hardlink nel nome “.” allinterno della directory “a” e il nome “..” allinterno della directory “b” e uno con il nome “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 ..
Quindi qui possiamo capire che i collegamenti fisici sono disponibili solo per le directory per connettersi con le directory padre e figlio. Quindi una directory senza un figlio avrà solo 2 hardlink, quindi la directory “b” avrà solo due hardlink.
Un motivo per cui lhard linking delle directory è stato impedito liberamente sarebbe quello di evitare cicli di riferimento infiniti che confonderà i programmi che attraversano il filesystem.
Dato che il filesystem è organizzato come albero e poiché lalbero non può avere riferimenti ciclici, questo avrebbe dovuto essere evitato.
Commenti
- Buon esempio. Ha chiarito il mio dubbio. Quindi questi casi vengono gestiti in modo speciale per evitare cicli infiniti. giusto?
- Poiché disponiamo di un modo limitato di consentire collegamenti fisici per directory, ad esempio ” .. ” e “. ” non raggiungeremo un ciclo infinito e quindi non avremmo bisogno di metodi speciali per evitarli in quanto non accadranno 🙂
Risposta
Nessuna delle seguenti è la vera ragione per disabilitare i collegamenti fisici alle directory; ogni problema è abbastanza facile da risolvere:
- i cicli nella struttura ad albero causano un attraversamento difficile
- più genitori, quindi qual è quello “reale”?
- garbage collection del filesystem
Il vero motivo (come suggerito da @ Thorbjørn Ravn Andersen) viene visualizzato quando elimini una directory che ha più genitori, dalla directory a cui punta ..
:
A cosa dovrebbe puntare ..
?
Se la directory viene eliminata dalla directory principale ma il conteggio dei collegamenti è ancora maggiore di 0
quindi deve esserci qualcosa, da qualche parte che lo punta ancora. Non puoi “lasciare ..
che punta a nulla; molti programmi si basano su ..
, quindi il sistema dovrebbe attraversare lintero file system finché non trova la prima cosa che punta alla directory eliminata, solo per aggiornare ..
. O quello, o il file system dovrebbe mantenere un elenco di tutte le directory puntano a una directory collegata in modo fisso.
In ogni caso, questo sarebbe un sovraccarico delle prestazioni e una complicazione aggiuntiva per i metadati e / o il codice del file system, quindi i progettisti hanno deciso di non consentirlo.
Commenti
- Anche ‘ è facile da risolvere: tieni un elenco dei genitori di una directory figlio, che aggiorni quando aggiungi o rimuovi un collegamento al figlio. Quando elimini il genitore canonico (il target del ‘ s
), aggiorna
..
in modo che punti a uno degli altri genitori nellelenco. - Accetto. Non scienza missilistica da risolvere. Tuttavia, un sovraccarico delle prestazioni e richiederebbe un po di spazio in più nei metadati del file system e aggiungerebbe complicazioni. E così i progettisti hanno optato per lapproccio semplice e veloce: don ‘ t consentire collegamenti a directory rigide.
- Collegamenti Sym a directory ” violano la semantica e i comportamenti consolidati “, ma sono ancora consentiti. Alcuni comandi richiedono quindi opzioni per controllare se i collegamenti simbolici vengono seguiti (ad esempio -L in find e cp). Quando un programma segue ‘ .. ‘ cè ulteriore confusione, da qui la differenza nelloutput di pwd e / bin / pwd dopo aver attraversato un collegamento sym. Non ci sono ” risposte Unix “; solo decisioni di progettazione. Questo ruota attorno a ciò che diventa di ” .. ” come ho affermato nella mia risposta. Sfortunatamente, ‘ .. ‘ non ‘ non è nemmeno menzionato nella risposta che tutti gli altri vota così timidamente.
- A proposito, ‘ non dico ‘ a favore degli hard link a dirs. Affatto. Non ‘ voglio che il mio lavoro quotidiano sia più difficile di quanto non sia già.
- ‘ non è quello POSIX dice, ma IMO ‘ .. ‘ non avrebbe mai dovuto essere un concetto di filesystem, piuttosto risolto sintatticamente sui percorsi, quindi
a/..
significherebbe sempre.
. Ecco come funzionano gli URL, btw. È ‘ il browser che ‘ sta risolvendo ‘ .. ‘ prima ancora che raggiunga il server. E funziona alla grande.
Risposta
La creazione di collegamenti fisici nelle directory sarebbe irreversibile. Supponiamo di avere:
/dir1 ├──this.txt ├──directory │ └──subfiles └──etc
Lo collego a /dir2
.
Quindi /dir2
ora contiene anche tutti questi file e directory
E se cambio idea? Non posso “solo rmdir /dir2
(perché non è vuoto)
E se elimino in modo ricorsivo in /dir2
. .. verrà eliminato anche da /dir1
!
IMHO “è un motivo ampiamente sufficiente per evitarlo!
Modifica:
I commenti suggeriscono di rimuovere la directory eseguendo rm
su di essa .Ma rm
su una directory non vuota non riesce e questo comportamento deve rimanere, indipendentemente dal fatto che la directory sia collegata o meno. Quindi non puoi “rm
scollegarlo. Sarebbe necessario un nuovo argomento per rm
, solo per dire” se la directory inode ha un conteggio dei riferimenti> 1, quindi scollega solo la directory “.
Il che, a sua volta, infrange un altro principio di minore sorpresa: significa che la rimozione di un hardlink di directory che ho appena creato non è la stessa cosa della rimozione di un normale hardlink di file …
Riformerò la mia frase: senza ulteriore sviluppo, la creazione di hardlink non sarebbe reversibile (poiché nessun comando corrente potrebbe gestire la rimozione senza essere incoerente con il comportamento corrente)
Se consentiamo un maggiore sviluppo per gestire il caso, il numero di insidie e il rischio di perdita di dati se “Non sei abbastanza consapevole di come funziona il sistema, implica un tale sviluppo, IMHO è una ragione sufficiente per limitare lhardlinking alle directory.
Commenti
- Non dovrebbe essere un problema. Nel tuo caso, quando creiamo hardlink a dir2 dobbiamo creare hardlink a tutti i contenuti in dir1 e quindi se rinominiamo o cancelliamo dir2 viene eliminato solo un link extra allinode. E questo non dovrebbe influenzare dir1 e il suo contenuto in quanto vi è almeno un collegamento (dir1) allinode.
- Il tuo argomento non è corretto. Dovresti semplicemente scollegarlo, non fare rm -rf. E se il conteggio dei collegamenti raggiunge 0, il sistema saprebbe di poter eliminare anche tutti i contenuti.
- Quelli ‘ sono più o meno tutti
rm
non viene comunque inserito (scollega). Vedi: unix.stackexchange.com/questions/151951/… Questo non è davvero ‘ t un problema, non più di quanto non lo sia con i file hardlink. Lo scollegamento rimuove semplicemente il riferimento denominato e riduce il conteggio dei collegamenti. Il fatto chermdir
non ‘ elimini directory non vuote è irrilevante: non ‘ Non farlo neanche perdir1
. I collegamenti fisici non sono ‘ t copie di dati, sono lo stesso file effettivo, quindi in realtà ” eliminazione ” il file dir2 cancellerebbe lelenco delle directory per dir1. Dovresti sempre scollegarlo. - Non puoi ‘ scollegarlo come un normale file, perché
rm
in una directory don ‘ t scollegala se ‘ non è vuota. Vedere Modifica.
Risposta
Questa è una buona spiegazione. Riguardo a “Quale dei molteplici genitori dovrebbe indicare ..?” una soluzione sarebbe che un processo mantenga il suo percorso wd completo, sia come inode che come stringa. gli inode sarebbero più robusti poiché i nomi possono essere modificati. Almeno nei tempi antichi, cera un inode in-core per ogni file aperto che veniva incrementato ogni volta che un file veniva aperto, decrementato quando veniva chiuso. Quando raggiungeva lo zero, e la memoria che indicava si sarebbero liberate. Quando il file non era più aperto da nessuno, (la copia in-core) sarebbe stato abbandonato. Ciò manterrebbe il percorso come valido se qualche altro processo spostasse una directory in unaltra directory mentre la sottodirectory si trovava nel percorso di un altro processo. Simile a come è possibile eliminare un file aperto, ma viene semplicemente rimosso dalla directory, ma è ancora aperto per tutti i processi che lo hanno aperto.
Le directory con collegamento fisso erano consentite liberamente in Bell Labs UNIX, almeno V6 e V7, non so di Berkeley o versioni successive. Nessun flag richiesto. Potresti creare dei loop? Sì, non farlo. È molto chiaro cosa stai facendo se fai un loop. Nether dovresti esercitarti a annodare il nodo intorno al collo mentre aspetti il tuo turno di paracadutismo da un aereo se hai laltra estremità comodamente appesa a un gancio sulla paratia.
Cosa Io speravo che oggi fosse di collegare hard-link lhome a home in modo da poter avere / home / administ disponibile indipendentemente dal fatto che / home fosse coperto o meno da un automout su home, che automount aveva un link simbolico chiamato administ a / lhome / administ. Ciò mi consente di avere un account amministrativo che funziona indipendentemente dallo stato del mio file system principale principale. Questo È un esperimento per Linux, ma penso che ho imparato una volta per SunOS basato su UCB che gli automount vengono eseguiti a livello di stringa ascii. È difficile vedere come potrebbero essere fatti altrimenti come un livello sopra qualsiasi FS arbitrario.
Lho letto altrove. e .. non sono più nemmeno file nella directory. Sono sicuro che ci siano buone ragioni per tutto questo e che gran parte di ciò che ci piace (come poter montare NTFS) è possibile grazie a queste cose, ma parte delleleganza di UNIX era nellimplementazione.Sono i vantaggi come la generalità e la malleabilità che questa eleganza ha fornito che gli hanno permesso di essere così robusto e di durare per quattro decenni. Man mano che perdiamo le eleganti implementazioni, alla fine diventerà come Windows (spero di sbagliarmi!). Qualcuno creerebbe quindi un nuovo sistema operativo basato su principi eleganti. Qualcosa a cui pensare. Forse mi sbaglio, non ho (ovviamente) familiarità con lattuale implementazione. È sorprendente, anche se la comprensione di 30 anni è applicabile a Linux … il più delle volte!
Commenti
- Penso, anche se mi sbaglio, che
.
e..
non siano collegamenti fisici nel file system, per i file system moderni. Tuttavia il driver del file system li falsifica. Sono questi file system che bloccano lhard linking delle directory. Per i vecchi file system era possibile (ma pericoloso). Per fare quello che stai provando, guardamount --bind
, vedi anchemount --make…
e forse contenitori.
Answer
Da quello che ho capito, il motivo principale è che è utile poter cambiare i nomi delle directory senza rovinare i programmi in esecuzione che usano il loro directory di lavoro per fare riferimento ad altri file. Supponi di utilizzare Wine per eseguire ~/.newwineprefix/drive_c/Program Files/Firefox/Firefox.exe
e di voler spostare lintero prefisso in ~/.wine
. Se per qualche strano motivo Firefox accedeva a drive_c/windows
facendo riferimento a ../../windows
, rinominava ~/.newwineprefix
interruzioni implementazioni di ..
che tengono traccia della directory genitore come una stringa di testo invece di un inode.
Memorizzare linode di una singola directory genitore deve essere più semplice che provare per tenere traccia di ogni percorso sia come stringa di testo che come serie di inode.
Un altro motivo è che si comporta male Le applicazioni ng potrebbero essere in grado di creare loop. Le applicazioni che si comportano dovrebbero essere in grado di controllare se linode della directory che viene spostata è lo stesso dellinode di qualsiasi directory annidata in cui viene spostata, proprio come non puoi spostare una directory in se stessa, ma questo potrebbe non essere applicato a livello di filesystem.
Ancora un altro motivo potrebbe essere che se potessi collegare le directory in modo fisso, vorresti impedire il collegamento fisso a una directory che non potresti modificare. find
ha considerazioni sulla sicurezza perché è utilizzato per cancellare file creati da altri utenti da directory temporanee, il che può causare problemi se un utente cambia una directory reale per un collegamento simbolico mentre find
sta invocando un altro comando. Essere in grado di collegare directory importanti forzerebbe un amministratore ad aggiungere test extra a find
per evitare di influenzarli. non è possibile farlo per i file, quindi questo motivo non è valido.)
Ancora un altro motivo è che la memorizzazione dellinode della directory padre può fornire ridondanza aggiuntiva in caso di danneggiamento o danneggiamento del file system. voleva che ..
elencasse tutte le directory principali che collegano a questa, in modo che un genitore diverso e arbitrario possa essere facilmente trovato se quello corrente viene scollegato, non solo stai violando lidea che i collegamenti sono uguali, è necessario modificare il modo in cui il file system memorizza e utilizza gli inode. I programmi trattano i percorsi come una serie (uniq a causa di ogni collegamento fisico) degli inode di directory lo eviterebbe, ma non si otterrebbe la ridondanza in caso di danni al file system.
..
? Soprattutto dopo aver rimosso il collegamento fisico a questo directory, nella directory a cui punta..
? Deve puntare da qualche parte...
non ‘ non deve esistere fisicamente su qualsiasi unità. ‘ è il lavoro del sistema operativo ‘ per tenere traccia della directory di lavoro corrente, comunque, quindi dovrebbe essere relativamente semplice mantenere anche un elenco di inode associati a ciascun processo