2012-09-26 26 views
8

Tenemos una aplicación personalizada de daemon de C++ que se bifurca una vez. Por lo que hemos estado haciendo esto en nuestro script Upstart en Ubuntu 12.04 y funciona perfectamente:¿Cómo establecer la variable de entorno en el precomienzo en el script Upstart?

expect fork 
exec /path/to/the/app 

Sin embargo, ahora tenemos que pasar en un argumento a nuestra aplicación que contiene el número de CPU en la máquina en la que se carreras:

cat /proc/cpuinfo | grep processor | wc -l 

nuestro primer intento fue la siguiente:

expect fork 
exec /path/to/the/app -t `cat /proc/cpuinfo | grep processor | wc -l` 

Mientras que comienza nuestra aplicación con el valor -t correcta, Upstart un seguimiento del valor PID mal, estoy asumiendo porque los gatos , grep & wc ordena todos los procesos de inicio en el servidor antes de nuestra aplicación.

También probé esto, e incluso no funciona, supongo porque al configurar un env var se ejecuta un proceso? Upstart todavía sigue el mal pid:

expect fork 
script 
    NUM_CORES=32 
    /path/to/the/app -t $NUM_CORES 
end script 

También he intentado hacer esto en una estrofa env pero al parecer los que no se ejecutan comandos:

env num_cores=`cat /proc/cpuinfo | grep processor | wc -l` 

También probamos a hacer esto en pre-salida, pero env vars puesto en ella no tienen ningún valor en la estrofa ejecutivo:

pre-start 
    NUM_CORES=32 
end script 

alguna idea de cómo conseguir este NUM_CORES configurado correctamente, y aún así obtener Upstart para rastrear el PID correcto para nuestra aplicación que se bifurca una vez?

Respuesta

16

Es incómodo. El método recomendado es escribir un archivo env en la estrofa de preinicio y luego buscarlo en la estrofa del guión. Es ridículo, lo sé.

expect fork 

pre-start script 
    exec >"/tmp/$UPSTART_JOB" 
    echo "NUM_CORES=$(cat /proc/cpuinfo | grep processor | wc -l)" 
end script 

script 
    . "/tmp/$UPSTART_JOB" 
    /path/to/app -t "$NUM_CORES" 
end script 

post-start script 
    rm -f "/tmp/$UPSTART_JOB" 
end script 

que utilizar la línea exec en la pre-salida, porque por lo general tienen múltiples variables env y que no quieren repetir el código de redirección.

Esto solo funciona porque el '. 'comando está integrado en guión y, por lo tanto, no se genera ningún proceso.

+0

súper útil! Una cosa: creo que todavía necesita usar "exec/ruta/a/aplicación" dentro del bloque de script si eso es lo que necesitaba para el seguimiento de pid antes. Una vez que agregué "exec", esto funcionó maravillosamente para mí. –

+0

@ CodyA.Ray que depende completamente del comportamiento de bifurcación del servicio que se inicia. En nuestro caso, 'expect daemon' puede haber sido apropiado. – mpm

0

yo añadiría

export NUM_CORES 

después de asignar un valor en el "guión". Recuerdo que un/bin/sh vinculado simbólicamente a un shell que no es Bash puede ejecutar scripts, por lo que evitaría las construcciones Bash-only.

Re: usando la estrofa "env", pasa los valores literalmente y no los procesa utilizando convenciones de shell.

2

Según config advenedizo de zram-config:

script 
    NUM_CORES=$(grep -c ^processor /proc/cpuinfo | sed 's/^0$/1/') 
    /path/to/the/app -t $NUM_CORES 
end script 
+0

El problema es que '$()' divide un proceso hijo (y luego el conducto causa otro fork), lo que puede confundir el seguimiento del fork.Si bifurca más de dos veces antes de su demonio real, el advenedizo más viejo no puede rastrear el proceso del daemon y luego reaparecer no funcionará correctamente. Esto funciona para zram-config porque solo se ejecuta una vez y no necesita reaparecer, pero no es universal. :) Es por eso que la respuesta de @mpm es necesaria. – dannysauer

Cuestiones relacionadas