Чи можна отримати файл за допомогою його inode?


27

Я виконував наступні команди у вказаному порядку:

$ln a b
$ls -i a b
523669 a 523669 b
$rm -f a
$ls -i b
523669 b

З цього тесту я зробив висновок, що команда rmфактично видаляє лише ім’я файлу ( aу цьому тесті) замість файлу, оскільки inode все ще існує і його можна отримати через інше ім'я файлу ( b).

Моє запитання, якщо файл важко пов'язаний лише з одним ім'ям rmфайлу, чи справді файл (тобто, inode) видаляється повністю? А якщо ні, чи можна отримати файловий inode без імені файлу та лише через inode?


Звучить для мене ОС.
Ігнасіо Васкес-Абрамс

@Ігнасіо Васкес-Абрамс. Ти маєш на увазі, це залежить від версії?
user43312

Ні, я маю на увазі, це залежить від операційної системи. У кожного є різні (якщо такі є ) способи введення в систему VFS.
Ігнасіо Васкес-Абрамс

@Ignacio Vazquez-Abrams Чи маєте ви якесь уявлення про RHL чи RHEL?
user43312

1
@BruceEdiger Os X подібного роду робить це. Ви можете отримати доступ до об'єкта файлової системи за допомогою "довідкової URL-адреси файлу", яка, по суті, будується з номера файлової системи та номера вузла. Однак офіційно не підтримується їх створення. Натомість ви отримуєте "довідкову URL-адресу файлу" для файлу, а потім використовуєте його замість імені шляху для наступних звернень за той же сеанс виконання, щоб ваша програма не звертала уваги на переміщення файлу в іншому місці на тому ж томі.
Аналоговий файл

Відповіді:


29

Якщо ви спробуєте відкрити файл через його inode, це обходить будь-який обхід каталогів. Обхід каталогів необхідний для визначення дозволів файлу та каталогів, що ведуть до нього. Без обходу каталогу ядро ​​не може визначити, чи дозволяється процесу виклику отримати доступ до файлу.

Був запропонований патч до ядра Linux, щоб дозволити створити посилання на файл із дескриптора файлу . Її було відхилено, оскільки надійно реалізувати це було б надзвичайно важко .

У Linux (і, можливо, в інших варіантах unix з тієї ж причини) ви не можете створити посилання на видалений файл, тому, якщо файл більше не має імені, ви не зможете повторно додати його. ¹ Ви можете відкрити видалений файл, відкривши магічні посилання під /proc/$pid/fd/.

Якщо файл більше не має посилання і більше не відкритий, він більше не існує і простір, раніше використаний його даними, може бути повернений у будь-який час.

¹ Ви можете зробити це, подвівши байти безпосередньо у файловій системі залежним від файлової системи способом, наприклад, debugfsдля ext2 / ext3 / ext4. Для цього потрібен доступ до пристрою, на якому встановлена ​​файлова система (тобто, як правило, спроб на неї може використовувати лише root). Однак, хоча налагоджувачі можуть отримати доступ до файлу за допомогою inode, це не допоможе, якщо файл буде видалено: файл буде справді видалено, якщо програма закриє його, а запуск налагоджень у режимі читання-запису на змонтованій файловій системі є рецептом для катастрофа.


11

В Linux debugfsінтерактивний налагоджувач файлової системи ext2 / ext3 / ext4 надає lnкоманду, яка може приймати число inode як filespecі створювати нове жорстке посилання на відповідний файл. Однак на практиці це вимагає, щоб від’єднаний файл залишався відкритим процесом , підтримуючи дескриптор відкритого файлу в /proc/[pid]/fd/[n]. Спроба цього на видаленому файлі, швидше за все, призведе до пошкодження файлової системи.

Це тому, що для забезпечення того, що ext3 (і в розширенні ext4) може безпечно відновити від’єднання після аварії, він фактично нульовує блок-покажчики в inode , тоді як ext2 просто позначає ці блоки як невикористані в растрових блоках блоків і позначає позначки inode як "видалений" і залишає вказівники блоку в спокої. Тим не менш, оскільки для створення жорсткого посилання потрібно встановити файлову систему для читання-запису, блоки, відведені для видаленого файлу, можливо, вже були перерозподілені.

До версії ядра 2.6.39 раніше було встановлено, що опція, введена у GNU coreutils v8.0, може бути використана для відновлення від’єднаного файлу через дескриптор відкритого файлу, якщо і відключений файл, і нова тверда посилання знаходились у файловій системі tmpfs . Ця можливість була з тих пір відключена , в зв'язку, як і Жиль зазначив, міркування безпеки , пов'язані з дозволяючи створювати жорстке посилання безпосередньо з файлового дескриптора.ln -L|--logical/proc/[pid]/fd/[n]


Я просто спробував ln -Lвідновити видалений файл з / proc і отримав помилку: "Немає такого файлу чи каталогу", тому я не думаю, що він насправді це підтримує. У мене є основні 8.21.
wingedsubmariner

1
ln -Lне робить те, що ти кажеш, що робить. Це говорить про lnте, що якщо джерело є символічним посиланням, воно повинно жорстко пов'язувати ціль. Символічні посилання в /proc/$pid/fdспеціальні, і жорстке (deleted)посилання не працює.
перестань бути злим"

Також debugfsне допоможе, якщо файл було видалено - якщо ви не захочете ризикувати запустити його в режимі читання-запису на змонтованій файловій системі, що, ймовірно, повністю забруднить всю файлову систему.
Жил "ТАК - перестань бути злим"

Оновлено відповідь стосовно ln -L. Раніше можна було створити жорсткі посилання, /proc/[pid]/fd/[n]використовуючи їх у певних особливих обставинах, але з цього часу це було виправлено.
Томас Найман

1
debugfs's lnдійсно низький рівень і створює лише ім'я, не оновлює кількість і не відмічає блоки як невикористані, тому це дуже небезпечно . Віддайте перевагу debugfsтому, undelщо все це. Увага: debugfsце не працюватиме на змонтованої файлової системи , якщо ви не хочете , щоб прийняти шанс на обпекти FS в попіл.
Lloeki

9

Команди 'ln' та 'rm' працювали саме так у кожній файловій системі UNIX з початку 1970-х. Mac OSX, BSD та Linux - успадковують цей оригінальний дизайн.

Сам по собі файл UNIX не має імені, лише номер inode або inum. Але ви можете отримати доступ до нього лише через запис у спеціальному файлі "каталогу", який пов'язує ім'я з відповідним inum; ви не можете вказати інум безпосередньо.

Каталог сам по собі є файлом, тому ви також повинні отримати доступ до нього через (інший) каталог тощо, через низку імен каталогів, розділених косою косою рискою (/), відомою як "ім'я шляху". Шлях починається в "поточному робочому каталозі" процесу, якщо ім'я не починається з "/", і в цьому випадку він починається з кореневого каталогу файлової системи. Наприклад, якщо ім'я шляху не містить символів "/", то очікується, що це буде запис у поточному каталозі.

Файл без каталогу може мати будь-яку кількість імен шляхів, відомих як "жорсткі посилання", і він буде існувати до тих пір, поки всі його імена шляхів не будуть видалені та останній процес не закриє файл. Потім файл фактично видаляється, а його простір позначається як доступний для повторного використання. Тобто, ви можете створити () або відкрити () файл, пов'язаний поодинці, а потім від’єднати () його, щоб він більше не з’являвся у просторі імен файлової системи, але файл буде існувати, поки ви його не закриєте. Це корисно для тимчасових файлів скретчів, які не читатиме жодна інша програма.

Хоча каталоги мають номери inode, більшість файлових систем забороняють жорсткі посилання на них; вони можуть з’являтися лише в одному іншому каталозі. (Одним незвичним винятком є ​​файлова система Mac OSX HFS +; це дозволяє створювати резервні копії Time Machine.) Ви все ще можете створювати "м'які посилання" на каталоги (або будь-який інший файл). М'яке посилання нагадує запис каталогу, за винятком того, що воно містить інше ім'я шляху, а не inum.

Кожен файл UNIX має права власника, групи та доступу. Необхідно, але недостатньо, щоб вони дозволили вам відкрити файл; ви також повинні мати принаймні виконання дозволу для кожного каталогу в імені шляху, який ви використовуєте для посилання на нього. Тому немає стандартного способу відкрити файл UNIX за його номером inode; це обходило б важливий широко застосовуваний механізм безпеки.

Але це не пояснює, чому кореневому (привілейованому) користувачеві не може бути стандартний спосіб відкрити файл за номером inode, оскільки перевірка дозволів у будь-якому випадку обходить. Це було б дуже корисно для певних функцій управління системою, таких як резервне копіювання. Наскільки мені відомо, такі механізми існують, але всі вони залежать від файлової системи; немає загального способу зробити це для будь-якої файлової системи UNIX.


1
Вперед /мовчить, тому його вимовляють «косою рискою».
ctrl-alt-delor

4

Питання можна сприймати теоретично (чого можна досягти debugfs) або прагматично (надзвичайна ситуація). В останньому випадку я припускаю, що намір економити день і відновити вміст файлу, можливо, терміново (саме тому я приземлився з цього питання, тому вважаю, що це все ще актуально і корисно).

Оскільки API ядра немає, debugfsйого не слід запускати в живій файловій системі, оскільки він безпосередньо маніпулює структурою FS. Тому, щоб зробити це в прямому ефірі, ви повинні отримати інше ім'я файлу. Якщо припустити, що файл все ще відкритий деяким процесом (будь-яким процесом), можна знайти будь-коли зручні дескриптори файлів у /proc:

$ lsof -F pf "$PWD/a" | sed 's/^p//' # find pid and file descriptor number of any process having the file open
$ pid=1234
$ ls -l /proc/$pid/fd/* | grep "$PWD/a" # find file descriptor number
$ fd=42
$ cat /proc/$pid/fd/$fd > "$PWD/a.restored" # read contents to a new filename

Поради:

  • якщо у вас є сумніви щодо правильного fd, ви можете запускати такі команди, як fileна ньому
  • якщо є запис процесу у файл, не забудьте зупинити цей процес якнайшвидше, або ви не отримаєте останні дані. (Неперевіреним) фокусом може бути відкриття файлу, прочитаного лише через fd, за допомогою якогось іншого процесу (спробуйте tail -f < /proc/$pid/fd/$fd > /dev/nullвийти з процесу запису, щоб він вийшов із чистоти, та використовувати fd нового процесу.

2
Це має бути tail -f < /proc/...у другій підказці.
Мюррей Йенсен

Або використовувати tail -c +0 -f , щоб скопіювати його в першу чергу , а не cat, якщо процес запису тільки додавання (не шукає назад і переписування). Вийдіть з іншого процесу раніше tail, а потім дочекайтеся, коли tailдойде до кінця файлу.
Пітер Кордес
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.