Recomendações e Comentários

Recomendações

Para que o trabalho possa ser desenvolvido a contento recomenda-se:

Ø      O entendimento da teoria e uso dos recursos de programação que foram vistos em SOI.

Ø      O conhecimento da teoria relacionada ao modelo de camadas de software proposto para o estudo de um sistema operacional tipo Unix, em relação a operações de entrada/saída.

Ø      O entendimento dos requisitos impostos pela manipulação de arquivos com dados multimídia, para propor soluções não convencionais para o seu tratamento.

Ø      O estudo das referências:

·         Modern Operating Systems, Tanembaum, Prentice Hall.

Capítulo 4 – FILE SYSTEMS, em especial, seções 4,1 (Files), 4,2 (Directories) e 4.3. (File System Implementation).

Capítulo 5 – INPUT/OUTPUT, em especial, seção 5.2. (Principles of I/O Software), subseções 5.2.2 (Interrupt Handlers), 5.2.3 (Device Drivers) e 5.2.4 (Device-Independent I/O Software) e figura 5.6 (Layers of the I/O system and the main functions of each layer), além da seção 5.3 (Disks), subseção 5.3.3 (Error Handling).

·         Operating Systems, Silberschatz & Galvin, Prentice Hall.

Capítulo 10 – Interface de Sistemas de Arquivos

Capítulo 11 – Implementação de Sistemas de Arquivos

Capítulo 12 – Seções 12.4.2 Áreas de Armazenamento Temporário, 12.4.3 Memória Cache, 12.4.5 Tratamento de Erros, 12.4.6 Estruturas de Dados do Núcleo

Capítulo 21 – seção 21.7 Sistema de Arquivos

Capítulo 23 – seção 23.5 Sistema de Arquivos

Ø      Revisão dos experimentos realizados durante a disciplina SO I, pois haverá a necessidade de mecanismos de IPC e threads.

Ø      Conhecimento da especificação RAID (ver arquivo RAID.PDF)

 

Diretrizes

O trabalho a ser desenvolvido deve seguir as seguintes diretrizes:

Ø      Nas etapas de Especificação, Projeto, Plano de Testes e de Integração, e Integração e Testes deve-se trabalhar em grupo de três pessoas. Ao final de cada uma das três primeiras etapas, haverá a apresentação de um subproduto. Isso ocorrerá em sala de aula, com a presença obrigatória de todos. Serão indicados alunos para a apresentação e discussão dos resultados, a critério do professor.

Ø      Na fase de Programação e Testes deve-se trabalhar individualmente, implementando-se e executando a parte do Plano de Testes e de Integração relacionada com os módulos funcionais equivalentes a um terço do resultado definido na etapa de Projeto. Cada parte a ser implementada e testada individualmente é definida posteriormente ao término da etapa de projeto.

 

Descrição

Descrição do produto a ser desenvolvido:

Ø      O produto final deve dar continuidade ao tratamento das seguintes chamadas ao sistema, relacionadas com arquivos com dados contínuos armazenados em disco: open, read e write;

Ø      Um arquivo com dados contínuos (multimídia). Este tipo de arquivo contém dados de mídias temporalmente contínuas, tais como filmes ou músicas. As chamadas ao sistema read e write para esse tipo de arquivo envolvem um dado que representa um elemento em um fluxo contínuo, por exemplo uma imagem de um filme ou uma nota de uma música. Para este trabalho, deve-se considerar arquivos de filmes, com imagens (quadros) de tamanho de 2 Megabytes;

Ø      Deve-se considerar ou o mapeamento baseado em I-nodes ou o mapeamento baseado em FAT (depende do estabelecido pelo professor – ver grupos), que controlem clusters de 512 bytes;

Ø      A configuração do disco deve ser dinâmica e é inicializada em uma tabela residente em memória. Tal tabela é compartilhada por vários módulos do SO, tal como o driver;

Ø      Devem fazer parte do produto final uma estrutura de diretório e com os mapeamentos registro lógico, registro físico e cluster;

Ø      Não há necessidade da preocupação com o aspecto segurança;

Ø      O produto final deve manipular solicitações em um ambiente multi-usuário e multi-tarefa; ou seja, a camada independente de dispositivo pode estar tratando de maneira “paralela” várias requisições a arquivos distintos; cuidado com as necessidades de exclusão mútua;

Ø      Deve-se considerar o código em C do driver existente em driver-int-1234.c para a definição de toda a camada independente de dispositivo;

Ø      O trabalho deve considerar a plataforma PC/LINUX;

Ø      Requisições a arquivos multimídia têm a peculiaridade de serem acompanhadas por um parâmetro que indica o momento no tempo em que a requisiçãao necessita estar pronta (o chamado deadline). A aplicação que solicita esse tipo de requisição é a responsável por determinar o instante do deadline.

 

Especificação

A Especificação é a primeira etapa do trabalho de laboratório propriamente dito. Na data prevista em cronograma, deverá ser entregue o primeiro subproduto, que corresponde a um documento que apresente O QUÊ vai ser implementado. Algo como um manual do usuário, explicando o funcionamento daquilo que vai ser construído, do ponto de vista do usuário.

Lembrar que o usuário, no caso das partes de um SO, é um projetista de sistemas operacionais e, portanto, a especificação deve abranger os elementos necessários para a realização da funcionalidade da camada independente de dispositivo, tal como o controle de buffers ou da memória cache.

Deve-se já nesta etapa indicar funcionalidades que estarão sendo realizadas em “paralelo”.

Exemplo de uma Especificação parcial, definida por alunos da FEC, para a implementação do comando write junto à camada independente de dispositivo, pode ser encontrado em especifica_exemplo.

 

Projeto

Na etapa de Projeto são exploradas questões de COMO aquilo que foi especificado será implementado.

Na documentação relativa à fase de projeto a ser entregue deve-se apresentar:

·         Os módulos que constituirão o resultado final. Deve-se providenciar diagramas funcionais (DFD) em níveis 0 e 1.

·         A definição das interfaces para e entre esses módulos, ou seja, quais os parâmetros passados, seus tipos, os resultados e, se necessário, as exceções que podem ocorrer. Não esquecer que a camada Independente de Dispositivo encontra-se entre a camada ao nível do usuário e a camada de drivers.

·         Deve-se providenciar um diagrama de chamadas de controle, para indicar qual módulo chama qual outro e em qual seqüência ocorrem ativações e retornos de controle. Se houver paralelismo de execução, isso deve aparecer no diagrama.

·         Representação gráfica das principais estruturas de dados existentes (por exemplo, registros, listas ligadas, pilhas, etc.) e que são necessárias para algum dos módulos identificados nos DFDs. Deverão acompanhar cada estrutura de dados: descrição sucinta das operações que podem ser realizadas sobre as mesmas; além de tipos e valores válidos para seus campos.

·         Algoritmos dos módulos em pseudo-código em alto nível, ou seja, sem detalhes de programação.

O projeto deverá apresentar o esqueleto do produto final. Entenda-se por esqueleto a rotina principal, com declarações, inicializações e instruções para chamada dos módulos individuais.

O projeto tem que ser completo, mas não detalhado. É diferente da implementação, ou seja, não tem todos os detalhes de uma programação, porque, caso apresente problemas, a quantidade de trabalho a ser refeito não é tão grande e, também, porque exige menos de quem quer entendê-lo ou necessita modificá-lo.

Exemplo de um Projeto parcial, definido por alunos da FEC para a implementação de um driver sem a preocupação de tratar dados multimídia, pode ser encontrado em projeto_exemplo.

 

Plano de Testes e de Integração

Nesta atividade deve-se explorar o que testar da implementação (que ainda não foi produzida) e como testar. Para isso, são considerados os documentos de especificação e de projeto já criados. O tipo de teste pretendido é caixa preta.

Na documentação a ser entregue, deve-se incluir casos de teste, tantos quantos sejam necessários para cobrir toda a implementação.

O que é um caso de teste? É uma unidade do plano de testes e de integração que estabelece um roteiro, o qual permite a um testador (humano) realizar um teste, com o objetivo de ocasionar uma falha que indique a existência de erros no produto final.

Um caso de testes é constituído de quatro partes:

a)      Uma única condição a ser testada - exemplos de condições, recebimento de uma requisição de leitura ou escrita para um arquivo que não foi aberto, busca de um determinado cluster (bloco de dados) que se encontra na memória cache ou o término de uma requisição com erro de leitura.

Não se pode esquecer de cobrir todas as situações de erro definidas na especificação.

b)      A maneira de fazer ocorrer a condição, ou seja, a determinação de quais estruturas de dados são necessárias para fazer a condição ocorrer, não se esquecendo da escolha dos valores que necessitam existir nessas estruturas e as operações para sua geração. Seguindo os exemplos anteriores de condições, cria-se uma requisição cujos parâmetros contêm valores válidos, porém o handler do arquivo não existe, ou seja, não está associado a uma estrutura de descritor de arquivo. No segundo exemplo, cria-se a estrutura de cache com o conteúdo do cluster que é calculado a partir da requisição de entrada/saída recebida. No terceiro exemplo, o status da requisição enviada ao driver deve conter o código de erro de leitura.

Obs.: Nos locais onde está escrito "com valores válidos" tem que se escolher valores efetivos, por exemplo, no parâmetro de deadline e assim por diante. Em outras palavras, em uma condição de testes não se pode especificar "qualquer valor", mas um determinado valor, 5 por exemplo.

c)      O resultado esperado, ou seja, aquilo (valor e seqüência) que deve ocorrer na condição que se escolheu, tal como a ativação de elementos ou o retorno de resultados. No primeiro exemplo visto, a camada independente de dispositivos deve retornar o código indicando requisição não atendida devido ao arquivo não estar aberto ou indicação de handler inválido. No segundo exemplo, deve ocorrer a colocação do cluster no buffer do arquivo, além do cancelamento do envio de requisição ao driver. No terceiro exemplo, percebendo ser um status indicando erro de leitura, retorna o valor do status para a camada ao nível do usuário. 

d)      Como observar o resultado esperado, ou seja, é necessário que o testador possa perceber visualmente o resultado esperado. Como, na maioria das vezes, em um sistema operacional, o que vai ser observado fica escondido, ou seja, o resultado não aparece para o usuário do sistema operacional, é necessário incluir linhas de código, que necessitam estar isoladas do restante da implementação, para exibir em um dispositivo de saída (tela, impressora ou arquivo em disco) alguma informação relativa ao que ocorreu. Nos exemplos anteriores, devem ser incluídas linhas de código que exibam em um arquivo mensagens indicando as ativações e os valores manipulados.

O Plano de Testes e de Integração vai acabar indicando qual código adicional necessita ser incluído no produto, o que possibilitará a realização da observação de resultados esperados. Este código adicional não é parte do produto, ou seja, não pode ser incluído na compilação do produto final. No documento do plano de testes deve ser apresentado apenas através de pseudo-código. Posteriormente, durante a programação, este código deve ser incluído próximo ao ponto que se quer testar – antes, para que a condição ocorra, e depois, para percepção do resultado esperado.

Evitar a todo custo transformar o plano de testes em orientações para um experimento, ou seja, algo do tipo: "vamos ativar a camada independente de dispositivo com uma requisição qualquer e ver o que acontece buffer do arquivo". Em um experimento, costuma-se estabelecer regras para observação de resultados sem, no entanto, definir explicitamente esses resultados, o que deve ocorrer em um plano de testes.

Deve-se organizar uma ordem para os testes, devido às dependências entre as partes, ou seja, não adianta querer realizar o teste do terceiro exemplo (ativação do driver) se ainda não se testou e ficou garantido que não há falhas de todas as condições que podem ocorrer desde o momento da chegada da requisição até aquele ponto.

Para se testar o produto final, além da chamada à camada independente de dispositivo, dependendo do caso de teste, haverá a necessidade de suprir software no lugar onde estariam, por exemplo, a camada ao nível do usuário ou o driver, ou seja elementos e rotinas que interagem com a camada independente de dispositivo.

Deverão existir dois tipos de casos de testes: aqueles orientados ao teste de cada módulo individualmente e queles orientados ao teste dos módulos juntos. Recomenda-se fortemente que a integração seja feita de maneira evolutiva, ou seja, integram-se e testam-se dois módulos, depois de verificado que os resultados esperados conferem com os resultados obtido, passa-se a integrar mais um módulo, e assim por diante.

Exemplo de um Plano de Testes e de Integração parcial, definido por alunos da FEC para a implementação do comando write junto à camada independente de dispositivo, pode ser encontrado em plano_exemplo.

 

Programação e Testes

O documento de Projeto será usado para dividir em três partes o trabalho de implementação. Individualmente cada elemento do grupo será responsável pela programação de uma das partes.

A implementação deve ser realizada em ambiente Intel-Linux, devido aos requisitos de multi-usuário e multi-tarefa, além da necessidade do uso de threads e outros mecanismos de IPC.

Deve-se, também, separar o código proveniente do projeto, daquele proveniente do plano de testes. Para isso, deve-se ou adotar diretivas de compilação, que permitem não compilar parte dos fontes (como ocorre no experimento 5), ou utilizar condições inicializadas através de parâmetros que permitam ou não a execução de parte dos fontes.

Após terminada a codificação, pode-se proceder qualquer tipo de teste que se considerar necessário. Mas, uma vez estabelecido o término da implementação, com base no documento Plano de Testes e de Integração, deve-se executar os casos de teste definidos para o teste individual dos módulos envolvidos. Caso algum caso de testes apresente resultado final diferente do esperado, deve-se procurar e resolver o erro.

 

Integração e Testes

Tomando como base o pseudo-código definido como esqueleto no documento de Projeto, devem ser integradas as três implementações já testadas pelos elementos do grupo.

A integração pretendida deve seguir a ordem de integração definida no Plano de Testes e de Integração bem como ser submetida aos respectrivos casos de teste, até se ter um produto inteiro que funcione de acordo com a Especificação.

 

Aspectos a serem observados na entrega dos RT

A nota relativa à componente prática da nota final, e que se refere aos resultados tecnológicos, será obtida se forem observados, de maneira integrada, os seguintes aspectos:

Þ     A implementação individual que não esteja executando NÃO SERÁ CONSIDERADA - a inexistência de um executável para o subproduto da programação e testes ocasionará a nota zero para o responsável por sua implementação.

Þ     A implementação integrada que não esteja funcionando – a inexistência de um produto final executando ocasionará a perda de até quatro pontos, dependendo do motivo.

Þ     O esqueleto do produto final deve estar presente - a ausência total ou parcial do esqueleto ocasionará a perda de até dois e meio pontos.

Þ     Inexistência de problemas entre os requisitos estabelecidos na especificação e no projeto com relação ao que foi implementado - discordância entre implementação e a especificação ou o projeto ocasionarão perdas de nota, de acordo com a sua gravidade, até um total de dois pontos, devido à especificação, e dois e meio pontos, devido ao projeto.

Þ     Problemas na lógica de um módulo - problemas na lógica de um módulo ocasionarão perdas de nota, de até cinco pontos ao seu responsável, de acordo com a sua gravidade, por exemplo o uso de arquivos no meio do produto final (exceto quando se tratar de código proveniente do plano de testes), falta de inicialização de variáveis, código redundante, etc.

Þ     Deve-se incorporar comentários à codificação - a falta de comentários ocasionará a perda de até dois pontos.

Þ     Deve-se separar o código proveniente do projeto, daquele proveniente do plano de testes - a ausência de separação ocasionará a perda de dois e meio pontos.

Þ     Deve-se usar threads - de acordo com o estabelecido no esqueleto do projeto. A ausência de threads ocasionará a perda de dois e meio pontos.

Þ     Deve-se usar memória compartilhada - de acordo com o estabelecido no esqueleto do projeto. A ausência de memória compartilhada ocasionará a perda de dois e meio pontos.

Þ     Deve-se usar semáforos - de acordo com o estabelecido no esqueleto do projeto. A ausência de semáforos ocasionará a perda de dois e meio pontos.

Þ     O plano de testes e os resultados dos testes realizados através da execução do plano de testes e de integração devem ser entregues - a ausência de casos de teste e dos resultados dos testes ocasionará a perda de até quatro pontos.

Þ     A nota final – a nota final relativa aos RT não é o simples resultado das eventuais perdas de pontos correspondentes aos aspectos citados. Além destes, deseja-se que estes sejam de conhecimento e domínio por parte do aluno. As novidades tecnológicas desta disciplina são: o uso de threads em conjunto com diversos mecanismos de IPC, além das soluções para o problema de tratamento de arquivos multimídia.