Как Linux работает с символическими ссылками?

11

Я имею в виду, что происходит, когда какой-то процесс хочет прочитать символическую ссылку? Что происходит, когда что-то меняет символическую ссылку в процессе чтения или даже записи?

Например: у меня есть 2 огромных, похожих файла 100G /mnt/1и /mnt/2. /mnt/1доступно через символическую ссылку /home/user/file. Некоторая программа Aначинает читать /home/user/file. И через некоторое время что-то меняет ссылку с /mnt/1на /mnt/2, но Aвсе равно читает файл.

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

Будет ли сбой и ошибка, потому что символическая ссылка была изменена или будет работать нормально, как будто ничего не произошло?

Будет ли он отличаться в случае, если /home/user/fileон связан с блочным устройством (например, 2 реплицированных диска iscsi)?

порыв
источник

Ответы:

9

Символьная ссылка указывает на имя реального файла ( inode ) в файловой системе. Когда система разрешает эту символическую ссылку, чтобы найти фактический файл и открыть его, она находит и использует индекс файла. На этом этапе путь к файлу, который вы использовали, не имеет значения. То, что ОС не кэширует, она читает из файла по его индексу. Вы можете, как я понимаю, начать чтение файла через жесткую ссылку и удалить эту жесткую ссылку (если файл все еще связан откуда-то еще) , и это не вызовет проблем, пока файл будет разрешен ( имя строка-> индекс).

Kevin
источник
4
Вы можете удалить ВСЕ ссылки на файл и продолжать читать его, как только он откроется. Вот почему вы можете обновить пакеты без перезагрузки, как в Windows; потому что вы можете запустить исполняемый файл программы, даже если он запущен.
psusi
1
@psusi Я знаю, что данные и inode все еще там и просто не указаны, но как только файл будет удален, система сможет перезаписать это место на диске, верно? Так что, если файл слишком велик, чтобы поместиться в файловый кеш, например, файлы размером 100 ГБ, что произойдет, если часть из них будет перезаписана до того, как вы доберетесь до конца? Это не относится к критическим системным файлам, потому что они загружаются в кэш и хранятся там, но 100 ГБ достаточно велики, так что я думаю, что это может быть проблемой.
Кевин
2
Кевин, файлы не удалялись с диска до тех пор, пока не умирает последний процесс, использующий файл. Вы всегда можете найти все файлы, которые в данный момент используются в proc. Но ваш ответ, кажется, объяснил мой вопрос. Спасибо.
Раш
2
В этом ответе пропущен критический момент: символическая ссылка содержит имя целевого файла.
Кит Томпсон
6

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

Когда вы открываете символическую ссылку, ОС будет следовать местоположению, чтобы найти целевой файл. Если цель сама является символической ссылкой, она также следует своему расположению (1) (2), пока местоположение не укажет на файл, который не является символической ссылкой (назовем его FinalFile ). Затем операционная система получает инод в FinalFile (индексный дескриптор содержит метаданные , как изменения времени и имеет также указатель на данные файла). Наконец открывается индекс FinalFile . Отныне процесс использует этот индекс для чтения / записи в файл. В результате изменение имени или пути символической ссылки, удаление символической ссылки, изменение пути или имени FinalFile или даже удаление FinalFile(3) не влияет на процесс; это все еще читает из того же самого inode.

В большинстве случаев операции с данными файла над символической ссылкой будут влиять на FinalFile (например, чтение и запись в символическую ссылку будут считывать / записывать в FinalFile ), но существуют исключения: readlink()системный вызов считывает содержимое самой символической ссылки.

С другой стороны, операции с метаданными файла (например, переименование или удаление) обычно влияют на символическую ссылку. Но здесь есть и исключения: lstat()системный вызов похож stat(), за исключением того, что он возвращает информацию о самой символической ссылке, а не о FinalFile (2).


(1) Существует ограничение на количество уровней, и все становится немного сложнее, если местоположение в символической ссылке является относительным путем.

(2) Прочитайте символическую ссылку (7): обработка символьных ссылок для более подробной информации.man 7 symlink

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

Кит Томпсон
источник
1

Это почти прозрачно для Linux, и оно гораздо больше связано с используемой файловой системой, чем с операционной системой.

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

Разница в символической ссылке на жесткую ссылку заключается в том, что назначение - это жесткая ссылка, а не привязка к секторам данных, как это делает жесткая ссылка.

Пример:

Тест 1:

echo 'data' >file.txt

Это создаст жесткую ссылку file.txt, указывающую на сектора от 10 до 20 * (* цифры только для пояснения).

Тест 2:

Что теперь, если?

ln file.txt file_2.txt

Это создало hardlink file_2.txt, указывающий на секторы с 10 по 20 (то же самое, что и у file.txt), поэтому, если вы удалите file.txt, сектора с 10 по 20 все еще зарезервированы, и вы сможете увидеть данные внутри file_2.txt ... , (file.txt и file_2.txt похожи на оригиналы)

Тест 3:

ln -s file.txt file_sym.txt 

Указанная символическая ссылка file_sym.txt на жесткую ссылку file.txt, поэтому при попытке доступа к file_sym.txt вы увидите file.txt, но если вы удалите file.txt, file_sym больше не найдет цель.

Они управляются файловой системой, например, модулями ext4 для linux (или если она скомпилирована в ядре), не имеет значения, используете ли вы Linux или другой Unix.

Лучано Андресс Мартини
источник