Assumption 2: I assume that if not all pages of the file are mapped into memory, that things will be fine until there is a page fault requiring pages from the file that have been replaced, and probably a segfault will occur?
Нет, этого не произойдет, потому что ядро не позволит вам открывать для записи или замены что-либо внутри исполняемого в данный момент файла. Такое действие потерпит неудачу сETXTBSY
[1] :
cp /bin/sleep sleep;./sleep 3600 & echo none >./sleep
[9] 5332
bash:./sleep: Text file busy
Когда dpkg и т. д. обновляют двоичный файл, он не перезаписывает его, а использует rename(2)
, который просто указывает запись каталога на совершенно другой файл, и любые процессы, которые все еще имеют сопоставления или открытые дескрипторы старого файла, будут продолжайте использовать его без проблем.
[1] защита ETXBUSY
не распространяется на другие файлы, которые также можно считать «текстовыми» (= живой код/исполняемый файл ):общие библиотеки, классы Java и т. д.; изменение такого файла во время отображения другим процессом приведет к сбою процесса. В linux динамический компоновщик покорно передает флаг MAP_DENYWRITE
в mmap(2)
, но не заблуждайтесь --, это не имеет никакого эффекта. Пример:
$ cc -xc - <<<'void lib(){}' -shared -o lib.so
$ cc -Wl,-rpath=. lib.so -include unistd.h -xc - <<<'
extern void lib();
int main(){ truncate("lib.so", 0); lib(); }
'
./a.out
Bus error
Я помню, как построил что-то подобное х лет назад, используя утилиты моста. В Debian/Ubuntu пакет «bridge -utils» — ваш друг. Установить с помощью:
apt install bridge-utils
и просмотрите справочную страницу, чтобы узнать, как ее настроить и использовать:
man bridge-utils-interfaces
man brctl
В среде CentOS7 вы можете установить его с помощью yum:
yum install bridge-utils
Удачи.