Czy używasz skrzynek na twarde linki? [Zamknięte]


40

W jakich sytuacjach chciałoby się użyć twardego linku zamiast miękkiego linku? Osobiście nigdy nie spotkałem się z sytuacją, w której chciałbym użyć twardego linku zamiast miękkiego linku, a jedynym przypadkiem, z jakim się spotkałem podczas przeszukiwania sieci, jest deduplikacja identycznych plików .


4
Poniżej znajdują się dobre odpowiedzi, ale weźmy pod uwagę (historyczny) kontekst historyczny. Kiedy Unix był nowy, dyski były wolne i miały ograniczoną pojemność i buforowanie. Twardy link był po prostu kolejnym bezpośrednim wpisem w systemie plików do tego samego pliku. Nieważne, czy korzystasz z ls , czy jak go nazywasz, lista nie ma znaczenia. Jeśli uczynił z wykazu miękkiej odnośnik, jego zastosowanie wiązałoby się ze znalezieniem go w katalogu, czytając specjalny plik o nazwie list , który chcesz zobaczyć plik ls , znaleźć ls w katalogu i zapoznania się z rzeczywistą ls plik z dysku. Ogromna różnica w wydajności!
RichF

16
Cóż, pierwszy link do pliku jest naprawdę przydatny.
Stop Harming Monica,

@OrangeDog: Tak, ale potrzebujesz tylko pola liczby linków w i-węźle, jeśli chcesz obsługiwać wiele linków. (Możesz potrzebować flagi dla wersji i-węzłów w pamięci, aby obsłużyć niepołączoną, ale wciąż otwartą skrzynkę. Fsck po awarii bez kronikowania nadal musiałby szukać i-węzłów bez łączy.)
Peter Cordes

1
Semantyka katalogu POSIX musiałaby być zaprojektowana inaczej: ..jest zawsze tym samym i-węzłem jak .w katalogu nadrzędnym. Rzeczy takie findmogą sprawdzić, czy link-count = 2, aby wykryć katalogi liści i uniknąć statwprowadzania wpisów z readdir w poszukiwaniu podkatalogów. Ale to tylko niewielka funkcja włączana przez obsługę twardych dowiązań plików spoza katalogu (zwykłe, dowiązanie symboliczne, urządzenie, gniazdo i potok nazwany). (Tak, dowiązania symboliczne mają własną i-węzeł i mogą być dowiązane na stałe.)
Peter Cordes

1
Jednym z powodów używania linków twardych, których nie widziałem w mojej recenzji SO, o charakterze „globalnym”. Wyobraź sobie system plików, w którym pliki są na ogół małe (powiedzmy, krótkie notatki), ale aby utrzymać porządek, możesz potrzebować wskaźników do tego samego pliku w różnych miejscach. W przypadku dowiązań symbolicznych każdy wskaźnik używa i-węzła. W takich systemach plików może już występować problem z brakiem i-węzłów. Używanie twardych linków jako wskaźników pomaga w rozwiązaniu tego problemu. i-węzły mają ograniczoną liczbę; imiona dla nich nie są (przynajmniej nie w ten sam sposób).
mathguy,

Odpowiedzi:


27

Oprócz użycia kopii zapasowej wymienionego w innym komentarzu, który moim zdaniem obejmuje również migawki na woluminie BTRFS, przypadek użycia twardych linków nad miękkimi linkami to kolekcja plików sortowana według znaczników. (Niekoniecznie najlepsza metoda tworzenia kolekcji, metoda oparta na bazie danych jest potencjalnie lepsza, ale w przypadku prostej kolekcji, która jest względnie stabilna, nie jest tak źle).

Zbiór multimediów, w którym wszystkie pliki są przechowywane w jednym, płaskim katalogu i są sortowane w innych katalogach na podstawie różnych kryteriów, np .: roku, tematu, wykonawcy, gatunku itp. Może to być osobista kolekcja filmów lub kolektyw komercyjnego studia Prace. Zasadniczo plik został zapisany, prawdopodobnie nie będzie modyfikowany i sortowany, być może w wielu lokalizacjach według łączy.

Należy pamiętać, że pojęcia „oryginał” i „kopia” nie mają zastosowania do twardych linków: każdy link do pliku jest oryginałem, w normalnym sensie nie ma „kopii”. Jednak w opisie przypadku użycia terminy naśladują logikę zachowania.

„Oryginał” jest zapisywany w katalogu „katalog”, a posortowane „kopie” są na stałe połączone z tymi plikami. Atrybuty plików w katalogach sortowania można ustawić na r / o, zapobiegając przypadkowym zmianom nazw plików i struktury posortowanej, podczas gdy atrybuty katalogu katalogu można zmienić na r / w, umożliwiając jego modyfikację w razie potrzeby. (Przykładem mogą być pliki muzyczne, w których niektóre odtwarzacze próbują zmieniać nazwę i reorganizować pliki na podstawie znaczników osadzonych w pliku multimedialnym, z danych wprowadzonych przez użytkownika lub z Internetu). Dodatkowo, ponieważ atrybuty katalogów „kopiuj” mogą być inne niż „oryginalny” katalog, posortowana struktura może zostać udostępniona grupie lub światu z ograniczonym dostępem, podczas gdy główny „katalog” jest dostępny tylko dla głównego użytkownika, z pełnym dostępem. Same pliki jednak zawsze będą miały te same atrybuty we wszystkich linkach do tego i-węzła. (ACL można zbadać, aby to poprawić, ale nie moją dziedzinę wiedzy.)

W przypadku zmiany nazwy oryginału lub przeniesienia (na przykład pojedynczy katalog „katalog” staje się zbyt duży, aby nim zarządzać), twarde linki pozostają ważne, miękkie linki są zepsute. Jeśli „kopie” zostaną przeniesione, a miękkie linki są względne, wówczas miękkie linki ponownie zostaną zerwane, a twarde linki nie będą.

Uwaga: wydaje się, że istnieje niespójność w sposobie, w jaki różne narzędzia zgłaszają użycie dysku, gdy w grę wchodzą miękkie linki. W przypadku twardych linków wydaje się to jednak spójne. Zatem przy 100 plikach w katalogu posortowanych w zbiór „znaczników” można łatwo połączyć 500 „kopii”. (W przypadku kolekcji fotografii, powiedzmy datę, fotografa i średnio 3 tagi „tematyczne”). Na przykład Dolphin zgłosi to jako 100 plików dla twardych linków i 600 plików, jeśli zostaną użyte miękkie linki. Co ciekawe, raportuje to samo użycie miejsca na dysku w obu kierunkach, więc wygląda na dużą kolekcję małych plików dla miękkich linków i małą kolekcję dużych plików dla twardych linków.

Jedynym zastrzeżeniem dla tego rodzaju przypadków użycia jest to, że w systemach plików korzystających z COW, modyfikacja „oryginału” może przerwać twarde dowiązania, ale nie przerwać miękkich dowiązań. Ale jeśli celem jest przygotowanie kopii wzorcowej, po edycji, zapisaniu i posortowaniu COW nie wchodzi w scenariusz.


3
FYI: migawki btrfs nie są dowiązaniami stałymi. Mają różne zachowanie (np. Modyfikowanie jednej kopii nie modyfikuje drugiej). I statpokaże tylko jeden link.
derobert

@derobert Nie jestem pewien, jak działają migawki, małe dochodzenie pokazuje ciekawe rzeczy. W przypadku niezmienionych plików / katalogów statpokaż ten sam numer i-węzła, ale inny identyfikator urządzenia. Musi mieć coś wspólnego ze sposobem nałożenia podwoluminów na główny, rzadko montowany wolumin. Podejrzewam, że jeśli zamontowany statbyłby główny wolumin , pokazywałby liczbę linków równą liczbie migawek, w których przechowywana była ta wersja pliku. COW prawdopodobnie dba o modyfikację, nie wpływając na żadne inne. Zwykłe spekulacje oparte na łagodnej ciekawości, ale niewystarczająco ciekawe, by kopać głębiej.
Gypsy Spellweaver

Każde dowiązanie symboliczne ma swój własny i-węzeł, więc wykorzystuje pozycję i-węzła w systemie plików. Tradycyjne systemy plików Unix wymagają wybrania miejsca do zarezerwowania dla i-węzłów w czasie tworzenia FS, zamiast przydzielania go w razie potrzeby, tak jak robi to XFS. Jest więc znaczące, że wersja dowiązania symbolicznego zużyłaby znacznie więcej i-węzłów (nawet poza implikacjami pamięci podręcznej VFS).
Peter Cordes

23

Twarde linki są przydatne w przypadkach, gdy nie chcesz wiązać istnienia obu plików. Rozważ to:

touch a
ln -s a b
rm a

Teraz bjest bezużyteczny. (I te kroki mogą się zdarzyć dość daleko od siebie, mogą być wykonywane przez różnych ludzi itp.)

Podczas gdy z twardym linkiem

touch a
ln a b
rm a

b jest nadal obecny i poprawny.


8
@MatthewCline Chciałbyś mieć takie zachowanie podczas zarządzania wydajnymi przyrostowymi kopiami zapasowymi. Zwłaszcza po usunięciu starych kopii zapasowych w systemie tworzenia kopii zapasowych opartym na miękkim łączu należy ponownie sprawdzić i ponownie połączyć wszystkie nowsze pliki / łącza do prawidłowej bazy, podczas gdy twarde łącza wykonują to zadanie „za darmo” na poziomie i-węzła. na przykład przesunięcie czasu / czas powrotu stosuje intensywne łącza twarde.
orzechów

3
@orzechow Nie wydaje mi się, żebyś chciał mieć zachowanie twardego łącza w pobliżu swojego systemu kopii zapasowych. github.com/bit-team/backintime/wiki/… backintime nierozsądnie zakłada, że ​​wszystkie zmiany w plikach będą dokonywane w cyklu usuwania-usuwania, a nie aktualizacji.
DepressedDaniel

10
Twarde linki @DepressedDaniel są w porządku w systemie tworzenia kopii zapasowych, po prostu nie chcesz, aby kopie zapasowe były na stałe połączone z plikami na żywo. W każdym razie kopia zapasowa nigdy nie powinna być dostępna bezpośrednio z systemu na żywo ...
Stephen Kitt

1
To nie jest odpowiedź - w szczególności nie jest to przypadek użycia. To tylko demonstracja zachowania twardych linków.
user394

1
@ ThomasPadron-McCarthy to nieporozumienie. BiT używa tylko twardych łączy do łączenia identycznych plików w różnych migawkach. NIE są one powiązane z oryginalnym plikiem! (Jestem biT Dev)
Germar

11

Pojedynczy program może zmienić swoje zachowanie w zależności od nazwy uruchomionej jako:

$ 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

Które w źródle decyduje się przez coś takiego

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

jednak dokładne szczegóły będą się różnić w zależności od systemu operacyjnego i języka.

Pozwala to (w większości) na identyczny kod, aby nie trzeba było go kompilować do dwóch (głównie) identycznych plików binarnych. Należy pamiętać, że unix datuje się na dni, kiedy miejsce na dysku było bardzo drogie, choć według Stevensa w APUE rozdział 4 dowiązania symboliczne zostały zaimplementowane w BSD4.2 (1983) w celu zastąpienia różnych ograniczeń dowiązań twardych. Program testowy, aby sprawdzić, czy nazwa dowiązania symbolicznego jest używana jako nazwa programu, może wyglądać mniej więcej tak:

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

I przetestowane przez:

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

4
Ale czy zwykle nie jest to obsługiwane za pomocą softlinków?
Matthew Cline

1
@MatthewCline może być dzisiaj, ale dowiązania symboliczne nie istniały przed 4.2BSD (1983) według Stevensa w APUE.
thrig

4
@ thrig, pytanie konkretnie dotyczy przypadków użycia, których nie można zrealizować za pomocą dowiązań symbolicznych lub przynajmniej są one preferowane zamiast używania dowiązań symbolicznych. Twoja odpowiedź dotyczy zarówno HL, jak i SL.
Marcelo

3
BusyBox maksymalizuje to.
Max Ried

8

Kiedy moje oprogramowanie P2P kończy pobieranie określonego pliku, plik jest umieszczany w określonym katalogu. Pobrane pliki prawie nigdy nie wymagają edycji. Często zdarza się, że tworzę dowiązanie twarde w innym katalogu, w którym powinien znajdować się plik.

Zalety:

  • Nadal udostępniam plik w sieci P2P tak, jak powinienem, nawet jeśli ja rmlub mv„kopia”.
  • Plik znajduje się również na ścieżce, w której go potrzebuję; większość takich lokalizacji nie jest udostępniana.
  • Mogę rm„oryginał”, aby zatrzymać udostępnianie pliku; ta operacja nie wpływa na „kopiowanie” w żądanym miejscu.
  • Moje miejsce na dysku jest używane tylko raz.

Główny punkt: gdybym wiedział z góry, który plik chciałbym rmnajpierw, mógłbym przejść do dowiązania symbolicznego. Ale ja nigdy nie wiem.


6

Systemy plików to prosty, a jednocześnie skuteczny sposób organizowania i klasyfikowania plików (jest to ich główny powód istnienia). Linki twarde pozwalają na większą elastyczność w tej kwestii.

Jak wspomniano, nie ma koncepcji oryginału i kopii w przypadku twardych dowiązań, wszystkie pozycje katalogu (dowiązania twarde) są po prostu odniesieniami do istnienia pliku (wskazują na jego i-węzeł) bez pierwszeństwa, dlatego też nie ma żadnych uszkodzonych dowiązań twardych. .

Oto kilka przypadków użycia, w których występują twarde linki, ale miękkie linki nie :

  1. Wyobraź sobie, że masz kolekcję filmów, muzyki lub innych mediów i chcesz zastosować inne kryteria klasyfikacji, na przykład utwory sklasyfikowane przez artystę w oddziale (każdy artysta ma własny podkatalog); według gatunku w innej gałęzi (każdy w innym podkatalogu) itp. Nadal nie chcesz duplikować plików ani decydować, gdzie umieścić „oryginał”, abyś miał swobodę przeklasyfikowania bez konieczności „ zarządzaj ”i ponownie łącz pliki podczas przenoszenia, aby uniknąć niedziałających łączy.

  2. Innym powodem jest uniknięcie marnotrawstwa przestrzeni dyskowej, która byłaby wymagana do posiadania wielu kopii tego samego pliku, a jednocześnie pozwoliła chrootsystemowi korzystać z podzbioru plików w katalogu głównym „głównego” systemu plików (dowiązania symboliczne nigdy nie mogłyby odwoływać się do plików z zewnątrz) chrootpiaskownicy, nawet jeśli mają one ścieżek względnych).

  3. Innym bardzo ważnym, ale rzadko wymienianym powodem istnienia linków twardych są ..podkatalogi. Te ..katalogi faktycznie są (w większości UNIX fs implementacje) hardlinki do katalogu nadrzędnego, bez hardlinki to musi być realizowane w zupełnie inny sposób, podczas gdy istnienie hardlinki sprawia, że to bardzo łatwe do wdrożenia.


1
W przypadku punktu 1 alternatywnym rozwiązaniem jest użycie UUID jako „kanonicznej” nazwy plików i uczynienie wszystkich czytelnych dla człowieka symbolicznych łączy z UUID.
R ..

Chociaż sugestie dotyczące uuidów brzmią naukowo poprawnie, używanie uuidów w nazwach plików nie wydaje się zbyt praktyczne, i znowu, celem jest uproszczenie rzeczy, a nie uczynienie ich trudniejszymi lub „mniej zrozumiałymi dla człowieka”. Poza tym posiadanie uudis dla „kanonicznego” odwołania do pliku byłoby tylko dodatkową pośrednią zmianą w stosunku do rzeczywistego i-węzła pliku, więc nie ma sensu, aby osiągnąć to podejście, ponieważ nie ma ono żadnych zalet, tylko wady takie jak: wpływ na wydajność, dodatkowe miejsce na dysku do przechowywania większej liczby pozycji katalogu, z mnóstwem plików o „dziwnych” nazwach wokół ...
Marcelo

5

Bardzo powszechny przykład w świecie rzeczywistym, który wymaga linków:

git clone --reference <repository>

To klonuje z lokalnego repozytorium Git z niemal zerowym kopiowaniem. Zamiast kopiować pliki obiektowe (niezmienne pliki używane przez Git do „bazy danych”), po prostu łączy je na stałe.

Każde repo może usunąć obiekt, ale i-węzeł pozostaje ważny przez resztę repo. A jeśli obiekt zostanie usunięty ze wszystkich repozytoriów, zostanie usunięty z dysku. Twarde linki tworzą wyjątkowo solidne i szybkie rozwiązanie. Bardzo często na serwerach CI.


Istnieje wersja non-hard-link: git clone --shared <repository>. Jest to jednak kapryśne i ma o wiele więcej zastrzeżeń, ponieważ wszyscy pracują nad tym samym katalogiem.


4

Niedawno miałem przypadek użycia nieco bezpiecznej procedury aktualizacji dla systemów opartych na U-Boot, gdzie uImagejest miękkie łącze wskazujące obraz do uruchomienia, pomysł polegał na tym, że przerwa w zasilaniu nie powinna powodować problemów, bez względu na to, w którym momencie proces się dzieje (zakładając, że system plików gra razem):

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

// replace image.bin

ln -sf image.bin uImage
rm backup_image.bin

Bez linków nie byłoby to takie proste.

/edytować:

Dzięki komentarzom wiem teraz, że lepiej byłoby zrobić:

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

( rmJest tutaj, aby móc lepiej uciec od dziwnego stanu, np. Jeśli uImagejest to coś nieoczekiwanego, co spowodowałoby mvniepowodzenie [ale niekoniecznie poprzednie ln -sfrozwiązanie]).


2
+1, ponieważ jest to koncepcyjnie bardzo fajny powód, ale niestety ln -sfnie jest atomowy. Usuwa stare dowiązanie symboliczne i tworzy nowe. W tym celu trzeba dokonać nowego dowiązania z tymczasową nazwą naprawić i rename(2)( mv) jej nazwa, którą chcesz zastąpić.
R ..

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

1
BTW, zobacz tutaj moją wersję, install.shktóra rozwiązuje problem: git.musl-libc.org/cgit/musl/tree/tools/install.sh
R ..

@R .. Zauważ, że mvnawet z -fmoże się nie powieść, jeśli miejsce docelowe już istnieje jako np. Dowiązanie symboliczne, które jest częścią pętli dowiązania symbolicznego. 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

Jednym z moich zastosowań twardych linków jest pobieranie lub dekompresowanie uszkodzonego pliku. Program, który pobiera lub rozpakowuje (np. Rozpakuj lub rozpakuj) często automatycznie usuwa niekompletny plik, gdy napotka błąd, i zwykle nie ma opcji, aby go zatrzymać. Jeśli chcę zachować plik, mogę utworzyć twardy link do niego.


3

BackupPC to system tworzenia kopii zapasowych, który wykorzystuje twarde łącza na serwerach w celu zapewnienia deduplikacji na poziomie plików.

Pliki są najpierw przechowywane w drzewie katalogów „pula” na podstawie ich skrótu md5. Każda kopia zapasowa, która korzysta z tego pliku, tworzy stałe łącze do pliku puli. Gdy kopie zapasowe wygasają / są usuwane, ich twarde łącza są usuwane z systemu plików.

Linki twarde są lepsze od linków miękkich, ponieważ zapewniają automatyczne zliczanie referencji. Zadanie cron okresowo usuwa wszystkie pliki w katalogu puli, które nie mają więcej niż jednego łącza.

Ta metoda ma pewne wady (przede wszystkim trudność w użyciu narzędzi opartych na systemie plików do replikacji magazynu kopii zapasowych), ale w praktyce okazała się dość solidna.


Kolejny przypadek użycia: serwer aplikacji WWW tomcat java traktuje nazwy plików jako metadane. Plik „wojny” java musi zostać nazwany na podstawie ścieżki na serwerze WWW.

np .: foo.war jest kodem Java, który obsługuje adres URL/foo

Niestety rozwiązuje dowiązania symboliczne przed podjęciem tej decyzji.

Powiedzmy, że chcesz wdrożyć kompilację aplikacji i nadaj jej opisową nazwę pliku (np. Z numerem lub datą wydania). Nie możesz utworzyć dowiązania symbolicznego do pliku o „prawdziwej” nazwie - musisz utworzyć dowiązanie stałe.

foo.wardowiązanie symboliczne do foo-20170129.warnie działa

foo.warhardlinkowane do foo-20170129.warutworów.

Nie podoba mi się to zachowanie kocurów, ale linki dające mi do obejścia.

Korzystając z naszej strony potwierdzasz, że przeczytałeś(-aś) i rozumiesz nasze zasady używania plików cookie i zasady ochrony prywatności.
Licensed under cc by-sa 3.0 with attribution required.