Ответы:
Как упоминает @Kusalananda, обычно обновления выполняются путем удаления старого файла и создания нового с тем же именем. Это фактически создаст новый файл с новым индексом, оставляя систему свободной, чтобы использовать старый, пока он открыт.
В качестве упрощенного примера, такие вещи, как
rm /bin/cat
cp /new/version/of/cat /bin/cat
создаст логически новый файл и работает, даже если catможет быть запущен. То же самое касается библиотек. (Выше приведен пример, а не надежный способ обновления файла в реальном мире.)
Кто-то может попытаться изменить двоичный файл вместо создания нового с тем же именем. В этом случае, по крайней мере, Linux фактически предотвращает внесение изменений в исполняемый файл, который используется:
window 1 # ./cat
window 2 # echo foobar > cat
-bash: cat: Text file busy
Тем не менее, это не похоже на работу с динамически загружаемыми библиотеками ...
Я сделал копию libc.so.6для тестирования и заполнил ее нулями, пока она использовалась:
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ldd ./cat
linux-vdso.so.1 (0x00007ffcfaf30000)
libc.so.6 => /tmp/lib/libc.so.6 (0x00007f1145e67000)
/lib64/ld-linux-x86-64.so.2 (0x00007f1146212000)
window 1 /tmp/lib# LD_LIBRARY_PATH=/tmp/lib ./cat
foo
foo
Segmentation fault
(Между тем в другом окне, после foo, до сегфоута)
window 2 /tmp/lib# dd if=/dev/zero of=libc.so.6 bs=1024 count=2000
На самом деле сама программа ничего не могла с этим поделать, поскольку я эффективно редактировал ее код в Интернете.
(Вероятно, это будет зависеть от системы, я тестировал на Debian Jessie 8.5, Linux 3.16.7-ckt25-2 + deb8u3. В частности, системы Windows IIRC еще более агрессивны в отношении предотвращения изменения используемых файлов.)
Поэтому я полагаю, что ответ заключается в том, что обновления обычно выполняются таким образом, чтобы избежать каких-либо проблем, и этому помогают внутренние компоненты файловой системы. Но (в Linux), похоже, нет никаких гарантий против фактического повреждения динамических библиотек.
installУтилита обычно используется для вещей , как это. Вам не нужно явно rmуказывать файл назначения. Кроме того, он сохраняет права доступа к существующему файлу, может сделать резервную копию, установить новый режим и т. Д. Пример использования:install /new/version/of/cat /bin/cat
rm+ cpПредназначались в качестве примера. Также может быть разумно поместить новый файл атомарно с переименованием, избегая короткого окна, в котором ни одна версия не доступна. (Хотя GNU install, похоже, даже этого не делает, hmpf.)
rm), он еще не удален. Он будет существовать на диске и все еще может быть прочитан всеми открытыми процессами. Он будет удален только тогда, когда количество жестких ссылок достигнет нуля, а число прецессов с открытым файлом достигнет нуля.
installУтилита специально небезопасна! Он перезаписывает целевой файл на месте, а не заменяет его атомарно. mv(с источником и папкой в одном каталоге, источником обычно является временный файл) - это единственный безопасный способ установки файлов.
strace, installв GNU coreutils отсоединяет целевой файл, а затем копирует новый на его место. Это означает, что есть короткое окно, в течение которого файл является частичным. Это не устанавливает файл атомарно на месте с переименованием.
Файлы не будут "правильно удалены", если они не связаны, пока они все еще открыты. Когда они закрыты, используемое ими дисковое пространство снова будет считаться «свободным». Это относится и к текущим приложениям и их общим библиотекам.
Единственное, что я мог увидеть сбой, - это если программа использовала dlopen()для загрузки разделяемую библиотеку по требованию или если программе приходилось обращаться к другим файлам по требованию, таким как словари, файлы тем или другие файлы, которые внезапно исчезали.
Для иллюстрации: запуск vimв одном сеансе оболочки при удалении установки vimв другом сеансе оболочки не «повредит» и не завершит текущий запущенный vimсеанс. Но некоторые вещи начнут давать сбой, например, проверка орфографии, которая требует vimоткрытия файлов при установке.
ln -sfпри замене через библиотеку, потому что-fпозволил вам «перезаписи» существующему назначение символической ссылки с новым, без него когда - либо «сломан» ( в отличие , если ты сrmпоследующим аln -s) Поэтому перед командой library.so указал на старую версию, например. library.so.4 ... после команды, он просто указал на library.so.5 (или любой другой ) , вместо этого - никогда не не указывая на действительной библиотеке.