Aquí dice que puede reescribir un archivo ejecutable y el proceso se ejecutará bien, se volverá a leer cuando se reinicie un proceso.
Sin embargo, cuando trato de reemplazar un archivo binario mientras se ejecuta el proceso (con scp, desde dev hasta el servidor de prueba) dice 'archivo ocupado'. Y si reemplazo un archivo de biblioteca compartida (* .so), todos los procesos que lo vinculan fallan.
¿Porque? ¿Me estoy perdiendo de algo? ¿Cómo puedo reemplazar los archivos binarios sin detener / bloquear un proceso?
.so
archivo usandoldd filename.so
para verificar las dependenciasstop app && create symlink of .so && start app
Respuestas:
Como se mencionó en ¿Por qué un paquete de software funciona bien incluso cuando se está actualizando? , el bloqueo se coloca en inode no en nombre de archivo. Cuando carga y ejecuta un archivo binario, el archivo se marca como ocupado, razón por la cual obtiene el error ETXTBSY (archivo ocupado) cuando intenta escribir en él.
Ahora, para las bibliotecas compartidas es ligeramente diferente: las bibliotecas asignan memoria al espacio de direcciones del proceso con
mmap()
. AunqueMAP_DENYWRITE
se puede especificar, al menos Glibc en Linux lo ignora silenciosamente (de acuerdo con la página del manual, no dude en verificar las fuentes) - verifique este hilo . De ahí que en realidad se le permite escribir el archivo y, ya que es la memoria asignada, los cambios son visibles casi de inmediato - que significa que si se esfuerza lo suficiente se pueden gestionar a ladrillo su máquina al sobrescribir la biblioteca.Por lo tanto, la forma correcta de actualizar es:
eliminar el archivo, que elimina la referencia a los datos del sistema de archivos, de modo que no sea accesible para ninguna aplicación recién generada que pueda querer usarlo, mientras mantiene los datos accesibles para cualquier persona que ya lo tenga abierto (o asignado) ;
creando un nuevo archivo con contenido actualizado.
Los procesos recién creados utilizarán los contenidos actualizados, las aplicaciones en ejecución accederán a la versión anterior. Esto es lo que hace cualquier utilidad de administración de paquetes sensata. Sin embargo, tenga en cuenta que no está completamente libre de peligro: por ejemplo, las aplicaciones que cargan dinámicamente código (usando
dlsym()
y amigos) experimentarán problemas si la API de la biblioteca cambia en silencio.Si desea estar realmente seguro, apague el sistema, monte el sistema de archivos desde otra instancia del sistema operativo, actualice y vuelva a abrir el sistema actualizado.
fuente
Una actualización de rpm hace lo mismo: ejecuta binarios y bibliotecas mientras nada falla.
Entonces cuál es la diferencia:
Esto NO reemplazará el archivo in situ: el inodo que se refiere al binario en uso todavía está "ocupado" hasta que finalice el último objeto que lo mantiene abierto. El nuevo archivo se creará con un nuevo número de inodo.
Ahora
scp
ocp
intentará reemplazar el archivo en el lugar, lo que cambiaría el contenido al que se refiere el inodo. Esto no funciona, como lo describiste.fuente