Solaris: añadir dependencias a un servicio SMF

Service Management Facility (SMF) permite establecer dependencias entre servicios. Esto, básicamente, abre la posibilidad de establecer una serie de requisitos en el momento de iniciar un servicio.

Por ejemplo, podemos indicar que para que un servicio pueda arrancar, antes debe tener montado un determinado filesystem, o incluso verificar que un archivo de configuración existe, tiene los permisos correctos y su propietario es el indicado.

Toda esta configuración se debe especificar en el manifesto del servicio, pero en lugar de editarlo a mano, lo mejor es hacerlo a través de la utilidad propia de SMF svccfg.

En el siguiente ejemplo vamos a configurar el servicio de MySQL para añadir como dependencia el servicio NFS:

# svccfg -s svc:/application/database/mysql:version_56
svc:/application/database/mysql:version_56> 
svc:/application/database/mysql:version_56> addpg nfs_client dependency
svc:/application/database/mysql:version_56> setprop nfs_client/grouping = astring: require_all
svc:/application/database/mysql:version_56> setprop nfs_client/entities = fmri: svc:/network/nfs/client:default
svc:/application/database/mysql:version_56> setprop nfs_client/type = astring: service
svc:/application/database/mysql:version_56> setprop nfs_client/restart_on = astring: none
svc:/application/database/mysql:version_56> end

Básicamente, lo que estamos haciendo es crear agregar al servicio un nuevo grupo de propiedades llamado nfs_client y que especifica que se requiere que todo lo que contenga el grupo esté levantado antes de arrancar MySQL, en este caso el servicio svc:/network/nfs/client:default. Si en lugar de un servicio fuera por ejemplo un archivo de configuración, en lugar de astring: service especificaríamos:

# svccfg -s application/foo:default setprop config_file/entities = fmri: file://localhost/etc/nfs.conf
# svccfg -s application/foo:default setprop config_file/type = astring: path

Es cuestión de empaparse la documentación para encontrar las distintas opciones. Importante también la parte de control de reinicio restart_on. Extraído directamente de la documentación:

As shown in the following table, if the value of the restart_on attribute of the dependency is none, the dependent service is not restarted when the dependency is stopped or refreshed. If the value of the restart_on attribute of the dependency is refresh, the dependent service is always restarted when the dependency is stopped or refreshed. If the value of restart_on is error, the dependent service is only restarted if the dependency stopped because of an error. If the value of restart_on is restart, the dependent service is only restarted if the dependency was refreshed.

Once running (online or degraded), if a service cited by a require_all, require_any, or optional_all dependency is stopped or refreshed, the SMF considers why the service was stopped and the restart_on attribute of the dependency to decide whether to stop the service.

                    |  restart_on value
event              |  none  error restart refresh
-------------------+------------------------------
stop due to error  |  no    yes   yes     yes
non-error stop     |  no    no    yes     yes
refresh            |  no    no    no      yes

Una vez añadida la dependencia al servicio, se puede hacer un refresh del mismo para aplicar los cambios:

# svcadm refresh svc:/application/database/mysql:version_56

# svcprop svc:/application/database/mysql:version_56 | grep -i nfs
nfs_client/grouping astring require_all
nfs_client/entities fmri svc:/network/nfs/client:default
nfs_client/type astring service
nfs_client/restart_on astring none