Sistema de ficheros con semántica de sesión (MINIAFS)
Se trata de una práctica que se puede desarrollar en grupos de 2 personas, con un peso de 4 sobre 10 en la nota final de la asignatura.
El plazo de entrega de la práctica tanto en la convocatoria de junio como en la de septiembre coincide con el día del examen de la asignatura.
NOTA IMPORTANTE: Aunque se puede desarrollar la práctica en cualquier máquina Linux,
ésta debe funcionar en triqui, que es donde se lleva a cabo la corrección
de la misma. Se debe tener en cuenta que triqui es una máquina de 64 bits, lo que
puede afectar a operaciones que mezclan tipos de datos (por ejemplo,
la asignación de un tipo puntero a un int no funcionará correctamente
en este tipo de arquitecturas).
Objetivo de la práctica
La práctica consiste en desarrollar un sistema de ficheros distribuido
simplificado basado en el modelo de carga/descarga y con una semántica
de sesión. Se trata, por tanto, de un sistema con unas características
similares al AFS estudiado en la parte teórica de la asignatura, aunque,
evidentemente, muy simplificado. Se recomienda, por tanto, que el alumno
estudie el sistema de ficheros AFS en la documentación de la asignatura
antes de afrontar la práctica.
Asimismo, dado que la comunicación se realizará mediante el mecanismo
RPC/XDR de SUN (conocido también como RPC/XDR de ONC), con esta práctica el
alumno llegará a familiarizarse con el mismo
(véase Guía de programación con las RPC de Sun/ONC).
NOTA IMPORTANTE: El código desarrollado debe permitir la transferencia
de ficheros binarios, no sólo de texto. Asegúrese de que en las pruebas
que realice a su práctica se usan ficheros que contienen al menos un byte a 0.
Arquitectura general del miniafs
Dada su similitud con AFS, la arquitectura del sistema que se pretende
desarrollar tiene las siguientes características:
- En el nodo "servidor" (directorio servidor), se ejecuta vice
que proporciona acceso a los ficheros del sistema mediante el modelo de carga
y descarga.
- En cada nodo "cliente" (directorios cliente1, cliente2
y cliente3), donde se ejecutan las
aplicaciones, hay dos componentes:
A pesar de las similitudes con AFS, el sistema que se pretende desarrollar
presenta numerosas diferencias con objeto de simplificar su diseño:
- En el sistema sólo hay un servidor que,
además, ofrece un sistema de ficheros plano (sin directorios).
Concretamente, el servidor exportará sólo los ficheros que se encuentran en el
directorio servidor/Ficheros (o sea, que si un cliente solicita el
fichero f, el servidor enviará el fichero Ficheros/f).
- En cada nodo "cliente" se ejecutará sólo una aplicación de usuario
en cada momento, no existiendo el concepto de usaurios y permisos de acceso
a los ficheros (o sea, todos los ficheros son accesibles).
Interfaz a las aplicaciones
A las aplicaciones de usuario se les ofrece la siguiente interfaz:
int OpenFile(char *fichero, int flags);
ssize_t read(int fd, void *buf, size_t tam);
ssize_t write(int fd, void *buf, size_t tam);
int CloseFile(char *fichero, int fd);
Nótese que los prototipos de las funciones read y write
son idénticos a los de POSIX. De hecho, imitando el comportamiento de AFS,
realmente la aplicación estará llamando directamente a las funciones
del sistema operativo, no siendo, por tanto, "capturadas" por el
miniafs.
Las funciones de apertura y cierre de fichero (cuyos prototipos
están definidos en el fichero (clienteX/venusbib.h) son específicas del
miniafs y serán las que generen las llamadas RPC de carga y
descarga, respectivamente.
Por lo que se refiere a la llamada OpenFile, el parámetro
flags, tienen el mismo significado que en el servicio open
de POSIX, pero, por simplicidad, sólo se permiten los siguientes valores:
- O_CREAT. Si el fichero no existe, se creará. Si no se
especifica este valor y se intenta abrir un fichero que no existe,
OpenFile devolverá un error (valor devuelto menor que 0).
Nótese que al igual que ocurre en POSIX, este flag no trunca
el contenido previo del fichero, sino que, en caso de que exista, lo
deja abierto manteniendo el contenido previo y con el desplazamiento colocado
al principio del fichero.
- O_RDONLY. El fichero se abre sólo para lectura.
- O_RDWR. El fichero se abre para lectura y escritura.
En cuanto a CloseFile, por simplicidad, la aplicación debe
especificar tanto el descriptor de fichero (el valor devuelto por
OpenFile) como el nombre del mismo.
Arquitectura del software de la práctica
Dado que la mayoría de alumnos desarrollará la práctica en una sola
máquina, para crear una cierta independencia entre las distintos
componentes, se van a usar varios directorios, de manera que cada uno
represente una máquina independiente:
- Directorio servidor, donde reside el software del servidor
vice. Incluye los siguientes componentes:
- Código del servicio (fichero vice.c). Este módulo debe
desarrollarlo el alumno.
- Resguardo del servidor vice. Ficheros generados automáticamente por
rpcgen (ficheros vice_svc.c, vice_xdr.c y
vice.h).
- Resguardo de cliente del servicio venus. Como se comentó
previamente, cuando se llega a la fase de desarrollo de la práctica
donde se implementa el protocolo de coherencia, el servidor vice
debe hacer de "cliente" de los servidores venus que ejecutan en los
nodos cliente. Por tanto, llegado ese momento, se necesitará el resguardo
de cliente para venus generado automáticamente por
rpcgen (ficheros venus.h, venus_xdr.c y
venus_clnt.c).
- Directorios clienteX, que representan las distintas máquinas
donde ejecutan las aplicaciones de usuario. En todos ellos hay los mismos
componentes software:
- Biblioteca de servicio (fichero venusbib.c). Este módulo debe
desarrollarlo el alumno.
- Resguardo de cliente del servicio vice. Ficheros generados automáticamente por
rpcgen (ficheros vice_clnt.c, vice_xdr.c y
vice.h).
- Servidor venus (fichero venus.c). Este módulo debe
desarrollarlo el alumno cuando emprenda la fase de desarrollo de la
práctica que lo requiere.
- Resguardo del servidor venus. Ficheros generados automáticamente por rpcgen (ficheros venus.h, venus_xdr.c y
venus_svc.c).
- Aplicaciones de ejemplo (lector y escritor).
Recapitulando, la práctica consiste en diseñar un servicio (directorio
idls):
- Servicio vice (fichero vice.x), vinculado
con la carga y descarga de ficheros. El alumno debe especificar este
servicio como considere oportuno.
Nótese que, por motivos que se explican
más adelante, en el material de apoyo ya se proporciona la especificación del
servicio venus (fichero venus.x), relacionado
con el protocolo de coherencia de la cache, así como sus resguardos.
Y en programar 3 componentes:
- El servidor vice.
- La biblioteca de servicio venusbib.
- El servidor venus, que ejecuta en los nodos "cliente".
Asignación de número de programa al servicio
Dado que se trata de un servicio basado en las RPC de Sun, es necesario
asignar un número de programa a estos servicios. A continuación, se
comenta cómo realizar esta asignacion siguiendo las recomendaciones
de Sun (que plantea que los programas desarrollados por los usuarios tengan
números mayores que 2 elevado a la 29) e intentando evitar las colisiones entre
alumnos que desarrollen la práctica en el mismo sistema.
Antes de plantear la estrategia, hay que hacer una aclaración
relacionada con el servicio venus.
Si la
práctica se desarrollase de forma "natural", o sea, usando varias máquinas
(una por cada nodo "cliente"
y otra para el servidor), sólo haría falta asignar 2 números de programa:
uno para el servicio vice y otro para venus. Sin embargo,
al usar la misma máquina, necesitamos algún "truco" para que los múltiples
servicios venus puedan coexistir sin que se produzcan colisiones.
Para ello, hemos "trucado" los resguardos del servicio venus
generados automáticamente (cosa que no debería hacerse normalmente) para
que lean el número de programa en tiempo de ejecución de la
variable de entorno PROGNUM. Por esta razón, ya se incluye
en el material de apoyo la especificación del servicio venus,
así como los resguardos "trucados".
La estrategia de asignación de número de programa se basa en usar
el número de D.N.I de uno de los alumnos, pero completándolo hasta 9 dígitos
añadiendo por la izquierda un número de relleno tantas veces como haga falta.
Para el servicio vice, el número de relleno será el 6 y para
los servicios venus serán el 7, 8 y 9, respectivamente:
DNI=7654321
Núm prog para vice=667654321 (especificado en vice.x)
Núm prog para venus en cliente1=777654321 (especificado en var. PROGNUM)
Núm prog para venus en cliente2=887654321 (especificado en var. PROGNUM)
Núm prog para venus en cliente3=997654321 (especificado en var. PROGNUM)
Para facilitar la corrección de las prácticas, el alumno no debe
especificar el número de programa elegido dentro de la sentencia
program del fichero de IDL (vice.x), sino en la
siguiente línea de dicho fichero:
%#define NUMPROG 667654321
Por otro lado, para que el cliente pueda conocer en qué máquina está ejecutando
el servidor, antes de ejecutar el cliente, se deberá definir la variable de
entorno SERVIDOR con el nombre de la máquina donde ejecuta el
servidor. La biblioteca de servicio (fichero venusbib.c) debe encargarse
de leer esta variable.
Por lo que se refiere a la comunicación cliente-servidor, dado el tamaño
de las transferencias, se usará
el protocolo TCP. Para optimizar la eficiencia del servicio, se
recomienda que la biblioteca de servicio realice la conexión (clnt_create) en la primera petición de la aplicación y la mantenga hasta que la
aplicación termine.
Fases en el desarrollo de la práctica
A continuación, se proponen una serie de etapas para el desarrollo de esta
práctica, especificándose la valoración de cada una de ellas. Antes de pasar
a ello y aunque parezca obvio, parece conveniente resaltar que para
el desarrollo de la práctica se hará uso de numerosos servicios POSIX
de acceso a ficheros.
Versión 1: Modelo de carga/descarga sin coherencia
El desarrollo correcto de esta fase proporcionará una nota de 5 puntos.
Nótese que en esta versión no "entra en juego" el servidor venus,
aunque, para acostumbrarse al modo de trabajo de versiones posteriores,
se recomienda usarlo. Por tanto, el orden de arranque de los componentes
de la práctica es el siguiente:
- Arranque del servidor vice.
- En cada nodo "cliente", arranque de su servidor venus. Aunque
no sea necesario en esta fase, es conveniente acostumbrarse a esta forma
de arranque. Además, el código del resguardo "trucado"
borra la cache del nodo (esto no ocurre así en AFS donde la cache se mantiene
al arrancar un nodo "cliente"). Recuerde definir la variable de entorno
PROGNUM antes de arrancar cada instancia de venus.
- Ejecución de aplicaciones en los distintos nodos "cliente".
Recuerde definir la variable de entorno SERVIDOR antes de ejecutar
las aplicaciones.
Con esta versión, está activa la cache, pero no hay protocolo de
coherencia. Por tanto, las copias de los ficheros que se traen a la cache,
se mantendrán allí indefinidamente.
Para desarrollar esta versión, se pueden seguir los siguientes pasos:
- Especificación del servicio en el fichero idls/vice.x. Se recomienda
especificar un número de programa basado en el DNI del alumno, siguiendo
las pautas anteriormente comentadas. Queda a descripción del alumno qué
servicios definir y con qué características.
Recuerde usar el siguiente comando para procesar el fichero IDL y
generar los resguardos:
rpcgen -C vice.x
No olvide tener en cuenta la influencia del flag O_CREAT.
- Implementación del servicio (servidor/vice.c).
Se recomienda tomar como punto de partida la salida generada por el
comando:
rpcgen -Ss -C vice.x
- Implementación de la biblioteca de servicio (cliente1/venusbib.c).
Se recomienda tomar como punto de partida la salida generada por el
comando:
rpcgen -Sc -C vice.x
Recuerde que debe incluir en este módulo la llamada getenv para leer
la variable de entorno SERVIDOR.
Nótese que no se ha explicado cómo implementar OpenFile
y CloseFile, ya que se corresponden directamente con lo
explicado en la parte teórica de la asignatura con respecto al AFS.
Repase, en caso de duda, estos aspectos teóricos.
De cualquier forma, una pequeña ayuda: Para detectar en CloseFile
si el fichero ha sido modificado, puede ponerse a cero el tiempo de
modificación del mismo (llamada utime) en la carga del fichero
y, al cerrarlo, comprobar este valor para ver si ha cambiado.
Versión 2: Inclusión de un algoritmo de coherencia con restricciones
El desarrollo correcto de esta fase proporcionará una nota de 3 puntos.
Nótese que en esta versión ya "entra en juego" el servidor venus,
pero sólo se usará uno de sus servicios, concretamente, revocar_callback. El servicio activar_callback sólo se usará en la última
versión de la práctica.
Como aparece en el título de esta sección, el protocolo de coherencia que
se va a implementar en esta fase va a tener una serie de restricciones y
simplificaciones para reducir su complejidad. En la siguiente fase
se abordará un algoritmo de coherencia más general y realista que
eliminará algunas de estas restricciones.
Las restricciones que se van a aplicar al algoritmo son las siguientes
(nótese que no hay que comprobar que se cumplan estas restricciones;
simplemente, se asegura que el sistema sólo se probará manteniendo
dichas restricciones):
- Como se comentó al principio del documento, en cada nodo "cliente" se
ejecutará sólo una aplicación de usuario en cada momento. Además, en
esta fase se establece la restricción de que una aplicación no pueda
tener abierto simultáneamente el mismo fichero.
- Se establece también una simplificación sobre qué "escenarios" de accesos
concurrentes se pueden dar en el sistema. Se va a restringir a situaciones
en las que no puede haber sesiones de escritura simultáneas. Por tanto, en cada
momento sólo puede haber una aplicación (o sea, un nodo "cliente")
con el fichero abierto para escritura. En el resto de los nodos, o bien
no se está usando ese fichero o está abierto para sólo lectura.
A continuación, se explican algunos de los cambios que hay que realizar para
abordar esta fase:
- Hay que programar el servicio revocar_callback de venus,
que simplemente debe borrar la copia local del fichero para que deje de
estar accesible.
- Se debe modificar la especificación del servicio vice para que
en las RPCs se incluya información sobre quién es el cliente (puede
usarse gethostname para averiguar en qué máquina ejecuta
un proceso), para poder
así mandarle mensajes de invalidación cuando sea necesario.
- La parte principal del algoritmo de coherencia está
en el servidor vice, donde hay que implementar el protocolo
basado en callbacks presentado en la teoría de la asignatura
como parte del estudio de AFS. Nótese que, a diferencia de lo que ocurre
en un sistema AFS, en esta práctica, una vez creado un fichero, no se
puede borrar (no hay ninguna llamada para hacerlo). Por tanto, siempre
habrá al menos una copia del fichero en la cache de algún nodo cliente
(o sea, la lista de callbacks nunca estará vacía).
Versión 3: Algoritmo de coherencia mejorado
El desarrollo correcto de esta fase proporcionará una nota de 2 puntos.
Nótese que en esta versión también "entra en juego" el servicio activar_callback
del servidor venus.
La eliminación de las restricciones planteadas en el apartado anterior
complica considerablemente el algoritmo de coherencia por las siguientes
razones:
- La posibilidad de que haya sesiones de escritura simultáneas
crea varios problemas:
- Hace que
ya no valga directamente la solución de borrar el fichero. Así, si
borramos la copia que hay en un nodo "cliente" mientras se está realizando
una sesión de escritura, cuando se cierre esa sesión, esa copia del
fichero será la "buena" para todo el sistema. Por tanto, en el nodo
cliente habría que hacer también que esa copia sea la "buena". Para ello,
sólo haría falta renombrarla, pero el problema es que esa copia es
"anónima" ya que previamente borramos su nombre. La solución que se
propone en este apartado, como se explicará más adelante, es hacer que
cada sesión sobre un fichero cree un "sinónimo" temporal (o sea, un enlace adicional
mediante la llamada link)
al fichero. Como se verá más adelante, este nombre temporal puede generarse automáticamente
a partir del nombre real.
Con ello, aunque el protocolo de coherencia borre el fichero,
podremos acceder al mismo cuando se cierra mediante el sinónimo.
Este nombre temporal será borrado cuando termine la sesión.
- Crea problemas de carrera cuando se produce el cierre de 2
sesiones de escritura simultáneas en 2 nodos diferentes. Puede ocurrir,
por ejemplo,
que ambas copias queden invalidadas. Hay que asegurarse de
que la última que vuelque el fichero es la que gana. Más adelante,
se analiza este problema.
- La posibilidad de que un proceso abra simultánemente varias
veces el mismo fichero también crea ciertos problemas:
El carácter asíncrono del tratamento de revocar_callback en
venus crea problemas de sincronización entre el servidor venus
y la biblioteca de servicio venusbib. A continuación, se analizan
estos problemas y cómo solucionarlos (como parte de esta explicación
se mostrará cuál es el objetivo de la RPC activar_callback
y cómo se usa):
Material de apoyo de la práctica
Al descomprimir el material de apoyo se crea el entorno de desarrollo de la práctica, que
reside en el directorio: $HOME/DATSI/SOD/MINIAFS.2013/.
Como parte del material de apoyo, se proporciona la especificación del
servicio venus, junto con los resguardos modificados.
Hay que resaltar que el material de apoyo proporcionado no compila
directamente ya que para ello es necesario que se generen previamente
los resguardos de RPC correspondientes.
Entrega de la práctica
Se realizará en la máquina triqui, usando el mandato:
entrega.sod miniafs.2013
Este mandato recogerá los siguientes ficheros: