2009-11-16 12 views
25

¿Cuál es la forma correcta de crear un demonio de Unix o Linux con buen comportamiento en Ruby?Crear un daemon con doble horquilla en Ruby

¿Cuál es la definición de un demonio de buen comportamiento de todos modos, y cómo uno podría escribir tal programa en Ruby?

Respuesta

50

Según Programación Avanzada Stevens en el entorno UNIX capítulo 13, este es el procedimiento para hacer un demonio de Unix buen comportamiento:

  1. Tenedor y tienen la salida de los padres. Esto hace que el script de shell o de arranque piense que el comando está hecho. Además, se garantiza que el proceso secundario no será un líder de grupo de proceso (un requisito previo para setsid)
  2. Llame al setsid para crear una nueva sesión. Esto hace tres cosas:
    1. El proceso se convierte en un líder de la sesión de una nueva sesión
    2. El proceso se convierte en el líder del grupo de proceso de un nuevo grupo de procesos
    3. El proceso no tiene control de terminal
  3. Opcionalmente, bifurque nuevamente y haga que el padre salga. Este guarantes que el demonio no es un líder de la sesión ni puede adquirir un terminal de control (bajo SVR4)
  4. Cambiar el directorio de trabajo actual a / para evitar interferir con el montaje y desmontaje de
  5. Conjunto máscara de modo de creación de archivos a 000 para permitir creación de archivos con cualquier permiso requerido más adelante.
  6. Cerrar las descripciones de archivos innecesarias heredadas del padre (no hay ninguna terminal de control de todos modos): stdout, stderr y stdin.

Hoy en día hay un archivo para rastrear el PID que se utiliza en gran medida por los scripts de arranque de distribución de Linux. Asegúrese de escribir el PID del nieto, ya sea el valor de retorno de la segunda bifurcación (paso 3) o el valor de getpid() después del paso 3.

Aquí hay una implementación de Ruby, en su mayoría traducida del libro, pero con el doble tenedor y escribir el daemon PID.

# Example double-forking Unix daemon initializer. 

raise 'Must run as root' if Process.euid != 0 

raise 'First fork failed' if (pid = fork) == -1 
exit unless pid.nil? 

Process.setsid 
raise 'Second fork failed' if (pid = fork) == -1 
exit unless pid.nil? 
puts "Daemon pid: #{Process.pid}" # Or save it somewhere, etc. 

Dir.chdir '/' 
File.umask 0000 

STDIN.reopen '/dev/null' 
STDOUT.reopen '/dev/null', 'a' 
STDERR.reopen STDOUT 
+4

O utilice http://daemons.rubyforge.org – ephemient

+0

Esto realmente es una excelente explicación! Muchas gracias por responder tu propia pregunta. No todos hacen esto, incluso si encontraron una solución al problema allí más tarde. – t6d

+0

¡De nada! Estoy feliz de contribuir. – JasonSmith