2009-11-10 7 views
19

Tengo un sistema Linux incorporado que puede actualizarse a sí mismo desde una tarjeta USB. El programa de interfaz detecta la inserción USB y busca el ejecutable actualizado. Actualmente lo copio en un archivo local e instalo algunos comandos en rc5.d para copiar el archivo sobre el exe existente en el siguiente inicio. Luego tengo el reinicio del software.Reemplazo de un ejecutable que se ejecuta en Linux

¿Hay una mejor manera de hacerlo?

+0

esta respuesta le ayudará a entender cómo hacer esto: http://stackoverflow.com/a/21115731/2706918 –

Respuesta

8

En Linux, puede reemplazar de forma segura el ejecutable en ejecución mientras se ejecuta el proceso. Mientras el proceso se esté ejecutando, esa instancia continuará usando el código "antiguo". Todas las llamadas nuevas a la aplicación usarán el código "nuevo". Entonces, simplemente reiniciando la aplicación (o el dispositivo si es necesario) usará la nueva copia.

Tenga en cuenta que debe tener cuidado si su aplicación cambiará los archivos de configuración o las bibliotecas, ya que es posible que no estén en la memoria. En este caso, la apuesta más segura es hacer que un script haga lo que usted mencionó.

+1

El punto crucial para mencionar es que necesita tener que 'desvincular()' el archivo original primero (por ejemplo, usando el comando 'rm') para que esta garantía se mantenga. –

29

No es necesario que copie el archivo en el siguiente inicio. En cambio, esta secuencia funcionará bien:

  • Copie nuevo archivo ejecutable en un archivo local.
  • Verifica el archivo local.
  • unlink() ejecutable existente.
  • rename() nuevo ejecutable con el nombre correcto.

La aplicación seguirá ejecutándose después del unlink() - el núcleo no lanzará los datos subyacentes hasta que todas las copias en ejecución hayan finalizado.

Incluso puede simplemente usar execve() para que el proceso actual se reemplace por la versión recién cargada.

21

Está bien para reemplazar el ejecutable mientras que el programa se está ejecutando SI que rm (desvincula) en primer lugar.

Esto no es lo que sucede con cp, entonces no lo use. O bien mv el archivo, o, para estar realmente seguro, rm y luego coloque el nuevo en el mismo lugar. Si está haciendo esto con el código en el software incrustado, entonces es con lo que desea comenzar con unlink(2).

Los kernels de Unix saben que el inodo todavía está en uso, y eliminarán la entrada de directorio para el archivo pero no liberarán el inode (y los bloques de datos) hasta que el recuento de referencia de inodo llegue a cero, y que ganó No ocurre mientras se ejecuta una instancia de este.

Probablemente esto no sea un problema con su sistema integrado, pero como precaución general, no confíe en que esto funcione para el almacenamiento en red, excepto cuando se encuentre en el servidor.

+0

Supongo que también debería agregar que está bien si la conexión de red se realiza debajo de la capa del sistema de archivos; entonces esta técnica estaría bien con iSCSI. – DigitalRoss

Cuestiones relacionadas