Bloqueo de archivos en ejecución: Windows lo hace, Linux no. ¿Por qué?

82

Noté que cuando un archivo se ejecuta en Windows (.exe o .dll), está bloqueado y no se puede eliminar, mover o modificar.

Linux, por otro lado, no bloquea los archivos en ejecución y puede eliminarlos, moverlos o modificarlos.

¿Por qué Windows se bloquea cuando Linux no? ¿Hay alguna ventaja en bloquear?

David Lenihan
fuente
6
Hay una utilidad llamada WhoLockMe que agrega una entrada de menú al menú contextual en el explorador que puede mostrar los procesos que bloquean un archivo determinado. Extremadamente útil cuando obtienes errores extraños de bloqueo de archivos. Editar: Sé que esto no responde a la pregunta, pero pensé que era lo suficientemente útil en el contexto como para justificar una respuesta separada (en oposición a solo un comentario).
JesperE

Respuestas:

106

Linux tiene un mecanismo de recuento de referencias, por lo que puede eliminar el archivo mientras se está ejecutando, y seguirá existiendo siempre que algún proceso (que lo abrió anteriormente) tenga un identificador abierto para él. La entrada de directorio para el archivo se elimina cuando lo elimina, por lo que no se puede abrir más, pero los procesos que ya usan este archivo aún pueden usarlo. Una vez que todos los procesos que utilizan este archivo terminan, el archivo se elimina automáticamente.

Windows no tiene esta capacidad, por lo que se ve obligado a bloquear el archivo hasta que finalicen todos los procesos que se ejecutan desde él.

Creo que es preferible el comportamiento de Linux. Probablemente haya algunas razones arquitectónicas profundas, pero la razón principal (y simple) que encuentro más convincente es que en Windows, a veces no puede eliminar un archivo, no tiene idea de por qué, y todo lo que sabe es que algún proceso lo mantiene en utilizar. En Linux nunca sucede.

Oren Shemesh
fuente
2
Tenga en cuenta que puede usar una herramienta como el Explorador de procesos en Windows para ver qué proceso está usando un archivo / carpeta.
J c
14
Una razón práctica a favor del comportamiento de Linux es que puede actualizar el sistema operativo y otro software en el sistema mientras se está ejecutando, y nunca / rara vez reiniciar (incluso puede cambiar el kernel en ejecución sin reiniciar, es lo suficientemente difícil que solo se llame para aplicaciones en las que el tiempo de actividad es crítico).
joelhardi
6
"Windows no tiene esta capacidad" ... ¿estás seguro? El kernel de NT se basa en el recuento de objetos con identificadores y referencias.
Adam Mitz
10
En realidad, Windows tiene 3 bits que puede configurar para definir lo que otro proceso puede hacer con un archivo mientras está abierto. Un archivo se puede eliminar mientras está abierto si el FILE_SHARE_DELETEbit está establecido. No creo que el cargador PE (que carga EXE y DLL) establezca este bit. Los identificadores se cuentan por referencias y en una eliminación, el archivo desaparece cuando se suelta el último identificador, pero la diferencia entre eso y Unix es que NT bloqueará la creación de un nuevo archivo con el mismo nombre cuando esto suceda.
asveikau
2
Lo que dice Comonad es completamente incorrecto, NTFS, por supuesto, usa Hardlinks y siempre lo hizo, se han agregado enlaces simbólicos en Windows Vista. También es completamente incorrecto que Windows no use ref copunting, lo hace, solo lea API como CreateFile donde se dice claramente bajo qué circunstancias los archivos se pueden eliminar y tal. Y ese es el lugar adecuado para la respuesta real a la pregunta también: CreateFile tiene un argumento llamado dwShareMode que controla el bloqueo obligatorio de los archivos abiertos y permite que las aplicaciones decidan. El valor predeterminado es un candado exclusivo ...
Thorsten Schöning
29

Por lo que yo sé, Linux hace ejecutables de bloqueo cuando se están ejecutando - sin embargo, se bloquea el i-nodo . Esto significa que puede eliminar el "archivo" pero el inodo todavía está en el sistema de archivos, intacto y todo lo que realmente eliminó es un enlace.

Los programas Unix usan esta forma de pensar sobre el sistema de archivos todo el tiempo, crean un archivo temporal, lo abren, eliminan el nombre. Su archivo aún existe, pero el nombre se libera para que otros lo usen y nadie más puede verlo.

Neil Williams
fuente
"todo el tiempo"? ¿Algún ejemplo?
Mez
4
Pregúntele a Google acerca del "archivo temporal seguro de Unix" y encontrará suficientes descripciones de la técnica para demostrar que es conocida y de uso común. Si bien no tengo ningún ejemplo específico para dar, me atrevo a decir que cualquier aplicación consciente de la seguridad que use archivos temporales hace esto.
Dave Sherohman
26

Linux bloquea los archivos. Si intenta sobrescribir un archivo que se está ejecutando, obtendrá "ETXTBUSY" (archivo de texto ocupado). Sin embargo, puede eliminar el archivo y el kernel eliminará el archivo cuando se elimine la última referencia a él. (Si la máquina no se apagó limpiamente, estos archivos son la causa de los mensajes "El inodo eliminado tenía cero tiempo d" cuando se verifica el sistema de archivos, no se eliminaron por completo, porque un proceso en ejecución tenía una referencia a ellos, y ahora lo son.)

Esto tiene algunas ventajas importantes, puede actualizar un proceso que se está ejecutando, eliminando el ejecutable, reemplazándolo y luego reiniciando el proceso. Incluso init puede actualizarse de esta manera, reemplazar el ejecutable y enviarle una señal, y se volverá a ejecutar () sin necesidad de reiniciar. (Esto normalmente lo hace su sistema de gestión de paquetes de forma automática como parte de su actualización)

En Windows, reemplazar un archivo que está en uso parece ser una molestia importante, ya que generalmente requiere reiniciar para asegurarse de que no se estén ejecutando procesos.

Puede haber algunos problemas, como si tiene un archivo de registro extremadamente grande y lo elimina, pero se olvida de decirle al proceso que estaba registrando ese archivo para volver a abrir el archivo, contendrá la referencia y se preguntará por qué su disco de repente no obtuvo mucho más espacio libre.

También puede usar este truco en Linux para archivos temporales. abra el archivo, elimínelo, luego continúe usando el archivo. Cuando su proceso finaliza (sin importar el motivo, incluso un corte de energía), el archivo se eliminará.

Programas como lsof y fuser (o simplemente hurgando en / proc // fd) pueden mostrarle qué procesos tienen archivos abiertos que ya no tienen nombre.


fuente
6

Creo que linux / unix no usa la misma mecánica de bloqueo porque están construidos desde cero como un sistema multiusuario, lo que esperaría la posibilidad de que varios usuarios usen el mismo archivo, tal vez incluso para diferentes propósitos.

¿Hay alguna ventaja en bloquear? Bueno, posiblemente podría reducir la cantidad de sugerencias que el sistema operativo tendría que administrar, pero hoy en día la cantidad de ahorros es bastante insignificante. La mayor ventaja que se me ocurre al bloquear es la siguiente: se guarda cierta ambigüedad visible para el usuario. Si el usuario a está ejecutando un archivo binario y el usuario b lo elimina, entonces el archivo real tiene que quedarse hasta que se complete el proceso del usuario A. Sin embargo, si el Usuario B o cualquier otro usuario lo buscan en el sistema de archivos, no podrán encontrarlo, pero seguirá ocupando espacio. No es una gran preocupación para mí.

Creo que en gran parte es más una cuestión de compatibilidad con versiones anteriores de los sistemas de archivos de Windows.

Eric Tuttleman
fuente
"Windows" en este contexto es la línea Windows NT. Esto fue diseñado como un sucesor multiusuario de Windows 3.11 para un solo usuario. Compare con Unix, que es el sucesor de usuario único de Multics.
MSalters
6

Creo que eres demasiado absoluto sobre Windows. Normalmente, no asigna espacio de intercambio para la parte del código de un ejecutable. En cambio, mantiene un bloqueo en los archivos DLL ejecutables. Si las páginas de códigos descartadas se necesitan nuevamente, simplemente se vuelven a cargar. Pero con / SWAPRUN, estas páginas se mantienen en intercambio. Se utiliza para ejecutables en CD o unidades de red. Por lo tanto, Windows no necesita bloquear estos archivos.

Para .NET, mire Shadow Copy .

MSalters
fuente
1

Si el código ejecutado en un archivo debe bloquearse o no, es una decisión de diseño y MS simplemente decidió bloquearlo, porque tiene claras ventajas en la práctica: de esa manera, no es necesario saber qué código en qué versión utiliza qué aplicación. Este es un problema importante con el comportamiento predeterminado de Linux, que la mayoría de la gente simplemente ignora. Si se reemplazan las bibliotecas de todo el sistema, no puede saber fácilmente qué aplicaciones usan el código de dichas bibliotecas, la mayoría de las veces lo mejor que puede obtener es que el administrador de paquetes conoce a algunos usuarios de esas bibliotecas y las reinicia. Pero eso solo funciona para cosas generales y bien conocidas como tal vez Postgres y sus bibliotecas o tal. Los escenarios más interesantes son si desarrolla su propia aplicación contra algunas bibliotecas de terceros y esas son reemplazadas, porque la mayoría de las veces el administrador de paquetes simplemente no conoce su aplicación. Y eso' No es solo un problema de código C nativo o algo así, puede suceder con casi todo: simplemente use httpd con mod_perl y algunas bibliotecas de Perl instaladas usando un administrador de paquetes y deje que el administrador de paquetes actualice esas bibliotecas de Perl por cualquier motivo. No reiniciará su httpd, simplemente porque no conoce las dependencias. Hay muchos ejemplos como este, simplemente porque cualquier archivo puede potencialmente contener código en uso en la memoria por cualquier tiempo de ejecución, piense en Java, Python y todas esas cosas.

Así que hay una buena razón para tener la opinión de que bloquear archivos de forma predeterminada puede ser una buena opción. Sin embargo, no es necesario que esté de acuerdo con esas razones.

Entonces, ¿qué hizo la EM? Simplemente crearon una API que le da a la aplicación que llama la oportunidad de decidir si los archivos deben bloquearse o no, pero decidieron que el valor predeterminado de esta API es proporcionar un bloqueo exclusivo a la primera aplicación que llama. Eche un vistazo a la API sobre CreateFile y su dwShareModeargumento. Esa es la razón por la que es posible que no pueda eliminar los archivos en uso por alguna aplicación, simplemente no le importa su caso de uso, usó los valores predeterminados y, por lo tanto, obtuvo un bloqueo exclusivo de Windows para un archivo.

Por favor, no crea en la gente que le dice algo sobre Windows que no usa el recuento de referencias en HANDLEs o que no es compatible con Hardlinks o algo así, eso es completamente incorrecto. Casi todas las API que utilizan HANDLE documentan su comportamiento con respecto al recuento de referencias y puede leer fácilmente en casi cualquier artículo sobre NTFS que, de hecho, es compatible con Hardlinks y siempre lo hizo. Desde Windows Vista, también tiene soporte para Symlinks y el Soporte para Hardlinks se ha mejorado al proporcionar API para leer todos los de un archivo determinado, etc.

Además, es posible que simplemente desee echar un vistazo a las estructuras utilizadas para describir un archivo en, por ejemplo, Ext4 en comparación con las de NTFS , que tienen mucho en común. Ambos trabajan con el concepto de extensión, que separa los datos de los atributos como el nombre del archivo, y los inodos son prácticamente otro nombre para un concepto anterior, pero similar. Incluso Wikipedia enumera ambos sistemas de archivos en su artículo .

Realmente hay mucho FUD en torno al bloqueo de archivos en Windows en comparación con otros sistemas operativos en la red, al igual que en la desfragmentación. Parte de este FUD se puede descartar simplemente leyendo un poco en Wikipedia .

Thorsten Schöning
fuente
Las divagaciones sobre la gestión de versiones de las dependencias compartidas son irrelevantes. Tienes que lidiar con esos problemas incluso si actualizarlos requiere reiniciar. En Windows, incluso tiene un nombre: DLL hell. Además, los comportamientos en tiempo de ejecución que usted describe están completamente manejados por el caso de Linux, donde ya tiene el archivo cargado en la memoria y permanece disponible; la aplicación seguirá ejecutándose con la versión anterior hasta que se reinicie, al igual que cuando Windows fuerza un reinicio para desbloquear el archivo. No hay ventaja en ese frente.
jpmc26
El infierno de DLL, por supuesto, está completamente perdiendo el punto y ya no tenemos los 90, solo lea sobre cosas como WinSxSy esas. Además, no se trata de cargar cosas en la memoria y mantenerlas allí, Windows hace exactamente eso también si es necesario, se trata de saber y decidir si los archivos deben reemplazarse o no y quién está a cargo de decidir eso. La API de Windows simplemente permite que el primer usuario del archivo decida y eso tiene mucho sentido.
Thorsten Schöning
Pero ese es mi punto: decidir qué versión de una DLL usar es parte del infierno de las DLL. Llámelo "infierno de la dependencia" si quiere distinguirse de algunos de los viejos comportamientos idiosincrásicos de Windows. Independientemente, el bloqueo de archivos ejecutables de forma predeterminada no ayuda a administrar las dependencias compartidas. En absoluto. Es posible que las cosas que dependen de un archivo en particular ni siquiera se estén ejecutando cuando intente actualizarlo; no hay seguridad adicional. Hay 2 opciones con dependencias compartidas: gratis para todos, que corre el riesgo de que se rompan las cosas cuando intenta ejecutarlo, o el administrador de paquetes, que corre el riesgo de impedirle instalar cosas.
jpmc26
Esta pregunta no se trata de decidir qué EXE o DLL usar, se trata de lo que sucede después de forma predeterminada y por qué. Estás discutiendo un tema completamente diferente. El bloqueo se usa después de decidir qué EXE o DLL ejecutar para obtener algún nivel de control adicional por parte del primer usuario, que es el propio Windows en este ejemplo, y para informar a otros sobre ese control. Y no permitir que "otros" borren o escriban en archivos que Windows necesita por alguna razón y por lo tanto los bloquea, por supuesto es un mecanismo de coordinación adicional.
Thorsten Schöning
1
Es muy probable que algunos EXE o DLL no estén "en la memoria" de todos modos, sino que están asignados a ellos de forma predeterminada. El mapeo requiere que el contenido del archivo esté disponible, por lo que reemplazarlo arbitrariamente se considera inseguro por defecto y uno debe saber lo que está haciendo. Lo que obviamente no es el caso si uno se sorprende con archivos EXE o DLL bloqueados. OTOH, todos los demás archivos solo están bloqueados de forma predeterminada, no necesariamente, por lo que las aplicaciones pueden decidir si le permiten escribir o eliminar operaciones, según su caso de uso. Los desarrolladores de la aplicación deberían saber mejor que los usuarios arbitrarios cómo utilizan sus archivos y qué operaciones son seguras y cuándo.
Thorsten Schöning
0

Las variantes NT tienen la

abrir archivos

comando, que mostrará qué procesos tienen identificadores en qué archivos. Sin embargo, requiere habilitar el indicador global del sistema 'mantener lista de objetos'

openfiles / local /?

le dice cómo hacer esto, y también que se incurre en una penalización de rendimiento al hacerlo.

gastador
fuente
0

Los ejecutables se asignan progresivamente a la memoria cuando se ejecutan. Lo que eso significa es que las partes del ejecutable se cargan según sea necesario. Si el archivo se intercambia antes de que se mapeen todas las secciones, podría causar una gran inestabilidad.

Ken Netherland
fuente