La práctica consiste en hacer un manejador (driver) de un dispositivo
de bloque que importa el disco físico a través de la red utilizando
sockets. El manejador llamado dbr (Driver de Bloque en Red)
es una opción alternativa a los sistemas de ficheros en red, pues el
acceso al dispositivo es mucho mayor, por ejemplo el dbr establece la independencia
del sistema de ficheros que se importe, que puede ser cualquiera: ext2, msdos,
ntfs, ufs, etc.
Se accederá al driver dbr a través de los ficheros
especiales /dev/dbr0 y /dev/dbr1(con número mayor 112). Estos dispositivos
podrán ser utilizados como cualquier otro dispositivo de bloques, con
la única salvedad de que las operaciones se transmitirán a
través de un socket a la máquina que exporta el disco donde
finalmente se ejecutarán.
El driver se hará para que funcione en kernels 2.4, y la práctica
se evaluará en los mismos laboratorios en que se imparten las clases.
La evaluación será presencial, y consistirá en una entrevista
con los miembros del grupo que mostrarán su práctica, le pasarán
una batería de pruebas, y contestarán a las preguntas del profesor
y eventuales modificaciones que requiera.
La diferencia de esta práctica con la práctica de junio
consiste en que en esta nueva versión, el encargado de realizar
la firma md5 de los datos es el driver dbr. La finalidad de este
cambio es facilitar procedimientos de reconexión sin necesidad de
introducir de nuevo la clave.
La arquitectura del sistema global será la siguiente:
Servidor (serv_dbr) : Proceso remoto que exporta
el dispositivo.
El servidor será un proceso que se ejecute en espacio
de usuario. El servidor abre un socket pasivo, lo ata (bind) a un
puerto determinado y se queda a la espera de conexiones. El dispositivo de
bloque que exporta el servidor será un fichero. El servidor una vez
conectado con un cliente, queda a la espera de recibir comandos de lectura
o escritura sobre el dispositivo y de mandar los ack correspondientes.
Cliente (clie_dbr) : Proceso local que realiza
la conexión con el servidor.
El cliente será el responsable de:
- abrir el dispositivo
- pasar al kernel la clave de firma de los datos, pues
es el driver dbr el responsable de realizar las firmas md5.
- conectarse con el servidor
- pasar al kernel la información del
tamaño del dispositivo importado
Una vez informado el driver de las características del dispositivo
importado, el cliente utiliza nuevos comandos ioctl para:
-
esperar a que se produzcan peticiones sobre el dispositivo
(request)
-
obtener información de la petición actual
-
informar del resultado de la petición cursada
Estas operaciones permiten la sincronización del driver
(dbr) con el proceso cliente (clie_dbr)
Driver (dbr) : Es el encargado de atender las
peticiones del kernel sobre el dispositivo de bloque.
El driver convierte las peticiones de lectura y escritura
de bloque recibidas de algún proceso o hilo del kernel en peticiones
que realiza sobre el cliente (cli_dbr). Por supuesto también debe de
sincronizarse con el cliente para indicar que se ha recibido una petición,
y para acabar las peticiones cuando se recibe la respuesta del cliente.
Dispositivos : El driver maneja dos dispositivos
con la misma política, dando la oportunidad de importar distintos
dispositivos de bloque desde distintos servidores. Son los dispositivos
/dev/dbr0 y /dev/dbr1 ya comentados.
Opciones
de cliente y servidor
|
|
El cliente (cli_dbr) y el servidor (serv_dbr) comparten
ambos un secreto (DBR_SECRET ) que van a utilizar para garantizar
la integridad de los mensajes del protocolo. El secreto lo obtienen ambos
por línea de comando como una de las opciones con las que se
invoca.
A diferencia de la práctica de junio el cliente NO realiza las firmas
md5, sino que las recibe del driver dbr, de esta forma se permite que se
puedan realizar reconexiones sin introducir de nuevo la
clave.
Por ejemplo a continuación se da la el comando para invocar a un servidor
que exporte el fichero llamado fichero_a_exportar utilizando
el secreto tortilladepatatasopepitodeternera y que espera recibir
llamadas en el puerto 3126:
server.serverdom$ serv_dbr fichero_a_exportar -s
tortilladepatatasopepitodeternera -p 3126
El cliente que se conectara a este servidor e importase
el disco en el dispositivo /dev/dbr0 , se invocaría con
los siguientes argumentos:
client.clientdom$ clie_dbr /dev/dbr0 -s tortilladepatatasopepitodeternera
-h server.serverdom -p 3126
Protocolo
cliente/servidor
|
|
Una vez arrancado el servidor y cuando el cliente se
ha conectado mediante un socket TCP, se inicia el siguiente protocolo:
- Inicio de conexión: Una vez conectado un cliente, el
servidor lee un reto acordado (
DBR_INIT ), los segundos transcurridos
desde EPOCH (1/1/1970) como la que devuelve time (ver la página
del manual time(2)). Junto con el reto se recibe la firma md5sum(DBR_INIT,
TIME, DBR_SECRET). Si el reto y la firma son correctos, el servidor
envía de vuelta el mismo reto, el tamaño del dispositivo exportado,
y la firma md5sum(DBR_INIT, SIZE, DBR_SECRET ). En caso
de que fueran incorrectos, el servidor cierra la conexión. Análogamente,
el cliente también cierra la conexión si el reto o la firma
recibidos del servidor fueran incorrectos.
- Lecturas y escrituras: Los mensajes de lecturas y escrituras
tienen un formato común definido en la estructura
dbr_request :
struct dbr_request { DBR_MAGIC_T magic; /* DBR_REQUEST_MAGIC */ DBR_TYPE_T type; /* == READ || == WRITE */ DBR_FROM_T from; /* puntero al fichero */ DBR_LEN_T len; /* longitud */ } ;
- Respuestas: A cada lectura/escritura le sigue una respuesta
con los datos/ack según la estructura
dbr_reply :
struct dbr_reply { DBR_MAGIC_T magic; /* DBR_REPLY_MAGIC */ DBR_LENT_T len; /* Longitud de datos de respuesta */ DBR_ERROR_T error; /* 0 = ok, else error */ } ;
En el caso de las lecturas los datos vendrán en la
respuesta del servidor a continuación de la estructura dbr_reply, y
finalmente la firma de los datos.
En el caso de las escrituras los datos vendrán en la propia petición
a continuación de la estructura dbr_request, y detrás de los
datos la firma md5. En el caso de escrituras, el campo de longitud de la respuesta
no es significativo.
Resumimos el protocolo a continuación, utilizando un color naranja para los envíos del cliente al servidor
y un color morado para los envíos del
servidor al cliente:
PROTOCOLO::= { CONEXION; OPERACION* } CONEXION::= { INIT_cli; INIT_serv} INIT_CLI::= { DBR_INIT TIME MD5SUM(DBR_INIT, TIME, DBR_SECRET) } INIT_SERV::= { DBR_INIT SIZE MD5SUM(DBR_INIT, SIZE, DBR_SECRET) } OPERACION::= { LECTURA | ESCRITURA } LECTURA::= { dbr_request_read; dbr_reply datos MD5SUM(datos, DBR_SECRET) } ESCRITURA::= { dbr_request_write datos MD5SUM(datos, DBR_SECRET); dbr_reply }
En el archivo pdbr.tgz, se encuentran los ficheros
cabecera del protocolo (dbr.h), el servidor de bloques para
utilizar de prueba y con el que se corregirán las
práctica, por lo que es IMPORTANTE NO MODIFICAR EL
SERVIDOR. En el archivo también se encuentran algunos
ficheros auxiliares.
A la hora de realizar las firmas md5 en el driver, es
necesario tener en cuenta que la función crypto_name_rev
del fichero hashcom.c debe de ser reescrita, pues utiliza
las funciones strspn, strncasecmp, y strlen.
Estas funciones se encuentran en la biblioteca estándar
libc que NO está disponible en el kernel.
Se recomienda utilizar el libro de
Rubini y basarse en el módulo sbull.
Para realizar pruebas de funcionalidad se recomienda seguir
los siguientes pasos:
- Arrancar el servidor, insertar el módulo dbr, y arrancar
el cliente. Comprobar que la conexión se realiza satisfactoriamente
y que el dispositivo tiene el tamaño correcto.
- Probar escrituras simples con un cliente propio (open, write,
close) y otro que haga lecturas simples.
- Probar a crear un sistema de ficheros con mke2fs /dev/dbr0.
- Probar a montar el sistema de ficheros con mount /dbr0 (en
el laboratorio hay una linea en /etc/fstab al efecto)
- Copiar el directorio con el código del dbr en /dbr0
- Desmontar el sistema de ficheros /dbr0
- Parar el cliente, quitar el dispositivo y parar el servidor.
- Arrancar de nuevo el servidor, insertar el módulo y
arrancar el cliente, y montar el /dbr0 para comprobar que las escrituras se
hicieron correctamente.
|