Está en la página 1de 32
18) Carreto Pérez, Jestis. (2003). “Introduccién a los sistemas distribuidos” en Précticas de Sistemas Operatives. México: McGraw-Hill, pp. 189-220. Introducci6n a los sistemas distribuidos En este capitulo se presentan practicas relacionadas con sistemas disiribuidos. Este capitu- lo tiene dos objetivos biisicos: en primer lugar, se muestran al lector los servicias y meca- nismos basicos que permiten construir aplicaciones distribuidas; en segundo higar, las précticas propuestas intentan que el lector entienda cémo se construyen algunos de los servicios que ofrece un sistema operativo distribuido, como son el sistema de archivos distribuido y los servicios de sincronizacién para aplicaciones distribuidas. 189 "Material compiiado confines académicos, se prohibe su reproducién total o parcial sin la autorzacin 6 cada autor, 190 Libro de practieas de sistemas operatives 6.1. CONCEPTOS BASICOS Un sistema distribuido se puede definir segin dos puntos de vista: * Desde un punto de vista fisico, un sistema distribuido es un conjunto de procesadores, posiblemente heterogéneos, sin memoria ni reloj comiin que se encuentran conectados @ través de una red de interconexién. Esta estructura se presenta en la Figura 6.1. + Desde un punto de vista légico, un sistema distribuido es un conjunto de procesos que ejecutan en una o mas computadoras y que colaboran y se comunican entre ellos mediante él intercambio de mensajes. Este tipo de sistemas ha tenido un enorme desarrollo durante ta década de los noventa debido sobre todo a la gran difusién de Intemet. Las principales caracteristicas que presentan los siste- mas distribuidos se enumeran a continuacién: Posibilidad de compartir recursos. Un sistema disttibuido permite compartir diferentes recursos hardware, software o datos. Un ejemplo tipico de recurso compartido en un entor- no distribuido es una impresora conectada a una red, que puede ser utilizada por los usua- rios de una organizacién. ‘+ Capacidad de crecimiento. Es relativamente facil que un sistema distribuido crezca para adaptarse a las nuevas demandas de servicio, basta con conectar mas computadoras ala red. «+ Alto rendimiento. Ei empleo de miittiples procesadores hace posible la construccién de un sistema de altas prestaciones que permite oftecer servicio concurrente a miitiples usuarios y del que pueden beneficiarse las aplicaciones paralelas. bilidad y disponibilidad. El hecho de disponer de miltiples procesadores conect dos a una red oftece la posibilidad de tener una alta disponibilidad. Asi, por ejemplo, ‘considere un servidor de archivos. En un sistema distribuido es posible replicar la infor. ‘macién de ese servidor en otro, de tal forma que se puede tener un servidor de archivos eplicado en dos nodos. En caso de que uno de los nodos falle, el otro podré seguir ofteciendo la funcionalidad de servidor de archivos. Esto es algo imposible de conseguir en un entomno centralizado. BB 7] | Oo lod de intorconenin| Ho alo ewe. dresden sien drs Material compiiado confines académicos, se prohibe su reproducién total o parca sin la autorzacén de cada autor Introduccién a fos sistemas distribuldos 191 6.2. PROTOCOLOS DE COMUNICACION Uno de los aspectos clave de todo sistema distribuido es Ia comunicacién, y para que ésta tenga lugar se necesita Ia existencia de protocolos de comunicacién. Un protocolo de comunicacién define un conjunto de reglas ¢ instrucciones que gobiernan el intercambio de mensajes entre procesos. La definicién de un protocolo incluye la especificacién de la secuencia de mensaje que deben intercambiarse los procesos y la especificacion del formato de los mensajes. Los protocolos de comunicacién suelen estructurarse como una pila de protocoles, es decir, un conjunto de protocolos apilados, cada uno de los cuales realiza tareas bien diferenciadas, entre las que se ‘encuentran el encapsulado, el control de flujo, de errores, etc. El protocolo de comunicacién més Utilizado en los sistemas distribuidos actuales es el protocolo TCP/IP. El protocolo TCP/IP, cuya arquitectura se muestra en la Figura 6.2, est formado por cuatro niveles: + Nivel de interfaz de red. Se encarga de manejar el acceso al hardware de red y es especi- fico de cada red en conereto, También ofrece funciones de nivel de enlace de datos, encar- gindose de Ia transferencia de tramas entre computadoras directamente conectadas entre si. ‘© Nivel de Internet, Este nivel, denominado también nivel 1P, se encarga de transferir los paquetes de este nivel, denominados datagramas, entre diferentes computadoras. Este nivel es similar al nivel de red del modelo OSI y oftece funciones de encaminamiento, += Nivel de transporte. Este nivel se encarga de la transmisién de mensajes entre los proce- sos. Dentro de este nivel, los usuarios pueden utilizar dos tipos de protocolos: — Protocolo UDP. Protocolo basado on datagramas de tamaiio maximo de 64 KB. Es un protocolo no orientado a conexién que no ofrece fiabilidad ni ordenacién en la entrega de los diferentes datagramas. — Protocolo TCP. Protocolo orientado a conexién que garantiza que los datos se entregan en el orden en el que se envian. Una conexién TCP constituye un flujo de bytes y asegura la entrega ordenada y fiable de los datos enviados. Las conexiones dentro del nivel de transporte se definen mediante el tipo de protocolo (ICP 0 UDP), la direecién IP de la computadora y un nimero de puerto que identifica a un proceso concreto ce tetany a ob R48 s2e| alelemet eng sin. Intertaz do red Emisor Receptor Figura 6.2 Niveles del protocolo TCPAP. Material compiiado confines académicos, se proibe su reprodvclén total o parca sin la autorzacén de cada autor, 192 Libro de précticas de sistemas operativos +» Nivel de aplicacién, Dentro de este protocolo se encuentra cualquier aplicacién que utilice el nivel de transporte, como, por ejemplo, la transferencia de archivos (fip) 0 el protocolo ‘up wiilizado en los servidores web. 6.3, COMUNICACION DE PROCESOS EN SISTEMAS DISTRIBUIDOS La comunicacién de procesos es una parte fundamental y basica en cualquier sistema distribuido. Existen dos enfoques de comunicacidn, ambos basados en el paso de mensajes: + Mecanismos de bajo nivel. En este tipo de esquemas se ofrecen servicios en los que el Programador debe encargarse de establecer los protocolos de comunicacién, la forma de representacién de los datos, etc. Ejemplos de este tipo de mecanismos son las colas de ‘mensajes de POSIX, los Mailstots de Win32 y los sockets ‘* Mecanismos de alto nivel. En este tipo de enfoques se offecen abstracciones que facilitan la programacién y en las que el programador no debe preocuparse de los aspectos de bajo nivel relacionados con el paso de mensajes. En este tipo de esquemas se incluyen las llama- das a procedimientos remotes y Ia invoeacién de métodos de remotos como la que ofrece CORBA 0 RMI de Java, En este capitulo se describirin los modelos utilizados para la realizacién de las practicas propuestas en este capitulo. Estos modelos, muy utilizados para el desarrollo de aplicaciones distribuidas, son los sockets y las Hamadas a procedimientos remotos (RPC), 6.3.1. Sockets Un socket es una abstraceién que representa un extremo en la comunicacién bidireccional entre dos procesos. Ofrece una interfaz para acceder a los servicios de red en el nivel de transporte de los protocolos TCP/IP. Actualmente, la interfaz de sockets esti siendo estandarizada dentro de POSIX y esté disponible en pricticamente todos los sistemas operativos Utilizando esta interfaz, dos procesos que desean comunicarse crean cada uno de ellos un Socket 0 extremo de comunicacién. Cada socket se encuentra asociado a una direccién y permite enviar o recibir datos a través de él En las siguientes secciones se van a describir todos los aspectos relacionados con la interftz de sockeis necesarios para el desarrollo de las précticas 6.3.1.1, Dominios de comunica Un dominio representa una familia de protocolos que se utiliza para el intercambio de datos entre sockets, Es importante destacar que sélo se pueden comunicar sackets del mismo dominio, En un sistema UNIX, los dominios més habituales son: * Dominio UNIX (PF_UNIX), que se utiliza para la comunicacién de procesos dentro de Ia misma computadora * Dominio Internet (PF_INET), que se emplea para la comunicacién de procesos que ejecu- tan en computadoras conectadas por medio de los protocolos TCP/P. Material compiiado confines académicos, se proibe su reprodvcién total o parca sin la autorzacén de cada autor Introduccién a los sistemas distribuidos 193 6.3.1.2, Tipos de sockets Existen dos tipos basicos de sockets que determinan el estilo de comunicacién empleado. Estos dos tipos son: + Sockets Stream (SOCK_STREAM). Con este tipo de sockets la comunicacién es orientada ‘8 conexién. El intercambio de datos utilizando sockets de este tipo es fiable y ademas se asegura el orden en Ia entrega de los mensajes. El canal de comunicaciones puede verse ‘como un flujo de bytes en el que no existe separacin entre los distintos mensajes. Cuando se emplea el dominio Internet, este tipo de sockets se corresponde con el protocolo de ‘transporte orientado a conexién, TCP. + Sockets de tipo datagrama (SOCK_DGRAM). Este tipo de sockeis se corresponde con una ‘comunieacién no orientada a conexién. Los mensajes en este caso se denominan datagra- mas y tienen un tamafio méximo de 64 KB. No se asegura fiabilidad, los datagramas se pueden perder y tampoco se asegura la entrega ordenada de los mismos. En este caso, si existe separacién entre cada uno de los distintos datagramas. Cuando se emplca el dominio Internet, los sockets de este tipo permiten acceder a los servicios del protocolo de transpor- te UDP. 6. Direcciones de sockets Cada socket debe tener asignada una direccién jinica. Se usan para asignar una direceién a un socket local y para especificar la direccién de un socket remoto con el que se desea comunicar. Cada dominio utiliza una direccién especifica. Existen, por tanto, dos familias de direcciones: -ecién cl nombre de un archi- ‘* AF_UNIX para sockets del dominio UNIX. Utilizan como vo Tocal, lo que representa una direccién inica. ‘+ AF_INET para socke/s del dominio Internet. Utiizan la direccién IP de una méquina y un niimero de puerto dentro de la maquina, El par (direccidn 1P, puerto) representa también una direccién tniea en Internet. La direccién genérica de un socket sc describe utilizando una estructura de tipo struct sockaddr. Cuando se trata de sockers del dominio Imernet, se usa la estructura struct sockaddr_in. Una estructura de este tipo incluye, entre otros, la direccién IP (un niimero entero de 32 bits) y un nimero de puerto (un nmero entero de 16 bits). En TCPAP, los mimeros se representan con formato big-endian, es decir, con el byte de mayor peso el primero. Una direccién IP se representa mediante una estructura de tipo struct in_addr. Aunque las direcciones IP son nimeros de 32 bits, normalmente lo que se hace es utilizar la notacién decimal-punto (por ejemplo «138.100.8.100») 0 la notacién dominio-punto (por ejemplo. ‘laurel datsi.fi.upm.esn), Existen diversas funciones que permiten obtener la direccién o direccio- nes IP asociadas a una maquina a partir de las notaciones anteriores. La mis itil es, quiza, la siguiente: struct hostent *gethostbyname(char *name); La funeién recibe el nombre de la maquina y devuelve una estructura con informacién rela- tiva a dicha miquina. Esta estructura es la siguiente: struct hostent ( char h_name; (+ nombre de 1a méquina */ Material compiido confines académicos, se proibe su reprodvcién total o parca sin la autorzacén de cada autor, 194 Libro de précticas de sistemas operatives char **h_aliases; /* lista de alias */ int h_addrtype; /* tipo de direccién */ int holength: 7+ longitud de las direcciones */ char **h_addr_list; /* lista de todas las direcciones */ hh Como se dijo anteriormente, en TCP/IP los niimeros se emplean con formato big-endian. Sin embargo, este formato no se emplea en todas los computadoras. En este caso es necesario utilizar tuna serie de rutinas que permiten traducir mimeros entre el formato que utiliza TCP/IP y el em- pleado por la propia computadora. Estas rutinas son: long hton} (u_long hostlong) ; ulsort htons(u_sort hostsort) ; ullong ntoh} (u_long netiong) ; ucshort ntohs(u_long netshort) ; La primera traduce un entero de 32 bits representado en el formato de la propia computadora al formato de red (el empleado por TCP/IP). La segunda traduce un nimero de 16 bits represen- tado en el formato de la computadora al formato de red. Las dos tltimas realizan el trabajo inverso, 6.3.1.4. Operaciones con sockets A continuacién se describen otras operaciones tipicas relacionadas con los sockets. int socket (int dominio, int tipo, int protecole); Permite crear un socket, El primer angumento especifica el dominio (PF_UNIX 0 PF_INET). El segundo indica el tipo de socket creado: socket stream (SOCK_STREAM) o socket de tipo datagra- ma (SOCK_DGRAM). EI tercer argumento permite especificar el protocalo a emplear. Por lo gene- ral, se utiliza para este argumento el valor 0, aunque en el archivo /etc/protocols de las maqui- nas UNIX se pueden encontrar diversos protocolos. La llamada socket devuelve un descriptor de archivos que se emplea en el resto de operaciones (especialmente en las de envio y recepcién de datos) de forma similar a lo ocurre con los archivos en POSIX. En caso de error se devuelve ~1. Es importante recordar que el socket creado con esta llamada no tiene asociada ninguna direccién, por lo que no se puede utilizar tal cual para la transferencia de datos. int bind(int socket, struct sockaddr *dir, int long); Permite asignar una direccién a un socket. El primer argumento es el descriptor de socket devuelto en la lamada socket. El segundo argumento especifica la direccién que se va asignar al socket. El tercer argumento especifica la longitud en bytes que ocupa la direceién. La direceién que se utiliza en el segundo argumento depende del dominio del socket creado, Si cl dominio del socket es PF_UNIX, la estructura que se emplea es del tipo struct sockadér_un, Si el dominio es PF_INET, la estructura es de tipo struct sockaddr_in, que incluird, entre otras cosas, una diteccién IP y un mimero de puerto. La Hamada devueive 0 en caso de éxito 0 =1 si hubo algin error. Ant connect (int socket, struct sockaddr *dir, int long); Llamada de solicitud de conexién. La invoca el cliente para establecer una conexién con un proceso servidor cuando se utilizan sockets de tipo stream. El primer argumento representa el Material compiiado confines académicos, se proibe su reprodvcién total o parca sin la autorzacén de cada autor Introduccién a los sistemas distribuidos 195 descriptor de socker devuelto en la Hamada socket. El segundo representa la direccién del socket del proceso servidor y que deberé haber sido rellenada con la correspondiente. El tercer argumento especifica en bytes la lon segundo argumento. La llamada devuelve 0 si se ejecuté con éxito 0 —1 en caso de error. int listen (int socket, int baklog): Esta llamada se utiliza para aceptar una nueva conexin. Se utiliza en el servidor cuando se utilizan sockets de tipo stream. El primer argumento es el descriptor de socket y el segundo repre- senta el niimero maximo de peticiones pendientes de aceptar que se encolaran. Su valor tipico y maximo en algunos casos es 5. int accept (int socket, struct sockaddr ‘dir, int *leng)? Una vez que el socket esté preparado para aceptar conexién, esta llamada permite al servidor ‘aceptar peticiones por parte de los clientes (los clientes utilizardn connect). El primer argumento representa el descriptor de socker. En el segundo se almacena la direccién del socket del proceso cliente que realiza la conexién. En el tercer argumento se almacena Ia longitud en bytes de la direceién anterior. Esta llamada bloquea al proceso servidor hasta que un cliente realice una conexién, Cuando se produce la conexién, el servidor obtiene en el segundo argumento la direccién del socker del cliente. ‘Ademés, la llamada devuelve un nuevo descriptor de socket que serd el que utilice el servidor para recibir 0 enviar datos. Nétese que después de la conexién permanecen activos dos descriptores de socket en el servidor: el original, que se utilizaré para aceptar nuevas conexiones, y el devuelto por la llamada, que se usaré para la transferencia de datos con el proceso que ha establecido la conexién. int write(int socket, char ‘mensaje, int longitu); int send(int socket, char ‘mensaje, int longitud, int flags); Permiten envier datos a través de un socket. BI primer argumento representa el descriptor de socket; el segundo, el mensaje que se quiere enviar, y el tercero, la longitud de ese mensaje en bytes, El argumento flags en la lamada send se utiliza en aspectos avanzados, que no serin cubiertos en este libro. Su valor tipico es 0. Las llamadas anteriores devuelven el nimero de bytes realmente transferidos. int read(int socket, char ‘mensaje, int longitud); dnt recv(int socket, char ‘mensaje, int longitud, int flags); Estas Hlamadas bloquean al proveso esperando la recepeién de un mensaje. La llamada de- ‘wuelve ef nimero de bytes que se han transferido 0 -1 en caso de error. En las lamadas de envio y recepcién es importante comprobar siempre el valor que devuel- ven las llamadas de envio y recepci6n de datos, ya que el valor devuelto puede no coincidir con el ‘campo longitud, que indica la cantidad de datos que se quieren transferit. En caso de que ambos valores no coincidan, deberia volverse a enviar 0 recibir los datos que aiin no se han transferido, A continuacién se presenta una funcién que se puede utilizar para enviar un bloque de datos haciendo los reintentos que sean necesarios. La funcin devuelve 0 en caso de éxito 0-1 si hubo algiin error y no se pudieron enviar todos los datos. int enviar (int socket, char ‘mensaje, int, longitud) c Material compiiado confines académicos, se proibe su reprodvcién total o parca sin la autorzacén de cada autor 196 LUbro de practicas de sistemas operatives int x; int long = longitud; ao ¢ r = write(socket, mensaje, long); long = long - zi mensaje = mensaje + r; } while ((Long > 0) && (r >= 0)); if (r <0) return (-1); /* 1a Gitima llamada fall6 */ else return (0); ) int sendto(int socket, char ‘mensaje, int long, int flags, struct sockaddr *dir, int long); Se utiliza para enviar un datagrama cuando se emplean sockets de tipo datagrama. El argu- mento dix representa la direccién del socket remoto al que se quieren enviar los datos y Long la longitud en bytes que ocupa, int recvfrom(int socket, char *mensaje, int long, int flags, struct sockaddr *dir, int *long); ‘Se emplea para recibir datos a través de un socket de tipo datagrama, En este caso, en dix se almacena la direccién del socket del que se han recibido los datos y en Long Ia longitud que ocupa cn bytes. Ant close(int socket); La llamada close se utiliza para cerrar un socker. En el caso de que el socker sea de tipo stream, la llamada cierra, ademis, la conexién en ambos sentidos. 6.3.1.5, Utilizacion de sockets de tipo stream ‘Cuando se utlizan sockets de tipo stream es necesario llevar a cabo todos los pasos que se pueden ver en la Figura 6.3 El proceso servidor de la aplicacién (véase la Figura 6.3) realiza los siguientes pasos: |. Crea un socker de tipo stream. 2. Leasigna una direcci6n utilizando bind. Cuando se utiliza un socket de dominio PF_iNE, Ja estructura que define la direceién tiene tres campos bisicos que hay que rellena ‘© Familia de direccién (sin_fami Ly). En este caso seri AP_INET. * Niimero de puerto asignado (sin_port). El rango de puertos disponibles es 0.65535, cstando reservados los 1.024 primeros para el sistema. ‘+ Estructura que contiene, entre otras cosas, la direccién 1P de una méquina (struct in_addr sin_adar). 3. Se prepara para iecibir conexiones utilizando 1isten. 4, Se bloquea esperando la recepcién de conexiones por parte de los clientes utilizando te Mlamada accept. Cuando se desbloquea, la llamada anterior devuelve un nuevo descrip- tor de socker que serd el que se utilice en Ia transferencia “Material compiiado confines académicos, se proibe su reprodvclén total o parca sin la autorzacén de cada autor Introduccién a los sistemas distribuidos 197 Proceso servidor Sh pda ea ‘socket Proceso cliente ‘Abrie conextén |. 07 [connect Peticion write) q read) |e q closed) Respuesta | Figura 63. Escenario tipico con «sockeis» de tipo «stream». EI proceso recibe un mensaje del proceso cliente. Para ello se utiliza la llamada read. El proceso servidor ejecuta el trabajo necesario, en este caso realiza la suma Devuelve el resultado al cliente utilizando write. Gierra el descriptor de socket devuelto en fa llamada accept, ya que éste no volver @ utilizarse. Al mismo tiempo se cierra la conexién con el cliente. 9. Vuelve al paso 4 para esperar nuevas peticiones. Los pasos que debe realizar ¢l cliente (v se Ia Figura 6.3) son més sencillos. El cliente debe: Crear un socket de tipo stream. Establecer una conexién con el proceso servidor utilizando connect. Enviar los nimeros que se quieren sumar utilizando la llamada write. Esperar el resultado utilizando read. Cerrar la conexién con close. El cliente obtiene la direccién IP del servidor utilizando la funcién gethostbyname. Esta funcién devuelve informacién sobre el servidor. Para rellenar la direccién de! servidor basta con acceder a los campos correspondientes de la estructura devuelta por la funcién anterior. hp = gethostbyname (*laurel .datsi.fi-upm.es"); memepy (&(sorver_addr.sin_addr), hp->h_addr, hp->h_length) Material compiado confines académicos, se proibe su reprodvcién total o parca sin la autorzacén de cada autor, 198 Libro de practicas de sistemas operativos 6.3.2. Llamadas a procedimientos remotos Las llamadas a procedimientos remotos (RPC, Remote Procedure Call) representan un hibrido entre las lamadas a procedimientos y el paso de mensajes. Las RPC constituyen el niicleo de muchos sistemas distribuidos y Hegaron a su culminacién con DCE (Distributed Computing En- vironment). Actualmente han evolucionado hacia la invocacién de métodos remotos como los utilizados en CORBA y RMI de Java. En una llamada a procedimiento remoto, el programador no necesita preocuparse de cémo se realiza la comunicacién entre procesos. Simplemente realiza llamadas a procedimientos que serin ejecutados en computadoras remotas. En este sentido, el programador desarrolla sus aplicaciones de forma convencional descomponiendo su software en una serie de procedimientos bien defini- dos. En una RPC, el proceso que realiza la llamada empaqueta los argumentos en un mensaje, se Jos envia a otro proceso y espera cl resultado. Por su parte, el proceso que ejecuta el procedimien- to extrae los argumentos del mensaje, realiza la llamada de forma local, obticne cl resultado y se lo envia de vuelta al proceso que realizé la llamada. Este proceso, totalmente transparente al usuario que utiliza las RPC, es realizado por unos médulos denominados resguardos, suplentes © stubs. Este funcionamiento se puede apreciar en la Figura 6.4 ‘A continuacién se describen los pasos que se presentan en la figura anterior. ‘+ El cédigo de la aplicacién hace una llamada a procedimiento. Por ejemplo, puede invocar ‘sumar (5,2). En una llamada a procedimiento remoto, al igual que en tina llamada @ procedimiento convencional, la lamada anterior supone la creacién en la pila del proceso del registro de activacién correspondiente. Este registro incluye, entre otras cosas, los pa- rimetros del procedimiento (5 y 2 en este caso) y la dircecién de retorno, + El procedimiento invocado anteriormente, que forma parte del cédigo del propio proceso, se encuentra en un médulo del programa cliente que se denomina resguardo y que como se (CODIGO DE LA APLICACION PROCEDIMENTOS INICIO ai °o mento) AMADA? coe ‘ PROGEDMIENTO eo | ie ‘EMOTO. paaane CONVIERTE, RESGUARDOgEE ENTRADA ENTRADA ‘CLIENTE PREPARA ‘SALIDA, Figura 6.4, Llamadas y mensajes en una RPC. Material compiiado confines académicos, se proibe su reproducién total o parcial sin la autorzacin de cada autor, Introduccién a los sistemas distribuides 199 vera mas adelante se obtiene de forma automética. Este procedimiento extrae de la pila los argumentos, pero no realiza la operacién; en este caso, la suma de los dos niimeros pasados en la pila. Lo que hace es enviar los argumentos al proceso servidor para que sea éste el que realiza la llamada, Para ello: — Localiza al servidor que ejecuta el procedimiento remoto. Mis adelante se vera cémo se realiza este proceso. — Construye un mensaje y empaqueta los parimetros en él. Asimismo, indica en el men- saje cl procedimiento que debe realizar el servidor. — Envia el mensaje al proceso servidor y espera un mensaje de él con la respuesta. + BI proceso servidor, que se encuentra en un bucle esperando la legada de peticiones por parte de los clientes: — Extrae del mensaje los argumentos y la funcién que debe invocar. — Una vez extraidos, invoca a una funcién del propio cédigo del servidor para realizar la Hamada y obtiene el resultado, — Una vez tomado el resultado, construye un nuevo mensaje en el que introduce el resul- tado y se lo envia al proceso cliente. ‘= El proceso cliente que se encuentra bloqueado esperando la respuesta del servidor extrac del mensaje el resultado y simplemente lo retorna, Con los pasos anteriores, todos los aspectos relacionados con el paso de mensajes quedan ‘ocultos al programador, siendo el sofware del paquete de RPC utilizado el encargado de realizarlo. Un aspecto muy importante de las lamadas a procedimientos remotos es el lenguaje de definicién de interfaces (IDL), que permite especificar las interfaces de los procedimientos a gjecutar en el servidor. A partir de un programa escrito utilizando un lenguaje de definicién de interfaces, el compilador de interfaces sc encarga de obtener los suplentes del cliente y del servidor. En la siguiente seccién se muestra un ejemplo de uso de un paquete de RPC que seré utilizado en las pricticas que se describen al final del capitulo. 6.3.3. Introduccién a las RPC de SUN La utitizaci6n de RPC permite a los programadores el desarrollo de aplicaciones distribuidas que utilizan e! modelo cliente-servidor. EI modelo de RPC desarrollado por Sun Microsystems es uno de los més extendidos y se disefié inicialmente para el desarrollo del sistema de archivos en red NFS (Network File System). Las RPC de Sun constan de unos formatos de datos descritos utilizando el formato de repre- sentacién de datos XDR (eXternal Data Representation) desarrollado también por Sun. Este for- mato describe un lenguaje de descripcién de datos y estandariza una sintaxis de transferencia, Dentro del lenguaje de descripcién de datos, XDR dispone de una serie de tipos elementales (int, bool, string, etc.) y una serie de constructores para declarar tipos de datos més complejos (vectores, estructuras, uniones). Casi todos estos tipos y constructores tienen su equivalente en los. enguajes de programacién mas habituales. En estas RPC se utiliza el término programa para hacer referencia a un servicio. Un programa cconsta de una serie de procedimientos que pueden ser utilizados por los clientes. Cada programa puede tener varias versiones. Los programas, versiones y procedimientos se idemtifican mediante riimeros enteros, De acuerdo a esto, cada procedimiento queda perfectamente identificado por la terna . "Material compiido confines académicos, se prohibe su reprodvcién total o parca sin la autorzacén de cada autor, 200 Libro de practicas de sistemas operatives La especiticacién de una aplicacién consiste en la definicién de un conjunto de procedimien tos dentro de un programa. De manera mas formal, la definicién de un protocolo de aplicacié debe seguir la siguiente sintaxis: prograna-def: “program” identifier "(+ version-def version-def * "yt ce contant version-def: ‘version identifier procedure-det procedure-def * ") "=" constant *;" 6.3.3.1. Principales tipos de datos en XDR En esta seccién se van a describir algunos de los tipos de datos definides en XDR. Enteros con signo: Dectaracién: int a, Equivaiente en C: int a Enteros sin signo: Declaracién: unsigned a; Equivalente en C: unsigned a; Valores légicos: Declaracién: bool a; Equivalente en C: enum bool_t (TRUE = 1, PALSE=0); typedef enum bool_t bool_t; bool_t a; Niimeros en coma flotante: Declaracién: float a; Equivatente en C: float ¢: Cadenas de bytes de longitud fija Declaracién: ‘opaque a(20); Equivatente en C: char 2(20]; Cadenas de bytes de longitud variable: Declaracién: ‘opaque a<37: opaque be>; Equivatente en C: struct ( int a_len; char *a_val; Material compiiado confines académicos, se proibe su reproduclén total o parca sin la autorzacin de cada autor, Introduccién a los sistemas disiribuidos 201 Cadenas de caracteres: Declaracién: string a<37>; string be; Equivalente en C: Veetores de tamaiio fijo: Declaracién: int (12); Equivalente en C: int a(12); ‘Veetores de tamaiio variabi Declaracién: int a; Float be>; Equivalente en C: struct ( int yar struct ( int bien; float *b_val; db; struct t ( int el; string ¢2<20>; h Equivalente en C: struct © ( int el; string *c2; ds typedef struct t ty car Constantes: Declaracién: const MAK = 1: Equivalente en C: define Max 12 6.3.3.2. Programa rpegen El programa xpegen genera a partir de un archivo con la especificacién de una aplicacién (por defecto, el archivo tiene extensién .») los siguientes archivos: 1, Archivo de cabecera con estructuras de datos en C equivalentes a las definidas en el archivo de especificacién, Este archivo deberd incluirse en el cédigo del cliente y el cédigo del servidor. 2. Archivo con funciones de transform: definido. mn de datos XDR, una por cada tipo de datos "Material compiiado confines académicos, se prohibe su reprodvclén total o parca sin la autorzacén de cada autor 202 Libro de practicas de sistemas operatives 3. Archivo con el suplente del cliente. 4. Archivo con el suplente del servidor. Tradicionalmente, una llamada a procedimiento remoto acepta un ‘inico parémetro y devuel- ve un tinico resultado. Para poder pasar diferentes valores a una llamada a procedimienio remoto ‘es necesario agrupar éstos en una estructura y pasar esta estructura como parametro. Si se quieren recoger varios valores de vuelta, también es necesario agrupar éstos en una estructura y hacer que cl procedimiento devuelva una estructura. También es posible pasar miltiples pardmetros en las RPC, pero para ello debe utilizarse la opcién -N con el programa rpegen. 63.33, Servidores Los servidores deben implementar cada una de las funciones especificadas en el archivo de def nicin de interfaces. Estas funciones, en el caso de utilizar miltiples pardmetros, tienen la si ‘guiente forma: tipo_resultado *procedimiento_v_sve(tipo_argumento? argl tipo_argumento? arg2 , struct svc_req *rqstp); Al nombre del procedimiento se le afiade cl niimero de versién y el sufijo «sven. 6.3.3.4. Clientes El cliente, para poder ejecutar un procedimiento remoto, debe en primer lugar establecer una conexién con un servidor mediante el siguiente servicio: CLIENT *cint_create(char *host, u_long prognum, u_long versnum, char *nettype); EL primer argumento (host) especifica ef nombre de 1a miquina donde ejecuta el servidor. Los dos siguientes argumentos especifican el mimero de programa y numero de version del pro- cedimiento remoto a ejecutar. El ultimo argumento especifica el protocolo (udp 0 tcp). El prototipo que debe emplear el cliente para las llamadas a procedimientos remotos es: tipo_resultado *procedimiento_v(tipo_argumentol argi, tipo_argumento2 arg2, ..., CLIENT *cl); donde el sufijo V representa el mimero de versién, 6.3.3.5. Ejemplo Si se desea realizar un servidor que exporte dos procedimientos remotos, sumar y restar, la inter- faz que debe incluirse en un archivo .x, por ejemplo, calcular. x, debe ser: program calcular ( version UNO { int sumar(int a, int b) = 1 int restar(int a, int b) we ) = 9999999 "Material compiiado confines académicos, se prohibe su reproducién total o parca sin la autrzacén de cada autor, Introduccion a los sistemas distribuides 203 ‘Una vez definida Ia interfaz, ésta se procesa de la siguiente forma: rpegen -N calcular.x ites archivos: E] programa xpegen generara de forma automatica los sigi * calcular.h, archivo de cabecera a incluir en el cliente y en el servidor. * calcular_svc.c, resguardo 0 suplente del servidor. * calcular_elnt.c, resguardo 0 suplente del cliente. * calcular_xdr.c, programa con funciones para la transformacién de tipos. El programador, a continuacién, tiene que codificar el programa cliente y el programa servi- dot. El programa servidor debe incluir la implementacién de las funciones sumar y restar. include int * sumar_i_sve(int a, int b, struct sve_rea *rastp) a static int x; return(ér) ; int * restar_i_eve(int a, int b, struct sve_req *rastp) static int r; return(ér) : ) Debido a que las funciones anteriores devuelven un puntero (una direceién de memoria), las les que almacenan el resultado deben ser de tipo static (static int r). El cédigo del cliente tendré, entre otras cosas, las siguientes: vari #include void main (int arge, char **argv) « host = argv(1); ev = clnt_create(host, CALCULAR, UNO, “*tep"): if (sv == NULL) ( clnt_pcreateerror (host) ; exit (0); > res = sumar_i(5, 2, sv); Material compiiado confines académicos, se prohibe su reprodvclén total o parca sin la autorzacin 6e cada autor, 204 6.4. Libro de précticas de sistemas operativos if (res == NULL) ( clnt_perror (svi, ‘call failed"); exit (0): d print£(*S + 2 = $d\n", *res); clnt_destroy (sv) ; exit (0); ) El programa cliente recibe el nombre de la maquina donde ejecuta el servidor en la linea de angumentos y 1a olmacena en la variable host. Para obtener los archivos ejecutables cliente y servi dor respectivamente, debe compilar- se de la siguiente forma ace -¢ calcular_sve.c gee -c calcular_xdr-c gee -¢ cliente.c gee -c servidér.c gee -o calcular_cnlt.o calcular_xdr.o cliente.o -o cliente gee -o calcular_svc.o calcular_xdr.o servidor 0 -o servidor Los dos tiltimos mandatos permiten obtener los ejecutables del cliente (denominado clien- te) y del servidor (denominado servidor), PRACTICA: PARAMETROS DE CONFIGURACION Y MONITORIZACION DE CONEXIONES DE RED EN WINDOWS 2000 6.4.1. Objetivos de la practica EI objetivo de la préctica es familiarizar al alumno con algunas herramientas, disponibles en computadoras con Windows 2000, que permiten obtener los parémetros de configuracién de los protocolos TCP/IP, asi como la posibilidad de monitorizar ciertos aspectos relacionados con el protocolo TCP/P. NIVEL: Introduccién. HORAS ESTIMADAS: 4, 6.4.1.1, Uso del mandato IPCONFIG EI mandato IPCONFIG se puede utilizar desde Ia linea de mandatos para mostrar la configuracién de los protocolos TCP/IP de una computadora con sistema operativo Windows 2000. Esta infor- macién también se puede obtener utilizando la opcién Conexiones de red y acceso telefénico; embargo, este mandato es més ripido y sencillo. Una forma de obtener toda la informacién de configuracién de su computadora es ejecutar el siguiente mandato: ipconfig /all Material compiiado confines académicos, se prohibe su reprodvcién total o parca sin la autorzacén de cada autor, Introduceién a los sistemas distrbuidos 205 Utilice este mandato para obtener Ia siguiente informacién de su computadora: Nombre de su computadora (host) Direecién IP. Direccién fisica de su interfaz de red. ‘Méscara de Ia subred. Servidores de DNS (Domain Name Service) a direeciones IP. jzados para traducir los nombres légicos 6.4.1.2. Uso del monitor de rendimiento de Windows En este apartado de Ia préctica se propone el empleo del monitor de rendimicnto para comprobar ciertos parimetros del uso de los protocolos TCPAP de su sistema. Para ejecutar el moniter de rendimiento siga los siguientes pasos: 1, Seleccione el botén Inicio | Programas | Herramientas administrativas. 2. Pulse dentro del meni anterior la opcién Monitor de sistem: ‘A continuacién aparecerd una ventana como la que se muestra en la Figura 6.5. EI monitor de rendimiento permite monitorizar ciertos parametros relacionados con el rendi- miento del sistema; en conereto, se pueden monitorizar pardmetros relacionados con los protoco- los IP, TCP y UDP. Para monitorizar uno o varios pardmetros basta con pulsar el icono Agregar contador (add counter) de la pantalla inicial que se muestra en la Figura 6.6 y clegir los pariime- ‘ros que se quieren visualizar. Por ejemplo, se pueden monitorizar los siguientes parémetros: ‘= Datagramas IP enviados por segundo. ‘= Datagramas IP recibidos por segundo ‘© Datagramas UDP recibidos por segundo. ‘* Niimero de conexiones TCP activas. Figura 6.5. Ventana inicial del monitor de rendimiento de Windows. Material compiiado confines académicos, se prohibe su reproducién total o parcial sin la autorzacin de cada autor, 206 Libro de précticas de sistemas operatives {Liem foie Je + or, Pel) eI FO 5] Figura 6.6. Agregar un nuevo contador. El trabajo a desarrollar por el alumno consistiré en: 1. Describir todos 1os pardmetros relacionados con los protocolos IP, TCP y UDP que se pueden monitorizar en su sistema. 2. Para los parimetros anteriores se debe indicar el ntimero medio, maximo y minimo que se obtiene durante un periodo de monitorizacién de diez minutos. 6.4.2, Recomendaciones generales Antes de empezar con la monitorizacién se recomienda que el alumno se familiarice con el moni- tor de rendimiento del sistema. Para ello puede consultarse la ayuda en linea que offece dicho ‘monitor. 6. Entrega de documentacién Se recomienda que el alumno entregue el siguiente archivo: ‘* Memoria.doc: Memoria de la prictica. Bibliografia * K. Siyan. Microsoft Windows 2000 TCP/P. Premice-Hall, mayo 2000. su reprodccln total o parcial sn ta autoizaiin de cada aut, Material compiiado confines académicos, se profi Introduccion a los sistemas distribuidos 207 65. PRACTICA: USO DEL MANDATO rpcinfo EN LINUX 6.5.1. Objetivos de la prac El objetivo de la prictica es que el alumno conozca el uso del mandato rpcinfo de UNIX/Linux. Este mandato permite conocer los servidores que emplean las RPC de Sun descritas al comienzo del capitulo que se encuentran arrancados en una determinada computadora, NIVEL: Introduccién. HORAS ESTIMADAS: 2. 6.5.2. Descripeién de la funcionalidad que debe desarrollar el alumno Para conocer los servicios arrancados en una determinada computadora debe ejecutarse el si- ‘guiente mandato: xpcinfo -p nombre_conputadora Este mandato muestra por pantalla una serie de servicios. Para cada servicio se muestra el rimero de programa, 1a versién, el protocolo utilizado (TCP 0 UDP), el niimero de puerto del servidor y el nombre del servici El trabajo a desarrollar por el los servicios arrancados en determinadas maq. tird en la ejecucién de este mandato para conocer s de su laboratorio. 6.5.3. Entrega de documentacién ‘Se recomienda que el alumno entregue el siguiente archivo: © Memoria. txt: Memoria de la prictica 6.5.4. Bibliografia © R. Stevens, UNL Network Programming. Prentice-Hall, 1996. 66. PRACTICA: SERVICIO DE ARCHIVOS REMOTOS UTILIZANDO SOCKETS 6.6.1. Objetivos de la practica Un sistema de archivos distribuido se encarga de la integracién transparente de los archivos de tun sistema distribuido, permitiendo compartir datos a los usuarios del mismo. En un sistema de archivos distribuido, cada archivo se almacena en un tinico servidor. El objetivo de esta prictica es. doble; por una parte, se pretende que los alunos se familiaricen con los servicios disponibles en sistemas UNIX/Linux para trabajar con sockets. Estos servicios permiten construir aplicaciones. distribuidas utilizando el nivel de transporte de los protocolos TCP/IP. El segundo gran objetivo Material compiado confines académicos, se profi su reprodccln total o parcial sn ta autoizaion de cada aut, 208 Libro de pricticas de sistemas operatives de la prictica es que los alumnos entiendan y analicen todos los aspectos relacionados con el disefio ¢ implementacién de un pequefio servicio de archivos distribuido. NIVEL: Avanzado. HORAS ESTIMADAS: 16. 6. . Descripcién de la funcionalidad que debe desarrollar el alumno Un servicio de archivos se encarga de proporcionar a los clientes acceso a los datos de los archi- vos almacenados en un servidor. Para el diseiio © implementacién del servicio de archivos se utilizaré un modelo de acceso basado en servicios remotos. En un modelo de acceso badado en servicios remotos, el servidor offece todos los servicios relacionados con el acceso a los archi- vos. Todas las operaciones de acceso a los archivos se resuelven mediante peticiones a los serv dores siguiendo un modelo cliente-servidor. Este servicio a desarrollar estara compuesto 1, Un servidor que implementa el servicio. 2. Una interfaz de bajo nivel que utilizarén los clientes para acceder al servicio. La interfaz que debe implementar ef alumno es la siguiente: FD *FD_creat(char ‘maquina, int puerto, char ‘nombre, int modo); Esta funcién crea un archivo con nombre nombre en la maquina basada en el primer argu- mento. El segundo argumento (puerto) indica el puerto en el que se encuentra el servidor que jplementa el servicio. La llamada devuelve un puntero a un descriptor de archivo de tipo #D. Este descriptor se describiré mas adelante. El argumento modo tiene el mismo significado que en la llamada creat de POSIX. En caso de error, la llamada devuelve NULL. El archivo que se crea queda abierto para escritura (igual que la llamada creat en POSIX). FD *FD_open(char *maquina, int puerto, char ‘nombre, int flags); La funcién abre un archivo cuyo nombre se pasa como parimetro. El archivo reside en la ‘maquina con nombre maquina. El segundo argumento (puerto) indica el puerto en el que se encuentra el servidor que implementa el servicio. La llamada devuelve un puntero a un descriptor de archivo de tipo Fp. Este descriptor se describira més adelante. El argumento flags tiene el mismo significado que en la llamada open de POSIX e indica si el archivo se abre para lectura, ra 0 lectura-escritura, En caso de error, la llamada devuelve NULL. Ant FD_clos (PD *£a); La funcién cierra un archivo previamente abierto, cuyo descriptor es £4. La llamada devuelve 0 en caso de éxito y =I en caso de error. Ant FD_read(rD *f4, char *buf, int long); Esta funcién es similar a la llamada read de POSIX y sus argumentos tienen el mismo signifi ccado. En este caso, se leen datos del archivo previamente abierto cuyo descriptor es £4 de tipo FD. Material compiiado confines académicos, se probe su reprodvclén total o parca sin la autorzacin de cada autor Introducetén a los sistemas distribuidos 209 int Fp_write(FD *€a, char *buf, int long): Esta funcién es similar a la llamada write de POSIX y sus argumentos tienen el mismo significado. En este caso, se escriben datos en el archivo previamente abierto cuyo descriptor es Ed de tipo FD, Ant FD_get_size(rD *£a); Esta funcién devuelve el tamafio del archivo correspondiente al descriptor £a. La llamada devuelve 0 en caso de éxito y -1 en caso de error. FD ‘*Fp_unlink(char ‘maquina, int puerto, char ‘*nombre); La funcién borra un archivo de una maquina. Los argumentos son similares a los de las Mamadas FD_creat y FD_open. El tipo FD se utiliza como descriptor de archivos en este servicio y permite identificar a un archivo en nuestro sistema distribuido. Existen varias posibilidades para definir este tipo, segtin el esquema de comunicacién que se utilice. El alumno puede elegir el que més le convenga. Dos posibles enfoques son: 1. Mantener la conexién abierta durante toda la sesion (desde que se abre 0 se crea el archivo hasta que se cierra). En este caso, si el servidor no es concurrente, no se podri atender a varios clientes a no ser que s¢ utilice la !lamada select. En este caso, el descriptor de archivo debe contener el socket de Ia conexién. Un posible ejemplo seria el siguiente: typedef struct descriptor( int socket; int f@; /* descriptor de archivo remoto */ ) FD; 2. Crear una nueva conexién por cada operacién que se realice. En este caso, cada operacién necesita conocet Ia maquina y el puerto del servidor que atiende la peticion. Estos datos deberdn ir incluidos en el descriptor de archivo. La ventaja de esta solucién frente a la anterior es que el servidor puede atender a varios clientes sin necesidad de utilizar la lama- da select. Su desventaja es la sobrecarga de cada operacién por la necesidad de estable- cer una conexién con el servidor en cada operacién. Un posible ejemplo seria el siguiente: typedef struct descriptor( struct sockaddr_in sock: int fa; /* descriptor de archivo remoto */ FD; Se valorard positivamente la implementacién de un servidor multithread. 6.6.3. Ejemplo de aplicacién cliente El alumno deberd realizar, utilizando el servicio de archivos de bajo nivel diset tado anteriormente, una aplicaci6n que permita transferir archivos entre un proceso cliente y otro servidor. El proceso cliente tendré un bucle que aceptaré las siguientes érdenes: Material compiiado confines académicos, se probe su reprodvclén total o parca sin la autorzacin de cada autor 210 Libro de practicas de sistemas operativos ‘get host archive_renoto archive_local. Permite transferir desde un host donde ejecuta el servidor un archivo remoto a un archivo local en la maquina cliente, * put archivo_local host archive_remoto. Transfiere un archivo a la méquina remoto. Para facilitar la implementacién, los nombres de archivo se indicarén con camino absoluto (por ejemplo: /export /home /pepe/archivo. txt). El cliente finalizard su ejecucién al te- clear Cont roi (fin de archivo en UNIX), 6.6.4. Recomendaciones generales Es importante estudiar el funcionamiento de los servicios que ofrece el estindar POSIX para trabs- Jar con archivos (open, creat, close, read y write). Para ello puede consultarse el Apéndice A. 6.6.5. Entrega de documentacién La documentacién a entregar sera la siguiente: ‘+ momoria.txt: Memoria de la prictica, que incluiré el diseio del servidor de archivos, el disefio de la aplicacién de transferencia de archivos y todos aquellos aspectos que se con- sideren de interés. * servicio.hy servicio. c: Cédigo fuente con la implementacién del servicio de archi- vvos que puede utilizar un cliente ‘+ cliente.c: Cédigo fuente en C con el programs cliente que realiza la transferencia de archivos. Este médulo utilizar las funciones implementadas en el médulo anterior. * servidor.c: Cédigo fuente en C con el programa servidor que implementa el servicio de archivos 6.6.6. Bibliografia * J. Carretero, F. Garcia, P. de Miguel y F. Pérez. Sistemas operativos: una visién aplicada McGraw-Hill, 2001. + W. Richard Stevens. Unix Network Programming, vol. 2: Interprocess Communications 28 edicién, Prentice-Hall, 1999. + K. A. Robbins y S. Robbins. UNIX Programacién Préctiea. Prentice-Hall, 1997. + F. Garcia, J. Carretero, J. Feméndez y A. Calderén, El lenguaje de programacidn C: diseko ¢ implementacién de programas. Prentice-Hall, 2002. 6.7. PRACTICA, SISTEMA DE ARCHIVOS REMOTO UTILIZANDO RPC 6.7.1. Objetivos 1 objetivo de esta practica es que el alumno aprecie la facilidad que supone el uso de RPC para €l desarrollo de aplicaciones y servicios distribuidos. Para ello se propone la realizacién de la Material compiiado confines académicos, se profi su reproduccln total o parcial sin ta autoizacion de cada auto, Introduccién a fos sistemas distribuidos 211 préctica anterior, pero utilizando en este caso llamadas a procedimientos remotos, en concreto las RPC de Sun disponibles en cualquier sistema UNIX, NIVEL: Avanzado. HORAS ESTIMADAS: 8. 6.7.2. Descripcién de la funcionalidad que debe desarrollar el alumno El alumno debe desarrollar la interfaz del servicio de archivos propuesto en la préctica descrita en la Seccidn 6.6. A continuacién se recuetda esta interfaz: FD *FD_creat(char ‘maquina, int puerto, char ‘nombre, int modo) FD *FD_open(char *maguina, int puerto, char ‘nombre, int flags) Ant FD_close(FD *£4) int FD_read(FD *fa, char *buf, int long) dnt FD_write(FD *f4, char *buf, int long) int FD_get_size(FD *f4) FD *FD_uniink(char *maquina, int puerto, char ‘*nombre) 6. 3. Ejemplo de aplicacién cliente El alumno deberd realizar, utilizando el servicio de archivos disefiado e implementado anterior- ‘mente, una aplicacién que permita transferir archivos entre un proceso cliente y otro servidor. El proceso cliente tendré un bucle que aceplaré las siguientes érdenes: * get host archivo_remote archive_local. Permite transferir desde un host donde ¢jecuta el servidor un archivo remoto a un archivo local en la maquina cliente. * put archive_local host archivo_remoto. Transfiere un archivo a la maquina remoto. Para facilitar fa implementacién, los nombres de archivo se indicarin con camino absoluto (por ejemplo: /export /home /pepe/archivo.txt). El cliente finalizaré su ejecucién al te- clear Contro1-p (fin de archivo en UNIX). 6.7.4. Recomendaciones generales Es importante estudiar el ejemplo de RPC descrito al comienzo del capitulo. Para que no haya problemas con versiones de diferentes grupos de practicas se utilizaré como numero de programa el niimero de matricula que identifica a uno de los alumnos. 6.7.5. Entrega de documentacién Se recomienda que el alumno entregue los siguientes archivos: ‘© memoria. txt: Memoria de la prictica (véase Normas de presentacién generales). * s£.x: Archivo con la especificacién de la interfaz, Material compiado confines académicos, se proibe su reproducién total o parcial sin la autorzacin de cada autor, 212 Libro de pricticas de sistemas operatives ‘+ s£.c: Cédigo fuente en C con Ja implementacién del servicio. * cliente.c: Cédigo fuente en C con el programa cliente, que se encarga de'la transferencia. Bibliografia J. Carretero, F, Garcia, P, de Miguel y F. Pérez. Sistemas operativos: una visién aplicada. McGraw-Hill 2001 ‘+ W. Richard Stevens. Unix Network Programming, vol. 2: Interprocess Communications. 2+ edicién. Prentice-Hall, 1999. K. A. Robbins y S. Robbins. UNIX programacién prictica. Prentice-Hall, 1997. F. Garcia, J. Carretero, J. Fernindez y A. Calderén. El lenguaje de programacién C: diseto ¢ implementacién de programas. Prentice-Hall, 2002. 6.8. PRACTICA: SERVICIO DE BLOQUES PARALELO. CON TOLERANCIA A FALLOS RAIDS 6.8.1. Objetivos de la préctica El sistema de archivos es uno de los componentes fundamentales de cualquier sistema distribuido y es uno de los que mayor fiabilided requiere. Habitualmente, la fiabilidad en los sistemas de archivos distribuidos se consigue mediante la replicacién de archivos, es decir, la copia de los archivos en diferentes servidores, de forma que si uno de los servidores es inaccesible, siempre quedarin otros que sigan ofteciendo el servicio y, por tanto, el acceso a los datos. En esta préctica se propone un enfoque completamente distinto para conseguir fiabilidad y tolerancia a fallos. Pare ello se propone construir un servicio de bloques paralelo soportado por diferentes servidores. La fiabilidad se conseguiré aplicando el concepto de disco RAID (Redundant Array of Inexpensive Disks) a estos servidores, El desarrollo de esta préctica permitiré al alumno: 1, Comprender el funcionamiento de un servicio de bloques paralelo y cémo se pueden agregar varios servidores de bloques para construir un servicio de bloques de mayor capacidad. 2. Comprender el funcionamiento de un dispositivo RAIDS y cémo este tipo de concept se puede aplicar también a los servidores. NIVEL: Disefo. HORAS ESTIMADAS: 16, La técnica habitual para ofrecer fiabilidad y tolerancia a fallos en los dispositivos de almacens- miento consiste en utilizar dispositives RAID (Redundant Array of Inexpensive Disks). Estos dispositivos estén formados por un conjunto de discos que almacenan la informacién y otto con- junto que almacena informacién de paridad del conjunto anterior. Desde el punto de vista fisio, se ve como un tnico dispositivo, ya que existe un tnico controlador para todos los discos. Ese controlador se encarga de reconfigurar y dstribuir los datos entre los discos de forma transparenie su reprodccln total o parcial sin ta autoizacion de cada aut, Material compiado confines académicos, se profi Introduccién a los sistemas distribuidos 213 al sistema de E/S. Se han descrito diferentes niveles de discos RAID. Uno de los mis utilizados habitualmente es el denominado RAIDS. Un dispositive RAIDS (véase Ia Figura 6.7) reparte los bloques y Ia paridad por todos los discos de forma ciclica. La paridad se calcula por el hardware en el controlador haciendo el XOR de los bloques de datos de cada franja. Asi, por ejemplo, 1a paridad correspondientes a los bloques 0, 1 y 2 del RAID se almacena en el bloque fisico 0 de! disco 3. ‘A continuacién se describen diferentes escenarios de funcionamiento en el acceso a un blo- que del RAIDS. * Lectura de un blogue de un disco sin fallo. Si se desea leer, por ejemplo, el bloque 2 basta con calcular el disco y el bloque correspondiente a est disco. El bloque 2 en el RAIDS de la Figura 6.7 se corresponde con el bloque 0 del disco 2. Si este disco esté funcionando correctamente, se lee el bloque y se devuelve. «Lectura de un bloque de un disco con fallo. Si se desea leer un bloque, por ejemplo, el bloque 2, de un disco con fallo, el controlador necesita reconstrur la informacién de ese bloque a partir de los otros bloques de su franja. Para ello deberd leer el bloque 0, el | y el bloque de paridad. El bloque 2 se obtiene calculando la paridad de estos tres’ bloques: Bloque 2 = bloque 0 @ bloque | @ bloque de paridad (donde ® define la operacién XOR). + Escritura de wn bloque en un RAIDS sin fatto, Para escribit un bloque, por ejemplo, cl 2, ¢5 necesario actualizar el bloque de paridad. Para ello se lee el bloque 2, el bloque de paridad y se calcula la paridad como: nueva paridad = (bloque 2 antiguo ® paridad antigua) © bbloque 2 nuevo. Una vez calculada la paridad, se escribe el bloque 2 y el nuevo bloque de paridad. + Excritura de un blogue en un RAIDS con fallo en el blogue de paridad. En este caso basta con escribir el bloque en el disco correspondiente. Puesto que el disco de paridad no fun- ciona, no se puede escribir en él + Escritura de un bloque en un RAIDS con fallo en el disco en el que se almacena el bloque. En este caso no se puede escribir en dicho disco; sin embargo, se necesita actualizar el Controlador Figura 6.7. Distribucién de bloques en un dispositivo RAIDS. Material compiiado confines académicos, se profi su reprodccln total o parcial sin ta autoizaiin de cada aut, : 214 Libro de précticas de sistemas operatives bloque de paridad para que la informacién se pueda recuperar posteriormente, Para ello se lee el bloque 0 y el 1 y se calcula la nueva paridad como: nueva paridad = bloque 0 © Dloque 1 ® nuevo bloque 2. A continuacién se escribe e! bloque de paridad. Observe que con el funcionamiento descrito anteriormente siempre se podri acceder, tanto para leetura como para escritura, a los datos siempre y cuando no fallen mas de un disco. ‘Una cuestién a tener en cuenta cuando se realizan escrituras concurrentes sobre un RAID 40 ‘un RAIDS es que las mismas tienen que hacerse en exclusiOn mutua, es decir, dos escrituras no pueden realizarse de forma concurrente sobre Ia misma franja de paridad debido a que podrian dejar el RAID en un estado inconsistente. Considere el siguiente escenario: dos procesos que intentan escribir en la misma franja de paridad (véase la Figura 6.7), el proceso A quiere escribir en el blogue 1 y el proceso B en el bloque 2, y acceden de la siguiente forma: Proceso A Proceso B 1 read(bloque!) 2° read{blogue2) 3 read{paridad) 4° read(paridad) 5 calculo nueva paridad 5 _caleulo nueva paridad 7 write(auevo bloquel) 6 —write(nuevo bloque2) 8 write(aueva paridad) 9 write(nueva paridad) En el ejemplo anterior, el bloque de paridad que queda escrito en el RAID es el bloque de paridad que calcula el proceso B. Este nuevo bloque de paridad no tiene en cuenta al bloque | escrito por el proceso A; por tanto, Ia franja de paridad correspondiente a los bloques 1, 2 y 3 queda en un estado inconsistente. Para solucionar este problema es necesario disponer de un rmecanismo de cerrojos que permita bloquear la franjas cuando se va a realizar una operacién de eseritura. El objetivo es impedir que dos procesos escriban de forma concurrente sobre una misma franja. Aunque este problema habria que resolverlo en un sistema real en la prictica a desarrollat no se contemplara el uso de este servicio de cerrojos. 6.8.3. Descripcién de la funcionalidad que debe desarrollar el alumno EL alumno parte de un servidor de bloques ya implementado (se proporciona el ejecutable al alumno) con la siguiente interfaz (utilizando las RPC de Sun), disponible en el arcl block_server.x: struct block_request { int block_no ; 1 nimero de bloque */ opaque data(1024) ; 7* bloque de datos */ Me struct block_result ( opaque data(1024) J+ bloque de datos */ int result ; 7* resultado de la operacién */ ya program, BLOCK_SERVER { version UNO t "Material compiiado confines académicos, se proibe su reprodvcién total o parcial sin la autorzacin 6 cada autor, Introduccién a los sistemas distrbuidos 215 block_result read_block ( int block_no ) = 1; iat write block ( block_request arg ) = int total blocks( ) = 37 yea } = 9999999 La fincién read_b2ock permite leer el bloque con niimero block_no del servidor. El tama~ fio del bloque de cada servidor es de | KB. La funcién devuelve en el campo result de block_resuit un 0 en caso de éxito y —1 en caso de error. La funcién weite_block permite escribir un bloque en el servidor. La estructura block_request incluye el ntimero de bloque y el contenido del bloque a leer. La funcién devuelve 0 en caso de éxito y valor ~1 en caso de error. La funcién total_biocks devuelve el nimero total de bloques que gestiona el servidor de bloques. El alumno debe utilizar cuatro servidores para construir un sistema de almacenamiento que define una particién distribuida entre los cuatro servidores de la forma que se muestra en la Tabla 6.1. Esta particién distribuida tiene un comportamiento similar a un RAIDS sobre discos. Es muy importante entender cual es la distribucién de los bloques légicos en los distintos nodos. Para empezar, los bloques que sirven los servidores de bloques los denominamos blogues fisicos. Los bloques que sirve la biblioteca RAIDS a través de su interfaz se denominan blogues logicos. Hay una correspondencia entre un bloque légico y su bloque fisico correspondiente. Como se puede ver en la figura, cada elemento de la tabla representa el niimero de bloque légico de la particién distribuida. Asi, el bloque légico 7 se corresponde con el bloque fisico 0 del servidor 2. Por su parte, la paridad correspondiente a los bloques légicos 3, 4 y 5 se encuentra en el bloque fisico 1 del servidor 2. El alumno debe utilizar cuatro servidores con la interfaz descrita anteriormente para construir, sobre estos cuatro servidores un RAIDS con la distribucién de bloques logicos descrita anteri mente. Para ello debe implementar las dos siguientes funciones (cuya interfaz se encuentra en el archivo raid5.h, que se proporciona al alumno): int raia5_read_block ( int block_no, char *data ); int raid5_write_block( int block no, char *data ); La funcién raias_read_block lee el bloque légico con mimero biock_no y lo almacena en el buffer data. La funcién raid5_write_block escribe un bloque légico. Las funciones deben devolver 0 en caso de éxito y ~i en caso de error. Estas dos funciones deben gestionar el RAIDS y hacer frente de forma transparente a la caida de uno de los servidores. Se proporciona al alumno un esqueleto de programa (test_raids .c) que sirve para acceder al RAIDS. Este programa permite leer y escribir bloques dei RAIDS utilizando las funciones Tabla 6.1. Diséribucién de bloques en la particién RAIDS Servidor 0 servidor 1 servider 2 servidor 3 0 1 2 P 3 4 e 5 6 P 7 3 P 9 0 n 2 B 4 Pe Material compiiado confines académicos, se proibe su reproducién total o parcial sin la autorzacin de cada autor, 216 Libro de précticas de sistemas operativos anteriores. El alumno debe modificar este programa para inicializar el RAID. Se recomienda que el alumno implemente en el archivo raidS.c una funcién, denominada raid5_init, que se encargue de inicializar el RAID. E] alumno ha de programar la biblioteca raids, asi como el programa de prueba comentado anteriormente. El alumno ha de implementar, ademés, 1a funcionalidad de reconstruccién de la informacién de un servidor, supuesto que éste deje de funcionar y més tarde se rearranque. La préctica ha de probarse suficientemente eligiendo diferentes servidores de bloques a lz hora de simular la caida matando el proceso, 6.8.4, Cédigo fuente de apoyo Para facilitar 1a realizacién de la préctica, se dispone en Ia pagina web del libro del archivo practica-6.8. tar.gz, que contiene cédigo fuente de apoyo. Al extracr su contenido, se ctea ¢l directorio practica-6..8, donde se debe desarrollar la prictca. Dentro de este directorio, se encuentran los siguientes archivos: * Makefi1e: archivo fuente para la herramienta make. NO debe ser modificado. Con él se consigue la recopilacién automatica de los archivos fuente cuando se modifique. Basta con ejecutar el mandato make para que el programa se compile de forma automitica. * block_server: ejecutable de un servidor. * block_server. x: archivo con la interfaz de un servidor. * raid5.h: archivo de cabecera con la interfaz de la biblioteca raids descrita anteriormente Este archivo puede modificarse si se considera necesario. ‘ raid5 .c: archivo fuente donde se implementaré la biblioteca raias descrita en el enun- ciado. Este archivo Si debe ser modificado y serd parte de Ia documentacién a entreger. * test_raids..c: archivo que permite al alumno probar las funciones que aeceden al RAIDS. Este archivo debe modificarse para iniciar el RAIDS. ‘+ rebuild.c: archivo que contiene ta funcionalidad para reconstruir la informacién de un servidor que supuestamente habia fallado y después se recupera 6.8.5. Recomendaciones generales Es importante entender tas bases del sistema: RPC y RAIDS. Para el célculo de Ia paridad es rnecesario empfear el operador binario de C, que permite calcular el XOR (*) entre dos valores, Conviene que el alumno implemente una funcién con prototipo similar al siguiente: void calcularParidad(char *datosi, char ‘dates?, char ‘paridad, int long) : que se encargard de calcular 1a paridad de dos bloques de datos (datos y datos2) y dejar el resultado en el bloque paridad. La longitud de los distintos bloques vendré dada por el timo parimetro (1on9), Es importante que el alumno tenga en cuenta qué ocurre cuando un servidor fallay se pierde Ja conexin con él. En este caso, se genera una sefal que deberd ser tratada, Material compiiado confines académicos, se proibe su reproducién total o parcial sin la autorzacin de cada autor, Introducelén a fos sistemas distribuides 217 6.8.6. Entrega de documentacién El alumno debe entregar los siguientes archivos: ‘+ memoria. txt: Memoria de la prictica. + raid5.c y raids .h: Cédigo fuente en C con Ia biblioteca que implementa la funcionali dad pedida. * test_raias..c: Cédigo fuente en C con el programa de prueba 6.8.7. liografia ‘* J. L. Antonakos y K. C. Mansfiled, Jr. Programacién estructurada en C. Prentice-Hall, 1997. ‘+ F Gareia, J. Carretero, J, Fenindez y A. Calderdn. El lenguaje de programacién C: disefio e implementacién de programas. Prentice-Hall, 2002. « P. Jalote. Fault Tolerance in Distributed Systems. Prentice-Hall, 1994. 6.9. PRACTICA: EXCLUSION MUTUA UTILIZANDO UN ANILLO- CON PASO DE TESTIGO 6.9.1. Objetivos de la practica El objetivo de esta prictica es mostrar al alumno la forma de ofrecer un servicio de sincronizacién {que permite a los procesos de una aplicacién distribuida acceder en exclusién mutua a un determi: nado recurso compartido. El método elegido es la configuracién de los procesos de Ia aplicacién como un anillo y la utilizacién de un mecanismo basado en el paso de un testigo. NIVEL: Disefio. HORAS ESTIMADAS: 16. 6.9.2. Exclusién mutua basada en paso de testigo Una forma de asegurar la exclusién mutua en una aplicacién distribuida consiste en organizar los procesos de la aplicacién como un anillo légico, tal y como se muestra en la Figura 6.8. Por el anillo va circulando un testigo. Cuando un proceso desea entrar en la seccién critica, debe esperar ‘a estar en posesién del testigo, Mientras el testigo no llegue a ese proceso, éste no podré pasar a ejecutar dentro de la seccién critica. Cada vez que el testigo lega a un proceso, se comprueba si tl proceso desea entrar en Ia seccién critica. En caso de no querer entrar, envia el testigo al siguiente proceso del anillo. En caso contrario, no reenvia el testigo y pasa a ejecutar dentro de la seccién critica. El testigo permanece en el proceso hasta que abandone la seccién critica. Una vez abandonada la seccién critica, se envia el testigo al siguiente proceso, dandole la oportunidad de entrar en la seccién critica El proceso descrito asegura la exclusién mutua en el acceso a un determinado recurso compartido, puesto que sélo aquel proceso que esté en posesién del testigo podra acceder al recurso. Material compiiado confines académicos, se profi su reprodccln total o parcial sn ta autoizaion de cada aut, 218 Libro de précticas de sistemas operatives Figura 6.8. Sincronizacién en el acceso a un recurso compartido uiilizando un anillo con paso de testigo, 6.9.3. Descripcién de la funcionalidad que debe desarrollar el alumno Se desea ofrecer un mecanismo de exclusién mutua que organice los procesos de una aplicacién distribuida en forma de anillo. La descripcién de la funcionalidad a desarrollar se explicaré utilizan- do como ejemplo la aplicacién distribuida de 1a Figura 6.9. En esta figura se muestran cuatro proce- sos (PO, Pl, P2 y P3) que se van a configurar como un anillo. Para ejecutar estos cuatro procesas (bien en la misma maquina o bien en miquinas distintas) se deben ejecutar los siguientes mandatos: © m0 pO mi pi m2 p2 m3 p3 anillo 1 m0 pO mi pi m2 p2 m3 p3 2 m0 pO mi pi m2 p2 m3 p3 3 m0 pO mi pl m2 p2 m3 p3 Figura 69. Ejemplo de aplicacién configurada en un anillo. Material compiiado confines académicos, se proibe su reproducién total o parcial sin la autorzacin de cada autor, Introduccién a los sistemas distribuidos 219 Cada proceso (el nombre del ejecutable es ani1i0) recibe como segundo argumento en 1a linea de mandatos un nimero entero que lo identifica dentro del anillo. A continuacién se pasan los nombres de las miquinas y los puertos donde van a ejecutar cada uno de estos procesos. Asi, por ejemplo, el proceso PO tiene como identificador 0, ejecutaré en la maquina mi y utilizaré ‘como niimero de puerto pi; el proceso P2 ejecutaré en Ia miquina m2 y uilizaré el puerto p2. Hay ‘que asegurarse que cada proceso se ejecuta en la maquina correspondiente. Todos pueden ejecu- tarse en la misma maquina siempre que se utilicen mimeros de puerto distintos. ‘Cada uno de estos procesos debe ser capaz. de utilizar las siguientes primitivas a desarrollar por el alumno: mutex_init (int arge, char **argv); mutex lock (void) ; mutex_unlock (void) ; La funcién mutex_init es la encargada de inicializar el anillo tal como se muestra en la Figura 6.10. Para conectar los procesos se utilizaran sockets stream. Observe que la funcién ante- rior crea un proceso ligero en cada proceso que sera el encargado de hacer circular cl testigo @ través del anillo. Se puede elegir al proceso con identificador 0 como el proceso que inserta el testigo inicialmente en el anillo, El testigo puede ser un simple byte. Para que el anillo quede correctamente configurado, todos los procesos de Ia aplicacién deben ejecutar la funcién Primttiva muvex_init. Material compiiado confines académicos, se proibe su reproducién total o parcial sin la autorzacin de cada autor, 220 Libro de practicas de sistemas operatives mutex_init. El objetivo del proceso ligero creado en esta funcién es recircular el testigo a través del anillo, es decir, debe estar en un bucle infinito similar al que se muestra a continuacién: while(1) £ leer el testigo del proceso anterior enviar el testigo al proceso siguiente; Una vez creado el proceso ligero, se deberén utilizar los servicios accept y connect para conectar de forma légica a todos los procesos del anillo. La formacién del anillo se puede realizar a partir de los parémetros argc y arav que acepta la funcién main y que se deben pasar a la fancién mutex_init, La funcién mutex_tock se utiliza para acceder en exclusién mutua a un determinado recur- 50. El cédigo de esta funcién se debe sineronizar con el proceso ligero que se encarga de recircu- lar el testigo a través del anillo. La funcién mutex_tock bloqueara al proceso que ejecuta la Hamada hasta que el testigo legue al proceso ligero que se encarga de recircular el testigo. Cuando el proceso ligero recibe el testigo, comprucba si se ha ejecutado dentro del proceso la funcién matex_Lock. Si es asi, no envia el testigo el siguiente proceso del anillo y despierta al proceso suspendido en la llamada mutex_lock permitiendo que continic con su ejecucién. El proceso ligero se bloqueard a continuacién hasta que s¢ ejecute la funcién mutex_uniock. La funcién matex_unlock se utiliza para liberar el acceso al recurso compartido, el cédigo de esta funcién tiene que set capaz de despertar al proceso ligero de forma que éste vuelva a insertar el testigo en ef anillo 6.9.4, Recomendaciones generales Para sincronizar ¢l cédigo de las funciones mutex_lock y mutex_unlock con el cédigo del proceso ligero que se encarga de recircular el testigo a través del anillo se pueden utilizar muter ¥ variables condicionales como las descritas en el Capitulo 4 6.9.5. Entrega de documentacién Bl alumno debe entregar los siguientes archivos: + memoria. txt: Memoria de la prictica ‘* anillo.c: Cédigo fuente con el cédigo del programa, 9.6. Bibliografia + J. Camretero, F, Garcia, P. de Miguel y F. Pérez. Sistemas operativos: una visién aplicada, McGraw-Hill, 2001 F Garcia, J. Carretero, J. Fernindez y A. Calderén. El lenguaje de programacién C: disefio € implementacién de programas. Prentice-Hall, 2002. "Material compiiado confines académicos, se proibe su reprodvclén total o parca sin la autorzacén de cada autor

También podría gustarte