2003 PROYECTO DE FIN DE CARRERA

UNIVERSIDAD REY JUAN CARLOS INGENIERÍA TÉCNICA EN INFORMÁTICA DE SISTEMAS CURSO ACADÉMICO 2002/2003 PROYECTO DE FIN DE CARRERA BACKUPS TEMPORALES

1 downloads 23 Views 636KB Size

Story Transcript

UNIVERSIDAD REY JUAN CARLOS

INGENIERÍA TÉCNICA EN INFORMÁTICA DE SISTEMAS

CURSO ACADÉMICO 2002/2003

PROYECTO DE FIN DE CARRERA

BACKUPS TEMPORALES DE FICHEROS EN PLAN9

UNDOFS

Autor: Bartolomé Marín Sánchez [email protected] Tutor: Francisco J. Ballesteros Cámara [email protected]

ÍNDICE Capítulo 1 – Introducción

.

.

.

.

. 4

1.1 Introducción a Plan 9

.

.

.

.

. 4

1.2 ¿Qué es un fichero?

.

.

.

.

. 6

1.3 Jerarquía de ficheros

.

.

.

.

. 7

1.4 Servidores de ficheros en Plan 9

.

.

.

.

. 8

.

.

.

.

. 9

.

.

.

.

. 12

2.1 Descripción de los problemas

.

.

.

.

. 12

2.2 Objetivos a cumplir

.

.

.

.

. 13

.

.

.

.

. 14

3.1 Interfaz undofs

.

.

.

.

. 15

3.2 Descripción del diseño

.

.

.

.

. 17

.

.

.

.

. 23

4.1 Implementación módulo Srv

.

.

.

.

. 23

4.2 Implementación módulo Ficheros

.

.

.

.

. 26

4.3 Implementación módulo Comandos .

.

.

.

. 37

1.4.1 El protocolo 9p Capítulo 2 – Objetivos

Capítulo 3 – Diseño

Capítulo 4 – Implementación

Capítulo 5 – Pruebas

.

.

.

.

. 38

Capítulo 6 – Conclusiones

.

.

.

.

. 42

6.1 Lecciones aprendidas

.

.

.

.

. 42

6.2 Trabajos futuros

.

.

.

.

. 43

1

RESUMEN Durante nuestra sesión de trabajo en el ordenador trabajando con algunos ficheros, éstos son modificados y en muchas ocasiones nos hubiera gustado volver a los ficheros anteriores. Muchas personas para evitar estas situaciones realizan copias a mano antes de empezar y durante el trabajo. También tenemos otras muchas personas que emplean programas independientes a los que usan durante su sesión de trabajo para ir manteniendo dichas copias. Éstos programas van generando directorios y ficheros temporales en disco que después del trabajo deberán ser borrados por el usuario. En éstos métodos de trabajo encontramos problemas comunes como son tener que utilizar herramientas ajenas al trabajo y lo que es aún peor obtener muchos ficheros innecesarios al final del día que debemos eliminar. Para solventar estos problemas surge la idea de que el propio servidor de ficheros sobre el que trabaja el cliente mantenga estas copias por si mismo y en lugar de guardarlas en disco trabaje con ellas en memoria volátil, para que cuando termine la sesión éstas se liberen. Además, ya que es el propio servidor el que lo hace se podrían modificar los programas del cliente de una manera sencilla para que ellos mismos ofrezcan la función de volver a copias anteriores para así no tener que emplear herramientas independientes. El objetivo del presente proyecto es construir uno de éstos servidores, en concreto ha sido implementado con el nombre undofs sobre el sistema operativo distribuido Plan 9 [2]. El servidor realiza copias de una manera simple y ofrece una interfaz para poder trabajar con ellas. Para generar copias o volver a una copia anterior bastará con escribir en unos ficheros especiales. Además las copias pueden ser consultadas en cualquier momento ya que cuelgan de un directorio especial.

2

El servidor se generó siguiendo el modelo en espiral de ingeniería del software. A la vez que se iba añadiendo funcionalidad los cambios realizados se iban probando para ir obteniendo versiones con un mínimo de estabilidad y cada vez más funcionales. Durante el desarrollo del proyecto surgen diferentes ideas acerca de cómo debería ser su funcionamiento, uno de estos casos es ¿cuándo se debería generar una copia?. Undofs lo hace de manera explícita cuando se lo pide el usuario por ser la manera que mayor libertad aporta a futuras aplicaciones. En trabajos futuros se podría aumentar la funcionalidad del proyecto añadiendo un método de generación de copias automático y permitiendo al usuario al arrancar el servidor que especifique en que método le gustaría que trabajara. Otro posible trabajo futuro es modificar el editor por excelencia de Plan 9 llamado acme [5] para que trabaje con las nuevas opciones de backups que le ofrece undofs.

3

Capítulo 1. Introducción

Capítulo 1 INTRODUCCIÓN El presente proyecto, undofs, es un servidor de ficheros en el sistema operativo distribuido Plan 9. El objetivo del presente capítulo es explicar una serie de conceptos generales pero necesarios para comprender el trabajo aquí expuesto.

1.1 Introducción a Plan 9 El objetivo de la informática es analizar la información de una forma automática. En un principio aparecieron los autómatas que realizaban tareas simples por si solos mecánicamente. Ante la evolución de la electrónica empezaron a surgir macrocomputadoras [1,2] utilizadas en centros de investigación como universidades. Éstos artefactos podían llegar a ocupar plantas enteras con funciones muy limitadas y costes elevados. Con el desarrollo de la electrónica se disminuyó el tamaño de las computadoras, podían manejar más información y sus costes se abarataron. En la década de los 80 empezaron a surgir ordenadores destinados a uso personal con precios asequibles y se empezó a pensar en interconectar dichos ordenadores. Esto hizo que surgieran las redes de ordenadores. Se ha hablado de cómo ha ido evolucionando el soporte físico del ordenador (hardware), pero a su vez han ido evolucionando los programas (información con la que trabajan los ordenadores). Los ordenadores, al estar construidos con piezas electrónicas sólo entienden de existencia o no de tensión, por tanto se trabaja con una lógica binaria. Al principio se debía introducir la información en dicha lógica (unos y ceros) pero se fueron añadiendo capas por encima que ofrecen abstracciones para poder trabajar de una forma mas cómoda.

4

Capítulo 1. Introducción Empezaron a surgir los llamados sistemas operativos, que no son más que programas que se cargan encima del hardware, ofrecen unas abstracciones para poder interactuar con los dispositivos y dialogan entre los programas de usuario y el hardware. Las sistemas operativos han ido evolucionando añadiendo abstracciones como el multiproceso (poder tener arrancados varios procesos o aplicaciones compartiendo los recursos de la máquina), multiusuario (ofrecer la existencia de varios usuarios cada uno de ellos con sus configuraciones propias y permisos), etc. Ante la aparición de la redes se empezó a pensar en poder aprovechar los recursos de otras máquinas o incluso utilizarlas como si fuera nuestra propia máquina, con esto aparecieron los sistemas operativos distribuidos[2]. Una definición de sistema operativo distribuido podría ser: “Un sistema distribuido es una colección de computadoras independientes que aparecen ante los usuarios del sistema como una única computadora”. En general la idea consiste en que todo lo que se encuentre conectado en la misma red puede ser utilizado por cualquier pc indistintamente de su posición geográfica o arquitectura a la que pertenece. Las características que miden la calidad de un sistema distribuido son: •

Tolerancia a fallos: El fallo de una máquina o de la red no debe acabar con todo el sistema.



Transparencia: Todo el sistema debe funcionar de manera similar en cualquier punto de la red.



Eficiencia: El objetivo de utilizar un sistema distribuido y no uno centralizado (basado en los recursos que ofrece la propia máquina) es obtener un mejor rendimiento por lo que el trabajo debe ser distribuido entre todos los recursos de forma que el tiempo de respuesta debe ser el menor posible.



Escalabilidad: El sistema debe ser capaz de soportar el aumento o disminución de ordenadores en la red.

5

Capítulo 1. Introducción •

Flexibilidad: El sistema debe admitir posibles cambios en su estructura y programas base ya que los sistemas distribuidos se encuentran en sus comienzos y los objetivos y técnicas evolucionan.

Existen otro tipo de características deseables como puede ser la fiabilidad, autonomía, etc. Un sistema operativo distribuido es Plan 9 (empleado en la realización del proyecto). Una característica importante de éste sistema es que todo son ficheros bien sea el monitor, la tarjeta de sonido, la conexión de red, los procesos, etc. Gracias a esto se puede trabajar de una forma simple y homogénea con cualquier cosa del sistema. Otra característica importante de Plan 9 es que el sistema de ficheros no se encuentra integrado en el kernel, sino que está en área de usuario. Esto permite la utilización de diferentes sistemas de ficheros, cada uno con sus peculiaridades. La única condición a cumplir por los sistemas de ficheros es que para poder comunicarse, bien sea con el kernel o con otro tipo de programas, deben utilizar un protocolo determinado cuyo nombre es 9p.

1.2 ¿Qué es un fichero? Los ordenadores para trabajar necesitan información, ésta información se encuentra almacenada en los ficheros. Los ficheros son una abstracción que nos ofrece el sistema operativo para interactuar con la información de una manera simple y coherente. Ésta abstracción ofrece 4 operaciones básicas con las que poder tratar la información. Las operaciones ofrecidas son: open, close, read y write. •

Open: se encarga de abrir un fichero (obtener un medio para referirnos a un fichero determinado) devolviéndonos un identificador de fichero (fd). Éste identificador de fichero es necesario para la utilización de las otras 3 primitivas ya que es el que indica con que fichero se interactúa.

6

Capítulo 1. Introducción •

Close: le indica al sistema operativo que ya no se va a trabajar más con el fichero representado por el descriptor de fichero.



Read: es la encargada de sacar información de un fichero. Para obtener dicha información se puede indicar a partir de donde se obtiene (offset) y cuanto se quiere obtener.



Write: se utiliza para introducir información en un fichero. También se puede especificar a partir de que posición se quiere escribir (offset) y por supuesto se le debe decir que es lo que se desea escribir.

El sistema operativo además de necesitar la información de los ficheros también necesita otra información para ofrecer otro tipo de abstracciones como usuarios, permisos o meramente para poder trabajar con los ficheros. Ésta información trata sobre los propios datos y recibe el nombre de metadatos.

1.3 Jerarquía de ficheros La jerarquía de ficheros es la forma en que el sistema operativo organiza los ficheros para que el usuario pueda acceder a ellos (método de nombrado de ficheros). En el caso de Plan 9 los ficheros se encuentran estructurados en una jerarquía de tipo árbol. En este tipo de jerarquía existen además de los ficheros anteriores un tipo especial de ficheros llamados directorios, cuya única información que almacenan son los ficheros y directorios que cuelgan de ellos junto a los metadatos propios. En los árboles de directorios existe un directorio raíz del que cuelgan ficheros y directorios y a su vez de estos directorios cuelgan otros formando así una estructura en árbol. En Plan 9 la jerarquía no es estática, en cualquier momento se pueden agregar o quitar ficheros o directorios. El directorio raíz tiene características especiales como que no puede ser borrado y su padre es él mismo.

7

Capítulo 1. Introducción

1.4 Servidores de ficheros en Plan 9 Los servidores de ficheros como cualquier tipo de servidor se encargan de ofrecer información, en este caso mediante ficheros. Los servidores de ficheros ofrecen un árbol de directorios con un raíz "local", esto es dentro del propio servidor. Para poder acceder a algún fichero que cuelgue del raíz local se empleará algún tipo de protocolo que entienda el servidor. Éste protocolo básicamente le indicará al servidor con qué fichero local se quiere interactuar y que operación ha de realizar. Básicamente el modo de funcionamiento en la estructura cliente/servidor es que el cliente realiza peticiones al servidor empleando un protocolo que ambos entiendan, el servidor realiza las operaciones necesarias para satisfacer la petición del cliente y contesta al cliente indicándole como ha ido la operación y los resultados obtenidos. Como se ha indicado anteriormente, en Plan 9 el servidor de ficheros no se encuentra dentro del kernel, esto permite emplear diferentes sistemas de ficheros para tratar ficheros de características especiales de una manera adecuada. Para comunicarse con el servidor bien sea un kernel u otro programa (incluso otro servidor) se debe emplear el protocolo 9p. Un servidor de Plan 9 provee uno o más árboles de ficheros jerárquicos. Éstos servidores atienden peticiones de clientes para navegar, crear, borrar, leer y escribir ficheros en el árbol de directorios que sirven. Para conectarse a un servidor el cliente deberá añadirlo (montarlo) en su árbol de directorios para poder comunicarse con éste (normalmente el servidor al ser arrancado se añadirá al árbol). Cualquier llamada al sistema de algún programa que opere con ficheros de ese servidor será traducida a peticiones y respuestas 9p que irán destinadas al servidor mediante una conexión bidireccional entre ambos. La conexión bidireccional generada podría ser empleada por múltiples clientes al mismo tiempo.

8

Capítulo 1. Introducción

1.4.1 El protocolo 9p El protocolo 9p[6] es empleado para la comunicación entre clientes y servidores. El cliente envía mensajes de petición y el servidor se encarga de enviar mensajes de respuesta correspondientes a cada una de las peticiones con el contenido adecuado. Los servidores para identificar los ficheros que sirven utilizan qids. Un qid identifica en un servidor un fichero determinado de forma unívoca y en ningún caso representará a más de un fichero. Los fids son identificadores que el servidor da a los clientes para indicar a qué fichero en el servidor se están refiriendo. El servidor se encarga de mantener la relación existente entre un fid y su qid correspondiente. El motivo de darle al cliente un fid en lugar de un qid radica en que el servidor en la relación que mantiene entre ambos también guarda información acerca de las operaciones y del estado del fichero con respecto a ese cliente. El protocolo 9p pone a disposición del cliente 12 mensajes de petición distintos (mensaje-T). El servidor responderá a éstos mensajes de petición con los mensajes de respuesta (mensaje-R) correspondientes a la peticiones realizadas o bien con un mensaje de error, por lo que existen 13 mensajes-R. Los distintos mensajes existentes son: •

Version: Negocia la versión del protocolo y el tamaño del mensaje utilizado en la conexión. Es el primer mensaje enviado en la conexión 9p.



Auth: Es empleado para la autentificación del cliente en el servidor, en caso de que no sea necesaria el cliente responderá con mensaje de error.



Attach: Se encarga de conectar el cliente con el servidor, pasándole el servidor un fid que apunta al directorio raíz de éste.



Flush: Anula el mensaje anterior y evita que se ejecute, en caso de que se haya recibido el mensaje-R del mensaje-T a anular no se desharán los cambios.

9

Capítulo 1. Introducción •

Walk: Se utiliza para avanzar de un fichero a otro, siendo éste o bien el padre o el hijo del fid enviado. Éste fid pasará a apuntar al fichero deseado.



Open: Se emplea para abrir el fichero al que apunta el fid pasado como argumento, en esta llamada se comprueban los permisos del cliente con respecto a dicho fichero.



Create: Crea un nuevo archivo con los permisos que le envía el cliente. Se comprueba que se tiene permisos para poder crearlo. El fid enviado pasa a apuntar al nuevo fichero y el fichero será marcado como abierto.



Read: Se lee del fichero representado por el fid enviado tantos bytes como sean posibles de los pedidos por el cliente a partir de la posición indicada.



Write: Se utiliza para escribir en el fichero representado por el fid tantos bytes como se le han enviado a partir de la posición pedida.



Clunk: Se emplea para indicar al servidor que el fichero representado por el fid enviado ya no va a ser empleado. El fid enviado se libera.



Remove: Indica al servidor que el fichero representado por el fid ya no va a ser utilizado y en caso de que no esté siendo referenciado por otro fid éste se elimine. El fid se libera.



Stat: Pide información de los metadatos del fichero representado por el fid.



Wstat: Intenta modificar los metadatos del fichero representado por el fid. Para ello se comprueban los permisos del cliente.



Error: Devuelve el string de error describiendo el fallo de una transacción, remplaza al mensaje-R correspondiente a la petición realizada.

10

Capítulo 1. Introducción Un ejemplo de los mensajes intercambiados en una operación podría ser el siguiente: term% cat f1 Rerror tag 1 ename file not found Rwalk tag 1 nwqid 1 0:(0000000000000007 1 ) Ropen tag 1 qid (0000000000000007 1 ) iounit 0 Rread tag 1 count 30 'esto es una prueba de lectura ' esto es una prueba de lectura Rread tag 1 count 0 '' Rclunk tag 1

Como se observa la operación consiste en una lectura del contenido del fichero f1. Para realizar dicha operación mediante mensajes walk se desplaza hasta el fichero en cuestión, después éste es abierto mediante open, se lee el contenido mediante read y por último se libera el fid empleado en la operación mediante el mensaje clunk.

11

Capítulo 2. Objetivos

Capítulo 2 OBJETIVOS Plan 9 en la actualidad es un sistema operativo cuyo número de usuarios es bastante limitado y además este grupo es bastante homogéneo. En su mayoría los usuarios son personas ligadas al mundo de la informática con conocimientos avanzados de programación. El motivo de que tenga tan pocos usuarios no es que sea un sistema operativo mediocre, sino que está en fase de desarrollo y no está orientado para usuarios no informáticos. Actualmente su uso mayoritario se encuentra en la empresa que lo desarrolló (BellLabs) para su propio uso, en algunas universidades y en proyectos de investigación. Aunque la funcionalidad de undofs puede llegar a ser muy diversa, en esencia lo que pretende es ayudar a los programadores en su sesión de trabajo diaria permitiéndoles trabajar cómodamente sin preocuparse de andar creando copias temporales de los ficheros con los que trabaja para evitar que un fallo humano pueda perder horas de trabajo.

2.1 Descripción de los problemas De esa metodología de trabajo llevada a cabo por el programador se encuentran múltiples problemas que nuestro servidor intenta solucionar de una manera simple y adecuada. Uno de los primeros problemas es el tener que generar copias manualmente y lo que es aún mas grave, tener que gestionarlas por uno mismo. El programador debe seleccionar al iniciar la sesión de trabajo los ficheros que va a modificar para guardarlos, debiendo almacenarlos en otro lugar dándoles una marca de tiempo para poder saber de que versión se trata. En caso de generar una nueva versión deberá seguir el mismo razonamiento, seleccionar que ficheros se van a modificar, escoger donde van a ser guardados y una marca de tiempo para saber la versión de estos. Y el peor caso de todos, cuando decide volver a una versión anterior, debe guardar la

12

Capítulo 2. Objetivos versión actual con otra marca de tiempo, buscar la versión anterior con la que desea trabajar y ponerla en su directorio de trabajo actual. Otro problema es la existencia de muchos ficheros que al final de la sesión de trabajo deben ser eliminados. Undofs solventa este problema de una manera muy simple, como todas las copias se encuentran en memoria volátil al terminar la sesión y desmontar el servidor todos serán eliminados. Otra característica relevante de undofs es que al estar integrada la funcionalidad dentro del propio servidor de ficheros permite modificar los programas de trabajo (actualmente el más utilizado en Plan 9 es acme, aunque existen otros como sam) para que soporten ésta nueva funcionalidad sin tener que llevar a cabo grandes modificaciones. Con esta característica evitamos que el usuario tenga que arrancar nuevos programas y aprender a trabajar con ellos, ya que estas nuevas características están integradas en sus aplicaciones de uso diario.

2.2 Objetivos a cumplir Para solventar los problemas anteriormente citados se ha creado undofs, cuyos objetivos principales del diseño son dos. El primero de ellos consiste en ofrecer un servidor de ficheros que se monte encima del directorio indicado atendiendo adecuadamente a las peticiones de los clientes y manteniendo los ficheros en disco actualizados de manera coherente. El segundo es proporcionar al usuario y a las aplicaciones una manera fácil con la que poder generar copias temporales de los ficheros servidos y permitir seleccionar en cualquier momento aquella copia con la que se debería seguir trabajando.

13

Capítulo 3. Diseño

Capítulo 3 DISEÑO En el presente proyecto se ha utilizado un modelo de desarrollo en espiral. Se eligió éste modelo y no otro porque se partía de una idea general, flexible con la que había que experimentar.

Figura 3-1: Modelo en espiral

El modelo de desarrollo en espiral realiza una serie de etapas repetidamente hasta llegar a un producto final que cumpla los requisitos, incluso llega mas adelante teniendo en cuenta el mantenimiento del producto final. Las etapas que se repiten tal como muestra la figura 3-1 son: •

Determinación de los objetivos.



Valoración y reducción de riesgos.



Desarrollo del sistema escogido y validación de éste.



Repaso del proyecto y planificación de la siguiente fase.

14

Capítulo 3. Diseño Gracias a sus características se ha podido decidir según avanzaba el desarrollo como iba a ser su diseño y funcionalidad finales, además se ha dispuesto de prototipos que han podido ser probados independientemente.

3.1 Interfaz undofs La interfaz del servidor de ficheros undofs es simple, debido a los pocos comandos que necesita y a las opciones de inicio que ofrece. Undofs tiene dos comandos, éstos son undo y snapshot. Para ejecutar uno de éstos comandos bastará con escribir en el fichero del mismo nombre hijo del raíz local del servidor. La sintaxis de los comandos es la siguiente: Snapshot: ´echo > snapshot´ Siendo nombre de copia el nombre que recibirá la copia generada. Undo: ´echo > undo´ Siendo nombre de copia el nombre de la copia ha restaurar que cuelga del directorio dumps. Al iniciar el servidor éste recibe el directorio que va a ser administrado por undofs. Por defecto el servidor será montado en el directorio administrado, aunque se le puede indicar además el punto de montaje. También tiene una opción de depuración que muestra los mensajes del protocolo 9p intercambiados entre el cliente y undofs. Ej. servidor iniciado por defecto: ´term% undofs /usr/glenda/tmp/pruebas´ Ej. servidor iniciado en un punto de montaje distinto al directorio servido: ´term% undofs /usr/glenda/tmp/pruebas /n/undo´ Ej. servidor iniciado con opción de depuración: ´term% undofs –d /usr/glenda/tmp/pruebas´

15

Capítulo 3. Diseño El árbol de ficheros del usuario, antes de ser montado undofs, podría ser tal como el que aparece en la figura 3-2. Dirservido será el directorio que servirá undofs.

Figura 3-2: Árbol de ficheros usuario

Al arrancar undofs, por defecto, para que sirva dirservido quedaría el árbol de ficheros del usuario como indica la figura 3-3. Como se ve en la figura aparecen los ficheros especiales undo y snapshot junto con el directorio especial dumps. En la figura dumps mantiene n copias, siendo copia1 una copia del árbol de ficheros actual.

Figura 3-3: Árbol de ficheros del usuario empleando undofs

16

Capítulo 3. Diseño

3.2 Descripción del diseño Los requerimientos del proyecto son permitir la generación de copias temporales del árbol de directorios servido y permitir cambiar en cualquier momento el árbol de trabajo por cualquier copia mantenida. Para satisfacer dichos requisitos se coloca un servidor de ficheros entre las peticiones de los clientes y el sistema de archivos de Plan 9. Ésta situación se encuentra representada en el esquema de la figura 3-4. A partir de ahora cualquier petición generada por un cliente (kernel, servidor de ficheros, etc) será enviada a undofs, la comunicación entre ambos será realizada mediante el protocolo 9p. Una vez undofs tiene la petición, éste se encargará de tratarla adecuadamente, responder al cliente y en el caso de algún tipo de actualización en los ficheros servidos ésta deberá ser propagada al sistema de ficheros mediante las llamadas al sistema destinadas a la manipulación de archivos.

Figura 3-4: Esquema interacción cliente-undofs-sistema_ficheros

Para hacer todo esto undofs estará compuesto por 3 módulos, cada uno de ellos encargado de realizar unas funciones muy específicas. Éstos módulos son srv, ficheros y comandos. La manera en la que interactúan entre ellos se encuentra representado en la figura 3-5 que se describe a continuación.

Figura 3-5: Módulos de undofs

17

Capítulo 3. Diseño El módulo srv tiene 2 funciones principales. La primera es comunicarse con el cliente mediante 9p respondiéndole adecuadamente, para ello es necesario que interactúe con el módulo ficheros del que obtendrá la información que concierne al árbol de directorios servido. La segunda función es propagar las peticiones del cliente bien sea al módulo comandos cuando llegue un comando o al módulo ficheros para obtener o modificar la información que mantiene. El módulo comandos se encarga de ver que comando ha recibido y en función de éste modificará de una forma u otra la información que mantiene ficheros. Ficheros se encarga de gestionar la información ofrecida por undofs y de comunicarse con el sistema de ficheros de Plan 9 para manipularlo cuando sea necesario. Para manipular los ficheros empleará las llamadas al sistema para la manipulación de ficheros.

3.2.1 Descripción del módulo Srv El módulo Srv, como ya hemos visto se encargará de las comunicaciones entre el cliente y undofs, así como de propagar las peticiones a los otros módulos cuando sea necesario. Para llevar a cabo estas tareas estará dividido a su vez en 3 módulos, como se observa en la figura 3-6. Éstos módulos son R/E (recibir/enviar), T/A (transformar/analizar) y G_respuesta (generar respuesta).

18

Capítulo 3. Diseño

Figura 3-6: División del módulo Srv

El módulo R/E es el encargado de hacer de puente entre el cliente y el módulo T/A. Para ello recibe/envia mensajes codificados como un array de bytes (conjunto de bytes ordenados) que se corresponderán con el formato de cada uno de los mensajes 9p. Éste módulo estará todo el tiempo esperando a recibir mensajes del cliente para pasárselos a T/A o viceversa. El módulo T/A se encargará de transformar y analizar los mensajes que reciba. Los mensajes que procedan del módulo G_respuesta serán codificados en un array de bytes y enviados al módulo R/E para que los transmita al cliente. En el caso de recibir un mensaje procedente de R/E, éste será convertido en una estructura de datos que analizará para saber si se trata de un comando o de una petición. En el caso de un comando será enviada la estructura a comandos y si fuera una petición al módulo G_respuesta para que genere una respuesta. El módulo G_respuesta recibe peticiones en una estructura adecuada (fcall[6]) procedentes de T/A. Su función consistirá en obtener la respuesta a la petición del cliente para ello necesitará interactuar con ficheros, para obtener la información solicitada o bien para actualizar la información que mantiene.

19

Capítulo 3. Diseño

3.2.2 Descripción del módulo Ficheros El módulo ficheros será el encargado de gestionar y almacenar la información ofrecida por el servidor. Para llevar a cabo dichas tareas se dividirá la funcionalidad tal como indica la figura 3-7.

Figura 3-7: División del módulo Ficheros

El módulo árbol será el encargado de mantener la estructura y la información del árbol. Recibirá de srv peticiones para obtener información o para modificarla, en el caso de modificación los cambios deberán ser replicados en el sistema de ficheros de Plan 9. La información mantenida en todo momento deberá ser coherente con la mantenida por Plan 9. Árbol también deberá interactuar con snapshot y undo, los cuales realizarán modificaciones: snapshot añadirá información y undo realizará modificaciones en la estructura, encargándose por si mismo de reestructurar también el sistema de ficheros. Árbol, a su vez se subdivide en otras 3 partes. La primera de ellas dumps, es un directorio especial donde serán almacenadas las copias generadas mediante snapshot , los hijos de dicho directorio no podrán ser modificados en ningún caso y no serán almacenado en Plan 9. Inicializar, como su nombre indica, se encargará de subir al 20

Capítulo 3. Diseño árbol la información de Plan 9 que será gestionada por el servidor cuando éste sea arrancado. La función de F_disco será propagar un cambio en la información del servidor al sistema de ficheros de Plan 9. Todas éstas subdivisiones y relaciones se encuentran representadas en la figura 3-8.

Figura 3-8: Descomposición de Árbol

El módulo snapshot será el encargado de llevar a cabo el comando con el mismo nombre. Será representado como un fichero especial que colgará del raíz del árbol servido por undofs y no aparecerá en el sistema de ficheros de Plan 9. Interactuará con árbol y comandos de la siguiente forma: comandos le indicará a snapshot el nombre de la copia a ser generada y éste generará una copia con dicho nombre bajo el directorio dumps. El módulo undo será similar a snapshot a excepción de la función que realizará. Dicha función consistirá en cambiar el árbol servido por una de las copias mantenidas bajo dumps. Undo recibirá de comandos el nombre de la copia que se desea ser restaurada. Para llevar a cabo dicha tarea se dividirá el trabajo como indica la figura 3-9.

Figura 3-9: Descomposición de undo

21

Capítulo 3. Diseño Act_arbol será el encargado de cambiar la estructura del árbol de ficheros en el servidor. Deberá colocar como raíz al árbol de dumps indicado y recolocar el árbol que era raíz bajo dumps con un nombre genérico. Para realizar acabo ésto deberá interactuar con árbol. Una vez cambiada la estructura de árbol dichos cambios deberán ser propagados en el sistema de ficheros de Plan 9. El encargado de ésto será act_disco, el cual comparará el árbol que tiene el sistema de ficheros y replicará los cambios a éste.

3.2.3 Descripción del módulo Comandos El módulo comandos será el encargado de analizar cual es el comando solicitado y en función de éste solicitar una acción u otra. El modo en que operará éste modulo es el siguiente: recibirá de srv el comando solicitado, lo analizará para saber el comando que se trata y transmitirá la información para la realización de la orden al módulo adeacuado perteneciente a árbol, bien sea éste snapshot o undo.

22

Capítulo 4. Implementación

Capítulo 4 IMPLEMENTACIÓN Ahora veremos como se ha transformado el diseño anterior en un servidor de ficheros llamado undofs.

4.1 Implementación módulo Srv Como se muestra en la figura 3-6 el módulo srv se encuentra dividido en 3 módulos que interactúan como indica la figura. En esta parte no ha sido necesario realizar algunos de éstos módulos ya que se ha utilizado la librería lib9p[6] la cual nos ofrece un servidor genérico que nos ahorra implementar algunas características comunes de los servidores de ficheros de Plan 9. Dicha librería nos ofrece la siguiente estructura de datos para indicar las características del servidor. A continuación describiremos dicha estructura, dado que es central en nuestra implementación. typedef struct Srv { Tree* tree; void (*attach)(Req *r); void (*auth)(Req *r); void (*open)(Req *r); void (*create)(Req *r); void (*read)(Req *r); void (*write)(Req *r); void (*remove)(Req *r); void (*flush)(Req *r); void (*stat)(Req *r); void (*wstat)(Req *r); void (*walk)(Req *r); char* (*walk1)(Fid *fid, char *name, Qid *qid); char* (*clone)(Fid *oldfid, Fid *newfid); void (*destroyfid)(Fid *fid); void (*destroyreq)(Req *r); void (*end)(Srv *s); … } Srv;

El campo tree es empleado para enlazar a la estructura srv una estructura de árboles jerárquica. De la estructura tree ofrecida por lib9p cuelgan estructuras de tipo file (ambas estructuras expuestas en el punto siguiente). Si empleamos dichas estructuras, lib9p nos obliga a implementar sólo 3 mensajes de respuesta, éstos son read, write y create.

23

Capítulo 4. Implementación Los campos desde attach a walk son para añadir al servidor las funciones encargadas de generar respuestas a las peticiones 9p con el mismo nombre. Walk1 y clone son una manera simplificada de implementar walk. Walk1 se encargaría de desplazarse a un nivel superior o inferior del árbol. Clone se encargaría de clonar un fid (crear un nuevo fid que apunta al mismo fichero en el árbol). Las funciones destroyfid y destroyreq son empleadas para liberar los campos aux de las estructuras fid y req respectivamente. La función end será llamada cuando se cierre el servidor, el objetivo de dicha función es liberar la memoria empleada por el servidor y realizar cualquier operación de backup que necesite realizar antes de cerrarse. La estructura req representa el contenido de los mensajes. El campo tag es el identificador de la transacción, los campos ifcall y ofcall son estructuras de datos de tipo fcall representando la primera el mensaje de petición y la segunda representa el mensaje de respuesta. En general cada transacción consistirá en recibir unos datos mediante ifcall y rellenar adecuadamente el campo ofcall para responder adecuadamente [6]. typedef struct Req { ulong tag; Fcall ifcall; Fcall ofcall; ... } Req;

Con la utilización de esta librería junto con las estructuras de datos que nos ofrece no ha sido necesario implementar los módulos Recibir/Enviar y Transformar/analizar ya que todo este trabajo lo lleva a cabo ella misma. En el caso del módulo Transformar/analizar no se puede hacer que éste analice la petición para ver si se trata de un comando o de una petición 9p, por lo que esta funcionalidad ha sido implementada en el módulo G_respuesta. El módulo G_respuesta encargado de generar mensajes 9p de respuesta a las peticiones llegadas también se ve notablemente simplificado con la utilización de la librería ya que ella misma se encarga de llamar a la función correspondiente para

24

Capítulo 4. Implementación tratar cada petición 9p y como se ha comentado anteriormente con la utilización de la estructura tree, srv sólo obliga a implementar read, write y create, auque undofs también ha implementado las respuestas wstat y remove para satisfacer algunas condiciones específicas del servidor. Al emplear dichas funciones la estructura srv ha quedado como se indica a continuación. Srv server={ .tree

= arbol,

.attach

= nil,

.auth

= nil,

.open

= nil,

.create

= screate,

.read

= sread,

.write

= swrite,

.remove

= sremove,

.flush

= nil,

.stat

= nil,

.wstat

= swstat,

.walk

= nil,

.walk1

= nil,

.clone

= nil,

.destroyfid

= nil,

.destroyreq

= nil,

.end

= ends,

};

La función screate se encarga de añadir un nuevo fichero al árbol de directorios, al emplear la estructura tree esto se realiza mediante la función createfile que básicamente recibe el directorio padre e información asociada al nuevo fichero. File*

createfile(File *dir, char *name, char *uid, ulong mode, void *aux)

La función sread se encarga de obtener el contenido de un fichero, dicha información será almacenada en una estructura llamada campo_aux (explicada en el punto siguiente) en la que uno de sus campos es un array de caracteres donde se encuentran almacenados los datos. Para realizar la lectura de los datos basta con emplear la función readbuf, que se encarga por si misma de realizar el mensaje de respuesta. El funcionamiento general de la función swrite consiste en escribir en el fichero indicado los datos enviados, pero a esto se le ha añadido también la funcionalidad de analizar si se trata de un comando o tan sólo una escritura a un fichero regular. El motivo

de

que

se

haya

migrado

dicha

funcionalidad

perteneciente

a

Transformar/Analizar a la función swrite es el propio funcionamiento de undofs, ya

25

Capítulo 4. Implementación que para indicar un comando es necesario escribir en uno de los ficheros especiales el nombre de un árbol bien sea para crearlo o restaurarlo. La función swrite funcionaría de la siguiente forma: SWRITE: Analizar permisos de escritura en el fichero (ya realizado por lib9p) Se trata de un comando o una escritura normal (controlar el fichero a escribir) Si es un fichero de comandos: Ver cual es Realizar la operación adecuada Si no: Actualizar contenido fichero Generar mensaje respuesta adecuado

La función swstat modifica los metadatos de un fichero. La función remove borra un fichero, para ello se emplea la función removefile. Int removefile (File * file)

Para iniciar el servidor es necesario indexarlo en el sistema de ficheros de Plan 9, para ello se ha empleado la siguiente función que ofrece la librería: Void postmountsrv(Srv *s, char *name, char *mtpt, int flag)

Postmountsrv se encarga de montar el servidor del tipo srv en el punto de montaje mtpt , ha dicha función se le debe indicar la manera en la que se monta el servidor en el sistema de ficheros (a continuación de los datos anteriores, sustituyendo a los datos anteriores, permitiendo o no crear nuevos ficheros, etc) mediante el entero flag, en undofs ,en concreto, se sustituyen los datos anteriores y se permite la creación de nuevos ficheros. Las funciones también serán analizadas en los puntos siguientes ya que implementan funcionalidad de otros módulos.

4.2 Implementación módulo Ficheros El módulo ficheros es el encargado de almacenar y gestionar la información ofrecida por el servidor. Ésta información se encuentra almacenada en una estructura jerárquica formada por ficheros y directorios. Para realizar dicha estructura se han empleado los tipos de datos tree y file ofrecidos por lib9p.

26

Capítulo 4. Implementación typedef struct File { Ref; Dir; void*aux; ... } File; typedef struct Tree { File *root; ... } Tree;

La estructura file es empleada para representar ficheros o directorios y está pensada para ser empleada junto a la estructura tree, ya que es ésta la que forma la jerarquía. El campo ref indica el número de estructuras que están referenciando a ese file, éste campo es empleado para evitar eliminar del servidor un file que esté siendo referenciado. File mantiene toda la información necesaria para un fichero o directorio en la estructura de tipo dir[6] que almacena, además nos ofrece un campo aux destinado a que el programador lo emplee para almacenar aquella información propia que necesite. En undofs éste campo almacena la siguiente estructura de datos: struct campo_aux { char * contenido; uvlong longitud; int permiso;//si vale 0 se puede modificar en caso contrario no vlong marcaraiz; vlong marcafichero; };

Dichos campos son empleados para almacenar el contenido del fichero (contenido y longitud), para controlar si un fichero puede ser modificado (permiso) y dos marcas de tiempo empleadas en la actualización en disco cuando se realiza una operación undo. Como se observa en el diseño de la figura 3-5 el módulo encargado de distribuir las peticiones procedentes del cliente es srv. Al utilizar lib9p la única parte del módulo srv implementada es G_respuesta, esto hace que sean las funciones de dicho módulo las encargadas de comunicarse con los módulos ficheros y comandos. Por esta razón mucha funcionalidad de ficheros estará implementada en las propias funciones de G_respuesta. Como indica la figura 3-7 el módulo ficheros se encuentra dividido en 3 submódulos, éstos son:

27

Capítulo 4. Implementación o Submódulo árbol. o Submódulo snapshot. o Submódulo undo.

4.2.1 Implementación Submódulo Árbol La figura 3-8 muestra la subdivisión de dicho submódulo y a su vez cómo interactúa éste con las demás partes del diseño. La función inicializar comprende 2 funciones elementales, éstas son la creación del árbol y la subida de la información servida al nuevo árbol. Todo esto en undofs lo realiza la función arbolservido. La función arbolservido funciona de la siguiente forma: ARBOLSERVIDO: Comprobar existencia y permisos del directorio a servir Si todo ha ido bien { crear árbol subir ficheros servidos añadir ficheros especiales (dumps,undo,snapshot) }si no { devolver nill }

Para crear el árbol basta con utilizar la función de la librería lib9p llamada alloctree. Tree* alloctree(char uid, char gid, ulong mode, void (*destroy)(File*))

Dicha función nos devuelve un tipo de datos tree ya inicializado con los nombres de usuario, grupo y permisos que se le hayan pasado como argumentos. Otro argumento es una función que será llamada por lib9p para liberar el campo aux de los ficheros representados mediante estructuras de tipo file. Para subir la información servida se han empleado dos funciones recursivas llamadas leerfichero y leerdirectorio. La idea de las funciones es bastante simple. Leerfichero se encarga de crear dicho fichero en el árbol tree con el contenido de éste. Leerdirectorio abre el directorio que le pasan, lo añade al árbol tree y para cada uno de sus hijos mira si es un fichero o un directorio, en el primer caso llamará a

28

Capítulo 4. Implementación leerfichero y en el segundo caso se volverá a llamar a leerdirectorio pero ahora para el hijo. El caso base de esta recursión sería el fichero. Para subir la información bastará con llamar a leerdirectorio pasándole el raíz del árbol tree y el directorio a servir. La funcionalidad de dumps es ofrecer un directorio especial que no aparezca en disco del que cuelguen las copias generadas mediante snapshot y todo aquello perteneciente a directorio no podrá ser modificado por el cliente. El directorio dumps ha sido generado en la función arbolservido en el paso de añadir ficheros especiales. Éste directorio se ha insertado en el árbol tree mediante la función ofrecida por lib9p para generar ficheros, ésta es createfile. Para hacer que dicho directorio sólo exista en el servidor y no en el sistema de ficheros se ha debido controlar ésta característica en la funcionalidad f_disco encargada de actualizar los cambios del árbol servido en disco. Para evitar que todo lo que cuelgue de dumps pueda ser modificado por el cliente se ha empleado el atributo permiso almacenado en el campo aux de cada fichero file. Para indicar que no puede ser modificado hay que poner dicho campo a –1 y en las peticiones que modifican el contenido de un árbol (swrite, screate, swstat y sremove) antes de llevar a cabo cualquier modificación se comprueba dicho campo y en el caso de estar a –1 será devuelto al cliente un mensaje indicando que los ficheros de dicho directorio no pueden ser modificados. La funcionalidad de f_write es ante cualquier modificación del árbol servido transmitir dichos cambios al sistema de ficheros de Plan 9. Durante el desarrollo se estudió dos alternativas de en que momento deberían ser transmitidos los cambios al sistema de ficheros. La primera opción, y posiblemente la de menor latencia, consistía en transmitir los cambios cuando se dejaba de utilizar el fichero, esto es ante la llegada de una petición clunk. Dicha alternativa no pudo ser implementada debido a que lib9p responde a esta petición por si misma y la única forma posible de cambiar la respuesta es cambiando la propia librería lib9p. La segunda opción (implementada en undofs) consiste en al mismo tiempo que se modifica la información en el servidor propagar los cambios al sistema de ficheros. 29

Capítulo 4. Implementación Los cambios de la información mantenida por el servidor son realizados en los propios mensajes 9p de respuesta (pertenecientes al submódulo G_respuesta). Por esta razón las actualizaciones en el sistema de ficheros son realizadas en las respuestas que puedan llegar a modificar la información, éstas son create, write, wstat y remove. No es necesario controlar si se va a escribir en disco un fichero especial, como pueda ser cualquiera que esté contenido en dumps o los ficheros de comandos snapshot y undo ya que en ningún momento éstos serán modificados en el servidor por lo que no habrá actualización. Para actualizar en disco se han creado las funciones crearfichero, actcontfichero, metadatosfichero y borrarfichero. La función crearfichero es utilizada para actualizar en el sistema de ficheros los cambios realizados ante una petición create. Éstos cambios consisten en crear un nuevo fichero. Crearfichero utiliza la llamada al sistema create para crearlo en el sistema de ficheros, también debe cambiar los metadatos asociados al nuevo fichero, para ello emplea la función metadatosfichero. Metadatosfichero es utilizado ante una petición wstat y se encarga de modificar los metadatos asociados a un fichero. Para llevar a cabo estos cambios en el sistema de ficheros se ha utilizado la llamada al sistema dirwstat que recibe una estructura que almacena los nuevos metadatos que debe tener el fichero. Actcontfichero se encarga de actualizar el contenido de un fichero, ésta operación se realiza ante una petición write. Actcontfichero utiliza la llamada pwrite la cual escribe en un fichero la información que se le pasa a partir de la posición del fichero recibida. Borrarfichero borra en el sistema de archivos un fichero. En el caso de ser un directorio éste no podrá tener hijos. Para ello se emplea la llamada al sistema remove, que recibe el path del fichero. Ésta función es empleada ante una petición 9p de tipo remove.

30

Capítulo 4. Implementación 4.2.2 Implementación Submódulo Snapshot Es el encargado de generar copias temporales (que sólo son almacenadas en el servidor mientras éste se encuentra arrancado) de los ficheros regulares ofrecidos por el servidor y almacenarlos bajo el directorio especial dumps. Para llevar a cabo dicha operación recibirá el nombre que representará la nueva copia. Para poder realizar esta operación de una forma cómoda y eficiente ha sido necesario recurrir a detalles de implementación. En concreto se ha tenido que emplear una estructura interna, ésta es: struct Filelist { File *f; Filelist *link; };

La estructura filelist no es más que una lista enlazada que guarda punteros a estructuras de tipo file. El campo link es el encargado de apuntar al siguiente nodo de la lista y f es el puntero a la estructura file. Dicha estructura es empleada para almacenar los hijos de un directorio representado por un file. Para ello el tipo de datos file contiene un campo llamado filelist que es un puntero al primer nodo de la lista, en el caso de ser un directorio dicho campo estará a nill. La función snapshot básicamente actuaría de la siguiente forma: SNAPSHOT: Localizar dumps en el árbol ¿existe una copia bajo dumps con el mismo nombre de la que va a ser generada? Si { devolver –1 indicando que la operación ha fallado }No { crear subdirectorio de dumps con el nombre de la copia partiendo del raiz ir recorriendo ficheros y directorios y todos los que sean regulares irlos copiando en el nuevo subdirectorio de dumps }

Todos los ficheros generados bajo dumps llevarán en el campo aux->permiso el valor –1 indicándole al servidor que no podrán ser modificados, tal como se explica en las propiedades de dumps del módulo árbol.

31

Capítulo 4. Implementación

4.2.3 Submódulo Undo Es el encargado de restaurar copias temporales almacenadas en dumps. Para realizar dicha función necesitará el nombre de la copia a ser restaurada. Como se muestra en la figura 3-9 la funcionalidad de undo se encuentra dividida en act_arbol y act_disco. El primero se encarga de modificar la estructura del servidor poniendo la copia deseada como nuevo raíz y la que había anteriormente almacenada bajo dumps con un nombre genérico rehacerX (siendo X un número entero). El segundo una vez cambiada la estructura del árbol propaga dichos cambios a disco. La función que engloba ambas funcionalidades es undo, la cual modifica la estructura y llama a actdiscoundo que es la encargada de propagar los cambios en disco. La función undo básicamente funciona de la siguiente forma: UNDO: Buscar ficheros especiales dumps, snapshot y undo Buscar en dumps el que va a ser nuevo raíz Llamar a actdiscoundo Recolocarfids Indexar los ficheros especiales apuntando al nuevo raíz Viejo raiz colgando bajo dumps Quitar de viejo raíz los ficheros especiales Poner nuevo raíz como raíz del arbol

Los dos primeros pasos localizan los ficheros especiales (dumps, snapshot y undo) y la copia que va a ser restaurada (nuevo raíz) en el árbol servido. Se restaura en disco la copia mediante la función actdiscoundo, debido a la complejidad del algoritmo y a que se corresponde con un submódulo del módulo undo éste será explicado aparte. La función recolocarfids se encarga de hacer que aquellos fids en uso que están referenciando a algún file del viejo raíz pasen a referenciar al mismo file del nuevo raíz. En el caso de no existir el file que referencia el fid en el nuevo raíz dicho fid será eliminado.

32

Capítulo 4. Implementación Los pasos siguientes se encargan de reestructurar el árbol servido. Dicha operación se realiza en cuatro etapas.

Figura 4-1: Árbol inicial

La figura 4-1 muestra como se encuentra el árbol de ficheros antes de comenzar a realizar la operación undo.

Figura 4-2: Árbol después de la primera modificación

La primera etapa enlaza los ficheros especiales al nuevo raíz quedando el árbol como indica la figura 4-2 .

Figura 4-3: Árbol después de la segunda modificación

La segunda etapa enlaza el viejo raíz en el directorio dumps tal como indica la figura 4-3.

33

Capítulo 4. Implementación

Figura 4-4: Árbol después de la tercera modificación

La tercera etapa elimina los ficheros especiales del viejo raíz quedando el árbol estructurado como muestra la figura 4-4.

Figura 4-5: Árbol final

La última etapa enlaza el nuevo raíz “copia” al servidor srv terminando así la fase de reestructuración del árbol. Los árboles son renombrados, “/” en “rehacer1” y “copia” en “/” quedando el árbol servido como indica la figura 4-5. Para la restauración en disco de un árbol de directorios se emplea la función actdiscoundo. Restaurar en disco un árbol de directorios conlleva un elevado gasto de recursos por lo que hay que maximizar la eficiencia del algoritmo empleado para intentar minimizar los accesos a disco llevados a cabo. Para minimizar el gasto se ha empleado un algoritmo basado en las versiones de los ficheros y de las copias para evitar así tener que eliminar y rescribir todos los ficheros servidos en disco. El algoritmo juega con dos tipos de versiones, una para el raíz de cada árbol y otra para cada fichero de un árbol. Ambas versiones son almacenadas en la estructura campo_aux que almacena el campo aux de la estructura file. El campo de la estructura campo_aux llamado marcaraiz almacena el valor de la versión del raíz de la copia y

34

Capítulo 4. Implementación el campo llamado marcafichero almacena la versión del fichero, que se corresponderá con la versión de la copia en que fue modificado por última vez. La versión de los árboles se actualiza en dos casos, cada vez que se cree una nueva copia o cuando se restaure. La versión del árbol que cuelgue del raíz siempre almacenará el valor de la marca de tiempo. En el caso de ser generada una nueva copia ésta almacenará en raíz la marca de tiempo y se incrementará dicha marca. En el caso de restaurar una copia, el árbol servido será almacenado como una copia que almacenará como versión la marca de tiempo, se incrementará dicha marca con lo que la versión del raíz del árbol restaurado tendrá el valor de la marca de tiempo (valor más alto). La versión de los ficheros será el valor de la marca de tiempo en el momento que fueron modificados por última vez (modificar un fichero implica ser creado, escrito o cambiado algún metadato). Por lo que la versión de los ficheros será incrementada en las funciones screate, swrite y swstat. La versión del raíz será modificada en las funciones undo y snapshot. Mediante este sistema de versiones se podrá saber si un fichero ha sido modificado o no sin necesidad de realizar cálculos costosos de comparación entre éstos, bastará con ver que las versiones son distintas. El funcionamiento de la función actdiscoundo se basa en recorrer dos veces los directorios que recibe, en un primer momento el raíz del árbol que va a ser restaurado y el raíz del árbol viejo. El primer recorrido es para actualizar los ficheros en el sistema de archivos. Para ello recorre el directorio que va a ser restaurado y para cada uno de sus hijos busca su correspondiente en el directorio viejo. En el caso de no encontrarlo es creado junto con todos los que dependan en la jerarquía de él. Si lo encuentra compara las versiones. En el caso de ser iguales pasa al siguiente fichero. Si las versiones son distintas se mira si es un fichero o un directorio. En el caso de ser un fichero se borra

35

Capítulo 4. Implementación el fichero en disco y se crea uno nuevo. En el caso de ser un directorio se llama a actdiscoundo pero ahora para éste subdirectorio, creando así la recursión. El segundo recorrido se encarga de borrar aquellos ficheros que existen en el directorio viejo y no en el nuevo. Para ello recorre cada uno de los hijos del directorio viejo buscando su correspondiente en el directorio nuevo, en el caso de no ser encontrado será borrado dicho hijo junto con todos los ficheros que dependan en la jerarquía de él. Para llevar a cabo las modificaciones pertinentes en el sistema de ficheros se han empleado

las

funciones

crearfichero,

actcontfichero,

metadatosfichero

y

borrarfichero, explicadas en el submódulo G_respuesta, junto a las funciones borrardirectorio y creardirectorio. Las funciones borrardirectorio y creardirectorio son similares a borrarfichero y crearfichero, aunque al trabajar con directorios borran o crean a su vez todos los ficheros que dependan del directorio en cuestión. En el primer recorrido las actualizaciones en cada uno de los casos es como sigue. Cuando debe generar el fichero porque no existía en el árbol viejo se emplean las funciones creardirectorio y crearfichero en función de que se trate de un fichero o un directorio. Cuando existen los dos ficheros, pero las versiones son distintas se utilizará metadatosfichero y en el caso de tratarse de un fichero actcontfichero. En el segundo recorrido para realizar el borrado de aquellos ficheros que no existen en el directorio viejo se llama a borrardirectorio o ha borrarfichero en función de si se trata de un directorio o un fichero.

36

Capítulo 4. Implementación

4.3 Implementación módulo comandos

El módulo comandos se encarga de analizar el comando solicitado y en función de éste llamar a los submódulos undo o snapshot pertenecientes al módulo árbol. Como se ha indicado en la explicación del submodulo G_respuesta, perteneciente al módulo srv, el análisis de la petición para determinar si se trata de un comando o una petición 9p será realizada en la función swrite. Ya que sólo se dispone de dos comandos distintos y el análisis se encuentra centralizado en la función swrite se ha añadido la selección del comando en la propia función swrite. La función swrite en pseudocodigo quedaría como sigue: SWRITE: Analizar permisos de escritura en el fichero (ya realizado por lib9p) Se trata de un comando o una escritura normal (controlar el fichero a escribir) Si es un fichero de comandos: Ver cual es Realizar la operación adecuada Si no: Actualizar contenido fichero Generar mensaje respuesta adecuado

La parte correspondiente al módulo comandos es “realizar la operación adecuada”, que consiste en analizar el fichero en el que se pretende escribir y en función de éste llamar a las funciones snapshot o undo pasándoles los datos que iban a ser escritos en dichos ficheros.

37

Capítulo 5. Pruebas

Capítulo 5 PRUEBAS Como se ha indicado en el capítulo de diseño se ha empleado un modelo de desarrollo en espiral, esto hace que durante el desarrollo se vayan obteniendo prototipos cada vez con mayor funcionalidad. El primer prototipo consistía en un servidor de ficheros genérico que permitía crear, borrar y modificar los ficheros que servía sin propagar los cambios al sistema de ficheros de Plan 9. Las pruebas en éste primer prototipo consistían en crear, borrar y modificar los ficheros que servía comprobando que éstas creaciones, borrados y modificaciones eran realizadas correctamente. Al segundo prototipo, además de ser un servidor de ficheros genérico, se le integran los ficheros especiales añadiendo las características especiales a éstos, como que no pueden ser borrados ni modificados. El tercer prototipo ya es capaz de generar copias, haciendo que éstas sean almacenadas bajo el directorio dumps e impidiendo que dichas copias puedan llegar a ser modificadas. Las pruebas realizadas consistían en generar copias observando que éstas eran correctas y comprobar para cada una de las peticiones 9p que puedan modificar un fichero (create, write, remove y wstat) que no pueden modificar las copias. El cuarto prototipo incorpora la operación undo al servidor. Las pruebas consisten en comprobar que tras haber realizado una operación de restauración el árbol servido ha quedado en un estado consistente. El último prototipo incorpora las modificaciones en disco tanto para actualizaciones como para operaciones undo. Las pruebas consisten en observar que aquellos ficheros existentes en disco se corresponden con los ofrecidos por el servidor. Para montar undofs se ha utilizado además el servidor mntgen que genera automáticamente puntos de montaje para servidores de ficheros.

38

Capítulo 5. Pruebas Para depurar el servidor se ha empleado además un script que recibe un identificador de proceso y para el proceso identificado muestra el contenido de la pila del sistema. Mediante la aplicación de dicho script obtendríamos la siguiente información: /proc/420/text:386 plan 9 executable /sys/lib/acid/port /sys/lib/acid/386 acid: createfile(fp=0x0,name=0x368f8cc,uid=0x368f8d5,aux=0x368fd88,perm=0x1fd)+0x7 /sys/src/lib9p/file.c:145 freel=0x0 fl=0x368fce4 f=0x368fd88 t=0x2054e leerfichero(path=0x368fc68,padre=0x0,name=0x368f8cc,uid=0x368f8d5,mode=0x1fd)+0x1c3 /usr/glenda/pfc/undofs_disco.c:400 f=0x7 estado=0x368fca8 contenido=0x3f87668 leerdirectorio(path=0x368efc8,padre=0x0)+0x276 /usr/glenda/pfc/undofs_disco.c:437 fd=0x6 hijos=0x368f548 numhijos=0xf sighijo=0x368f548 i=0x0 aux1=0x368fc68 leerdirectorio(path=0x2df70,padre=0x1bda4)+0x218 /usr/glenda/pfc/undofs_disco.c:437 fd=0x5 hijos=0xca278 numhijos=0x126 sighijo=0xcd608 i=0xdc aux1=0x368efc8 leerdirectorio(path=0x7fffeff2,padre=0x1bab0)+0x218 /usr/glenda/pfc/undofs_disco.c:437 fd=0x4 hijos=0x2cc50 numhijos=0x28 sighijo=0x2cc8c i=0x1 aux1=0x2df70 arbolservido(path=0x7fffeff2)+0x9b /usr/glenda/pfc/undofs_disco.c:463 ar=0x1ba70 contsnapshot=0x0 contundo=0x7fffef64 main(argv=0x7fffefe0,argc=0x2)+0x98 /usr/glenda/pfc/undofs_disco.c:1004 _argc=0x0 _args=0x0 mnt=0x7fffeff4 _main+0x31 /sys/src/libc/386/main9.s:16 acid: echo kill > /proc/420/ctl

Como se puede observar las funciones aparecen tal y como han sido llamadas durante la ejecución del programa, junto con el valor de los parámetros que reciben. Al ser una pila las funciones de la parte superior son las más recientes. Para depurar el sistema ha sido necesario observar los mensajes intercambiados entre cliente y servidor (característica ofrecida por el servidor). Ésta opción nos la ofrece la librería lib9p y para activarla basta con poner a 1 el valor de la variable chatty9p de la librería. 39

Capítulo 5. Pruebas Un ejemplo de las pruebas realizadas es el que sigue a continuación. Este ejemplo realiza una copia “copia1”, borra algunos ficheros comprobando que también son borrados en el sistema de ficheros de Plan 9 y restaura “copia1” comprobando que se ha realizado correctamente la restauración en disco. De una forma más detallada: term% mntgen /n term% undofs /usr/glenda/tmp/undofs /n/undo term% cd /n/undo

Se monta el servidor mntgen en /n para que el servidor genere /n/undo cuando vayamos a acceder a él. Undofs es montado en /n/undo sirviendo el directorio /usr/glenda/tmp/undofs. El usuario se desplaza a /n/undo (directorio servido por undofs). term% lc a b c dumps f1 f2 term% lc /usr/glenda/tmp/undofs a b c f1 f2 f3 f4 term% cat f1 hola1 term% cat /usr/glenda/tmp/undofs/f1 hola1

f3

f4

snapshot undo

Se realiza una comprobación rápida de correspondencia entre el sistema de ficheros y el árbol servido por undofs. term% echo copia1 > snapshot term% lc dumps copia1

Se realiza una copia llamada “copia1” y se comprueba que ha sido generada bajo el directorio dumps. term% rm f* term% lc a b c dumps snapshot undo term% rm c term% lc a b dumps snapshot undo term% lc /usr/glenda/tmp/undofs ab

Son borrados algunos ficheros y se comprueba que en disco también han sido borrados. term% echo copia1 > undo term% lc a b c dumps f1 f2 term% lc /usr/glenda/tmp/undofs a b c f1 f2 f3 f4 term% cat f1 hola1 term%

f3

f4

snapshot undo

40

Capítulo 5. Pruebas

Se restaura “copia1” y se comprueba que la operación ha sido satisfactoria tanto en el sistema de archivos como en el servidor.

41

Capítulo 6. Conclusiones

Capítulo 6 CONCLUSIONES Como resultado del desarrollo de este proyecto, se ha obtenido un servidor de ficheros llamado undofs que resuelve los problemas expuestos en el capítulo objetivos. Undofs se monta entre el cliente y el sistema de ficheros de Plan 9 respondiendo a las peticiones del árbol que sirve. Para el usuario aparece como un montaje en su sistema de ficheros con la particularidad de ofrecer tres ficheros especiales. Estos ficheros especiales están destinados a ofrecer la interfaz de las características especiales del servidor al cliente. Las características especiales de undofs son permitir la creación de backups temporales de los datos servidos, permitiendo volver a algún backup en cualquier momento mediante una interfaz sencilla. Esas características son cumplidas por undofs y la interfaz que ofrece consiste en escribir el nombre de la copia deseada al fichero que representa el comando ha realizar. También ofrece un directorio especial llamado dumps que permite navegar entre las copias para poder consultar la información almacenada.

6.1 Lecciones aprendidas Para la realización del presente proyecto ha sido necesario el aprendizaje o ampliación de conocimientos en los siguientes temas: -

Manejo del sistema operativo Plan 9.

-

Manejo del entorno de ventanas Rio.

-

Utilización del editor por excelencia de Plan 9, Acme.

-

Ampliación de conocimientos en el lenguaje de programación C, empleado para la realización de programas en Plan 9.

-

Herramientas de compilación (8c, 8l) y depuración (acid) de programas en Plan 9.

-

Funciones y funcionamiento de servidores de ficheros.

42

Capítulo 6. Conclusiones -

Características de los servidores de ficheros en Plan 9.

-

Protocolo de comunicaciones 9p.

-

Llamadas al sistema para la manipulación de ficheros.

-

Manejo de la librería lib9p dedicada a la creación de servidores en Plan 9.

-

Estudio de la implementación de la librería lib9p relacionada con el manejo de árboles de ficheros mediante la estructura tree.

-

Métodos para la depuración de programas.

6.2 Trabajos futuros Una posible mejora del servidor consistiría en permitir restaurar en lugar de copias completas parte de éstas, esto es sólo algún subdirectorio. Añadir dicha funcionalidad obligaría a cambiar la interfaz del comando undo para diferenciar cuando se realiza la restauración de una copia o de una parte de ésta. La otra función que debería ser modificada es undo, aunque sus modificaciones consistirían en diferenciar cuando se va a restaurar el árbol al completo o tan sólo un subdirectorio de éste, ya que en función de uno u otro es necesario realizar unas operaciones o no. Para la restauración en disco bastaría con realizar pequeñas distinciones en cuanto a los directorios en los que se trabaja. Otra posible mejora es modificar undofs para que sirva una lista de ficheros y directorios, aunque su realización conllevaría grandes modificaciones en el servidor y ésta mejora puede ser realizada por otros medios, como pudiera ser arrancar un servidor por cada uno de los elementos de la lista. Otra mejora consistiría en permitir que undofs pudiera recibir un fichero para que éste lo administre. Seria una modificación simple que consistiría en modificar la función arbolservido, ya que es la encargada de crear en el servidor los ficheros que administra éste. Otra posible mejora consistiría en modificar el editor de Plan 9 acme para que soporte la nueva funcionalidad que ofrece undofs.

43

BIBLIOGRAFÍA 1. A. Tanenbaum, A. Woodhull. Sistemas Operativos: diseño e implementación. Prentice may, 2ª edición, 1997. 2. A. Tanenbaum. Sistemas Operativos distribuidos. Prentice Hall, 2ª edición, 1996. 3. Brian W. Kernighan, Dennis M. Ritchie. The C Programming Language. Prentice Hall, 2ª edición, 1988. 4. Francisco J. Ballesteros. Plan 9 en la URJC. http://plan9.escet.urjc.es 5. Vita Nuova. Plan 9 Documents volumen2. Disponible también en http://cm.bell-labs.com/sys/doc/index.html y en /sys/doc de un Plan 9. 6. Vita Nueva. User´s Manual (Manual Page´s) volumen 1. Disponible también en http://cm.bell-labs.com/sys/man/index.html, y en man de un Plan 9 instalado.(En concreto las páginas de la sección 5 y de la sección 2: 9p, 9pfile, 9pfid, stat).

44

Get in touch

Social

© Copyright 2013 - 2024 MYDOKUMENT.COM - All rights reserved.