El uso de Espacios de Nombres en Plan 9

Rob Pike

Dave Presotto

Ken Thompson

Howard Trickey

Phil Winterbottom

??????.MH

USA

ABSTRACT

Plan 9 es un sistema distribuido creado en el Computing Sciences Research Center de los Laboratorios Bell de AT&T (ahora Lucent Technologies, Bell Labs) durante los últimos años. Su objetivo es proporcionar un sistema de calidad para el desarrollo de software y la computación en general utilizando hardware heterogeneo y un software mínimo. Un sistema Plan 9 comprende servidores de ficheros y de CPU en un lugar centralizado conectados mediante redes rápidas. Mediante redes más lentas se contecta con máquinas de tipo estación de trabajo que actúan como terminales. Plan 9 demuestra que mediante una serie de abstracciones cuidadosamente implementadas es posible producir un sistema operativo pequeño que proporcione soporte para grandes sistemas en una varidad de arquitecturas y redes. Los cimientos del sistema se basan en dos ideas: un espacio de nombres por proceso y un sencillo protocolo de sistema de ficheros orientado a mensajes.

El sistema operativo para los servidores de CPU y los terminales está estructurado como un nucleo tradicional: una sola imagen compilada que contiene código de gestión de recursos, control de procesos, procesos de usuario, memoria virtual y E/S. Debido a que el servidor de ficheros es una máquina separada, el sistema de ficheros no va compilado dentro, pero sí el manejo del espacio de nombres, algo propio de cada proceso. El nucleo entero para la máquina multiprocesador SGI Power Series ocupa 25000 lineas de código en C, la mayor parte del cual se ocupa del manejo de red, incluyendo Ethernet y la suite de protocolos de Internet. Menos de 1500 lineas son específicas de cada máquina, y un nucleo funcional con E/S mínima puede montarse con un total de 6000 lineas. [Pike90]

El sistema es relativamente pequeño por varias razones. Primero, todo es nuevo: no ha tenido tiempo de que se le acumulen los parches y las características de otros sistemas. También, aparte del protocolo de red, no se adhiere a ningún interfaz externo; en particular, no es compatible con UNIX. La economía se consigue con una selección cuidadosa de servicios e interfaces. Finalmente, en lo posible, el sistema se construye en base a dos ideas simples: cada recurso del sistema, sea local o remoto, se presenta mediante un sistema de ficheros jerárquico; y un proceso de usuario ensambla una vista privada del sistema construyendo un espacio de nombres de ficheros que conecta estos recursos. [Needham]

Protocolo de ficheros

Todos los recursos en Plan 9 parecen sistemas de ficheros. Esto no significa que sean repositorios para ficheros permanentes en disco, sino que el interfaz con ellos es orientado a ficheros: encontrar ficheros (recursos) en un arbol de nombres jerárquico, engancharse a ellos por su nombre, acceder a sus contenidos por medio de llamadas read y write. Hay docenas de tipos de sistemas de ficheros en Plan 9, pero solo unos pocos presentan ficheros tradicionales. En este nivel de abstracción, los ficheros en Plan 9 son similares a objetos, excepto que los ficheros ya tienen un nombre, métodos de acceso y de protección que deben ser creados de nuevo para los objetos. Los lectores expertos en objetos, pueden aprovechar el resto de este documento para estudiar la forma de hacer que los objetos parezcan ficheros.

El interfaz con sistemas de ficheros está definido por un protocolo, llamado 9P, análogo, aunque diferente, al protocolo NFS. Este protocolo habla de ficheros, no de bloques; dada una conexión con el directorio raíz de un servidor de ficheros, los mensajes 9P navegan por la jerarquía de ficheros, abren ficheros para E/S, y leen o escriben bytes en los ficheros. 9P contiene 17 tipos de mensajes: 3 para inicialización y autenticación de una conexión y 14 para manipulación de objetos. Los mensajes se generan por el nucleo como respuesta a solicitudes de E/S del usuario o del propio nucleo. Este es un vistazo rápido a los tipos de mensajes. Los mensajes auth y attach autentican una conexión, establecida por medios externos a 9P, y validan a su usuario. El resultado es un canal ?????? que apunta a la raíz del servidor. that points to the root of the server. ?????? El mensaje clone crea un nuevo canal idéntico a uno existente, que puede ser movido a un fichero del servidor usando el mensaje walk para descender cada nivel en la jerarquía. Los mensajes stat y wstat leen y escriben los atributos del fichero al que apunta el canal. El mensaje open prepara el canal para su uso mediante read o write que acceden al contenido del fichero, mientras que create y remove realizan la acción que su nombre indica. El mensaje clunk descarta un canal sin afectar al fichero. Ninguno de los mensajes 9P considera el cacheo; se proporcionan cachés, en caso de necesidad, o bien dentro del servidor (caché centralizado) o implementándolo como un sistema de ficheros transparente entre el cliente y la conexión 9P con el servidor (caché de cliente).

Por eficiencia, la conexión a sistemas de ficheros residentes en el nucleo, incorrectamente llamados dispositivos, se realiza mediante llamadas normales, en lugar de llamadas remotas. Los procedimientos corresponden uno a uno con tipos de mensajes 9P. Localmente cada canal tiene una estructura de datos asociada que guarda un campo de tipo usado para indexar una tabla de llamadas a procedimiento, un conjunto por tipo de sistema de ficheros, análogo a seleccionar el conjunto de métodos de un objeto. En sistemas de ficheros residentes en el nucleo, el dispositivo mount, convierte las llamadas locales a procedimientos 9P en mensajes RPC a servicios remotos sobre un protocolo de transporte proporcionado externamente como TCP o IL, un nuevo protocolo de datagrama fiable, o sobre un pipe a un proceso de usuario. Llamadas a write y read transmiten los mensajes sobre la capa de transporte. El dispositivo mount es el único puente entre el interfaz procedural que ven los programas de usuario y los servicios remotos y de nivel de usuario. Hace toda la clasificación, manejo de buffers y multiplexado y es el único mecanismo íntegramente RPC de Plan 9. En realidad es un objeto proxy. No hay compilador de stubs RPC; en lugar de eso, el driver de montaje y todos los servidores simplemente comparten una librería que empaqueta y desempaqueta mensajes 9P.

Ejemplos

Un tipo de sistema de ficheros sirve ficheros permanentes desde el servidor de ficheros principal, un sistema stand-alone munltiprocesador con una jukebox optica WORM de 350 gigabytes que guarda los datos, precedido por un caché de bloques que comprende 7 gigabytes de disco magnético y 128 megabytes de RAM. Los clientes se conectan al servidor de ficheros usando alguna de las múltiples redes y protocolos y accede a los ficheros usando 9P. El servidor de ficheros ejecuta un sistema operativo distinto y no tiene soporte para procesos de usuario; aparte de un conjunto restringido de comandos disponibles en la consola, todo lo que hace es contestar a mensajes 9P de sus clientes.

????? Diariamente, a las 5:00 AM, el servidor de ficheros hace un barrido por los bloques del caché y marca los bloques sucios para ser copiados. Once a day, at 5:00 AM, the file server sweeps through the cache blocks and marks dirty blocks copy-on-write. ????? Crea una copia del directorio raíz y la etiqueta con la fecha actual, por ejemplo 1995/0314. Luego empieza un proceso en background para copiar los bloques ???????? sucios ???????? en el WORM. El resultado es que el servidor retiene una imagen del sistema de ficheros tal como estaba cada mañana. El conjunto de antiguos directorios raíz es accesible usando 9P, así que un cliente puede examinar los ficheros de backup usando comandos normales. Tener un servicio de backup implementado como un sistema de ficheros normal tiene sus ventajas. La más obvia es que se puede acceder a él con comandos ordinarios. Por ejemplo, para ver cuándo se ha reparado un fallo

El servidor de ficheros es solamente un tipo de sistema de ficheros. El nucleo proporciona un número inusual de servicios como sistemas locales de ficheros. Estos servicios no estan limitados a dispositivos de E/S como discos. Incluyen dispositivos de red y sus protocolos asociados, la pantalla y el ratón, una representación de procesos similar a /proc [Killian], los pares nombre/valor que forman el entorno pasado a cada nuevo proceso, servicios de profiling, y otros recursos. Cada uno de ellos se representa como un sistema de ficheros — directorios que contienen conjuntos de ficheros — pero los ficheros que lo constituyen no representan almacenamiento permanente en disco. Son más parecidos a dispositivos de UNIX.

Por ejemplo, el dispositivo console contiene el fichero /dev/cons, simirar al fichero de UNIX /dev/console: cuando es escribe en él, /dev/cons agrega el dato en la pantalla; cuando se lee, devuelve los caracteres que se han tecleado. Otros ficheros del dispositivo console son /dev/time, el número de segundos desde epoch, /dev/cputime, el tiempo de computación usado por el proceso que está leyendo el dispositivo, /dev/pid, el id de dicho proceso, y /dev/user, el nombre de login del usuario que está accediendo al dispositivo. Todos estos ficheros contienen texto, no números binarios, así que su uso está libre de problemas de orden de bytes. Sus contenidos se sintetizan bajo demanda cuando se leen; cuando se escriben, modifican estructuras de datos del nucleo.

El dispositivo process contiene un directorio por proceso local activo, que se llama igual que el id numérico del proceso: /proc/1, /proc/2, etc. Cada directorio contiene un conjunto de ficheros que acceden al proceso. Por ejemplo, en cada directorio, el fichero mem es una imagen de la memoria virtual del proceso que puede ser leida o escrita para debugging. El fichero text es una especie de enlace al fichero desde el cual el proceso fué ejecutado; puede abrirse para leer las tablas de símbolos para el proceso. El fichero ctl puede escribirse con mensajes de texto como stop o kill para controlar la ejecución del proceso. El fichero status contiene una linea de formato fijo de texto con información sobre el proceso: su nombre, dueño, estado, etc. Pueden escribirse cadenas de texto al fichero note para que sean enviadas al proceso al como notes, análogas a las señales de UNIX. Proporcionando estos servicios como E/S textual sobre ficheros, en lugar de como llamadas al sistema (como By providing these services as textual I/O on files rather kill) o operaciones de proposito especial (como ptrace), el dispositivo process de Plan 9 simplifica la implementación de debuggers y programas de ese tipo. Por ejemplo, el comando

El dispositivo bitmap contiene 3 ficheros, /dev/mouse, /dev/screen, y /dev/bitblt, que ofrecen un interfaz a la pantalla gráfica local (si la hay) y al dispositivo apuntador. El fichero mouse devuelve un registro de formato fijo que contiene 1 byte para el estado de los botones y 4 bytes más para las posiciones x e y del ratón. Si no se ha movido desde que el fichero se leyó la última vez, otra lectura se bloquerá. El fichero screen contiene la imagen de memoria del contenido de la pantalla; el fichero bitblt ofrece un interfaz procedural. Llamadas a la librería gráfica son traducidas a mensajes que se escriben en el fichero bitblt para realizar operaciones gráficas. (Esto es esencialmente un protocolo RPC anidado)

Todos los servicios que está usando un proceso son reunidos en el espacio de nombres del proceso, una jerarquía de nombres de fichero con una sola raíz. Cuando un proceso bifurca, el proceso hijo comparte el espacio de nombres con el padre. Varias llamadas del sistema manipulan los espacios de nombres. Dado un descriptor de fichero fd que guarda un canal de comunicación abierto con un servicio, la llamada

El sistema de ventanas, [Pike91], es un servidor que ofrece ficheros como /dev/cons y /dev/bitblt. Cada cliente ve una copia diferente de estos ficheros en su espacio de nombres local: hay muchas instancias de /dev/cons, cada una de ellas servida por al espacio de nombres local de una ventana. De nuevo implementa los servicios utilizando espacios de nombres locales además de usar E/S a ficheros con nombres convencionales. Cada cliente simplemente conecta su entrada, su salida y su salida de errores a /dev/cons, con operaciones análogas para acceder a gráficos de mapa de bits. Compárese esto con la implementación de /dev/tty en UNIX, que está hecha mediante código especial en el nucleo, que sobrecarga el fichero, cuando se abre, con la entrada o salida estandar del proceso. Se necesitan medidas especiales en UNIX para que /dev/tty se comporte como se espera en un sistema de ventanas. por el contrario usa la provisión del fichero correspondiente como idea central, y el éxito de ello depende críticamente del espacio de nombres local.

El entorno que proporciona a sus clientes es exactamente el mismo entorno en el que está implementado: un conjunto convencional de ficheros en /dev. Esto permite que él mismo sea ejecutado recursivamente en una de sus propias ventanas, lo que es muy util para debugging. También significa que si los ficheros son exportados a otra máquina, como se describe más adelante, el sistema de ventanas o las aplicaciones cliente pueden ejecutarse de forma transparente en máquinas remotas, incluso si carecen de hardware gráfico. Este mecanismo es usado para las implementaciones Plan 9 del sistema X Window: X corre como cliente de , a menudo en una máquina remota con mucha memoria. En esta configuración, usar Ethernet para conectarse a máquinas MIPS, nosotros hemos medido solamente una degradación del 10% de rendimiento en gráficos, comparado con correr X en una máquina con Plan 9.

Una aplicación inusual de estas ideas es un sistema de ficheros de recopilación estadística, implementado por medio del comando iostats. Este comando encapsula el proceso en un espacio de nombres local, monitoreando solicitudes 9P desde el proceso hacia el mundo exterior — el espacio de nombres en el que iostats se está ejecutando. Cuando el comando termina iostats muestra un informe del uso y gráficos de rendimiento de la actividad de ficheros. Por ejemplo

El comando import conecta una pieza del espacio de nombres desde un sistema remoto al espacio de nombres local. Su implementación consiste en llamar a la máquina remota y empezar un proceso en ella que sirva el espacio de nombres remoto usando 9P. Luego llama a mount para enlazar la conexión con el espacio de nombres y finalmante muere; el proceso remoto continua sirviendo ficheros. Un uso es acceder a dispositivos no disponibles localmente. Por ejemplo, para escribir en un disquete, se puede decir

Otra aplicación es el debugging remoto:

Esta estructura hace muy fácil la creación de pasarelas. Nosotros tenemos máquinas con interfaces Datakit pero sin interfaz Internet. En una de ellas, uno puede teclear

En la práctica no usamos rlogin o telnet entre máquinas Plan 9. En lugar de eso, el comando cpu reemplaza eficazmente la CPU en una ventana por la de otra máquina, típicamente un rápido servidor de CPU multiprocesador. El objetivo es recrear el espacio de nombres en la máquina remota, usando el equivalente de import para conectar piezas del espacio de nombres de la terminal con el del proceso (shell) del servidor de CPU, haciendo de la terminal un servidor de ficheros para la CPU. Las conexiones con los dispositivos locales como el rápido sistema de ficheros siguen siendo locales; solamente los dispositivos residentes de la terminal son importados. El resultado es diferente del rlogin, de UNIX, que se mete en un espacio de nombres distinto en la máquina remota, o de la compartición de ficheros con NFS, que mantiene el mismo espacio de nombres pero fuerza a los procesos a ejecutarse localmente. Los enganches en /bin pueden cambiar debido a un cambio en la arquitectura de la CPU, y las redes involucradas pueden ser distintas a causa de un hardware diferente, pero el efecto sigue siendo una simple aceleración del procesador en el espacio de nombres actual.

Posición

Estos ejemplos ilustran cómo las ideas de representar recursos como sistemas de ficheros y un espacio de nombres por proceso pueden usarse para resolver problemas a menudo en manos de mecanismos más exóticos. No obstante, hay algunas operaciones en Plan 9 que no se mapean en E/S de ficheros. Un ejemplo es la creación de procesos. Podríamos imaginar un mensaje a un fichero de control en /proc que crease un proceso, pero los detalles de construcción del entorno del mismo — si abre ficheros, su espacio de nombres, su imagen de memoria, etc. — serían demasiado intrincados para ser descritos en una simple operación de E/S. Por eso, los nuevos procesos en Plan 9 son creados simplemente con las llamadas convencionales del sistema rfork y exec; /proc se usa solamente para representar y controlar los procesos existentes.

Plan 9 no intenta mapear los espacios de nombre de la red en el espacio de nombres del sistema de ficheros, por varias razones. Las diferentes reglas de direccionamiento para varias redes y protocolos no pueden mapearse uniformemente en un espacio de nombres jerárquico. Aunque pudiese hacerse, los diferentes mecanismos de autenticación, selección de servicios, y control de las conexiones no podría mapearse de manera consistente en operaciones sobre un fichero.

La memoria compartida es otro recurso no adecuado para representar por medio de un espacio de nombres de ficheros. Plan 9 se preocupa de proporcionar mecanismos para permitir a grupos de procesos locales compartir y mapear la memoria. La memoria es controlada mediante llamadas del sistema, en lugar de ficheros especiales, sin embargo, puesto que una representación en el sistema de ficheros podría implicar que la memoria podría ser importada desde máquinas remotas.

Aparte de estas limitaciones, el sistema de ficheros y los espacios de nombres ofrecen un modelo efectivo en torno al cual construir un sistema distribuido. Bien utilizados, pueden proporcionar un interfaz uniforme, familiar y transparente con un conjunto diverso de recursos distribuidos. Comportan propiedades de acceso protección y nombrado perfectamente estudiadas. La integración de dispositivos en un sistema de ficheros jerárquico es la mejor idea de UNIX. Plan 9 lleva estos conceptos mucho más alla y muestra que los sistemas de ficheros, cuando se usan de manera inventiva, tienen plena vigencia en la investigación productiva.

Referencias

[Killian] T. Killian, ‘‘Processes as Files’’, USENIX Summer Conf. Proc., Salt Lake City, 1984

[Needham] R. Needham, ‘‘Names’’, in Distributed systems, S. Mullender, ed., Addison Wesley, 1989

[Pike90] R. Pike, D. Presotto, K. Thompson, H. Trickey, ‘‘Plan 9 from Bell Labs’’, UKUUG Proc. of the Summer 1990 Conf., London, England, 1990

[Presotto] D. Presotto, ‘‘Multiprocessor Streams for Plan 9’’, UKUUG Proc. of the Summer 1990 Conf., London, England, 1990

[Pike91] Pike, R., ‘‘8.5, The Plan 9 Window System’’, USENIX Summer Conf. Proc., Nashville, 1991

Notes

Aparecido en Operating Systems Review, Vol. 27, #2, April 1993, págs. 72-76 (reimpreso de Proceedings of the 5th ACM SIGOPS European Workshop, Mont Saint-Michel, 1992, Paper nº 34).