Introducción a los sistemas operativos: uso del proyecto OpenSolaris Guía del estudiante

Sun Microsystems, Inc. 4150 Network Circle Santa Clara, CA 95054 U.S.A. Copyright 2007 , Inc. 4150 Network Circle, Santa Clara, CA 95054 U.S.A. Reservados todos los derechos.

Sun Microsystems, Inc. posee derechos de propiedad intelectual en relación con la tecnología incluida en el producto descrito en este documento. De forma específica y sin limitación, entre estos derechos de propiedad intelectual se incluyen una o varias patentes en los EE.UU. o aplicaciones pendientes de patente en los EE.UU. y otros países. Derechos gubernamentales de los EE. UU. – Software comercial. Los usuarios gubernamentales están sujetos al acuerdo de licencia estándar de Sun Microsystems, Inc. y a las disposiciones aplicables de la regulación FAR y sus suplementos. Esta distribución puede incluir materiales desarrollados por terceras partes. Determinadas partes del producto pueden derivarse de Berkeley BSD Systems, con licencia de la Universidad de California. UNIX es una marca registrada en los EE.UU. y otros países, bajo licencia exclusiva de X/Open Company, Ltd. Sun, Sun Microsystems, el logotipo de Sun, el logotipo de Solaris, el logotipo de la taza de café de Java, docs.sun.com, Java y Solaris son marcas comerciales o marcas comerciales registradas de Sun Microsystems, Inc. en EE.UU y otros países. Todas las marcas registradas SPARC se usan bajo licencia y son marcas comerciales o marcas registradas de SPARC International, Inc. en los EE.UU. y en otros países. Los productos con las marcas registradas de SPARC se basan en una arquitectura desarrollada por Sun Microsystems, Inc. La interfaz gráfica de usuario OPEN LOOKTM ySun fue desarrollada por Sun Microsystems, Inc. para sus usuarios y licenciatarios. Sun reconoce los esfuerzos pioneros de Xerox en la investigación y desarrollo del concepto de interfaces gráficas o visuales de usuario para el sector informático. Sun dispone de una licencia no exclusiva deXerox para la interfaz gráfica de usuario de Xerox, que también cubre a los licenciatarios de Sun que implementen lasGUI de OPEN LOOK y que, por otra parte, cumplan con los acuerdos de licencia por escrito de Sun. Los productos descritos y abordados en esta publicación están sometidos a la legislación de control de exportaciones de los EE.UU. y pueden estar sujetos a leyes de importación o exportación de otros países. Se prohíbe estrictamente el uso final de estos productos en misiles nucleares, armas químicas o biológicas o aplicaciones nucleares marítimas,ya sea de forma directa o indirecta. Se prohíbe estrictamente la exportación o reexportación a países bajo el embargo de los EE.UU o a entidades incluidas en la lista de exclusión de exportación de los EE.UU., incluidas, pero no limitándose a, las personas rechazadas y a las listas nacionales designadas específicamente. ESTA DOCUMENTACIÓN SE PROPORCIONA “TAL CUAL”.SE RENUNCIA A TODAS LAS CONDICIONES EXPRESAS O IMPLÍCITAS, REPRESENTACIONES Y GARANTÍAS, INCLUIDAS CUALQUIER GARANTÍA IMPLÍCITA DE COMERCIALIZACIÓN, ADECUACIÓN PARA UNA FINALIDAD DETERMINADA O DE NO CONTRAVENCIÓN, EXCEPTO EN AQUELLOS CASOS EN QUE DICHA RENUNCIA NO FUERA LEGALMENTE VÁLIDA.

Copyright 2007 Sun Microsystems, Inc. 4150 Network Circle, Santa Clara, CA 95054 U.S.A. Tous droits réservés. Sun Microsystems, Inc. détient les droits de propriété intellectuelle relatifs à la technologie incorporée dans le produit qui est décrit dans ce document. En particulier, et ce sans limitation, ces droits de propriété intellectuelle peuvent inclure un ou plusieurs brevets américains ou des applications de brevet en attente aux Etats-Unis et dans d'autres pays. Cette distribution peut comprendre des composants développés par des tierces personnes. Certaines composants de ce produit peuvent être dérivées du logiciel Berkeley BSD, licenciés par l'Université de Californie. UNIX est une marque déposée aux Etats-Unis et dans d'autres pays; elle est licenciée exclusivement par X/Open Company, Ltd. Sun, Sun Microsystems, le logo Sun, le logo Solaris, le logo Java Coffee Cup, docs.sun.com, Java et Solaris sont des marques de fabrique ou des marques déposées de Sun Microsystems, Inc. aux Etats-Unis et dans d'autres pays. Toutes les marques SPARC sont utilisées sous licence et sont des marques de fabrique ou des marques déposées de SPARC International, Inc. aux Etats-Unis et dans d'autres pays. Les produits portant les marques SPARC sont basés sur une architecture développée par Sun Microsystems, Inc. L'interface d'utilisation graphique OPEN LOOK et Sun a été développée par Sun Microsystems, Inc. pour ses utilisateurs et licenciés. Sun reconnaît les efforts de pionniers de Xerox pour la recherche et le développement du concept des interfaces d'utilisation visuelle ou graphique pour l'industrie de l'informatique. Sun détient une licence non exclusive de Xerox sur l'interface d'utilisation graphique Xerox, cette licence couvrant également les licenciés de Sun qui mettent en place l'interface d'utilisation graphique OPEN LOOK et qui, en outre, se conforment aux licences écrites de Sun. Les produits qui font l'objet de cette publication et les informations qu'il contient sont régis par la legislation américaine en matière de contrôle des exportations et peuvent être soumis au droit d'autres pays dans le domaine des exportations et importations. Les utilisations finales, ou utilisateurs finaux, pour des armes nucléaires, des missiles, des armes chimiques ou biologiques ou pour le nucléaire maritime, directement ou indirectement, sont strictement interdites. Les exportations ou réexportations vers des pays sous embargo des Etats-Unis, ou vers des entités figurant sur les listes d'exclusion d'exportation américaines, y compris, mais de manière non exclusive, la liste de personnes qui font objet d'un ordre de ne pas participer, d'une façon directe ou indirecte, aux exportations des produits ou des services qui sont régis par la legislation américaine en matière de contrôle des exportations et la liste de ressortissants spécifiquement designés, sont rigoureusement interdites. LA DOCUMENTATION EST FOURNIE "EN L'ETAT" ET TOUTES AUTRES CONDITIONS, DECLARATIONS ET GARANTIES EXPRESSES OU TACITES SONT FORMELLEMENT EXCLUES, DANS LA MESURE AUTORISEE PAR LA LOI APPLICABLE, Y COMPRIS NOTAMMENT TOUTE GARANTIE IMPLICITE RELATIVE A LA QUALITE MARCHANDE, A L'APTITUDE A UNE UTILISATION PARTICULIERE OU A L'ABSENCE DE CONTREFACON.

Contenido

1 ¿Qué es el proyecto OpenSolaris? ...... 9 Portales de países ...... 12 Recursos Web para OpenSolaris ...... 13 Debates ...... 13 Comunidades ...... 13 Proyectos ...... 15 Depósitos de origen ...... 16 OpenGrok ...... 16

2 Impulsores de OpenSolaris ...... 19 ¿Por qué se recomienda el uso de OpenSolaris? ...... 20 Precio ...... 20 Funciones principales innovadoras ...... 21 Compatibilidad con versiones anteriores ...... 21 Plataforma de hardware neutra ...... 22 Herramientas de desarrollo ...... 23 Agradecimientos ...... 25

3 Planificación del entorno de OpenSolaris ...... 27 Configuración del entorno de desarrollo ...... 29 Redes ...... 32

5 Contenido

Daemon de configuración automática de red ...... 33 Descripción general de zona ...... 34 Administración de zonas ...... 35 Introducción a la administración de zonas ...... 36 Virtualización del servidor Web con zonas ...... 40 Creación de zonas no globales ...... 41 Creación de agrupaciones de almacenamiento ZFS y sistemas de archivos ...... 46 Creación de agrupaciones de almacenamiento ZFS duplicadas ...... 47 Creación de sistemas de archivos ZFS como directorios de inicio ...... 49 Creación de una configuración RAID-Z ...... 52

4 Consolidaciones de userland ...... 55 Consolidaciones userland y descripciones ...... 56

5 Características principales del sistema operativo Solaris .....59 Proceso de desarrollo y estilo de código ...... 60 Información general ...... 64 FireEngine ...... 64 Minimización de los privilegios ...... 67 Filtros de paquetes ...... 68 Zonas ...... 71 Zonas de marca (BrandZ) ...... 73 Redes de zonas ...... 74 Recuperación automática predecible ...... 77 Dynamic Tracing (DTrace) ...... 78 Modular Debugger (MDB) ...... 79

6 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Contenido

Sistema de archivos ZFS ...... 80 Utilidad de gestión de servicios (SMF) ...... 81

6 Conceptos de programación ...... 83 Administración del sistema y los procesos ...... 84 Programación de subprocesos ...... 85 Planificación de la CPU ...... 88 Descripción general del núcleo ...... 92 Depuración de procesos ...... 95

7 Introducción a DTrace ...... 99 Activación de sondeos DTrace sencillos ...... 100 Enumeración de sondeos rastreables ...... 103 Programación en D ...... 107

8 Depuración de aplicaciones con DTrace ...... 111 Activación de los sondeos en modo de usuario ...... 112 Uso de DTrace con aplicaciones ...... 113

9 Depuración de aplicaciones C++ con DTrace ...... 119 Uso de DTrace para perfilar y depurar un programa en C++ 120

10 Gestión de memoria con DTrace y MDB ...... 133 Gestión de memoria del software ...... 134 Uso de DTrace y MDB para examinar la memoria virtual .... 135

7 Contenido

11 Depuración de controladores con DTrace ...... 149 Asignación de puertos al controlador smbfs de Linux al sistema operativo Solaris ...... 150

A Recursos de OpenSolaris ...... 161

8 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 1MÓDULO 1 ¿Qué es el proyecto OpenSolaris?

Objetivos El objetivo de este curso es conocer el funcionamiento de un sistema operativo utilizando el código fuente del sistema operativo SolarisTM, disponible de forma gratuita a través del proyecto OpenSolaris.

Consejo – Para recibir un paquete de inicio de OpenSolaris gratuito que incluya el material de formación, el código fuente y las herramientas de desarrollo, regístrese en línea en la página http://get.opensolaris.org.

Empezaremos describiendo los grupos de usuarios, los portales y la documentación que necesitará para familiarizarse con UNIX®. A continuación, le indicaremos cómo acceder al código, las comunidades, los debates, los proyectos y el navegador de código del proyecto OpenSolaris. Le señalaremos los pasos necesarios para configurar las zonas, ZFS, las redes y el entorno. Por último, mostraremos los procesos de depuración, las aplicaciones, los errores de páginas y los controladores de dispositivos con DTrace en los ejercicios prácticos.

El proyecto OpenSolaris se inició el 14 de junio de 2005 para aunar los esfuerzos de desarrollo de la comunidad tomando como punto de partida el código del sistema operativo Solaris. Se trata de un

9 ¿Qué es el proyecto OpenSolaris?

nexo para el desarrollo de la comunidad, donde colaboradores de Sun y otros lugares pueden contribuir al desarrollo y la mejora de la tecnología de sistema operativo. El código fuente de OpenSolaris puede tener múltiples usos, por ejemplo constituir la base de futuras versiones del sistema operativo Solaris, otros proyectos de sistema operativo, y distribuciones y productos de terceros que puedan ser de interés para la comunidad. El proyecto OpenSolaris está patrocinado actualmente por Sun Microsystems, Inc.

Durante los dos primeros años, más de 60.000 participantes se han registrado como miembros. La comunidad de ingenieros no para de aumentar y cambiar para satisfacer las necesidades de los desarrolladores, los administradores de sistemas y los usuarios finales del sistema operativo Solaris.

La formación con el proyecto OpenSolaris proporciona las ventajas siguientes con respecto a los sistemas operativos de formación: ■ Acceso al código para las innovadoras tecnologías del sistema operativo Solaris 10 ■ Acceso al código para un sistema operativo comercial que se utilice en varios entornos y se pueda escalar a sistemas más grandes ■ Herramientas superiores de depuración y observación ■ Compatibilidad con plataforma de hardware que incluye las arquitecturas SPARC, x86 y x64 ■ Liderazgo en funcionamiento de 64 bits ■ Derechos de uso ilimitados y gratuitos ■ Base de código libre, innovadora, emocionante, completa, sólida e integral ■ La disponibilidad bajo la licencia CDDL (Common Development and Distribution License o Desarrollo común y licencia de distribución) aprobada por la Open Source

10 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 ¿Qué es el proyecto OpenSolaris?

Initiative (OSI) permite usar sin derechos de autor, realizar modificaciones y llevar a cabo trabajos derivados

Módulo 1 • ¿Qué es el proyecto OpenSolaris? 11 Portales de países Portales de países La Internationalization and Localization Community está contribuyendo a la traducción de la página Web en inglés de OpenSolaris a múltiples idiomas. Hasta la fecha, se están desarrollando los portales de ocho países:

■ Portal de India: http://in.opensolaris.org ■ Portal de China: http://cn.opensolaris.org ■ Portal de Japón: http://jp.opensolaris.org ■ Portal de Polonia: http://pl.opensolaris.org ■ Portal de Francia: http://fr.opensolaris.org ■ Portal de Brasil: http://opensolaris.org/os/project/br ■ Portal de España: http://opensolaris.org/os/project/es

Está previsto el desarrollo de los portales de Alemania, Rusia, República Checa, España, Corea y México. Consulte los portales del proyecto OpenSolaris para participar o charlar en una de las siete salas de charla de OpenSolaris utilizando IRC en irc.freenode.net. Consulte http://opensolaris.org/os/chat/.

12 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 RecursosWeb para OpenSolaris RecursosWeb para OpenSolaris Puede descargar la fuente de OpenSolaris, ver los términos de la licencia y acceder a instrucciones sobre cómo crear código e instalar los archivos previamente configurados en: http://www.opensolaris.org/os/downloads.

Los iconos de la parte superior derecha de las páginas Web de OpenSolaris son vínculos a debates, comunidades, proyectos, descargas y recursos de navegador de código.

Además, la página Web de OpenSolaris permite buscar contenido en todo el sitio y en los blogs agregados.

Debates Los debates permiten entrar en contacto con los expertos que trabajan en nuevas tecnologías de código abierto. Asimismo, incluyen un archivo de las conversaciones anteriores que puede consultar para dar respuesta a sus preguntas. Consulte http://www.opensolaris.org/os/discussions para ver una lista completa de los foros a los que se puede suscribir.

Comunidades Las comunidades permiten contactar con otros participantes con intereses similares en el proyecto OpenSolaris. Se componen de grupos de interés, tecnologías, soporte, herramientas y grupos de usuarios, como:

Teoría e http://www.opensolaris.org/os/community/edu investigación

Módulo 1 • ¿Qué es el proyecto OpenSolaris? 13 RecursosWeb para OpenSolaris

DTrace http://www.opensolaris.org/ os/community/dtrace

ZFS http://www.opensolaris.org/os/community/zfs

Redes http://www.opensolaris.org/ os/community/networking

Zonas http://www.opensolaris.org/os/community/zones

Documentación http://www.opensolaris.org/ os/community/documentation

Controladores http://www.opensolaris.org/ de dispositivos os/community/device_drivers

Herramientas http://www.opensolaris.org/os/community/tools

Impulsores http://www.opensolaris.org/ os/community/advocacy

Seguridad http://www.opensolaris.org/ os/community/security

Rendimiento http://www.opensolaris.org/ os/community/performance

Almacenamiento http://www.opensolaris.org/ os/community/storage

Administradores http://www.opensolaris.org/ de sistemas os/community/sysadmin

Éstas son sólo algunas de las 30 comunidades que trabajan de forma activa en OpenSolaris. Consulte http://www.opensolaris.org/os/communities para ver la lista completa.

14 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 RecursosWeb para OpenSolaris Proyectos Los proyectos alojados en la página Web http://www.opensolaris.org/ reúnen aportaciones que generan, por ejemplo, cambios de código, documentos, gráficos o productos de varios autores. Los proyectos cuentan con depósitos de código y "committers", y pueden existir dentro de una comunidad o de forma independiente.

Los participantes inician nuevos proyectos a partir de las peticiones que los usuarios efectúan en los debates. Los proyectos que se envían consiguen espacio en la página de proyectos para poder iniciarse siempre que lo acepte al menos un participante interesado de la comunidad patrocinadora que no sea el "commiter". Consulte http://www.opensolaris.org/os/projects para ver la lista actual de proyectos nuevos.

Herramienta de http://www.opensolaris.org/ visualización os/project/dtrace-chime Chime para DTrace

Google Summer http://www.opensolaris.org/os/project/powerPC of Code

Indiana http://www.opensolaris.org/os/project/indiana

OpenGrok http://www.opensolaris.org/ os/project/opengrok

Concurso de http://www.opensolaris.org/os/project/contest programación

Paquete de http://www.opensolaris.org/ inicio os/project/starterkit

Destino iSCSI http://www.opensolaris.org/ de Solaris os/project/iscsitgt

Módulo 1 • ¿Qué es el proyecto OpenSolaris? 15 RecursosWeb para OpenSolaris Depósitos de origen Los depósitos de origen centralizados y distribuidos se alojan en el sitio Web opensolaris.org. El modelo de administración de orígenes centralizados utiliza el programa de administración de control de origen Subversion (SVN). Los depósitos administrados de forma distribuida utilizan el programa de administración de control de origen Mercurial (hg). Los responsables de proyectos de opensolaris.org utilizan las páginas Web de proyectos para completar la creación de un depósito de origen. Los desarrolladores con derechos de envío acceden a los depósitos a través de sus cuentas de opensolaris.org. Los responsables de proyectos se encargan de administrar los derechos de envío. Si necesita una cuenta, puede registrarse para obtener una. Debe proporcionar una clave pública Secure Shell (SSH). Consulte la comunidad de herramientas para conocer la información más reciente relativa al control de origen, acceder a descargas y obtener instrucciones (http://opensolaris.org/os/community/tools).

OpenGrok OpenGrokTM es el motor de búsqueda de código fuente y referencias cruzadas de gran rapidez que se utiliza en OpenSolaris. Vaya a http://cvs.opensolaris.org/source para probarlo. OpenGrok fue el primer proyecto que se alojó en opensolaris.org. Consulte http://www.opensolaris.org/os/project/opengrok para obtener información sobre el proyecto de desarrollo actual. Eche un vistazo al código fuente; descubrirá código claro y con amplios comentarios que se leen con gran facilidad. Si le interesa trabajar en un proyecto de OpenSolaris, descargue el

16 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 RecursosWeb para OpenSolaris código base completo. Si sólo desea conocer el funcionamiento de algunas opciones del sistema operativo Solaris, el navegador de código fuente es de gran ayuda. OpenGrok admite varios formatos de archivos de programa e historiales de control de versiones como SCCS, RCS o CVS, de modo que facilita la comprensión del código abierto.

Módulo 1 • ¿Qué es el proyecto OpenSolaris? 17 18 MÓDULO2 2 Impulsores de OpenSolaris

Objetivos La comunidad de impulsores tiene la finalidad de promover la participación de personas de todo el mundo en la comunidad OpenSolaris. Agradecemos la participación de cualquier persona, independientemente de su idioma, cultura o nivel de conocimientos técnicos y no técnicos. Todo el mundo tiene algo que aportar.

Consulte http://opensolaris.org/os/community/advocacy/.

En la comunidad de impulsores, encontrará proyectos de grupos de usuarios independientes, así como presentaciones, noticias, artículos, blogs, contenido técnico y no técnico, vídeos y podcasts, eventos y conferencias, estadísticas de la comunidad, promociones, dispositivos y parches, botones y otros proyectos promocionales.

19 ¿Por qué se recomienda el uso de OpenSolaris? ¿Por qué se recomienda el uso de OpenSolaris?

En esta sección se describen los motivos prácticos por los que debe considerar el uso de OpenSolaris como plataforma de desarrollo.

Precio

Desde el lanzamiento del sistema operativo Solaris 10 en enero de 2005, su popularidad ha crecido enormemente. A fecha de julio de 2007, se registraron más de 8,7 millones de copias, una cifra superior a la suma de todas las versiones anteriores del sistema operativo Solaris. El lanzamiento de OpenSolaris en junio de 2005 afianzó esta frenética tendencia. Debido aeste aumento repentino del número de usuarios, cada vez más desarrolladores (tanto comerciales como de código abierto) consideran el sistema operativo Solaris como una solución viable para su software.

Uno de los motivos por los que el sistema operativo Solaris disfrutó de un gran aumento de popularidad fue su precio: es gratuito para cualquier uso (tanto comercial como no comercial) en cualquier equipo (en plataformas SPARC y x86). Otro motivo fue la promesa de Sun (y el cumplimiento de la misma) de facilitar el código fuente de Solaris disponible con una licencia de código abierto aprobada por la OSI, la licencia de distribución y desarrollo común o Common Development and Distribution License (CDDL).

20 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 ¿Por qué se recomienda el uso de OpenSolaris? Funciones principales innovadoras Sin embargo, el motivo más importante de la popularidad de la que goza el sistema operativo Solaris es sin duda la amplia variedad de funciones que ofrece. A continuación se incluyen algunas de ellas, sin un orden específico: ■ Zonas de Solaris: permiten particionar un equipo en distintos equipos virtuales, cada uno de los cuales está aislado del resto. ■ DTrace: completa herramienta de rastreo dinámico para analizar el comportamiento del sistema sin que ello afecte a la producción de los equipos. ■ Nueva pila IP: ofrece un rendimiento mejorado notablemente. ■ ZFS: sistema de archivos de 128 bits de última generación con comprobación y corrección de errores, una interfaz de línea de comandos sencilla y una capacidad de almacenamiento casi ilimitada.

Compatibilidad con versiones anteriores Todas estas funciones se basan en unos pilares que los usuarios habituales del sistema operativo Solaris esperan encontrar: solidez y estabilidad, escalabilidad, elevado rendimiento y compatibilidad con versiones anteriores garantizada. La compatibilidad con versiones anteriores resulta especialmente importante para los desarrolladores de software comercial, ya que el mantenimiento es normalmente el mayor gasto asociado a cualquier software. Gracias a la garantía de compatibilidad con versiones anteriores, los proveedores de software saben que el software creado para Solaris N (siempre que se utilicen únicamente las API publicadas) se ejecutará correctamente en

Módulo 2 • Impulsores de OpenSolaris 21 ¿Por qué se recomienda el uso de OpenSolaris?

las versiones Solaris N+1 y posteriores. Esto es una ventaja con respecto a otros sistemas operativos, en los que se realizan cambios incompatibles en los componentes del sistema (por ejemplo, bibliotecas), sin importar el efecto que ello tenga en las aplicaciones. Por ejemplo, si las aplicaciones se bloquean, se generan más gastos de mantenimiento y la frustración de proveedores y usuarios.)

Plataforma de hardware neutra

En los párrafos anteriores se mencionan algunos motivos por los que se debe desarrollar para el sistema operativo Solaris, pero existen motivos adicionales para desarrollar en la plataforma Solaris. Uno de ellos es que Solaris es un sistema operativo que sirve de plataforma para varios sistemas operativos, y es compatible con arquitecturas SPARC y x86 (y además se está desarrollando un puerto controlado por la comunidad para Power). Aunque hace unos años hubo un problema con el sistema operativo Solaris para las plataformas x86, el hecho de que Sun haya introducido una gama de estaciones de trabajo y servidores basados en AMD demuestra el compromiso de la compañía con la tecnología x86.

Desde el punto de vista de los desarrolladores, las versiones de Solaris para plataformas SPARC y x86 cuentan con los mismos grupos de funciones y API. Gracias a ello, los desarrolladores se pueden centrar en otros problemas endémicos del desarrollo entre plataformas, como el formato de los bytes significativos de CPU. En la plataforma SPARC se incluyen primero los bytes más significativos, y en la plataforma x86 se incluyen primero los bytes menos significativos, de modo que es muy probable que una aplicación que se desarrolla y prueba en la plataforma Solaris plantee problemas relativos a los bytes significativos. El sistema operativo Solaris también admite aplicaciones tanto de

22 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 ¿Por qué se recomienda el uso de OpenSolaris?

32 como de 64 bits en ambas plataformas, con lo cual se pone fin a los problemas derivados de las suposiciones de tamañode palabra.

Posiblemente el motivo más convincente para desarrollar software en el sistema operativo Solaris sea la gran variedad de herramientas de desarrollo profesional que hay disponibles para el mismo.

Herramientas de desarrollo Una de las características más importantes de un sistema operativo desde el punto de vista de un desarrollador es la variedad y calidad de las herramientas de desarrollo disponibles. Los compiladores y depuradores son el ejemplo más obvio de estas herramientas, pero también se incluyen comprobadores de código (para asegurarse de que el código no tenga pequeños errores que no detecte el compilador), generadores de referencias cruzadas (para ver qué funciones hacen referencia a otras funciones y variables) y analizadores del rendimiento.

El paquete Sun Studio es el producto preferido de los desarrolladores del sistema operativo Solaris. El software Sun Studio, que se puede descargar gratuitamente en el sitio Web http://developers.sun.com, es un conjunto de herramientas y compiladores profesionales. Incluye los compiladores C, C++ y FORTRAN, herramientas de análisis de código, un entorno de desarrollo integrado (IDE), el depurador de nivel fuente dbx y editores. Otras herramientas que se incluyen con el software Studio son cscope (un examinador de código fuente interactivo), ctrace (una herramienta para generar una versión de nuestros programas que se rastree automáticamente), cxref (un generador de referencias cruzadas de C), dmake (para makes paralelos distribuidos) y lint (el comprobador del programa C).

Módulo 2 • Impulsores de OpenSolaris 23 ¿Por qué se recomienda el uso de OpenSolaris?

El sistema operativo Solaris se suministra con el compilador C GNU, gcc, y su correspondiente depurador de nivel fuente, gdb. Además, incluye el potente depurador modular mdb. Sin embargo, mdb no es un depurador de nivel fuente. Resulta más útil cuando se depura código del núcleo, o cuando se llevan a cabo análisis al final del proyecto en programas para los queno hay código fuente disponible. Consulte Solaris Modular Debugger Guide y Solaris Performance and Tools de McDougall, Mauro y Gregg para obtener información adicional sobre mdb.

24 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Agradecimientos Agradecimientos Los siguientes miembros de la comunidad OpenSolaris han revisado y comentado este documento:

■ Boyd Adamson ■ Pradhap Devarajan ■ Alan Coopersmith ■ Brian Gupta ■ Rainer Heilke ■ Eric Lowe ■ Ben Rockwood ■ Cindy Swearingen

Los siguientes miembros de la comunidad OpenSolaris han aportado nuevo contenido de calidad excelente:

■ Dong-Hai Han ■ Narayana Janga ■ Shivani Khosa ■ Rich Teer ■ Sunay Tripathi ■ Yifan Xu

Nuestro agradecimiento también a Steven Cogorno, David Comay, Teresa Giacomini, Stephen Hahn, Patrick Finch y Sue Weber por su trabajo para hacer posible la versión inicial.

Para participar en futuras revisiones de este documento, siga las instrucciones de esta dirección URL:

http://www.opensolaris.org/ os/community/documentation/reviews

Módulo 2 • Impulsores de OpenSolaris 25 26 MÓDULO3 3 Planificación del entorno de OpenSolaris

Objetivos El objetivo de este módulo es comprender los requisitos del sistema, la información de compatibilidad y la documentación disponible para la instalación y configuración del proyecto OpenSolaris.

Recursos adicionales

■ Solaris Express Developer Edition Installation Guide: Laptop Installations. Sun Microsystems, Inc., 2007. ■ Recursos para ejecutar el sistema operativo Solaris en un portátil: http://www.sun.com/ bigadmin/features/articles/laptop_resources.html ■ Comunidad de OpenSolaris para portátiles: http://opensolaris.org/os/community/laptop ■ Paquete de inicio de OpenSolaris: http://opensolaris.org/os/project/starterkit ■ System Administration Guide: IP Services, Sun Microsystems, Inc., 2007 ■ Comunidad de redes de OpenSolaris: http://www.opensolaris.org/os/community/networking

27 Planificación del entorno de OpenSolaris

■ ZFS Administration Guide y páginas del comando man: http://opensolaris.org/os/community/zfs/docs

28 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Configuración del entorno de desarrollo Configuración del entorno de desarrollo

Nada mejor que la experiencia y la práctica con código de sistema operativo y acceso directo a los módulos de núcleo. Los desafíos exclusivos del desarrollo de núcleos y el acceso a los privilegios root de un sistema resultan más sencillos gracias al uso de las herramientas, los foros y la documentación disponibles para el proyecto OpenSolaris.

Consejo – Para recibir un paquete de inicio de OpenSolaris que incluya el material de formación, el código fuente y las herramientas de desarrollo, vaya a http://get.opensolaris.org.

Tenga en cuenta los siguientes aspectos de OpenSolaris cuando planifique su entorno de desarrollo:

TABLA 3–1 Compatibilidad con componentes configurables

Componente configurable Compatibilidad del proyecto OpenSolaris

Hardware OpenSolaris admite sistemas que utilizan las familias de arquitecturas de procesadorSPARC® y x86: UltraSPARC®, SPARC64, AMD64, Pentium y Xeon EM64T. Para conocer los sistemas compatibles, consulte la lista de compatibilidad de hardware de Solaris en http://www.sun.com/bigadmin/hcl.

Archivos de Consulte http://opensolaris.org/os/downloads origen para obtener instrucciones detalladas sobre cómo generar a partir del origen.

Módulo 3 • Planificación del entorno de OpenSolaris 29 Configuración del entorno de desarrollo

TABLA 3–1 Compatibilidad con componentes configurables (Continuación) Componente configurable Compatibilidad del proyecto OpenSolaris

Imágenes de Las distribuciones de OpenSolaris generadas instalación previamente se limitan a Solaris Express: Community Edition [versión en DVD], versión 32 o posterior, Solaris Express: Developer Edition, Nexenta, Schillix, Martux y Belenix. Para el núcleo de OpenSolaris con el entorno de usuario GNU, vaya a http://www.gnusolaris.org/gswiki/Download-form.

Archivos BFU Se proporciona el archivo on-bfu-DATE.PLATFORM.tar.bz2 si se está instalando desde archivos generados previamente.

Herramientas Se proporciona el archivo de generación SUNWonbld-DATE.PLATFORM.tar.bz2 si se genera desde el origen.

Compiladores Los compiladores y las herramientas de Sun Studio 11 y herramientas están disponibles de forma gratuita para los desarrolladores de OpenSolaris. Consulte http://www.opensolaris.org/ os/community/tools/sun_studio_tools/ para obtener instrucciones sobre cómo descargar e instalar las versiones más recientes. Consulte también http://www.opensolaris.org/ os/community/tools/gcc para acceder a la comunidad gcc.

Requisitos de ■ Memoria necesaria: 256 MB mínimo (sólo memoria y instalador de texto), 1 GB recomendado disco ■ Requisito de memoria: 768 MB mínimo para el instalador de Solaris Express Developer Edition. ■ Espacio en el disco necesario: 350 MB.

30 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Configuración del entorno de desarrollo

TABLA 3–1 Compatibilidad con componentes configurables (Continuación) Componente configurable Compatibilidad del proyecto OpenSolaris

Entornos de Las zonas y zonas de marca en OpenSolaris sistema proporcionan entornos de sistema operativo protegidos operativo y virtualizados en una instancia de Solaris. Eso permite virtuales la ejecución de uno o más procesos de forma aislada de otra actividad del sistema. OpenSolaris admite Xen, un monitor de máquina virtual de código abierto desarrollado por el laboratorio de Informática de la Universidad de Cambridge. Consulte http://www.opensolaris.org/os/community/xen/ para obtener más detalles y vínculos al proyecto Xen. OpenSolaris también es un invitado de VMWareTM. Consulte http://www.opensolaris.org/os/project/content para ver un artículo reciente de introducción.

Consulte el Módulo 4 para obtener más información sobre el modo en que las zonas y las zonas de marca permiten el núcleo y el desarrollo del modo de usuario de las aplicaciones Solaris y Linux sin repercutir en el trabajo de los desarrolladores en otras zonas.

La participación en el proyecto OpenSolaris puede mejorar el rendimiento global de la red con las tecnologías más innovadoras. El entorno de trabajo se convierte en autosuficiente cuando se aloja en OpenSolaris porque siempre se ejecuta el mejor entorno y más reciente, y se le da la posibilidad de actualizarlo usted mismo.

Módulo 3 • Planificación del entorno de OpenSolaris 31 Configuración del entorno de desarrollo Redes El proyecto OpenSolaris satisface los futuros requisitos de las redes al mejorar radicalmente el rendimiento de las mismas sin necesidad de efectuar cambios en las aplicaciones.

■ Acelera el rendimiento de la aplicación en un 50 por ciento gracias al uso de una pila TCP/IP mejorada ■ Admite muchas de las recientes tecnologías de redes, como 10 Gigabit Ethernet, redes inalámbricas y transferencia de hardware ■ Admite flujo de datos de alta disponibilidad y funciones de redes de Voz sobre IP (VoIP) gracias a la compatibilidad con protocolos y rutas extendidas ■ Admite las especificaciones IPv6 actuales

En la dirección siguiente encontrará más información sobre los desarrollos de red actuales de la comunidad de redes de OpenSolaris: http://www.opensolaris.org/os/community/networking.

32 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Daemon de configuración automática de red Daemon de configuración automática de red El proceso de arranque de Solaris Express Developer Edition 5/07 ejecuta el daemon nwamd. Este daemon implementa una instancia alternativa del servicio SMF, svc:/network/physical, lo que permite una configuración de red automatizada con una intervención mínima.

El daemon nwamd supervisa el puerto Ethernet y admite DHCP automáticamente en la interfaz IP pertinente. Si no hay ningún cable conectado a la red con cables, el daemon nwamd lleva a cabo una exploración inalámbrica y envía consultas al usuario para obtener un punto de acceso WiFi al que conectarse.

No es necesario dedicar una gran cantidad de tiempo a configurar manualmente las interfaces de los sistemas. La configuración automática también es útil para la administración, ya que puede reconfigurar las direcciones de red con una intervención mínima.

Para ver el estado de NWAM, escriba el comando siguiente en una ventana de terminal.

# svcs nwam

STATE STIME FMRI

online 11:29:50 svc:/network/physical:nwam

La página de OpenSolaris Network Auto-Magic Phase0yla página del comando man nwamd contienen más detalles, como las instrucciones para desactivar el daemon nwamd, en caso de que desee hacerlo. Para obtener información adicional y un vínculo a la página del comando man nwamd(1M), consulte http://www.opensolaris.org/os/project/nwam.

Módulo 3 • Planificación del entorno de OpenSolaris 33 Descripción general de zona Descripción general de zona Una zona se puede considerar un contenedor en el que una o más aplicaciones se ejecutan de forma aislada de todas las demás aplicaciones del sistema. La mayoría del software que se ejecuta en OpenSolaris se ejecuta sin modificaciones en una zona. Dado que las zonas no cambian la interfaz de programación de aplicación (API) ni la interfaz binaria de aplicación (ABI) de OpenSolaris, no es necesario compilar de nuevo una aplicación para volver a ejecutarla dentro de una zona.

34 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Administración de zonas Administración de zonas La administración de zonas se compone de los comandos siguientes:

■ zonecfg: crea y configura zonas (agrega recursos y propiedades). Almacena la configuración en un archivo XML privado en /etc/zones. ■ zoneadm: lleva a cabo las tareas administrativas de las zonas, como la lista, la instalación, el arranque o la detención. ■ zlogin: permite al usuario iniciar sesión en la zona para realizar tareas de mantenimiento. ■ zonename: muestra el nombre de zona actual.

Las siguientes propiedades de ámbito global se utilizan con las zonas:

■ zonepath: ruta de la zona global al directorio root en el que se instalará la zona. ■ autoboot: permite decidir si se inicia cuando se arranca la zona global. ■ pool: agrupaciones de recursos a las que deben estar vinculadas las zonas. Los recursos pueden ser de los siguientes tipos: ■ fs: sistema de archivos. ■ Inherit-pkg-dir: directorio que hereda sus paquetes asociados de la zona global. ■ net: dispositivo de red. ■ device: dispositivos.

Módulo 3 • Planificación del entorno de OpenSolaris 35 Introducción a la administración de zonas Introducción a la administración de zonas Este ejercicio práctico es una introducción a la creación de zonas.

Resumen Se utilizan ejemplos detallados para enseñar el proceso de creación, instalación y arranque de una zona.

Nota – Este procedimiento no se aplica a una zona de marca lx.

36 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Introducción a la administración de zonas Para crear, instalar y arrancar una zona

1 Utilice el ejemplo siguiente para configurar una zona nueva:

Nota – El ejemplo siguiente utiliza una pila IP compartida, que es la predeterminada para una zona.

# zonecfg -z Apache Apache: No such zone configured Use ’create’ to begin configuring a new zone. zonecfg:Apache> create zonecfg:Apache> set zonepath=/export/home/Apache zonecfg:Apache> add net zonecfg:Apache:net> set address=192.168.0.50 zonecfg:Apache:net> set physical=bge0 zonecfg:Apache:net> end zonecfg:Apache> verify zonecfg:Apache> commit zonecfg:Apache> exit

2 Utilice el ejemplo siguiente para instalar y arrancar una zona nueva: # zoneadm -z Apache install Preparing to install zone . Creating list of files to copy from the global zone. Copying <6029> files to the zone. Initializing zone product registry. Determining zone package initialization order. Preparing to initialize <1038> packages on the zone. Initialized <1038> packages on zone. Zone is initialized. Installation of these packages generated warnings: .... The file contains a log of the zone installation.

Módulo 3 • Planificación del entorno de OpenSolaris 37 Introducción a la administración de zonas

Se crean los directorios necesarios. Ya puede arrancar la zona.

3 Visualice los directorios: # ls /export/home/Apache/root bin etc home mnt platform sbin tmp var dev export lib opt proc system usr Los paquetes no se reinstalan.

# /etc/mount /export/home/Apache/root/lib on /lib read only /export/home/Apache/root/platform on /platform read only /export/home/Apache/root/sbin on /sbin read only /export/home/Apache/root/usr on /usr read only /export/home/Apache/root/proc on proc read/write/setuid/nodevices/zone=Apache

4 Arranque la zona. # ifconfig -a lo0: flags=2001000849 mtu 8232 index 1 inet 127.0.0.1 netmask ff000000 bge0: flags=1004803 mtu 1500 index 2 inet 192.168.0.4 netmask ffffff00 broadcast 192.168.0.255 ether 0:c0:9f:61:88:c9 # zoneadm -z Apache boot # ifconfig -a lo0: flags=2001000849 mtu 8232 index 1 inet 127.0.0.1 netmask ff000000 lo0:1: flags=2001000849 mtu 8232 index 1 zone Apache inet 127.0.0.1 bge0: flags=1004803 inet 192.168.0.4 netmask ffffff00 broadcast 192.168.0.255 ether 0:c0:9f:61:88:c9 bge0:1: flags=1000803mtu 1500 index 2 zone Apache inet 192.168.0.50 netmask ffffff00 broadcast 192.168.0.255

5 Configure la zona e inicie sesión: # zlogin -C Apache [Connected to zone ’Apache’ pts/5]

38 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Introducción a la administración de zonas

# ifconfig -a lo0:2: flags=2001000849 mtu 8232 index 1 inet 127.0.0.1 netmask ff000000 bge0:2: flags=1000803 inet 192.168.0.50 netmask ffffff00 broadcast 192.168.0.255 # ping -s 192.168.0.50 64 bytes from 192.168.0.50: icmp_seq=0. time=0.146 ms # exit [Connection to zone ’Apache’ pts/5 closed]

Módulo 3 • Planificación del entorno de OpenSolaris 39 Virtualización del servidorWeb con zonas Virtualización del servidorWeb con zonas Cada zona tiene sus propias características, por ejemplo un nombre, direcciones IP,nombre de host, servicios de nombres, usuarios root y usuarios no root. De modo predeterminado, el sistema operativo se ejecuta en una zona global. El administrador puede virtualizar el entorno de ejecución definiendo una o más zonas no globales. Los servicios deredse pueden ejecutar limitando los posibles daños en caso de infracción de la seguridad. Dado que las zonas se implementan en el software, no están limitadas a la granularidad que establecen los límites del hardware. Las zonas ofrecen granularidad de la subCPU.

40 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Creación de zonas no globales Creación de zonas no globales Este ejercicio práctico muestra cómo un host físico admite dos conjuntos diferentes de grupos de usuarios de servidor Web.

Resumen El acceso simultáneo a ambos servidores Web se configura de modo que cada sistema y servidor Web quede protegido en caso de que uno de ellos peligre.

Módulo 3 • Planificación del entorno de OpenSolaris 41 Creación de zonas no globales Creación de dos zonas no globales

1 Cree una zona no global Apache1: # zonecfg -z Apache1 info zonepath: /export/home/Apache1 autoboot: false pool: inherit-pkg-dir: dir: /lib inherit-pkg-dir: dir: /platform inherit-pkg-dir: dir: /sbin inherit-pkg-dir: dir: /usr net: address: 192.168.0.100/24 physical: bge0

2 Cree una zona no global Apache2: # zonecfg -z Apache2 info zonepath: /export/home/Apache2 autoboot: false pool: inherit-pkg-dir: dir: /lib inherit-pkg-dir: dir: /platform inherit-pkg-dir: dir: /sbin inherit-pkg-dir: dir: /usr net: address: 192.168.0.200/24 physical: bge0

3 Inicie sesión en Apache1 e instale la aplicación: # zlogin Apache1 # zonename Apache1 # ls /Apachedir apache_1.3.9 apache_1.3.9-i86pc-sun-solaris2.270.tar #cd /Apachedir/apache_1.3.9 ; ./install-bindist.sh /local You now have successfully installed the Apache 1.3.9 HTTP server.

42 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Creación de zonas no globales

4 Inicie sesión en Apache2 e instale la aplicación: # zlogin Apache2 # zonename Apache2 # ls /Apachedir httpd-2.0.50 httpd-2.0.50-i386-pc-solaris2.8.tar # cd /Apachedir/httpd-2.0.50; ./install-bindist.sh /local You now have successfully installed the Apache 2.0.50 HTTP server.

5 Inicie la aplicación Apache1: # zonename Apache1 # hostname Apache1zone # /local/bin/apachectl start /local/bin/apachectl start: httpd started

6 Inicie la aplicación Apache2: # zonename Apache2 # hostname Apache2zone # /local/bin/apachectl start /local/bin/apachectl start: httpd started

7 En la zona global, edite el archivo /etc/hosts: # cat /etc/hosts # # Internet host table # 127.0.0.1 localhost 192.168.0.1 loghost 192.168.0.100 Apache1zone 192.168.0.200 Apache2zone

8 Abra un navegadorWeb y vaya a la dirección URL siguiente: http://apache1zone/manual/index.html

Módulo 3 • Planificación del entorno de OpenSolaris 43 Creación de zonas no globales

El servidor Web Apache1 está en funcionamiento.

9 Abra un navegadorWeb y vaya a la dirección URL siguiente:

10 http://apache2zone/manual/ El servidor Web Apache2 está en funcionamiento.

44 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Creación de zonas no globales Discusión El usuario final ve cada zona como un sistema diferente. Cada servidor Web tiene su propio servicio de nombres:

■ /etc/nsswitch.conf ■ /etc/resolv.conf

Si se produce un ataque en un servidor Web, queda limitado a su zona. Los conflictos de puertos ya no constituyen un problema.

Módulo 3 • Planificación del entorno de OpenSolaris 45 Creación de agrupaciones de almacenamiento ZFS y sistemas de archivos Creación de agrupaciones de almacenamiento ZFS y sistemas de archivos Cada agrupación de almacenamiento ZFS se compone de uno o más dispositivos virtuales, que describen la disposición del almacenamiento físico y sus características de errores.

En este módulo, en primer lugar trataremos la configuración de agrupaciones de almacenamiento duplicadas. A continuación, se indica cómo crear una configuración RAID-Z.

46 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Creación de agrupaciones de almacenamiento ZFS duplicadas Creación de agrupaciones de almacenamiento ZFS duplicadas El objetivo de este ejercicio práctico es crear y enumerar la agrupación de almacenamiento duplicada mediante el comando zpool.

Para obtener información sobre cómo determinar si su entorno requiere la configuración de una agrupación de almacenamiento ZFS duplicada o RAID-Z, vaya a: http://www.solarisinternals.com/ wiki/index.php/ZFS_Best_Practices_Guide

Resumen ZFS es realmente sencillo de utilizar. A continuación, va a crear su primera agrupación.

Módulo 3 • Planificación del entorno de OpenSolaris 47 Creación de agrupaciones de almacenamiento ZFS duplicadas Para crear agrupaciones de almacenamiento duplicadas

1 Abra una ventana de terminal.

2 Cree una agrupación de almacenamiento duplicada denominada tank. A continuación, visualice la información sobre la agrupación. # zpool create tank mirror c1t1d0 c2t2d0 # zpool status tank pool: tank state: ONLINE scrub: none requested config:

NAME STATE READ WRITE CKSUM tank ONLINE 0 0 0 mirror ONLINE 0 0 0 c1t1d0 ONLINE 0 0 0 c2t2d0 ONLINE 0 0 0

errors: No known data errors La capacidad de los discos c1t1d0 y c2t2d0 es de 36 Gbytes cada uno. Dado que los discos están duplicados, la capacidad total de la agrupación refleja el tamaño aproximado de unode los discos. Los metadatos de la agrupación consumen una pequeña cantidad del espacio del disco. Por ejemplo:

# zpool list NAME SIZE USED AVAIL CAP HEALTH ALTROOT tank 33.8G 89K 33.7G 0% ONLINE -

48 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Creación de sistemas de archivos ZFS como directorios de inicio Creación de sistemas de archivos ZFS como directorios de inicio El objetivo de este ejercicio práctico es aprender a configurar un sistema de archivos ZFS como varios directorios de inicio.

Al utilizar las funciones del sistema de archivos ZFS, disponibles en el proyecto OpenSolaris, puede simplificar el entorno de desarrollo del núcleo implementado instantáneas y sus funciones de inversión.

Resumen Utilizaremos el comando zfs para crear un sistema de archivos y definir su punto de montaje.

Módulo 3 • Planificación del entorno de OpenSolaris 49 Creación de sistemas de archivos ZFS como directorios de inicio Para crear sistemas de archivos ZFS como directorios de inicio

1 Visualice el sistema de archivos ZFS predeterminado creado automáticamente al crear la agrupación de almacenamiento. # zfs list NAME USED AVAIL REFER MOUNTPOINT tank 86K 33.2G 24.5K /tank

2 Cree el sistema de archivos tank/home: # zfs create tank/home

3 A continuación, defina el punto de montaje para el sistema de archivos tank/home: # zfs set mountpoint=/export/home tank/home

4 Por último, cree los sistemas de archivos tank/home para todos los desarrolladores: # zfs create tank/home/developer1 # zfs create tank/home/developer2 # zfs create tank/home/developer3 # zfs create tank/home/developer4 La propiedad mountpoint se hereda como prefijo de nombre de ruta. Es decir, tank/home/developer1 se monta automáticamente en /export/home/developer1 porque tank/home está montado en /export/home.

5 Confirme que se hayan creado los sistemas de archivos ZFS: # zfs list NAME USED AVAIL REFER MOUNTPOINT tank 246K 33.2G 26.5K /tank tank/home 128K 33.2G 29.5K /export/home tank/home/developer1 24.5K 33.2G 24.5K /export/home/developer1 tank/home/developer2 24.5K 33.2G 24.5K /export/home/developer2 tank/home/developer3 24.5K 33.2G 24.5K /export/home/developer3

50 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Creación de sistemas de archivos ZFS como directorios de inicio tank/home/developer4 24.5K 33.2G 24.5K /export/home/developer4

6 Realice una instantánea recursiva del sistema de archivos tank/home. A continuación, visualice la información de instantánea: # zfs snapshot -r tank/home@today # zfs list NAME USED AVAIL REFER MOUNTPOINT tank 252K 33.2G 26.5K /tank tank/home 128K 33.2G 29.5K /tank/home tank/home@today 0 - 29.5K - tank/home/developer1 24.5K 33.2G 24.5K /tank/home/developer1 tank/home/developer1@today 0 - 24.5K - tank/home/developer2 24.5K 33.2G 24.5K /tank/home/developer2 tank/home/developer2@today 0 - 24.5K - tank/home/developer3 24.5K 33.2G 24.5K /tank/home/developer3 tank/home/developer3@today 0 - 24.5K - tank/home/developer4 24.5K 33.2G 24.5K /tank/home/developer4 tank/home/developer4@today 0 - 24.5K - Para más información, consulte zfs.1m.

Módulo 3 • Planificación del entorno de OpenSolaris 51 Creación de una configuración RAID-Z Creación de una configuración RAID-Z El objetivo de este ejercicio práctico es mostrarle cómo configurar RAID-Z.

Resumen Si desea crear una configuración RAID-Z como alternativa a una configuración de agrupación de almacenamiento duplicada si necesita maximizar el espacio en disco.

52 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Creación de una configuración RAID-Z Para crear una configuración de RAID-Z

1 Abra una ventana de terminal.

2 Cree una agrupación con un único dispositivo RAID-Z compuesto por 5 discos. A continuación, visualice la información sobre la agrupación de almacenamiento. # zpool create tank raidz c1t1d0 c2t2d0 c3t3d0 c4t4d0 c5t5d0 # zpool status tank pool: tank state: ONLINE scrub: none requested config:

NAME STATE READ WRITE CKSUM tank ONLINE 0 0 0 raidz1 ONLINE 0 0 0 c1t1d0 ONLINE 0 0 0 c2t2d0 ONLINE 0 0 0 c3t3d0 ONLINE 0 0 0 c4t4d0 ONLINE 0 0 0 c5t5d0 ONLINE 0 0 0 errors: No known data errors Los discos pueden especificarse utilizando su nombre abreviado o la ruta completa. Por ejemplo, /dev/dsk/c4t4d0 es idéntico a c4t4d0. Es posible utilizar segmentos de disco para configuraciones de agrupaciones duplicadas y de almacenamiento RAID-Z, pero no se recomiendan para entornos de producción. Para obtener más información sobre el uso de ZFS en entornos de producción, vaya a: http://www.solarisinternals.com/ wiki/index.php/ZFS_Best_Practices_Guide.

Módulo 3 • Planificación del entorno de OpenSolaris 53 54 MÓDULO4 4 Consolidaciones de userland

Objetivos El objetivo de este módulo es introducirle a las consolidaciones userland de OpenSolaris. En general, puede considerar las consolidaciones userland como externas al núcleo y como componentes con los que interactúan los usuarios. Cada una de las consolidaciones siguientes transfieren archivos de origen al sitio Web opensolaris.org o al centro de descargas. Para acceder a cada consolidación, consulte la siguiente dirección URL: http://opensolaris.org/os/downloads/

55 Consolidaciones userland y descripciones Consolidaciones userland y descripciones

Servidor de aplicaciones Servidor de aplicaciones Glassfish

Herramientas de La biblioteca matemática del sistema, la productos de desarrollo biblioteca de medios, la biblioteca de (DevPro) microtareas, SCCS y make y las bibliotecas de tiempo de ejecución C++.

Documentación (Docs) Documentación técnica de desarrollo y administración.

Globalización (G11N) Internacionalización y localización.

Instalación (Install) Admisión de instalación y herramientas de empaquetado.

Java Desktop (JDS) Solución de software de escritorio empresarial segura y completa.

Plataforma Java, Hay disponibles binarios para Java Standard Edition (Java Development Kit (JDK) y Java Runtime SE) Environment (JRE).

Páginas del comando Código fuente para las páginas del manual de man referencia de SunOS.

Message Queue Sun Java System Message Queue.

Almacenamiento de red Compatibilidad con dispositivos de (NWS) almacenamiento de red.

SFW (Solaris FreeWare) Software de código abierto integrado con Solaris/OpenSolaris.

Compatibilidad con La consolidación de gráficos SPARC tiene gráficos SPARC disponibles controladores en formato binario.

Pruebas Herramientas de prueba y conjuntos de pruebas OpenSolaris.

56 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Consolidaciones userland y descripciones

Sistema de ventanas X Software X11. (X11)

Módulo 4 • Consolidaciones de userland 57 58 MÓDULO5 5 Características principales del sistema operativo Solaris

Objetivos La finalidad de este módulo es describir las características principales del sistema operativo Solaris y cómo han cambiado de forma sustancial el funcionamiento del sistema operativo.

Recursos adicionales OpenSolaris Development Process; http://www.opensolaris.org/ os/community/onnv/os_dev_process/

C Style and Coding Standards for SunOS; http://www.opensolaris.org/ os/community/documentation/getting_started_docs/

59 Proceso de desarrollo y estilo de código Proceso de desarrollo y estilo de código Los pasos del proceso de desarrollo y el estilo de código que se utilizan en la consolidación OS/Net (ON) se utilizan para ofrecer los principales componentes del sistema operativo y de red a Solaris. ON contiene el código del núcleo y todas las plataformas (en todas las arquitecturas), la mayoría de los controladores, los sistemas de archivos, las bibliotecas principales y los comandos básicos de un sistema Solaris.El proceso de desarrollo del proyecto OpenSolaris sigue este procedimiento de alto nivel: 1. Idea En primer lugar, alguien tiene una idea para realizar una mejora o una queja sobre un defecto. Busque un error, registre uno nuevo o solicite una mejora en http://bugs.opensolaris.org/. A continuación, anuncie su solicitud a los demás desarrolladores en la lista de correo pertinente. La posibilidad de anunciar la solicitud aporta una serie de ventajas: ■ Acelera el proceso de debate sobre el cambio o la mejora ■ Determina la complejidad de los cambios propuestos ■ Evalúa el interés de la comunidad ■ Identifica los posibles miembros del equipo 2. Diseño En la fase de diseño se decide si es necesario revisar un diseño formal. Si lo es, siga estos pasos: ■ Identifique los revisores del diseño y la arquitectura ■ Escriba un documento de diseño ■ Escriba un plan de prueba ■ Lleve a cabo revisiones de diseño y obtenga la aprobación correspondiente 3. Implementación La fase de implementación se compone de lo siguiente:

60 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Proceso de desarrollo y estilo de código

■ Escritura del código de acuerdo con las políticas y normas Descargue C Style and Coding Standards for SunOS aquí:http://www.opensolaris.org/ os/community/documentation/getting_started_docs/. ■ Escritura de los conjuntos de pruebas ■ Aprobación de las diferentes pruebas de unidad y preintegración ■ Escritura o actualización de la documentación del usuario, si se requiere ■ Identificación de los revisores del código para preparar la integración 4. Integración La integración tiene lugar una vez se han completado todas las revisiones y concedido los permisos.

En la fase de integración se comprueba si se han llevado a cabo todas las acciones previstas, para lo que se revisa el código, la documentación y la finalización.

El documento del proceso formal de OpenSolaris describe los pasos anteriores de forma más detallada, con diagramas de flujo que ilustran las fases de desarrollo. También especifica los siguientes valores básicos y principios de diseño que se aplican al desarrollo de código fuente para el proyecto OpenSolaris:

■ Fiabilidad: OpenSolaris debe funcionar correctamente y ofrecer resultados precisos sin perder ni dañar datos. ■ Disponibilidad: los servicios deben configurarse como reiniciables en caso de error de la aplicación, y OpenSolaris debe poder recuperarse de errores de hardware que no sean graves.

Módulo 5 • Características principales del sistema operativo Solaris 61 Proceso de desarrollo y estilo de código

■ Facilidad de mantenimiento: debe poderse diagnosticar tanto los errores graves como los transitorios y, cuando sea posible, automatizar el diagnóstico. ■ Seguridad: la seguridad de OpenSolaris debe integrarse en el sistema operativo y contar con mecanismos para auditar los cambios que se realizan en el sistema y la persona que los lleva a cabo. ■ Rendimiento: el rendimiento de OpenSolaris debe ser insuperable en comparación con otros sistemas operativos que se ejecutan en entornos idénticos. ■ Facilidad de uso: debe permitir la administración de componentes individuales, software o hardware de manera coherente y directa. ■ Compatibilidad: los nuevos subsistemas e interfaces deben poder ampliarse y admitir nuevas versiones para incorporar futuros cambios y mejoras sin que peligre la compatibilidad. ■ Facilidad de mantenimiento: OpenSolaris debe generarse de modo que las subrutinas comunes se combinen en módulos de núcleos o bibliotecas que los pueda utilizar un número aleatorio de usuarios. ■ Neutralidad de plataforma: OpenSolaris debe seguir teniendo una plataforma neutra; asimismo, deben diseñarse abstracciones de nivel reducidas teniendo en cuenta diferentes y futuras plataformas.

Consulte http://www.opensolaris.org/ os/community/onnv/os_dev_process/ para obtener información más detallada acerca del proceso que se sigue para el desarrollo colaborativo de código de OpenSolaris.

Al igual que otros muchos proyectos, OpenSolaris aplica un estilo de código al código que se aporta, sea cual sea su origen. Este estilo se describe detalladamente en http://opensolaris.org/os/community/onnv/.

62 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Proceso de desarrollo y estilo de código

La distribución de OpenSolaris incluye dos herramientas para comprobar numerosos elementos del estilo de código. Estas herramientas son; cstyle(1), para verificar el cumplimiento del código C con la mayoría de las normas de estilo, y hdrchk(1), para comprobar el estilo de las cabeceras de C y C++.

Módulo 5 • Características principales del sistema operativo Solaris 63 Información general Información general Una vez considerados el entorno de desarrollo, los procesos y valores que aplican los desarrolladores en el proceso de ingeniería, describiremos más detalladamente las funciones del sistema operativo que ejemplifican el rendimiento, la seguridad, la capacidad de servicio y la manejabilidad: ■ Rendimiento ■ FireEngine ■ Nemo ■ Crossbow ■ Seguridad ■ Minimización de los privilegios ■ Filtros de paquetes ■ Zonas ■ Zonas de marca (BrandZ) ■ Facilidad de mantenimiento ■ Recuperación automática predecible ■ Tecnología Dynamic Tracing (DTrace) ■ Modular Debugger (MDB) ■ Capacidad de control ■ Utilidad de gestión de servicios (SMF) ■ ZFS

FireEngine El enfoque de FireEngine en Solaris 10 combina todas las capas de protocolo en un módulo STREAMS de subproceso múltiple. En el módulo combinado, en lugar de bloqueos de estructura por datos, se utiliza un mecanismo de sincronización por CPU denominado "perímetro vertical".El"perímetro vertical" se implementa utilizando una abstracción de cola de serialización

64 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Información general denominada "squeue". Cada squeue está vinculada a una CPU, y cada conexión está a su vez vinculada a una squeue que proporciona la sincronización y exclusión mutua necesaria para las estructuras de datos específicas de la conexión.

Sincronización Dado que la pila cuenta con múltiples subprocesos (y bloquea la serialización por CPU que aplica el perímetro vertical), utiliza un esquema basado en referencias para asegurar que haya una instancia de conexión cuando se necesite. Para una conexión TCP establecida, se garantiza la existencia de tres referencias. Cada capa de protocolo cuenta con una referencia en la instancia (una para TCP e IP) y el clasificador tiene una referencia al tratarse de una conexión establecida. Cada vez que llega un paquete para la conexión y el clasificador consulta la instancia de conexión, se coloca una referencia adicional, que se suelta cuando la capa de protocolo termina de procesar el paquete.

TCP,IP y UDP El sistema operativo Solaris 10 proporciona la misma vista para TCP que las versiones anteriores, es decir, TCP aparece como dispositivo de copia pero en realidad es un compuesto, con el código TCP e IP combinado en un único módulo D_MP STREAMS. La parte operativa de TCP está completamente protegida por el perímetro vertical que se activa mediante las primitivas de squeue. FireEngine cambia la interfaz entre TCP e IP desde la interfaz de transferencia de mensajes basada en STREAMS hasta una interfaz funcional basada en llamadas, ambas en las rutas de control y datos.

Hay un módulo UDP completo con múltiples subprocesos en ejecución en el mismo dominio de protección que IP.Aunque UDP e IP se ejecutan en el mismo dominio de protección, siguen siendo módulos STREAMS separados. Por tanto, el

Módulo 5 • Características principales del sistema operativo Solaris 65 Información general

establecimiento de STREAMS se mantiene sin cambios y siempre se coloca una instancia del módulo UDP por encima de IP.La plataforma de Solaris 10 permite los siguientes modos de establecimiento: ■ Normal: IP se abre primero y luego se coloca encima UDP. Es la acción predeterminada que tiene lugar cuando se abre un dispositivo o socket UDP. ■ SNMP: UDP se coloca encima de un módulo que no sea IP. Cuando esto ocurre, sólo se admite semántica SNMP.

GLDv3 El software Solaris 10 introduce una nueva estructura de controladores de dispositivos denominada GLDv3 junto con la nueva pila. La mayoría de los controladores de dispositivos se ha pasado a esta estructura, y todos los controladores de dispositivos de 10 Gb y futuros se basarán en ella. Esta estructura también proporciona una capa DLPI basada en STREAMS para la compatibilidad con versiones anteriores (para permitir que los módulos externos que no sean IP sigan funcionando). La arquitectura GLDv3 virtualiza la capa dos de la pila de red. Ya no existe una correspondencia uno a uno entre las interfaces de red y los dispositivos.

Consulte el proyecto Nemo en opensolaris.org para obtener más información sobre la estructura, el módulo de servicios MAC y el módulo de servicios de vínculo de datos.

Virtualización El proyecto Crossbow crea pilas virtuales para cualquier servicio (HTTP,HTTPS, FTP,NFS, etc.), protocolo (TCP,UDP, SCTP,etc.) o tecnología de . Las pilas virtuales se separan mediante un motor de clasificación H/W para que el tráfico de una pila no repercuta en otras pilas virtuales. A cada pila virtual se puede asignar su propia

66 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Información general prioridad y su propio ancho de banda en una NIC compartida sin que ello perjudique al rendimiento del sistema o al servicio/contenedor. La arquitectura administra dinámicamente los recursos de prioridad y ancho de banda, y puede proporcionar una mejor protección contra ataques de denegación de servicios dirigidos a un servicio o contenedor específico aislando el impacto sólo a dicho servicio o contenedor.

Minimización de los privilegios

Históricamente, UNIX® ha tenido siempre un modelo de privilegios de "todo o nada" que impone las restricciones siguientes:

■ No existe modo alguno de limitar los privilegios de usuarios root ■ Los usuarios que no sean root no pueden realizar operaciones con privilegios ■ Las aplicaciones que sólo necesitan algunas operaciones con privilegios deben ejecutarse como root ■ Los privilegios de root se confían a muy pocos, y entre ellos no hay casi ningún estudiante

En el sistema operativo Solaris, hemos desarrollado privilegios avanzados. Permiten la ejecución de aplicaciones y el uso o acceso a funciones justo con los privilegios que se necesitan. El privilegio mínimo permite a los estudiantes completar su trabajo, participar en investigaciones y mantener una parte de la infraestructura del departamento o el campus.

Módulo 5 • Características principales del sistema operativo Solaris 67 Información general Filtros de paquetes El filtro IP de Solaris proporciona un filtrado de paquetes con estado y traducción de direcciones de red (NAT). El filtro IP de Solaris se deriva de software de filtro IP de código abierto. El filtro IP puede filtrar por dirección IP,puerto, protocolo o interfaz de red de acuerdo con las reglas de filtros.

Filtro IP La API de enlaces de filtros de paquetes (PFHooks) seha introducido desde Solaris 10 Update 4, para reemplazar la implementación basada en STREAMS del filtro IP.Con el uso de la estructura PFHooks, el rendimiento del software cortafuegos como el filtro IP se ha mejorado considerablemente. PFhooks también permite interceptar el tráfico en bucle y entre zonas. El software cortafuegos deotros proveedores se desarrolla y registra con la API PFHooks utilizando el enlace net_register_hook(info, event, hook);.

Activación de filtros de paquetes sencillos El objetivo de este ejercicio es aprender sobre los filtros de paquetes. El filtro IP de Solaris se instala con el sistema operativo Solaris. Sin embargo, los filtros de paquetes no están activos de modo predeterminado. El filtro IP puede filtrar por dirección IP,puerto, protocolo o interfaz de red de acuerdo con las reglas de filtros. A continuación se incluye un ejemplo de regla de filtro: block in on ce0 proto tcp from 192.168.0.0/16 to any port = 23

Para utilizar el filtro IP de Solaris, especifique las reglas de filtros en el archivo /etc/ipf/ipf.conf. A continuación, active y reinicie el servicio svc:network/ipfilter utilizando el comando svcadm.

68 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Información general

Nota – También puede utilizar el comando ipf con los conjuntos de reglas.

El filtro IP de Solaris puede llevar a cabo la traducción de direcciones de red (NAT) para una dirección de origen o destino de acuerdo con las reglas NAT. A continuación se incluye un ejemplo de regla NAT: map ce0 192.168.1.0/24 -> 10.1.0.0/16 Para utilizar la traducción de direcciones de red, especifique las reglas NAT en el archivo /etc/ipf/ipnat.conf.A continuación, active y reinicie el servicio svc:/network/ipfilter utilizando el comando svcadm.

Nota – También puede utilizar el comando ipnat para trabajar con conjuntos de reglas.

Reglas de filtros de paquetes de ejemplo En esta sección se incluyen varios ejemplos de sintaxis de reglas de filtros. Invoque las reglas agregándolas al archivo /etc/ipf/ipf.conf. A continuación, active el filtro IP de Solaris y rearranque el equipo tal como se detalla en el ejercicio anterior. Registre en le0 todos los paquetes entrantes que cuenten con opciones de IP. log in on le0 from any to any with ipopts Bloquee en le0 los paquetes entrantes que estén fragmentados y sean demasiado pequeños para poder llevar a cabo una comparación significativa. Esta acción sólo se aplica alos paquetes TCP que puedan carecer de indicadores/puertos (en función de la parte del fragmento que vea).

Módulo 5 • Características principales del sistema operativo Solaris 69 Información general

block in log quick on le0 from any to any with short frag

Registre todos los paquetes TCP entrantes con el conjunto de indicadores SYN (solamente).

Nota – Si se trata de un paquete TCP entrante con el conjunto de indicadores SYN y cuenta con opciones de IP,esta regla y la anterior lo registrarían por duplicado.

log in on le0 proto tcp from any to any flags S/SA

Bloquee y registre las instrucciones ICMP entrantes inaccesibles. block in log on le0 proto icmp from any to any icmp-type unreach

Bloquee y registre en le0 los paquetes UDP entrantes que se dirijan al puerto 2049 (el puerto NFS).

block in log on le0 proto udp from any to any port = 2049

Admita rápidamente la transferencia de paquetes de un par de hosts concreto.

pass in quick from any to 10.1.3.2/32 pass in quick from any to 10.1.0.13/32 pass in quick from 10.1.3.2/32 to any pass in quick from 10.1.0.13/32 to any

Bloquee y detenga la coincidencia de cualquier paquete con opciones de IP.

block in quick on le0 from any to any with ipopts

Permite la transferencia de cualquier paquete.

pass in from any to any

70 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Información general

Bloquee los paquetes UDP entrantes destinados a estas subredes.

block in on le0 proto udp from any to 10.1.3.0/24 block in on le0 proto udp from any to 10.1.1.0/24 block in on le0 proto udp from any to 10.1.2.0/24

Bloquee cualquier paquete TCP entrante que sólo tengan el conjunto de indicadores SYN y estén destinados a estas subredes. block in on le0 proto tcp from any to 10.1.3.0/24 flags S/SA block in on le0 proto tcp from any to 10.1.2.0/24 flags S/SA block in on le0 proto tcp from any to 10.1.1.0/24 flags S/SA

Bloquee cualquier paquete ICMP entrante destinado a estas subredes.

block in on le0 proto icmp from any to 10.1.3.0/24 block in on le0 proto icmp from any to 10.1.1.0/24 block in on le0 proto icmp from any to 10.1.2.0/24

Zonas Una zona es una abstracción virtual del sistema operativo que ofrece un entorno protegido en el que se ejecutan las aplicaciones. Las aplicaciones se protegen unas de otras para aislar los errores de software. Para facilitar la administración de múltiples aplicaciones y sus entornos, coexisten en una instancia del sistema operativo y normalmente se gestionan como una entidad.

Ciertas aplicaciones que normalmente se ejecutan como root o con algunos privilegios quizá no se ejecuten dentro de una zona si dicha ejecución depende de su capacidad para acceder o cambiar algún recurso global. Un ejemplo sería la posibilidad de cambiar el reloj del sistema. Las pocas aplicaciones que se

Módulo 5 • Características principales del sistema operativo Solaris 71 Información general

ajustan a estos criterios pueden necesitar que las aplicaciones se ejecuten correctamente dentro de una zona o, en ocasiones, deben seguir utilizándose dentro de la zona global.

A continuación se establecen algunas pautas:

■ Una aplicación que accede a la red y los archivos y no lleva a cabo ninguna tarea adicional de E/S debería funcionar sin problemas. ■ Las aplicaciones que requieren acceso directo a determinados dispositivos, por ejemplo, una partición de disco, suelen funcionar si la zona se ha configurado correctamente. Sin embargo, en ocasiones esto puede afectar a la seguridad. ■ Es posible que se deban modificar las aplicaciones que requieren acceso directo a estos dispositivos para que funcionen correctamente. Por ejemplo, /dev/kmem oun dispositivo de red. Las aplicaciones deben utilizar uno de los múltiples servicios IP.

Las zonas se pueden combinar con las utilidades de administración de recursos que incluye OpenSolaris para ofrecer entornos aislados más completos. Mientras que la zona proporciona la seguridad, el espacio de nombre y el aislamiento de errores, se pueden utilizar las utilidades de administración de recursos para impedir que los procesos de una zona utilicen demasiados recursos de un sistema o para garantizarles cierto nivel de servicio. De forma conjunta, las zonas y la administración de recursos se suelen denominar "contenedores".

Consulte http://opensolaris.org/os/community/zones/faq para ver la respuesta a una gran cantidad de preguntas frecuentes sobre las zonas y vínculos a la documentación más reciente sobre administración.

72 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Información general

Las zonas proporcionan entornos protegidos para las aplicaciones de Solaris.Mediante el uso de BrandZ en el proyecto OpenSolaris hay disponibles entornos de ejecución independientes y protegidos.

Zonas de marca (BrandZ) BrandZ es un sistema que amplía la infraestructura de las zonas para crear zonas de marca, que son zonas que contienen entornos operativos no nativos. Una zona de marca puede resultar tan sencilla como un entorno en que las utilidades estándar de Solaris se sustituyen por sus equivalentes GNU, o tan compleja como un espacio de usuario completo de Linux.

BrandZ amplía la infraestructura de zonas en el espacio del usuario de los modos siguientes:

■ Una marca es un atributo de una zona, que se define durante la configuración de la misma. ■ Cada marca tiene su propia rutina de instalación, que permite instalar un determinado grupo de software en la zona de marca. ■ Cada marca puede proporcionar secuencias previas y posteriores al inicio que permitan al usuario configurar durante el arranque. ■ Las herramientas zonecfg y zoneadm pueden definir e informar del tipo de marca de una zona.

BrandZ proporciona un conjunto de puntos de interposición en el núcleo:

■ Estos puntos se encuentran en la ruta syscall, la ruta de carga del proceso, la ruta de creación de divisiones, etc. ■ Estos puntos de interposición sólo se aplican a los procesos de una zona de marca.

Módulo 5 • Características principales del sistema operativo Solaris 73 Información general

■ En cada uno de estos puntos, una marca puede decidir si el comportamiento estándar del sistema operativo Solaris se complementa o se sustituye. ■ Las marcas fundamentalmente distintas pueden requerir nuevos puntos de interposición.

La marca lx permite que las aplicaciones binarias de Linux se ejecuten sin modificaciones en Solaris, dentro de zonas que ejecutan un espacio de usuario completo de Linux. La marca lx permite que el software de usuario de Linux se ejecute en una máquina con un núcleo de OpenSolaris, e incluye las herramientas necesarias para instalar una distribución CentOS o Red Hat Enterprise Linux dentro de una zona en un sistema Solaris. La marca lx se ejecuta en sistemas x86/x64 iniciados con un núcleo de 32 o 64 bits. Sea cual sea el núcleo subyacente, sólo se pueden ejecutar aplicaciones Linux de 32 bits. Esta función sólo está disponible actualmente para arquitecturas x86 y AMD x64. Sin embargo, pasar a SPARC podría ser un proyecto interesante para la comunidad ya que BrandZ lx es todavía algo que se está desarrollando.

Consulte http://opensolaris.org/os/community/brandz/install para ver las instrucciones y los requisitos de instalación.

El proyecto OpenSolaris afronta los desafíos exclusivos del desarrollo de sistemas operativos y las pruebas para el rendimiento de las aplicaciones utilizando funciones como las zonas.

Redes de zonas Las zonas de Solaris se pueden designar como: ■ Zona de IP exclusiva ■ Zona de IP compartida

74 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Información general

Las zonas de IP exclusiva tienen sus propias pilas de IP y pueden tener sus propias interfaces físicas. Una zona de IP exclusiva también puede tener sus propias interfaces VLAN. La configuración de zonas de IP exclusiva es la misma que ladeun equipo físico.

Las zonas de IP compartida comparten la pila de IP con la zona global, de modo que las zonas de IP compartida se aíslan de la configuración de los dispositivos, el encaminamiento, etc.A cada zona de IP compartida se pueden asignar direcciones IPv4/IPv6. Cada zona de IP compartida también tiene su propio espacio de puerto. Las aplicaciones se pueden vincular a INADDR_ANY y sólo recibir tráfico para esa zona.

Ninguno de los dos tipos de zonas puede ver el tráfico de otras zonas. Los paquetes que provienen de una zona tienen una dirección de origen que pertenece a dicha zona. Una zona de IP compartida sólo puede enviar paquetes en una interfaz en la que tenga una dirección. Una zona de IP compartida sólo puede utilizar un encaminador predeterminado si se puede acceder a él directamente desde la zona. El encaminador predeterminado debe encontrarse en la misma subred IP que la zona.

Las zonas de IP compartida no pueden modificar su configuración de red o su tabla de encaminamiento, yno pueden ver la configuración de otras zonas. /dev/ipno está presente en la zona de IP compartida. En lugar de ello, los agentes SNMP deben abrir /dev/arp. Varias zonas de IP compartida pueden compartir una dirección de emisión y pueden unirse al mismo grupo multidifusión.

Las zonas de IP compartida tienen las siguientes limitaciones de red: ■ No es posible colocar una interfaz física dentro de una zona. ■ IPFilter no trabaja entre zonas. ■ No hay protocolo DHCP para las direcciones IP de las zonas.

Módulo 5 • Características principales del sistema operativo Solaris 75 Información general

■ No hay encaminamiento dinámico.

Las zonas de IP exclusiva no tienen las limitaciones anteriores, y pueden cambiar su configuración de red o tabla de encaminamiento dentro de la zona. /dev/ip está presente en la zona de IP exclusiva.

Identidad de zonas, visibilidad de la CPU y empaquetamiento Cada zona controla su nombre de nodo, zona horaria y servicios de nombres como LDAP y NIS. sysidtool permite configurarlos. Si hay distintos archivos /etc/passwd, significa que los privilegios de root se pueden delegar a la zona. Los ID de usuario se pueden asignar a diferentes nombres cuando los dominios son distintos.

De modo predeterminado, todas las zonas ven todas las CPU. La vista restringida se activa de forma automática cuando se habilitan las agrupaciones de recursos.

Las zonas pueden agregar sus propios paquetes. Se pueden crear parches para esos paquetes. Los parches del sistema se aplican en la zona global. Por tanto, en las zonas no globales la zona inicia automáticamente -s para aplicar el parche. El paquete SUNW_PKG_ALLZONES debe mantenerse de forma coherente entre la zona global y todas las zonas no globales. SUNW_PKG_HOLLOW hace que el nombre del paquete aparezca en las zonas no globales (NGZ) por motivos de dependencia, pero no se instala el contenido.

Dispositivos de zonas Cada zona tiene sus propios dispositivos. Las zonas ven un subconjunto de pseudodispositivos seguros en su directorio /dev. Las aplicaciones hacen referencia a la ruta lógica de un dispositivo presentado en /dev. El directorio /dev existe en las

76 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Información general zonas no globales, pero no el directorio /devices.Los dispositivos como random, console y null son seguros, pero otros como /dev/kmem no lo son.

Las zonas pueden modificar los permisos de sus dispositivos, pero no pueden emitir mknod(2). Los archivos de dispositivos físicos como los de los discos sin procesar se pueden colocar en una zona tomando determinadas precauciones. Las zonas pueden compartir dispositivos, pero es necesario adoptar ciertas medidas de seguridad.

Por ejemplo, quizá tenga dispositivos que desee asignar a zonas específicas. Si se permite a los usuarios sin privilegios accedera los dispositivos de bloques, éstos se podrían utilizar para crear una situación crítica del sistema, reiniciar el bus u otras acciones malintencionadas. Si se coloca un dispositivo físico en más de una zona, puede crearse un canal oculto entre las zonas. Las aplicaciones de zonas globales que utilizan dichos dispositivos pueden provocar que una zona no global dañe los datos o los ponga en peligro.

Recuperación automática predecible La tecnología de reparación preventiva Predictive Self-Healing se implantó de dos modos en el sistema operativo Solaris 10. En esta sección se describen las nuevas tecnologías Fault Management Architecture y Services Management Facility que componen la tecnología de reparación preventiva.

Fault Management Architecture (FMA) El sistema operativo Solaris proporciona una nueva arquitectura, FMA, para generar controles de errores con capacidad de recuperación, telemetría de errores, software de

Módulo 5 • Características principales del sistema operativo Solaris 77 Información general

diagnóstico automatizado, agentes de respuestas y un modelo coherente de errores del sistema para la pila de tareas de administración. Muchas partes de Solaris ya participan en la arquitectura FMA, incluida la CPU y el control de errores de la memoria para UltraSPARC III y IV, los adaptadores de bus PCI UltraSPARC y Opteron. Se están desarrollando una serie de proyectos, incluida la compatibilidad total para la CPU, la memoria y los errores de E/S en Opteron, la conversión de controladores de dispositivos clave y la integración con varias pilas de administración. Cuando se convierte un subsistema para participar en la administración de errores, el control de errores se puede recuperar para que el sistema pueda seguir funcionando a pesar del error, y se producen eventos de telemetría que generan de forma automatizada un diagnóstico y una respuesta. La arquitectura y las herramientas de administración de errores permiten desarrollar contenido de autorrecuperación para los errores de software y hardware, para recursos del sistema tanto microscópicos como macroscópicos. Todo con una única vista simplificada para los administradores y el software de administración del sistema. Consulte http://opensolaris.org/os/community/fm para obtener información sobre cómo participar en la comunidad de administración de errores o descargar la base de información de gestión MIB que se está desarrollando.

DynamicTracing (DTrace) DTrace proporciona una potente infraestructura que permite a los administradores, desarrolladores y personal de servicio responder de forma concisa a las preguntas mas diversas sobre el comportamiento del sistema operativo y los programas del usuario. DTrace permite: ■ Permitir y administrar dinámicamente miles de sondeos

78 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Información general

■ Asociar dinámicamente predicados y acciones con sondeos ■ Administrar dinámicamente búfers de trama y gastos de sondeos ■ Examinar los datos de rastreo de un sistema activo o un volcado del sistema ■ Implementar nuevos proveedores de datos de rastreo que se conecten a DTrace ■ Implementar consumidores de datos de rastreo que proporcionen presentaciones de datos ■ Implementar herramientas que configuren los sondeos de DTrace

Encontrará las páginas de la comunidad de DTrace en la dirección siguiente: http://opensolaris.org/os/community/dtrace.

Además de DTrace, el proyecto OpenSolaris ofrece funciones de depuración para los tipos de desarrollo de bajo nivel, por ejemplo, el desarrollo de controladores de dispositivos.

Modular Debugger (MDB) MDB es un depurador que facilita el análisis de problemas que requieren funciones de depuración de bajo nivel, el examen de archivos núcleo y el lenguaje ensamblador para diagnosticar y corregir. Generalmente, los desarrolladores de núcleos y dispositivos se basan en mdb para determinar el motivo y el lugar donde se produce un error de código.

MDB está disponible en forma de dos comandos que comparten funciones comunes: mdb y kmdb. Puede utilizar el comando mdb de forma interactiva o en secuencias para depurar procesos activos del usuario, archivos de núcleo de procesos del usuario, volcados del núcleo, el sistema activo, archivos de

Módulo 5 • Características principales del sistema operativo Solaris 79 Información general

objetos y otros archivos. Puede utilizar el comando kmdb para depurar el núcleo del sistema operativo activo y los controladores de dispositivos cuando también deba controlar y detener la ejecución del núcleo.

Existe una comunidad activa para MDB. En ella puede formular preguntas a expertos, o leer conversaciones anteriores y preguntas habituales. Consulte http://opensolaris.org/os/community/mdb.

Sistema de archivos ZFS Los sistemas de archivos ZFS no se limitan a dispositivos concretos, de modo que se pueden crear de forma fácil y rápida como directorios. Aumentan automáticamente en el espacio asignado a la agrupación de almacenamiento.

Suma de comprobación y recuperación de datos En ZFS se efectúa una suma de comprobación de todos los datos y metadatos mediante un algoritmo seleccionable por el usuario. La recuperación de todos los datos y las sumas de comprobación se efectúa en la capa del sistema de archivos, y es transparente para todas las aplicaciones. Asimismo, ZFS ofrece soluciones para la reparación automática de datos. ZFS admite grupos de almacenamiento con diversos niveles de redundancia de datos que incluyen la duplicación y una variación sobre RAID-5. Si se detecta un bloque de datos incorrecto, ZFS recupera los datos correctos de otra copia redundante y repara los datos anómalos sustituyéndolos por la copia buena.

ZFS presenta un modelo de almacenamiento agrupado que elimina el concepto de volúmenes y los problemas asociados de particiones, configuración, mal uso del ancho de banda y almacenamiento no válido.

80 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Información general

El ancho de banda de E/S combinado de todos los dispositivos de la agrupación está disponible para todos los sistemas de archivos en todo momento.

Cada agrupación de almacenamiento se compone de uno o más dispositivos virtuales, que describen la disposición del almacenamiento físico y sus características de errores. Consulte en la página http://opensolaris.org/os/community/zfs/demos/basics la demostración 100 Mirrored Filesystems in 5 Minutes, que presenta la administración sistemas de archivos ZFS.

RAID-Z Además del almacenamiento agrupado, ZFS proporciona configuraciones de redundancia de datos RAID-Z y redundantes con duplicaciones. RAID-Z es un dispositivo virtual que almacena datos y paridad en varios discos, similar a RAID-5.

En RAID-Z, ZFS utiliza divisiones RAID de ancho variable para que todas las escrituras estén totalmente divididas. Esto sólo es posible gracias a la integración que ZFS hace del sistema de archivos y la administración de dispositivos, de modo que los metadatos del sistema de archivos tienen suficiente información sobre el modelo de réplica de datos subyacente para controlar las divisiones RAID de ancho variable. RAID-Z es la principal solución de sólo software existente para el "agujero de escritura" de RAID-5.

Utilidad de gestión de servicios (SMF) SMF crea un modelo unificado y compatible para la gestión de una gran cantidad de servicios, como la entrega de correo electrónico, las solicitudes ftp y la ejecución remota de

Módulo 5 • Características principales del sistema operativo Solaris 81 Información general

comandos en el proyecto OpenSolaris. La estructura smf(5) sustituye (de un modo compatible) el mecanismo de inicio init.d(4) existente y mejora inetd(1M). SMF ofrece a los desarrolladores lo siguiente:

■ Reinicio automatizado de los servicios por orden de dependencia debidos a errores incorregibles de software, hardware o administrativos ■ Una única API para la administración, configuración y observación de servicios ■ Acceso a la administración de recursos basada en servicios ■ Depuración simplificada del proceso de arranque

Consulte http://opensolaris.org/os/community/smf/scfdot para ver un gráfico de los servicios SMF y sus dependencias enun sistema x86 en el que se acaba de instalar el sistema operativo Solaris Nevada.

82 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 MÓDULO6 6 Conceptos de programación

Objetivos Este módulo ofrece una descripción avanzada de los conceptos fundamentales del entorno de programación de OpenSolaris:

■ Administración del sistema y los procesos ■ Programación de subprocesos ■ Descripción general del núcleo ■ Planificación de la CPU ■ Depuración de procesos

Recursos adicionales

■ Solaris Internals (2nd Edition), Prentice Hall PTR (12 de mayo de 2006), de Jim Mauro y Richard McDougall ■ Solaris Systems Programming, Prentice Hall PTR (19 de agosto de 2004), de Rich Teer ■ Multithreaded Programming Guide Sun Microsystems, Inc., 2005. ■ STREAMS Programming Guide. Sun Microsystems, Inc., 2005. ■ Solaris 64-bit Developer’s Guide Sun Microsystems, Inc., 2005.

83 Administración del sistema y los procesos Administración del sistema y los procesos La unidad básica de trabajo es el proceso. Los ID de proceso (PID) se enumeran secuencialmente en el sistema. De modo predeterminado, el administrador del sistema asigna a cada usuario un proyecto, que es un identificador administrativo en la red. Cada inicio de sesión que se realiza correctamente en un proyecto crea una tarea, que constituye un mecanismo de agrupación para los procesos. Una tarea contiene el proceso de inicio de sesión, así como los procesos secundarios subsiguientes.

La utilidad de agrupación de recursos une los recursos ligados a procesos en una abstracción común denominada agrupación. Los grupos de procesos y otras entidades se configuran, agrupan y etiquetan de modo que los componentes de trabajo se asocian con un subconjunto de los recursos totales de un sistema. Cuando la utilidad de agrupaciones está desactivada, todos los procesos pertenecen a la misma agrupación, pool_default, y los grupos de procesadores se administran a través de la llamada de sistema pset(). Cuando la utilidad de agrupaciones está activada, debe utilizarse para administrar los grupos de procesadores. Es posible crear agrupaciones y asociarlas con los grupos de procesadores. Los procesos pueden estar vinculados a agrupaciones que tengan conjuntos de recursos que no estén vacíos.

Si en OpenGrok se busca pool.c, se encontrarán numerosos comentarios sobre código que describen las relaciones entre las tareas, las agrupaciones, los proyectos y los procesos del modo siguiente:

La operación que vincula los proyectos y las tareas con las agrupaciones es atómica. Eso significa que se vincularán todos los procesos de un determinado proyecto o tarea a una nueva agrupación o, en caso de error, permanecerán vinculados a la antigua agrupación. Los procesos de un determinado proyecto

84 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Administración del sistema y los procesos o tarea sólo se pueden vincular a diferentes agrupaciones si se vuelven a vincular de forma individual como procesos únicos. Los subprocesos o LWP del mismo proceso no tienen vínculos de agrupaciones, y se vinculan al mismo grupo de recursos asociado con la agrupación de recursos del proceso en cuestión.

Los procesos cuentan con la posibilidad de ejecutarse dentro de una zona. Las zonas las configuran los administradores del sistema, normalmente por motivos de seguridad, para aislar grupos de usuarios de procesos.

Programación de subprocesos Una vez descritos los procesos en el contexto de las tareas, los proyectos, las agrupaciones de recursos, las zonas y las zonas de marca, pasaremos al contexto de los subprocesos. El sistema UNIX tradicional ya admite el concepto de subprocesos. Cada proceso contiene un único subproceso, de modo que programar con varios procesos implica programar con varios subprocesos. Sin embargo, un proceso también es un espacio de direcciones; crear un proceso implica crear un nuevo espacio de direcciones.

La comunicación entre los subprocesos de un proceso resulta sencilla porque lo comparten todo, incluidos los descriptores de archivos abiertos y un espacio de direcciones común. De este modo, los datos producidos por un subproceso están inmediatamente disponibles para todos los demás subprocesos.

Las bibliotecas son libpthread para los subprocesos POSIX y libthread para los subprocesos de OpenSolaris. El subproceso múltiple ofrece flexibilidad al desvincular los recursos del núcleo y los del usuario. En OpenSolaris, la biblioteca de C estándar se encarga del subproceso múltiple para ambos grupos de interfaces.

Módulo 6 • Conceptos de programación 85 Administración del sistema y los procesos

Utilice pthread_create(3C) para agregar un nuevo subproceso de control al proceso actual. int pthread_create(pthread_t *tid, const pthread_attr_t *tattr, void*(*start_routine)(void *), void *arg);

Para llamar a la función pthread_create() se utiliza el comando attr, que tiene el comportamiento de estado necesario. start_routine es la función con la que el nuevo subproceso inicia la ejecución. Cuando se devuelve start_routine, el subproceso se cierra con el estado configurado en el valor que devuelve start_routine. pthread_create() devuelve cero cuando la llamada se finaliza correctamente. Si se devuelve cualquier otro valor, significa que se ha producido un error. Vaya a /on/usr/src/lib/libc/spec/threads.spec en OpenGrok para obtener una lista completa de las funciones y declaraciones de pthread.

La sincronización de subprocesos permite controlar el flujo del programa y acceder a datos compartidos para los subprocesos que estén en ejecución. Los cuatro objetos de sincronización son bloqueos mutex, bloqueos de lectura/escritura, variables de condiciones y semáforos. ■ Los bloqueos mutex no permiten que haya más de un subproceso ejecutando una sección específica del código o accediendo a determinados datos. ■ Los bloqueos de lectura/escritura permiten lecturas simultáneas y escrituras exclusivas en un recurso compartido protegido. Para modificar un recurso, un subproceso debe adquirir primero el bloqueo de escritura exclusivo. No se permite adquirir un bloqueo de escritura exclusivo hasta que se hayan liberado todos los bloqueos de lectura. ■ Las variables de condiciones bloquean los subprocesos hasta que una condición concreta tenga el valor true.

86 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Administración del sistema y los procesos

■ Los semáforos suelen coordinar el acceso a los recursos. Limitan los subprocesos que pueden tener acceso a un semáforo. Cuando se alcanza el límite, el subproceso que intenta acceder al recurso se bloquea.

Sincronización Los objetos de sincronización son variables en la memoria a las que se accede como si fueran datos. Los subprocesos de distintos procesos pueden comunicarse entre sí a través de los objetos de sincronización que se encuentran en la memoria compartida controlada por los subprocesos. Los subprocesos se pueden comunicar entre sí aunque los subprocesos de distintos procesos normalmente no se pueden ver entre sí. Los objetos de sincronización también se pueden colocar en archivos. Los objetos de sincronización pueden tener una vida útil más larga que la del proceso que los crea.

En el árbol de código fuente, podemos utilizar OpenGrok para buscar libthread, y el segundo resultado más importante se encuentra en mutex.c, acompañado del siguiente extracto de comentario de código:

Implementation of all threads interfaces between ld.so.1 and libthread. In a non-threaded environment all thread interfaces are vectored to noops. When called via _ld_concurrency() from libthread these vectors are reassigned to real threads interfaces. Two models are supported:

TI_VERSION == 1 Under this model libthread provides rw_rwlock/rw_unlock, through which we vector all rt_mutex_lock/rt_mutex_unlock calls. Under lib/libthread these interfaces provided _sigon/_sigoff (unlike lwp/libthread that provided signal blocking via bind_guard/bind_clear.

Módulo 6 • Conceptos de programación 87 Administración del sistema y los procesos TI_VERSION == 2 Under this model only libthreads bind_guard/bind_clear and thr_self interfaces are used. Both libthreads block signals under the bind_guard/bind_clear interfaces. Lower level locking is derived from internally bound _lwp_ interfaces. This removes recursive problems encountered when obtaining locking interfaces from libthread. The use of mutexes over reader/writer locks also enables the use of condition variables for controlling thread concurrency (allows access to objects only after their .init has completed).

Ahora que ya conoce un poco mejor cómo se definen los objetos de sincronización en la programación de subprocesos múltiples, veremos cómo se pueden administrar estos objetos mediante el uso de clases de planificación.

Planificación de la CPU Los procesos se ejecutan en una clase de planificación con una política de planificación independiente para cada clase, del modo siguiente:

■ Realtime (RT): la clase de planificación de mayor prioridad ofrece una política para los procesos que requieren una respuesta rápida y un control absoluto por parte del usuario, o la aplicación de las prioridades de planificación. La planificación en tiempo real RT se puede aplicar a un proceso completo o a uno o más procesos ligeros (LWP) de un proceso. Para utilizar la clase Realtime, es necesario tener el privilegio proc_priocntl. Consulte la página del comando man privileges(5) para obtener más información. ■ System (SYS): es la clase de planificación de prioridad media; no se puede aplicar a un proceso del usuario.

88 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Administración del sistema y los procesos

■ Timeshare (TS): es la clase de planificación de prioridad menor; viene configurada de forma predeterminada. La política TS distribuye el recurso de procesamiento de forma equitativa entre los procesos con distintas características de consumo de CPU. Otras partes del núcleo pueden monopolizar el procesador durante breves intervalos de tiempo, sin afectar al tiempo de respuesta que obtiene el usuario. ■ Inter-Active (IA): la política IA distribuye el recurso de procesamiento de forma equitativa entre los procesos con distintas características de consumo de la CPU, a la vez que ofrece una gran capacidad de respuesta para la interacción con el usuario. ■ Fair Share (FSS): la política FSS distribuye el recurso de procesamiento de forma equitativa entre los proyectos, al margen del número de procesos que tengan, especificando shares para controlar la asignación de procesos a los recursos de la CPU. Se recuerda el uso de los recursos, de modo que la asignación se reduce en caso de un uso elevado y se aumenta si el uso es reducido con respecto a otros proyectos. ■ Fixed-Priority (FX): es una política de planificación preventiva de prioridad fija para los procesos que requieren que el sistema no ajuste dinámicamente las prioridades de planificación sino que sea el usuario o la aplicación quienes tienen el control de las mismas. Esta clase es un punto de partida útil para controlar las políticas de asignación de CPU.

Se mantiene una clase de planificación para cada proceso ligero (LWP). Los subprocesos tienen la clase de planificación y la prioridad de sus LWP subyacentes. Cada LWP de un proceso puede tener una clase de planificación y una prioridad únicas visibles al núcleo. Las prioridades de los subprocesos regulan la contención de los objetos de sincronización.

Módulo 6 • Conceptos de programación 89 Administración del sistema y los procesos

Las clases de planificación RT y TS llaman a priocntl(2) para definir el nivel de prioridad de los procesos o de los LWP dentro de un proceso. Si utilizamos OpenGrok para buscar priocntl en la base de código, encontramos las variables que se utilizan en las clases de planificación RT y TS en el archivo rtsched.c, del modo siguiente:

27 #pragma ident "@(#)rtsched.c 1.10 05/06/08 SMI" 28 29 #include "lint.h" 30 #include "thr_uberdata.h" 31 #include 32 #include 33 #include 34 #include 35 #include 36 #include 37 38 /* 39 * The following variables are used for caching information 40 * for priocntl TS and RT scheduling classs. 41 */ 42 struct pcclass ts_class, rt_class; 43 44 static rtdpent_t *rt_dptbl; /* RT class parameter table */ 45 static int rt_rrmin; 46 static int rt_rrmax; 47 static int rt_fifomin; 48 static int rt_fifomax; 49 static int rt_othermin; 50 static int rt_othermax; ...

Si escribimos el comando man priocntl en una ventana del terminal, se muestran los detalles de cada clase de planificación y se describen los atributos y el uso. Por ejemplo:

% man priocntl Reformatting page. Please Wait... done

90 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Administración del sistema y los procesos

User Commands priocntl(1)

NAME priocntl - display or set scheduling parameters of specified process(es)

SYNOPSIS priocntl -l

priocntl -d [-i idtype] [idlist]

priocntl -s [-c class] [ class-specific options] [- i idtype] [idlist]

priocntl -e [-c class] [ class-specific options] command [argument(s)]

DESCRIPTION The priocntl command displays or sets scheduling parameters of the specified process(es). It can also be used to display the current configuration information for the system’s pro- cess scheduler or execute a command with specified schedul- ing parameters.

Processes fall into distinct classes with a separate scheduling policy applied to each class. The process classes currently supported are the real-time class, time-sharing class, interactive class, fair-share class, and the fixed priority class. The characteristics of these classes and the class-specific options they accept are described below in the USAGE section under the headings Real-Time Class, Time- Sharing Class, Inter-Active Class, Fair-Share Class, and --More--(4%)

Módulo 6 • Conceptos de programación 91 Administración del sistema y los procesos Descripción general del núcleo

Ahora que ya cuenta con un conocimiento avanzado de los procesos, los subprocesos y la planificación, describiremos el núcleo y las diferencias entre los módulos de núcleo y los programas de usuario. El núcleo de Solaris:

■ Administra los recursos del sistema, incluidos los sistemas de archivos, los procesos y los dispositivos físicos. ■ Ofrece a las aplicaciones servicios de sistema como la administración de E/S, memoria virtual y planificación. ■ Coordina las interacciones de todos los procesos del usuario y recursos del sistema. ■ Asigna prioridades y proporciona solicitudes de recursos e interrupciones y excepciones de hardware. ■ Planifica y alterna subprocesos, asigna memoria e intercambia procesos.

En la sección siguiente se abordan varias diferencias importantes entre los módulos de núcleo y los programas de usuario.

92 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Administración del sistema y los procesos Diferencias de ejecución entre los módulos de núcleo y los programas de usuario Las siguientes características de los módulos de núcleo son motivo de importantes diferencias entre la ejecución de los módulos de núcleo y la de los programas de usuario:

■ Los módulos de núcleo tienen un espacio de dirección independiente. Un módulo se ejecuta en un espacio de núcleo. Una aplicación se ejecuta en un espacio de usuario. El software del sistema está protegido de los programas de usuario. El espacio de núcleo y el de usuario tienen sus propios espacios de dirección de memoria. ■ Los módulos de núcleo tienen un mayor privilegio de ejecución. El código que se ejecuta en espacio de núcleo tiene un mayor privilegio que el que se ejecuta en espacio de usuario. ■ Los módulos de núcleo no se ejecutan secuencialmente. Un programa de usuario suele ejecutarse de forma secuencial y lleva a cabo una única tarea de principio a fin. Un módulo de núcleo no se ejecuta secuencialmente, y se registra para dar respuesta a futuras solicitudes. ■ Los módulos de núcleo pueden interrumpirse. Más de un proceso puede solicitar el módulo de núcleo de forma simultánea. Por ejemplo, un control de interrupción puede solicitar el módulo de núcleo al mismo tiempo que dicho módulo está respondiendo a una llamada del sistema. En un sistema de multiprocesador simétrico (SMP), el módulo de núcleo puede ejecutar una o más CPU de forma simultánea. ■ Los módulos de núcleo deben ser previsibles. No puede suponer que el código del módulo de núcleo es seguro sólo porque el código del controlador no se bloquea. Configure el controlador para que pueda preverse el comportamiento del módulo.

Módulo 6 • Conceptos de programación 93 Administración del sistema y los procesos

■ Los módulos de núcleo pueden compartir datos. No es necesario que los diferentes subprocesos de un programa de aplicación compartan los datos. Las rutinas y estructuras de datos que constituyen un controlador son comunes a todos los subprocesos que utilizan el controlador. El controlador debe poder resolver los problemas de contención derivados de múltiples solicitudes. Diseñe cuidadosamente las estructuras de datos del controlador para mantener separados los diferentes subprocesos de ejecución.

Diferencias estructurales entre los módulos de núcleo y los programas de usuario Las siguientes características de los módulos de núcleo son motivo de importantes diferencias entre la estructura de los módulos de núcleo y la de los programas de usuario:

■ Los módulos de núcleo no definen un programa principal. Estos módulos, incluidos los controladores de dispositivos, no tienen ninguna rutina main(). Los módulos de núcleo son grupos de subrutinas y datos. ■ Los módulos de núcleo sólo se vinculan con el núcleo. No se vinculan en las mismas bibliotecas en que se vinculan los programas de usuario. Las únicas funciones a las que puede llamar un módulo de núcleo son las que exporta el núcleo. ■ Los módulos de núcleo utilizan diferentes archivos de encabezado. Los módulos de núcleo requieren un grupo diferente de archivos de encabezado que el que necesitan los programas de usuario. Los archivos de encabezado necesarios se enumeran en la página del comando man de cada función. Los módulos de núcleo pueden incluir archivos de encabezado que comparten los programas de usuario si las interfaces de usuario y núcleo dentro de dichos archivos de encabezado compartidos se definen condicionalmente utilizando la macro _KERNEL.

94 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Administración del sistema y los procesos

■ Los módulos de núcleo deben evitar las variables globales. Evitar las variables globales en los módulos de núcleo es incluso más importante que evitar las variables globales en los programas de usuario. Siempre que sea posible, declare los símbolos como static. Cuando deba utilizar símbolos globales, asígneles un prefijo que sea exclusivo en el núcleo. También se recomienda utilizar este prefijo para los símbolos exclusivos del módulo. ■ Los módulos de núcleo se pueden personalizar según el hardware. Pueden dedicar registros de proceso a roles específicos. El código de núcleo se puede optimizar paraun procesador concreto. Asimismo, en OpenSolaris es posible personalizar las bibliotecas para algunas de las plataformas x86/x64 y UltraSPARC más recientes. Mientras que el núcleo puede dedicar determinados registros a determinados roles, es posible escribir código personalizado para las bibliotecas de usuario y para las de núcleo. ■ Los módulos de núcleo se pueden cargar y descargar según sea necesario. El grupo de subrutinas y datos que componen un controlador de dispositivos se pueden compilar en un único módulo cargable de código de objeto. Este módulo cargable se puede vincular estática o dinámicamente en el núcleo y desvincularlo de él. Puede agregar funciones al núcleo mientras el sistema está funcionando. Puede probar nuevas versiones del controlador sin necesidad de reiniciar el sistema.

Depuración de procesos La depuración de procesos en todos los niveles de la pila de desarrollo constituye una parte principal de la escritura de los módulos de núcleo.

Una búsqueda completa de libthread en OpenGrok genera los siguientes comentarios de código en el archivo mdb_tdb.c que

Módulo 6 • Conceptos de programación 95 Administración del sistema y los procesos

describen la conexión entre la depuración de varios subprocesos y el funcionamiento de mdb:

In order to properly debug multi-threaded programs, the proc target must be able to query and modify information such as a thread’s register set using either the native LWP services provided by libproc (if the process is not linked with libthread), or using the services provided by libthread_db (if the process is linked with libthread). Additionally, a process may begin life as a single-threaded process and then later dlopen() libthread, so we must be prepared to switch modes on-the-fly. There are also two possible libthread implementations (one in /usr/lib and one in /usr/lib/lwp) so we cannot link mdb against libthread_db directly; instead, we must dlopen the appropriate libthread_db on-the-fly based on which libthread.so the victim process has open. Finally, mdb is designed so that multiple targets can be active simultaneously, so we could even have *both* libthread_db’s open at the same time. This might happen if you were looking at two multi-threaded user processes inside of a crash dump, one using /usr/lib/libthread.so and the other using /usr/lib/lwp/libthread.so. To meet these requirements, we implement a libthread_db "cache" in this file. The proc target calls mdb_tdb_load() with the pathname of a libthread_db to load, and if it is not already open, we dlopen() it, look up the symbols we need to reference, and fill in an ops vector which we return to the caller. Once an object is loaded, we don’t bother unloading it unless the entire cache is explicitly flushed. This mechanism also has the nice property that we don’t bother loading libthread_db until we need it, so the debugger starts up faster.

96 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Administración del sistema y los procesos

Se pueden utilizar los siguientes comandos mdb para acceder a los LWP de un programa de varios subprocesos:

■ $l Imprime el ID del LWP del subproceso representativo si el destino es un proceso de usuario. ■ $L Imprime los ID de cada LWP del destino si dicho destino es un proceso de usuario. ■ pid ::attach Se adjunta a los procesos utilizando el pid oel ID de proceso. ■ ::release Libera el archivo principal o proceso adjuntado previamente. El proceso puede continuarse posteriormente mediante prun(1) o reanudarse mediante la aplicación de MDB u otro depurador. ■ dirección ::context Contexto pertinente al proceso especificado. Estos comandos para definir puntos de interrupción condicionales a menudo resultan de gran utilidad. ■ [ addr ] ::bp [+/-dDestT] [-c cmd] [-n count] sym ... Define un punto de interrupción en las ubicaciones especificadas. ■ addr ::delete [id | all] Elimina los especificadores de eventos con el número de ID dado.

Los sondeos DTrace se construyen de modo similar a las consultas MDB. Proseguiremos con los ejercicios prácticos de DTrace y, a continuación, agregaremos MDB cuando la depuración sea más compleja.

Módulo 6 • Conceptos de programación 97 98 MÓDULO7 7 Introducción a DTrace

Objetivos El objetivo de esta práctica es introducirle a DTrace utilizando una secuencia de sondeo para una llamada de sistema con DTrace.

Recursos adicionales

■ Solaris Dynamic Tracing Guide. Sun Microsystems, Inc., 2007. ■ DTrace User Guide, Sun Microsystems, Inc., 2006

99 Activación de sondeos DTrace sencillos Activación de sondeos DTrace sencillos Al finalizar el ejercicio habrá adquirido conocimientos básicos sobre los sondeos DTrace.

Resumen En primer lugar, vamos a aprender el funcionamiento de DTrace mediante la creación de varias solicitudes muy sencillas con el sondeo denominado BEGIN, que se activa cada vez que inicia una nueva solicitud de seguimiento. Puede utilizar la opción n de -dtrace(1M) para activar un sondeo utilizando su nombre de cadena.

100 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Activación de sondeos DTrace sencillos Para activar un sondeo DTrace sencillo

1 Abra una ventana de terminal.

2 Active el sondeo: # dtrace -n BEGIN Después de una breve pausa, dtrace indicará que se ha habilitado un sondeo y verá una línea de salida que informará de que se ha activado el sondeo BEGIN. Cuando vea esta salida, dtrace permanece en estado de pausa, a la espera de que se activen otros sondeos. Como no se ha habilitado ninguno de los otros sondeos y BEGIN sólo se activa una vez, pulse Control+C en la shell para salir de dtrace y volver al indicador de la shell:

3 Vuelva al indicador de la shell. Para ello, pulse Control+C: # dtrace -n BEGIN dtrace: description ’BEGIN’ matched 1 probe CPU ID FUNCTION:NAME 0 1 :BEGIN ^C # La salida indica que se ha activado el sondeo con el nombre BEGIN y tanto su nombre como el ID de entero, 1, se han imprimido. De forma predeterminada, se muestra el nombre en forma de entero de la CPU en que se activa este sondeo. En este ejemplo, la columna de la CPU indica que el comando dtrace se estaba ejecutando en la CPU 0 cuando se activó el sondeo. Puede crear solicitudes de DTrace mediante números arbitrarios de sondeos y acciones. Vamos a crear una solicitud sencilla con dos sondeos agregando el sondeo END al comando del ejemplo anterior. El sondeo END se activa una vez al completar el seguimiento.

Módulo 7 • Introducción a DTrace 101 Activación de sondeos DTrace sencillos

4 Agregue el sondeo END: # dtrace -n BEGIN -n END dtrace: description ’BEGIN’ matched 1 probe dtrace: description ’END’ matched 1 probe CPU ID FUNCTION:NAME 0 1 :BEGIN ^C 0 2 :END # El sondeo END se activa una vez al completar el seguimiento. Como puede observar, al pulsar Control+C para salir de DTrace se activa el sondeo END. DTrace informa de la activación de este sondeo antes de salir.

102 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Enumeración de sondeos rastreables Enumeración de sondeos rastreables El objetivo de este ejercicio es analizar los sondeos de forma más detallada y mostrar la forma de enumerar los sondeos en un sistema.

Resumen En los ejemplos anteriores, hemos aprendido a utilizar dos sencillos sondeos denominados BEGIN y END. Pero, ¿de dónde proceden estos sondeos? Los sondeos DTrace provienen de un conjunto de módulos del núcleo denominados proveedores; cada uno de ellos realiza un tipo determinado de instrumentación para crear sondeos. Por ejemplo, el proveedor syscall ofrece sondeos en cada llamada del sistema; por su parte, el proveedor fbt los ofrece en cada función del núcleo.

Al utilizar DTrace, a cada proveedor se le concede la oportunidad de publicar los sondeos que puede proporcionar a la estructura de DTrace. A continuación, puede habilitar y enlazar las acciones de seguimiento a cualquiera de los sondeos publicados.

Módulo 7 • Introducción a DTrace 103 Enumeración de sondeos rastreables Para enumerar los sondeos rastreables

1 Abra una ventana de terminal.

2 Escriba el siguiente comando: # dtrace Las opciones del comando dtrace se imprimen en la salida.

3 Escriba el comando dtrace con la opción -l: # dtrace -l | more ID PROVIDER MODULE FUNCTION NAME 1 dtrace BEGIN 2 dtrace END 3 dtrace ERROR 4 lockstat genunix mutex_enter adaptive-acquire 5 lockstat genunix mutex_enter adaptive-block 6 lockstat genunix mutex_enter adaptive-spin 7 lockstat genunix mutex_exit adaptive-release --More-- Se enumeran los sondeos disponibles en el sistema, que incluyen los datos siguientes:

■ ID: ID interno del sondeo enumerado. ■ Proveedor: nombre del proveedor. Los proveedores se utilizan para clasificar los sondeos. También es el método de instrumentación. ■ Módulo: nombre del módulo de Unix o la biblioteca de aplicación del sondeo. ■ Función: nombre de la función en la que se encuentra el sondeo. ■ Nombre: nombre del sondeo.

104 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Enumeración de sondeos rastreables

4 Dirija el comando anterior a wc para buscar el número total de sondeos en el sistema: # dtrace -l | wc -l 30122 El número de sondeos del que tiene conocimiento el sistema se enumera en la salida. El número varía según el tipo de sistema.

5 Agregue una de las opciones siguientes para filtrar la lista:

■ -P para el proveedor ■ -m para el módulo ■ -f para la función ■ -n para el nombre Vea los siguientes ejemplos:

# dtrace -l -P lockstat ID PROVIDER MODULE FUNCTION NAME 4 lockstat genunix mutex_enter adaptive-acquire 5 lockstat genunix mutex_enter adaptive-block 6 lockstat genunix mutex_enter adaptive-spin 7 lockstat genunix mutex_exit adaptive-release Sólo se enumeran en la salida los sondeos disponibles en el proveedor lockstat.

# dtrace -l -m ufs ID PROVIDER MODULE FUNCTION NAME 15 sysinfo ufs ufs_idle_free ufsinopage 16 sysinfo ufs ufs_iget_internal ufsiget 356 fbt ufs allocg entry Sólo se enumeran en la salida los sondeos del módulo UFS.

# dtrace -l -f open ID PROVIDER MODULE FUNCTION NAME 4 syscall open entry 5 syscall open return 116 fbt genunix open entry

Módulo 7 • Introducción a DTrace 105 Enumeración de sondeos rastreables

117 fbt genunix open return Sólo se enumeran los sondeos con el nombre de función open.

# dtrace -l -n start ID PROVIDER MODULE FUNCTION NAME 506 proc unix lwp_rtt_initial start 2766 io genunix default_physio start 2768 io genunix aphysio start 5909 io nfs nfs4_bio start El comando anterior enumera todos los sondeos cuyo nombre es start.

106 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Programación en D Programación en D Ahora que ya tiene conocimientos básicos sobre cómo asignar un nombre a un sondeo, activarlo y enumerarlo, puede escribir la versión de DTrace del primer programa general, "Hola, mundo""

Resumen En este ejercicio puede constatar que, además de la creación de experimentos de DTrace en la línea de comandos, también puede escribirlos en archivos de texto utilizando el lenguaje de programación D.

Módulo 7 • Introducción a DTrace 107 Programación en D Para escribir un programa DTrace

1 Abra una ventana de terminal.

2 En un editor de texto, cree un archivo llamado hello.d.

3 Escriba su primer programa de D: BEGIN { trace("Hola mundo"); exit(0); }

4 Guarde el archivo hello.d.

5 Ejecute el programa utilizando la opción -s de dtrace: # dtrace -s hello.d dtrace: script ’hello.d’ matched 1 probe CPU ID FUNCTION:NAME 0 1 :BEGIN Hola, mundo # Como puede ver, dtrace imprimió el mismo resultado que antes seguido del texto "Hola, mundo". A diferencia del ejemplo anterior, no ha tenido que esperar ni pulsar Control+C. Estos cambios son el resultado de las acciones especificadas en el sondeo BEGIN de hello.d. Examinemos la estructura del programa D con más detalle para comprender lo que ha ocurrido.

108 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Programación en D Discusión Cada programa D está formado por una serie de cláusulas; cada una de ellas describe uno o varios de los sondeos que se van a habilitar, y una serie de acciones opcionales que se efectuarán una vez activado el sondeo. Estas acciones se enumeran como una serie de instrucciones entre llaves {}a continuación del nombre del sondeo. Cada instrucción finaliza con un punto y coma (;).

La primera instrucción utiliza la función trace() para indicar que DTrace debe registrar el argumento especificado, la cadena "Hola, mundo", al activarse el sondeo BEGIN y, a continuación, imprimirse. La segunda instrucción utiliza la función exit() para indicar que DTrace debe detener el seguimiento y salir del comando dtrace.

DTrace proporciona un conjunto de funciones útiles, por ejemplo trace() y exit(), a las que puede llamar en sus programas D. Para llamar a una función, debe especificar su nombre seguido de una lista de los argumentos entre paréntesis. El conjunto completo de funciones de D se describe en la Solaris Dynamic Tracing Guide.

De momento, si está familiarizado con el lenguaje de programación C, quizá haya observado a partir del nombre y de nuestros ejemplos que el lenguaje de programación D de DTrace es muy similar a C y awk(1). De hecho, D se deriva de un gran subconjunto de C combinado con un grupo especial de funciones y variables que facilitan el seguimiento.

Si anteriormente ya ha escrito un programa en C, la mayor parte de sus conocimientos podrán aplicarse en la creación de programas de seguimiento en D. Por el contrario, aunque nunca haya escrito ningún programa en C, el lenguaje D resulta muy fácil de aprender. En primer lugar, por un momento dejemos a un lado las reglas del lenguaje y examinemos cómo

Módulo 7 • Introducción a DTrace 109 Programación en D

funciona DTrace. Regresaremos más adelante al aprendizaje de cómo crear programas en D más interesantes.

110 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 MÓDULO8 8 Depuración de aplicaciones con DTrace

Objetivos El objetivo de este módulo es utilizar DTrace para supervisar los eventos de las aplicaciones.

Recursos adicionales Application Packaging Developer’s Guide. Sun Microsystems, Inc., 2005.

111 Activación de los sondeos en modo de usuario Activación de los sondeos en modo de usuario DTrace permite agregar sondeos dinámicamente a las funciones de nivel de usuario. No es necesario volver a compilar el código de usuario, ni se necesitan indicadores especiales ni ningún reinicio. Los sondeos DTrace pueden activarse con sólo llamar al proveedor.

Una descripción de sondeo tiene la siguiente sintaxis:

pid:mod:function:name

■ pid: format pid processid (por ejemplo, pid5234) ■ mod: nombre de la biblioteca o a.out (ejecutable) ■ function: nombre de la función ■ name: entry para la entrada de funciones, y return para el retorno de funciones

112 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace con aplicaciones Uso de DTrace con aplicaciones En este ejercicio, aprenderá a utilizar DTrace en las aplicaciones de usuario.

Resumen Este ejercicio se basa en el uso de un ID de proceso en la descripción del sondeo para hacer un seguimiento de la aplicación asociada. La complejidad del procedimiento va aumentando hasta el final del ejercicio; también aumenta la cantidad y profundidad de la información sobre el comportamiento de la aplicación que se genera.

Módulo 8 • Depuración de aplicaciones con DTrace 113 Uso de DTrace con aplicaciones Para aplicar DTrace a gcalctool

1 En el menú Programas o Aplicaciones, inicie la calculadora.

2 Busque el ID del proceso que acaba de iniciar. # pgrep gcalctool 8198 Este número es el ID del proceso calc, que denominaremos procid.

3 Siga estos pasos para crear una secuencia en D que cuente la cantidad de veces que se llama a cualquier función de la herramienta gcalctool.

a. En un editor de texto, cree un archivo llamado proc_func.d.

b. Utilice pid$1:::entry como descriptor de sondeos. $1 es el primer argumento que se obtiene al enviar la secuencia, y el predicado se deja vacío.

c. En la sección de acción, agregue un elemento para contar la cantidad de veces que se llama a la función mediante la instrucción agregada @[probefunc]=count(). pid$1:::entry { @[probefunc]=count(); }

d. Ejecute la secuencia que acaba de escribir. # dtrace -qs proc_func.d procid Sustituya procid con el ID de proceso de gcalctool

e. Realice un cálculo con la calculadora.

114 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace con aplicaciones f. Pulse Control+C en la ventana en que ejecutó la secuencia en D.

Nota – La secuencia de DTrace obtiene los datos y espera a que el usuario detenga la obtención pulsando Control+C. Si no necesita imprimir la agregación obtenida, DTrace la imprimirá automáticamente.

4 A continuación, modifique la secuencia para que solamente cuente las funciones de la biblioteca libc.

a. Copie proc_func.d en proc_libc.d.

b. Modifique la descripción del sondeo del archivo proc_libc.d y cámbiela a: pid$1:libc::entry

c. La nueva secuencia debe tener el aspecto siguiente: pid$1:libc::entry { @[probefunc]=count(); }

5 A continuación, ejecute la secuencia. # dtrace -qs proc_libc.d procid Sustituya procid con el ID de proceso de gcalctool

a. Realice un cálculo con la calculadora.

b. Pulse Control+C en la ventana en que ejecutó la secuencia en D para ver la salida.

Módulo 8 • Depuración de aplicaciones con DTrace 115 Uso de DTrace con aplicaciones

6 Por último, modifique la secuencia para averiguar el tiempo que se ha destinado a cada función.

a. Cree un archivo y asígnele el nombre func_time.d. Utilizaremos dos descripciones de sondeo en func_time.d.

b. Escriba el primer sondeo del siguiente modo: pid$1:::entry

c. Escriba el segundo del siguiente modo: pid$1:::return

d. En la sección de acción del primer sondeo, guarde timestamp en la variable ts. La indicación de hora es un elemento integrado de DTrace que cuenta el número de nanosegundos desde un punto en el pasado.

e. En la sección de acción del segundo sondeo, calcule los nanosegundos que han transcurrido utilizando la agregación siguiente: @[probefunc]=sum(timestamp - ts)

f. La nueva secuencia func_time.d debe coincidir con la siguiente: pid$1:::entry { ts = timestamp; } pid$1:::return /ts/ { @[probefunc]=sum(timestamp - ts); }

7 Ejecute la nueva secuencia func_time.d: # dtrace -qs func_time.d procid

116 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace con aplicaciones

Sustituya procid con el ID de proceso de gcalctool

a. Realice un cálculo con la calculadora.

b. Pulse Control+C en la ventana en que ejecutó la secuencia en D para ver la salida. ^C gdk_xid__equal 2468 _XSetLastRequestRead 2998 _XDeq 3092

... La columna izquierda muestra el nombre de la función; la derecha, el tiempo dedicado a dicha función. El tiempo se mide en nanosegundos.

Módulo 8 • Depuración de aplicaciones con DTrace 117 118 MÓDULO9 9 Depuración de aplicaciones C++ con DTrace

Objetivos Los ejemplos de este módulo muestran el uso de DTrace para diagnosticar errores de aplicación C++. Estos ejemplos también se utilizan para comparar DTrace con otras herramientas de depuración de aplicaciones, como Sun Studio 10 o mdb.

119 Uso de DTrace para perfilar y depurar un programa en C++ Uso de DTrace para perfilar y depurar un programa en C++

Se creó el programa de muestra CCtest para mostrar un error común a las aplicaciones en C++: la pérdida de memoria. En muchos casos, la pérdida de memoria tiene lugar cuando se crea un objeto, pero nunca se destruye, tal como ocurre con el programa de este módulo.

Al depurar un programa en C++, el compilador puede convertir algunos nombres de C++ en cadenas mezcladas de dígitos y caracteres apenas inteligibles. Esta mezcla del nombre es un detalle de implementación necesario para admitir la sobrecarga de funciones de C++, proporcionar nombres externos válidos para las funciones de C++ que incluyen caracteres especiales, y distinguir las instancias del mismo nombre declaradas en distintos espacios de nombres y clases.

Por ejemplo, el uso de nm para extraer la tabla de símbolos de un programa de muestra llamado CCtest produce el resultado siguiente:

# /usr/ccs/bin/nm CCtest ... [61] | 134549248| 53|FUNC |GLOB |0 |9 |__1cJTestClass2T5B6M_v_ [85] | 134549301| 47|FUNC |GLOB |0 |9 |__1cJTestClass2T6M_v_ [76] | 134549136| 37|FUNC |GLOB |0 |9 |__1cJTestClass2t5B6M_v_ [62] | 134549173| 71|FUNC |GLOB |0 |9 |__1cJTestClass2t5B6Mpc_v_ [64] | 134549136| 37|FUNC |GLOB |0 |9 |__1cJTestClass2t6M_v_ [89] | 134549173| 71|FUNC |GLOB |0 |9 |__1cJTestClass2t6Mpc_v_ [80] | 134616000| 16|OBJT |GLOB |0 |18 |__1cJTestClassG__vtbl_ [91] | 134549348| 16|FUNC |GLOB |0 |9 |__1cJTestClassJClassName6kM_pc_ ...

120 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace para perfilar y depurar un programa en C++

Nota – El código fuente y el archivo MAKE de CCtest se incluyen al final de este módulo.

A partir de esta salida, puede suponer correctamente que una serie de estos símbolos mezclados se asocia con una clase denominada TestClass, pero no puede determinar fácilmente si estos símbolos se asocian con constructores, destructores o funciones de clase.

El compilador de Sun Studio incluye las tres utilidades siguientes, que sirven para traducir los símbolos mezclados a sus equivalentes en C++: nm -C, dem, and c++filt.

Nota – Aquí se utiliza el software Sun Studio 10, pero los ejemplos se han probado con Sun Studio9y10.

Si la aplicación en C++ se ha compilado con gcc/g++, también cuenta con la posibilidad de volver a componer la aplicación. Además de c++filt, que reconoce los nombres mezclados de Sun Studio y GNU, el código abierto gc++filt encontrado en /usr/sfw/bin se puede utilizar para volver a componer los símbolos de la aplicación en g++.

Ejemplos: Símbolos de Sun Studio sin c++filt:

# nm CCtest | grep TestClass [65] | 134549280| 37|FUNC |GLOB |0 |9 |__1cJTestClass2t6M_v_ [56] | 134549352| 54|FUNC |GLOB |0 |9 |__1cJTestClass2t6Mi_v_ [92] | 134549317| 35|FUNC |GLOB |0 |9 |__1cJTestClass2t6Mpc_v_ ...

Símbolos de Sun Studio con c++filt:

# nm CCtest | grep TestClass | c++filt [65] | 134549280| 37|FUNC |GLOB |0 |9 |TestClass::TestClass()

Módulo 9 • Depuración de aplicaciones C++ con DTrace 121 Uso de DTrace para perfilar y depurar un programa en C++

[56] | 134549352| 54|FUNC |GLOB |0 |9 |TestClass::TestClass(int) [92] | 134549317| 35|FUNC |GLOB |0 |9 |TestClass::TestClass(char*) ...

Símbolos de g++ sin gc++filt:

[86] | 134550070| 41|FUNC |GLOB |0 |12 |_ZN9TestClassC1EPc [110] | 134550180| 68|FUNC |GLOB |0 |12 |_ZN9TestClassC1Ei [114] | 134549984| 43|FUNC |GLOB |0 |12 |_ZN9TestClassC1Ev ...

Símbolos de g++ con gc++filt:

# nm gCCtest | grep TestClass | gc++filt [86] | 134550070| 41|FUNC |GLOB |0 |12 |TestClass::TestClass(char*) [110] | 134550180| 68|FUNC |GLOB |0 |12 |TestClass::TestClass(int) [114] | 134549984| 43|FUNC |GLOB |0 |12 |TestClass::TestClass() ...

Y, finalmente, símbolos con nm -C:

[64] | 134549344| 71|FUNC |GLOB |0 |9 |TestClass::TestClass() [__1cJTestClass2t6M_v_] [87] | 134549424| 70|FUNC |GLOB |0 |9 |TestClass::TestClass(const char*) [__1cJTestClass2t6Mpkc_v_] [57] | 134549504| 95|FUNC |GLOB |0 |9 |TestClass::TestClass(int) [__1cJTestClass2t6Mi_v_]

Esta información permite crear una secuencia de DTrace para agregar en las llamadas a objetos asociadas con nuestro programa de prueba. Podemos utilizar el proveedor pid de DTrace para activar los sondeos asociados con nuestros símbolos en C++ mezclados.

Para probar la teoría de constructor/destructor, empezaremos efectuando los siguientes recuentos:

■ El número de objetos creados -- llamadas a new() ■ El número de objetos destruidos --llamadas a delete()

122 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace para perfilar y depurar un programa en C++

Utilice la siguiente secuencia para extraer los símbolos que corresponden a las funciones new() y delete() del programa CCtest:

# dem ‘nm CCtest | awk -F\| ’{ print $NF; }’‘ | egrep "new|delete" __1c2k6Fpv_v_ == void operator delete(void*) __1c2n6FI_pv_ == void*operator new(unsigned)

La secuencia de DTrace correspondiente se utiliza para activar los sondeos en new() y delete() (guardado como CCagg.d):

#!/usr/sbin/dtrace -s

pid$1::__1c2n6FI_pv_: { @n[probefunc] = count(); } pid$1::__1c2k6Fpv_v_: { @d[probefunc] = count(); }

END { printa(@n); printa(@d); }

Inicie el programa CCtest en una ventana; a continuación, ejecute la secuencia que acaba de crear en otra ventana, del modo siguiente:

# dtrace -s ./CCagg.d ‘pgrep CCtest‘ | c++filt

La salida de DTrace se dirige a través de c++filt para volver a componer los símbolos de C++, tomando en consideración la siguiente advertencia.

Módulo 9 • Depuración de aplicaciones C++ con DTrace 123 Uso de DTrace para perfilar y depurar un programa en C++

Precaución – No puede salir de la secuencia de DTrace con ^C, como lo haría normalmente, porque c++filt se podría desconectar junto con DTrace y no se obtendría ninguna salida. Para ver la salida de este comando, vaya a otra ventana del sistema y escriba:

# pkill dtrace

Utilice esta secuencia de pasos para el resto de los ejercicios: Ventana 1:

# ./CCtest

Ventana 2:

# dtrace -s scriptname | c++filt Ventana 3:

# pkill dtrace

La salida de la secuencia de agregación de la ventana 2 debería tener el siguiente formato:

void*operator new(unsigned) 12 void operator delete(void*) 8

Quizá estemos en lo cierto al afirmar que estamos creando más objetos de que los borramos. A continuación, comprobaremos las direcciones de memoria de los objetos e intentaremos hacer coincidir las instancias de new() y delete(). Las variables del argumento DTrace se utilizan para mostrar las direcciones asociadas con los objetos. Como el valor de retorno de new() contiene un puntero al objeto, veremos el mismo valor de puntero que arg0 en la

124 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace para perfilar y depurar un programa en C++

llamada a delete(). Tras haber realizado una ligera modificación en nuestra secuencia inicial, a continuación se presenta la siguiente secuencia, denominada CCaddr.d:

#!/usr/sbin/dtrace -s

#pragma D option quiet /* __1c2k6Fpv_v_ == void operator delete(void*) __1c2n6FI_pv_ == void*operator new(unsigned) */

/* return from new() */ pid$1::__1c2n6FI_pv_:return { printf("%s: %x\n", probefunc, arg1); }

/* call to delete() */ pid$1::__1c2k6Fpv_v_:entry { printf("%s: %x\n", probefunc, arg0); }

Ejecute esta secuencia:

# dtrace -s ./CCaddr.d ‘pgrep CCtest‘ | c++filt

Espere unos instantes y escriba lo siguiente en la ventana 3:

# pkill dtrace

Nuestra salida parece un patrón de repetición de tres llamadas a new() y dos llamadas a delete():

void*operator new(unsigned): 809e480 void*operator new(unsigned): 8068a70 void*operator new(unsigned): 809e4a0 void operator delete(void*): 8068a70 void operator delete(void*): 809e4a0

Módulo 9 • Depuración de aplicaciones C++ con DTrace 125 Uso de DTrace para perfilar y depurar un programa en C++

Al examinar la salida que se repite, puede verse un patrón. Parece que el primer new() del patrón de repetición no tiene ninguna llamada correspondiente a delete(). Llegados a este punto, hemos identificado el origen de la pérdida de memoria.

Continuemos con DTrace para ver qué más puede obtenerse de esta información. Todavía no conocemos el tipo de clase asociada con el objeto creado en la dirección 809e480.La inclusión de una llamada a ustack() en la entrada a new() es una pista. A continuación se incluye la modificación a nuestra secuencia anterior, que ahora se denomina CCstack.d:

#!/usr/sbin/dtrace -s

#pragma D option quiet

/* __1c2k6Fpv_v_ == void operator delete(void*) __1c2n6FI_pv_ == void*operator new(unsigned) */

pid$1::__1c2n6FI_pv_:entry { ustack(); } pid$1::__1c2n6FI_pv_:return { printf("%s: %x\n", probefunc, arg1); } pid$1::__1c2k6Fpv_v_:entry { printf("%s: %x\n", probefunc, arg0); }

Ejecute CCstack.d en la ventana 2 y escriba pkilldtrace en la ventana 3 para imprimir la salida siguiente:

# dtrace -s ./CCstack.d ‘pgrep CCtest‘ | c++filt

126 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace para perfilar y depurar un programa en C++

libCrun.so.1‘void*operator new(unsigned) CCtest‘main+0x19 CCtest‘0x8050cda void*operator new(unsigned): 80a2bd0

libCrun.so.1‘void*operator new(unsigned) CCtest‘main+0x57 CCtest‘0x8050cda void*operator new(unsigned): 8068a70

libCrun.so.1‘void*operator new(unsigned) CCtest‘main+0x9a CCtest‘0x8050cda void*operator new(unsigned): 80a2bf0 void operator delete(void*): 8068a70 void operator delete(void*): 80a2bf0

Los datos ustack() indican que se llama a new() desde main+0x19, main+0x57 y main+0x9a. Nos interesa el objeto asociado con la primera llamada a new(),enmain+0x19.

Con el fin de determinar el tipo de constructor al que se llama en main+0x19, podemos utilizar mdb del modo siguiente:

# gcore ‘pgrep CCtest‘ gcore: core.1478 dumped # mdb core.1478 Loading modules: [ libc.so.1 ld.so.1 ] > main::dis main: pushl %ebp main+1: movl %esp,%ebp main+3: subl $0x38,%esp main+6: movl %esp,-0x2c(%ebp) main+9: movl %ebx,-0x30(%ebp) main+0xc: movl %esi,-0x34(%ebp) main+0xf: movl %edi,-0x38(%ebp) main+0x12: pushl $0x8 main+0x14: call -0x2e4

Módulo 9 • Depuración de aplicaciones C++ con DTrace 127 Uso de DTrace para perfilar y depurar un programa en C++ main+0x19: addl $0x4,%esp main+0x1c: movl %eax,-0x10(%ebp) main+0x1f: movl -0x10(%ebp),%eax main+0x22: pushl %eax main+0x23: call +0x1d5 <__1cJTestClass2t5B6M_v_> ...

El constructor recibe el nombre de la llamada al nuevo desfase main+0x23. De este modo, hemos identificado una llamada al constructor __1cJTestClass2t5B6M_v_ que nunca se destruye. El uso de dem para volver a componer este símbolo produce:

# dem __1cJTestClass2t5B6M_v_ __1cJTestClass2t5B6M_v_ == TestClass::TestClass #Nvariant 1()

Una llamada a la nueva TestClass() de main+0x19 es la causa de la pérdida de memoria. Al examinar el archivo de origen CCtest.cc, encontramos:

... t = new TestClass(); cout << t->ClassName();

t = new TestClass((const char *)"Hello."); cout << t->ClassName();

tt = new TestClass((const char *)"Goodbye."); cout << tt->ClassName();

delete(t); delete(tt); ...

El primer uso de la variable t = new TestClass(); lo sobrescribe el segundo uso: t = new TestClass((const char *)"Hello.");. Se ha identificado la pérdida de memoria yse puede implementar una corrección.

128 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace para perfilar y depurar un programa en C++

El proveedor pid de DTrace permite activar un sondeo en cualquier instrucción asociada con un proceso que se esté examinando. Este ejemplo pretende modelizar el enfoque de DTrace para la depuración de procesos interactivos. Las funciones de DTrace utilizadas en este ejemplo son: agregaciones, visualización de valores de retorno y argumentos de funciones, y visualización de la pila de llamadas del usuario. Se han utilizado los comandos dem y c++filt del software Sun Studio y gc++filt en gcc para extraer los sondeos de funciones de la tabla de símbolos del programa y mostrar la salida de DTrace en un formato compatible con el origen. Archivos de origen creados para este ejemplo:

EJEMPLO 9–1 TestClass.h class TestClass { public: TestClass(); TestClass(const char *name); TestClass(int i); virtual ~TestClass(); virtual char *ClassName() const; private: char *str; };

TestClass.cc:

#include #include #include #include #include "TestClass.h"

TestClass::TestClass() { str=strdup("empty."); }

Módulo 9 • Depuración de aplicaciones C++ con DTrace 129 Uso de DTrace para perfilar y depurar un programa en C++

EJEMPLO 9–1 TestClass.h (Continuación)

TestClass::TestClass(const char *name) { str=strdup(name); }

TestClass::TestClass(int i) { str=(char *)malloc(128); sprintf(str, "Integer = %d", i); }

TestClass::~TestClass() { if ( str ) free(str); }

char *TestClass::ClassName() const { return str; }

EJEMPLO 9–2 CCtest.cc

#include #include #include #include #include "TestClass.h"

int main(int argc, char **argv) { TestClass *t; TestClass *tt;

while (1) { t = new TestClass(); cout << t->ClassName();

t = new TestClass((const char *)"Hello.");

130 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace para perfilar y depurar un programa en C++

EJEMPLO 9–2 CCtest.cc (Continuación)

cout << t->ClassName();

tt = new TestClass((const char *)"Goodbye."); cout << tt->ClassName();

delete(t); delete(tt); sleep(1); } }

EJEMPLO 9–3 Archivo MAKE

OBJS=CCtest.o TestClass.o PROGS=CCtest

CC=CC all: $(PROGS) echo "Done." clean: rm $(OBJS) $(PROGS)

CCtest: $(OBJS) $(CC) -o CCtest $(OBJS)

.cc.o: $(CC) $(CFLAGS) -c $<

Módulo 9 • Depuración de aplicaciones C++ con DTrace 131 132 10MÓDULO 10 Gestión de memoria con DTrace y MDB

Objetivos En este módulo utilizaremos lo que ha aprendido sobre el uso de DTrace para observar los procesos examinando un fallo de página. A continuación, incorporaremos depuración de bajo nivel con MDB para localizar el problema en el código.

Recursos adicionales Solaris Modular Debugger Guide Sun Microsystems, Inc., 2007.

133 Gestión de memoria del software Gestión de memoria del software La gestión de memoria de OpenSolaris utiliza estructuras de software denominadas segmentos para gestionar la memoria virtual de los procesos, así como el núcleo. La mayoría de las estructuras de datos del software de gestión de memoria se definen en /usr/include/vm/*.h. En este módulo, examinaremos el código y las estructuras de datos que se utilizan para controlar los fallos de las páginas.

134 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace y MDB para examinar la memoria virtual Uso de DTrace y MDB para examinar la memoria virtual El objetivo de este ejercicio es examinar un fallo de página con DTrace y MDB.

Resumen Empezaremos con una secuencia de DTrace para rastrear las acciones de un único fallo de página de un proceso concreto. La secuencia imprime la dirección virtual del usuario que provoca el fallo; a continuación, rastrea cada una de las funciones a las que se llama desde el momento del fallo hasta que se devuelve el control del fallo de la página. Utilizaremos la salida de la secuencia para determinar el código fuente que se debe examinar para obtener más información.

Nota – En este módulo, hemos agregado texto a la salida de código extensiva para guiar el ejercicio. Busque el símbolo <---- para localizar el texto asociado en la salida.

Módulo 10 • Gestión de memoria con DTrace y MDB 135 Uso de DTrace y MDB para examinar la memoria virtual Uso de DTrace en un fallo de página para un proceso único

1 Abra una ventana de terminal.

2 Cree un archivo llamado pagefault.d con la secuencia siguiente: #!/usr/sbin/dtrace -s

#pragma D option flowindent

pagefault:entry /execname == $$1/ { printf("fault occurred on address = %p\n", args[0]); self->in = 1; }

pagefault:return /self->in == 1/ { self->in = 0; exit(0); }

entry /self->in == 1/ { }

return /self->in == 1/ { }

3 Ejecute la secuencia en Mozilla.

136 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace y MDB para examinar la memoria virtual

Nota – Debe especificar mozilla-bin como nombre del ejecutable, ya que mozilla no coincide exactamente con el nombre. Se activan las afirmaciones, de modo que verá varias llamadas a, por ejemplo, mutex_owner(), que sólo se utiliza con ASSERT(). Las afirmaciones se activan sólo para los núcleos de depuración.

# ./pagefault.d mozilla-bin dtrace: script ’./pagefault.d’ matched 42626 probes CPU FUNCTION 0 -> pagefault fault occurred on address = fb985ea2

0 | pagefault:entry <-- i86pc/vm/vm_machdep.c or sun4/vm/vm_dep.c 0 -> as_fault <-- generic address space fault common/vm/vm_as.c 0 -> as_segat 0 -> avl_find <-- segments are in AVL tree 0 -> as_segcompar <-- search segments for segment 0 <- as_segcompar <-- containing fault address 0 -> as_segcompar <-- common/vm/vm_as.c 0 <- as_segcompar 0 -> as_segcompar 0 <- as_segcompar 0 -> as_segcompar 0 <- as_segcompar 0 -> as_segcompar 0 <- as_segcompar 0 -> as_segcompar 0 <- as_segcompar 0 -> as_segcompar 0 <- as_segcompar 0 -> as_segcompar 0 <- as_segcompar 0 <- avl_find 0 <- as_segat 0 -> segvn_fault<-- segment containing fault is found, (not SEGV) <-- common/vm/seg_vn.c 0 -> hat_probe <-- look for page table entry for page

Módulo 10 • Gestión de memoria con DTrace y MDB 137 Uso de DTrace y MDB para examinar la memoria virtual

<-- i86pc/vm/hat_i86.c or sfmmu/vm/hat_sfmmu.c 0 -> htable_getpage <-- page tables are hashed on x86 0 -> htable_getpte <-- i86pc/vm/htable.c 0 -> htable_lookup 0 <- htable_lookup 0 -> htable_va2entry 0 <- htable_va2entry 0 -> x86pte_get <-- return a page table entry 0 -> x86pte_access_pagetable 0 -> hat_kpm_pfn2va 0 <- hat_kpm_pfn2va 0 <- x86pte_access_pagetable 0 -> x86pte_release_pagetable 0 <- x86pte_release_pagetable 0 <- x86pte_get 0 <- htable_getpte 0 <- htable_getpage 0 -> htable_release 0 <- htable_release 0 <- hat_probe 0 -> fop_getpage <-- file operation to retrieve page(s) 0 -> ufs_getpage<--file in ufs fs(common/fs/ufs/ufs_vnops.c) 0 -> bmap_has_holes <-- check for sparse file 0 <- bmap_has_holes 0 -> page_lookup <-- check for page already in memory 0 -> page_lookup_create <-- common/vm/vm_page.c 0 <- page_lookup_create <-- create page if needed 0 <- page_lookup 0 -> ufs_getpage_miss <-- page wasn’t in memory 0 -> bmap_read <-- get block number of page from inode 0 -> bread_common 0 -> getblk_common 0 <- getblk_common 0 <- bread_common 0 <- bmap_read 0 -> pvn_read_kluster <-- read pages (common/vm/vm_pvn.c) 0 -> page_create_va <-- create some pages 0 <- page_create_va 0 -> segvn_kluster 0 <- segvn_kluster

138 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace y MDB para examinar la memoria virtual

0 <- pvn_read_kluster 0 -> pageio_setup <-- setup page(s) for io common/os/bio.c 0 <- pageio_setup 0 -> lufs_read_strategy <-- logged ufs read 0 -> bdev_strategy <-- read device common/os/driver.c 0 -> cmdkstrategy <-- common disk driver (cmdk(7D)) <-- common/io/dktp/disk/cmdk.c 0 -> dadk_strategy <-- direct attached disk (dad(7D)) <-- for ide disks(common/io/dktp/dcdev/dadk.c) <-- driver sets up dma and starts page in 0 <- dadk_strategy 0 <- cmdkstrategy 0 <- bdev_strategy 0 -> biowait <-- wait for pagein complete common/os/bio.c 0 -> sema_p <-- wakeup sema_v from completion interrupt 0 -> swtch <-- let someone else run(common/disp/disp.c) 0 -> disp <-- dispatch to next thread to run 0 <- disp 0 -> resume <-- actual switching occurs here <-- intel/ia32/ml/swtch.s 0 -> savectx <-- save old context 0 <- savectx <-- someone else is running here... 0 -> restorectx <-- restore context (we’re awakened) 0 <- restorectx 0 <- resume 0 <- swtch 0 <- sema_p 0 <- biowait 0 -> pageio_done <-- undo pageio_setup 0 <- pageio_done 0 -> pvn_plist_init 0 <- pvn_plist_init 0 <- ufs_getpage_miss <-- page is in memory 0 <- ufs_getpage 0 <- fop_getpage 0 -> segvn_faultpage <-- call hat to load pte(s) for page(s) 0 -> hat_memload 0 -> page_pptonum <-- get page frame number 0 <- page_pptonum

Módulo 10 • Gestión de memoria con DTrace y MDB 139 Uso de DTrace y MDB para examinar la memoria virtual

0 -> hati_mkpte <-- build page table entry 0 <- hati_mkpte 0 -> hati_pte_map <-- locate entry in page table 0 -> x86_hm_enter 0 <- x86_hm_enter 0 -> hment_prepare 0 <- hment_prepare 0 -> x86pte_set <-- fill in pte into page table 0 -> x86pte_access_pagetable 0 -> hat_kpm_pfn2va 0 <- hat_kpm_pfn2va 0 <- x86pte_access_pagetable 0 -> x86pte_release_pagetable 0 <- x86pte_release_pagetable 0 <- x86pte_set 0 -> hment_assign 0 <- hment_assign 0 -> x86_hm_exit 0 <- x86_hm_exit 0 <- hati_pte_map 0 <- hat_memload 0 <- segvn_faultpage 0 <- segvn_fault 0 <- as_fault 0 <- pagefault

# Tenga en cuenta que la salida anterior se ha reducido. En un nivel más elevado, ha ocurrido lo siguiente con el fallo de página:

■ Se llama a la rutina pagefault() para controlar los fallos de página. ■ La rutina pagefault() llama a as_fault() para controlar los fallos de un espacio de dirección específico.

140 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace y MDB para examinar la memoria virtual

■ as_fault() recorre el árbol AVL de estructuras seg en busca de un segmento que contenga la dirección con el fallo. Si no lo encuentra, se envía al proceso la señal SIGSEGV (violación de segmentación). ■ Si se encuentra, se llama a un control de fallos específico del segmento. Para la mayoría de los segmentos, es segvn_fault(). ■ segvn_fault() busca la página con el fallo que ya esté en la memoria. Si la página ya existe pero se ha liberado, se excluye de la lista libre. Si la página no existe aún, es necesario asignarla. En este caso, la página no se encuentra todavía en la memoria, de modo que se llama a ufs_getpage(). ■ ufs_getpage() busca los números de bloque de las páginas del sistema de archivos llamando a bmap_read(). ■ A continuación, se llama a una rutina de estrategia del controlador de dispositivos. Consulte strategy(9E) para ver una descripción general de las tareas que lleva a cabo la rutina de estrategia. ■ Mientras se lee la página, se bloquea el subproceso que genera el fallo de página (se apaga) mediante una llamada a swtch(). En este punto, se ejecutan otros subprocesos. ■ Una vez completada la E/S de paginación, el control de interrupción del controlador del disco activa el subproceso mozilla-bin bloqueado. ■ El controlador del disco devuelve segvn_fault() a través del código del sistema de archivos. ■ A continuación, segvn_fault() llama a segvn_faultpage(). ■ segvn_faultpage() llama a la capa HAT (Hardware Address Translation) para cargar la tabla de página entry(s) (PTE) para la página.

Módulo 10 • Gestión de memoria con DTrace y MDB 141 Uso de DTrace y MDB para examinar la memoria virtual

■ En este punto, la dirección virtual que ha ocasionado el fallo de página debe asignarse a una página física válida. Cuando se devuelve pagefault(), se volverá a intentar la instrucción que causa el fallo de página, que ahora deberá llevarse a cabo correctamente.

4 Utilice mdb para examinar las estructuras de datos del núcleo y localice la página de la memoria física que corresponde al fallo de la forma que se indica a continuación:

a. Abra una ventana de terminal.

b. Busque el número de segmentos que utiliza Mozilla mediante pmap: # pmap -x ‘pgrep mozilla-bin‘ | wc 368 2730 23105 # El resultado muestra que hay 368 segmentos.

Nota – La búsqueda del segmento que contiene la dirección del fallo ha encontrado el segmento correcto después de 8 segmentos. Consulte las llamadas a as_segcompar en la salida de DTrace más arriba. El uso del árbol AVL acorta la búsqueda.

c. Utilice mdb para localizar el segmento que contiene la dirección del fallo.

Nota – Si desea continuar, puede utilizar: ::log /tmp/logfile en mdb y luego !vi /tmp/logfile para realizar la búsqueda. Asimismo, puede ejecutar mdb en un búfer del editor.

142 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace y MDB para examinar la memoria virtual

# mdb -k Loading modules: [ unix krtld genunix specfs dtrace ufs ip sctp usba random fctl s1394 nca lofs crypto nfs audiosup sppp cpc fcip ptm ipc ] > ::ps !grep mozilla-bin <-- find the mozilla-bin process R 933 919 887 885 100 0x42014000 ffffffff81d6a040 mozilla-bin

> ffffffff81d6a040::print proc_t p_as | ::walk seg | ::print struct seg <-- Lots of output has been omitted... --> { s_base = 0xfb800000 <-- the seg we want, fault addr (fb985ea2) s_size = 0x561000 <-- greater/equal to base and < base+size s_szc = 0 s_flags = 0 s_as = 0xffffffff828b61d0 s_tree = { avl_child = [ 0xffffffff82fa7920, 0xffffffff82fa7c80 ] avl_pcb = 0xffffffff82fa796d } s_ops = segvn_ops s_data = 0xffffffff82d85070 } <-- and lots more output omitted -->

> ffffffff82d85070::print segvn_data_t <-- from s_data { lock = { _opaque=[0] } segp_slock = { _opaque=[0] } pageprot = 0x1 prot = 0xd maxprot = 0xf type = 0x2 offset = 0 vp = 0xffffffff82f9e480 <-- points to a vnode_t anon_index = 0 amp = 0 <-- we’ll look at anonymous space later

Módulo 10 • Gestión de memoria con DTrace y MDB 143 Uso de DTrace y MDB para examinar la memoria virtual

vpage = 0xffffffff82552000 cred = 0xffffffff81f95018 swresv = 0 advice = 0 pageadvice = 0x1 flags = 0x490 softlockcnt = 0 policy_info = { mem_policy = 0x1 mem_reserved = 0 } }

> ffffffff82f9e480::print vnode_t v_path v_path = 0xffffffff82f71090 "/usr/sfw/lib/mozilla/components/libgklayout.so"

> fb985ea2-fb800000=K <-- offset within segment 185ea2 <-- rounding down gives 185000 (4kpage size)

> ffffffff82f9e480::walk page !wc <-- walk list of pages on vnode_t 1236 1236 21012 <-- 1236 pages,(not all are necessarily valid)

> ffffffff82f9e480::walk page | ::print page_t<-- walk pg list on vnode <-- lots of pages omitted in output --> { p_offset = 0x185000 <-- here is matching page p_vnode = 0xffffffff82f9e480 p_selock = 0 p_selockpad = 0 p_hash = 0xfffffffffae21c00 p_vpnext = 0xfffffffffaca9760 p_vpprev = 0xfffffffffb3467f8 p_next = 0xfffffffffad8f800 p_prev = 0xfffffffffad8f800 p_lckcnt = 0 p_cowcnt = 0 p_cv = { _opaque = 0 }

144 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace y MDB para examinar la memoria virtual

p_io_cv = { _opaque = 0 } p_iolock_state = 0 p_szc = 0 p_fsdata = 0 p_state = 0 p_nrm = 0x2 p_embed = 0x1 p_index = 0 p_toxic = 0 p_mapping = 0xffffffff82d265f0 p_pagenum = 0xbd62 <-- the page frame number of page p_share = 0 p_sharepad = 0 p_msresv_1 = 0 p_mlentry = 0x185 p_msresv_2 = 0 }

<-- and lots more output omitted -->

> bd62*1000=K <-- multiple page frame number time page size (hex) bd62000 <-- here is physical address of page

> bd62000+ea2,10/K <-- dump 16 64-bit hex values at physical address 0xbd62ea2: 2ccec81ec8b55 e8575653f0e48300 32c3815b00000000 5d89d46589003ea7 840ff6850c758be0 e445c7000007df 1216e8000000 dbe850e4458d5650 7d830cc483ffeeea 791840f00e4 c085e8458904468b 500c498b088b2474 8b17eb04c483d1ff e8458de05d8bd465 c483ffeeeac8e850 458b0000074ce904

> bd62000+ea2,10/ai <-- data looks like code, let’s try dumping as code 0xbd62ea2: 0xbd62ea2: pushq %rbp 0xbd62ea3: movl %esp,%ebp 0xbd62ea5: subl $0x2cc,%esp 0xbd62eab: andl $0xfffffff0,%esp 0xbd62eae: pushq %rbx

Módulo 10 • Gestión de memoria con DTrace y MDB 145 Uso de DTrace y MDB para examinar la memoria virtual

0xbd62eaf: pushq %rsi 0xbd62eb0: pushq %rdi 0xbd62eb1: call +0x5 <0xbd62eb6> 0xbd62eb6: popq %rbx 0xbd62eb7: addl $0x3ea732,%ebx 0xbd62ebd: movl %esp,-0x2c(%rbp) 0xbd62ec0: movl %ebx,-0x20(%rbp) 0xbd62ec3: movl 0xc(%rbp),%esi 0xbd62ec6: testl %esi,%esi 0xbd62ec8: je +0x7e5 <0xbd636ad> 0xbd62ece: movl $0x0,-0x1c(%rbp)

> ffffffff81d6a040::context <--change context from kernel to mozilla-bin debugger context set to proc ffffffff81d6a040, the address of process

> fb985ea2,10/ai <-- and dump from faulting virtual address 0xfb985ea2: 0xfb985ea2: pushq %rbp <-- looks like a match 0xfb985ea3: movl %esp,%ebp 0xfb985ea5: subl $0x2cc,%esp 0xfb985eab: andl $0xfffffff0,%esp 0xfb985eae: pushq %rbx 0xfb985eaf: pushq %rsi 0xfb985eb0: pushq %rdi 0xfb985eb1: call +0x5 <0xfb985eb6> 0xfb985eb6: popq %rbx 0xfb985eb7: addl $0x3ea732,%ebx 0xfb985ebd: movl %esp,-0x2c(%rbp) 0xfb985ec0: movl %ebx,-0x20(%rbp) 0xfb985ec3: movl 0xc(%rbp),%esi 0xfb985ec6: testl %esi,%esi 0xfb985ec8: je +0x7e5 <0xfb9866ad> 0xfb985ece: movl $0x0,-0x1c(%rbp)

> 0::context debugger context set to kernel

> ffffffff81d6a040::print proc_t p_as <-- get as for mozilla-bin p_as = 0xffffffff828b61d0

146 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Uso de DTrace y MDB para examinar la memoria virtual

> fb985ea2::vtop -a ffffffff828b61d0 <-- check our work virtual fb985ea2 mapped to physical bd62ea2 <--physical address matches Una vez encontrado el segmento, se imprime la estructura segvn_data. En este segmento, vnode_t asigna los datos del segmento. vnode_t contiene una lista de páginas que "pertenecen" a vnode_t. Localizamos la página correspondiente al desplazamiento del segmento. Cuando se localiza page_t, se obtiene el número de imagen de la página. A continuación, el número de imagen de la página se convierte en una dirección física y se examinan algunos datos de la dirección. Estos datos son código. Se comprueba la dirección física utilizando el comando vtop (virtual a físico) mdb.

d. Información adicional: recorra las tablas de página del proceso para ver cómo una dirección virtual se convierte en una dirección física.

Módulo 10 • Gestión de memoria con DTrace y MDB 147 148 11MÓDULO 11 Depuración de controladores con DTrace

Objetivos El objetivo de este módulo es aprender a utilizar DTrace para depurar los proyectos de desarrollo de controladores estudiando un caso.

149 Asignación de puertos al controlador smbfs de Linux al sistema operativo Solaris Asignación de puertos al controlador smbfs de Linux al sistema operativo Solaris Este caso se centra en el uso de la función de DTrace para el desarrollo de controladores de dispositivos.

Desde siempre, la depuración de un controlador de dispositivos ha requerido que los desarrolladores utilicen llamadas a funciones como cmn_err() para registrar la información de diagnóstico en el archivo /var/adm/messages. Esta ardua tarea implica realizar suposiciones, volver a compilar y reiniciar el sistema para descubrir errores de código del software. Los desarrolladores con conocimientos de lenguaje ensamblador pueden utilizar adb para crear módulos personalizados en C para que mdb diagnostique los errores de software. Sin embargo, el enfoque que siempre se ha dado al desarrollo y la depuración del núcleo resulta muy lento.

DTrace ofrece un método abreviado para realizar diagnósticos. En lugar de tener que buscar en el archivo /var/adm/messages o las páginas de salida truss, se puede utilizar DTrace para capturar información únicamente en los eventos que desee ver el desarrollador. Veamos algunos ejemplos para ilustrar mejor las ventajas de DTrace.

En primer lugar, cree una plantilla de controlador smbfs basada en el controlador nfs de Sun. Tras la compilación correcta del controlador, compruebe que se pueda cargar y descargar sin problemas. En primer lugar, copie el controlador de prototipo en /usr/kernel/fs e intente aplicar modload manualmente:

# modload /usr/kernel/fs/smbfs can’t load module: Out of memory or no room in system tables

El archivo /var/adm/messages contiene:

150 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Asignación de puertos al controlador smbfs de Linux al sistema operativo Solaris genunix: [ID 104096 kern.warning] WARNING: system call missing from bind file

Al buscar el mensaje que indica que falta la llamada al sistema, vemos que se encuentra en la función mod_getsysent() en el archivo modconf.c, en una llamada fallida a mod_getsysnum.En lugar de buscar manualmente en el flujo de mod_getsysnum() de los archivos de origen uno a uno, a continuación se incluye una secuencia de DTrace sencilla para permitir todos los eventos de entrada y retorno en el proveedor fbt (Function Boundary Tracing) una vez se ha especificado mod_getsynum().

#!/usr/sbin/dtrace -s

#pragma D option flowindent

fbt::mod_getsysnum:entry /execname == "modload"/ { self->follow = 1; }

fbt::mod_getsysnum:return { self->follow = 0; trace(arg1); }

fbt:::entry /self->follow/ { }

fbt:::return /self->follow/ { trace(arg1); }

Módulo 11 • Depuración de controladores con DTrace 151 Asignación de puertos al controlador smbfs de Linux al sistema operativo Solaris

Nota – trace(arg1) muestra el valor de retorno de la función.

Al ejecutar esta secuencia y ejecutar el comando modload en otra ventana, se obtiene la salida siguiente:

# ./mod_getsysnum.d dtrace: script ’./mod_getsysnum.d’ matched 35750 probes

CPU FUNCTION 0 -> mod_getsysnum 0 -> find_mbind 0 -> nm_hash 0 <- nm_hash 41 0 -> strcmp 0 <- strcmp 4294967295 0 -> strcmp 0 <- strcmp 7 0 <- find_mbind 0 0 <- mod_getsysnum 4294967295

El causante es find_mbind() que devuelve '0', o nm_hash() que devuelve '41'. Si examinamos rápidamente find_mbind(), veremos que un valor de retorno de 0 indica un estado de error. Al ver el origen de find_mbind() en /usr/src/uts/common/os/modsubr.c, vemos que estamos buscando una cadena char en una tabla de hash. A continuación, mostraremos el contenido de la cadena de búsqueda y la tabla de hash utilizando DTrace.

Para ver el contenido de la cadena de búsqueda, agregamos un seguimiento strcmp() a la secuencia mod_getsysnum.d anterior:

fbt::strcmp:entry {

152 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Asignación de puertos al controlador smbfs de Linux al sistema operativo Solaris

printf("name:%s, hash:%s", stringof(arg0), stringof(arg1)); }

Éstos son los resultados de nuestro próximo intento de cargar el controlador:

# ./mod_getsysnum.d dtrace: script ’./mod_getsysnum.d’ matched 35751 probes CPU FUNCTION 0 -> mod_getsysnum 0 -> find_mbind 0 -> nm_hash 0 <- nm_hash 41 0 -> strcmp 0 | strcmp:entry name:smbfs, hash:timer_getoverrun 0 <- strcmp 4294967295 0 -> strcmp 0 | strcmp:entry name:smbfs, hash:lwp_sema_post 0 <- strcmp 7 0 <- find_mbind 0 0 <- mod_getsysnum 4294967295

Estamos buscando smbfs en una tabla de hash y no se encuentra. ¿Cómo se coloca smbfs en esta tabla de hash? Si volvemos a find_mbind(), observamos que la variable sb_hashtab de la tabla de hash se pasa a la función nm_hash() que falla.

Una búsqueda rápida en el código fuente muestra que sb_hashtab se inicia con una llamada a read_binding_file(), que toma como argumentos un archivo config, la tabla de hash y un puntero a función. Al seguir explorando el código fuente, veremos que el contenido del archivo config se define como /etc/name_to_sysnum en el archivo /usr/src/uts/common/os/modctl.c. Al parecer, hemos olvidado incluir una entrada de configuración para el

Módulo 11 • Depuración de controladores con DTrace 153 Asignación de puertos al controlador smbfs de Linux al sistema operativo Solaris

controlador. Agregue lo siguiente al archivo /etc/name_to_sysnum y reinicie.

’smbfs 177’ (read_binding_file() is read once at boot time.)

Tras reiniciar, el controlador se puede cargar correctamente.

# modload /usr/kernel/fs/smbfs

Compruebe que el controlador esté cargado con el comando modinfo:

# modinfo | grep smbfs 160 feb21a58 351ac 177 1 smbfs (SMBFS syscall,client,comm) 160 feb21a58 351ac 24 1 smbfs (network filesystem) 160 feb21a58 351ac 25 1 smbfs (network filesystem version 2) 160 feb21a58 351ac 26 1 smbfs (network filesystem version 3)

Nota – Recuerde que este controlador se basa en una plantilla nfs, que explica esta salida.

Asegúrese de que también pueda descargar el módulo:

# modunload -i 160 can’t unload the module: Device busy

Esto se debe probablemente a un valor de retorno EBUSY errno. Dado que el controlador smbfs es un módulo cargado, tenemos acceso a todas las funciones de smbfs:

#dtrace -l fbt:smbfs:: | wc -l 1002

Sorprendente. Sin necesidad de código especial, ahora tenemos acceso a la entrada 1002 y los eventos de retorno que contiene el controlador. Estos controles de la función 1002 permiten

154 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Asignación de puertos al controlador smbfs de Linux al sistema operativo Solaris

depurar el trabajo sin necesidad de ninguna versión especial de "código instrumentado" del controlador. A continuación, supervisaremos todas las llamadas smbfs cuando se llama a modunload, utilizando esta secuencia de DTrace sencilla:

#!/usr/sbin/dtrace -s

#pragma D option flowindent

fbt:smbfs::entry { }

fbt:smbfs::return { trace(arg1); }

Parece que modunload no puede acceder al código smbfs. Utilicemos DTrace para buscar en modunload con esta secuencia:

#!/usr/sbin/dtrace -s

#pragma D option flowindent

fbt::modunload:entry { self->follow = 1; trace(execname); trace(arg0); }

fbt::modunload:return { self->follow = 0; trace(arg1); }

Módulo 11 • Depuración de controladores con DTrace 155 Asignación de puertos al controlador smbfs de Linux al sistema operativo Solaris

fbt:::entry /self->follow/ { }

fbt:::return /self->follow/ { trace(arg1); }

Here’s the output of this script:

# ./modunload.d dtrace: script ’./modunload.d’ matched 36695 probes CPU FUNCTION 0 -> modunload modunload 160 0 | modunload:entry 0 -> mod_hold_by_id 0 -> mod_circdep 0 <- mod_circdep 0 0 -> mod_hold_by_modctl 0 <- mod_hold_by_modctl 0 0 <- mod_hold_by_id 3602566648 0 -> moduninstall 0 <- moduninstall 16 0 -> mod_release_mod 0 -> mod_release 0 <- mod_release 3602566648 0 <- mod_release_mod 3602566648 0 <- modunload 16

Observe que el valor de retorno EBUSY '16' procede de moduninstall. Examinemos el código fuente de moduninstall. moduninstall devuelve EBUSY en algunas ubicaciones, de modo que tomaremos en consideración las siguientes posibilidades:

156 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Asignación de puertos al controlador smbfs de Linux al sistema operativo Solaris

1. if (mp->mod_prim || mp->mod_ref || mp->mod_nenabled != 0) return (EBUSY); 2. if ( detach_driver(mp->mod_modname) != 0 ) return (EBUSY); 3. if ( kobj_lookup(mp->mod_mp, "_fini") == NULL ) 4. A failed call to smbfs _fini() routine

No es posible acceder directamente a todas estas posibilidades, pero las abordaremos mediante un proceso de eliminación. Utilizaremos la secuencia siguiente para ver el contenido de las diferentes estructuras y valores de retorno de moduninstall:

#!/usr/sbin/dtrace -s

#pragma D option flowindent

fbt::moduninstall:entry { self->follow = 1; printf("mod_prim:%d\n", ((struct modctl *)arg0)->mod_prim); printf("mod_ref:%d\n", ((struct modctl *)arg0)->mod_ref); printf("mod_nenabled:%d\n", ((struct modctl *)arg0)->mod_nenabled); printf("mod_loadflags:%d\n", ((struct modctl *)arg0)->mod_loadflags); }

fbt::moduninstall:return { self->follow = 0; trace(arg1); }

fbt::kobj_lookup:entry /self->follow/ {

Módulo 11 • Depuración de controladores con DTrace 157 Asignación de puertos al controlador smbfs de Linux al sistema operativo Solaris

}

fbt::kobj_lookup:return /self->follow/ { trace(arg1); }

fbt::detach_driver:entry /self->follow/ { }

fbt::detach_driver:return /self->follow/ { trace(arg1); }

This script produces the following output:

# ./moduninstall.d dtrace: script ’./moduninstall.d’ matched 6 probes CPU FUNCTION 0 -> moduninstall mod_prim:0 mod_ref:0 mod_nenabled:0 mod_loadflags:1 0 -> detach_driver 0 <- detach_driver 0 0 -> kobj_lookup 0 <- kobj_lookup 4273103456 0 <- moduninstall 16

Al comparar esta salida con el código, vemos que el fallo no se debe a los valores de la estructura mp o los valores de retorno de detach_driver() de kobj_lookup(). Por tanto, si seguimos un proceso de eliminación, debe ser el estado devuelto mediante la

158 Introducción a los sistemas operativos: uso del proyecto OpenSolaris • Septiembre de 2007 Asignación de puertos al controlador smbfs de Linux al sistema operativo Solaris llamada status = (*func)();, que llama a la rutina smbfs _fini(). Éste es el contenido de la rutina smbfs _fini(): int _fini(void) { /* don’t allow module to be unloaded */ return (EBUSY); }

Al cambiar el valor de retorno a '0' y volver a compilar el código se obtiene un controlador que podemos cargar y descargar, por lo que habremos completado el objetivo de este ejercicio. En estos ejemplos hemos utilizado exclusivamente el proveedor Function Boundary Tracing. Tenga en cuenta que fbt es sólo uno de los múltiples proveedores de DTrace.

Módulo 11 • Depuración de controladores con DTrace 159 160 APÉNDICEA A Recursos de OpenSolaris

Para obtener más información, asistencia y formación, utilice los recursos siguientes.

■ Documentación de la comunidad: http://opensolaris.org/os/community/documentation ■ Documentación de Sun: http://www.sun.com/documentation ■ Asistencia de Sun: http://www.sun.com/support ■ Formación de Sun: Sun ofrece una gama completa de opciones de formación y certificación profesional de Solaris para ayudarle a aplicar esta potente plataforma y conseguir un mayor éxito en sus operaciones. Para obtener información adicional sobre la formación de Solaris, visite:http://www.sun.com/ training/catalog/operating_systems/index.xml

161 162