Блокировка исполняемых файлов: Windows делает это, Linux-нет. Почему?

#windows #linux #operating-system #filesystems #locking

Вопрос:

Я заметил, что когда файл выполняется в Windows (.exe или .dll), он заблокирован и не может быть удален, перемещен или изменен.

Linux, с другой стороны, не блокирует исполняемые файлы, и вы можете удалять, перемещать или изменять их.

Почему Windows блокируется, когда Linux этого не делает? Есть ли преимущество в блокировке?

Комментарии:

1. Существует утилита под названием WhoLockMe , которая добавляет пункт меню в контекстное меню проводника, который может отображать процесс(ы) блокировки данного файла. Чрезвычайно полезно, когда вы получаете странные ошибки блокировки файлов. Редактировать: Я знаю, что это не ответ на вопрос, но я подумал, что это достаточно полезно в контексте, чтобы гарантировать отдельный ответ (в отличие от простого комментария).

Ответ №1:

В Linux есть механизм подсчета ссылок, поэтому вы можете удалить файл во время его выполнения, и он будет существовать до тех пор, пока у какого-либо процесса (который ранее его открыл) есть для него открытый дескриптор. Запись каталога для файла удаляется при его удалении, поэтому он больше не может быть открыт, но процессы, уже использующие этот файл, все еще могут его использовать. Как только все процессы, использующие этот файл, завершатся, файл будет удален автоматически.

Windows не имеет этой возможности, поэтому она вынуждена блокировать файл до тех пор, пока все процессы, выполняемые из него, не завершатся.

Я считаю, что поведение Linux предпочтительнее. Вероятно, есть какие-то глубокие архитектурные причины, но главная (и простая) причина, которую я нахожу наиболее убедительной, заключается в том, что в Windows вы иногда не можете удалить файл, вы понятия не имеете, почему, и все, что вы знаете, это то, что какой-то процесс поддерживает его использование. В Linux этого никогда не происходит.

Комментарии:

1. Обратите внимание, что вы можете использовать такой инструмент, как Проводник процессов в Windows, чтобы узнать, какой процесс использует файл/папку.

2. Практическая причина в пользу поведения Linux заключается в том, что вы можете обновлять операционную систему и другое программное обеспечение в системе во время ее работы и никогда/редко перезагружаться (вы даже можете переключать работающее ядро без перезагрузки, просто это достаточно сложно, потому что это требуется только в приложениях, критически важных для бесперебойной работы).

3. «Windows не имеет этой возможности»… Ты уверен? Ядро NT основано на пересчете объектов с помощью дескрипторов и ссылок.

4. На самом деле в Windows есть 3 бита, которые вы можете установить, которые определяют, что другой процесс может сделать с файлом, пока он открыт. Файл может быть удален во время его открытия, если FILE_SHARE_DELETE установлен бит. Я не думаю, что загрузчик PE (который загружает файлы EX и библиотеки DLL) устанавливает этот бит. Дескрипторы подсчитываются по ссылкам, и при удалении файл удаляется при удалении последнего дескриптора, но разница между этим и Unix заключается в том, что NT заблокирует создание нового файла с тем же именем, когда это произойдет.

5. То, что говорит comonad, совершенно неправильно, NTFS, конечно, использует жесткие ссылки и всегда использовала, символические ссылки были добавлены в Windows Vista. Также совершенно неправильно, что Windows не использует повторную загрузку, это так, просто прочитайте API-интерфейсы, такие как CreateFile, где четко указано, при каких обстоятельствах файлы могут быть удалены и тому подобное. И это также подходящее место для реального ответа на вопрос: CreateFile имеет аргумент dwShareMode, который управляет обязательной блокировкой открытых файлов и позволяет приложениям принимать решения. Значение по умолчанию-эксклюзивная блокировка…

Ответ №2:

Насколько я знаю, linux блокирует исполняемые файлы, когда они запущены, однако он блокирует индекс. Это означает, что вы можете удалить «файл», но индекс все еще находится в файловой системе, нетронутый, и все, что вы действительно удалили, — это ссылка.

Программы Unix постоянно используют этот способ представления о файловой системе, создают временный файл, открывают его, удаляют имя. Ваш файл все еще существует, но имя освобождено для использования другими, и никто другой не может его видеть.

Комментарии:

1. «все время»? Есть какие-нибудь примеры?

2. Спросите Google о «безопасном временном файле unix», и вы найдете достаточно описаний этого метода, чтобы показать, что он хорошо известен и широко используется. Хотя у меня нет конкретных примеров для приведения, я осмелюсь сказать, что любое приложение, заботящееся о безопасности, которое использует временные файлы, делает это.

Ответ №3:

Linux действительно блокирует файлы. Если вы попытаетесь перезаписать выполняемый файл, вы получите «ETXTBUSY» (текстовый файл занят). Однако вы можете удалить файл, и ядро удалит файл, когда будет удалена последняя ссылка на него. (Если машина не была полностью выключена, эти файлы являются причиной сообщений «Удаленный индекс имел нулевое время ожидания» при проверке файловой системы, они не были полностью удалены, потому что запущенный процесс имел ссылку на них, и теперь они есть.)

Это имеет некоторые основные преимущества, вы можете обновить запущенный процесс, удалив исполняемый файл, заменив его, а затем перезапустив процесс. Даже init можно обновить таким образом, заменить исполняемый файл и отправить ему сигнал, и он сам повторно выполнит (), не требуя перезагрузки. (Обычно это делается автоматически вашей системой управления пакетами в рамках ее обновления)

В Windows замена используемого файла, по-видимому, является серьезной проблемой, обычно требующей перезагрузки, чтобы убедиться, что никакие процессы не запущены.

Могут возникнуть некоторые проблемы, например, если у вас очень большой файл журнала, и вы его удаляете, но забываете сообщить процессу, который входил в этот файл, чтобы он снова открыл файл, он сохранит ссылку, и вы удивитесь, почему на вашем диске внезапно не стало намного больше свободного места.

Вы также можете использовать этот трюк в Linux для временных файлов. откройте файл, удалите его, затем продолжайте использовать файл. Когда ваш процесс завершится (независимо от причины-даже при отключении питания), файл будет удален.

Такие программы, как lsof и fuser (или просто покопаться в /proc//fd), могут показать вам, в каких процессах открыты файлы, у которых больше нет имени.

Ответ №4:

Я думаю, что linux / unix не использует одну и ту же механику блокировки, потому что они построены с нуля как многопользовательская система, что предполагает возможность использования несколькими пользователями одного и того же файла, возможно, даже для разных целей.

Есть ли преимущество в блокировке? Что ж, это, возможно, могло бы уменьшить количество указателей, которыми должна была бы управлять ОС, но сейчас, через несколько дней, сумма экономии довольно незначительна. Самое большое преимущество, которое я могу придумать для блокировки, заключается в следующем: вы сохраняете некоторую двусмысленность, доступную для просмотра пользователем. Если пользователь a запускает двоичный файл, а пользователь b удаляет его, то фактический файл должен сохраняться до завершения процесса пользователя A. Тем не менее, если пользователь B или любые другие пользователи будут искать его в файловой системе, они не смогут его найти, но он будет продолжать занимать место. На самом деле это не очень меня беспокоит.

Я думаю, что в основном это скорее вопрос обратной совместимости с файловыми системами Windows.

Комментарии:

1. «Windows» в данном контексте-это строка Windows NT. Он был разработан как многопользовательский преемник однопользовательской Windows 3.11. Сравните с Unix, которая является однопользовательской преемницей Multics.

Ответ №5:

Я думаю, что вы слишком категоричны в отношении окон. Обычно он не выделяет место подкачки для кодовой части исполняемого файла. Вместо этого он сохраняет блокировку доступных amp; DLL. Если отброшенные кодовые страницы снова понадобятся, они просто перезагружаются. Но с /SWAPRUN эти страницы сохраняются в режиме подкачки. Это используется для исполняемых файлов на компакт-диске или сетевых дисках. Следовательно, Windows не нужно блокировать эти файлы.

Для .NET посмотрите на Теневое копирование.

Ответ №6:

Если выполняемый код в файле должен быть заблокирован или нет, это дизайнерское решение, и MS просто решила заблокировать, потому что на практике это имеет явные преимущества: таким образом, вам не нужно знать, какой код в какой версии используется каким приложением. Это серьезная проблема с поведением Linux по умолчанию, которое просто игнорируется большинством людей. Если общесистемные библиотеки заменены, вы не сможете легко узнать, какие приложения используют код таких библиотек, в большинстве случаев лучшее, что вы можете получить, — это то, что менеджер пакетов знает некоторых пользователей этих библиотек и перезапускает их. Но это работает только для общих и хорошо знакомых вещей, таких как, возможно, Postgres и его библиотеки или что-то в этом роде. Более интересные сценарии возникают, если вы разрабатываете свое собственное приложение на основе сторонних библиотек, и они заменяются, потому что в большинстве случаев менеджер пакетов просто не знает вашего приложения. И это не только проблема собственного кода на C или что-то в этом роде, это может произойти практически со всем: просто используйте httpd с mod_perl и некоторыми библиотеками Perl, установленными с помощью менеджера пакетов, и позвольте менеджеру пакетов обновлять эти библиотеки Perl по любой причине. Он не перезапустит ваш httpd просто потому, что не знает зависимостей. Существует множество примеров, подобных этому, просто потому, что любой файл потенциально может содержать код, используемый в памяти любой средой выполнения, подумайте о Java, Python и всех подобных вещах.

Таким образом, есть веские основания полагать, что блокировка файлов по умолчанию может быть хорошим выбором. Однако вам не нужно соглашаться с этими причинами.

Так что же сделала мисс? Они просто создали API, который дает вызывающему приложению возможность решать, следует ли блокировать файлы или нет, но они решили, что значение этого API по умолчанию-предоставить эксклюзивную блокировку первому вызывающему приложению. Взгляните на API вокруг CreateFile и его dwShareMode аргумента. Именно по этой причине вы, возможно, не сможете удалять файлы, используемые каким-либо приложением, ему просто наплевать на ваш вариант использования, он использовал значения по умолчанию и, следовательно, получил эксклюзивную блокировку Windows для файла.

Пожалуйста, не верьте в то, что люди говорят вам что-то о том, что Windows не использует ссылки, рассчитанные на дескрипторы, или не поддерживает жесткие ссылки или что-то в этом роде, это совершенно неправильно. Почти каждый API, использующий дескрипторы, документирует свое поведение в отношении подсчета ссылок, и вы можете легко прочитать почти в любой статье о NTFS, что на самом деле он поддерживает жесткие ссылки и всегда поддерживал. Начиная с Windows Vista, он также поддерживает символические ссылки, а поддержка жестких ссылок была улучшена за счет предоставления API для чтения всех из них для данного файла и т. Д.

Кроме того, вы можете просто захотеть взглянуть на структуры, используемые для описания файла, например, в Ext4, по сравнению со структурами NTFS, которые имеют много общего. Оба работают с концепцией экстентов, которая отделяет данные от атрибутов, таких как имя файла, а индексы-это в значительной степени просто другое название для более старой, но похожей концепции. Даже Википедия перечисляет обе файловые системы в своей статье.

В Windows действительно много проблем с блокировкой файлов по сравнению с другими операционными системами в сети, так же как и с дефрагментацией. Некоторые из этих ошибок можно исключить, просто немного почитав в Википедии.

Комментарии:

1. Бредни об управлении версиями общих зависимостей неуместны. Вам придется решать эти проблемы, даже если для их обновления потребуется перезагрузка. В Windows у него даже есть название: DLL hell. Кроме того, поведение во время выполнения, описанное вами, полностью обрабатывается в случае Linux, когда файл уже загружен в память и остается доступным; приложение будет продолжать работать со старой версией до тех пор, пока не перезагрузится, точно так же, как при принудительной перезагрузке Windows для разблокировки файла. На этом фронте нет никаких преимуществ.

2. DLL-ад, конечно, полностью упускает суть, и у нас больше нет 90-х, просто читайте о таких вещах, как WinSxS и все такое. Кроме того, речь идет не о загрузке файлов в память и их хранении там, Windows делает именно это, если это необходимо, речь идет о знании и принятии решения о том, следует ли заменять файлы или нет, и кто отвечает за это решение. Windows-API просто позволяет первому пользователю файла принять решение, и это имеет большой смысл.

3. Но это моя точка зрения: решение о том, какую версию библиотеки DLL использовать, является частью ада DLL. Назовите это «адом зависимостей», если хотите отличить его от некоторых старых особенностей поведения Windows. Несмотря на это, блокировка исполняемых файлов по умолчанию не помогает в управлении общими зависимостями. Вообще. Вещи, зависящие от конкретного файла, могут даже не запускаться при попытке его обновления; дополнительной безопасности нет. Есть 2 варианта с общими зависимостями: бесплатно для всех, что может привести к поломке при попытке запустить его, или менеджер пакетов, который может помешать вам установить что-либо.

4. Этот вопрос не о том, чтобы решить, какой EXE или DLL вообще использовать, а о том, что происходит потом по умолчанию и почему. Вы обсуждаете совершенно другую тему. Блокировка используется после принятия решения о том, какой EXE или DLL следует выполнить, чтобы получить некоторый уровень дополнительного контроля со стороны первого пользователя, которым в данном примере является сама Windows, и сообщить другим об этом элементе управления. И не позволять «другим» удалять или записывать файлы, необходимые Windows по какой-либо причине, и, следовательно, блокировать их, конечно, является механизмом дополнительной координации.

5. Какой-то EXE или DLL, скорее всего, все равно не находится «в памяти», но по умолчанию отображается в нее. Сопоставление требует, чтобы содержимое файла было доступно, поэтому произвольная его замена по умолчанию считается небезопасной, и человек должен знать, что он делает. Что, очевидно, не так, если вас удивляют заблокированные бывшие или библиотеки DLL. OTOH, все остальные файлы блокируются только по умолчанию, не обязательно, поэтому приложения могут решать, разрешают ли они вам операции записи или удаления, в зависимости от их варианта использования. Разработчики приложений должны лучше, чем обычные пользователи, знать, как они используют свои файлы и какие операции безопасны, когда.

Ответ №7:

Варианты NT имеют

открытые файлы

команда, которая покажет, какие процессы имеют дескрипторы для каких файлов. Однако для этого требуется включить системный глобальный флаг «ведение списка объектов».

открытые файлы /локальные /?

рассказывает вам, как это сделать, а также о том, что это приведет к снижению производительности.

Ответ №8:

Исполняемые файлы постепенно отображаются в памяти при запуске. Это означает, что части исполняемого файла загружаются по мере необходимости. Если файл будет заменен до отображения всех разделов, это может привести к серьезной нестабильности.