What is: что такое symlink, hard link и inode в Linux?

Автор: | 08/13/2013
 

В Linux hardlink — «жёсткая ссылка». По сути — является тем же файлом, на который ссылается, в отличии от symlink-а — «мягкой ссылки».

Проще всего это объяснить используя inode — «индексный дескриптор«.

inode

inode — это объект файловой системы, содержащий информацию о владельце/группе, которым принадлежит файл или каталог, его права доступа к нему, его размер, тип файла, timestamp-ы отражающие время модификации индексного дескриптора (ctime, changing time), время модификации содержимого файла (mtime, modification time) и время последнего доступа к файлу (atime, access time) и счётчик для учёта количества жёстких ссылок на файл. Каждый inode имеет собственный номер, который присваевается ему файловой системой в момент её создания (форматирования).

Для примера возьмём описание файлов, где с помощью ключа -i команды ls вместо  отобразим их «номер» inode:

ls -lih | grep file
475949 -rw-r--r--  1 root     setevoy     0B Aug 13 11:51 file1
475950 -rw-r--r--  1 root     setevoy     0B Aug 13 11:51 file2
475951 -rw-r--r--  1 root     setevoy     0B Aug 13 11:51 file3

Первая колонка как раз и отображает номер inode. Далее указываются права доступа, счётчик hardlink-ов на этот файл, права доступа и тип файла, пользователь, группа, размер, дата последней модификации файла и последним — его имя.

Inodes и ошибка “No Space Left on Device”

Немного не по общей теме поста, но полезно знать.

Иногда может возникнуть «странная» ситуация: с одной стороны — df или du будут говорить, что свободное место на диске есть, а с другой стороны операционная система будет уверждать, что “No Space Left on Device”.

Одна из вероятных причин как раз явлется полное использование пула inode, выделенных для раздела на жёстком диске, т.к. кол-во inode фиксировано и задаётся во время создания таблицы раздела.

Проверить общее, занятое и доступное количество inode можно с помощью df и опции -i:

df -i /dev/sdb4
Filesystem      Inodes IUsed   IFree IUse% Mounted on
dev            2042653   523 2042130    1% /dev

Тут для раздела /dev/sdb4 создано 2.042.653 inode, и это же является ограничением на количество файлов и директорий, которые можно будет создать на этом разделе (но есть ещё ограничения самой файловой системы, см Linux: файловые системы — краткий обзор и сравнение).

Hard link

Вернёмся к рассмотрению того, что же такое hardlink.

По сути, «жесткая» ссылка — это тот же самый файл, на который идёт такая «ссылка». Что бы продемонстрировать это — создадим такую ссылку при помощи команды ln. Синтаксис команды:

ln целевой_файл файл_ссылка

Пример — создадим файл-ссылку с именем hardlink1, которая будет указывать на уже существующий файл file1:

ln file1 hardlink1

Что бы убедиться, что по сути оба файла являются одним и тем же объектом файловой системы — сравним их inode-номер, в данном случае — это номер 475949:

ls -lih | grep 475949
475949 -rw-r--r--  2 root     setevoy     0B Aug 13 11:51 file1
475949 -rw-r--r--  2 root     setevoy     0B Aug 13 11:51 hardlink1

Как видим — оба файла с разными именами, но имеют общий inode. Добавим ещё одну ссылку — и посмотрим на счётчик жестких ссылок:

ln file1 hardlink2
ls -lih | grep 475949
475949 -rw-r--r--  3 root     setevoy     0B Aug 13 11:51 file1
475949 -rw-r--r--  3 root     setevoy     0B Aug 13 11:51 hardlink1
475949 -rw-r--r--  3 root     setevoy     0B Aug 13 11:51 hardlink2

Счётчик вместо 2 теперь отображает 3.

Правильнее было бы называть его не «счётчик ссылок» — а «счётчик имён файла», так как по сути один файл хранится с разными именами.

Symlink

Перейдём к symlink-ам. Создаётся такая ссылка с помощью той же команды ln но с ключём -s:

ln -s file1 symlink1

Мы создаём новый (!) объект файловой системы с именем symlink1, который указывает на уже существующий файл file1:

ls -lih | grep sym
475948 lrwxr-xr-x  1 root     setevoy     5B Aug 13 12:02 symlink1 -> file1

Обратите внимание на тип (или атрибут), указанный буквой l перед правами доступа к файлу — в данном случае он указывает на то, что этот файл является символической ссылкой на другой файл. То же самое отображается и в его имени — symlink1 -> file1.

Основные типы файлов, которые отображаются командой ls:

  • -: обычный файл
  • d: каталог
  • l: символическая ссылка
  • s: сокет

Теперь — сравним inode-номера обоих файлов:

ls -li
...
475949 -rw-r--r--  3 root     setevoy       0 Aug 13 11:51 file1
...
475949 -rw-r--r--  3 root     setevoy       0 Aug 13 11:51 hardlink1
475949 -rw-r--r--  3 root     setevoy       0 Aug 13 11:51 hardlink2
...
475948 lrwxr-xr-x  1 root     setevoy       5 Aug 13 12:02 symlink1 -> file1

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

Hard link vs symlink – ключевые различия

Тепреь кратко рассмотрим основные раззличия при работе с жёсткими и «мягкими» ссылками:

  • hardlink не может указывать на файл в другой файловой системе (так как inode может принадлежать только одной ФС), а symlink — может.
  • рри редактировании файла-ссылки в случае с hardlink-ом — изменятся оба файла, так как это один и тот же объект, а в случае с symlink-а  — можно изменять его имя, атрибуты, направить его на другой файл и при этом оригинальный файл не будет затронут (но учтите, что если вы откроете файл симлинка для редактирования — то измените оригинальный файл, т.к. по сути вы откроете для редактирования именно его)
  • жёсткая ссылка не может указывать на на каталог (см. причины тут>>>)

Удаление ссылок

При удалении hardlink-а — файл будет существовать до тех пор, пока есть хотя бы 1 hardlink на него, но может «менять каталог размещения», если был удалён «исходный» файл, но остался файл-hardlink в другом месте. При удалении же файла, на который указывает symlink — файл-ссылка просто станет нерабочим.

Например — удалим файл file1, на который у нас есть символическая ссылка symlink1:

rm file1

При этом сам файл симлинка остался:

ls -la | grep file1
lrwxr-xr-x   1 root     setevoy       5 Aug 13 12:02 symlink1 -> file1

Но при попытке получить информацию о file1 — получим сообщение об ошибке:

file file1
file1: cannot open `file1' (No such file or directory)
file symlink1
symlink1: broken symbolic link to `file1'

В целом — на этом всё.