Utilizzare casi per hardlink? [chiuso]


40

In quali situazioni si vorrebbe usare un hard link piuttosto che un soft link? Personalmente non mi sono mai imbattuto in una situazione in cui vorrei usare un hard-link su un soft-link e l'unico caso d'uso che ho riscontrato durante la ricerca sul web è la deduplicazione di file identici .


4
Di seguito ci sono buone risposte, ma considera il contesto storico (controverso). Quando Unix era nuovo, le unità disco erano lente e avevano capacità e buffer limitati. Un hard link era semplicemente un'altra voce diretta nel file system allo stesso file. Se stavi accedendo a ls , o come ti piaceva chiamarlo, l' elenco , era irrilevante. Se avessi fatto dell'elenco un collegamento software, il suo utilizzo implicherebbe trovarlo nella directory, leggere il file speciale chiamato list , vedere che vuoi il file ls , trovare ls nella directory e leggere il file ls effettivo dal disco. Un enorme differenza di prestazioni!
RichF

16
Bene, il primo hardlink di un file è davvero utile.
Smetti di fare del male a Monica il

@OrangeDog: Sì, ma è necessario un campo di conteggio dei collegamenti nell'inode se si desidera supportare più collegamenti. (Potrebbe essere necessario un flag per la versione in-memory degli inode per gestire il caso non collegato ma ancora aperto. Fsck dopo un arresto senza inserimento nel journal dovrebbe comunque cercare inode senza collegamenti in entrambi i modi.)
Peter Cordes

1
La semantica della directory POSIX dovrebbe essere progettata diversamente: ..è sempre lo stesso inode .della directory parent. Cose come findpossono verificare che link-count = 2 per rilevare directory foglia ed evitare statdi inserire le voci da readdir per cercare le sottodirectory. Ma questa è solo una funzione minore abilitata dal supporto per hardlink di file non di directory (normale, symlink, dispositivo, socket e named pipe). (Sì, i symlink hanno il loro inode e possono essere hardlinked.)
Peter Cordes,

1
Una ragione per usare hardlink che non ho visto nella mia recensione di SO, di natura "globale". Immagina un filesystem in cui i file sono generalmente piccoli (per lo più brevi memo, diciamo), ma per mantenere le cose organizzate potresti aver bisogno di puntatori allo stesso file in luoghi diversi. Con i collegamenti simbolici, ogni puntatore utilizza un inode. Tali filesystem potrebbero già avere un problema con l'esaurimento degli inode. L'uso di hardlink come puntatori aiuta a risolvere questo problema. gli inode hanno un numero limitato; i nomi per loro non lo sono (almeno, non allo stesso modo).
Mathguy,

Risposte:


27

A parte l'utilizzo del backup menzionato in un altro commento, che a mio avviso include anche le istantanee su un volume BTRFS, un caso d'uso per hard-link su soft-link è una raccolta di file ordinati per tag. (Non necessariamente il metodo migliore per creare una raccolta, un metodo basato su database è potenzialmente migliore, ma per una raccolta semplice ragionevolmente stabile, non è poi così male.)

Una raccolta multimediale in cui tutti i file sono archiviati in una directory flat e ordinati in altre directory in base a vari criteri, ad esempio: anno, soggetto, artista, genere, ecc. Potrebbe trattarsi di una collezione di film personale o di un collettivo di uno studio commerciale lavori. Essenzialmente finito, il file viene salvato, probabilmente non modificato, e ordinato, possibilmente in più posizioni tramite collegamenti.

Tieni presente che il concetto di "originale" e "copia" non è applicabile ai collegamenti reali: ogni collegamento al file è originale, non esiste una "copia" in senso normale. Per la descrizione del caso d'uso, tuttavia, i termini imitano la logica del comportamento.

L '"originale" viene salvato nella directory "catalog" e le "copie" ordinate sono strettamente collegate a tali file. Gli attributi dei file nelle directory di ordinamento possono essere impostati su r / o, impedendo qualsiasi modifica accidentale ai nomi dei file e alla struttura ordinata, mentre gli attributi sulla directory del catalogo possono essere r / w permettendo di modificarli secondo necessità. (Caso per questo sarebbero i file musicali in cui alcuni giocatori tentano di rinominare e riorganizzare i file in base ai tag incorporati nel file multimediale, dall'input dell'utente o dal recupero di Internet.) Inoltre, poiché gli attributi delle directory "copia" possono essere diversi da nella directory "originale", la struttura ordinata potrebbe essere messa a disposizione del gruppo o del mondo con accesso limitato mentre il "catalogo" principale è accessibile solo all'utente principale, con pieno accesso. I file stessi, tuttavia, avranno sempre gli stessi attributi su tutti i collegamenti a quell'inode. (ACL potrebbe essere esplorato per migliorarlo, ma non la mia area di conoscenza.)

Se l'originale viene rinominato o spostato (la singola directory "catalogo" diventa troppo grande per essere gestita, ad esempio), i collegamenti permanenti rimangono validi, i collegamenti morbidi vengono interrotti. Se le "copie" vengono spostate e i soft-link sono relativi, i soft-link verranno nuovamente interrotti e i hard-link non lo saranno.

Nota: sembra esserci un'incoerenza sul modo in cui diversi strumenti segnalano l'utilizzo del disco quando sono coinvolti soft-link. Con hard-link, tuttavia, sembra coerente. Quindi, con 100 file in un catalogo ordinati in una raccolta di "tag", potrebbero esserci facilmente 500 "copie" collegate. (Per una raccolta di fotografie, ad esempio data, fotografo e una media di 3 tag "soggetto"). Dolphin, ad esempio, segnalerebbe che come 100 file per collegamenti fisici e 600 file se si utilizzano collegamenti software. È interessante notare che riporta lo stesso utilizzo dello spazio su disco in entrambi i modi, quindi sembra una grande raccolta di piccoli file per i soft-link e una piccola raccolta di file di grandi dimensioni per i hard-link.

Un avvertimento a questo tipo di caso d'uso è che nei file system che usano COW, la modifica dell'originale potrebbe spezzare i collegamenti reali, ma non i collegamenti diretti. Ma, se l'intenzione è quella di avere la copia master, dopo la modifica, il salvataggio e l'ordinamento, COW non entra nello scenario.


3
Cordiali saluti: le istantanee di btrfs non sono hardlink. Hanno un comportamento diverso (ad esempio, la modifica di una copia non modifica l'altra). E statmostrerà solo un link.
derobert,

@derobert Non sono sicuro di come funzionano le istantanee, una piccola indagine mostra cose interessanti. Per i file / directory invariati statmostra lo stesso numero di inode, ma ID dispositivo diverso. Deve avere qualcosa a che fare con il modo in cui i volumi secondari sono sovrapposti sul volume principale, montato raramente. Sospetto che se il volume principale fosse montato statmostrerebbe un conteggio dei collegamenti pari al numero di istantanee che contenevano quella versione del file. COW probabilmente si prende cura di chi modifica non influisce su nessun altro. Semplice speculazione basata su lieve curiosità, ma non abbastanza curiosa da scavare più a fondo.
Gypsy Spellweaver,

Ogni collegamento simbolico ha il proprio inode, quindi utilizza una voce di inode nel filesystem. I filesystem Unix tradizionali richiedono di scegliere la quantità di spazio da riservare agli inode al momento della creazione di FS, invece di allocarlo secondo necessità come fa XFS. Quindi è in realtà significativo che la versione di symlink utilizzi molti più inode (anche oltre alle implicazioni sull'impronta della cache VFS).
Peter Cordes,

23

I collegamenti reali sono utili nei casi in cui non si desidera legare l'esistenza di entrambi i file. Considera questo:

touch a
ln -s a b
rm a

Adesso bè inutile. (E questi passaggi possono accadere abbastanza distanti, essere fatti da persone diverse, ecc.)

Considerando che con un collegamento reale,

touch a
ln a b
rm a

b è ancora presente e corretto.


8
@MatthewCline Questo comportamento si desidera quando si gestiscono backup incrementali efficienti. Soprattutto quando i vecchi backup vengono eliminati, in un sistema di backup basato su soft-link è necessario controllare e ricollegare tutti i file / collegamenti di backup più recenti a una base valida, mentre i collegamenti fisici eseguono quel lavoro "gratuitamente" a livello di inode. timeshift / backintime, ad esempio, usano estesamente hardlink.
Orzechow,

3
@orzechow Non penso che tu voglia un comportamento hard link vicino al tuo sistema di backup. github.com/bit-team/backintime/wiki/… backintime presume follemente che tutte le modifiche ai file verranno eseguite mediante un ciclo di rimozione-creazione anziché aggiornamento in atto.
Depresso

10
I collegamenti hard di @DepressedDaniel vanno bene all'interno di un sistema di backup, semplicemente non vuoi che i backup siano strettamente collegati ai file live. Ma in ogni caso un backup non dovrebbe mai essere raggiungibile direttamente da un sistema live ...
Stephen Kitt,

1
Questa non è una risposta - in particolare, non è un caso d'uso. È solo una dimostrazione del comportamento degli hard link.
user394

1
@ ThomasPadron-McCarthy è un malinteso. BiT utilizza gli hard link solo per collegare file identici all'interno di diverse istantanee. NON sono collegati al file originale! (I'm the BiT Dev)
Germar,

11

Un singolo programma può cambiare il suo comportamento a seconda del nome che viene lanciato come:

$ ls -li `which pgrep` `which pkill`
208330 -r-xr-xr-x  2 root  bin  19144 Jul 26  2016 /usr/bin/pgrep
208330 -r-xr-xr-x  2 root  bin  19144 Jul 26  2016 /usr/bin/pkill

Che nella fonte è deciso tramite qualcosa di simile

if (strcmp(__progname, "pgrep") == 0) {
    action = grepact;
    pgrep = 1;
} else {
    action = killact;

sebbene i dettagli esatti varieranno a seconda del sistema operativo e della lingua coinvolti.

Ciò consente di non compilare (per lo più) codice identico in due binari (per lo più) identici. Ricorda che le date unix ai giorni in cui lo spazio su disco era super costoso, sebbene secondo Stevens in APUE il capitolo 4 dei symlink fossero implementati in BSD4.2 (1983) per sostituire varie limitazioni degli hardlink. Un programma di test per verificare se il nome del collegamento simbolico viene utilizzato come nome del programma potrebbe essere simile a:

#include <stdio.h>
#include <stdlib.h>
int main(int argc, char *argv[])
{
    printf("called as '%s'\n", *argv);
    exit(0);
}

E testato tramite:

$ cc -o myname myname.c 
$ ln -s myname alias
$ ./myname
called as './myname'
$ ./alias
called as './alias'
$ 

4
Ma di solito non viene gestito con i softlink?
Matthew Cline,

1
@MatthewCline potrebbe essere oggi, ma i collegamenti simbolici non esistevano prima della 4.2BSD (1983) secondo Stevens in APUE.
thrig

4
@thrig, la domanda richiede in particolare casi d'uso che non possono essere realizzati con collegamenti simbolici o, almeno, preferibili piuttosto che utilizzare collegamenti simbolici. La tua risposta si applica sia a HL che a SL.
Marcelo,

3
BusyBox porta questo al massimo.
Max Ried il

8

Quando il mio software P2P termina il download di un determinato file, il file viene inserito in una directory specifica. I file scaricati non devono quasi mai essere modificati. Il caso comune è che faccio un hardlink in una directory diversa dove ho bisogno del file.

vantaggi:

  • Condivido ancora il file nella rete P2P come dovrei anche se io rmo mvla "copia".
  • Il file è anche nel percorso in cui ne ho bisogno; la maggior parte di tali posizioni non sono condivise.
  • Posso rm"l'originale" per interrompere la condivisione del file; questa operazione non influisce sulla "copia" nella posizione desiderata.
  • Il mio spazio su disco viene utilizzato solo una volta.

Il punto principale: se sapessi in anticipo quale file vorrei rmprima, potrei andare con symlink. Ma non lo so mai.


6

I filesystem sono un modo semplice ma efficace per organizzare e classificare i file (questa è la loro principale ragione di esistenza). Gli hardlink consentono un maggiore grado di flessibilità in questa materia.

Come accennato, non esiste un concetto di originale e di copie quando si tratta di hardlink, tutte le voci della directory (hardlink) sono semplicemente riferimenti all'esistenza del file (puntano al suo inode) senza precedenza, quindi non ci sono anche hardlink rotti. .

Quindi qui ci sono alcuni dei casi d'uso cui partecipano gli hardlink ma i softlink no :

  1. Immagina di avere una collezione di film o musica o altri media e desideri applicare criteri di classificazione diversi, come canzoni classificate per artista in un ramo (ogni artista ha la sua sottodirectory); per genere in un altro ramo (ciascuno in una diversa sottodirectory), ecc. Tuttavia non si desidera duplicare i file né decidere dove inserire "originale" in modo da avere la libertà di riclassificarsi senza dovere " gestire "e ricollegare i file durante lo spostamento per evitare collegamenti interrotti.

  2. Un altro motivo è quello di evitare lo spreco di spazio di archiviazione necessario per avere più copie dello stesso file e tuttavia consentire a chrootsyscall di beneficiare di un sottoinsieme di file nella radice del file system "master" (i collegamenti simbolici non potrebbero mai fare riferimento a file esterni la chrootsandbox, anche se hanno percorsi relativi).

  3. Un altro motivo molto importante ma raramente menzionato per l'esistenza di hardlink sono le ..sottodirectory. Le ..directory in realtà sono (nella maggior parte delle implementazioni di unix fs) hardlink alla directory principale, senza hardlink questo deve essere implementato in un modo completamente diverso, mentre l'esistenza di hardlink rende molto facile l'implementazione.


1
Per il punto 1, usare uuidi come nome "canonico" per i file e rendere tutti i nomi leggibili dall'uomo come collegamenti simbolici agli uuidi è una soluzione alternativa.
R ..

Sebbene il suggerimento degli uuidi sembri accademicamente corretto, l'uso degli uuidi per i nomi dei file non sembra molto pratico e, di nuovo, l'obiettivo è semplificare le cose, non renderle più difficili o "meno comprensibili all'uomo". Inoltre, avere uudis per il riferimento al file "canonico" sarebbe solo un'ulteriore riferimento indiretto all'attuale inode del file, quindi, non ha senso realizzare questo approccio in quanto non offre alcun vantaggio, solo svantaggi come: impatto sulle prestazioni, ulteriori spazio su disco per memorizzare più voci di directory, con un mucchio di file con nomi "strani" intorno ...
Marcelo

5

Esempio molto comune e reale che necessita di hardlink:

git clone --reference <repository>

Questo clone da un repository Git locale con copia quasi zero. Invece di copiare i file oggetto (file immutabili usati da Git per il suo "database"), li collega semplicemente.

Qualsiasi repository può rimuovere un oggetto, ma l'inode rimane valido per il resto dei repository. E se un oggetto viene rimosso da tutti i repository, viene eliminato dal disco. I collegamenti fissi rendono una soluzione meravigliosamente robusta e veloce. Molto comune nei server CI.


C'è una versione non-hard-link: git clone --shared <repository>. Questo, tuttavia, è instabile e presenta molti più avvertimenti poiché tutti stanno lavorando sulla stessa directory.


4

Recentemente ho avuto un caso d'uso per una procedura di aggiornamento in qualche modo sicura per i sistemi basati su U-Boot in cui uImageè presente un soft-link che punta all'immagine per l'avvio, l'idea era che un'interruzione di corrente non dovesse presentare problemi, indipendentemente da quale punto processo succede (supponendo che il file system funzioni insieme):

ln image.bin backup_image.bin
ln -sf backup_image.bin uImage

// replace image.bin

ln -sf image.bin uImage
rm backup_image.bin

Senza hardlink non sarebbe così semplice.

/modificare:

Grazie ai commenti ora so che sarebbe meglio fare:

ln image.bin backup_image.bin
ln -sf backup_image.bin uImageNew
mv uImageNew uImage || rm -rf uImage && mv uImageNew uImage

// replace image.bin

ln -sf image.bin uImageNew
mv uImageNew uImage || rm -rf uImage && mv uImageNew uImage
rm backup_image.bin

( rmÈ qui per poter sfuggire meglio a uno stato strano, ad esempio se uImageè qualcosa di inaspettato che farebbe mvfallire [ma non necessariamente la ln -sfsoluzione precedente ].)


2
+1 perché questa è concettualmente una ragione molto bella, ma sfortunatamente ln -sfnon è atomica. Elimina il vecchio link simbolico e ne crea uno nuovo. Per risolvere questo problema è necessario creare un nuovo collegamento simbolico con un nome temporaneo e rename(2)( mv) per nominare quello che si desidera sostituire.
R ..

@R .. hai ragione! 😲 stat("uImage", {st_mode=S_IFREG|0777, st_size=0, ...}) unlink("uImage"),symlink("backup_image.bin", "uImage")
phk,

1
A proposito, vedi qui per la mia versione install.shche risolve il problema: git.musl-libc.org/cgit/musl/tree/tools/install.sh
R ..

@R .. Notare che mvanche con -fpotrebbe fallire se la destinazione esiste già come ad es. Un collegamento simbolico che fa parte di un ciclo di collegamento simbolico. Demo:ln -sf foo bar; ln -sf bar foo; echo "Before:"; ls -l foo bar; >testfile; mv testfile foo || { echo "Using mv -f"; mv -f testfile foo; }; echo "After:"; ls -l foo bar
phk,

3

Un uso che ho avuto per i collegamenti reali è durante il download o la decompressione di un file rotto. Il programma che esegue il download o la decompressione (come decomprimere o decomprimere) rimuoverà spesso automaticamente il file incompleto quando si verifica un errore e di solito non esiste alcuna opzione per mantenerlo. Se voglio conservare il file, posso creare un collegamento reale ad esso.


3

BackupPC è un sistema di backup che utilizza collegamenti fissi sui server per fornire la deduplicazione a livello di file.

I file vengono prima memorizzati in un albero di directory "pool" basato sul loro hash md5. Qualsiasi backup che utilizza quel file costituisce un collegamento reale al file del pool. Man mano che i backup scadono / vengono eliminati, i loro collegamenti reali vengono rimossi dal file system.

Gli hard link sono superiori ai soft link qui perché forniscono il conteggio automatico dei riferimenti. Un cron job elimina periodicamente tutti i file nella directory del pool che non hanno più di un collegamento.

Questo metodo presenta alcuni svantaggi (principalmente, che è difficile utilizzare strumenti basati su filesystem per replicare l'archivio di backup), ma ha dimostrato di essere abbastanza robusto in pratica.


Un altro caso d'uso: il server di applicazioni Web Tomcat java considera i nomi dei file come metadati. Un file "war" java deve essere nominato in base al suo percorso sul server web.

ad esempio: foo.war è il codice Java che serve l'URL/foo

Sfortunatamente, risolve i collegamenti simbolici prima di prendere questa decisione.

Quindi, supponi di voler distribuire una build dell'applicazione e assegnagli un nome file descrittivo (ad es. Con un numero di rilascio o una data). Non è possibile creare un collegamento simbolico al file con il nome "reale" - è necessario creare un collegamento reale.

foo.warcollegato a foo-20170129.warnon funziona

foo.warhardlinked to foo-20170129.warworks.

non mi piace questo comportamento da gatto, ma i collegamenti fisici mi danno un modo per aggirarlo.

Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.