Почему жесткие ссылки не разрешены для каталогов?

Я использую Ubuntu 12.04. Когда я пытаюсь создать жесткую ссылку для любой директории, она не работает. Я могу создать жесткие ссылки для файлов внутри границы файловой системы. Я знаю причину, по которой мы не можем создавать жесткие ссылки для файлов за пределами файловой системы.

Я попробовал эти команды:

$ ln /Some/Direcoty /home/nischay/Hard-Directory
hard link not allowed for directory
$ sudo ln /Some/Direcoty /home/nischay/Hard-Directory
[sudo] password for nischay: 
hard link not allowed for directory

Я просто хочу знать причину этого. Это одинаково для всех дистрибутивов GNU/Linux и Unix (BSD, Solaris, HP-UX, IBM AIX) или только в Ubuntu или Linux?

6 ответов

Решение

Жесткие ссылки на каталоги нарушают файловую систему несколькими способами

Они позволяют создавать петли

Жесткая ссылка на каталог может ссылаться на самого родителя, который создает цикл файловой системы. Например, эти команды могут создать цикл с обратной ссылкой l:

mkdir -p /tmp/a/b
cd /tmp/a/b
ln -d /tmp/a l

Файловая система с циклом каталогов имеет бесконечную глубину:

cd /tmp/a/b/l/b/l/b/l/b/l/b

Избегать бесконечного цикла при обходе такой структуры каталогов довольно сложно (хотя, например, POSIX требует find чтобы избежать этого).

Файловая система с такой жесткой ссылкой больше не является деревом, потому что дерево по определению не должно содержать цикл.

Они нарушают однозначность родительских каталогов

В цикле файловой системы существует несколько родительских каталогов:

cd /tmp/a/b
cd /tmp/a/b/l/b

В первом случае /tmp/a является родительским каталогом /tmp/a/b,
Во втором случае /tmp/a/b/l является родительским каталогом /tmp/a/b/l/b, который так же, как /tmp/a/b,
Таким образом, у него есть два родительских каталога.

Они умножают файлы

Файлы идентифицируются путями после разрешения символических ссылок. Так

/tmp/a/b/foo.txt
/tmp/a/b/l/b/foo.txt

это разные файлы.
Существует бесконечно много дальнейших путей к файлу. Конечно, они одинаковы по количеству инодов. Но если вы явно не ожидаете циклов, нет причин проверять это.

Жесткая ссылка на каталог также может указывать на дочерний каталог или каталог, который не является ни дочерним, ни родительским. В этом случае файл, являющийся дочерним по отношению к ссылке, будет реплицирован на два файла, идентифицированных двумя путями.

Ваш пример

$ ln /Some/Direcoty /home/nischay/Hard-Directory
$ echo foo > /home/nischay/Hard-Directory/foobar.txt
$ diff -s /Some/Direcoty/foobar.txt /home/nischay/Hard-Directory/foobar.txt
$ echo bar >> /Some/Direcoty/foobar.txt
$ diff -s /Some/Direcoty/foobar.txt /home/nischay/Hard-Directory/foobar.txt
$ cat /Some/Direcoty/foobar.txt
foo
bar

Как тогда могут работать мягкие ссылки на каталоги?

Путь, который может содержать программные ссылки и даже программно-связанные циклы каталогов, часто используется только для идентификации и открытия файла. Его можно использовать как обычный линейный путь.

Но есть и другие ситуации, когда для сравнения файлов используются пути. В этом случае символические ссылки в пути могут быть разрешены в первую очередь, преобразуя его в минимальное и обычно согласованное представление, создавая канонический путь:

Это возможно, потому что все программные ссылки могут быть расширены до путей без ссылки. После этого со всеми мягкими ссылками в пути, оставшийся путь является частью дерева, где путь всегда однозначен.

Команда readlink Можно найти путь к своему каноническому пути:

$ readlink -f /some/symlinked/path

Мягкие ссылки отличаются от того, что использует файловая система

Мягкая ссылка не может вызвать все проблемы, потому что она отличается от ссылок внутри файловой системы. Его можно отличить от жестких ссылок и при необходимости разрешить по пути без символических ссылок.
В некотором смысле добавление символических ссылок не меняет основную структуру файловой системы - она ​​сохраняет ее, но добавляет дополнительную структуру, например уровень приложения.


От man readlink:

 NAME
        readlink - print resolved symbolic links or canonical
        file names

 SYNOPSIS
        readlink [OPTION]... FILE...

 DESCRIPTION
        Print value of a symbolic link or canonical file name

        -f, --canonicalize
               canonicalize by  following  every  symlink  in
               every component of the given name recursively;
               all but the last component must exist
        [  ...  ]

"Вы вообще не должны использовать жесткие ссылки в любом случае" - это слишком широко. Вы должны понимать разницу между жесткими ссылками и символическими ссылками и использовать их по мере необходимости. Каждый из них имеет свои преимущества и недостатки:

Симлинки могут:

  • Указать на каталоги
  • Указывать на несуществующие объекты
  • Укажите файлы и каталоги вне одной и той же файловой системы

Жесткие ссылки могут:

  • Сохранить файл, на который они ссылаются, от удаления

Жесткие ссылки особенно полезны при выполнении приложений "копирование при записи". Они позволяют сохранять резервную копию структуры каталогов, используя только пространство для файлов, которые меняются между двумя версиями.

Команда cp -al Особенно полезно в этом отношении. Он создает полную копию структуры каталогов, где все файлы представлены жесткими ссылками на исходные файлы. Затем вы можете приступить к обновлению файлов в структуре, и только файлы, которые вы обновите, займут дополнительное пространство. Это особенно полезно при сохранении резервных копий нескольких поколений.

К вашему сведению, вы можете добиться того же, что и жесткие ссылки для каталогов, используя mount:

mount -t bind /var/www /home/user/workspace/www

Это очень опасно, потому что большинство инструментов и программ не будут знать о привязке. Однажды я сделал что-то подобное в приведенном выше примере, а затем приступил к rm -rf /home/user, К счастью, в /var/www,

Причина, по которой жесткие ссылки на каталоги не разрешены, является немного технической. По сути, они нарушают структуру файловой системы. Как правило, вы не должны использовать жесткие ссылки в любом случае. Символьные ссылки обеспечивают большую часть той же функциональности, не вызывая проблем (например, ln -s target link).

Это не будет жесткая ссылка.

Каталог, по сути, представляет собой набор индексных дескрипторов, указывающих на блоки данных родительского каталога, самого каталога,.(ради подкаталогов/дочерних каталогов, имеющих его в качестве супер/родительского каталога), дочерних каталогов и файлов.

Жесткие ссылки не должны изменять данные в блоках данных, которые индексирует индексный дескриптор.

Жесткая ссылка на каталог либо должна была бы добавить другой родительский каталог (другой) inode, тем самым нарушив вышеприведенное правило (жесткие ссылки не должны изменять блок данных, проиндексированный связанным с inode), либо она должна вызвать жесткую связанный каталог, чтобы он отличался от исходного каталога (у него будет индексный дескриптор родительского каталога, который не является очевидным родительским каталогом с точки зрения пользователя).

Уточнение

Скажем, у вас есть каталог dir-1a в качестве родительского каталога. Затем вы жестко связали его внутри одного из дочерних каталогов, dir-1b , но не добавили второй..в связанный каталог (поскольку это изменит блок данных).

Теперь, если вы посмотрите на жесткую ссылку в каталоге dir-1b, он будет иметь родительский каталог, который не является каталогом dir-1b, а является корневым./. Это означает, что вы можете определить, какая ссылка является жесткой, а какая — исходной.

Жесткие ссылки не предназначены для того, чтобы их можно было отличить от оригиналов.

Это событие окажет негативное влияние на процессы, которые ожидают, что жесткие ссылки не будут отличимы от исходных файлов. Каталоги разработаны так, чтобы содержать индексные дескрипторы для себя и для каталога их жесткой ссылки (родительские каталоги).

Другие ответы здесь хороши, но вот простая практическая причина. Допустим, у вас есть каталог с именем, в котором есть несколько файлов и подкаталогов, например:

  • Фред/Барни/Вильма
  • Фред/Бетти

Теперь вы создаете жесткую ссылку на именованный файл . Затем вы выполняетеrm -rf fred. Затем вы попробуйтеcd homer/barney/wilmaтолько для того, чтобы сказать, что этого не существует. Затем вы пытаетесь открыть , и это тоже пропало! На самом деле совершенно пусто!

Почему? Ну, что же делать? Он удаляет не только каталог, но и его содержимое. Итак, первое, что он делает, это удаляетfred/barney/wilma, затем он удаляетfred/barney, а затем он удаляетfred/betty. Поскольку и являются двумя именами одного и того же объекта, можно сказать иначе: он удаляетhomer/barney/wilma, затемhomer/barney, затемhomer/betty. Удаление содержимого означает удаление содержимогоhomer.

Почемуrm -rfудалить все такие файлы? Представьте, что произойдет, еслиfred не было жесткой ссылки до того, как вы ее удалили. Затем файлыbarney/wilmaиbettyстанут потерянными и займут место, и их невозможно будет удалить, кроме как запустить инструмент очистки файловой системы, который ищет потерянные файлы.

Теперь версия с поддержкой жестких ссылокrmможно написать, что не удаляет содержимое каталога, если существует жесткая ссылка на этот каталог, но вам также необходимо убедиться, что любая другая программа, которая может удалять каталоги, поддерживает жесткую ссылку. Я думаю, что это ждет катастрофа, а польза от нее весьма сомнительна. Это также означает, что жесткие ссылки больше не работают так, как в стандартной файловой системе Unix.

Другие вопросы по тегам