Este reportaje está dirigido a
usuarios familiarizados con sistemas UNIX, con lo que no vamos a
explicar los detalles más comunes o conocidos de estos sistemas.
Este reportaje ha sido escrito por Fernando López Hernández para macprogramadores.org
y de acuerdo a las leyes internacionales sobre propiedad intelectual, a
la Directiva 2001/29/CE del Parlamento Europeo de 22 de mayo de 2001 y
al artículo 5 de la Ley 22/1987 de 11 de Noviembre de Propiedad
Intelectual Española, el autor prohíbe la publicación de este documento
en cualquier otro servidor web, así como su venta, o difusión en
cualquier otro medio sin autorización previa.
Sin embargo el autor anima a todos los servidores web a colocar enlaces a este documento. El
autor también anima a cualquier persona interesada en conocer el
proceso de arranque de Mac OS X y su configuración a bajarse o
imprimirse este reportaje.
Madrid, Septiembre 2005
Para cualquier aclaración contacte con:
fernando@macprogramadores.org
En Mac OS X 10.4 Apple introdujo un nuevo sistema de arranque coordinado por el programa launchd.
Este programa asume las responsabilidades de las que hasta ahora se
habían encargado otros programas más clásicos de UNIX como son mach_init, init, xinetd o cron. Antes de Mac OS X 10.4 el proceso de arranque estaba coordinado por los procesos mach_init e init los cuales ejecutaban el script /etc/rc
que preparaba el sistema para el usuario. Aunque este script todavía
existe, y se sigue usando para configurar el proceso de arranque, los
comandos mach_init e init han sido eliminados y sustituidos por el comando launchd (situado en /sbin/launchd) que es el nuevo proceso raíz del sistema.
¿Por qué el cambio en el sistema de arranque?
Tradicionalmente en UNIX la responsabilidad de arrancar el sistema y configurar sus distintos demonios y procesos ha estado delegado al menos a tres programas distintos:
1) init que es el primer proceso que se ejecuta, y que se encarga de arrancar y configurar los servicios más básicos.
2) xinetd
que es el encargado de lanzar los procesos que dan servicios de red.
Aunque inicialmente los sistemas UNIX no usaban TCP/IP para
comunicarse, con el tiempo se popularizó este protocolo, y fue cuando
se creó xinetd. Una peculiaridad característica de xinetd
es que puede lanzar los procesos bajo demanda, es decir, los demonios
que dan servicios de red pueden estar siempre lanzados, pero también
pueden lanzarse sólo cuando se conecta un cliente al puerto del
servicio.
3) cron
es un proceso que una vez lanzado se encarga de ejecutar otros procesos
periódicamente, o en una fecha determinada, de acuerdo a la
configuración indicada en el fichero /etc/crontab. El proceso launchd ha asumido ahora estas responsabilidades.
launchd ofrece principalmente tres ventajas respecto al mecanismo tradicional de arranque de Mac OS X. La primera ventaja es que con launchd se centraliza y estandariza toda la gestión de los demonios. También launchd
se encarga de gestionar los posibles límites de recursos que asignamos
a los programas, y de decidir con que cuenta de usuario se ejecuta cada
uno.
La segunda ventaja es que la configuración de todos los procesos launchd compatibles se hace en un fichero XML con la extensión .plist. Hasta ahora, cada comando tenía su propio fichero de configuración, y cada uno usaba su propio formato.
La tercera ventaja es que los procesos launchd
compatibles se pueden lanzar bajo demanda, lo cual permite no tener
cargados en memoria procesos que no se están usando. Además launchd
puede descargar de memoria un proceso si éste lleva mucho tiempo inactivo y se está necesitando memoria.
El proceso de arranque
El proceso de arranque de una máquina Mac OS X se puede resumir en cuatro pasos:
El primer paso es el arranque de la BIOS,
durante este proceso se comprueba el hardware disponible y se elige el
sistema operativo a ejecutar. Este primer paso se puede dividir en:
- POST (Power-On Self Test) donde se
determinar el hardware disponible y se comprueba que exista suficiente
memoria, así como que éste está en buen estado.
- Open
Firmware construye un árbol de dispositivos hardware existentes (una
representación jerárquica del ordenador), y elige el sistema operativo
a ejecutar.
El segundo paso sería la carga del núcleo
del sistema operativo. Se carga una imagen del núcleo en memoria.
Durante este proceso la máquina suele mostrar el icono con la manzana
de Apple. Al acabar la carga del núcleo se lanza el proceso de usuario
root, que es launchd.
Durante el tercer paso launchd lanza los demonios necesarios para configurar el sistema. Para ello launchd lanza los procesos indicados en el script /etc/rc, así como otro procesos que comentaremos más adelante. Esta es la parte que ha sido optimizada con el uso de launchd.
En el cuarto paso launchd lanza loginwindow que es el proceso encargado de autentificar a los usuarios y controlar su sesión.
Configurar demonios launchd
Los demonios launchd deben de colocarse como ficheros .plist bajo el directorio /Library/LaunchDaemons. También existe otro directorio /System/Library/LaunchDaemons, pero este directorio no debemos de usarlo, ya que está reservado para los demonios de Apple.
Los demonios pueden ser de dos tipos:
RunAtLoad, los cuales se ejecutan una vez al arrancar la máquina, y permanecen cargados durante toda la ejecución.
OnDemand, los cuales se ejecutan sólo cuando algún cliente intenta usar el servicio.
En principio, es mejor que los procesos se carguen OnDemand,
pero esto no siempre es posible, ya que para que un proceso se cargue
de esta forma tiene que haber seguido una serie de recomendaciones que
da Apple a los desarrolladores, como son el capturar la señal SIGTERM para terminar, o el que el proceso demonio no llame a la primitiva daemon()
para desligarse del proceso padre que lo creó. Si está intentando
añadir un proceso ya existente a la lista de demonios de su máquina,
use la opción RunAtLoad, a no ser que en la documentación del programa indique que es launchd compatible.
Como hemos dicho, para crear un demonio debe de crear un fichero .plist en la carpeta /Library/LaunchDaemons, indicando a launchd como lanzar el demonio.
Este
fichero debe de contener una serie de propiedades que se resumen en
la Tabla 1. Puede consultar una documentación más detallada
ejecutando man launchd.plist.
|
Clave
|
Tipo
|
Req.
|
Descripción
|
|
Label
|
string
|
Sí
|
Cadena única que identifica al job de launchd.
|
|
|
boolean
|
No
|
Permite deshabilitar un job. Por defecto es false.
|
|
UserName
|
string
|
No
|
Nombre de usuario con el que ejecutar el job. Por defecto es root.
|
|
GroupName
|
string
|
No
|
Grupo con el que ejecutar el job. Por defecto es wheel.
|
|
inetdCompatibility
|
dictionary
|
No
|
La presencia de esta clave indica que el proceso espera lanzarse como si estuviera configurado para inetd
|
|
ProgramArguments
|
array of strings
|
Sí
|
Argumentos de línea de comandos del demonio.
|
|
Program
|
string
|
No
|
Indica el comando a ejecutar. Si se omite se usa el primer argumento de ProgramArguments.
|
|
OnDemand
|
boolean
|
No
|
Indica si el proceso se lanza bajo demanda. Por defecto es true.
|
|
RunAtLoad
|
boolean
|
No
|
Indica si el proceso se lanza siempre al arrancar. Por defecto es false.
|
|
RootDirectory
|
string
|
No
|
Indica el directorio al que hacer chroot antes de ejecutar el proceso.
|
|
WorkingDirectory
|
string
|
No
|
Indica el directorio al que hacer chdir antes de ejecutar el proceso.
|
|
ServiceDescription
|
string
|
No
|
Permite dar una descripción del proceso
|
|
EnvironmentVariables
|
dictionary of strings
|
No
|
Variables de entorno a fijar antes de ejecutar el proceso
|
|
Umask
|
integer
|
No
|
Indica que debe de pasarse a umask antes de ejecutar el proceso.
|
|
ServiceIPC
|
boolean
|
No
|
Indica si el proceso se comunica con launchdinetdCompatibility. usando técnicas de IPC. El flag es incompatible con
|
|
TimeOut
|
integer
|
No
|
El tiempo máximo que tardará el job en arrancar.
|
|
StartInterval
|
integer
|
No
|
Indica cada cuanto tiempo debe de lanzarse el job. Usado para jobs periódicos.
|
|
StartCalendarInterval
|
dictionary of integer
|
No
|
Permite indicar fechas periódicas a las que lanzar el programa. Vea man launchd.plist
|
|
StandardOutPath
|
string
|
No
|
Fichero a usar como stdout.
|
|
StandardErrorPath
|
string
|
No
|
Fichero a usar como stderr.
|
|
SoftResourceLimits
HardResourceLimits
|
dictionary of integers
|
No
|
Indica límites a los recursos del proceso
como se indica en man launchd.plist.
|
|
Nice
|
integer
|
No
|
Indica un valor a pasar a nice para ejecutar el comando con menos prioridad.
|
|
Sockets
|
dictionary of strings
|
No
|
Permite indicar que sockets lanzan este proceso al llegar un cliente como se indica en man launchd.plist.
|
Tabla 1: Propiedades del fichero .plist de un demonio launchd
En la carpeta /System/Library/LaunchDaemons tiene varios demonios de ejemplo, pero aquí vamos a ver como se crearía un demonio para mldonkey, la conocida herramienta de intercambio de ficheros. Esta herramienta viene en la distribución Fink, y puede bajársela con:
$ fink install mldonkey
La herramienta se lanza usando el comando mlnet.
Una vez ejecutado este comando, en el directorio actual se crea una
serie de carpetas con la configuración del programa, así como con las
carpetas donde depositar los ficheros a intercambiar. El comando se
queda esperando a que nos conectemos a él: O bien haciendo un telnet al
puerto 4000, o bien conectándo vía web al puerto 4080.
Este es un buen ejemplo de comando que podemos tener ejecutando desde
que arrancamos la máquina hasta que la paramos. Luego usaremos la
entrada RunAtLoad.
Para indicar donde está el directorio con los ficheros compartidos podemos usar la entrada WorkingDirectory, y su queremos dar un usuario con el que lanzar el comando podemos usar la entrada UserName y GroupName.
La Figura 1 muestra el contenido del fichero .plist propuesto.

Figura 1: Fichero de configuración de mlnet
El fichero mlnet.plist
debe de tener permisos de sólo lectura para los usuarios que no sean
administradores, con el fin de evitar que un usuario sin permiso de
administración modifique estos ficheros. Apple pide que tengan permiso
de lectura para el grupo wheel,
con el fin de poder ser lanzados. El usuario que tengan como dueño debe
tener permiso de lectura y escritura (p.e. en mi caso el dueño es el
usuario fernando). Los ficheros del sistema (los de la carpeta /System/Library/LaunchDaemons) tienen como dueño a system, que es el dueño de todos los ficheros bajo la carpeta /System.
Testear un demonio
Antes de poner el demonio en la carpeta /Library/LaunchDaemons y reiniciar su máquina puede probar a ver si arranca correctamente. Para ello puede usar el comando launchctl y pedirle que cargue el demonio.
$ launchctl
launchd% load /Library/LaunchDaemons/mlnet.plist
Por
la salida que produzca este programa al lanzarle podrá saber si algo
está mal. Si todo va bien ya puede colocar el demonio en el directorio/Library/LaunchDaemons y reiniciar su máquina.
Resto del documento:
http://www.macprogramadores.org/tutoriales/propios/propios.shtml#ConfiguracionArranque