Home UC3M
Home IT
 


 LABORATORIO DE ARQUITECTURA DE ORDENADORES (4º Ingeniería de Telecomunicación)

 PRÁCTICA DE SEPTIEMBRE: MANEJADORES DE BLOQUE EN RED


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.


Arquitectura

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 }
Material disponible

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:

  1. 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.
  2. Probar escrituras simples con un cliente propio (open, write, close) y otro que haga lecturas simples.
  3. Probar a crear un sistema de ficheros con mke2fs /dev/dbr0.
  4. Probar a montar el sistema de ficheros con mount /dbr0 (en el laboratorio hay una linea en /etc/fstab al efecto)
  5. Copiar el directorio con el código del dbr en /dbr0
  6. Desmontar el sistema de ficheros /dbr0
  7. Parar el cliente, quitar el dispositivo y parar el servidor.
  8. 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.


 



Localización | Personal | Docencia | Investigación | Novedades | Intranet
inicio | mapa del web | contacta