Introdução aos Sistemas Operacionais Subsistema de Arquivos Eleri Cardozo FEEC/Unicamp Subsistema de Arquivos O subsistema de arquivos deve prover soluções para as seguintes questões: Como a informação presente nos arquivos é armazenada no dispositivo de armazenamento? Como o espaço físico do dispositivo de armazenamento é gerenciado? Como arquivos e diretórios são organizados? Como aumentar a eficiência de operações sobre arquivos e diretórios?
Subsistema de Arquivos Graças ao acionador de dispositivos o disco se apresenta ao sistema operacional como uma sequência contínua de blocos. 0 1 N-1 Blocos de disco são equivalentes a páginas de memória. Acionador de Dispositivo (Device Driver) Dispositivo físico de armazenamento Gerenciamento do Espaço Físico Um sistema de arquivos define como o dispositivo de armazenamento é organizado (seu layout). O Linux particiona o disco em grupos de blocos.
Organização de Aquivos Dado um arquivo identificado pelo seu nome, como identificar os blocos que armazenam os dados do arquivo? Soluções: FAT (File Allocation Table): Lista ligada onde cada nó da lista identifica um bloco. Solução factível para dispositivos de pequena capacidade (pen drivers, por exemplo). Inode: estrutura de dados que descreve o arquivo (nome, dono, permissões, blocos, etc.). Solução para discos de qualquer capacidade. Organização de Arquivos
Diretórios Diretórios são arquivos especiais que agregam arquivos e diretórios. Todo sistema de arquivo possui um diretório raiz especificado por / Um arquivo é identificado pelo seu caminho completo ou relativo. Exemplo de caminho completo: /usr/include/stdio.h Exemplo de caminho relativo: mylib.so Relativo a que? Ao diretório local (representado por.) A caminhos presentes em uma variável de ambiente, por exemplo, LD_LIBRARY_PATH. Diretórios (Ext2)
Diretórios (Ext2) Diretório contendo os arquivos a.tex e fig.jpg Mesmo diretório após remoção de a.tex Esquemas de Cache Os sistemas de arquivos empregam cache para otimizar o acesso ao disco. O cache (em memória) armazena os buffers que estão sendo utilizados pelos processos. Similar a paginação: quais buffers estão sendo utilizados? O sistema UNIX emprega um mecanismo denominado Cache de Buffers. Versões recentes do Linux integra cache de disco com paginação no Cache de Páginas.
O Cache de Buffers O Cache de Páginas
Sistema de Arquivos Mapeados em Memória O esquema de cache de páginas tem a vantagem de integrar o cache de disco e o sistema de paginação. Entretanto, apresenta uma desvantagem: Um mesmo conteúdo do disco pode estar armazenado em duas páginas físicas distintas, uma associada ao cache de páginas e outra associada ao espaço de endereçamento do processo. Uma solução para este problema são os arquivos mapeados em memória, mais precisamente, na memória virtual dos processos que os utilizam. Sistemas de Arquivos Mapeados em Memória #include <sys/mman.h> #include <sys/types.h> #include <sys/stat.h> #include <fcntl.h> int offset = 0; // inicio do arquivo void *mapping; // endereco do mapeamento int tamanho = 5000; // tamanho do arquivo // pode ser obtido com a chamada stat // abre arquivo int fd = open("database.txt", O_RDWR); if(fd > 0) { // mapeia em memoria mapping = mmap (NULL, tamanho. PROT_READ PROT_WRITE, MAP_SHARED, fd, offset); if(mapping!= MAP_FAILED) { // acessa o 100-esimo byte do arquivo char c = *(char*)(mapping + 100);... } }
Sistemas de Arquivos Mapeados em Memória Área de Dados Arquivo mapeado acesso ao arquivo acesso à memória Área de Texto Virtual File System
Journaling Sistemas de arquivos atuais como o ext4 do Linux e NTFS do Windows empregam um conceito denominado journaling (diário). Um sistema que emprega este conceito mantém um log das alterações no sistema de arquivos que é utilizado na recuperação do sistema de arquivos após uma pane do sistema. É importante notar que journaling não torna o sistema de arquivos imune a falhas, apenas aumenta sua robustez, propiciando uma restauração mais rápida após uma pane. Basicamente, journaling pode gravar em log os metadados e/ou os dados de um arquivo. Podemos entender metadados como as informações sobre um arquivo como aquelas presentes no seu inode. Journaling Antes de alterar um arquivo o sistema pode gravar em log o conteúdo de seu inode. Caso uma pane ocorra no momento que o inode esteja sendo modificado, o sistema pode recuperar seu último estado consistente do log. Mesmo com o log de metadados, perdas de dados podem acontecer caso a pane ocorra antes da sincronização entre o cache de páginas e o disco. Esquemas mais tolerantes a falhas podem gravar em log não apenas os metadados, mas também os dados de um arquivo. Apesar de minimizar a perda de dados, este esquema degrada o desempenho do sistema e requer um extenso espaço em disco para o armazenar o log.
RAID RAID (Redundant Array of Independent Disks) utiliza mais de um disco para fins de aumento de eficiência e confiabilidade. Existem sete formas de utilização destes discos, denominadas RAID nível 0 até RAID nível 6. Eficiência é obtida via paralelismo: a informação é distribuída por vários discos e acessada em paralelo. Confiabilidade é obtida via redundância da informação armazenada. Alguns sistemas RAID requerem hardware dedicado, por exemplo, com capacidade de leitura/escrita sincronizada em vários discos. Exemplo: RAID 1 e 5 Bloco 1 Bloco 1 Bloco 2 Bloco 2 Bloco 3 Bloco 3 Faixa 1 Faixa 3 Paridade Faixa 2 Paridade Faixa 5 Paridade Faixa 4 Faixa 6
RAID 1 no LINUX RAID nível 1 é também denominado espelhamento de disco. No Linux, RAID 1 é configurado no arquivo /etc/raidtab: raiddev /dev/md0 raid-level 1 nr-raid-disks 2 nr-spare-disks 0 persistent-superblock 1 device /dev/sdb6 raid-disk 0 device /dev/sdc5 raid-disk 1 Verificadores de Consistência Verificadores de consistência são programas que inspecionam o sistema de arquivos em busca de inconsistências, promovendo, inclusive, a sua reparação quando possível. Estes programas varrem o superbloco, inspecionando cada bloco livre e, a partir dos inodes, cada bloco utilizado pelos arquivos. O programa mantém um vetor de blocos livres e um vetor de blocos em uso. A i-ésima posição no vetor de blocos livres tem o valor um se o bitmap de blocos indica que o bloco está livre, ou zero caso contrário. A i-ésima posição no vetor de blocos ocupados é incrementada toda a vez que o bloco estiver associado com um arquivo (inode).
Verificadores de Consistência Ao final, cada posição nestes vetores é confrontada. Pode haver quatro situações: 1. Um bloco possui valor um em um vetor e zero no outro (situação de consistência para o bloco). O sistema de arquivos é considerado consistente se esta condição é satisfeita para todos os blocos. 2. Um bloco possui valor zero nas duas listas (bloco perdido). A correção é marcar o bloco como livre no bitmap de blocos livres do superbloco. 3. Um bloco possui valor um nas duas listas. A correção é marcar o bloco como em uso no bitmap de blocos livres do superbloco. 4. Um bloco possui valor maior que um na lista de blocos em uso. Neste caso, dois ou mais arquivos estão utilizando o mesmo bloco. A correção é desmembrar o bloco, alocando um novo bloco para cada arquivo que o utiliza. Note que os arquivos que utilizam este bloco podem estar inconsistentes pois o bloco pode ter sido sobrescrito por estes arquivos. RAM Disks Alguns sistemas operacionais como o Linux permitem criar arquivos em memória (física ou virtual). No primeiro caso o sistema de arquivos é denominado ramfs (RAM file system) e no segundo caso tmpfs (temporary file system). Em ambos os casos o sistema de arquivos é criado no cache de páginas. O sistema de arquivos ramfs trava as páginas que utiliza em memória impedindo que as mesmas sofram permuta. O mesmo não ocorre com o sistema de arquivos tmpfs cujas páginas que utiliza não são travadas em memória. Para criar um sistema de arquivos tipo ramfs ou tmpfs utiliza-se o comando mount: mount -t ramfs -o size=100m ramfs /mnt/ram mount -t tmpfs -o size=20m tmpfs /mnt/tmp