Introducción a SMF (Service Management Facility) en Solaris

SolarisHace unos días comentaba el paso de System V a Upstart en RHEL y Centos 6. Hoy vamos a hablar sobre Solaris y el cambio introducido a partir de Solaris 9 para la gestión de servicios.

Antes de Solaris 9 los servicios se gestionaban como en la mayoría de sistemas Unix y Linux (legacy), teníamos scripts de arranque en /etc/init.d y se creaban enlaces simbólicos contra ellos en los distintos runlevels (directorios RC) para su arranque/parada. A partir de Solaris 9 se introdujo SMF (Service Management Facility) y se ha convertido en la manera por defecto de gestionar los servicios en Solaris 10.

Los beneficios de SMF sobre el método anterior son sustanciales. Entre ellos la posibilidad de mantener monitorizados los servicios para que en el momento que se produzca una caída levanten de forma instantánea, la gestión inteligente de arranque mediante la cual el servicio tiene unas dependencias y hasta que no estén activas el servicio no está disponible, el arranque en paralelo y de forma asíncrona, etc.

Los comandos básicos para gestion de servicios en SMF son svcs, svccfg y svcadm. Mediante svcs a secas podemos ver el estado de los servicios del sistema (incluidos los del sistema antiguo legacy), a través de distintos parámetros podemos filtrar únicamente los deshabilitados, etc:

# svcs
STATE          STIME    FMRI
legacy_run      9:04:48 lrc:/etc/rc2_d/S20sysetup
legacy_run      9:04:48 lrc:/etc/rc2_d/S47pppd
legacy_run      9:04:49 lrc:/etc/rc2_d/S72autoinstall
legacy_run      9:04:49 lrc:/etc/rc2_d/S73cachefs_daemon
legacy_run      9:04:49 lrc:/etc/rc2_d/S81dodatadm_udaplt
legacy_run      9:04:49 lrc:/etc/rc2_d/S89PRESERVE
disabled        9:02:34 svc:/platform/i86pc/acpihpd:default
online          9:01:28 svc:/system/svc/restarter:default
online          9:01:35 svc:/system/early-manifest-import:default
online          9:01:38 svc:/network/netcfg:default
online          9:01:39 svc:/network/datalink-management:default
online          9:01:39 svc:/network/socket-config:default
...
...

Básicamente vemos el estado del proceso, la última vez que el servicio cambió de estado y su FMRI (Fault Management Resource Identifier). El FMRI es el identificador del servicio. El FMRI se divide en tres partes separadas por “:”. La primera el esquema (svc o lrc según el tipo de servicio), la categoría en la que se encuentra (network, system…) y el nombre del servicio, y finalmente la instancia.

Podemos ver también con detalle el estado de un único servicio con el parámetro “-x” y sus dependencias con “-d”:

# svcs -x  svc:/system/cron:default
svc:/system/cron:default (clock daemon (cron))
 State: online since  1 de noviembre de 2011 09:02:51 WET
   See: cron(1M)
   See: crontab(1)
   See: /var/svc/log/system-cron:default.log
Impact: None.
# svcs -d svc:/system/cron:default
STATE          STIME    FMRI
online          9:02:35 svc:/milestone/name-services:default
online          9:02:49 svc:/system/filesystem/local:default

Podemos verificar rápidamente cómo SMF monitoriza activamente los servicios que están bajo su control, vamos a ver el estado del servicio cron, matarlo con una señal kill y verificar que al momento SMF lo ha levantado de nuevo:

# date
martes  1 de noviembre de 2011 09:46:24 WET
# svcs -v system/cron
STATE          NSTATE        STIME    CTID   FMRI
online         -              9:02:51     62 svc:/system/cron:default
# ps -ef | grep cron
    root   441     1   0 09:02:51 ?           0:00 /usr/sbin/cron
    root   841   687   0 09:46:33 pts/1       0:00 grep cron
# kill 441
# svcs -v system/cron
STATE          NSTATE        STIME    CTID   FMRI
online         -              9:46:38     96 svc:/system/cron:default

A través de svcs también podemos ver el estado de un servicio y diagnosticarlo cuando no es satisfactorio. Encontraremos los siguientes estados: online, offline, disabled, degraded, maintenance y legacy-run. Los cuatro primeros estados están claros, online, offline, deshabilitado y degradado. Cuando un servicio está en estado maintenance es debido a que hay algún problema con el servicio y no puede ser arrancado. Como requiere nuestra intervención se pone a nuestra disposición la ruta hacia el log del servicio para verificar el origen del problema. El estado legacy-run simplemente indica que se trata de un servicio legacy.

Mediante svcadm podemos gestionar el estado de cada uno de los servicios, con los parámetros “enable”, “disable”, “refresh”, “clear”, “mark” y “restart”. Aparte de los obvios, conviene comentar que “refresh” sirve para leer de nuevo los ficheros de configuración del servicio por si se ha realizado algún cambio, “clear” sirve para resetear el servicio si se encuentra en estado de mantenimiento y “mark” para marcar un servicio como degradado, mantenimiento, etc.

Para que veáis un ejemplo de fichero xml básico para un servicio aquí tenéis uno para la gestión de Oracle iPlanet webserver 7 que instalamos hace unos días. Básicamente hemos establecido como dependencias los servicios de red, los sistemas de ficheros locales y el arranque bajo el milestone multi-user (lo que viene siendo el runlevel 3 en legacy). Después establecemos los tres comandos para el arranque, parada y reinicio del servicio:

<?xml version='1.0'?>

<!DOCTYPE service_bundle SYSTEM '/usr/share/lib/xml/dtd/service_bundle.dtd.1'>

<service_bundle type='manifest' name='webserver7'>

<service name='network/webserver7' type='service' version='0'>
<create_default_instance enabled='true'/>
<single_instance/>
<dependency name='fs' grouping='require_all' restart_on='none' type='service'>
<service_fmri value='svc:/system/filesystem/local'/>
</dependency>
<dependency name='net' grouping='require_all' restart_on='none' type='service'>
<service_fmri value='svc:/network/physical'/>
</dependency>
<dependent name='webserver7_multi-user' restart_on='none' grouping='optional_all'>
<service_fmri value='svc:/milestone/multi-user'/>
</dependent>
<exec_method name='start' type='method' exec='su www -c "/opt/webserver7/bin/webserver7 start"' timeout_seconds='60'>
<method_context/>
</exec_method>
<exec_method name='stop' type='method' exec='su www -c "/opt/webserver7/bin/webserver7 stop"' timeout_seconds='60'>
<method_context/>
</exec_method>
<exec_method name='restart' type='method' exec='su www -c "/opt/webserver7/bin/webserver7 restart"' timeout_seconds='60'>
<method_context/>
</exec_method>
</service>

</service_bundle>

Para importar un servicio creado de este modo ejecutamos el siguiente comando:

# svccfg import webserver7.xml

Como siempre os recomiendo revisar las páginas man de todos estos comandos para recibir información detallada sobre cada uno de ellos, esto es una pequeña introducción que podría extenderse mucho más si entráramos en detalle de cada una de las características y posibilidades de SMF. Ahí van unas cuantas referencias para aprender más sobre Service Management Facility:

2 comentarios en “Introducción a SMF (Service Management Facility) en Solaris

  1. Hola, excelente tu blog, siempre me llegan tus mails y los leo!!
    quería preguntarte si hay algún comando similar a svcs en debian/ubuntu, es excelente lo flexible que es esta herramienta.
    Lo mas parecido que encontre fue svc, pero no es lo mismo.

    gracias!!

  2. Hola Esteban,

    Algo similar en Debian será Upstart (que ya está en Ubuntu) pero todavía no lo han debido adoptar:

    Se ha anunciado que Debian esta considerando usar Upstart en su versión Squeeze

Deja un comentario

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *