Як згадується в Чому пакет програмного забезпечення працює добре, навіть коли він оновлюється? , блокування встановлено на inode, а не на ім'я файлу. Під час завантаження та виконання двійкового файлу файл позначається як зайнятий - саме тому ви отримуєте помилку ETXTBSY (файл зайнятий) при спробі запису на нього.
Тепер для бібліотек, що поділяються, дещо інакше: бібліотеки отримують пам'ять, відображену в адресному просторі процесу mmap()
. Хоча, MAP_DENYWRITE
можливо, вказано, щонайменше Glibc в Linux мовчки ігнорує це (згідно зі сторінкою man, не соромтеся перевіряти джерела) - перевірте цю тему . Отже , ви на самому справі дозволяється писати файл і, як це пам'ять відображається, будь-які зміни видно майже відразу - а це означає , що якщо ви спробуєте досить важко ви можете управляти цегла машиною перезапису бібліотеки.
Отже, правильний спосіб оновлення:
видалення файлу, який видаляє посилання на дані з файлової системи, так що він не є доступним для новозапущених додатків, які можуть захотіти ним користуватися, зберігаючи дані доступними для всіх, хто вже має їх відкритими (або нанесено на карту) ;
створення нового файлу з оновленим вмістом.
Новостворені процеси використовуватимуть оновлений вміст, запущені програми отримають доступ до старої версії. Це те, що робить будь-яка зручна програма управління пакетами. Зауважте, що це не зовсім без будь-якої небезпеки - наприклад, програми, що динамічно завантажують код (за допомогою dlsym()
та друзів), матимуть проблеми, якщо API бібліотеки змінюється безшумно.
Якщо ви хочете опинитися на справді, справді безпечній стороні, вимкніть систему, змонтуйте файлову систему з іншого екземпляра операційної системи, оновіть і знову відновіть оновлену систему.
.so
файл за допомогоюldd filename.so
перевірки залежностей