Чому пакет програмного забезпечення працює добре, навіть коли він оновлюється?


29

Скажімо, я запускаю програмне забезпечення, а потім запускаю менеджер пакетів для оновлення програмного забезпечення, я помічаю, що Linux не збиває запущений процес оновлення пакету - він все ще працює нормально. Як це робить Linux?

Відповіді:


35

Причина полягає в тому, що Unix не блокує виконуваний файл під час його виконання або навіть якщо він працює як Linux, це блокування застосовується до inode, а не до імені файлу. Це означає, що процес, який підтримує його відкритим, отримує доступ до тих же (старих) даних навіть після того, як файл був видалений (фактично відключений) і замінений на новий з тим же ім'ям, що по суті є тим, що робить оновлення пакета.

Це одна з головних відмінностей Unix від Windows. Останній не може оновити файл, що заблокується, оскільки в ньому відсутній шар між іменами файлів та inodes, що створює великі клопоти, щоб оновити або навіть встановити деякі пакети, оскільки зазвичай потрібно повне перезавантаження.


10
Для уточнення, в Linux не можна змінювати виконуваний файл під час його роботи. Але ви можете від’єднати файл і замінити його на новий однойменний файл.
cjm

У Linux можна змінити виконуваний файл під час його роботи. Результат, швидше за все, буде непередбачуваним, якщо тільки ви дійсно не знаєте, що робите. Додано пункт "однойменного", який чітко не вказано.
jlliagre

4
@jlliagre Якщо я не розумію, ви не можете, наскільки мені відомо: sprunge.us/egiR
Chris Down

2
Хоча одна акуратна річ щодо NFTS - якщо ви виконайте перейменування з командного рядка або іншої програми, ви можете розмістити там однойменний файл, і це не вплине на програми, у яких відкритий оригінальний файл. (команда перейменувати в Explorer не працює для цього)
Стеффан Дональ

1
@cjm Ви неправі щодо захисту "файлу текст зайнятий" під Linux, відповідь оновлена. У Solaris немає такого обмеження, яке я більше знайомий. Ви все ще можете змінювати спільні бібліотеки з обома ОС.
jlliagre

18

Виконавчі файли, як правило, відкриваються один раз, приєднуються до дескриптора файлу, і не мають дескриптора файлу до їх бінарного повторного відкриття протягом одного періоду виконання. Наприклад, якщо ви виконуєте bash, exec()як правило, створюється лише дескриптор файлу для вводу, на який вказує /bin/bashодин раз - при виклику.

Це часто означає, що для простих бінарних файлів, які не намагаються перечитати себе під час виконання (використовуючи шлях, по якому вони викликалися), вміст, який зберігається в кеші, залишається дійсним як звисаючий inode. Це означає, що по суті є репліка попередньої версії виконуваного файлу.

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

Для простих випадків використання оновлення безпечно, не перезавантажуючи процес.


1
Інша небезпека, навіть у простих випадках, полягає в тому, що, оскільки запущений додаток використовує кешовану копію двійкового файлу, що поки ви не перезавантажите програму вручну, вона все ще запускає стару версію коду. Хоча це не має значення більшості часу; якщо оновлення включало виправлення безпеки, незважаючи на встановлення патчу, ваша система все ще вразлива, оскільки стара версія все ще працює.
Ден Нелі

1
Боюся, ваш перший абзац неточний. Ядра Unix / Linux не завантажують виконувані програми одразу, а карту пам'яті. Це означає, що лише сторінки, які фактично використовуються, в кінцевому підсумку переходять на оперативну пам’ять. Це вся суть захисту "Текстовий файл зайнятий" під Linux. Немає гарантії, що частина запущеного файлу не буде прочитана довгий час після запуску. Більше того, деякі сторінки ніколи не завантажуватимуться для достатньо великих програм, і це ще більше стосується динамічно завантажених бібліотек. Наприклад, bashдвійковий вміст становить близько 200 4К сторінок, не впевнений, що вони використовуються в середньому сеансі.
jlliagre

@jlliagre Я говорив про те, ialloc()щоб структуру ядра було прочитано, а не відображення пам'яті самих сторінок. Хіба я не правий, думаючи, що в сучасних файлових системах ext * inode зрештою є послідовним в ядрі (і всередині підсистеми VM)?
Кріс Даун

Немає гарантійних частин виконуваного вмісту не буде читатися довгий час після його запуску, і немає гарантії, що ті самі сторінки не будуть прочитані знову через деякий час протягом часу виконання.
jlliagre

@jlliagre Правильно, але це не те, що я мав на увазі. Можливо, я трохи підрізав свої слова у своїй відповіді, спробую зробити те, що мав на увазі, зрозумілішим.
Кріс Даун
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.