Documenti di Didattica
Documenti di Professioni
Documenti di Cultura
0a
Community Edition
Comunidad OpenSolaris Hispano
es.opensolaris.org
Licencia
Esta obra está bajo una licencia de Creative Commons. Para ver una copia de esta licencia, visite
http://creativecommons.org/licenses/by-sa/2.5/ o envíe una carta a Creative Commons, 559 Nathan
Abbott Way, Stanford, California 94305, USA.
Usted es libre de:
- Copiar, distribuir y comunicar públicamente la obra y hacer obras derivadas.
Bajo las condiciones siguientes:
• Reconocimiento. Debe reconocer los créditos de la obra de la manera especificada por el autor o el
licenciador (pero no de una manera que sugiera que tiene su apoyo o apoyan el uso que hace de su
obra).
• Compartir bajo la misma licencia. Si altera o transforma esta obra, o genera una obra derivada,
sólo puede distribuir la obra generada bajo una licencia idéntica a ésta.
• Al reutilizar o distribuir la obra, tiene que dejar bien claro los términos de la licencia de esta obra.
• Alguna de estas condiciones puede no aplicarse si se obtiene el permiso del titular de los
derechos de autor
• Nada en esta licencia menoscaba o restringe los derechos morales del autor.
Referencias
Todos los nombres propios de programas, sistemas operativos, equipos hardware, etc., que aparecen en este
libro son marcas registradas de sus respectivas compañías u organizaciones.
2
Comunidad OpenSolaris Hispano
OpenSolaris
OpenSolaris nace en Junio de 2005 y es el resultado de la liberación de la mayor parte del código
fuente de Solaris pasando a ser un proyecto de software libre. Desde este nuevo enfoque nacen nuevas
distribuciones que aportan mejoras al sistema además de enriquecerlas con más software.
Distribuciones OpenSolaris
De las diferentes aportaciones realizadas por comunidades de usuarios o desarrolladores nacen las
siguientes distribuciones:
• Solaris 10: es la versión oficial de Sun Microsystems disponible para arquitectura Sparc y x86. Es
estable y robusta estando diseñada para entornos de producción donde se necesita estabilidad. Es
gratuita y podemos descargarla del sitio web oficial de Sun.
• Solaris Express Community Edition: su nombre en clave es “nevada” es una distribución binaria que
se actualiza cada dos viernes, es una versión que puede no ser compatible con otras versiones ya que
incorpora muchos cambios.
• Solaris Express Developer Edition: contiene todas las nuevas incorporaciones de funcionalidades y
software que darán lugar a la próxima versión estable de Solaris por lo tanto esta recomendada para
entornos de desarrollo o preproducción. Se actualiza cada tres o cuatro meses.
• OpenSolaris Developer Preview: mas conocida como OpenSolaris 2008.05 es una distribución en
un solo CD que combina livecd e instalación en disco. OpenSolaris 2008.05 esta en sus primeras
3
Comunidad OpenSolaris Hispano
fases de desarrollo. Las versiones actualmente liberadas no son totalmente estables. Incluye un kit
para crear tu propia distribución y es instalable en una llave USB.
• Nexenta OS: es una distribución totalmente independiente a Sun y esta basado en GNU libre y de
código abierto, integra el kernel de OpenSolaris y un conjunto de aplicaciones Open Source. Es una
distribución que comparte la filosofía de a Ubuntu.
• Belenix: LiveCD basado en OpenSolaris que esta dando pasos en convertirse en una distribución
completa. Aporta un conjunto de software OpenSource. Incluye scripts para crear tu propio livecd y
se puede instalar y arrancar desde una llave USB.
• MartUX mBE :es un DVDlive para SPARC y x64/x86 y esta cargado de paquetes de
CommunitySoftWare.
• Shillix: es una distro basada en OpenSolaris y es LiveCD para arquitecturas x86,x64 y EM64T. Esta
basada en Nevada Build 17.
OpenGrok
OpenGrok es el motor de búsqueda de código fuente, con OpnGrok podemos descargar el fuente
de OpenSolaris y examinar su código ademas de poder hacer modificaciones para realizar modificaciones al
ya existente.
Para entrar en OpenGrok entre en la dirección:
http://cvs.opensolaris.org/source
Las comunidades
Las comunidades son puntos de encuentro dentro de OpenSolaris.org donde puedes encontrar otras
personas con las mismas inquietudes sobre una tecnología o apliación. Hay comunidades alrededor de ZFS,
DTrace, SMF, Virtualización etc..
Algunas de las comunidades:
4
Comunidad OpenSolaris Hispano
Proyectos
Los proyectos alojados en www.opensolaris.org albergan las contribuciones de código, documentos,
gráficos o productos de varios autores. Los proyectos disponen de espacio para alojar código.
Participa
Puedes participar en la comunidad OpenSolaris Hispano de formas diferentes y da igual tu nivel de
experiencia con OpenSolaris.
5
Comunidad OpenSolaris Hispano
6
Comunidad OpenSolaris Hispano
• Sun xVM Hypervisor (basado en el trabajo de la comunidad Xen permitiendo correr Solaris,
GNU/Linux y Windows en máquinas virtuales)
Requisitos de Instalación
Antes de comenzar la instalación debemos comprobar si la maquina destino cumple con los
requisitos demandados por OpenSolaris 2008.05 . En la siguiente tabla podemos ver dichos requisitos
mínimos:
• Reiniciar.
Iniciando el LiveCD
Comenzamos el proceso de instalación arrancando desde CD con el LiveCD de OpenSolaris
2008.05 , lo primero que veremos será el gestor de arranque GRUB.
OpenSolaris 2008.05 comenzara a iniciarse y solicitará el idioma del teclado y del escritorio como podemos
ver en las siguientes capturas:
7
Comunidad OpenSolaris Hispano
Después de seleccionar el idioma continua el arranque del sistema y procede a arrancar el escritorio
GNOME donde nos muestra la licencia.
8
Comunidad OpenSolaris Hispano
Una vez aceptada la licencia veremos el escritorio donde tenemos el sistema totalmente operativo en
modo live, ahora tenemos que iniciar la instalación. Para ello arrancamos el instalador identificado en el
escritorio como “Install OpenSolaris”.
Al arrancar nos mostrará el proceso de instalación que consiste en un volcado a disco de todo el
sistema. Los pasos del instalador son:
1. Pantalla de bienvenida.
2. Seleccionar el disco o partición donde vamos a instalar.
3. Seleccionar la zona horaria.
4. Introducimos la contraseña, creamos un usuario y damos nombre al sistema.
5. Inicia la instalación.
6. Finaliza y reinicio.
10
Comunidad OpenSolaris Hispano
11
Comunidad OpenSolaris Hispano
12
Comunidad OpenSolaris Hispano
GRUB
13
Comunidad OpenSolaris Hispano
Inicia la primera carga de los servicios SMF (nuevo sistema de arranque por dependencias).
Lo siguiente que veremos será la pantalla de bienvenida donde hacemos login con el usuario que
hemos creado durante el proceso de instalación. Después de introducir el usuario y contraseña tenemos
disponible el sistema con el escritorio GNOME.
Con la instalación base dispones de tecnologías como Zonas, BrandZ, SMF, ZFS y DTrace y xVM
Hypervisor (basado en XEN).
14
Comunidad OpenSolaris Hispano
Arranque y Parada
Introducción
En este capitulo veremos el proceso arranque y parada de OpenSolaris 2008.05 , los comandos
necesarios para reiniciar y parar el sistema
Reinicio de la máquina:
Si deseamos realizar un reinicio del sistema y queremos emitir un mensaje personalizado avisando a
los usuarios usaremos el comando shutdown que permite los siguientes parámetros:
15
Comunidad OpenSolaris Hispano
Con –i indicamos el nivel de ejecución, con –g damos 360 segundos a los usuarios para cerrar sus
aplicaciones y ficheros. Cuando finalicen los 360 segundos el sistema solicita la confirmación del reinicio al
administrador:
# /usr/sbin/reboot
El comando reboot ejecuta una parada inmediata e inicia el sistema en el nivel 3 de ejecución
ahora llamado multi-user-server.
Parada de la máquina:
Para parar el sistema de forma ordenada y después realizar un apagado eléctrico de la máquina
ejecutamos:
ok power-off
Podemos pulsar cualquier tecla y reiniciar o realizar directamente el apagado eléctrico de la máquina.
Si necesitáramos parar la máquina de forma urgente podemos utilizar el comando halt que realizara
una parada inmediata no ordenada:
# /usr/sbin/halt
# /usr/sbin/poweroff
16
Comunidad OpenSolaris Hispano
Para reiniciar el sistema podemos ejecutar la orden reboot que antes proceder al reinicio actualiza el
superbloque:
# /usr/sbin/reboot
Introducción a GRUB
GRUB es el nuevo gestor de arranque para arquitecturas x86 que añade nuevas posibilidades de
arranque a OpenSolaris 2008.05 . GRUB se inicia en el MBR ocupando tan solo 512 bytes y este pequeño
código comienza la carga del resto de GRUB ubicado en el disco.
No podemos comparar GRUB con la OpenBoot para arquitecturas SPARC ya que la OBP se basa
en hardware y software, pero sin duda viene a mejorar las posibilidades de Solaris y su integración con otros
sistemas operativos como Linux. GRUB es un gran conocido dentro de la comunidad Linux por lo que
facilita aun mas el acercamiento de administradores Linux a Solaris. GRUB nos ofrece tres interfaces
diferentes para el uso y configuración de GRUB:
• Interfaz de menú: es la primera que vemos cuando arranca GRUB y muestra una lista con todas
las opciones disponibles para elegir con que sistema queremos arrancar. (ver figura 4.4)
• Interfaz de edición: Permite la edición de las opciones de arranque establecidas para cada
sistema operativo configurado. Un ejemplo es cambiar de forma temporal el kernel para
realizar pruebas. (ver figura 4.3)
• Interfaz de línea de comandos: es una pequeña shell que permite configurar GRUB, realizare
pruebas de dispositivos, red etc..
• eprom: OpenSolaris se integra con GRUB con el comando eprom al igual que lo hace con la
OpenBoot en SPARC.
Opciones de arranque
Cuando arrancamos la máquina lo primero que nos muestra GRUB es la Interfaz de menú donde
podemos elegir el sistema operativo. Esta interfaz se basa en un fichero de configuración que permite añadir
nuevos sistemas o modificar los ya existentes. El fichero de configuración se encuentra en
/boot/grub/menu.lst .
Cuando finalizamos la instalación de Solaris el archivo queda de la siguiente forma:
#---------------------END BOOTADM--------------------
#
# default menu entry to boot
default 0
#
# menu timeout in second before default OS is booted
# set to -1 to wait for user input
timeout 10
18
Comunidad OpenSolaris Hispano
OpenSolaris 2008.05 incorpora un nuevo sistema de gestión del arranque que ofrece nuevas
posibilidades y optimiza el arranque del sistema, este nuevo componente se llama SMF (Service Management
Facility) y forma parte de una nueva infraestructura que viene a sustituir al clásico inicio secuencial de Unix
System V. Esta nueva infraestructura permite arrancar los servicios de forma paralela acorde a sus relaciones
de dependencia. Una vez arrancado el sistema el administrador puede observar, deshabilitar, arrancar y parar
servicios de una manera sencilla y eficiente.
Características de SMF:
• Ofrece los mecanismos para establecer relaciones de dependencia entre servicios. Un servicio
no arranca hasta que estén correctamente arrancadas sus dependencias.
• Repositorio que contiene toda la información referente a la configuración del servicio,
modos de arranque, parada, reinicio y el estado en el que se encuentra.
• Log con información de eventos de cada servicio.
• Cambios de niveles de ejecución a mono usuario, red, mantenimiento etc..
19
Comunidad OpenSolaris Hispano
Beneficios de SMF:
• Los servicios al ser objetos pueden ser vistos y gestionados con sencillos comandos de
administración.
• Se puede definir que SMF monitorice un proceso del servicio y tomar acciones si detecta
que el proceso a muerto o hay un fallo hardware.
• Delegar en otros usuarios el poder arrancar o parar servicios de esta forma no
necesitamos utilidades como sudo o la cuenta de root.
Un servicio definido en SMF no tiene por que estar necesariamente asociado a un proceso que se
este ejecutando en el sistema, un servicio puede ser el estado de un dispositivo, de una tarjeta de red o de un
sistema de ficheros.
Un servicio puede estar compuesto a su vez por otra serie de servicios a los que se denominan
instancias. Un ejemplo seria un servidor web Apache con el servicio web escuchando por el puerto 80, otro
seguro por el 443 y un tercero por el 8080. Para gestionar el servicio deberíamos crear el servicio web con
tres instancias.
Un servicio en SMF esta formado por un conjunto de componentes que interactúan entre si.
Veamos cada uno de estos componentes:
20
Comunidad OpenSolaris Hispano
SMF manifiest: es un fichero XML en el que se definen las características de un servicio o una instancia del
servicio. Los ficheros XML con las propiedades de los servicios se almacenan en /var/svc/manifest. Estos
ficheros son cargados en el repositorio SMF.
Methods: los métodos son usados por el restarter para interactuar con el servicio y puede ser un fichero
ejecutable: un script o una palabra clave. Se utilizan para definir los métodos de arranque, parada o reinicio
de un servicio. Los métodos son almacenados en /lib/svc/method.
Service Log Files: es un servicio que escribe un log con todo los datos sucesos sobre un servicio, los logs
se encuentran en /var/svc/log.
Service Identifiers : cada servicio y cada instancia de servicio tienen un nombre con el que identificarse
con “Fault Management Resource Identifier (FMRI)” en el que se especifica como actuar en caso de fallo
en el sistema.
Los servicios pueden tener varios estados en los que podemos ver si el servicio esta parado,
arrancado, degradado o en mantenimiento. Anteriormente se utilizaba el comando “ps –ef” para ver si un
servicio estaba arrancado, ahora podemos utilizar los comandos de SMF para ver el estado del servicio
además de poder continuar haciéndolo con el comando “ps –ef” para buscar el proceso.
Estados en los se puede encontrar un servicio SMF:
• online: la instancia del servicio esta disponible y se esta ejecutando correctamente.
• offline: la instancia del servicio esta disponible pero no esta ejecutandose.
• disabled: la instancia del servicio no esta disponible y no esta ejecutándose.
• maintenance: la instancia del servicio tiene un error y esta siendo resuelto por el administrador.
• degraded: la instancia del servicio esta disponible pero esta funcionando al límite de su capacidad.
• uninitialized: este es el estado inicial de todos los servicios antes de iniciar su ejecución.
• legacy_run: este estado solo se utiliza para guardar la compatibilidad con los viejos niveles de arranque
y nos índica que el estado en el que se encuentran. Los niveles de arranque solo pueden ser
observados con SMF son se pueden editar.
Dependencias
Cuando definimos un servicio podemos definir dependencias, estableciendo que no arranque el
servidor Apache hasta que no este arrancado el sistema en multiusuario (run level 3) y la bbdd MYSQL
iniciada. Para cada servicio podemos establecer desde ninguna a varias dependencias.
Dicha entrada ejecuta el proceso svc.startd que inicia el proceso svc.configd que es el encargado
de conectar con el repositorio SMF que reside en /etc/svc/repository.db. El repositorio tiene la propiedad de
auto recuperarse si se producen daños ya que siempre mantiene una copia de respaldo. (ver figura 3.1)
Los primeros errores producidos durante la ejecución de SMF bien del repositorio o con
problemas de inicio de un servicio se escriben en el directorio /etc/svc/volatile (montado en memoria) ya que
todavía no esta montado o disponible “/var”, una vez sea accesible “/var” los logs son escritos en la ruta
predeterminada “/var/svc/log”.
boot
bbdd
Init (pid 1)
configurac
ión SMF
init lee
/etc/initta
svc.startd svc.confif.d
svc:/platform
svc:/site
svc:/mileston
e
svc:/system
Figura 3.1
Milestone Services
22
Comunidad OpenSolaris Hispano
Con la llegada de SMF también se ha redefinido la forma de poner la máquina en diferentes niveles
de ejecución. Los niveles de ejecución mas conocidos son sigle user y multi user. Ahora se les denomina
milestone. Milestone no es más que un servicio especial de SMF que agrupa las dependencias necesarias
para establecer un nivel de ejecución.
Se han añadido dos nuevos niéveles de ejecución: none que no ejecuta ningún servicio y all en el que
se ejecutan todos los servicios disponibles.
Las equivalencias al sistema tradicional son las reflejadas en la siguiente tabla:
Para pasar de un nivel de ejecución a otro podemos realizarlo sin problemas de la manera tradicional
con el comando init y el número del nivel de ejecución al que queremos pasar o con el comando svcadm de la
siguiente forma:
Pasar a single-user:
# svcadm milestone single-user
A multi-user
# svcadm milestone multi-user
A multi-user-server
# svcadm milestone multi-user-server
Para averiguar en que Runlevel esta ejecutándose el sistema lanzamos el siguiente comando:
Podemos ver que el sistema se encuentra en el nivel de ejecución multi-user-server. Si la ejecución del
comando no muestra nada en pantalla significa que estemos en el nivel de ejecución all.
Un milestone es un servicio tiene definidas dependencias de otros servicios, por ejemplo el servicio
multi-user depende de los servicios de red. Obervando las dependencias de cada nivel de ejecución podemos
averiguar que servicios ejecuta el milestone multi-user.
Para ello ejecutamos el comando svcs –d servicio para ver sus dependencias:
Para ver las dependencias del milestone multi-user ejecutamos:
23
Comunidad OpenSolaris Hispano
Como se puede ver el número de servicios que ejecuta multi-server es muy superior al single-user que
no requiere de tantos servicios como podemos ver en el ejemplo:
A continuación vamos a ver los comandos que tiene SMF para la monitorizar el estado de los
servicios, obtener información de un servicio y como parar o arrancar servicios. El conjunto de comandos
que nos permite la administración de SMF son:
Los servicios SMF están organizados en grupos con los siguientes nombres:
Application: Contiene los servicios asociados con aplicaciones.
Device: Usado para las dependencias
Milestone: Equivalente a los niveles de ejecución SVR4
Network: Todos los servicios del antiguo inetd.conf
Platform: Servicios específicos de la plataforma.
System: Servicios independientes de la plataforma
Site: Sin uso, reservado para uso futuro.
Para ver el estado todos los servicios recurrimos al comando svcs que en ejemplo lo ejecutamos con
la opción –a para que muestre todos los servicios independientemente de su estado.
# svcs –a
25
Comunidad OpenSolaris Hispano
En el ejemplo podemos observar el servicio legacy_run utilizado para guardar la compatibilidad con
las practicas administrativas de versiones anteriores de Solaris. Del servicio legacy_run solo se puede
consultar su estado y no podemos realizar cambios sobre el.
Si añadimos un servicio de la forma tradicional con un script en el directorio ined.d y el enlace en el
rc* correspondiente funcionara con normalidad viéndolo en el SMF como un servicio legacy_run .
En OpenSolaris 2008.05 no es recomendable seguir utilizando el viejo sistema para añadir servicios
al arranque debiendo utilizar SMF.
También podemos observar que los servicios tradicionales como ftp y ssh están en estado online.
Para ver las dependencias de un servicio, es decir que servicios tienen que estar arrancados para que
pueda ejecutarse utilizamos el comando svcs con la opción –d.
Veamos el ejemplo:
# svcs -d svc:/network/http:apache2
STATE STIME FMRI
online 10:10:12 svc:/milestone/network:default
online 10:10:33 svc:/system/filesystem/local:default
online 10:10:48 svc:/system/filesystem/autofs:default
Figura 3.2
En el ejemplo de la figura 3.2 vemos que para que pueda ejecutarse el servicio web Apache 2
necesitamos que estén levantados los servicios network, y filesystem.
Para averiguar que procesos están asociados a un servicio ejecutamos el comando svcs con la opción
–p . El resultado de la ejecuión produce la siguiente salida:
# svcs -p svc:/network/smtp:sendmail
STATE STIME FMRI
online 10:10:53 svc:/network/smtp:sendmail
10:10:54 334 sendmail
10:10:54 341 sendmail
Figura 3.3
En el ejemplo de la figura 3.3 podemos ver los pid asociados al servicio sendmail aunque podemos
averiguarlo tambien de la forma tradicional con la orden ps -ef | grep sendmail.
SMF puede aportar información detallada de un servicio como su nombre, si esta habilitado, su
propio estado y las dependencias.
Ejecutamos svcs con el parámetro –l :
26
Comunidad OpenSolaris Hispano
# svcs -l svc:/network/http:apache2
fmri svc:/network/http:apache2
nombre Apache 2 HTTP server
habilitada Falso
estado disabled
next_state none
state_time Thu Dec 28 10:10:08 2006
reiniciador svc:/system/svc/restarter:default
dependency require_all/error svc:/milestone/network:default (online)
dependency require_all/none svc:/system/filesystem/local:default (online)
dependency optional_all/error svc:/system/filesystem/autofs:default (online)
Diagnostico de fallos
SMF con el comando svcs puede aportarnos información sobre la causa de porque un servicio no
puede arrancar, para ellos utilizamos el comando svcs con el parámetro –x. Para este ejemplo hemos
deshabilitado manualmente el servicio de apache.
Veamos el resultado del diagnostico:
# svcs -x svc:/network/http:apache2
svc:/network/http:apache2 (Apache 2 HTTP server)
Estado: disabled desde Thu Dec 28 10:10:08 2006
Motivo: Un administrador lo ha inhabilitado.
Consulte: http://sun.com/msg/SMF-8000-05
Consulte: httpd(8)
Impacto: Este servicio no está funcionando.
La salida del comando nos indica que el servicio fue parado por un administrador, en que momento
lo hizo y el impacto sobre el servicio.
También nos remite a una url de Sun donde se nos amplia información sobre la causa por la que no
esta arrancado el servicio. Sea cual sea el error siempre nos dará una url para obtener información que nos
ayude a diagnosticar y solucionar el problema.
Parada de un servicio
Para parar un servicio utilizamos el comando svcadm con los parámetros disable y –t seguido del
nombre de servicio:
Verificamos que ha parado con el comando svcs –p el cual nos indicara que el proceso esta en disable y
que no hay procesos de apache2 ejecutándose.
El resultado es el siguiente:
# svcs -p svc:/network/http:apache2
La opción –t estipula que es una para temporal si olvidamos poner el parámetro –t en el próximo
arranque de la máquina el servicio no arrancara quedando en disable.
Arrancar un servicio
Para arrancar un servicio utilizamos el comando svcadm con los parámetros enable y –t seguido del
nombre de servicio:
# svcadm enable -t svc:/network/http:apache2
#
# svcs -p svc:/network/http:apache2
STATE STIME FMRI
online 12:31:23 svc:/network/http:apache2
12:31:23 1559 httpd
12:31:24 1560 httpd
12:31:24 1561 httpd
12:31:24 1562 httpd
12:31:24 1563 httpd
12:31:24 1564 httpd
Figura 3.3
Tal como podemos ver en la figura 3.3 el servicio ha arrancado correctamente y podemos ver todos
los pid de los procesos en ejecución.
Reiniciar un servicio
Hasta el momento si queríamos reiniciar un servicio como por ejemplo ssh acudíamos a ejecutar:
# svcs -p svc:/network/http:apache2
STATE STIME FMRI
28
Comunidad OpenSolaris Hispano
Si deseamos saber los valores de las propiedades de un servicio disponemos del comando svcprop
que extrae dicha información del repositorio. Como ejemplo vamos a averiguar que método esta definido
para arrancar el servicio apache2.
Ejecutamos primeramente el comando svcprop y el nombre del servicio para obtener una lista de las
propiedades definidas:
# svcprop svc:/network/http:apache2
En el ejemplo de la figura 3.4 podemos ver una lista con todas las propiedades del servicio, para
nuestro ejemplo nos centramos en la línea que pone:
Esta línea muestra el fichero que ejecuta el arranque del apache 2 que es /lib/svc/method/http-apache2
pasándole el parámetro start. Podemos ver el contenido del scritp realizando un more sobre
/lib/svc/method/http-apache2.
Si queremos obtener datos formateados sobre una de las propiedades ejecutamos:
El proceso inetd ha sido migrado completamente como un servicio SMF, ya no es necesario editar el
fichero /etc/inet/inetd.conf para establecer valores o habilitar y deshabilitar servicio como telnet, ftp, tftp etc..
Si deshabilitamos un servicio como telnet ya no es necesario reiniciar con el comando kill el proceso
inet.d.
Para ver todos los servicios del proceso inetd y el estado en el que se encuentran ejecutamos el
comando inetadm y pulsamos intro:
# inetadm
ENABLED STATE FMRI
enabled online svc:/application/x11/xfs:default
enabled online svc:/application/font/stfsloader:default
enabled offline svc:/application/print/rfc1179:default
enabled online svc:/network/rpc/mdcomm:default
enabled online svc:/network/rpc/meta:default
enabled online svc:/network/rpc/metamed:default
enabled online svc:/network/rpc/metamh:default
enabled online svc:/network/rpc/gss:default
…………
…………..
enabled online svc:/network/ftp:default
disabled disabled svc:/network/comsat:default
enabled online svc:/network/finger:default
disabled disabled svc:/network/login:eklogin
disabled disabled svc:/network/login:klogin
enabled online svc:/network/login:rlogin
disabled disabled svc:/network/shell:kshell
disabled disabled svc:/network/talk:default
Al ser un servicio mas de SMF recurrimos al comando svcadm y el parámetro disable. Ejemplo para no
permitir conexiones telnet:
30
Comunidad OpenSolaris Hispano
#inetadm -l ftp
SCOPE NAME=VALUE
name="ftp"
endpoint_type="stream"
proto="tcp6"
isrpc=FALSE
wait=FALSE
exec="/usr/sbin/in.ftpd -a"
user="root"
default bind_addr=""
default bind_fail_max=-1
default bind_fail_interval=-1
default max_con_rate=-1
default max_copies=-1
default con_rate_offline=-1
default failrate_cnt=40
default failrate_interval=60
default inherit_env=TRUE
default tcp_trace=FALSE
default tcp_wrappers=FALSE
Para cambiar un valor de los servicios inet.d utilizamos el comando inetadm de la siguiente forma:
31
Comunidad OpenSolaris Hispano
La ejecución del comando para cambiar el valor wait=FALSE del servicio ftp a valor wait=TRUE
seria:
y lo verificamos con:
# inetadm -l ftp
SCOPE NAME=VALUE
name="ftp"
endpoint_type="stream"
proto="tcp6"
isrpc=FALSE
wait=TRUE
exec="/usr/sbin/in.ftpd -a"
user="root"
default bind_addr=""
default bind_fail_max=-1
default bind_fail_interval=-1
default max_con_rate=-1
default max_copies=-1
default con_rate_offline=-1
default failrate_cnt=40
default failrate_interval=60
default inherit_env=TRUE
default tcp_trace=FALSE
default tcp_wrappers=FALSE
Cambios en inetd.conf
El fichero /etc/inet/inetd.conf no puede sufrir cambios ya que toda la gestión recae sobre SMF pero
en caso de producirse un cambio voluntario o por una aplicación el sistema nos alertara en /adm/messages
que el fichero ha sido modificado para que el administrador determine su naturaleza.
En OpenSolaris 2008.05 se han migrado todos los demonios del fichero /etc/inet/inetd.conf, pero si
necesitamos añadir posteriormente un servicio contamos con la utilidad inetconv.
El procedimiento es el siguiente:
32
Comunidad OpenSolaris Hispano
3. Ejecutamos el comando:
Para crear un nuevo servicio SMF debemos definir un nuevo SMF manifiest que es fichero XML
que contiene los métodos para arrancar, parar, reiniciar, definición de dependencias, documentación etc..
Recordemos que los servicios SMF están organizados en grupos con los siguientes nombres:
Vamos a proceder a crear un nuevo servicio SMF de un servidor web de Sun Microsystems: Sun
ONE Web Server 6 para ello recopilamos la siguiente información:
• Vamos a crear el servicio dentro del grupo Application y a su vez dentro de un nuevo
subgrupo definido por nosotros llamado servidoresweb y finalmente el identificador del servicio
AulaUnix que se corresponde con el servidor web Sun One. Quedando se la siguiente
forma: /application/servidoresweb/AulaUnix.
• Definimos como dependencia el nivel de ejecución 3 o multi-user-server.
• Los scripts de arranque, parada y reinicio son:
o /software/binarios/webserversunone/https-aulaunix.aulaunix.org/start
o /software/binarios/webserversunone/https-aulaunix.aulaunix.org/stop
o /software/binarios/webserversunone/https-aulaunix.aulaunix.org/restart
• La documentación la ubicamos en /software/documentacion
En el ejemplo de la figura 3.6 podemos ver un XML completo en el que se define el servicio
/application/servidoresweb/AulaUnix. Veamos las partes mas importantes:
En la primera parte del XML vemos que se han creado los comentarios sobre el servicio y se ha
definido un identificador:
Este identificador debe ser único y podemos personalizar el texto acorde al servicio que vamos a dar
de alta.
En el siguiente se establece a que grupo pertenece y se define un subgrupo para albergar los
servidores web:
<service
name='application/servidoresweb/AulaUnix'
type='service'
version='1'>
El nombre definido con name= será el que nos muestre el comando svcs cuando verifiquemos el
estado del servicio. Debe ser un nombre sencillo y que permita identificar los servicios de forma practica. En
este caso hemos optado por organizar todos los servidores web por debajo de servidoresweb.
La propiedad de la figura 3.6 create_default_instance nos permite dos valores false y true con los que
indicamos que el servicio se inicie o se detenga con las paradas y arranques del sistema. Anteriormente esto
34
Comunidad OpenSolaris Hispano
lo hacíamos con los scripts dentro del run revel correspondient pondiendo la S deltante del nombre para
arrancar o la K para parar el servicio.
Ya hemos definido las dependencias y ahora vamos a crear los métodos para arrancar, reiniciar y
parar. Como vemos en el ejemplo de la figura 3.6 con la opción name= establecemos el valor start para
arrancar, stop para parar y restart para reiniciar.
Los métodos definidos se ejecutaran cuando llamemos al comando svcadm de la siguiente forma:
svcs Método
svcadm enable nombredelservicio start
svcadm disable nombredelservicio stop
svcadm restart nombredelservicio restart
El valor de exec= contiene la ruta absoluta al script o binario que se ejecutara y con time
timeout_seconds definimos los segundos que esperara SMF como limite para el arranque:
<exec_method
type='method'
name='start'
exec='/software/binarios/webserversunone/https-aulaunix.aulaunix.org/start'
timeout_seconds='30' >
</exec_method>
Ya tenemos creados los métodos y nos queda definir la información sobre la documentación del
servicio en la etiqueta <documentation> donde establecemos el valor para manpage title con el titulo de la
documentación y del valor manpath con el path absoluto del lugar donde se encuentra la máquina.
<documentation>
Ya tenemos creado el fichero XML y nos queda cargarlo en el repositorio para poder ser gestionado.
La carga en el repositorio la realizamos con el comando svccfg ejecutando la siguiente sentencia:
svccfg -v import fichero.xml
# svcs -l svc:/application/servidoresweb/AulaUnix
fmri svc:/application/servidoresweb/AulaUnix:default
nombre Servicio SMF de ejemplo sobre SunONE
habilitada Falso
estado disabled
next_state none
state_time Tue Jan 02 17:56:41 2007
reiniciador svc:/system/svc/restarter:default
dependency require_all/none svc:/milestone/multi-user-server (online)
Podemos ver las propiedades correctamente, el nombre es svc:/application/servidoresweb/AulaUnix tal
como hemos definido en el XML y su estado es disabled..
El servicio ya esta disponible para gestionarlo con SMF. Verificamos el método start arrancando el
servidor web con el comando svcadm:
# svcs -p svc:/application/servidoresweb/AulaUnix:default
STATE STIME FMRI
online 10:41:16 svc:/application/servidoresweb/AulaUnix:default
10:41:06 3986 webservd-wdog
10:41:06 3987 webservd
10:41:07 3988 webservd
Podemos verificar el servidor web con ps –ef o ejecutando el comando svcs –p que nos mostrara los
procesos y su pid asociados al servicio.
36
Comunidad OpenSolaris Hispano
Para modificar las propiedades de un servicio SMF es suficiente con modificar el fichero XML con
los nuevos datos y realizar la importación al repositorio con el comando svccfg:
<?xml version='1.0'?>
<!DOCTYPE service_bundle SYSTEM "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
<!--
XML de ejemplo de ejemplo creado por David Galan
dgalan@aulaunix.org
www.aulaunix.org
wikilaris.aulaunix.org
blog.aulaunix.org
-->
<service
name='application/servidoresweb/AulaUnix'
type='service'
version='1'>
<single_instance/>
<exec_method
type='method'
name='start'
exec='/software/binarios/webserversunone/https-aulaunix.aulaunix.org/start'
timeout_seconds='30' >
</exec_method>
<exec_method
type='method'
name='stop'
exec='/software/binarios/webserversunone/https-aulaunix.aulaunix.org/stop'
timeout_seconds='60' />
<exec_method
type='method'
name='restart'
exec='/software/binarios/webserversunone/https-aulaunix.aulaunix.org/restart'
37
Comunidad OpenSolaris Hispano
timeout_seconds='120'>
</exec_method>
<template>
<common_name>
<loctext xml:lang='C'>
Servicio SMF de ejemplo sobre SunONE
</loctext>
</common_name>
<documentation>
<manpage title='Documentos Web Server' section='1M'
manpath='/software/documentacion' />
</documentation>
</template>
</service>
</service_bundle>
Figura 3.6
En algún momento puede surgir la necesidad de delegar la gestión de un servicio a otro usuario del
sistema para poder arrancar, parar y reiniciar servicios.
En nuestro ejemplo vamos a dar permisos al usuario aulaunix para que pueda gestionar el servidor
web. El primer paso es añadir al servicio el atributo value_authorization utilizando el comando svcprop:
aulaunix::::type=normal;auths=solaris.smf.manage
Con estos dos pasos el usuario aulaunix ya puede gestionar el servicio web:
# su - aulaunix
bash-3.00$ /usr/sbin/svcadm disable /application/servidoresweb/AulaUnix
bash-3.00$ /usr/sbin/svcadm enable /application/servidoresweb/AulaUnix
Si deseamos quitarle los permisos para que no pueda continuar gestionando el servicio ejecutamos el
comando svcprop para eliminar la propiedad value_authorization:
38
Comunidad OpenSolaris Hispano
Gestión de usuarios
Las cuentas de usuario para el acceso al sistema no difieren en
Solaris de otros sistemas unix, en el siguiente capitulo
aprenderemos a:
• Ficheros de inicialización
Ficheros de configuración
Los ficheros de configuración contienen la información sobre las cuentas de usuario, los grupos y
contraseñas. Los ficheros son:
/etc/passwd
39
Comunidad OpenSolaris Hispano
Cada una de las líneas del fichero contiene la información de un usuarios. Cada línea esta organizada
en campos separados por el carácter dos puntos que hace de separador de campo. Ejemplo de una línea del
fichero passwd:
aulaunix:x:65535:1:Nombre y apellidos:/export/home/aulaunix:/bin/bash
IDlogin:x:UID:GID:comentario:home_directory:login_shell
• IDlogin: es el identificador con el que hacemos login en el sistema debe de ser único.
• UID: esta representado por un número superior a 0 ya que 0 pertenece al usuario root. Los números
del 1 al 99 están reservados para usuarios administradores del sistema. Para el resto de usuarios se
utiliza el rango del 100 al 60000. Se reserva para el usuario nobody el 60001 y para el usuario
noaccess el 60002.
• GID: número mayor de 0 que representa el grupo primario al que pertenece el usuario.
• Directorio home (home_directory): ruta absoluta del directorio home para el usuario.
• Shel (login_shell ): Define la shell para el usuario (sh, ksh, csh, etc..)
/etc/shadow
Contiene las contraseñas de las cuentas de usuario, al ser un fichero que puede comprometer la
seguridad del sistema solo el usuario root debe de tener permisos de lectura para el archivo. El contenido del
archivo es el siguiente:
root:SbEPJrMu/wMTw:6445::::::
daemon:NP:6445::::::
bin:NP:6445::::::
sys:NP:6445::::::
adm:NP:6445::::::
lp:NP:6445::::::
uucp:NP:6445::::::
nuucp:NP:6445::::::
dladm:*LK*:::::::
smmsp:NP:6445::::::
listen:*LK*:::::::
gdm:*LK*:::::::
webservd:*LK*:::::::
postgres:NP:::::::
nobody:*LK*:6445::::::
40
Comunidad OpenSolaris Hispano
noaccess:*LK*:6445::::::
nobody4:*LK*:6445::::::
aulaunix:nMF64Wg9ff/HU:13570::::::
IDlogin:pwd:lastchg:min:max:warn:inactivo:expiracion:
Los datos que contiene cada línea del fichero shadow son:
• max: establece el máximo numero de días que una contraseña esta activa.
• inactive: días que puede estar la cuenta inactiva (sin entradas al sistema) antes de bloquearse.
/etc/group/
Todos los usuarios del sistema tienen que pertenecer a un grupo principal definido en el
fichero /etc/passwd. Adicionalmente un usuario puede pertenecer más grupos disponibles en el sistema
denominados grupos secundarios definidos en el fichero /etc/group. El siguiente ejemplo muestra las entradas
por defecto en el fichero group:
root::0:
other::1:root
bin::2:root,daemon
sys::3:root,bin,adm
adm::4:root,daemon
uucp::5:root
mail::6:root
tty::7:root,adm
lp::8:root,adm
nuucp::9:root
staff::10:
daemon::12:root
sysadmin::14:
smmsp::25:
gdm::50:
webservd::80:
postgres::90:
nobody::60001:
noaccess::60002:
41
Comunidad OpenSolaris Hispano
nogroup::65534:
nonmbredelgrupo:group-password:GID:listausuarios
Los datos que contiene cada línea del fichero group son:
Gestión de usuarios
Crear usuario
El comando empleado para crear usuarios es useradd con las siguiente sintaxis:
useradd [–u uid] –g [gid] –G [gid1,gid2, …] [-d dir] –m [–s shell] [–c comment] [–e expire] usuario
42
Comunidad OpenSolaris Hispano
Crear usuario:
El siguiente ejemplo muestra como crear el usuario aula, definir su UID manualmente e incluirlo en
el grupo alumnos definiendo su home en /export/home/aulaunix, definimimos la shell como ksh.
aula:x:109:100:usuarios de pruebas:/export/home/aulaunix:/bin/ksh
Modificar un usuario
Si ya tenemos un usuario en el sistema y deseamos cambiar alguna de sus propiedades utilizamos el
comando usermod:
• -f Definimos el número de días puede estar inactiva. Si la cuenta no es usada en el número de días
especificado se bloquea.
• -e Define la fecha de caducidad de la cuenta. Cuando llega ldicha fecha la cuenta es inutilizable.
Este ejemplo implica que el nuevo home para el usuario dgalan es /export/nuevohome y mueve todos
los archivos del viejo directorio al nuevo.
Vamos a ejecutar el ejemplo anterior pero además vamos a cambiar el nombre de inicio de sesión:
Después de ejecutar el comando tenemos un nuevo home y un nuevo nombre de inicio de sesión.
Borrado de usuarios
Borrar un usuario del sistema es muy sencillo utilizando el comando userdel.
userdel –r [usuario a borrar]
La opción –r elimina el home del usuario si este existe, pero no borra los archivos que el usuario
pueda tener repartidos en otros directorios de la máquina.
Para eliminar todos los archivos del usuario deberíamos de recurrir a una búsqueda recursiva
utilizando el comando find. Buscaríamos todos los archivos y directorios pertenecientes al usuario eliminado.
passwd [usuario]
Gestión de grupos
Hemos visto como crear, modificar y eliminar usuarios. Ahora vamos a realizar el mismo recorrido
pero esta vez gestionando grupos, para ello utilizaremos los comandos:
• groupadd
• groupmod
• groupdel
44
Comunidad OpenSolaris Hispano
Lo verificamos:
Hemos buscado el nuevo usuario en el fichero de grupos y efectivamente se añada la nueva entrada
de grupo.
Modificar un grupo
Podemos ejecutar cambios en un grupo existente con el comando groupmod que nos permite
modificar el GID o renombrar un grupo.
Eliminar un grupo
Eliminar un grupo existente es muy facil con el comando groupdel.
groupdel [nombre del grupo]
Ejemplo:
Cambio de grupos
Siempre que entramos al sistema lo hacemos perteneciendo al grupo principal, pero un usuario que
pertenece a varios grupos puede necesitar operar en cada uno de ellos en diferentes momentos de su sesión
en el sistema.
Para cambiar de grupo recurrimos al comando newgrp, veamos un ejemplo practico:
Hemos entrado al sistema con el usuario dgalan tal como se puede ver en el siguiente ejemplo:
$ id
uid=109(dgalan) gid=1(other)
45
Comunidad OpenSolaris Hispano
Lo verificamos:
$ id
uid=109(dgalan) gid=1(other) gid=45(admins)
A partir de este momento todos los ficheros y directorio creados pertenecerán al grupo admins.
El comando who
Solaris al igual que el resto de sistemas Unix nos facilita una serie de comandos que nos permite
averiguar que usuarios están conectados al sistema y desde donde se han conectado.
El primero de estos comandos es who que muestra una lista con todos los usuarios conectados al
sistema mostrando datos como:
• usuario
• conexión
• fecha de entrada
$ who
root console Sep 1 19:41
aula pts/1 Sep 1 19:45 (192.168.1.33)
$
El comando w
Otro comando a nuestro alcance es w que muestra la lista de usuarios en el sistema como el
comando who pero añadiendo datos como los procesos y carga de CPU.
Ejemplo del comando w:
$w
9:05pm en funcionamiento 1:26, 2 usuarios, promedio de carga: 0,01, 0,01, 0,21
User tty login@ idle JCPU PCPU what
root console 7:41pm 1:21 -sh
aula pts/1 7:45pm 1 w
El comando finger
Muestra información detallada de los usuarios conectados al sistema y detalles de usuarios de forma
individual, es un comando basado
46
Comunidad OpenSolaris Hispano
finder: no encontrado
$ finger
Login Name TTY Idle When Where
root Super-User console 1:30 Sat 19:41
aula ??? pts/1 Sat 19:45 192.168.1.33
$
Ejemplo de la salida del comando finger para obtener detalles de un solo usuario:
Login name: root In real life: Super-User
Directory: / Shell: /sbin/sh
On since Sep 1 19:41:45 on console
1 hour 31 minutes Idle Time
No unread mail
No Plan.
El segundo ejemplo nos aporta información como la shell y el home del usuario así como el tiempo
conectado.
47
Comunidad OpenSolaris Hispano
Procesos y señales
Introducción
En este capitulo veremos como gestiona Solaris los procesos que no difiere mucho del resto de unix
existentes en el mercado. Igualmente si provienes de Linux te resultará fácil adaptarte a las singularidades de
Solaris.
Cada programa que se ejecuta en el sistema se corresponde con uno o varios procesos.
Solaris como cualquier sistema multiusuario permite a cualquier usuario ejecutar más de un proceso
simultáneamente, los procesos de un mismo usuario pueden comunicarse entre si pero no con los procesos
de otro usuario. El usuario root es el único que puede comunicarse con todos los procesos en ejecución.
Cada proceso está identificado por un PID único y a su vez tienen asociado un identificador de
usuario (UID) y su grupo (GID).
48
Comunidad OpenSolaris Hispano
La siguiente tabla contiene los parámetros más útiles para utilizar con el comando ps:
Parámetro Función
-a Muestra los procesos mas solicitados.
-e Muestra todos los procesos en ejecución.
-f Muestra información ampliada de los
procesos.
-p Muestra el ID de la CPU asociada al proceso.
-u Muestra todos los procesos de un usuario
específico.
-c Muestra los datos con formato planificación
y prioridad de procesos.
-G Muestra los procesos ejecutados por un
grupo.
La opción ejecutada en el ejemplo con –c muestra información interesante como los valores CLS
que indica el tipo de prioridad y PRI que muestra la prioridad del proceso.
Observa que el grupo es indicado con su GID que hemos obtenido mirando su valor en el fichero
/etc/group.
El comando prstat
El comando prstat muestra información de los procesos en ejecución ordenados por el uso de CPU.
Ejemplo de la ejecución del comando prstat:
bash-3.00$ prstat
PID USERNAME SIZE RSS STATE PRI NICE TIME CPU PROCESS/NLWP
668 noaccess 159M 80M sleep 59 0 0:00:29 0,5% java/24
744 aulaunix 4492K 2644K cpu0 39 0 0:00:00 0,4% prstat/1
682 aulaunix 7952K 2100K sleep 59 0 0:00:00 0,0% sshd/1
712 aulaunix 2484K 1612K sleep 49 0 0:00:00 0,0% bash/1
131 root 3824K 2360K sleep 59 0 0:00:00 0,0% nscd/24
535 root 4444K 1724K sleep 59 0 0:00:00 0,0% dtlogin/1
670 root 7096K 2076K sleep 59 0 0:00:00 0,0% sendmail/1
1 root 2024K 1120K sleep 59 0 0:00:00 0,0% init/1
269 root 4416K 3052K sleep 59 0 0:00:03 0,0% inetd/4
278 root 2820K 1140K sleep 59 0 0:00:00 0,0% sh/1
214 root 2272K 900K sleep 59 0 0:00:00 0,0% cron/1
143 daemon 3932K 1968K sleep 59 0 0:00:00 0,0% kcfd/3
111 root 2156K 1296K sleep 59 0 0:00:00 0,0% snmpdx/1
258 root 1700K 896K sleep 59 0 0:00:00 0,0% sac/1
71 root 6556K 4572K sleep 59 0 0:00:00 0,0% snmpd/1
Total: 43 processes, 180 lwps, load averages: 0,02, 0,03, 0,31
En la siguiente lista puedes ver la información aportada por la ejecución del comando:
50
Comunidad OpenSolaris Hispano
El comando prstat proporciona diversos parámetros para obtener mas información, los parámetros mas
útiles son:
Señales
Los procesos en ejecución puede ser necesario detenerlos por que su funcionamiento no es el
esperado, no responden o cualquier otra causa. El comando kill nos permite enviar una señal al proceso
para que se detenga.
Formato de kill:
kill –señal pidproceso
Ejempo de kill
Matar una sesión ssh:
# adtasweb01 /var/opt/aat/d#ps -ef | grep ssh
root 449 1 0 Aug 20 ? 1:01 /usr/local/sbin/sshd
root 25618 449 0 17:51:52 ? 0:00 /usr/local/sbin/sshd -R
ora9 18084 18082 0 20:25:28 ? 0:00 /usr/local/sbin/sshd -R
ora9 8645 8476 0 20:22:26 ? 0:00 /usr/local/sbin/sshd –R
# kill -9 25618
#
La señal SIGHUP comúnmente conocida como interrumpir una conexión telefónica o de Terminal,
esta señal puede provocar en servicios como inetd que relean el fichero de configuración.
51
Comunidad OpenSolaris Hispano
Señal en curso
En algún momento puede interesarnos ver todas las señales enviadas a un proceso en ejecución para
ello recurrimos al comando psig.
Formato:
psig pid
Ejemplo de psig:
#psig 13936
13936: /usr/lib/ssh/sshd
HUP default
INT default
QUIT default
ILL default
TRAP default
ABRT default
EMT default
FPE default
KILL default
BUS default
SEGV default
SYS default
PIPE ignored
ALRM caught 0x2d7fc RESETHAND,NODEFER
TERM default
USR1 default
USR2 default
CLD caught 0x40f14 0
PWR default
WINCH default
URG default
Señales de proceso:
Árbol de procesos
Disponemos de un comando llamado ptree que nos permite ver los procesos de forma jerárquica es
decir podemos ver los procesos hijos desplegados de forma arbórea. El comando ptree se lanza sin opciones,
veamos el ejemplo de su ejecución:
adtasbac01 /opt/na#ptree
51 /usr/lib/sysevent/syseventd
60 /usr/lib/picl/picld
137 /usr/lib/sparcv9/cpudiagd -i
174 /usr/sbin/rpcbind
197 /usr/sbin/inetd -s
326 rpc.metad
5089 in.telnetd
5094 -ksh
16041 bash
28382 bash
15728 ptree
22123 in.telnetd
22125 -ksh
23114 bash
218 /usr/lib/nfs/statd
219 /usr/lib/nfs/lockd
221 /usr/lib/autofs/automountd
224 /usr/lib/autofs/automountd
235 /usr/sbin/syslogd
242 /usr/sbin/cron
263 /usr/sbin/nscd
266 /usr/lib/power/powerd
A continuación vamos a ver una serie de comandos que nos aportaran información sobre los
procesos en ejecución.
Para averiguar las librerías en uso por un proceso recurrimos al comando pldd:
53
Comunidad OpenSolaris Hispano
El siguiente ejemplo muestra las librerías utilizadas por el proceso 6171 perteneciente a un servicio
web de Sun Java:
# pldd 6717
6717: ../../bin/https/bin/Cgistub -f /tmp/https-admserv-98ccc083/.cgistub_88
/usr/lib/libsocket.so.1
/usr/lib/libnsl.so.1
/usr/lib/libC.so.5
/usr/lib/libm.so.1
/usr/lib/libw.so.1
/usr/lib/libc.so.1
/usr/lib/libdl.so.1
/usr/lib/libmp.so.2
/usr/platform/sun4u-us3/lib/libc_psr.so.1
El comando pfiles lista todos los descriptores de ficheros abiertos por un proceso:
# pfiles 6717
6717: ../../bin/https/bin/Cgistub -f /tmp/https-admserv-98ccc083/.cgistub_88
Current rlimit: 1024 file descriptors
1: S_IFCHR mode:0666 dev:85,1 ino:72269 uid:0 gid:3 rdev:13,2
O_RDWR
2: S_IFCHR mode:0666 dev:85,1 ino:72269 uid:0 gid:3 rdev:13,2
O_RDWR
El comando pmap muéstrela el uso que hace de la memoria un proceso mostrando una mapa del
espacio de direcciones:
54
Comunidad OpenSolaris Hispano
0/bin/https/bin/Cgistub
00026000 8K read/write/exec [ heap ]
FF080000 688K read/exec /usr/lib/libc.so.1
FF13C000 32K read/write/exec /usr/lib/libc.so.1
FF1B0000 224K read/exec /usr/lib/libm.so.1
FF1F6000 8K read/write/exec /usr/lib/libm.so.1
FF200000 312K read/exec /usr/lib/libC.so.5
FF25C000 32K read/write/exec /usr/lib/libC.so.5
FF264000 64K read/write/exec /usr/lib/libC.so.5
FF280000 576K read/exec /usr/lib/libnsl.so.1
FF310000 40K read/write/exec /usr/lib/libnsl.so.1
FF31A000 24K read/write/exec /usr/lib/libnsl.so.1
FF330000 16K read/exec /usr/lib/libmp.so.2
FF344000 8K read/write/exec /usr/lib/libmp.so.2
FF350000 8K read/write/exec /usr/lib/libdl.so.1
FF360000 8K read/exec /usr/platform/sun4u-us3/lib/libc_psr.so.1
FF370000 8K read/write/exec [ anon ]
FF380000 40K read/exec /usr/lib/libsocket.so.1
FF39A000 8K read/write/exec /usr/lib/libsocket.so.1
FF3A0000 8K read/exec /usr/lib/libw.so.1
FF3B0000 192K read/exec /usr/lib/ld.so.1
FF3E0000 8K read/write/exec /usr/lib/ld.so.1
FF3E2000 8K read/write/exec /usr/lib/ld.so.1
FFBEA000 24K read/write/exec [ stack ]
total 2376K
A continuación veremos una serie de comandos que nos permiten observar los procesos y la carga
de trabajo de las CPU del sistema.
El comando ps pero en versión BSD alojado en /usr/ucb nos permite ver el consumo de CPU y memoria
de los procesos:
/usr/ucb/ps -aux
El siguiente ejemplo muestra los diez primeros procesos que mas consumen recursos, se ha añade el
comando head para que solo muestra los diez primeros resultados:
Los comandos psinfo y mpstat nos muestran estadísticas sobre el estado de las CPU del sistema:
mpstat muestra la actividad de las CPU de forma individual, veamos la ejecución del comando mpstat:
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
1 7 1 120 412 309 168 4 21 3 0 638 1 4 0 95
55
Comunidad OpenSolaris Hispano
La información más importante que vemos en el resultado de la ejecución del comando es:
• mjf que corresponde con fallos importantes.
• minf que corresponde con fallos de menor importancia.
• xcal aporta información sobre la llamada entre las CPU.
• intr indica el número de interrupciones.
• wt indica en % el tiempo consumido por los procesos de usuario.
• sys tiempo de CPU consumido por los procesos del sistema.
El comando psrinfo mostrará el estado de las CPU y cuando se iniciaron. Ejemplo de la salida del
comando psrinfo:
#psrinfo
0 on-line since 10/04/07 09:03:13
1 on-line since 10/04/07 09:03:13
2 on-line since 10/04/07 09:03:13
3 on-line since 10/04/07 09:03:13
4 on-line since 10/04/07 09:03:13
5 on-line since 10/04/07 09:03:13
6 on-line since 10/04/07 09:03:13
7 on-line since 10/04/07 09:03:01
16 on-line since 10/04/07 09:03:13
17 on-line since 10/04/07 09:03:13
18 on-line since 10/04/07 09:03:13
19 on-line since 10/04/07 09:03:13
20 on-line since 10/04/07 09:03:13
21 on-line since 10/04/07 09:03:13
22 on-line since 10/04/07 09:03:13
23 on-line since 10/04/07 09:03:1
Trabajos planificados
El comando at
El comando at permite la ejecución de un trabajo una sola vez en una fecha y hora determinada.
Sintaxis:
Parámetro Función
-m Cuando termina el trabajo envía un correo al usuario.
-r Elimina un trabajo programado.
56
Comunidad OpenSolaris Hispano
Programar un trabajo.
El ejemplo primero establece la hora con at 03:00 pm seguidamente introducimos el comando que se
va a ejecutar /opt/servidorweb/stop.sh y salimos pulsando Control-d. Observa que el comando nos devuelve el
nombre del trabajo job 1195653600.a.
# at -l
user = root 1195653600.a Wed Nov 21 15:00:00 2007
#
57
Comunidad OpenSolaris Hispano
No todos los usuarios del sistema pueden ejecutar el comando at, para autorizar o denegar el uso del
comando at hay que editar los ficheros /etc/cron.dat.deny o /etc/cron.d/at.allow ambos ficheros de root.
El fichero at.deny contiene los usuarios a los que se deniega el uso del comando at:
Contenido del fichero at.deny:
# cat /etc/cron.d/at.deny
daemon
bin
smtp
nuucp
listen
nobody
noaccess
El fichero at.allow contiene los usuarios que pueden ejecutar el comando at, en ocasiones el fichero puede no
existir por lo que hay que crearlo.
# cat /etc/cron.d/at.allow
web
ldap
dgalan
Logs de at
Toda la actividad realizada con el comando at queda registrada en el log ubicado en /var/cron/log.
Crontab
1 2 3 4 5 /usr/local/bin/iniciobackup.sh
Comienza con cinco campos separados por espacios seguido de la tarea a ejecutar. Los cinco campos
representan:
Campo Descripción
1 El primer campo contiene los minutos. Valores entre 0 y 59.
2 El segundo campo tiene la hora. Valores entre 0 y 23.
3 Día del mes, valore entre 1 y 31.
4 El mes del año, valores entre 1 y 12.
5 Día de la semana, valores entre 0 y 6.
Usando crontab
Para ver las tareas planificadas ejecutamos el comando crontab –l obteniendo la lista de tareas
programas:
# crontab -l
#ident "@(#)root 1.20 01/11/06 SMI"
#
# The root crontab should be used to perform accounting data collection.
#
# The rtc command is run to adjust the real time clock if and when
# daylight savings time changes.
#
10 3 * * * /usr/sbin/logadm
15 3 * * 0 /usr/lib/fs/nfs/nfsfind
1 2 * * * [ -x /usr/sbin/rtc ] && /usr/sbin/rtc -c > /dev/null 2>&1
30 3 * * * [ -x /usr/lib/gss/gsscred_clean ] && /usr/lib/gss/gsscred_clean
#10 3 * * * /usr/lib/krb5/kprop_script ___slave_kdcs___
Cada usuario solo puede ver sus propias planificaciones siendo una excepción el usuario root que
puede ver la planificación de cualquier usuario del sistema utilizando el comando crontab de la siguiente
forma:
crontab –l nombre_de_usuario
59
Comunidad OpenSolaris Hispano
En los siguientes ejemplos vamos a mostrar como editar el crontab para editar o añadir nuevas
entradas.
Para comenzar tenemos que establecer el editor por defecto ejecutando:
EDITOR=vi
export EDITOR
Con el editor vi podemos añadir nuevas líneas, modificar las existentes o eliminar entradas para
eliminarlas de la planificación.
No todos los usuarios del sistema pueden ejecutar el comando crontab, para autorizar o denegar el
uso del comando at hay que editar los ficheros /etc/cron.dat.deny o /etc/cron.d/at.allow ambos ficheros de root.
60
Comunidad OpenSolaris Hispano
El fichero at.deny contiene los usuarios a los que se deniega el uso del comando at:
Contenido del fichero at.deny:
# cat /etc/cron.d/at.deny
daemon
bin
smtp
nuucp
listen
nobody
noaccess
El fichero at.allow contiene los usuarios que pueden ejecutar el comando at, en ocasiones el fichero puede no
existir por lo que hay que crearlo.
# cat /etc/cron.d/at.allow
web
ldap
dgalan
61
Comunidad OpenSolaris Hispano
Gestión de discos
El siguiente capitulo comprende la gestión de discos con OpenSolaris 2008.05 aprendiendo a
configurar y dividir el disco en particiones. También aprenderemos el nuevo sistema de ficheros ZFS
(Zettabyte) incorporado a OpenSolaris 2008.05 .
Nombres de Dispositivos
bash-3.00# cd /dev/dsk
bash-3.00# ls –l
62
Comunidad OpenSolaris Hispano
……
• Dispositivos físicos: los nombres para los dispositivos físicos identifican su ubicación en el
hardware de la máquina. Son mas complejos de utilizar en la administración diaria por lo que
es mas práctico la utilización de los nombres lógicos. Ejemplo de un dispositivo físico:
/devices/pci@0,0/pci-ide@7,1/ide@0. Cada nodo esta separado con una / que se corresponde
también con su ruta en disco, es decir podemos ir al directorio ejecutando:
cd /devices/pci@0,0/pci-ide@7,1/ide@0
• Nombres de instancia: es un nombre de dispositivo abreviado que es creado por el propio
kernel. Un ejemplo del uso de los nombres de instancia lo encontramos en la ejecución del
comando ifconfig –a donde podemos ver en negrita el nombre de la instancia que corresponde
con la interfaz de red:
#ifconfig -a
lo0: flags=1000849<UP,LOOPBACK,RUNNING,MULTICAST,IPv4> mtu 8232 index 1
inet 127.0.0.1 netmask ff000000
hme0: flags=1000843<UP,BROADCAST,RUNNING,MULTICAST,IPv4> mtu 1500 index 2
inet 10.65.164.155 netmask fffffc00 broadcast 10.65.167.255
karol@un19009>>
Para obtener información sobre todos los dispositivos instalados en el sistema ejecutamos el
comando prtconf:
SUNW,Ultra-1
options, instance #0
sbus, instance #0
zs, instance #0
zs, instance #1
SUNW,fas, instance #0
sd, instance #0
sd, instance #6
SUNW,hme, instance #0
SUNW,ffb, instance #0
pseudo, instance #0
La opción de grep -v not mostrada en el ejemplo es añadida para que no muestre los
dispositivos que no tienen el driver cargado. Si no ponemos dicha opción que aparecen con el texto “driver
not attached”.
Si ejecutamos el comando prtconf con la opción –v obtenemos mas detalles sobre todos los
dispositivos del sistema.
63
Comunidad OpenSolaris Hispano
Para ver los discos reconocidos por el sistema ejecutamos el fomando format:
El comando format muestra los discos reconocidos por el sistema. Para salir pulsamos ctrl + c.
Muestra los discos numerados y con su nombre de dispositivo asignado. No olvidar que cada partición viene
definida en el nombre lógico por la letra s (slice), es decir que para el disco c0t0d0 las particiones son
c0t0d0s0, c0t0ds1, c0t0d0s2 etc..
Hemos visto como ver los dispositivos instalados en una máquina y ahora vamos a explicar como
reconocer un nuevo disco instalado en la máquina para su división en particiones.
64
Comunidad OpenSolaris Hispano
Cuando queremos añadir un nuevo disco al sistema pueden ocurrir dos circunstancias: añadir el
disco con la máquina arrancada por que alberga un servicio 24x7 o tenemos que parar sistema y hardware
para instalar el disco. La primera opción es viable con el hardware apropiado obligando al sistema a detectar
el nuevo disco sin reiniciar.
Para una máquina que no admite añadir discos en caliente tenemos que realizar una parada completa
de la máquina para añadir el nuevo hardware. Para reconocer nuevo componente en el sistema actuaríamos
de la siguiente forma:
1. Realizamos una copia del fichero /etc/path_to_inst
2. Creamos el fichero /reconfigure ejecutando: touch /reconfigure esto obliga al sistema en el próximo
arranque a detectar y reconfigurar todo el hardware.
3. Paramos la máquina con init 5.
4. Instalamos el nuevo hardware.
5. Arrancamos nuevamente la máquina.
6. Ejecutamos el comando prtconf para ver si esta el nuevo hardware, también podemos comparar con
el comando diff el backup del fichero /etc/path_to_inst con el nuevo siendo las diferencias el nuevo
hardware instalado.
Ahora vamos a proceder a reconocer un nuevo disco sin necesidad de detener la máquina para ello
ejecutamos el comando devfsadm.
La ejecución de este comando implica la regeneración de los directorios:
• /dev
• /devices
• Actualización del fichero /etc/path_to_inst
Antes de la ejecución del comando devfsadm es recomendable realizar un backup del fichero
/etc/path_to_inst para poder realizar una comparación entre el backup y el nuevo fichero /etc/path_to_inst
generado por el comando devfsadm. La comparación de ambos fichero nos mostrara el nuevo hardware
detectado.
Ejemplo de la comparación del fichero /etc/path_to_inst antes de la ejecución devfsadm y el nuevo
fichero generado por devfsadm:
Ejecutamos el comando prtconf para ver si esta el nuevo hardware detectado por el sistema.
65
Comunidad OpenSolaris Hispano
El nuevo disco ya es visible para sistema y podemos proceder a crear las particiones (slices).
Para crear las particiones utilizamos el comando format. Los pasos a seguir son los siguientes:
• Seleccionar el disco
• Crear las particiones
• Etiquetar el nuevo disco
• Crear el sistema de ficheros
• Montar el disco
# format
Searching for disks...done
En el menú de format muestra de forma numerada los discos disponibles con su nombre de lógico,
seleccionamos el disco con el que queremos trabajar y pulsamos intro:
selecting c1d1
Controller working list found
[disk formatted, defect list found]
FORMAT MENU:
disk - select a disk
type - select (define) a disk type
partition - select (define) a partition table
current - describe the current disk
format - format and analyze the disk
fdisk - run the fdisk program
repair - repair a defective sector
show - translate a disk address
label - write label to the disk
analyze - surface analysis
defect - defect list management
backup - search for backup labels
verify - read and display labels
save - save new disk/partition definitions
volname - set 8-character volume name
!<cmd> - execute <cmd>, then return
quit
66
Comunidad OpenSolaris Hispano
La utilizad format nos muestra un nuevo menú donde vamos a elegir la opción partition. Para entrar en
la utilizad de particiones tecleamos partition y pulsamos intro; nos mostrara un nuevo menú:
PARTITION MENU:
0 - change `0' partition
1 - change `1' partition
2 - change `2' partition
3 - change `3' partition
4 - change `4' partition
5 - change `5' partition
6 - change `6' partition
7 - change `7' partition
select - select a predefined table
modify - modify a predefined partition table
name - name the current table
print - display the current table
label - write partition map and label to the disk
!<cmd> - execute <cmd>, then return
quit
partition>
Ahora teclea print para ver la tabla de particiones que existe actualmente:
partition> print
Current partition table (original):
Total disk cylinders available: 2044 + 2 (reserved cylinders)
La partición numero dos es solo informativa y muestra el tamaño total del disco disponible.
Podemos definir hasta siete particiones, por lo tanto tenemos que planificar bien las particiones que
queremos crear.
El comando print muestra el estado actual de las particiones y la información es:
• Part: numero de la partición
• Tag: etiqueta predefinida.. Los valores posibles son:
o unassigned
o boot
o root
o swap
o usr
o backup
o stand
67
Comunidad OpenSolaris Hispano
o home
o alternates
• Flag: etiqueta predefinida. Los valores posibles son:
o wm: la partición se puede leer y escribir. Se puede montar
o wu: la partición es solo de lectura y no se pude montar.
o rm: la partición es solo de lectura y se puede montar.
o ru: la partición es solo de lectura y no se puede montar
- Seguidamente nos pregunta el valor para el tag. Tecleamos ? y pulamos intro para que muestre
todos los valores posibles. Elegimos la opción alternates ya que ninguna de las opciones mostradas
será el uso final del disco.
Enter partition id tag[unassigned]: ?
Expecting one of the following: (abbreviations ok):
unassigned boot root swap
usr backup stand var
home alternates reserved
- Ahora tenemos que definir los permisos para la partición, elegimos la opción por defecto wm que
permite la escrita en disco y su montaje.
- Ahora nos pedirá el cilindro de inicio. Esta opción la dejamos por defecto para que el sistema la
complete:
partition> print
Current partition table (unnamed):
Total disk cylinders available: 2044 + 2 (reserved cylinders)
partition> label
Ready to label disk, continue? y
Repetiremos el proceso para el resto de particiones que necesitamos crear. Cuando finalicemos
podemos salir de la utilidad format tecleando el comando quit.
Si al ejecutar el comando partition de la utilidad format responde el siguiente mensaje: Please run fdisk
first debemos ejecutar el comando fdisk para crear la tabla de particiones. El siguiente ejemplo muestra la
ejecución del comando:
format> partition
Please run fdisk first.
format> fdisk
No fdisk table exists. The default partition for the disk is:
Type "y" to accept the default partition, otherwise type "n" to edit the
partition table.
y
Al teclear fdisk y pulsar intro nos informa de que va a crear una tabla de particiones por defecto y nos
pide confirmación. Tecleamos y pulsamos intro. Ya podemos continuar gestionando el disco.
La VTOC
69
Comunidad OpenSolaris Hispano
Todos los discos en Solaris tienen un área especial que esta definida para almacenar toda la
información sobre el controlador de disco y sus particiones. A esta información sobre las particiones se la
denomina label y contiene información sobre las particiones que contiene el disco como su tamaño, los
límites de inicio y final de cada partición con datos sobre los cilindros.
Para ver la información de la VTOC dentro de la utilidad format seleccionamos el disco y ejecutamos
el comando verify.
Backup la VTOC
Para realizar un backup de la VTOC hay que ejecutar el comando prtvtoc redirigiendo la salida a un
archivo que contendrá el backup de la VTOC. Ejemplo:
Restaurar la VTOC
Nota: los comandos fmthard y prtvtoc necesitan tener acceso a los discos en modo raw por lo que hay que
utilizar siempre la ruta /dev/rdsk/nombre_del_disco
Hemos visto como crear los slices o particiones con la utilidad format ahora hay que crear un sistema
de ficheros por cada partición creada y posteriormente poder montarla. El comando que permite la creación
de un sistema de ficheros ufs es newfs.
El siguiente ejemplo muestra la ejecución del comando newfs que solicita confirmación antes de
ejecutar el comando ya que borra de forma irreversible todos los datos.
# newfs /dev/rdsk/c0d1s0
newfs: construir un nuevo sistema de archivos /dev/rdsk/c0d1s0: (y/n)? y
/dev/rdsk/c0d1s0: 8368128 sectores en 2043 cilindros de 128 pistas, 32 sectores
4086,0MB en 79 grupos de cilindros (26 c/g, 52,00MB/g, 6400 i/g)
70
Comunidad OpenSolaris Hispano
El comando newufs utiliza el acceso a disco en modo raw por lo que siempre hay que darle la ruta del
dispositivo /dev/rdsk. Si creamos varias particiones o slices tenemos que ejecutar el comando newfs por cada
una de ellas. Recordar que cada partición viene definida en el nombre lógico por la letra s (slice), es decir que
para el disco c0t0d0 las particiones son c0t0d0s0, c0t0ds1, c0t0d0s2 etc..
El directorio lost+found
Cuando el comando newufs crea el nuevo sistema de ficheros reserva un pequeño porcentaje de disco
para crear el directorio lost+found en el que se guarda la información necesaria para una posible reparación
del disco con la utilidad fsck. Este espacio reservado se le denomina minfree.
Ya tenemos creado el sistema de ficheros utilizando el comando newufs ahora hay que definir un
punto de montaje y montar el disco.
El comando que nos permite montar un sistema de ficheros es mount. El siguiente ejemplo crea un
punto de montaje y monta la partición:
# mkdir /nuevodisco
# mount /dev/dsk/c0d1s0 /nuevodisco/
# cd /nuevodisco/
# ls
lost+found
71
Comunidad OpenSolaris Hispano
El comando mount
El comando mount lo utilizaremos para montar unidades de forma manual desde una partición de un
disco, a un CDROM o un disquete.
La sintaxis del comando mount es:
El siguiente ejemplo monta un sistema de ficheros con todas las opciones que hemos visto:
Para montar un sistema de ficheros diferente a ufs utilizamos el mount con el parámetro –F. Los
sistemas de ficheros soportados por Solaris son:
• ufs: sistema de ficheros UNIX estándar.
• pcfs: sistema de ficheros que permite acceder a FAT32 para lectura y escritura.
• hsfs: sistema de ficheros High Sierra es el estándar para los CDROM.
• udf: de Formato de Disco Universal con soporte operaciones de lectura y escribe sobre DVD y
CD.
Desmontar un sistema de ficheros es sencillo solo tenemos que ejecutar el comando umount seguido
del punto de montaje. Un ejemplo para desmontar una unidad:
#umount /nuevodisco
Hasta el momento todos los comandos que hemos ejecutados no permanecen si reiniciamos la
máquina. Es decir si montamos un disco y lo utilizamos en el próximo arranque no esta montado y solo
veremos su punto de montaje. Para dejar una unidad montada de forma permanente en el sistema tenemos
que añadir los datos al fichero /etc/vfstab.
El contenido del vfstab es leído en el arranque del sistema y montadas todas las unidades que en el se
encuentran. En contenido del fichero es el siguiente:
Se compone de siete campos separados por tabulación y los campos sin valor se representan con un
guión “-“. Los campos que contiene son:
• device to mount: dispositivo que se va montar con su nombre lógico. Ejemplo /dev/dsk/cd1s0s0
• device to fsck: dispositivo que cuqueara la utilidad fsck con formato raw. Ejemplo /dev/rdsk/cd1s0s0.
• mount point: directorio que se establece como punto de montaje.
• FS type: tipo de sistema de ficheros que se va montar.
• fsck pass: activa el chequeo en al arranque. Se activa con un número como valor, excepto 0 que
desactiva el chuequeo.
• mount at boot: con valor yes se monta el sistema de ficheros en el arranque, y con valor no se queda sin
montar. Esto es utilizado para una desactivación temporal del sistema de ficheros.
• mount options: opciones separadas por comas que se pasan al comando mount cuando se monta file
systems. Un ejemplo puede ser montarlo solo en modo lectura.
Para añadir una partición de forma permanente al sistema editamos el archivo /etc/vfstab y añadimos
la nueva línea:
73
Comunidad OpenSolaris Hispano
El comando umount
Ejemplo:
bash-3.00# df -k
Sistema de archivos kbytes usados aprovechar capacidad Montado en
bash-3.00#
bash-3.00# umount /nuevodisco
Para desmontar un disco con seguridad ningún usuario o aplicación tiene que estar haciendo uso del
filesystem. Si al intentar desmontar un disco nos da el mensaje de ocupado es porque hay accesos al file
system y al desmontarlo podemos generar errores en una aplicación.
Ejemplo de aviso al intentar desmontar un disco:
Para averiguar que procesos están haciendo uso de un file system recurrimos al comando fuser.
#fuser -cu /nuevodisco
74
Comunidad OpenSolaris Hispano
ZFS
Introducción a ZFS
ZFS (Zettabyte File System ) es el nuevo sistema de archivos incorporado a OpenSolaris. Es un
sistema de archivos de 128 bits y su límite de tamaño máximo es de 256 cuatrillones de zettabytes1.
En la wikipedia se hace la siguiente referencia sobre la capacidad de ZFS:
“Como ejemplo de las capacidades expresadas por estos números, si un usuario crease 1000 ficheros por segundo, tardaría unos
9000 años en alcanzar el límite impuesto por el número de ficheros.”.
En este capitulo pretendemos ver la parte práctica de ZFS, si deseas conocer los límites teóricos de
ZFS puedes ver los valores de referencia en la wikipedia o en www.sun.com .
Las principales características de ZFS son:
• Administración sencilla por comandos o web. (nos olvidamos de format, newfs, mount, vfstab, etc..)
• Copy-on-write (ZFS no sobrescribe los nuevos datos directamente, crea los datos en un nuevo
bloque y posteriormente cambia los punteros de datos y realiza la escritura definitiva. Con este
método siempre esta garantizada la integridad de los datos y no es necesario el uso de utilidades
como fsck )
• Snapshots (capturas). Podemos sacar un “foto” de forma rápida a todo un sistema de ficheros.
Podemos instalar un paquete en el sistema y si este no cumple nuestras expectativas podemos
realizar un rollback para volver al estado anterior.
• Comprensión. Podemos definir un sistema de ficheros donde toda la información este comprimida.
• Mirror y RAID-Z: Se pueden definir de forma muy sencilla mirroring entre discos y RAID-Z.
Actualmente cuando trabajamos con herramientas como Solaris Volume Manager hay que crear las
particiones (slice), agrupar discos y crear la base de datos que alberga la configuración y estado de todos los
1
Información detallada sobre la unidad de medida en la wikipedia: http://es.wikipedia.org/wiki/Zettabyte
75
Comunidad OpenSolaris Hispano
volúmenes. Todo esto implica la ejecución de comandos como prtvtoc, fmthard, metadb, metainit y metaroot sin
contar las modificaciones en el fcihero /etc/vfstab.
Con ZFS todo se resume a dos comandos zfs y zpool. Tal como podemos ver en la figura 4.1 ZFS
trabaja con un pool que esta formado por todos los dispositivos físicos. Las características del pool son:
Forma ZFS
F F Z Z Z
V V
O O
STORAGE
POOL
Crear un pool
Vamos a crear un pool de 4GB comprendido por lo discos c1d0 y c1d1 ambos con un tamaño de
2GB. Para crear un pool llamado babilonia utilizamos el comando zpool de la siguiente forma:
# zpool list
NAME SIZE USED AVAIL CAP HEALTH ALTROOT
babilonia 3,88G 59,5K 3,87G 0% ONLINE -
#
Podemos ver que el tamaño del pool es de 3,88GB y es accesible desde /babilonia.
76
Comunidad OpenSolaris Hispano
Ya tenemos creado el pool y ahora podemos comenzar a definir sistemas de ficheros. Vamos a crear
dos sistemas de ficheros uno para instalar aplicaciones y otro para datos utilizando el comando zfs con la
opción create:
Para ver los nuevos sistema de ficheros ejecutamos el comando zfs con la opción list:
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
babilonia 138K 3,81G 27,5K /babilonia
babilonia/aplicaciones 24,5K 3,81G 24,5K /babilonia/aplicaciones
babilonia/datos 24,5K 3,81G 24,5K /babilonia/datos
La salida muestra los dos nuevos sistemas de ficheros que también son visibles con el comando df –
k. Se puede observar que todos los sistemas de ficheros comparten el mismo espacio de 3,81GB que es el
tamaño del pool.
Los sistemas de ficheros creados con ZFS se montan automáticamente y de forma persistente. Con
ZFS nos hemos ahorrado los pasos con los comandos format, newfs, mount y la posterior edición del fichero
/etv/vfstab para dejarlo de forma persistente.
Propiedades de un ZFS
Los sistemas de ficheros ZFS tienen propiedades que pueden ser activadas o desactivadas según
nuestras necesidades. Para establecer el valor de una propiedad se ejecuta el comando zfs con las opciones set
para establecer o get para leer. Veamos algunos de los mas interesantes:
ZFS nos da la posibilidad de controlar el espacio de los sistemas de ficheros estableciendo cuotas y
reserva de espacio para los sistemas de ficheros. Continuando con el pool de los ejemplos anteriores vamos
a establecer una cuota para el sistema de ficheros babilonia/aplicaciones y reservar espacio del pool para
babilonia/datos.
Estableciendo una cuota a un sistema de ficheros limitamos el espacio máximo que puede tener.
Para crear una cuota utilizamos el comando zfs y la opción set quota=1GB:
77
Comunidad OpenSolaris Hispano
Si ejecutamos el comando zfs list para ver los sistemas de ficheros observaremos que se ha
establecido la cuota correctamente:
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
babilonia 138K 3,81G 27,5K /babilonia
babilonia/aplicaciones 24,5K 1024M 24,5K /babilonia/aplicaciones
babilonia/datos 24,5K 3,81G 24,5K /babilonia/datos
Una cuota limita el espacio de un sistema de ficheros pero no garantiza dicho espacio. Para reservar
el espacio para un sistema de ficheros dentro del pool ejecutamos zfs con el parámetro set reservation=1GB:
El sistema de ficheros babilonia/datos tiene reservados 1GB del pool. Si el resto de ficheros llena el
pool no peligra nuestro espacio reservado. Ejecutando zfls list se puede ver que el pool babilonia tiene como
usado 1GB y para el resto de sistemas de ficheros hay disponible 2,81GB. Salida de zfs list:
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
babilonia 1,00G 2,81G 27,5K /babilonia
babilonia/aplicaciones 24,5K 1024M 24,5K /babilonia/aplicaciones
babilonia/datos 24,5K 3,81G 24,5K /babilonia/datos
Realizar una reserva de espacio no implica un limite de cuota para el sistema de ficheros este puede
utilizar todo el tamaño del pool. Se pueden combinar las opciones de cuota y reserva para un sistema de
ficheros.
ZFS ofrece nuevas posibilidades como tener un sistema de ficheros con información comprimida. El
comando para habilitar la compresión del sistema de ficheros es zfs con el parámetro compression=on. El
siguiente ejemplo activa la compresión para el sistema de ficheros babilonia/datos:
78
Comunidad OpenSolaris Hispano
Para establecer un sistema de ficheros como solo lectura utilizamos el colmando zfs con el parámetro
readonly=on
Para cambiar el punto de montaje de un sistema de ficheros ejecutamos el comando zfs estableciendo
el nuevo punto de montaje con el parámetro mountpoint. El siguiente ejemplo muestra como cambiar el
punto de montaje de babilonia/datos a /aulaunix:
#cd /
# zfs set mountpoint=/aulaunix babilonia/datos
Hasta ahora hemos utilizado el comando zfs set para establecer propiedades del sistema de archivos.
Para ver los valores de las propiedades de un ZFS ejecutamos zfs con la opción get:
79
Comunidad OpenSolaris Hispano
Con la opción all podemos ver todos los valores de las propiedades de un ZFS y cuales son sus
valores por defecto:
Para ampliar el espacio disponible en un pool tenemos que añadir nuevos discos a la máquina o
utilizar particiones (slices) no usada en otro disco. Para ampliar el pool utilizamos el comando zpool con la
opción add:
Tal como podemos ver en la salida de la ejecución de zpool add el espacio a aumentado de 1,89G a
3,97G. Se pueden añadir tantos discos como sean necesarios.
80
Comunidad OpenSolaris Hispano
Se pude sacar un disco que forma parte del pool utilizamos la orden zpool remove :
Eliminar un pool
Si tenemos que eliminar un pool por completo y dejar los dispositivos libres para otro uso utilizamos
el comando zpool:
Esta opción es “destructiva” por lo que tenemos que estar muy seguros de que no tenemos
información valiosa en el pool a borrar.
En caso de que un de los discos falle y se tenga que reemplazar utilizamos el comando zpool con el
parámetro replace:
81
Comunidad OpenSolaris Hispano
Si tuviéramos que crear un espejo de dos discos utilizando herramientas como Solaris Volume
Manager realizaríamos varias tareas para logar nuestro objetivo. Con ZFS es muy sencillo tan solo
necesitamos con los comandos zpool y zfs.
Si tenemos un pool de un disco y queremos crear un mirror del disco acudimos al comando zpool
con el parámetro attach:
La ejecución del comando creara un mirror formado por los discos c0d1 ya existente y el nuevo disco c1d1.
En caso de que un de los discos falle y se tenga que reemplazar utilizamos el comando zpool con el
parámetro replace:
almoroz ONLINE 0 0 0
mirror ONLINE 0 0 0
c0d1 ONLINE 0 0 0
c1d1 ONLINE 0 0 0
Y lo verificamos:
zpool status
conjunto: almoroz
estado: ONLINE
limpiar: resilver completed con 0 errores en Wed Jan 31 16:46:57 2007
config:
Crear RAID-Z
ZFS permite la creación de RAID-Z muy similar a RAID 5. RAID 5 se compone como mínimo de
tres discos y en cada uno de ellos se reserva un espacio con información de paridad.
RAID-Z cuenta con ventajas como la paridad distribuida simple y doble. La doble paridad permite
asumir errores en uno dos discos que componen el RAIDZ.
83
Comunidad OpenSolaris Hispano
Snapshots
Los snapshots son fotos de los datos de un sistema de ficheros, esto se hace de forma instantánea y
comparte el espacio de los datos no modificados. Tiene gran utilidad para realizar modificaciones sobre
servicios y si no funcionan realizar un rollback de forma sencilla. Vamos un caso práctico:
Disponemos de los siguientes sistemas de ficheros en el pool llamado babilonia:
# zfs list
NAME USED AVAIL REFER MOUNTPOINT
babilonia 500M 3,42G 27,5K /babilonia
babilonia/prueba1 500M 3,42G 500M /babilonia/prueba1
babilonia/prueba2 24,5K 3,42G 24,5K /babilonia/prueba2
El sistema de ficheros babilonia/prueba1 contiene los siguientes archivos:
# ls -lrt
total 1024223
-rw------T 1 root root 104857600 Feb 2 13:10 fichero1
-rw------T 1 root root 104857600 Feb 2 13:10 fichero2
-rw------T 1 root root 104857600 Feb 2 13:10 fichero3
-rw------T 1 root root 104857600 Feb 2 13:10 fichero4
84
Comunidad OpenSolaris Hispano
Procedemos a crear el snapshot o foto del sistema de ficheros babilonia/prueba1 con el comando zfs
y e parámetro snapshots:
Ejecutamos el comando:
#zfs list
Ahora vamos a simular un pequeño desastre borrando los archivos fichero4 y fichero5:
# rm fichero4 fichero5
# ls -lrt
total 614541
-rw------T 1 root root 104857600 Feb 2 13:10 fichero1
-rw------T 1 root root 104857600 Feb 2 13:10 fichero2
-rw------T 1 root root 104857600 Feb 2 13:10 fichero3
Recuperamos archivos los borrados recurriendo a snapshot creado. Recuperamos con el comando
zfs y el parámetro rollback:
Ejecutamos el comando:
#zfs rollback -r babilonia/prueba1@nombredelafoto
# ls -lrt
total 1024223
-rw------T 1 root root 104857600 Feb 2 13:10 fichero1
-rw------T 1 root root 104857600 Feb 2 13:10 fichero2
-rw------T 1 root root 104857600 Feb 2 13:10 fichero3
-rw------T 1 root root 104857600 Feb 2 13:10 fichero4
-rw------T 1 root root 104857600 Feb 2 13:10 fichero5
Y el resultado es la recuperación de los archivos fichero4 y fichero5. Tal como se decía al principio la
foto comparte los datos con los no modificados, en nuestro ejemplo se traduce con que la foto comparte el
espacio de fichero1, fichero2 y fichero3 que no se han modificado ocupando realmente solo el tamaño de fichero4
y fichero5.
85
Comunidad OpenSolaris Hispano
Cuando ya no sea necesario conservar un snapshot podemos borrarlo con el comando zfs y el
parámetro destroy:
Ejemplo:
#zfs list
Estados de ZFS
86
Comunidad OpenSolaris Hispano
Con el comando zpool status –x obtenemos de forma rápida sin un pool esta teniendo problemas:
El siguiente ejemplo muestra un mirror compuesto por dos dispistivos fallando c0d1 que esta
totalmente inaccesible. Al ser un mirror el servicio continuo operativo pero se degrada el rendimiento y
perdemos alta disponibilidad hasta que se reponga el disco dañado.
En el ejemplo hemos reemplazado el disco c0d1 por c2t0d0 y automáticamente el mirror para a
estado ONLINE y replica los datos de c0d1 a c2t0d0.
También podemos optar por sacar el disco del mirror para repararlo. Tenemos que desasociar el
disco c0d1 del mirror con el comando.
zpool detach:
87
Comunidad OpenSolaris Hispano
El disco c0d1 ya no forma parte del mirror babilonia. Podemos someterlo a pruebas y volver a
añadirlo al mirror o añadir otro disco distinto se la siguiente forma:
ZFS proporciona el comando zpool iostat que reporta e sobre operaciones de lectura, escritura y
ancho de banda. El siguiente ejemplo muestra la salida del comando zpool iostat:
Si omitimos el nombre del pool en el comando lista la información de todos los pool disponibles.
88
Comunidad OpenSolaris Hispano
Zonas
Zonas con OpenSolaris 2008.05
89
Comunidad OpenSolaris Hispano
La zonas no globales pueden compartir directorios con la zona global o estar aislada. Una zona no
global puede compartir con la zona global los sistemas de ficheros:
• /usr
• /lib
• /sbin
• /platform
El uso de una zona no global compartida ocupa tan solo 100MB al tener compartidos directorios
con la zona global tal como se puede ver en la figura 5.1.
/lib /lib
/sbin /sbin
/platform /platform
/var /var
/etc /etc
4GB 100MB
Zona Global 0
BIG ZONE
/dev/dsk/c0d0 /dev/dsk/c1d0
/usr /usr
/lib /lib
/sbin /sbin
/platform /platform
/var /var
/etc /etc
4GB 3GB
90
Comunidad OpenSolaris Hispano
Las zonas no compartidas o zonas grandes ocupan 4GB ya que no comparten sistema de ficheros.
Al no compartir sistemas de ficheros con la zona global podemos aplicar parches a la zona distintos a los de
la zona global. Podemos tener varias zonas con niveles de parche distintos según las necesidades de las
aplicaciones. En la figura 5.2 se representa una zona no compartida.
Control de recursos
Cuando creamos una zona tenemos que asignarlas recursos como red, memoria, CPU etc..
Asignar CPU
- CPU fija: una zona puede tener asignada una o mas CPUs de forma fija. Esta forma puede ser útil
cuando licenciamos aplicaciones por el numero de CPU. Esta opción tiene una desventaja si la zona
no requiere mucho uso de CPU ya que perdemos capacidad de procesamiento estando la CPU
solamente asignada una zona.
- CPUs dinamicas: se asigna un mínimo y un máximo de CPU´s para una zona. El demonio poold se
encarga de balancear el numero de CPUs disponibles según la necesidades de cada zona.
- CPUs compartidas: consiste en un pool de CPUs asignado a todas las zonas. El sistema repartirá las
CPU según las necesidades de cada zona.
Memoria
El control de memoria para zonas antes de OpenSolaris 2008.05 no se podía realizar de forma
directa utilizando. Se ha incluido una nueva propiedad denominada zone.max-locked-memory que establece el
limite de memoria para una zona.
Espacio en disco
RED
Cuando creamos una zona se le asigna una dirección IP e interfaz de red de la zona global.
91
Comunidad OpenSolaris Hispano
En el siguiente apartado vamos a seguir los pasos necesarios para crear una zona OpenSolaris
2008.05 no compartida ocupando tan solo 100MB . La zona a crear tiene un dirección IP asociada a la
interfaz pcn1 y se instala en /babilonia/mizona.
Ejecutamos el comando zonecfg con la opción –z de la siguiente forma:
Al ejecutar el comando aparece un mensaje indicando que la zona no esta configurada. Para
configurar la zona tenemos que introducir los comandos de configuración el editor de zonezfg. Los datos a
introducir son:
• autoboot=trae: este parámetro define si la zona es persintente a los reinitos del sistema. Si
reiniciamos la máquina anfitriona la zona también arrancara.
• zonepath: PATH donde se instalara la zona Solarias 10.
• set address: asigna una dirección IP para la zona
• set physical: asocia una interfaz de la zona no global para su uso en la zona.
# zonecfg -z mizona
zonecfg:mizona> create
zonecfg:mizona> set autoboot=true
zonecfg:mizona> set zonepath=/babilonia/mizona
zonecfg:mizona> add net
zonecfg:mizona:net> set address=10.73.111.25
zonecfg:mizona:net> set physical=pcn1
zonecfg:mizona:net> end
zonecfg:mizona> info
zonename: mizona
zonepath: /babilonia/mizona
autoboot: true
pool:
limitpriv:
inherit-pkg-dir:
dir: /lib
inherit-pkg-dir:
dir: /platform
inherit-pkg-dir:
dir: /sbin
inherit-pkg-dir:
dir: /usr
net:
address: 10.73.130.25
physical: pcn1
92
Comunidad OpenSolaris Hispano
zonecfg:mizona> verify
zonecfg:mizona> commit
zonecfg:mizona> exit
Con los pasos anteriores hemos creado la zona. Al realizar el commit se crea un fichero XML
en /etc/zones con los datos de la zona:
Ejemplo de mizona.xml:
# more mizona.xml
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE zone PUBLIC "-//Sun Microsystems Inc//DTD Zones//EN" "file:///usr/share/lib/xml/dtd/zonecfg.dtd.1">
<!--
DO NOT EDIT THIS FILE. Use zonecfg(1M) instead.
-->
<zone name="mizona" zonepath="/babilonia/mizona" autoboot="true">
<inherited-pkg-dir directory="/lib"/>
<inherited-pkg-dir directory="/platform"/>
<inherited-pkg-dir directory="/sbin"/>
<inherited-pkg-dir directory="/usr"/>
<network address="10.73.130.25" physical="pcn1"/>
</zone>
Ya esta creada la zona y tenemos que inicializarla para que se instalen los paquetes necesarios. Este
paso puede tardar varios minutos por que implica la copia de todos los paquetes necesarios.
Antes de iniciar la instalación de paquetes para la zona debemos de comprobar los permisos de la
zona par ello acudimos al comando zoneadm para verificar que la zona tiene los permisos necesarios para su
creación.
Para verificar ejecutamos:
Al lanzar el comando nos muestra un mensaje avisando que los permisos sobre los ficheros de la
zona no son los correctos:
Si ejecutamos nuevamente el comando zoneadm para verificar la zona no observaremos ningún error.
Instalamos la máquina ejecutando la orden:
Una vez finalizada la copia de paquetes comprobamos que la maquina esta instalada correctamente
ejecutando zoneadm list –cv:
Arrancar la zona
La máquina ya esta configurada e instalada ahora tenemos que arrancar la zona con el comando
zoneadm y el parámetro boot:
Para verificar que la zona esta arrancada ejecutamos el comando zoneadm list –cv y veremos que su
estado es running.
94
Comunidad OpenSolaris Hispano
Tenemos la máquina virtual ejecutándose correctamente y queda realizar el ultimo paso supone
entrar en la máquina y responder unas preguntas sobre la configuración que queremos para la zona. Las
preguntas son las mismas que en una instalación normal de Solaris, realizará las siguientes preguntas:
• Nombre de la máquina
• Idioma del sistema
• Idioma del teclado
• Tipo de Terminal
• Zona geográfica
• Contraseña de root
• Compatibilidad NTFS v4
Como se aprecia en el siguiente ejemplo se inicia un pequeño instalador que pregunta nuestras
preferencias para el sistema:
Select a Language
0. English
1. Spanish
2. it
Sobre el Terminal:
¿Qué tipo de terminal esta usando?
1) Est√°ndar ANSI CRT
2) DEC VT52
3) DEC VT100
4) Heathkit 19
5) Lear Siegler ADM31
6) Consola PC
7) Herramienta de comandos Sun
8) Estación de Trabajo (Workstation) Sun
9) Televideo 910
10) Televideo 925
11) Wyse, modelo 50
12) Emulador X Terminal (xterms)
95
Comunidad OpenSolaris Hispano
Cuando finalizamos la preguntas se configura e inicia el arranque del sistema operativo OpenSolaris
2008.05 como en cualquier máquina:
babilonia console login: Feb 13 03:09:03 babilonia sendmail[5971]: My unqualified host name (localhost) unknown; sleeping for
retry
Estamos dentro de la máquina virtual babilonia y podemos hacer login con el usuario introducido en
las preguntas de la instalación de la zona. Ahora podemos instalar y configurar la máquina virtual como
cualquier otra.
Ahora se puede hacer telnet o ssh a la dirección IP que tenemos asociada a nuestra máquina virtual e
instar cualquier servicio normalmente.
Para parar una máquina virtual podemos proceder de dos formas diferentes:
1. Al ser una máquina virtual responde a los mismos comandos de parada que cualquier instalación
normal de Solaris por lo tanto podemos parar con comandos como init 0, shutdown o halt.
2. Desde la zona global podemos o reiniciar la máquina utilizando el comando zoneadm con los
parámetros reboot y halt:
a. zoneadm -z [nombre de la zona] reboot
b. zoneadm -z [nombre de la zona] halt
Tal como hemos visto al comienzo una zona no compartida no comparte los directorios
/usr./lib,/sbin y /platform por lo tanto ocupa 4GB de espacio aportando la ventaja de tener una zona
totalmente independiente donde se puede aplicara un nivel de parches diferente a la zona global.
Para crear una zona no compartida vamos utilizar un disco completo de 6GB con sistema de
ficheros UFS montado en /bigzone.
Antes de instalar la zona vemos que tan solo ocupamos el 1% del disco:
Al finalizar la instalación el espacio ocupado por la zona es igual a una instalación completa de
OpenSolaris 2008.05 :
96
Comunidad OpenSolaris Hispano
Una zona no compartida o BigZone se crea igual que una zona compartida con la salvedad de que
indicamos que no se compartan los sistemas de ficheros /usr./lib,/sbin y /platform con los parámetros:
# zonecfg -z mibigzone
mibigzone: No se ha configurado esa zona
Use 'create' para comenzar a configurar una zona nueva.
zonecfg:mibigzone> create
zonecfg:mibigzone> remove inherit-pkg-dir dir=/sbin
zonecfg:mibigzone> remove inherit-pkg-dir dir=/usr
zonecfg:mibigzone> remove inherit-pkg-dir dir=/platform
zonecfg:mibigzone> remove inherit-pkg-dir dir=/lib
zonecfg:mibigzone> set autoboot=true
zonecfg:mibigzone> set zonepath=/bigzone
zonecfg:mibigzone> add net
zonecfg:mibigzone:net> set address=127.0.0.100
zonecfg:mibigzone:net> set physical=lo0
zonecfg:mibigzone:net> end
zonecfg:mibigzone> info
zonename: mibigzone
zonepath: /bigzone
autoboot: true
pool:
limitpriv:
net:
address: 127.0.0.100
physical: lo0
zonecfg:mibigzone> verify
zonecfg:mibigzone> commit
zonecfg:mibigzone> exit
Arrancamos la zona:
Select a Language
0. English
1. Spanish
2. it
Hemos visto como crear una zona, configurarlas y las operaciones de parada y arranque. Ahora
veremos como detectar el estado de una máquina desde la zona global. Con el comando zoneadm list –cv
obtenemos información sobre el estado de una zona:
98
Comunidad OpenSolaris Hispano
• Incomplete: mostrará este estado muestran se están instalando los paquetes al ejecutar zoneadm con la
opción install.
• Installed: la zona tiene todos los paquetes necesarios para su funcionamiento.
• Ready: la zona esta lista tiene creado el kernel, los controladores de red están cargados y los sistemas
de ficheros montados.
• Running: la zona esta arrancada.
• Shutting Down: la zona esta en proceso de parada.
Una zona puede ser monitorizada desde la zona global utilizando el comando zlogin con la opción –S
que permite la ejecución de un comando dentro la zona y enviar la salida del comando a la zona global.
Uptime:
FileSystems:
#
# zlogin -S nocompartida "df -k"
Filesystem kbytes used avail capacity Mounted on
/ 5783070 2964445 2760795 52% /
/dev 5783070 2964445 2760795 52% /dev
proc 0 0 0 0% /proc
ctfs 0 0 0 0% /system/contract
swap 513036 260 512776 1% /etc/svc/volatile
mnttab 0 0 0 0% /etc/mnttab
/usr/lib/libc/libc_hwcap1.so.1 5783070 2964445 2760795 52% /lib/libc.so.1
fd 0 0 0 0% /dev/fd
swap 512812 36 512776 1% /tmp
swap 512796 20 512776 1% /var/run
Uname –a:
99
Comunidad OpenSolaris Hispano
Para entrar a una zona podemos realizar un telnet o ssh a la dirección IP asociada a la zona o entrar
por consola con la utilizad zlogin:
Para desinstalar una zona tenemos que detener la zona y ejecutar el comando zoneadm con la opción
uninstall. Hay que usar esta opción con mucha precaución ya que elimina todos los ficheros:
Introducción
Debemos imaginar una zona de OpenSolaris como un contenedor de procesos, es decir la zona es
una jaula cuyo contenido no puede ver lo que hay fuera de ella. Para que los procesos puedan ejecutarse el
kernel debe proporcionar una serie de recursos a dicha zona, como pueden ser acceso a discos, interfaces de
red, etc. Dichos recursos no pueden ser compartidos entre zonas.
La excepción es la zona global con id 0, esta se crea cuando arranca el sistema y tiene asociado todos
los recursos sin restricciones de privilegios. Incluso en los sistemas que no se ha definido ninguna zona
existe una zona global.
Cada zona esta identificada por un nombre y un id, el nombre global y el id 0 está reservados para la
zona global.
100
Comunidad OpenSolaris Hispano
En nuestro sistema solo tenemos un Kernel ejecutándose, los procesos de las distintas zonas se
ejecutan todos en el mismo que, lógicamente es el que se inicia al arrancar la zona global.
Esto tiene grandes beneficios a nivel de performance, especialmente si el diseño de las zonas ha sido
bien pensado.
• Las páginas de texto (el código de los ejecutables y librerías) que ha cargado en memoria una zona
son compartidas con las demás.
• Las tareas que periódicamente se ejecutan en el kernel (p.ej. todas las de la callout table) no se
duplican por cada zona.
Teniendo en cuenta lo anterior interesa, desde el punto de vista de la performance, que las distintas
zonas sean los mas parecidas posible y compartan el mayor número de directorios posibles.
P. ej. mientras que levantar el sistema consume en mi equipo 339 megas de la memoria física, arrancar
una zona adicional consume solo 79 mb.
101
Comunidad OpenSolaris Hispano
Privilege Description
PRIV_NET_RAWACCESS Allows a process to have direct access to the
network layer.
PRIV_PROC_CLOCK_HIGHRES Allows process to create high-resolution timers.
PRIV_PROC_LOCK_MEMORY Allows process to lock pages in physical memory.
PRIV_PROC_PRIOCNTL Allows process to change scheduling priority or
class.
PRIV_PROC_ZONE Allows process to control/signal other processes
in different zones.
[...]
De esta manera los procesos se hallan aislados de forma efectiva de aquellos que no se están
ejecutando en su misma zona.
Obviamente, a parte de la restricción nivel de privilegios, es vital para la seguridad de las zonas, que
los derechos de acceso a los distintos recursos sean correctos. Es decir, los privilegios nos indican que
"acciones" podemos realizar (p. ej. Un chown), pero donde realizarlas está controlado a nivel de objetos (p.
ej. Usando zonecfg damos acceso a los filesystem que nos interesa.).
Es la combinación de ambas cosas, privilegios y restricciones de acceso , lo que finalmente garantiza
la seguridad entre zonas.
Como pequeño ejemplo prático podemos comprobar como desde la zona global vemos los pids de
las demás y no así a viceversa. En ambos casos el id del usuario es 0 (root).
bash-3.00# uname -a
SunOS test 5.11 snv_70b i86pc i386 i86pc
bash-3.00# ps
PID TTY TIME CMD
11227 console 0:01 bash
29665 console 0:02 sh
26806 console 0:00 ps
#ps desde la zona global con un grep para ver el proceso bash de la zona test
bash-3.00# id
uid=0(root) gid=0(root)
bash-3.00# ps -ef | grep 11227
root 11227 29665 1 Jan 18 zoneconsole 0:01 bash
root 26809 555 1 09:45:14 pts/2 0:00 grep 11227
#ps desde la zona global
bash-3.00# ps
PID TTY TIME CMD
555 pts/2 0:03 bash
551 pts/2 0:00 sh
26812 pts/2 0:00 ps
#ps desde la zona test buscando el pid del bash de la zona global
Como consecuencia de lo anterior existen algunas tareas que no están permitidas ejecutarse dentro de
una zona:
Existen dos nuevos procesos por cada zona no global que tenemos en el sistema, su función
gestionar los recursos de ellas:
• Configurar el control a los recursos de dicha zona (como pools de CPU, memoria o privilegios).
103
Comunidad OpenSolaris Hispano
• Proporcionar un Door Server, los clientes como el zoneadm o el propio kernel se conectan a el para
enviar mensajes de cambio de estado a la zona como halt, reboot, ...
Hay una completa descripción de este proceso en el fichero zoneadmd.c del código fuente.
El otro proceso es el zsched, sus tareas son:
La estructura zone_t
Por cada zona existente en el sistema hay una estructura zone_t en el kernel, en ella tenemos
información acerca del estado y configuración de esta.
Podemos ver su definición en el fichero zone.h de nuestro sistema:
typedef struct zone {
/*
* zone_name is never modified once set.
*/
char *zone_name; /* zone's configuration name */
/*
* zone_nodename and zone_domain are never freed once allocated.
*/
char *zone_nodename; /* utsname.nodename equivalent */
char *zone_domain; /* srpc_domain equivalent */
/*
* zone_lock protects the following fields of a zone_t:
104
Comunidad OpenSolaris Hispano
* zone_ref
* zone_cred_ref
* zone_ntasks
* zone_flags
* zone_zsd
*/
kmutex_t zone_lock;
/*
[...]
Dentro de ella encontramos los parámetros con los que hemos configurado la zona, entre ellos los
que limitan el consumo, como por ejemplo el máximo de memoria, el número de semáforos, etc. Vamos
hacer un breve repaso a los mas destacados:
*zone_name; /* nombre de la zona */
zoneid_t zone_id; /* ID de la zona */
rctl_qty_t zone_locked_mem_ctl; /* límite máximo de
memoria*/
rctl_qty_t zone_max_swap_ctl; /* límite máximo de
swap */
[...]
También hay información de la zona, como por ejemplo:
char *zone_rootpath; /* path de la raíz de la zona */
zone_status_t zone_status; /* en que estado esta actualmente la
zona*/
rctl_qty_t zone_nlwps; /* número de hilos ejecutándose */
[...]
Podemos acceder fácilmente a ella usando mdb:
bash-3.00# mdb -k
Loading modules: [ unix genunix specfs dtrace uppc pcplusmp scsi_vhci ufs ip
hook neti sctp arp usba fctl nca lofs mpt audiosup zfs random sppp crypto ptm
md nfs cpc fcip fcp logindmux nsctl sdbc sv ii rdc ]
> ::walk zone
fec7f028
d5072b40
d884ac40
> ::walk zone
fec7f028
d5072b40
d884ac40
> d5072b40 ::zone
ADDR ID NAME PATH
d5072b40 1 linux /zone/root/
> d884ac40 ::zone
105
Comunidad OpenSolaris Hispano
106
Comunidad OpenSolaris Hispano
Brandz y Linux
Introducción
Brandz es un tipo específico de zona que permite la ejecución de binarios no nativos dentro de ella.
Esta tecnología se está desarrollando dentro de el proyecto OpenSolaris, puesto que aun no está finalizado
puede que este documento quede obsoleto tras pasar algunos meses, sin embargo es difiícil que se produzca
un cambio radical de diseño por lo que en su mayoría debería ser aplicable.
Técnica de interposición
En Linux un proceso para usar una llamada al sistema ejecuta la interrupción 80, este método no
existe en OpenSolaris, para emularlo se ha diseñado una macro BRAND_CALLBACK() que captura ese
punto de entrada. Una vez capturado, en lugar de seguir el flujo normal dentro del kernel, esos hilos son
procesados por un módulo específico para tareas dentro de un brandz.
107
Comunidad OpenSolaris Hispano
Existen otros puntos de interposición situados en el flujo de vida de un proceso para asegurar que el
kernel presta todos los servicios necesarios, como por ejemplo en la creación/salida de hilos, tratamiento de
señales, etc.
Dicho módulo hace de traductor, es decir modifica el formato de la llamada al sistema de Linux a su
equivalente a OpenSolaris. El ciclo de vida sería el siguiente:
1. El proceso Linux ejecuta la interrupción 80.
2. La macro BRAND_CALLBACK() comprueba si la interrupción tiene origen en un Brandz.
3. Opensolaris pasa el control del thread al módulo específico para brandz.
4. El módulo lx lanza la librería de emulación.
5. Dicha librería modifica la llamada al sistema para que sea compatible con OpenSolaris.
6. El kernel de OpenSolaris procesa la llamada y devuelve la salida a la librería.
7. Otra vez se realizan las operaciones oportunas, ahora para adaptar la salida a lo que espera el proceso
Linux.
8. La librería devuelve el resultado al proceso.
Puesto que los servicios del kernel tienen pequeñas variaciones dependiendo de la versión y de que las
librerías glibc usadas, ha día de hoy (febrero del 2008) está probado y funciona de forma estable RHEL 3, se
está trabajando para que funcione RHEL 4 pero aun quedan algunos flecos.
Peculiaridades
A pesar que lo expuesto parece sencillo, su implementación práctica es compleja, ya que son
numerosas las peculiaridades con las que topamos, teneís una lista detallada en la web de la comunidad. A
continuación explico un par de ejemplos:
Algunas llamadas al sistema son muy diferentes entre OpenSolaris y Linux, algunas ni siquiera tienen
equivalente.
Quizás el caso más llamativo es la llamada clone (), que Linux usa para crear un hijo y que no existe
en OpenSolaris. En su lugar se utiliza fork (2), sin embargo alguno de los flags no tienen ninguna
equivalencia, afortunadamente su uso es marginal.
Otro caso curioso es que el número de señales existentes en Linux y OpenSolaris para procesos en
Real Time es distinto, 32 vs 7, afortunadamente esas señales extras no tienen uso en la actualidad, por lo que
directamente se ignoran.
Caso Práctico
Crear un Brandz es sencillo, el procedimiento es identico a como crear una zona, solo que al ejecutar
el create debemos espcificar que use el módulo lx, por otro lado, cuando hacemos el install debemos
especificar la fuente de donde se deben copiar los binarios.
Para ir rápido podeís descargar un tar de Centos 3.5 directamente de la web de la comidad
OpenSolaris, os dejo una captura de la shell de todo el proceso:
# zonecfg -z linux
linux: No such zone configured
Use 'create' to begin configuring a new zone.
zonecfg:linux> create -t SUNWlx
zonecfg:linux> set zonepath=/linux-zone
zonecfg:linux> commit
108
Comunidad OpenSolaris Hispano
zonecfg:linux> exit
# mkdir /linux-zone
# chmod 700 /linux-zone
bash-3.2# zoneadm -z linux install -d /centos_fs_image.tar
Installing zone 'linux' at root directory '/linux-zone'
from archive '/centos_fs_image.tar'
This process may take several minutes.
Setting up the initial lx brand environment.
System configuration modifications complete.
Setting up the initial lx brand environment.
System configuration modifications complete.
linux login: ~.
[Connection to zone 'linux' console closed]
109
Comunidad OpenSolaris Hispano
No podemos olvidar que las distintas técnicas de virtualización, tienen como fin, no el que podamos
disfrutar en una máquina de un SO Linux, un Windows y varias versiones distintas de Solaris, aunque
aparentemente suena tentador. El objetivo principal de utilizar tecnología de virtualización consiste en
110
Comunidad OpenSolaris Hispano
• Uso de la memoria
• Entrada/Salida
Particiones físicas.
En una máquina realizamos una serie de particiones a nivel físico de forma que se reparten los recursos
disponibles entre los distintos SO que van a ser ejecutados en la máquina. A todos los efectos disponemos
de varias máquinas, esa es la visión que tiene el SO.
Máquinas virtuales.
En una máquina podemos tener corriendo varias máquinas virtuales con distintos SO. En este caso los
recursos son asignados mediante la utilización de un Hypervisor que se encarga de gestionar el acceso al
HW, los distintos SO tienen asignados unos recursos que son controlados por el Hypervisor.
Virtualización de SO.
La virtualicación de SO, consiste en que un SO anfitrión ejecuta varias instancias del mismo SO,
asignando y gestionando los recursos del sistema. La impresión es de disponer varios sistemas con el mismo
SO.
111
Comunidad OpenSolaris Hispano
Control de recursos.
Solaris dispone de una serie de herramientas para controlar los recursos del sistema. CPU, memoria,
tiempo de CPU, de esta forma los recursos no son asignados a un SO invitado, sino que se asigna mediante
políticas a los procesos o grupos de procesos que están ejecutándose en el sistema.
xVM se encuentra dentro del nicho de máquinas virtuales y sería para x86 lo mismo que LDoms
para SPARC.
Arquitectura
112
Comunidad OpenSolaris Hispano
Red
Los distintos domU acceden a dispositivos virtuales, que están asociado a dispositivos virtuales en el
dom0 que a su vez se encuentran asociados a un dispositivo físico, como en este caso una interfaz de red
bge0.
Dispositivos de bloque
Un dominio, puede ser bien el dominio de control dom0, bien cualquiera de los dominios de usuarios
domU, pueden exportar un dispositivo de bloques, que puede ser a su vez, un dispositivo físico, como un
disco o bien puede ser un fichero del FS, el cual es exportado al domU y éste la visión que tendrá será la de
que está accediendo a un dispositivo de bloques.
• Dispositivo físico
disk = [‘phy:dispositivo_dom0, disp_domU, rw’]
• Fichero
disk = [‘file:file_dom0, disp_domU, rw’]
xVM esta disponible desde la build 75 de Solaris Express. Para comprobar que tenemos instalado
en nuestra maquina xVM, podemos chequear el directorio /boot/
bash-3.2# cd /boot/
bash-3.2# ls
acpi grub solaris x86.miniroot-safe xen.gz
amd64 platform solaris.xpm xen-syms
bash-3.2#
En la salida anterior podemos comprobar que existe un kernel con soporte para Xen, el fichero es
xen.gz. También podemos chequear el estado de los servicios en SMF.
bash-3.2# svcs | grep xvm
disabled 23:36:20 svc:/system/xvm/store:default
disabled 23:36:20 svc:/system/xvm/domains:default
disabled 23:36:21 svc:/system/xvm/console:default
disabled 23:36:22 svc:/system/xvm/xend:default
bash-3.2#
113
Comunidad OpenSolaris Hispano
114
Comunidad OpenSolaris Hispano
• virt-manager, es un sencillo GUI que nos ayuda con la gestión de los domU.
Directorios
Entre los directorios utilizados por xVM, vamos a destacar los siguientes, por que son donde se
almacenan los ficheros que vamos a necesitar cuando comencemos a trabajar con xVM:
• /var/log/xen, se utiliza para almacenar los logs, es importante echar un vistazo a este directorio, ya
que los errores que devuelven los distintos comandos no son demasiado descriptivos.
• /var/lib/xend/domains, cada dominio que creemos disponde de un directorio, identificado con el
ID del dominio. Existe un directorio por cada dominio.
• /var/xen/dump, en este directorio se almacenan, por defecto, los ficheros cores que se crean
cuando los solicitamos con el subcomando dump-core de xm.
Starting install...
Creating storage file... 100% |=========================| 5.0 GB 00:00
Creating domain... 0 B 00:06
Bootdata ok (command line is method=/export/home/root/Desktop/CentOS-5.1-x86_64-bin-DVD.iso)
Linux version 2.6.18-53.el5xen (mockbuild@builder6.centos.org) (gcc version 4.1.2 20070626 (Red Hat 4.1.2-14)) #1 SMP Mon
Nov 12 02:46:57 EST 2007
BIOS-provided physical RAM map:
Xen: 0000000000000000 - 0000000020800000 (usable)
No mptable found.
115
Comunidad OpenSolaris Hispano
Welcome to CentOS
Para el ejemplo utilizaremos la opción de instalar mediante NFS, para ellos utilizaremos como
servidor NFS nuestro dom0 y compartiremos el directorio donde se encuentra la ISO de Centos.
(huelva@dom0)# share /export/home/root/Desktop/
(huelva@dom0)# share
116
Comunidad OpenSolaris Hispano
- /export/home/root/Desktop rw ""
(huelva@dom0)#
El siguiente paso consiste en configurar una IP cuando el instalador de Centos nos lo solicite,
también nos pedirá que le digamos cual es la IP del servidor de NFS y el directorio que dicho servidor está
compartiendo.
Welcome to CentOS
117
Comunidad OpenSolaris Hispano
118
Comunidad OpenSolaris Hispano
La siguiente imagen muestra como podemos exportar el display de nuestra maquina virtual
centos_x64 para trabajar con el entorno KDE, desde una ventana de Xnest
Parando un domU
Para parar un domU, podemos utilizar varios subcomandos del comando xm:
xm destroy, esto es parecido a meter un botonazo al domU.
(huelva@dom0)# xm list
Name ID Mem VCPUs State Time(s)
Domain-0 0 774 2 r----- 389.4
centos_x64 30 720 2 -b---- 39.0
(huelva@dom0)#
(huelva@dom0)# xm destroy centos_x64
(huelva@dom0)# xm list
Name ID Mem VCPUs State Time(s)
Domain-0 0 774 2 r----- 391.7
centos_x64 512 1 0.0
(huelva@dom0)#
Pausando un domU
Tenemos dos formas de suspender la ejecución de un domU y volver a ejecutarla cuando nosotros
deseemos:
• xm pause, provoca una pausa en la ejecución del domU. Para que el dominio vuelva a ejecutarse
utilizaremos el comando xm unpause.
119
Comunidad OpenSolaris Hispano
• xm suspend, en este caso se provoca una suspensión del dominio, se almacena en disco el estado de
ejecución del dominio y se para, de echo podriamos volver a ejecutar el dominio, bien con el
comando xm resume o bien volviendo a arrancarlo con el comando xm start, es este caso
arrancaría como si hubiéramos dado un botonazo al dominio.
(huelva@dom0)# xm list
Name ID Mem VCPUs State Time(s)
Domain-0 0 1479 2 r----- 366.0
centos_x64 8 511 1 -b---- 0.1
solaris_11_x64 750 1 64.8
(huelva@dom0)#
(huelva@dom0)# xm suspend centos_x64
(huelva@dom0)# xm list
Name ID Mem VCPUs State Time(s)
Domain-0 0 1479 2 r----- 374.7
centos_x64 1 1 0.1
solaris_11_x64 750 1 64.8
Como podemos ver en el ejemplo, al suspender un dominio no tiene estado en la columna state.
Puntos de control
Tenemos la posibilidad de almacenar en un fichero, la ejecución de un dominio en un determinado
instante, esto nos permite crear puntos de control, para posteriormente recuperarlos en caso necesario.
(huelva@dom0)# xm save centos_x64 /var/snap/centos_x64.save_01;xm
restore /var/snap/centos_x64.save_01
(huelva@dom0)#
Con la línea anterior hemos creado un fichero con la imagen de la ejecución del dominio
centos_x64 en un momento determinado, justo después hemos utilizado el comando xm restore para
continuar la ejecución. El tiempo que el dominio ha estado parado correspondo con el tiempo que hemos
tardado en almacenar en disco el fichero. Si no ejecutamos el comando xm restore el dominio estará offline.
Borrando un domU
Para borrar un domU, necesitamos que primero esté parado y posteriormente podemos utilizar el
comando xm delete :
(huelva@dom0)# xm list
Name ID Mem VCPUs State Time(s)
Domain-0 0 774 2 r----- 391.7
centos_x64 512 1 0.0
(huelva@dom0)#
(huelva@dom0)# xm delete centos_x64
120
Comunidad OpenSolaris Hispano
(huelva@dom0)# xm list
Name ID Mem VCPUs State Time(s)
Domain-0 0 774 2 r----- 392.6
(huelva@dom0)#
El domU centos_x64 ha sido eliminado, pero el fichero que hemos utilizado como disco root
continua en su directorio original, por lo que podemos utilizarlo para otra prueba. El comando xm delete
solo elimina las configuraciones del domU que utiliza xVM.
121
Comunidad OpenSolaris Hispano
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
processor :1
vendor_id : GenuineIntel
cpu family :6
model : 15
model name : Intel(R) Core(TM)2 Duo CPU E4500 @ 2.20GHz
stepping : 13
cpu MHz : 2194.500
cache size : 2048 KB
physical id :1
siblings :1
core id :0
cpu cores :1
fpu : yes
fpu_exception : yes
cpuid level : 10
wp : yes
flags : fpu tsc msr pae mce cx8 apic mca cmov pat pse36 clflush dts acpi mmx fxsr
sse sse2 ss ht tm syscall nx lm constant_tsc pni monitor ds_cpl est tm2 cx16 xtpr lahf_lm
bogomips : 5489.33
clflush size : 64
cache_alignment : 64
address sizes : 36 bits physical, 48 bits virtual
power management:
[trantor@domU ~]
122
Comunidad OpenSolaris Hispano
[trantor@domU ~] init 6
...
[trantor@domU ~]# cat /proc/meminfo
MemTotal: 737280 kB
MemFree: 462248 kB
Buffers: 12920 kB
Cached: 152432 kB
SwapCached: 0 kB
Active: 70148 kB
Inactive: 144184 kB
HighTotal: 0 kB
HighFree: 0 kB
LowTotal: 737280 kB
LowFree: 462248 kB
SwapTotal: 1081336 kB
SwapFree: 1081336 kB
Dirty: 764 kB
Writeback: 0 kB
AnonPages: 49060 kB
Mapped: 9012 kB
Slab: 18428 kB
PageTables: 2996 kB
NFS_Unstable: 0 kB
Bounce: 0 kB
CommitLimit: 1449976 kB
Committed_AS: 94868 kB
VmallocTotal: 34359738367 kB
VmallocUsed: 1160 kB
VmallocChunk: 34359736511 kB
123
Comunidad OpenSolaris Hispano
124
Comunidad OpenSolaris Hispano
• -s 5, tamaño en GB de disco.
Starting install...
Creating storage file... 100% |=========================| 5.0 GB 00:00
Creating domain... 0 B 00:07
v3.0.4-1-xvm chgset 'Mon Nov 12 23:09:42 2007 -0800 13228:ed897008a4c9'
SunOS Release 5.11 Version snv_78 64-bit
Copyright 1983-2007 Sun Microsystems, Inc. All rights reserved.
Use is subject to license terms.
Configuring /dev
Solaris Interactive Text (Console session)
Using install cd in /dev/dsk/c0d1p0
Using RPC Bootparams for network configuration information.
Attempting to configure interface xnf0...
Skipped interface xnf0
Reading ZFS config: done.
Setting up Java. Please wait...
Y tanto que esperé, de aquí no pasó la instalación, tuve que subir a 750MB la memoria asignada para que la instalación pudiera
continuar.
bash-3.2# virt-install -n solaris_11_x64 -r 750 -f /export/home/xen/Solaris_11/solaris_11_x64.img -s 5
--nographics --paravirt --os-type=solaris -l /export/home/IMAGES/Solaris_11_x86_1.iso
Starting install...
Creating domain... 0 B 00:06
v3.0.4-1-xvm chgset 'Mon Nov 12 23:09:42 2007 -0800 13228:ed897008a4c9'
125
Comunidad OpenSolaris Hispano
Select a Language
1. English
2. French
3. German
4. Italian
5. Japanese
6. Korean
7. Simplified Chinese
8. Spanish
9. Swedish
10. Traditional Chinese
About navigation...
- The mouse cannot be used
- If your keyboard does not have function keys, or they do not
respond, press ESC; the legend at the bottom of the screen
will change to show the ESC keys to use for navigation.
126
Comunidad OpenSolaris Hispano
--------------------------------------------------------------------------------
F2_Continue F6_Help
Specify whether or not this network interface should use DHCP to configure
itself. Choose Yes if DHCP is to be used, or No if the network interface is
to be configured manually.
NOTE: DHCP support will not be enabled, if selected, until after the system
reboots.
--------------------------------------------------------------------------------
Esc-2_Continue Esc-6_Help
Networked: Yes
Use DHCP: No
Host name: mordor
IP address: 192.168.0.190
System part of a subnet: Yes
Netmask: 255.255.255.0
Enable IPv6: No
Default Route: Specify one
Router IP Address: 192.168.0.1
--------------------------------------------------------------------------------
Esc-2_Continue Esc-4_Change Esc-6_Help
On this screen you must specify your default time zone. You can specify a
time zone in three ways: select one of the continents or oceans from the
list, select other - offset from GMT, or other - specify time zone file.
127
Comunidad OpenSolaris Hispano
> To make a selection, use the arrow keys to highlight the option and
press Return to mark it [X].
--------------------------------------------------------------------------------
Esc-2_Continue Esc-6_Help
- Profile ----------------------------------------------------------------------
The information shown below is your profile for installing Solaris software.
It reflects the choices you've made on previous screens.
NOTE: You must change the BIOS because you have changed the default boot
device.
=========================================================================
===
--------------------------------------------------------------------------------
Esc-2_Begin Installation F4_Change F5_Exit F6_Help
128
Comunidad OpenSolaris Hispano
Pausing for 90 seconds at the "Reboot" screen. The wizard will continue to
the next step unless you select "Pause". Enter 'p' to pause. Enter 'c' to
continue. [c]
Unable to run Launcher without Java.
The following CDs will not be installed:
Solaris Software 2 for x86 Platforms
Creating ram disk for /a
updating /a/platform/i86pc/boot_archive...this may take a minute
updating /a/platform/i86pc/amd64/boot_archive...this may take a minute
syncing file systems... done
rebooting...
mordor# df -k
Filesystem kbytes used avail capacity Mounted on
/dev/dsk/c0d0s0 1125599 595232 474088 56% /
/devices 0 0 0 0% /devices
/dev 0 0 0 0% /dev
ctfs 0 0 0 0% /system/contract
129
Comunidad OpenSolaris Hispano
proc 0 0 0 0% /proc
mnttab 0 0 0 0% /etc/mnttab
swap 1073356 376 1072980 1% /etc/svc/volatile
objfs 0 0 0 0% /system/object
sharefs 0 0 0 0% /etc/dfs/sharetab
/usr/lib/libc/libc_hwcap3.so.1
1125599 595232 474088 56% /lib/libc.so.1
fd 0 0 0 0% /dev/fd
swap 1072980 0 1072980 0% /tmp
swap 1072992 12 1072980 1% /var/run
/dev/dsk/c0d0s7 3494494 3489 3456061 1% /export/home
mordor#
130
Comunidad OpenSolaris Hispano
Navegando en el /proc
Todos los sistemas Unix disponen de una serie de ficheros, los cuales mantienen información sobre
los distintos procesos que se están ejecutando en la máquina, Solaris utiliza un pseudo sistemas de ficheros
llamado Procfs, en el cual, el kernel mantiene información sobre los procesos que está corriendo.
El sistema de archivos procfs está organizado en directorios, uno por cada proceso en que se ejecuta
en la máquina, los directorios se llaman con el PID del proceso del cual mantienen la información.
(root@huelva)# cd /proc
(root@huelva)# ls
0 14470 18279 19575 22216 2496 28190 3782 4622 605
1 1464 18340 19604 22610 25190 28252 398 4636 606
10192 1465 18709 19634 22645 25229 285 421 472 6347
10622 14896 18779 2 23054 25479 28610 4210 476 664
11058 15321 18973 20009 23072 25626 28685 439 496 6775
11478 15751 18983 20063 23484 25656 29038 442 5021 678
11906 16187 19031 20450 23505 26047 29039 4428 505 679
1215 1646 19047 20490 23785 26089 29124 445 5061 680
12332 16460 19059 2072 23909 26474 2926 4608 507 7077
127 16611 19064 20881 23945 26528 29464 4609 508 7082
12756 16959 19086 20923 24099 26900 29888 4610 520 7204
13186 17051 19092 21312 24121 26951 3 4611 523 73
13622 17405 19100 21362 24336 27324 326 4613 5491 7628
1372 17480 19105 21744 24369 27382 3362 4614 552 784
14 17849 19141 21785 24764 27754 353 4619 554 789
14042 17907 19202 22178 24800 27811 371 4621 5927 8058
(root@huelva)#
131
Comunidad OpenSolaris Hispano
Cada uno de estos ficheros que representa a un proceso contiene un a serie de ficheros y directorios,
de los cuales podemos obtener información sobre el proceso y todos sus LWP.
(root@huelva)# cd 29039
(root@huelva)# ls -l
total 5933
-rw------- 1 nagios nagios 2998272 Apr 11 12:13 as
-r-------- 1 nagios nagios 152 Apr 11 12:13 auxv
-r-------- 1 nagios nagios 36 Apr 11 12:13 cred
--w------- 1 nagios nagios 0 Apr 11 12:13 ctl
lr-x------ 1 nagios nagios 0 Apr 11 12:13 cwd ->
dr-x------ 2 nagios nagios 8208 Apr 11 12:13 fd
-r--r--r-- 1 nagios nagios 344 Apr 11 12:13 lpsinfo
-r-------- 1 nagios nagios 2720 Apr 11 12:13 lstatus
-r--r--r-- 1 nagios nagios 1064 Apr 11 12:13 lusage
dr-xr-xr-x 5 nagios nagios 80 Apr 11 12:13 lwp
-r-------- 1 nagios nagios 3744 Apr 11 12:13 map
dr-x------ 2 nagios nagios 800 Apr 11 12:13 object
-r-------- 1 nagios nagios 4336 Apr 11 12:13 pagedata
-r--r--r-- 1 nagios nagios 336 Apr 11 12:13 psinfo
-r-------- 1 nagios nagios 3744 Apr 11 12:13 rmap
lr-x------ 1 nagios nagios 0 Apr 11 12:13 root ->
-r-------- 1 nagios nagios 1472 Apr 11 12:13 sigact
-r-------- 1 nagios nagios 1232 Apr 11 12:13 status
-r--r--r-- 1 nagios nagios 256 Apr 11 12:13 usage
-r-------- 1 nagios nagios 0 Apr 11 12:13 watch
-r-------- 1 nagios nagios 5928 Apr 11 12:13 xmap
(root@huelva)#
/proc/< pid >/as
Este fichero contiene una imagen del espacio de direcciones del proceso, podemos abrirlo para
realizar tanto lecturas como escrituras.
/proc/< pid >/auxv
Contiene una array de elementos de tipo auxv_t los cuales son pasados al linkador dinámico en el
momento en el que se arrancó el proceso.
/proc/< pid >/cred
Este fichero contiene la descripción de las credenciales del proceso. Las credenciales del proceso las
define la estructura de datos struct prcred que podemos encontrar el fichero de cabecera sys/procfs.h
/proc/< pid >/ctl
Este fichero es solo de lectura y lo podemos utilizar para enviar mensajes de control al proceso.
/proc/< pid >/cwd
Es un enlace simbólico al directorio actual de trabajo del proceso.
/proc/< pid >/fd/
Este directorio contiene una referencia a cada uno de los descriptores de ficheros que tiene abierto el
proceso.
132
Comunidad OpenSolaris Hispano
133
Comunidad OpenSolaris Hispano
>/map el cual está formando por un array de elementos de tipo struct prmap, este tipo de datos está
definido en el fichero sys/procfs.h, la estructura prmap la forman, entre otros, los siguientes campos:
El siguiente programa acepta como único parámetro el PID de un proceso, para abrir el fichero
/proc/< PID >/map, como sabemos el fichero está formando por un array de elementos de tipo struct
prmap.
Programa proc_lwp_map.c
1 #include < stdio.h >
2 #include < sys/types.h >
3 #include < sys/stat.h >
4 #include < fcntl.h >
5
6 #define _STRUCTURED_PROC 1
7
8 #include < sys/procfs.h >
9
10 main(int argc, char **argv)
11 {
12
13 int fd;
14 char cadena[80];
15 int pid;
16 struct prmap pmap;
17
18 if (argc<2)
19 {printf("Error: Falta el < pid >nn Uso: %s < pid >nn",argv[0]);return;}
20
21 pid=atoi(argv[1]);
22
23 sprintf(cadena,"/proc/%d/map",pid);
24 fd=open(cadena,O_RDWR);
25
26 if (fd<0)
27 {printf("n Error: No se ha podido abrir el fichero %sn",cadena);return(1);}
28
29 printf("nAddrttSizetPSizetFlagstObject");
30 printf("n-------------------------------------------------------n");
137
Comunidad OpenSolaris Hispano
31
32 while((read(fd,&pmap,sizeof(struct prmap)))>0)
33 {
34 printf("n0x%.8lx",pmap.pr_vaddr);
35 printf("t%dK",pmap.pr_size/1024);
36 printf("t%dt",pmap.pr_pagesize);
37
38 if(pmap.pr_mflags & MA_READ)
39 {printf("r");}
40 else
41 {printf("-");}
42
43 if(pmap.pr_mflags & MA_WRITE)
44 {printf("w");}
45 else
46 {printf("-");}
47
48 if(pmap.pr_mflags & MA_EXEC)
49 {printf("x");}
50 else
51 {printf("-");}
52
53 if(pmap.pr_mflags & MA_SHARED)
54 {printf("s");}
55 else
56 {printf("-");}
57
58 if(pmap.pr_mflags & MA_ANON)
59 {printf("A");}
60 else
61 {printf("-");}
62
63 printf("t%s",pmap.pr_mapname);
64 }
65
66 close(fd);
67 printf("n");
68 }
Una vez que compilemos el programa, la salida de su ejecución será algo parecido a esto:
(root@huelva)# ./proc_lwp_map 520
138
Comunidad OpenSolaris Hispano
La salida está compuesta por una serie de líneas, una por cada segmento que formen el espacio de
direcciones del proceso, la primera es la dirección de memoria en la que podemos localizar el segmento, la
última columna presenta el nombre del fichero que se ha mapeado en el segmento, el tamaño de un
segmento no tiene por qué coincidir con el tamaño del fichero que se mapea, ya que puede que el segmento
se mapee un trozo del fichero. El nombre el nombre del objeto está formado con el inodo del fichero que
se está utilizando, podemos buscar el fichero cuyo inodo es 2794.
139
Comunidad OpenSolaris Hispano
ejemplo1.c
Consiste en un programa que dispone de un contador, el cual se irá incrementando cada 5 segundos.
1 #include < stdio.h >
2
3 void main()
4 {
5 int *cont;
6
7 cont=malloc(sizeof(int));
8 *cont=0;
9 printf("n Dir. Memoria de la varable cont: 0x%lx %lun",cont,cont);
10 for(;;)
11 {
12 printf("n Contador: %d",*cont);
13 sleep(5);
14 *cont=*cont+1;
15 }
16
17 return;
18 }
140
Comunidad OpenSolaris Hispano
Contador: 0
Contador: 1
Contador: 2
Contador: 3
Contador: 4
Contador: 5
Contador: 6
Contador: 7
Contador: 8^C
(root@huelva)#
Presenta la dirección de memoria de la variable cont, la cual como podemos ver en la línea 5 de
ejemplo1.c es de tipo puntero a un entero. Cada 5 segundos se incrementará el contenido de la dirección
donde apunta *cont. Podemos dejar corriendo ejemplo1.
proc_as_wr.c
Este programa aceptará como parámetros el PID de un proceso y una dirección de memoria, el PID
lo utilizará para abrir el fichero del espacio de direcciones del proceso y la dirección de memoria, para, en
primer lugar leer su contenido y posteriormente incremetar dicho contenido en 100.
141
Comunidad OpenSolaris Hispano
Una vez que compilemos el programa podemos realizar la prueba de nuestro ejemplo, para ello
ejecutaremos ejemplo1 en un terminal y lo dejaremos ejecutandose, tenemos que recordar la dirección de
memoria del contador.
(root@huelva)# ./ejemplo1
Contador: 0
Contador: 1
Contador: 2
Contador: 3
...
142
Comunidad OpenSolaris Hispano
(root@huelva)#
Hasta ahora hemos visto, la estructura básica del sistema de archivos /proc, la estructura de algunos
de los fichero que lo forman y como podemos acceder al espacio de direcciones de un proceso simplemente
utilizando las llamadas open() y read(), hasta hemos visto como cambiar el valor de una variable de un
proceso. Este artículo nació de la charla que tuvimos algunos compañeros con los que trabajo, sobre la
razón de que una de las aplicaciones con las que trabajamos estaba continuamente realizando llamadas poll()
y necesitabamos conocer cuales son los descriptores de ficheros que están utilizando las distintas llamadas a
poll().
Comando truss
El primer paso consiste en realizar un pequeño estudio sobre el número de llamadas al sistema, su
frecuencia y el tipo, para esta tarea podemos utiliza el comando truss, con la opción -c obtendremos las
estadísticas de las llamadas a sistema.
write .000 12
close .000 1
fcntl .000 1
poll .010 1419
lwp_self .000 8
lwp_mutex_wakeup .000 31
lwp_mutex_lock .000 18
lwp_cond_wait .002 95 61
lwp_cond_signal .000 4
lwp_cond_broadcast .000 30
lwp_schedctl .000 8
accept .000 1
send .001 17
getsockname .000 4
setsockopt .000 1
-------- ------ ----
sys totals: .015 1686 73
usr time: .114
elapsed: 2.480
(root@huelva)#
Con los resultados anteriores no podemos considerar que tengamos un ejemplo, unicamente es un
ejemplo para destacar que el número de llamadas poll() es bastante superior al del resto de llamadas. Ahora
tenemos que averiguar si existen varias llamadas poll() distintas, en distintos procesos o si solo existe un poll,
responsable de todas las llamadas, ejecutaremos el comando truss para que unicamente nos enseñe las
llamadas poll().
(root@huelva)# truss -t poll -f -p 25089
25089/10: poll(0x310FFD58, 3, 50) =0
25089/46: poll(0x00273E50, 3, -1) =1
25089/46: poll(0x00273E50, 4, -1) =1
25089/46: poll(0x27DFEE10, 1, 30000) =1
25089/10: poll(0x310FFD58, 3, 50) =0
25089/46: poll(0x00273E50, 3, -1) =1
25089/46: poll(0x00273E50, 4, -1) =1
25089/46: poll(0x27DFEE10, 1, 5000) =1
...
En la salida del ejemplo podemos observar que la llamada poll() acepta como parámetros, el puntero
a un array de elementos de tipo struct pollfd, el número de elementos del array y un timeout. Como
conocemos la dirección del array de elementos podemos utilizar el fichero /proc/< PID >/as, que
recordemos es el espacio de direcciones del proceso, para leer el contenido del array, para ello utilizaremos el
siguiente programa en C.
proc_as_rd.c
/*
* Este programa lee una dir de memoria y la interpreta
* como dato de tipo "pollfd_t" el cual es una estructura
144
Comunidad OpenSolaris Hispano
int fd;
char s_dir[16];
char cadena[80];
char HEX[]="0123456789ABCDEF";
int pid;
int n,i;
long long addr;
char c;
int nelem;
pollfd_t dato;
if (argc<3)
{printf("nn Uso: %s
0x nn”,argv[0]);return;}
pid=atoi(argv[1]);
nelem=atoi(argv[3]);
145
Comunidad OpenSolaris Hispano
/*
* Se lee la dir de memoria en formato HEX
* y se convierte en una dir de tipo “long long”
*/
if(argv[2][1]==’x')
argv[2][1]=’0′;
else
{printf(”nn Uso: %s
0x “);
printf(”nnLa direccion de memoria tiene que estar en formato hex 0xnn”,argv[0]);return;}
sprintf(s_dir,”%016s”,argv[2]);
addr=0;
for(n=0;n< sizeof(s_dir);n++)
{
i=0;
while((HEX[i]!=toupper(s_dir[n]))&&(i<16))
{i++;}
if (i>15)
{printf(”nError: La direccion contiene caracteres no validosnn”);return;}
addr|=i;
addr=addr<<4;
}
addr=addr>>4;
/*
* La variable addr contiene la dir de memoria
* convertida de HEX -> long long
*/
fd=open(cadena,O_RDONLY);
if (fd<0)
{printf(”n Error: Abriendo el fichero %sn”,cadena);return;}
printf(”n Abriendo el fichero %sn”,cadena);
146
Comunidad OpenSolaris Hispano
for(n=0;n< nelem;n++)
{
if (lseek(fd,addr,SEEK_SET)<0)
{printf(”nError: Moviendo el puntero %sn”,cadena);return;}
if(read(fd,&dato,sizeof(dato))<0)
{printf(”nError: Escribiendo el fichero %sn”,cadena);return;}
printf(”n———————-n”);
addr=addr+(sizeof(pollfd_t));
}
close(fd);
}
El programa abre el fichero /proc/< PID >/as, desplaza el puntero a la dirección 0xaddr_hex y
leen tantas estructuras de tipo pollfd_t como le digamos con el parámetro < iter>. La salida será parecida a
la siguiente, utilizaremos la información de las llamadas poll() que recuperamos con el comando truss,
ejecutaremos proc_as_rd con el proceso 25089 y la dirección de memoria 0×27DFEE10
(root@huelva)# ./proc_as_rd 25089 0x27DFEE10 1
PID: 25089
Dir. de memoria: 0x27dfee10
147
Comunidad OpenSolaris Hispano
poll() utiliza un array, el cual tiene solo un elemento, de elementos de tipo pollfd_t, cuyo campo fd almacena
el descriptor de fichero 77. Podemos ver a qué fichero corresponde el descriptor de fichero 77 en el proceso
25089 mediante el comando pfiles
En este caso, el descriptor de fichero corresponde con un socket, que la aplicación está utilizando,
esta información nos puede ayudar para identificar cual es la causa para que la aplicación esté realizando un
uso excesivo de llamadas poll().
Este artículo pretende enseñar lo sencillo que es trabajar con el fichero del espacio de direcciones del
proceso y como nos puede ayudar a identificar problemas, ya que nos permite consultar la información del
proceso que nos interese.
- Procesos y procesadores
- Entrada/Salida
- Memoria
No solo se tratarán los distintos comandos para medir el rendimiento, sino que se explicaran algunos
de los parámetros que podremos cambiar en nuestro sistema para mejorar el rendimiento, ya sea de
memoria, procesador, entrada/salida, etc. De todas formas es importante conocer como pueden afectar los
148
Comunidad OpenSolaris Hispano
cambios propuestos en cada uno de nuestros sistemas y el objetivo no es dar una serie de axiomas o
parámetro, los cuales deben aplicarse ciegamente, sino el que, como administradores, conozcamos
las posibilidades que tenemos para evitar problemas en el rendimiento.
Rendimiento/Tuning
Procesos y procesadores
Ahora veremos algunas de las herramientas que nos permitan identificar posibles cuellos de botella,
tanto en los procesos que se están ejecutando en el sistema como en las operaciones que estén realizando los
procesadores. Para ellos vamos a comenzar haciendo una aclaración sobre lo que parece, para mucha gente,
un axioma indiscutible sobre el rendimiento de un sistema.“Mucho uso de CPU está directamente relacionado con un
problema de rendimiento”
Aunque muchas veces esto puede ser cierto, existen casos en los que no se cumple y otros casos en
los que una solución al problema, como sería aumentar el número de CPUs del sistema, no conseguiría
aumentar el rendimiento. Por lo tanto no debemos alarmarnos frente a un aumento del uso de CPU,
149
Comunidad OpenSolaris Hispano
tendremos que analizar la causa para intentar dar una solución. Podemos decir, y lo comprobaremos mas
adelante, que “frente a un uso alto de CPU, comprar más procesadores no garantiza que se
solucione el problema.” es importante que tengamos claro este principio, ya que normalmente, cuando
existe un problema de rendimiento, se suele optar por la solución rápida, comprar HW y podemos llevarnos
una desagradable sorpresa, cuando descubrimos que el haber gastado una suma importante de dinero para
conseguir únicamente, el el porcentaje de uso de CPU se ha reducido, pero el rendimiento del sistema es
igual de malo.
El rendimiento de un procesos no se puede medir simplemente con el porcentaje de uso de CPU,
existen una serie de parámetros que nos ayudarán a conocer no solo qué está haciendo el proceso, sino la
causa de un posible problema de degradación en nuestro sistema.
NOTA - No podemos basar nuestro análisis del problema de rendimiento, únicamente en el uso de CPU.
Como hemos comentado, existen otros factores que puede generar un cuello de botella y no tiene
por qué ser el uso de CPU, en sistemas multitareas y multithreads como es Solaris, el que un proceso
decremente su rendimiento se debe principalmente a dos posibles causas:
-Externa, la lentitud en el proceso se produce por un elemento externo al proceso, como puede ser el
acceso a la memoria, lentitud en los dispositivos de E/S, pésima asignación de tiempo de CPU, etc.
-Interna, en los procesos con múltiples threads, normalmente existen una serie de sincronizaciones entre los
distintos threads, estas sincronizaciones, pueden provocar bloqueos entre varios de los threads, produciendo
una pérdida del rendimiento del proceso.
Tendremos que analizar si la causa de que el rendimiento del proceso no es el esperado está en el propio
proceso, que a su vez está afectando al rendimiento del resto de procesos del sistema o por el contrario, la
razón de la pérdida de rendimiento se debe un causa externa al proceso.
Nuestro análisis debe comenzar desde un punto de vista global, hasta desembocar en un foco concreto, no
es buena idea centrarnos, a priori, en un elemento particular, ya que esto, nos podría evitar ver la causa del
problema en otro elemento que no esté relacionado con el que nosotros pensamos que es la causa de todo el
problema.
Como podemos comprobar, el comando prstat nos permite disponer de una primera visión de qué
se está ejecutando en nuestros sistema. En el ejemplo, lo primero que nos llama la atención es el proceso con
PID 23288, es un proceso java con 129 threads, a priori y sin ningún diagnóstico previo, podemos pensar
que la causa del problema es este proceso, pero no podemos parar aquí nuestro análisis, ya que puede que la
causa de lentitud del sistema no se deba solo a este proceso y sea un elemento ajeno a él la razón de la
lentitud.
Lo que si nos debe llamar la atención, es el crecimiento que se está produciendo en la carga media del
sistema load averages: 4.61, 4.30, 3.71, que podemos ver que está creciendo.
mpstat
Como segundo paso vamos a ver qué está ocurriendo con los procesadores del sistema, es decir, en qué
están empleando su tiempo, esto nos ayudará a que nos aproximemos al diagnostico. Para ver qué están
haciendo los procesadores de nuestro sistema utilizaremos el comando mpstat. La salida del comando
muestra una fila por cada uno de los procesadores presentes en el sistema y una serie de columnas con
estadísticas sobre distintos elementos, cada una de las columnas vienen explicadas en la documentación del
man, por lo tanto no vamos a perder tiempo explicándolas y solo vamos a ver las que pueden ser más
intersante para nosotros en estos momentos.
# mpstat 1
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 737 0 172 229 3 2429 143 500 72 0 3903 40 10 0 50
1 627 0 185 235 7 2461 152 519 95 0 4429 42 12 0 46
2 342 0 414 222 4 2872 140 608 109 0 3818 23 8 0 69
3 492 0 691 2252 2139 2258 52 447 191 1 3815 31 9 0 60
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 1046 0 556 234 2 2494 155 504 95 0 10747 44 11 0 46
1 844 0 882 225 7 2327 162 556 114 0 10418 43 15 0 43
2 619 0 842 236 3 3055 164 693 126 0 4954 32 9 0 59
3 816 0 913 2053 1933 1795 96 449 203 0 10199 54 11 0 35
CPU minf mjf xcal intr ithr csw icsw migr smtx srw syscl usr sys wt idl
0 795 0 255 361 3 3249 290 772 81 0 5503 60 6 0 34
1 868 0 556 353 11 2789 307 745 72 0 5091 54 20 0 26
2 654 0 1049 358 2 3131 320 847 95 0 5175 55 14 0 31
3 1161 0 1187 2673 2543 2319 203 646 210 0 5291 59 20 0 21
De todas las columnas vamos a centrar nuestro análisis únicamente en las siguientes:
minf, fallos menores de memoria, estos fallos afectan a los accesos a memoria y se tratan de fallos de cache,
por lo tanto no afectan, de forma directa, al rendimiento del sistema. Este tipo de fallos nos pueden servir de
151
Comunidad OpenSolaris Hispano
indicativo sobre el comportamiento de la aplicación. Los fallos de memoria se deben analizar dentro del
contexto de uso de memoria.
xcall, refleja el número de cross-call de cada procesador. Las cross-call son llamadas que realiza un
procesador a otro, a modo de interrupciones, para indicarle que debe realizar alguna operación. Las cross-
call las suelen utilizar los procesadores para informar de cambios en las caches de la MMU. Un número
elevado de cross-call
puede indicarnos un problema de rendimiento en las caches, de todas formas, el que se produzacan muchas
llamadas de este tipo provocará que los procesadores consuman mucho tiempo atendiendo dichas
interrupciones y por lo tanto afecten al rendimiento.
csw y icsw, cambio de contexto voluntario y cambio de contexto involuntario. El número de cambios de
contexto dependerá, principalmente del número de procesos que se estén ejecutando en el sistema,
recordemos que un cambio de contexto consiste en el proceso por el cual el kernel detiene un proceso que se
está ejecutando en un procesador, elije otro proceso de la cola de ejecución, actualiza los registros del
procesador con la información del nuevo proceso y el procesador continua ejecutando el nuevo proceso en
el punto donde fue parado previamente por otro cambio de contexto.
Cuando el Kernel tiene que elegir un proceso para sacarlo de un procesador, tiene 2 opciones, elegir
uno que esté esperando un dato de E/S, por ejemplo leyendo de disco, a esto se le llama un cambio de contexto
voluntario, es el proceso el que anuncia que no está haciendo nada en ese instante o elegir uno de los que no
están esperando E/S, esto se conoce como cambio de contexto involuntario. Si el valor de icsw se bastante
superior a csw, podemos decir, que el Kernel está sacando de los procesadores a procesos que están
ejecutando código que no está en un estado de espera, sino que está ejecutando código y que es el propio
kernel el que está ralentizando la ejecución de esos procesos en concreto.
Por otra parte no debemos entender esto como un problema del Kernel, sino más bien, un problema
con el número de procesos que se están ejecutando, debería intentar reducir el factor procesos/CPU, bien
bajando el número de procesos, bien aumentando el número de CPUs.
smtx, presenta el número de veces que se ha intentado acceder a un mutex y no se ha conseguido en el
primer intento. Podemos considerar que existe un problema de contención con los mutex, si el valor de
smtx es superior a 300 intentos por CPU y el valor de sys > usr, esto significaría que el Kernel está
consumiendo CPU intentando acceder a una serie de mutex sin conseguirlo.
srw, presenta el número de veces que se ha intentado acceder a un lock de tipo lectura/escritura y no se ha
conseguido en el primer intento.
syscl, número de llamadas ejecutadas por cada CPU.
kstat
Este comando nos permite visualizar una serie de datos estadísticos del Kernel. Mediante kstat podemos
obtener la misma información que obtendremos con los comandos mpstat, vmstat, etc. Los valores que
devuelve el comando kstat son contadores, por lo tanto, tendremos que ser nosotros los que calculemos los
valores realizando una sencilla resta. Las estadísticas del Kernel están organizadas de la siguiente forma
módulo:instancia:nombre:estadistica
si ejecutamos el comando kstat tal cual, la salida será parecida a la siguiente.
(root@huelva)# kstat
...
module: cpu_info instance: 0
name: cpu_info0 class: misc
chip_id 0
clock_MHz 1062
cpu_type sparcv9
crtime 147.6276642
152
Comunidad OpenSolaris Hispano
device_ID 209202519330
fpu_type sparcv9
implementation UltraSPARC-IIIi
snaptime 25738067.4963142
state on-line
state_begin 1154200415
De toda la información que podemos obtener con kstat, nos interesa la que se almacena en el
módulo unix:*:sysinfo, es algo parecido a la siguiente salida:
(root@huelva)# kstat -p unix:*:sysinfo
unix:0:sysinfo:class misc
unix:0:sysinfo:crtime 85.4492862
unix:0:sysinfo:runocc 1600644
unix:0:sysinfo:runque 15857131
unix:0:sysinfo:snaptime 25738291.5173894
unix:0:sysinfo:swpocc 0
unix:0:sysinfo:swpque 0
unix:0:sysinfo:updates 25737884
unix:0:sysinfo:waiting 346454
#
Donde las estadisticas almacenan los siguientes datos.
Estadística Descripción
runque Procesos en la cola de ejecución
swpquea Procesos en la SWAP
waiting Procesos esperando E/S
Estos 3 datos, también los podemos obtener del comando vmstat pero esto lo veremos más
adelante. De la información obtenida, debemos tener en cuenta que, el número de procesos en la cola de
ejecución no debe ser alto, ya que un número alto de procesos en esta cola, significa que hay procesos
esperando para que se les asigne un procesador, podemos considerar como número alto el que en la cola
haya más de 5 procesos por cada CPU del sistema.
Un número elevado de procesos en swap nos avisará de un posible problema con la memoria del
sistema, ya que el Kernel ha tenido que pasar algunos procesos al área de swap, previsiblemente por falta de
espacio en la memoria del sistema. Y un número elevado de procesos en waiting nos indicará un problema
de accesos en la E/S a algún dispositivo.
153
Comunidad OpenSolaris Hispano
truss
Hasta la aparición en escena de Dtrace con OpenSolaris, el comando truss ha sido herramienta
esencial para la identificación de problemas en el rendimiento del sistema. Con el comando truss podremos
ver, las llamadas a sistema que esté realizando un proceso en ejecución, los valores de los distintos
parámetros de las llamadas, los valores devueltos, los errores devueltos por las llamadas, etc. Cuando
tenemos un problema en el rendimiento del sistema, verificar si los procesos, que pensamos son la causa de
la degradación, están haciendo lo que creemos que deben estar haciendo, es una tarea importante, ya que
mucha gente (yo diría demasiada), cuando crean software no se preocupan de gestionar los errores que o
bien puede generar la aplicación, o bien la aplicación se encuentra, como por ejemplo el intentar acceder a
un fichero que no existe, el enviar datos utilizando un socket que se ha cerrado, etc. Estos errores
frecuentemente está directamente relacionadas con la caida del rendimiento en las aplicaciones.
truss nos puede ayudar a localizar todos los errores o causas de la pérdida del rendimiento. Por
ejemplo, nos puede ayudar a descubrir posible contención en el acceso a un fichero o los fallos generados al
intentar acceder a un mutex. Las posibilidades de truss van mucho más allá de lo que podemos ver en este
sencillo artículo, de todas formas, para que nos sirva como ejemplo y sin entrar en excesivos detalles, vamos
a utilizar el comando truss con el el parámetro -c, para que nos muestre una serie de estadísticas sobre las
distintas llamadas a sistema que está ejecutando un proceso.
(root@huelva)# truss -c -p 14178
^Csyscall seconds calls errors
read .119 5252 36
write .002 41
close .000 19
fcntl .003 19
poll .016 310
lwp_mutex_wakeup .001 7034
lwp_mutex_lock .002 6128
lwp_cond_wait .002 5327 26
lwp_cond_signal .000 121
lwp_cond_broadcast .000 300
accept .006 19
send .119 2689
setsockopt .003 38
-------- ------ ----
sys totals: .278 8617 62
usr time: 1.337
elapsed: 11.940
(root@huelva)#
Para poder interpretar los datos que devuelve truss, debemos conocer algunas de las llamadas a
sistema, todas las llamadas a sistema están documentadas perfectamente en el man del sistema. Con la salida
obtenida del ejemplo anterior, podemos decir, que quizás exista un problema de acceso a un mutex por
parte de algunos LWP (Lightweight process) del proceso. Que un proceso tenga una gran cantidad de
operaciones sobre un mutex puede significar, dependiendo de si dichas operaciones son todas sobre un
mismo mutex o sobre varios, que los LWP del proceso están luchando por obtener acceso al mutex y por lo
tanto, que existe un recurso compartido que está provocando una reducción del rendimiento de la
aplicación.
154
Comunidad OpenSolaris Hispano
La columna de errores nos puede dar una pista de la causa de la pérdida de rendimiento, por ejemplo
que se deba a un número excesivos de intentos de acceso a un elemento que no existe o de una forma que
no es la correcta, en el siguiente ejemplo, tenemos la salida del comando truss, la cual nos muestra un
posible problema con las llamadas read.
lockstat
En el man de este comando podemos leer que nos facilita información sobre los candados (locks) en
el kernel. Antes de continuar debemos hacer una aclaración sobre uno de los tipos de objetos que se utilizan
para la sincronización entre threads en Solaris, los mutex. Un mutex es un objeto de exclusión mutua, que
solo permite que un thread acceda al recurso controlado por dicho mutex, por lo tanto una de las causas que
pueden producir una reducción en el rendimiento de nuestro sistema, es que varios threads intenten hacerse
a un mismo mutex. Con lockstat podemos identificar qué está intentando bloquear un mutex.
En Solaris encontramos dos tipos de candados, los spin locks y los block locks. Los candados de
tipo spin son aquellos en los que los threads no dejan de intentar acceder a él, independientemente de que el
candado esté bloqueado o no, este tipo de candado se implementa cuando queremos que los threads estén
continuamente ejecutándose intentando acceder al candado y sin perder tiempo en esperar algún timeout.
Sencillamente el thread más rápido en solicitar el candado, justo después de que el candado se ha liberado,
será el afortunado. Los candados de tipo block no utilizan un método tan agresivo como los spin, sino que
los threads que intentan acceder a un candado de tipo block que esté bloqueado, sencillamente se bloquean
a la espera de que el candado vuelva a ser liberado, estos candado son más lentos con respecto a los
anteriores, ya que los procesos deben ser avisados de que el candado se ha liberado. Los candados de tipo
block se suelen utilizar para acceder a recursos de E/S.
Por lo tanto en Solaris podemos encontrar candados de tipo spin o mutex spin y candados de tipo
block o mutex block, además de estos dos tipos existe un tercer tipo de candado, el cual será de tipo spin o
de tipo block, dependiendo del estado en el que esté el thread que lo tiene bloqueado, este tipo de candado
se conoce con el nombre de adaptative lock. Si el thread que tiene bloqueado el candado al que queremos
acceder está corriendo, todos los threads que están intentando acceder a dicho candado se comportarán
155
Comunidad OpenSolaris Hispano
como si fuese un spin lock, si por el contrario, el thread que está utilizando el candado, está en un estado
bloqueado, por ejemplo, porque esté esperado datos de E/S, todos los threads que estén intentando acceder
al cando, se comportarán como si el candado fuese de tipo block locks.
Una vez que tenemos claro los distintos tipos de candados que nos podemos encontrar, vamos a
continuar con el comando lockstat para ver algunas de las posibilidades que nos ofrece. Ejecutamos
lockstat y le pasamos como parámetro -b para que devuelva una salida básica y el comando sleep 1 para
que no devuelva la información de los candados durante la ejecución del comando sleep. La salida devuelta
será parecida a la siguiente:
(root@huelva)# lockstat -b sleep 1
156
Comunidad OpenSolaris Hispano
-------------------------------------------------------------------------------
Podemos ver en la salida anterior, que hay una sección por cada tipo de candado al que se intenta
acceder, por lo tanto, podemos obtener el número de peticiones a candados de tipo Spin lock spin, en
nuestro ejemplo, se producen 246 eventos en 1 segundo. De la salida podemos destacar las siguiente
columnas, Count con el número de intentos para acceder a un candado, Lock con los nombres del los
candados
157
Comunidad OpenSolaris Hispano
y Caller con las direcciones de los objetos que han intentado el acceso al candado. Estas 3 columnas nos
pueden ayudar a identificar un posible problema de contención en algún candado y si este problema de
accesoa un candado está produciendo una degradación del rendimiento de nuestro sistema.
Tener un número alto de intentos sobre candados de estos dos tipos, puede provocar que la cantidad
de tiempo asignada
al sistema SYS aumente, obligando al sistema a reducir la cantidad de tiempo que se asigna al usuario y por
lotanto, se producirá una pérdida de rendimiento es todos los procesos de usuario, al recibir menos tiempo
de CPU por partedel Kernel.
cpustat y cputrack
Los procesadores SPARC disponen de una serie de contadores, lo cuales podemos consultar para medir el
rendimiento de ciertas operaciones a nivel de los procesadores. Estos contadores nos permitirán descubrir
posibles cuellos de botellas en los procesadores, bien por el número de instrucciones que se estén
ejecutando, bien por el nivel de aciertos en las distintas caches.
La información almacenada en los contadores, dependerá del tipo de procesador que tenga nuestro sistema,
por lo tanto,antes de utilizar este comando, debemos comprobar cuales son los contadores disponibles, para
ello solo tendremos que ejecutar cpustat con el parámetro -h.
(root@huelva)# cpustat -h
Usage:
cpustat [-c events] [-nhD] [interval [count]]
events pic0=,pic1=[,sys][,nouser]
158
Comunidad OpenSolaris Hispano
(root@huelva)#
La utilización del comando es bastante sencilla, acepta un evento en cada contador, solo le tenemos
que decir qué eventos queremos monitorizar, el intervalo en segundos y el número de repeticiones. Vamos a
ejecutar el comando cpustat, cada segundo, 5 veces, para que nos devuelva el contador Cycle_cnt, el cual
almacena el número de ciclos de CPU y Instr_cnt que nos dice cuantas instrucciones se han ejecutando, el
comando devuelve una línea por cada CPU.
(root@huelva)# cpustat -c pic0=Cycle_cnt,pic1=Instr_cnt 1 5
time cpu event pic0 pic1
1.006 1 tick 5253507 2214596
1.006 0 tick 5906614 1840943
2.006 1 tick 751843 173146
2.006 0 tick 694595 118216
3.006 1 tick 557997 194365
3.006 0 tick 1166984 271610
4.006 1 tick 5253396 2321969
4.006 0 tick 4473184 1284188
5.006 1 tick 781913 223580
5.006 0 tick 474001 70561
5.006 2 total 25314034 8713174
(root@huelva)#
Como ya hemos comentado, los contadores que se pueden monitorizar con el comando cpustat
dependen del tipo de procesador que tenga nuestro sistema, por lo tanto, tendremos que recurrir a la
159
Comunidad OpenSolaris Hispano
documentación especifica de cada procesador. En nuestro ejemplo, el procesador que está utilizando la
máquina es un UltraSPARC-IIIi y algunos de los contadores son los siguientes:
Contador Descripción
Cycle_cnt Contador de cilclos
Instr_cnt Instrucciones ejecutadas
IC_miss Fallos en la cache de instrucciones
DC_rd_miss Fallos de lectura en la cache
DC_rw_miss Fallos de escritura en la cache
ITLB_miss Fallos de instrucciones en la TLB
DTLB_miss Fallos de datos en la TLB
EC_misses Fallos en la cache externa
La mayoría de los contadores, los veremos más adelante, cuando hablemos de la memoria, ya que los
más relevantes hacen referencia a estadísticas sobre elementos como las caches.
El comando cputrack tiene la misma finalidad que cpustat, pero con la diferencia que podemos
analizar los distintos eventos referidos únicamente a un proceso, ya sea en ejecución o que lo lancemos con
el propio comando cputrack.
160
Comunidad OpenSolaris Hispano
Introducción a DTrace
Hace tiempo que estoy detrás de intentar escribir una pequeña entrada en el blog sobre DTrace,
pienso que ha sido una de las herramientas más interesante que han aparecido para el estudio del
rendimiento de los sistemas y no solo para eso, tambien puede ayudar a todos aquellos que deseen
profundizar en la compresión de cómo funciona el Kernel de Solaris. Creo que cualquier persona que bien
vaya a desarrollar, bien administre sistemas Solaris, debería conocer DTrace, sino en profundidad, al menos
conocer las posibilidades que nos ofrece. En este artículo veremos una breve introducción a DTrace, de
todas formas es imprescindible, para todos aquellos que deseen profundizar más, la lectura de Solaris
Dynamic Tracing Guide.
¿Qué es DTrace?
Es una herramienta de instrumentación desarrollada por Sun en el 2005 y disponible en Solaris 10.
No consiste en una simple herramienta de consulta de estadísticas, al estilo kstat, donde todos los datos son
generados y posteriormente recogidos. DTrace explota el concepto de Instumentación, tal y como se
conoce en el mundo de la Ingeniería.
Instrumentación industrial: es el grupo de elementos que sirven para medir, convertir, transmitir, controlar o
registrar variables de un proceso con el fin de optimizar los recursos utilizados en éste. (http://es.wikipedia.org)
DTrace está formado por una serie de elementos, el uso de los cuales nos permiten medir, controlar,
registrar, etc. variables del sistema. Cuando utilicemos DTrace debes pensar (la misma nomenclatura de
DTrace nos lleva a ello) que estamos poniendo sondas en el sistema que están recogiendo datos para
nosotros.
Está orientada tanto para desarrolladores, a los cuales puede ayudar en las distintas fases de
desarrollo, midiendo variables del sistema, de la misma forma que ocurriría en un sistema en producción.
También es una herramienta fundamental para los administradores, DTrace va mucho más allá del
imprescindible truss, ahora un administrador con unos conocimientos básicos de DTrace puede, por
161
Comunidad OpenSolaris Hispano
ejemplo, conocer cuanto tiempo tardan las escrituras en disco de un proceso determinado o la veces que se
llama a una syscall determinada.
Lo mejor de DTrace es que podemos realizar todas estas tareas en sistemas en producción, sin coste
alguno para el rendimiento del sistemas, ya que es una herramienta no intrusiva.
Arquitectura de DTrace
En la figura anterior podemos ver un esquema de la arquitectura de DTrace, básicamente está formada por:
• Consumers, son todos aquellos elementos que de una forma u otra utilizan DTrace, en este punto
debemos aclarar que DTrace es el sistema de instrumentación y que existe un comando
<b>dtrace(1M)</b> que es uno de los <b>consumers</b> de DTrace, pero no el único.
• Providers, son todos aquellos elementos que pueden generar información sobre el sistema,
normalmente consiste en un módulo del Kernel.
• Probe, es la sonda que definimos para poder extraer información del sistema.
• Programas en D, son programas desarrollados en lenguaje D, los cuales serán compilados por el
comando dtrace(1M) y pasados al Kernel para extraer la información que deseemos. Estos
programas definen las sondas y su comportamiento.
Lenguaje D
Es una mezcla de C y awk, la característica mas notable es que este lenguaje no dispone de
instrucciones para el control de fujo, no tenemos ni if … then, ni while, for, etc.
Los programas son compilados con el comando dtrace(1M), de una forma parecida a como se hace
en Java, una vez probado que no contiene errores es enviado a Kernel para que lo ejecute DTrace.
La estructura básica de un programa en D es:
Descripción de la sonda
162
Comunidad OpenSolaris Hispano
/ predicado /
{
Acciones;
}
Descripción de la sonda
La descripción de la sonda, está formada por una o más cadenas de la forma:
provider:module:funcition:name
Predicado
La única forma de controlar el flujo de un programa en D es mediante los predicados.
Son expresiones encerradas en / / y que se evaluan como verdaderas o falsas.
Ejemplo:
/ pid == 78 / El PID es igual a 78
/ execname == "bash"/ El nombre del programa sea bash
/ x <= 1 / El valor de la variable x sea menor o igual a 1
Acciones
La lógica de la sonda que estamos definiendo, se describe mediante una serie de acciones, las cuales
estarán encerradas entre {}. Estas acciones nos permitiran medir, imprimir, contar, modificar, los datos que
la sonda obtenga.
Disponemos de una serie de funciones, que podemos utilizar para definir el comportamiento de nuestra
sonda. Alguna de las cuales son:
• trace, toma una exprecion y la pasa directamente al buffer.
• printf, nos permite formatear una salida.
• stack, almacena el stack.
• stop, para el proceso.
• system, ejecuta un programa.
• panic, genera un kernel panic.
• exit, termina la ejecución de la sonda.
NOTA - Debemos leer la guía de DTrace antes de utilizar las funciones disponibles, ya que algunas de estas funciones son
destructivas y podrían generarnos algunos problemas.
Existen una serie de variables definidas, la cual contienen cierta información, como el nombre del
ejecutable, el pid, el tiempo desde el arranque del sistemas:
Ejemplo 1
Este primer ejemplo muestra el sencillo “Hola mundo” en lenguaje D.
dtrace:::BEGIN{
trace(“Hola mundo”);
}
dtrace:::END
{
trace(“Adios!!”);
}
Ejemplo 2
Este ejemplo muestra una versión en lenguaje D del comando truss.
syscall:::entry/ pid == $1 /
{
printf("%s (%d, 0x%x, %4d)n",probefunc,arg0,arg1,arg2);
}
Ejemplo 3
En este ejemplo vamos a crear un programa en D que nos devuelva el tiempo que se ha tardado en ejecutar cada syscall, para
obtener el tiempo utilizaremos la variable timestamp, la cual da los nanosegundos desde que se inicio el sistema.
syscall:::entry
/ pid == $1 /
{
array_sc[probefunc] = timestamp;
}
syscall:::return
/ pid == $1 /
{
printf("time %d t %s (%d, 0x%x, %4d) n",timestamp-array_sc[probefunc], probefunc, arg0, arg1, arg2);
}
Agregaciones
El lenguaje D, dispone de una serie de funciones de agregación, que nos ayudarán a analizar los datos
obtenidos tras el lanzamiento de una sonda.
165
Comunidad OpenSolaris Hispano
Ejemplo 4
En este ejemplo hemos construido un programa en D, el cual cuenta con 3 probes:
• El primer probe almacena en el array @array_sc_count la veces que se inicia cualquier syscall del
proceso pid == $1, también se almacena en array_sc[probefunc] el timestamp de la entrada en la
llamada.
• El tercer probe, solo aplica a la salida de la llamada read, cuyo pid == $1, almacena en el array
@array_time_q[probefunc] el valor de la función de agregación quantize(timestamp-
array_sc[probefunc]).
syscall:::entry
/ pid == $1 /
{
@array_sc_count[probefunc] = count();
array_sc[probefunc] = timestamp;
}
syscall::read:entry
/ pid == $1 /
{
@array_time_lq[probefunc]=lquantize(arg0,0,100,1);
}
syscall::read:return
/ pid == $1 /
{
@array_time_q[probefunc]=quantize(timestamp-array_sc[probefunc]);
}
read
value ------------- Distribution ------------- count
11 | 0
12 | 2
166
Comunidad OpenSolaris Hispano
13 |@@@@ 37
14 | 0
41 |@@@@@@@@ 74
42 | 0
43 |@@@@@@@@@@@@@@@@@@@@@@@@@@@ 252
44 | 0
read
value ------------- Distribution ------------- count
512 | 0
1024 |@@ 19
2048 |@@@@@@@@@@@@@@@@@@@@@@@@@@ 241
4096 |@@@@@@@@@ 86
8192 |@@ 23
16384 | 1
32768 | 0
dtrace(1M)
Es el comando que nos permite compilar nuestros programas en D. Dispone de una serie
deparámetros entre los que podemos destacar:
o -l listado de todos los probes disponibles.
o -s compila un programa en D.
o -P lista los probes de un provider específico.
167
Comunidad OpenSolaris Hispano
Providers
Las sondas (probes) son generadas por unos módulos del kernel que se denominan providers. Con el
comando dtrace(1M) podemos ver la lista de providers que tiene nuestro sistema, de esta lista podemos
destacar:
o fbt (Function Boundary Tracing) nos permiten tracear la mayoría de las funciones del
Kernel. Con el comando dtrace -l -P fbt podemos ver la lista de los probes disponibles.
o lockstat, con este provider podemos tracear posibles problemas de contención en locks.
o mib, nos da acceso a los contadores MIBs de Solaris.
Una de las cosas que hace interesante a Dtrace es que podemos crear nuestros propios providers,
para que generen probes en cualquiera de nuestras aplicaciones.
o Es una herramienta muy potente para las fases de desarrollo de SW, ya que permite de forma
sencilla hacer un análisis del rendimiento de la aplicación.
o El nuevo provider no generará nada mientras no se cree un probe que lo consulte, por lo que
las aplicaciones no reducirán su rendimiento.
o Para los administradores, es una forma sencilla de controlar el estado y rendimiento de las
aplicaciones, sobre todo de aquellas de las que dispongamos el fuente.
Un ejemplo:
En cualquier SMTP de código abierto, podríamos modificar el fuente, para que nos devuelva información de cuanto tarda en
procesar un mensaje o el tiempo medio que se utiliza para almacenar un mensaje en disco.
Vamos a ver como en 4 sencillos pasos podemos, crear nuestro propio provider, definir una serie de
probes y hacer que cualquiera de nuestras aplicaciones (siempre que tengamos el código fuente) puedan
utilizar DTrace.
Creamos un fichero en el cual definimos el nuevo provider y los probes que tendrá, para nuestro
ejemplo, creamos el fichero myprovider.d y definimos el provider myprovider.
bash-3.2# cat myprovider.d
provider myprovider
168
Comunidad OpenSolaris Hispano
{
probe op_entry(string);
probe op_return();
};
Nuestro provider tendrá dos probes:
o op_entry, el cual acepta una parámetro como entrada.
Modificamos nuestra aplicación para que utilice los probes de nuestro provider.
main()
{
int sp;
for(;;)
{
DTRACE_PROBE1(myprovider,op_entry,"Entrada en op");
sp=rand()%5;
printf("Inicio Op: sleep (%d) n",sp);
sleep(sp);
printf("Fin Opn");
DTRACE_PROBE(myprovider,op_return);
}
}
169
Comunidad OpenSolaris Hispano
Fin Op
Inicio Op: sleep (4)
Fin Op
Inicio Op: sleep (3)
Fin Op
Inicio Op: sleep (2)
Creamos un script en D para poder chequear los nuevos probes en nuestra aplicación.
bash-3.2# cat app1_probe.d
myprovider$1:::op_entry
{
ts = timestamp;
}
myprovider$1:::op_return
{
printf("n probename: %s t time: %d ns",probename, (timestamp - ts));
}
bash-3.2#
En la siguiente imagen podemos ver un ejemplo de la salida del programa que acabamos de crear
app1 y la ejecución del programa app1_probe.d que hemos lanzado con el comando dtrace(1M).
170
Comunidad OpenSolaris Hispano
¿Qué es DTrace?
171
Comunidad OpenSolaris Hispano
mecanismos tradicionales. Nos ofrece una vista comprensible del comportamiento del sistema operativo y
de las aplicaciones que se ejecutan sobre él. Con funciones similares a las de truss, apptrace, prex y mdb,
DTrace integra en una única y poderosa herramienta de instrumentación que examina la actividad de usuario
y del kernel de Solaris.
Está considerada actualmente como la única herramienta disponible que es lo suficientemente segura
para utilizar en sistemas de producción, además con un insignificante impacto en el rendimiento (0% cuando
no se emplea).
Primero necesitas ser root ó tener algún privilegio DTrace para poder emplear la herramienta.
• Los administradores de sistemas pueden utilizar DTrace para entender el comportamiento del
sistema operativo y de las aplicaciones.
• Los programadores de aplicaciones puede utilizar DTrace para recoger tiempos y argumentar detalles
de las funciones que ellos escriben, tanto en entornos de desarrollo como en sistemas en producción.
• Los ingenieros del kernel y drivers pueden emplear DTrace para depurar un kernel ya cargado en
memoria así como todos sus módulos sin necesidad de ejecutar drivers en modo depuración
(DEBUG).
¿Es necesario tener conocimientos internos del kernel para emplear DTrace?
Cualquiera puede emplear DTrace desde el principio utilizando la documentación de los scripts ya
escritos de DTraceToolkit ó los scripts de una única línea documentados en Solaris Performance and Tools.
Al principio no necesitarán escribir sus propios scripts, pero a medida que vayan surgiendo necesidades, los
usuarios encontrarán que escribir sus propios scripts puede probar una mayor eficacia a la hora de resolver
problemas en sus entornos.
172
Comunidad OpenSolaris Hispano
No es necesario tener conocimientos del kernel para estudiar el código a nivel de usuario. Los
desarrolladores de aplicaciones pueden estudiar las funciones que ellos mismos escriben y seguro que
además les resultan familiares.
Existen muchos providers de alto nivel que pueden ser diseñados a medida para proveernos de una
documentada abstracción del kernel (Ver la Guía DTrace, ej: proc, io, sched, sysinfo, vminfo), que hacen
tracing al kernel mucho mejor y más fácilmente de lo que se pueda creer inicialmente.
Comprender el kernel de Solaris es necesario para escribir scripts DTrace avanzados para los que de
momento no existe un provider de alto nivel. Por ejemplo para examinar la actividad TCP/IP en detalle.
Para ésta cuestión se recomienda leer el libro Solaris Internals 2nd Edition.
Si no estás seguro de los privilegios que tienes actualmente, ejecutando el comando 'ppriv $$' ,
obtendrás los privilegios que tu shell te ha proporcionado.
¿No se había inventado ya algo similar hace 20 años para los mainframes?
• “The DTrace Guide” es la mejor referencia para DTrace que cubre el lenguaje, providers y
montones de ejemplos más. Fue escrito por los ingenieros de DTrace y es una referencia obligada. El
libro entero está online gratuitamente y también se puede bajar en formato PDF.
• “Solaris Performance and Tools” demuestra el uso de DTrace para la observación y el depurado del
rendimiento. Fué escrito por Brendan Gregg (autor del DTraceToolkit), Richard McDougall y Jim
Mauro (autor de “Solaris Internals”) .
173
Comunidad OpenSolaris Hispano
Existen de momento unos cuantos casos de éxito documentados en la red. Realmente muchos de los
ingenieros, consultores, NDAs etc. suelen utilizan habitualmente DTrace, pero lamentablemente no pueden
mostrar al mundo los detalles de pruebas y monitorización de sus clientes.
De momento, podemos revisar la documentación de Jarod Jenson, el consultor con más experiencia
del mundo en DTrace. Jarod ha sido entrevistado por las revistas SysAdmin Magazine y ACM; en dichas
entrevistas podemos ver algunos casos de éxito reales empleando DTrace.
El lenguaje de programación D está basado en el lenguaje C, así que algún conocimiento inicial de
éste lenguaje puede ayudar a su entendimiento. D es bastante más fácil que C ya que sólo hay que aprender
un pequeño número de funciones y tipo de variables para ser capaz de escribir poderosos scripts. Además
los programas en D también son similares a los programas escritos en awk, lo cual puede resultar de ayuda.
El comando dtrace(1M) utiliza una librería llamada libdtrace como punto de entrada de varios
“providers” dentro del kernel de Solaris, cada uno de ellos nos ofrece una vista lógica de algunos
subsistemas del kernel. El binario dtrace puede ser utilizado tanto desde línea de comandos como desde shell
a través del lenguaje D.
Cuando se ejecutan, los programas escritos en D son compilados “al vuelo” en bytecodes que
pueden ser interpretados dentro del kernel.. La máquina virtual de DTrace ejecuta los bytecodes para
garantizar que sean seguros. Si el código es seguro y tenemos los suficientes privilegios, el código se parchea
dentro delkernel dinámicamente y es ejecutado como código de kernel. Éste es el por qué los probes que no
están activos no pueden crear ninguna sobrecarga.
Una “probe” es un punto de instrumentación que puede ser seguido (tracing) por DTrace. Por ejemplo,
llamamos el probe "syscall:read:entry" cuando invocamos la llamada del sistema (syscall) read(2) y se llama a
"syscall::read::return" cuando se completa la syscall read(2).
leonidas ~ # dtrace -l | wc -l
48722
174
Comunidad OpenSolaris Hispano
.El “provider” ó proveedor es una colección de ciertos probes, muy similar a una colección de
funciones. Por ejemplo, el provider "syscall" nos provee de probes para la entrada y retorno de todas las
llamadas al sistema. Al final de ésta guía podemos encontrar una referencia de los providers.
.
Los módulos corresponden a los módulos de kernel de Solaris. En caso de crear nuestros propios
probes dentro de las aplicaciones, el módulo puede ser la clase ó el código del módulo en el que definimos
el probe. Si el probe corresponde a una ubicación específica, el nombre del módulo es donde se localiza la
prueba.
Las funciones son los nombres de las funciones del código en las que están situados los probes. El
nombre es el componente final del probe nos da una idea de cuando se ejecuta el probe, como por ejemplo
BEGIN ó END
Los syscalls pueden ser fácilmente seguidos utilizando el provider syscall, que nos ofrece un probe
para la entrada y retorno de la llamada al sistema. Como un punto en el medio entre en el espacio de usuario
y el de kernel, la interfaz syscall refleja perfectamente el comportamiento de la aplicación. Cada syscall está
documentada en la sección 2 de las páginas del manual (man).
175
Comunidad OpenSolaris Hispano
sh 1115
Terminal 1415
java 3219
Xorg 3422
fcntl 1
getpid 1
mmap 1
open 1
schedctl 1
fstat64 2
so_socket 2
stat64 2
close 3
sysconfig 3
sigaction 5
brk 6
xstat 10
lwp_sigmask 11
setcontext 11
nanosleep 13
gtime 14
write 15
writev 16
setitimer 19
p_online 32
read 56
lwp_park 66
pollsys 239
ioctl 495
Se puede establece un valor particular para medir el tiempo transcurrido y el tiempo en CPU de las
llamadas al sistema, de forma que nos explique el tiempo de carga y respuesta de la CPU. Por ejemplo, la
herramienta procsystime de DTraceToolkit realiza ésta función utilizando los flags -e y -o
177
Comunidad OpenSolaris Hispano
Los eventos de disco se pueden seguir empleando el provider io, el cual nos ofrece probes para la
petición y completación de Entrada/Salida de discos y clientes NFS.
Cada probe nos muestra detalles muy extensos sobre la Entrada/Salida a través de la matriz args[],
como está documentado en la guía DTrace.
Las I/O Completions (io:::done) son asíncronas, así que pid y execname podrian no identificar los
procesos responsables. Las peticiones de escritura en disco (io:::start) suelen ser a menudo asíncronas a los
pocesos responsables, como el sistemas de ficheros ha cacheado la escritura, ya no existirá más adelante en el
medio de almacenamiento. .
Los eventos io no significan necesariamente que las cabezas del disco se estén moviendo. Algunos discos
tienen buffers para cachear la actividad de Entrada/Salida, especialmente los arrays de discos.
178
Comunidad OpenSolaris Hispano
sched
256 |
0
512 |@@@@@@@@@
9
1024 |@@@@@@@@@@@@
13
2048 |@@@@@@@@@@@@@@@ 16
4096 | 0
8192 | 0
16384 |@@@@ 4
32768 | 0
179
Comunidad OpenSolaris Hispano
Ya en nuestro editor de textos favorito escribimos el siguiente código y lo guardamos con el nombre
hola.d :
BEGIN
{
trace(“Hola, mundo!);
exit(0);
CPU ID FUNCTION:NAME
0 1 :BEGIN Hola, mundo!
En DTraceToolkit podremos encontrar numerosos scripts más que nos sirvan de ayuda.
También puedes usar tu navegador web para verlos todos, escribiendo la URL:
file:///usr/demo/dtrace/index.html en la barra de dirección.
180