¿Cómo puede un programa de registro continuar registrándose en un archivo eliminado?


12

Desde Unix Power Tools, 3.a edición : en lugar de eliminar un archivo, vacíelo :

Si un proceso activo tiene el archivo abierto (no es raro para los archivos de registro), eliminar el archivo y crear uno nuevo no afectará el programa de registro; esos mensajes seguirán yendo al archivo que ya no está vinculado . Vaciar el archivo no interrumpe la asociación, por lo que borra el archivo sin afectar el programa de registro.

( énfasis mío )

No entiendo por qué un programa continuará registrándose en un archivo eliminado. ¿Es porque la entrada del descriptor de archivo no se elimina de la tabla de proceso?

Respuestas:


11

Cuando eliminas un archivo, realmente eliminas un enlace al archivo (al inodo). Si alguien ya tiene ese archivo abierto, puede conservar el descriptor de archivo que tiene. El archivo permanece en el disco, ocupando espacio, y puede escribirse y leerse si tiene acceso a él.

La unlinkfunción se define con este comportamiento por POSIX:

Cuando el recuento de enlaces del archivo se convierte en 0 y ningún proceso tiene el archivo abierto, el espacio ocupado por el archivo se liberará y el archivo ya no será accesible. Si uno o más procesos tienen el archivo abierto cuando se elimina el último enlace, el enlace se eliminará antes de que unlink () regrese, pero la eliminación del contenido del archivo se pospondrá hasta que se cierren todas las referencias al archivo .

Este consejo debido a ese comportamiento. El daemon tendrá el archivo abierto y no notará que se ha eliminado (a menos que lo esté monitoreando específicamente, lo cual es poco común). Seguirá escribiendo alegremente en el descriptor de archivo existente que tiene: seguirá ocupando (más) espacio en el disco, pero no podrá ver ninguno de los mensajes que escribe, por lo que realmente está en el peor de ambos mundos. Si trunca el archivo a una longitud cero, entonces el espacio se libera inmediatamente, y cualquier mensaje nuevo se agregará en el nuevo final del archivo donde puede verlos.

Eventualmente, cuando el demonio termina o closeenvía el archivo , el espacio se liberará. Nadie nuevo puede abrir el archivo mientras tanto (excepto a través de interfaces reflectantes específicas del sistema como las de Linux/proc/x/fd/... ). También se garantiza que:

Si el recuento de enlaces del archivo es 0, cuando todos los descriptores de archivo asociados con el archivo están cerrados, el espacio ocupado por el archivo se liberará y el archivo ya no será accesible.

Por lo tanto, no pierde el espacio en el disco de forma permanente, pero no gana nada al eliminar el archivo y pierde el acceso a los mensajes nuevos.


1
¿Qué ocurrirá si un usuario (digamos root aquí) intenta desvincularse /proc/x/fd/y? ¿Causaría eso que el proceso no pueda escribir en el descriptor de archivo, o es una operación ilegal?
nanofarad

@hexafraction /proc/*/fd/*son enlaces simbólicos a archivos reales, por lo que eliminarlos no eliminará el archivo. Te sugiero que experimentes :) (¡no en el sistema de producción, por supuesto!)
Ruslan

1
@MichaelHomer Quizás podría aclarar en su respuesta que una vez que un archivo está desvinculado, el proceso que tiene un descriptor de archivo apuntando a él puede vincularlo nuevamente, en la misma ruta o no. Esto a veces puede ser útil.
lgeorget

@hexafraction Bueno, estas son solo representaciones (en el espacio del sistema de archivos) del estado del proceso y los objetos. Si elimina esas representaciones en el espacio del sistema de archivos, no debería pasar nada con el proceso real, a menos que (o algún otro proceso) se base en esa representación. No estoy seguro de que pueda usarlo de manera rmincontinente en el interior /proco /syssin que el sistema lo regañe de todos modos.
David Tonhofer

@lgeorget ¿Cómo se logra eso?
Michael

8

Exactamente.

Los archivos son tripartitos.

  • El contenido, es decir, una matriz plana de bytes, escrita en algún lugar de un disco o generada sobre la marcha.
  • El nodo de índice , o inodo para abreviar, que es una estructura de datos poblada y utilizada por el núcleo. Contiene todos los metadatos (tamaño, permiso, etc.) sobre el archivo, y también apunta a la ubicación del contenido del archivo.
  • Una o más entradas de directorio , que son lugares, manipulados como caminos como /home/user/personal_file, que actúan como asas a través del cual se puede utilizar el archivo, modificar su contenido, cambiar sus metadatos, etc.

Cuando abre un archivo, le da la ruta al sistema operativo y le devuelve un identificador directamente al inodo. Con este identificador, llamado descriptor de archivo, puede manipular el archivo como desee (o al menos, según lo permita el sistema operativo).

Nunca puede eliminar directamente un inodo, debe proporcionar una ruta al sistema operativo para que sea necesario eliminarlo. Entonces, cuando desea eliminar un archivo, elimina solo la entrada del directorio. Si el archivo tiene otras entradas de directorio, continuará siendo accesible, e incluso si no lo tiene, su inodo no se eliminará mientras todavía haya descriptores de archivo apuntando a él. La respuesta de @ MichaelHomer es más técnica y más detallada sobre este tema específico.


4

Las otras 2 respuestas explican bien el problema: un archivo no se "elimina" hasta que todos los directorios enlazan con él y todos los descriptores de archivo abiertos desaparecen.

Para evitar esto, es un buen hábito usar

> /var/log/bigfile

en lugar de

rm -f /var/log/bigfile

dado que eso solo restablece el contenido a 0 bytes en lugar de eliminarlo, y aún puede ver lo que está escrito en él.

Si eliminó el archivo y está en Linux donde tiene un sistema de archivos / proc / fd, aún puede usar

> /proc/12345/fd/3

poner a cero el contenido del archivo (suponiendo que 12345 es su identificación de proceso y 3 es el número fd del archivo grande). Esto puede salvarle la vida si su disco se está llenando y no puede eliminar el proceso que está escribiendo su archivo de registro por alguna razón.


> /var/log/bigfileelimina los datos existentes en el archivo pero no impide que los programas escriban allí. Hay muy pocas circunstancias en las que sea lo correcto. Diría que es un mal hábito entrar. Si desea eliminar un archivo, use rm. Si desea detener los programas que están escribiendo allí, elimínelos o haga que dejen de escribir antes o después de eliminarlos.
Gilles 'SO- deja de ser malvado'

1
@Giles, este tema trata sobre el hecho de que eliminar no ayudará si un programa todavía tiene el archivo abierto. Y si su disco está lleno porque algunos programas se comportan mal y se syslogdllenan /var/log/messages, > /var/log/messageses una opción mucho mejor que matar syslogd. Por supuesto, eso no debería impedirle analizar cuál es el problema en primer lugar.
Guntram Blohm apoya a Monica el
Al usar nuestro sitio, usted reconoce que ha leído y comprende nuestra Política de Cookies y Política de Privacidad.
Licensed under cc by-sa 3.0 with attribution required.