Trabalho de Laboratório Programação de Sistemas - LEE IST - 2007/2008 Sistema de Controlo com Acesso Remoto 1 Introdução Um sistema de controlo é, normalmente, constituído por vários processos controladores que, dependendo do tipo de operação a realizar, podem ter necessidade de aceder a diversos dispositivos antes de efectuarem o processamento e controlo propriamente dito. Estas operações têm normalmente um carácter cíclico, podendo o seu período ser configurável pela intervenção de um operador. Este tipo de aplicações possuem inerentemente um carácter concorrente atendendo às diversas actividades que se devem desenrolar em paralelo. Para além disso, é, por vezes, necessário o acesso a um repositório que permita registar, de forma persistente, a evolução do sistema, para eventual análise posterior. Finalmente, uma interface que permita o acesso ao sistema de controlo, para operações de consulta e reconfiguração, é de extrema importância do ponto de vista de flexibilidade de utilização. A aplicação que se pretende concretizar, envolve os aspectos de comunicação entre o(s) utilizador(es) e o sistema de controlo propriamente dito (constituido por diversos processos), bem como aspectos de sincronização entre os diversos componentes do sistema de controlo, e ainda o registo e consulta de um histórico sobre a evolução do sistema (interacção com o sistema de ficheiros). Este trabalho tem como objectivo fundamental a familiarização por parte dos alunos com os aspectos de concorrência, sincronização e comunicação oferecidos por um sistema operativo (Unix/Linux). Os aspectos da interface aplicacional são relegados para segundo plano, sendo portanto simplificados. 2 Descrição Geral do Problema Com este trabalho pretende-se programar uma aplicação constituída por vários processos que comunicam entre si. A aplicação está dividida em três partes fundamentais: a interface com o utilizador ( interface ), o sistema de controlo propriamente dito ( controlo ), e o registo histórico ( registo ) (ver Figura 1). A interface com o utilizador permite que este possa efectuar comandos de consulta e configuração do sistema de controlo, bem como consulta do registo histórico. Podem existir vários utilizadores activos simultaneamente. O sistema de controlo é constituído por um conjunto de processos controladores ( threads ) que, dependendo do seu tipo, acedem a determinados dispositivos, efectuando seguidamente um processamento específico. Os vários passos da sua execução podem ser guardados em memória não volátil, através do seu envio para o processo que faz o registo histórico. No sistema de controlo, existe ainda um outro processo/ thread que dialoga com o(s) utilizador(es). O registo histórico recolhe a informação proveniente do sistema de controlo e guarda-a num ficheiro. Para além disso aceita comandos para consulta dos registos guardados. 1
controlo msg registo mmap sockets datagram sockets stream interface Figure 1: Arquitectura global do sistema de controlo Para que a aplicação global tenha a funcionalidade completa é necessário que os programas controlo e registo estejam em execução. Para se poderem terminar de forma ordeira, e salvaguardando toda a informação relevante, eles devem aceitar um comando de terminação, que pode ser enviado pela aplicação interface, ou também através de um sinal SIGTERM enviado a partir da linha de comando ( shell ). 3 Interface com o utilizador interface O processo responsável pela interface com o utilizador (interface), permitirá a este efectuar um conjunto de comandos para interagir, quer com o sistema de controlo propriamente dito (controlo), quer com o processo de registo histórico (registo). São os seguintes, os comandos a disponibilizar: Comandos Disponíveis comando argumentos descrição cc < tipo > < periodo > - criar processo controlador lc - listar processos controladores ec < id > - eliminar processo controlador mc < id > < tipo > < periodo > - modificar processo controlador areg - activar envio para registo histórico dreg - desactivar envio para registo histórico tctl - terminar processo sistema de controlo lr < n > < t > - listar < n > registos a partir do tempo/nseq < t > treg - terminar processo de registo histórico sair - terminar interface utilizador No primeiro grupo de comandos a interacção é feita com o sistema de controlo (controlo), e no segundo grupo de comandos a interacção é feita com o processo de registo histórico (registo). Em qualquer dos casos existe uma mensagem de resposta, ficando o processo bloqueado à sua espera (interface síncrona). Devem, no entanto, prever a hipótese de impossibilidade de comunicação. No caso em que o comando especificado não seja executado com sucesso remotamente, a mensagem de resposta terá um código de erro. 2
4 O sistema de controlo controlo Como se disse atrás, o sistema de controlo é constituído por diversos processos controladores, que funcionam em ciclo e de forma periódica. Cada processo controlador corresponde a uma thread (pthread). Estas threads são idênticas entre si (mesmo código). Distinguem-se apenas pelos parâmetros que lhe estão associados. Cada processo controlador é conhecido por um identificador e por um tipo. Estes parâmetros, em conjunto com o período, são-lhe atribuídos no momento da sua criação. O tipo de controlador, que pode tomar valores entre 1 e 3, determina quais os dispositivos a que esse controlador necessita de aceder antes de fazer o respectivo processamento. O seu número representa em binário 2 possíveis dispositivos (DispB, DispA). Por exemplo, um controlador tipo 2 (10 em binário) necessita de aceder ao dispositivo DispB, mas não ao DispA. Cada dispositivo necessita de ser acedido em exclusividade. No entanto, para permitir o máximo de paralelismo, a ordem pela qual um processo controlador acede aos dispositivos de que necessita é indiferente. Desde que um deles esteja disponível, ser-lhe-á atribuído. Se não houver nenhum disponível, o processo ficará bloqueado, sendo desbloqueado assim que lhe puder ser atribuído um dos dispositivos pretendidos. Se houver mais do que um processo controlador à espera, a ordem de atribuição é FIFO. O algoritmo de atribuição dos dispositivos deve ser distribuído (i.e. não existe nenhum gestor centralizado) e não se admitem soluções que usem teste cíclico ( polling ) ou espera activa. O acesso a um determinado dispositivo é simulado através do adormecimento do processo ( sleep ) durante um intervalo de tempo especificado (TDISPA, TDISPB). De seguida liberta-se o dispositivo, permitindo, eventualmente, o acesso por parte de outro processo controlador. Se o processo controlador ainda necessita de aceder ao outro dispositivo antes de efectuar o processamento, repete os passos anteriores eliminado do pedido o dispositivo já acedido. Caso contrário, prossegue para o processamento e espera de novo ciclo, simulado também por um adormecimento do processo ( sleep ) pelo tempo correspondente ao seu período. Todos estes passos de execução (pedido de acesso a dispositivos, acesso a dispositivo, liberta dispositivo, espera novo ciclo) de um processo controlador serão registados num ficheiro (caso esse registo esteja activo) através do envio dessa informação para o processo de registo histórico (registo). Essa informação consiste no identificador do processo controlador, no seu tipo, no código de operação, e no identificador do(s) dispositivo(s), a que se junta ainda um número de sequência, que serializa todos os registos enviados (ver registo reg t). Esta interface com o processo de registo histórico é assíncrona, não havendo qualquer mensagem de resposta. Para além dos processos controladores, o sistema de controlo tem ainda a capacidade de dialogar com a interface utilizador para execução dos comandos referidos anteriormente. O programa controlo é activado de forma independente, sendo responsável pelas inicializações necessárias ao correcto funcionamento da aplicação (criação dos vários objectos de comunicação e sincronização). Caso o processo de registo histórico não esteja ainda disponível, também deverá ser criado. O programa controlo, do ponto de vista da comunicação com a interface utilizador (socket unix datagrama), é conhecido pelo nome global CONTROLO. 3
5 O registo histórico registo O programa registo pode ser activado de forma independente, ou a partir do programa controlo. É responsável por guardar em memória persistente (ficheiro FICHHIST) os registos que lhe são enviados pelo sistema de controlo. Para além disso, deve ainda permitir a consulta de registos feita a partir da interface utilizador. Para evitar um crescimento desmesurado do ficheiro, existirão, num dado instante, até um máximo de NREG registos. A partir deste valor, os novos registos sobrepõem-se aos anteriores, funcionando o ficheiro como um buffer circular. A gestão do ficheiro pode ser efectuada quer utilizando as primitivas mais tradicionais de acesso a ficheiros (open, read, write,...), como mapeando o ficheiro em memória (mmap) (aconselhado). O programa registo, do ponto de vista da comunicação, é conhecido pelos nomes globais REGHISTM (chave da caixa de correio), e REGHISTS (socket stream). 6 Objectos de comunicação e sincronização A sincronização entre as várias threads existentes no sistema de controlo, bem como o controlo do acesso destas a eventuais estruturas de dados partilhadas, deve ser feito utilizando semáforos POSIX (sem init, sem post, sem wait,...), ou as próprias primitivas associadas às pthreads. Na comunicação entre a interface utilizador e o sistema de controlo devem ser usados sockets (sockets unix datagrama), e na comunicação entre a interface utilizador e o registo histórico devem ser usados sockets stream. A comunicação entre o processo de controlo ( threads ) e o processo que faz o registo histórico deve ser efectuada por mensagens, utilizando as primitivas IPC do sistema V (msgget, msgctl, msgsnd, msgrcv,...). 7 Desenvolvimento do projecto No desenvolvimento do projecto, aconselha-se a utilização de uma estrutura modular, com testes faseados. Na interface com o utilizador, não se pretende nada de muito complexo (não é esse o objectivo fundamental). Para simplificar a sua concretização, os alunos podem/devem utilizar um interpretador de comandos rudimentar, que é fornecido (ver página da disciplina). 8 Estruturas de dados e constantes Na concretização do trabalho considere os seguintes valores para as constantes referidas anteriormente: #define NCTRL 5 /* numero maximo de processos controladores */ #define TDISPA 10 /* tempo de acesso dispositivo A (segundos) */ 4
#define TDISPB 15 /* tempo de acesso dispositivo B (segundos) */ #define NREG 100 /* numero maximo de registos no ficheiro */ #define FICHHIST "REGISTO.LOG" /* ficheiro com registo historico */ #define CONTROLO "/tmp/controlo" /* nome do sistema de controlo (socket) */ #define REGHISTM 0x5248 /* ( R H ) nome do registo historico (msg) */ #define REGHISTS "/tmp/registo" /* nome do registo historico (socket) */ #define INTUTIS "/tmp/us<pid>" /* nome interface utilizador (socket) */ /* em que <pid> e o identificador do processo */ /* codigos de operacao -- para registo */ #define OP_PDA 1 /* pede acesso a dispositivos */ #define OP_ACD 2 /* acesso a dispositivo */ #define OP_LIB 3 /* liberta dispositivo */ #define OP_ENC 4 /* espera novo ciclo */ typedef struct reg_s { /* possivel estrutura de um registo */ unsigned int estamp; /* estampilha temporal / numero de sequencia */ int id; /* identificador do processo controlador */ int tipo; /* tipo de processo controlador */ int periodo; /* periodo do processo controlador */ int op; /* operacao a realizar */ int disp; /* identificador do(s) dispositivo(s) */ } reg_t; 9 Entrega e Visualização do Trabalho Este trabalho tem uma meta intercalar na semana de 19 de Novembro (no horário de laboratório). Devem entregar 1 ou 2 páginas A4 com uma descrição dos componentes fundamentais e sua interligação (diagrama de blocos). Do ponto de vista prático, deverão mostrar a funcionar uma versão elementar da interface com o utilizador e do sistema de controlo (comandos para criação, consulta e modificação de parâmetros dos processos controladores ( pthreads )). Esta meta intercalar contribuirá com 5% (1 valor) para a nota do laboratório. O trabalho final deve ser entregue na aula teórica do dia 5 de Dezembro de 2007. O material a entregar consiste numa cópia em formato digital de todos os programas desenvolvidos e respectivo makefile, e numa listagem (em papel) dos mesmos. Devem ainda juntar 1 ou 2 páginas A4 com a especificação da estrutura de dados e as partes mais relevantes dos algoritmos (em pseudo-código). Todos estes elementos devem vir identificados com o número do grupo de laboratório e identificação dos alunos que o compõem. A visualização do trabalho será efectuada na semana de 3 de Dezembro (no horário de laboratório) com base no trabalho entregue. As discussões dos trabalhos serão realizadas na semana de 10 de Dezembro (no horário de laboratório), e, eventualmente, na semana seguinte, em data e hora a afixar posteriormente na página da disciplina. 5