Timers en systemd, reemplazo a cron

Odiado por muchos, alabado por otros, systemd se ha impuesto como el init por excelencia del mundo Linux. Las distros más populares como Debian, Ubuntu, Fedora, openSUSE y Arch Linux usan systemd por defecto. Hoy vengo a hablaros de una característica interesante de systemd que son son los timers. Se trata de poder definir que arranquen programas/servicios cada cierto tiempo o a una hora, su versatilidad es tal que pueden sustituir a cron en la mayoría de casos. Veamos como usar los timers.

Creando un servicio

Para crear un timer primero necesitamos crear un servicio simple que ejecute el comando que queramos al ser iniciado.

Crea el archivo miapp.service y ponlo en /etc/systemd/system/.

[Unit]
Description=Cat Mania GIF

[Service]
ExecStart=/home/pi/charlatan/catmania.py

 

Creando el timer

Para el timer es necesario un archivo con extensión timer en /etc/systemd/system/. Se suele usar el mismo nombre que el que tiene el servicio para escenarios simples. El archivo miapp.timer quedaría así:

[Unit]
Description=Run Cat Mania daily

[Timer]
OnCalendar=daily
RandomizedDelaySec=5min
Unit=catmania.service

[Install]
WantedBy=timers.target

 

Aquí es donde podemos realizar toda la magia de los timers. Los timers de systemd tienen dos modos de funcionamiento. En el primer modo, systemd ejecutará el timer cada cierto tiempo desde el arranque del sistema ( o algo más tarde si no queremos saturar el sistema). El otro modo es el modo calendario donde podemos especificar fechas y horas con wildcards y patrones. Además, es posible modificar la hora exacta de ejecución del timer con las propiedades de Randomize y que evitan que si hay varios timers configurados a la vez, no lo hagan exactamente a la vez (pero siempre dentro de un margen). Otras opciones para OnCalendar pueden ser:

OnCalendar=Wed,Sun *-*-10..15 12:00:00

En ese caso, el timer se activaría los miércoles y domingos que cayesen entre el 10 y el 15 de todos los meses a las 12 horas.

Activando el timer

Una vez estén copiados los archivos service y timer ejecutamos:

systemctl start miapp.timer
systemctl enable miapp.timer

Ya solo queda esperar a que systemd lance el servicio en la fecha y hora especificados.

Monitorización

Los timers están integrados con systemd, por lo que los logs se registran con journalctl. Podemos inspeccionarlos de forma sencilla:

journalctl -f -u miapp.service
journalctl -f -u miapp.timer

Para revisar los timers instalados y activos en el sistema puedes usar el comando:

systemtctl list-timers

Y ya estaría. De este modo podemos usar systemd como reemplazo de cron. Yo personalmente lo prefiero, ya que me parece una sintaxis más clara.

Emulando a Linus Torvalds: Crea tu propio sistema operativo desde 0 (VII)

Este artículo lo escribí para el blog en español DesdeLinux el 25 de agosto de 2014 y ahora lo dejo aquí, en mi blog personal. El artículo está tal cual, sin ninguna modificación desde aquella fecha.

Bienvenidos a otro post sobre cómo crear nuestro propio sistema operativo. Ha pasado mucho tiempo desde el último post, debido principalmente a un bug que encontré en lo que nos toca hoy. Veremos cómo manejar el reloj en arquitecturas x86.

Anteriormente habíamos activado los IRQ de manera genérica, pero hubo un pequeño problema ya que no los activábamos correctamente y pasábamos datos extra. Finalmente lo solucionamos carlosorta y yo y os puedo seguir comentando cómo seguir.

Bien, el reloj es un IRQ, concretamente el primero. Para configurarlo usaremos la función que definimos anteriormente para instalar de manera genérica los IRQ, la NDIRQInstallHandler.

El código se ejecuta de la siguiente manera: el sistema de inicialización llama a ND::Timer::Setup, que llama a NDIRQInstallHandler para insertar en la primera posición, el IRQ0, una función de callback cuando el evento se produzca, esa es NDTimerHandler que aumenta los ticks. Como hemos puesto la velocidad del reloj a 18 Hz, como veremos más adelante, si lo dividiésemos entre 18 y nos diese entero habría pasado un segundo.

La función ND::Timer::Phase nos sirve para ajustar la velocidad del timer, ese número tan extravagante es 1.19 MHz que es un valor común. Bien, esta función la deberemos llamar si quisiésemos cambiar la velocidad del timer, por defecto va a 18,22 Hz, un valor peculiar que debió de decidir alguien dentro de IBM y se ha quedado hasta nuestros días.

La función ND::Timer::Wait es bastante simple, solamente espera con un bucle while hasta que se hayan alcanzado los ticks necesarios para continuar.

En la imagen podemos comprobar que si descomentamos el código dentro del NDTimerHandler obtenemos esto:

NextDivelSegundos