Demonizar un programa como servicio es muy sencillo en FreeBSD, tan solo debemos crear un script de RC para ello, en este artÃculo explicaremos mediante un programa en C muy básico como hacerlo.
Creamos un sencillo programa que no hará nada mas que permanecer en marcha eternamente:
#include <stdio.h>
#include <unistd.h>
int main(){
while(1) {
sleep(1);
}
}
Compilamos el software:
Creamos el script de RC que controlará nuestro programa, lo creamos bajo /usr/local/etc/rc.d/ ya que es un script que NO forma parte del sistema base:
#!/bin/sh
#
# PROVIDE: kr0mUtility
# REQUIRE: DAEMON
# KEYWORD: shutdown
. /etc/rc.subr
name=kr0mUtility
rcvar=kr0mUtility_enable
command="/root/kr0mUtility"
start_cmd="kr0mUtility_start"
pidfile="/var/run/${name}.pid"
kr0mUtility_start(){
echo "starting kr0mUtility."
/usr/sbin/daemon -c -f -p ${pidfile} ${command}
}
load_rc_config $name
run_rc_command "$1"
Asignamos los permisos necesarios al script de RC:
chown root:wheel /usr/local/etc/rc.d/kr0mUtility
NOTA: Si nuestro programa hiciese un fork en background no harÃa falta un start_cmd ni la función, simplemente con la lÃnea command ya serÃa suficiente. Si solo se pone esa lÃnea con el programa mostrado cuando arranca la shell se queda “dentro” del programa hasta que presionamos Ctrl+c
Damos de alta nuestro servicio:
kr0mUtility_enable="yes"
Comprobamos el estado del servicio:
kr0mUtility is not running.
Lo arrancamos:
starting kr0mUtility.
Volvemos a comprobar el servicio:
kr0mUtility is running as pid 98683.
Podemos ver el proceso daemon que ha arrancado nuestra utilidad:
root 98395 0.0 0.0 10812 2364 - Ss 09:27 0:00.00 daemon: /root/kr0mUtility[98683] (daemon)
root 98683 0.0 0.0 10648 2272 - S 09:27 0:00.00 /root/kr0mUtility
root 11987 0.0 0.0 11272 2732 0 S+ 09:27 0:00.00 grep kr0mUtility
Paramos el servicio:
Stopping kr0mUtility.
Waiting for PIDS: 98683.
Comprobamos el estado:
kr0mUtility is not running.
Comprobamos que ya no existe el proceso de la utilidad ni del daemon:
root 54321 0.0 0.0 11272 2732 0 S+ 09:27 0:00.00 grep kr0mUtility
Si nuestra utilidad requiere de algún otro servicio en el script RC debemos indicarlo, el parámetro en cuestión es REQUIRE, podemos sacar un listado de los servicios disponibles con:
grep PROVIDE /usr/local/etc/rc.d/*
Hay algunas dependencias con las que se han formado grupos para no tener que incluir una por una:
- NETWORK/NETWORKING: This is a dummy dependency, for services which require networking to be operational before starting.
- SERVERS: This is a dummy dependency, for early-start servers relying on some basic configuration.
- DAEMON: This is a dummy dependency, to ensure that general purpose daemons are run after the above are(NETWORKING SERVERS).
- LOGIN: This is a dummy dependency to ensure user services such as xdm, inetd, cron and kerberos are started after everything else, in case the administrator has increased the system security level and wants to delay user logins until the system is (almost) fully operational.
- FILESYSTEMS: This is a dummy dependency, for services which require filesystems to be mounted before starting. Â It also serves as the default early / late divider; after this point, rc.d directories are rescanned to catch scripts from other filesystems than /.
También nos puede resultar de utilidad las KEYWORDs:
- nojail: The service is not for jail(8) environment. The automatic startup and shutdown procedures will ignore the script if inside a jail.
- nojailvnet: only allow vnet-enabled jails
- nostart: The service is to be started manually or not started at all. The automatic startup procedure will ignore the script. In conjunction with the shutdown keyword, this can be used to write scripts that do something only at system shutdown.
- shutdown: This keyword is to be listed explicitly if the service needs to be stopped before system shutdown.
En el artÃculo sobre Django podemos encontrar un ejemplo de un servicio real como es Daphne.