2012-09-07 38 views
6

Contexto:¿Cómo me aseguro de que un proceso en ejecución sea el proceso que espero se esté ejecutando?

Tengo un Linux [1] sistema que gestiona una serie de de Daemon de terceros con los que las interacciones se limitan a desembolsar [2] scripts de inicio, es decir, sólo {Inicio | reinicio | stop | status} están disponibles.

Problema:

Los procesos pueden asumir el PID de un proceso previamente en marcha, el estado de los procesos son controlados por la inspección de la presencia de unos procesos en ejecución con el mismo de la PID.

Ejemplo:

Proceso de una carrera con PID 123, muere posteriormente, se inicializa proceso B con PID 123 y el comando de estado responde con un no auténtico (errónea) "OK". En otras palabras, solo verificamos la presencia de un proceso desde su PID para validar que el proceso se está ejecutando, suponemos que si un proceso con este PID existe, es el proceso en cuestión.

Soluciones propuestas:

  1. interrogar al proceso, usando el PID, para asegurar el comando/demonio que se ejecuta como el PID es como se esperaba. El problema con esta solución es que tanto el comando como el PID deben coincidir; por lo tanto, es necesario mantener y sincronizar múltiples bits de información, y agregar complejidad adicional a las condiciones de error/borde.
  2. Correlacione el tiempo de creación del archivo PID con la hora de inicio del proceso, si el proceso está dentro de un cierto delta del tiempo de creación del archivo PID, podemos estar bastante seguros de que el comando/daemon en ejecución es el esperado.

¿Existe alguna forma estándar de ratificar la autenticidad de un archivo de proceso/PID, más allá de la presencia de un proceso que se ejecuta con ese PID? Es decir. Yo (como el sistema) quiero saber si usted (el proceso) se está ejecutando y si usted es quien creo que es (A y no B).

Suponiendo que hemos elegido implementar la segunda solución propuesta anteriormente, ¿qué intervalo de confianza/delta entre el tiempo de creación del PID y la hora de inicio del proceso es razonable? Aquí, razonable significa un compromiso aceptable entre los errores tipo 1/tipo 2.

[1] CentOS/RHEL [2] Bash

+1

¿No debería estar esto en [ServerFault] (http://serverfault.com/)? – Graham

+0

¿Puede realizar cambios en los demonios de terceros por sí mismos? Si es así, puede usar 'flock' para crear algunos bloqueos de sistema de archivos para los daemons. –

+2

¿Estás seguro de que los identificadores de proceso se reutilizan a la vez? Sé que ese es el caso de Windows, pero no lo he observado en Linux o UNIX. Ver http://stackoverflow.com/questions/3446727/how-does-linux-determine-the-next-pid – cdarke

Respuesta

5

El contenido del archivo:

/proc/{PID}/cmdline

es la línea de comandos utilizada para comenzar el proceso Es eso lo que necesita?

+0

Esto se consideró en la solución propuesta 1: todavía me exige mantener un duplicado del comando pid al ratificar el proceso. Mantener ambos bits de información, aunque plausible, agrega complejidad adicional. – Gary

+0

Gary, ¿quieres resultados "bastante seguros" o "ciertos"? Si las estimaciones y los resultados aproximados son lo suficientemente buenos (y solo USTED puede ser el juez de eso), intente implementar su segunda solución, y si tiene problemas con su código, publíquelos en StackOverflow. Este es un sitio de preguntas y respuestas para la programación, no la mejor administración del sistema. Mientras tanto, considere cambiar a [Daemontools] (http://cr.yp.to/daemontools.html) en lugar de iniciar cosas con las secuencias de comandos init. – ghoti

+0

Gracias por la sugerencia, ghoti. Tengo interpretaciones en funcionamiento de ambas soluciones propuestas; Estoy tratando de determinar si existe un enfoque recomendado/estándar para resolver este problema. – Gary

0

Mi solución fue capturar el comando (a través de /proc/PID/cmdline) junto con el relativo hora de inicio. Es posible que el uso del absolute start time (a través de ps -p PID -o lstart=) funcione, pero obtendrás confusing results if your system clock changes (por ejemplo, de una actualización NTP o horario de verano).

Aquí está mi aplicación:

# Prints enough detail to confirm a PID still refers to the same process. 
# In other words, even if a PID is recycled by a call to the same process the 
# output of this command should still be different. This is not guaranteed 
# across reboots. 
proc_detail() { 
    local pid=${1:?Must specify PID} 
    # the process' commandline, if it's running 
    # ensures a non-existant PID will never have the same output as a running 
    # process, and helps debugging 
    cat "/proc/$pid/cmdline" 2> /dev/null && echo 
    # this is the number of seconds after boot that the process started 
    # https://unix.stackexchange.com/a/274722/19157 
    # in theory this could collide if the same process were restarted in the same 
    # second and assigned the same PID, but PIDs are assigned in order so this 
    # seems acceptably unlikely for now. 
    echo "$(($(cut -d. -f1 < /proc/uptime) - \ 
      $(ps -p "$pid" -o etimes= 2> /dev/null || echo "0")))" 
} 

También decidí guardar esta salida en /dev/shm de manera que se borra automáticamente al cerrar el sistema para mí. Hay otras opciones viables (como un cronjob @reboot) pero para mi caso de uso, escribir en un tmpfs fue fácil y limpio.

Cuestiones relacionadas