Я выполнил следующие команды в указанном порядке:
$ln a b
$ls -i a b
523669 a 523669 b
$rm -f a
$ls -i b
523669 b
Из этого теста я пришел к выводу, что команда rm
фактически удаляет только имя файла ( a
в этом тесте), а не файл, так как индекс все еще существует и может быть получен через другое имя файла ( b
).
Мой вопрос заключается в том, что если файл жестко связан только с одним именем файла, то, когда rm
файл исполняется, полностью ли удален реальный файл (т. Е. Индекс)? И если нет, можно ли получить файловый индекс без имени файла и только через этот индекс?
Ответы:
Если вы попытаетесь открыть файл через его inode, это обойдет любой обход каталога. Обратный путь в каталогах необходим для определения прав доступа к файлу и каталогам, ведущим к нему. Без обхода каталога ядро не может определить, разрешено ли вызывающему процессу доступ к файлу.
Был предложен патч для ядра Linux, позволяющий создать ссылку на файл из файлового дескриптора . Он был отвергнут, потому что это было бы крайне сложно осуществить .
В Linux (и, вероятно, в других вариантах Unix по той же причине) вы не можете создать ссылку на удаленный файл, поэтому, если у файла больше нет имени, вы не можете повторно добавить его. Вы можете открыть удаленный файл, открыв магические ссылки под
/proc/$pid/fd/
.Если у файла больше нет ссылки и он больше не открыт, он больше не существует, и пространство, ранее использовавшееся его данными, может быть восстановлено в любое время.
May Вы можете сделать это, поворачивая байты непосредственно в файловой системе зависимым от файловой системы способом, например, с помощью
debugfs
для ext2 / ext3 / ext4. Для этого требуется доступ к устройству, на котором смонтирована файловая система (т. Е., Как правило, это может сделать только root). Однако, хотя debugfs может обращаться к файлу по inode, это не поможет, если файл будет удален: файл будет действительно удален, если приложение закроет его, и запуск debugfs в режиме чтения-записи в смонтированной файловой системе является рецептом для стихийное бедствие.источник
В Linux
debugfs
интерактивный отладчик файловой системы ext2 / ext3 / ext4 предоставляетln
команду, которая может взять номер индексаfilespec
и создать новую жесткую ссылку на соответствующий файл. Однако на практике это требует, чтобы несвязанный файл оставался открытым процессом , поддерживая дескриптор открытого файла в/proc/[pid]/fd/[n]
. Попытка сделать это для удаленного файла, скорее всего, приведет к повреждению файловой системы.Это связано с тем, что для того, чтобы ext3 (и в расширении ext4) могли безопасно возобновить отключение после сбоя, он фактически обнуляет указатели блоков в inode , тогда как ext2 просто помечает эти блоки как неиспользуемые в растровых изображениях блоков и отмечает inode как "удалено" и оставляет указатели блока в покое. Тем не менее, поскольку файловая система должна быть смонтирована для чтения-записи, чтобы создать жесткую ссылку, блоки, зарезервированные для удаленного файла, возможно, уже были перераспределены.
До версии ядра 2.6.39 раньше использовалась опция, представленная в GNU coreutils v8.0 , для восстановления несвязанного файла с помощью дескриптора открытого файла, если и несвязанный файл, и новый hardlink находились в файловой системе tmpfs . Эта возможность была с тех пор отключена , в связи, как и Жиль отметил, соображения безопасности , связанные с позволяя создавать жесткую ссылку непосредственно из файлового дескриптора.
ln
-L|--logical
/proc/[pid]/fd/[n]
источник
ln -L
для восстановления удаленного файла из / proc и получил ошибку: «Нет такого файла или каталога», так что я не думаю, что на самом деле это поддерживает. У меня есть coreutils 8.21.ln -L
не делает то, что вы говорите, это делает. Это говоритln
о том, что если источник является символической ссылкой, он должен жестко связать цель. Символические ссылки внутри/proc/$pid/fd
являются специальными, и жесткая(deleted)
ссылка не работает.debugfs
не поможет, если файл был удален - если только вы не рискуете запустить его в режиме чтения-записи на смонтированной файловой системе, которая, вероятно, полностью искажает всю файловую систему.ln -L
. Раньше было возможно создать жесткие ссылки,/proc/[pid]/fd/[n]
используя его в определенных особых обстоятельствах, но с тех пор это было исправлено.debugfs
«sln
действительно низкий уровень и создает только имя, не обновляет счетчик и не снимает выделение блоков как неиспользуемые , так что это очень опасно . Предпочитаюdebugfs
,undel
что все это. Внимание:debugfs
это не будет работать на смонтированной файловой системе , если вы не хотите , чтобы принять шанс на обжечь FS в пепел.Команды 'ln' и 'rm' работали точно так же в каждой файловой системе UNIX с начала 1970-х годов. Mac OSX, BSD и Linux все наследуют этот оригинальный дизайн.
Сам по себе файл UNIX не имеет имени, только номер инода или inum. Но вы можете получить к нему доступ только через запись в специальном файле «directory», который связывает имя с рассматриваемым inum; Вы не можете указать Inum напрямую.
Каталог сам по себе является файлом, поэтому вы также должны обращаться к нему через (другой) каталог и т. Д. Через серию имен каталогов, разделенных прямой косой чертой (/), известной как «имя пути». Путь начинается в «текущем рабочем каталоге» процесса, если только имя не начинается с «/», в этом случае он начинается с корневого каталога файловой системы. Например, если имя пути не содержит символов "/", то ожидается, что это будет запись в текущем каталоге.
Файл без каталога может иметь любое количество имен путей, известных как «жесткие ссылки», и он будет существовать до тех пор, пока все его пути не будут удалены, и последний процесс не закроет файл. Затем файл фактически удаляется, а его пространство помечается как доступное для повторного использования. То есть вы можете создать () или открыть () односвязный файл, а затем отсоединить () его, чтобы он больше не появлялся в пространстве имен файловой системы, но файл будет существовать до тех пор, пока вы его не закроете. Это полезно для временных файлов, которые не будут прочитаны какой-либо другой программой.
Хотя каталоги имеют номера инодов, большинство файловых систем не допускают жестких ссылок на них; они могут появляться только в одном другом каталоге. (Одним необычным исключением является файловая система Mac OSX HFS +; это позволяет работать резервным копиям Time Machine.) Вы по-прежнему можете создавать «мягкие ссылки» на каталоги (или любой другой файл). Мягкая ссылка напоминает запись каталога, за исключением того, что она содержит другое имя пути, а не inum.
Каждый файл UNIX имеет владельца, группу и права доступа. Необходимо, но не достаточно, чтобы они позволили вам открыть файл; Вы также должны иметь как минимум разрешение на выполнение для каждого каталога в пути, который вы используете для ссылки на него. Вот почему нет стандартного способа открыть файл UNIX по номеру его индекса; это обойдёт важный, широко используемый механизм безопасности.
Но это не объясняет, почему не может быть стандартного способа для корневого (привилегированного) пользователя открыть файл по номеру инода, так как проверка разрешений в любом случае обходится. Это было бы очень полезно для определенных функций управления системой, таких как резервное копирование. Насколько мне известно, такие механизмы существуют, но все они зависят от файловой системы; не существует общего способа сделать это для любой файловой системы UNIX.
источник
/
молчит, поэтому он произносится как слэш.Вопрос может быть взят теоретически (что может быть достигнуто
debugfs
) или прагматично (чрезвычайная ситуация). В последнем случае я предполагаю, что целью является сохранение дня и восстановление содержимого файла, возможно, в срочном порядке (именно так я и попал в этот вопрос, поэтому я думаю, что он все еще актуален и полезен).Поскольку нет API ядра,
debugfs
его не следует запускать в действующей файловой системе, поскольку он напрямую управляет структурой FS. Поэтому, чтобы сделать это вживую, вы должны получить другое имя файла. Предполагая, что файл все еще открыт каким-либо процессом (любым процессом), можно найти все удобные файловые дескрипторы в/proc
:Подсказки:
file
на немtail -f < /proc/$pid/fd/$fd > /dev/null
выйти из процесса записи, чтобы он завершился корректно, и использовать fd нового процесса.источник
tail -f < /proc/...
во второй подсказке.tail -c +0 -f
для копирования в первую очередь вместоcat
, если процесс записи только добавляется (без поиска назад и переписывания). Прежде чем выйти из другого процессаtail
, дождитесьtail
окончания файла.