(M)  s i s t e m a   o p e r a c i o n a l   m a g n u x   l i n u x ~/ · documentação · suporte · sobre

  Página seguinte Página anterior Índice

68. Construíndo um Sistema de Arquivos Raiz

Criar um sistema de arquivos raiz envolve a seleção dos arquivos necessários para que o sistema possa ser executado. Nesta seção descreveremos como construir um sistema de arquivos raiz compactado . Uma opção menos usual é a construção de um sistema de arquivos não compactados em um disquete, que é montado diretamente como raiz; esta alternativa é descrita na seção nonramdiskroot .

68.1 Visão Geral

Um sistema de arquivos raiz deve conter todo o necessário para suportar um sistema Linux completo. Para tanto, o disco deve incluir os requisitos mínimos de um sistema Linux:

  • A estrutura básica do sistema de arquivos
  • Conjunto mínimo de diretórios: /dev, /proc, /bin, /etc, /lib, /usr, /tmp
  • Conjunto básico de utilitários: sh, ls, cp, mv, etc.
  • Conjunto mínimo de arquivos de configuração: rc, inittab, fstab, etc...
  • Dispositivos: /dev/hd*, /dev/tty*, /dev/fd0, etc...
  • Biblioteca que disponibilize as funções básicas necessárias aos utilitário

Evidentemente, qualquer sistema somente torna-se útil quando permite a execução de algum programa, e um disquete raiz somente é útil quando permite que sejam executadas funções como:

  • Verificar um sistema de arquivos em outro dispositivo, por exemplo para checar o sistema de arquivos raiz em um disco rígido será necessário carregar o sistema operacional a partir de outro dispositivo, o que pode ser feito com um sistema de arquivos raiz em disquete. Pode-se então executar fsck no dispositivo original que contém o sistema raiz enquanto ele não estiver montado.
  • Restauração total ou parcial do dispositivo raiz original a partir de uma cópia de segurança usando arquivamento ou utilitários de compactação, tais como cpio, tar, gzip e ftape.

Descreveremos como construir um sistema de arquivos compactado, assim chamado porque é arquivado compactado no disco e é descompactado do disco para memória. Um sistema de arquivos compactado pode conter diversos arquivos (aproximadamente 2 megabytes) em um disquete padrão 1.440 Kb. Como o arquivo é muito maior que o disquete, não se pode construí-lo diretamente no dispositivo. Deve-se construí-lo em outro local qualquer, compactá-lo, e então copiá-lo para o disquete.

68.2 Criando o Sistema de Arquivos

Para construir-se um sistema de arquivos raiz, deve-se ter um dispositivo extra, grande o suficiente para conter todos os arquivos antes da compactação. Deve-se ter à mão um dispositivo capaz de conter pelo menos 4 Mb. Há diversas opções:

  • Usar um disco em memória (DEVICE = /dev/ram0). Neste caso a memória é utilizada para simular um dispositivo de disco, sendo que deve ser grande o suficiente para conter todo o sistema de arquivos em seu tamanho adequado. Caso se use o LILO, deve-se verificar o arquivo de configuração (/etc/lilo.conf) e buscar uma linha similar a :
            RAMDISK_SIZE = nnn
    
    RAMDISK_SIZE, parâmetro LILO o qual determina quanto de memória RAM será alocada. O padrão é 4096K, o qual deverá ser suficiente. Não se deve tentar utilizar esse disco em memória para máquinas com menos de 8 Mb de RAM. Verifique a existência de um dispositivo como por exemplo /dev/ram0, /dev/ram ou /dev/ramdisk. Caso não exista, crie /dev/ram0 com mknod (maior numero 1, menor 0).
  • Caso se tenha uma partição de disco rígido grande o suficiente (diversos megabytes) disponível, esta certamente será uma boa solução. Caso se tenha memória RAM disponível, pode-se desligar as funções de troca e utilizar a partição de troca (swap).
  • Usar uma simulacao de dispositivo , a qual permite que um arquivo em disco seja tratado como um dispositivo. O uso de uma simulação permite a criação de um arquivo de três megabytes no disco rígido e a construção do sistema de arquivos nele. Para fazer uso da simulação de dispositivos, deve-se utilizar os programas mount e unmount especialmente alterados para isso. Eles podem ser encontrados no diretório: ftp://ftp.win.tue.nl/pub/linux/util/mount/

    Caso não se tenha uma simulação de dispositivos (/dev/loop0, /dev/loop1, etc...) no sistema, pode-se criar uma através do comando ``mknod /dev/loop0 b 7 0''. Uma vez instalados os binários especiais de mount e umount , deve-se criar um arquivo temporário em um disco rígido com capacidade suficiente (por exemplo, /tmp/fsfile). Pode-se, por exemplo, utilizar o comando:

    dd if=/dev/zero of=/tmp/fsfile bs=1k count=nnn
    para criar um arquivo com nnn blocos.

    Deve-se utilizar então o nome do arquivo no lugar do DISPOSITIVO a seguir. Ao utilizar o comando mount deve-se incluir a opção``-o loop'' para definir uma simulação de dispositivo. Por exemplo:

            mount -o loop -t ext2 /tmp/fsfile /mnt
    

    irá montar /tmp/fsfile (através de uma simulação de dispositivo) no ponto de montagem /mnt. Através do comando df pode-se obter a confirmação disso.

Após a escolha de alguma dessas opções, deve-se preparar o DISPOSITIVO com o seguinte comando:

        dd if=/dev/zero of=DISPOSITIVO bs=1k count=3000

Este comando inicializa com zeros o DISPOSITIVO. Este passo é importante pois o sistema de arquivos será compactado posteriormente e as partes não utilizadas e preenchidas com zeros, atingirão o máximo de compactação.

Após, pode-se criar o sistema de arquivos. O kernel do Linux reconhece dois tipos de sistemas de arquivos para discos raiz a serem automaticamente copiados para discos em memória. Há o minix e o ext2, sendo o segundo o mais indicado. No caso de utilização do ext2, pode ser útil o uso da opção -i para especificar um número maior de inodes que o padrão do sistema; -i 2000 é o valor sugerido, garantindo-se assim que não faltarão inodes. Alternativamente, pode-se salvar inodes removendo-se os diversos arquivos dev desnecessários. mke2fs irá criar 360 inodes por padrão em um disquete 1.44. Cremos que 120 inodes são suficientes para um disco de emergência padrão, mas caso todos os dispositivos /dev sejam incluídos, então pode-se facilmente exceder os 360 disponíveis. Usar um sistema de arquivos raiz compactado permite um sistema de arquivos maior, provocando a utilização de um número de inodes maior que o padrão, porém pode ainda ser necessário reduzir o número de arquivos ou incrementar o número de inodes.

O comando necessário será algo similar a:

mke2fs -m 0 -i 2000 DISPOSITIVO

(Caso se esteja usando uma simulação de dispositivos, o arquivo em disco que se esteja utilizando deve ser informado no lugar do DISPOSITIVO. Neste caso o mke2fs perguntará se realmente se deseja executar o comando e a resposta deve ser positiva.)

O comando mke2fs automaticamente detectará o espaço disponível e fará a configuração automaticamente. O parâmetro -m 0 evita a alocação de espaço para o raiz, e adicionalmente provê mais espaço útil em disco.

A seguir deve-se montar o dispositivo:

        mount -t ext2 DISPOSITIVO /mnt

(Deve-se criar um ponto de montagem mnt caso ele ainda não exista). Nas próximas seções, todos os nomes de diretórios são assumidos como relativos a /mnt.

68.3 Ocupando o Sistema de Arquivos

Segue um razoável número mínimo de diretórios no sistema de arquivos raiz:

  • /dev Dispositivos, necessários para as operações de Leitura/Gravação
  • /proc Diretório temporário requerido pelo sistema de arquivos proc
  • /etc Arquivos de configuração do sistema
  • /sbin Binários fundamentais do sistema
  • /bin Binários básicos e considerados parte do sistema
  • /lib Bibliotecas compartilhadas que provêem suporte à execução dos binários
  • /mnt Um ponto de montagem para manutenção em outros discos
  • /usr Utilitários adicionais e aplicações

(A estrutura de diretórios aqui apresentada é somente para uso no disquete raiz. Sistemas Linux têm uma política mais complexa e disciplinada, chamada Padrões de Sistemas de Arquivos, para determinar quais arquivos devem estar presentes e aonde.)

Três destes diretórios devem estar vazios no sistema de arquivos raiz, devendo somente serem criados com o comando mkdir. O diretório /proc é basicamente um ponto de referência onde o sistema de arquivos proc está localizado. Os diretórios /mnt e /usr são somente pontos de montagem para uso após a inicialização do sistema e a carga do sistema de arquivos raiz. Mais uma vez, estes diretórios somente precisam ser criados.

Os quatro diretórios remanescentes estão descritos nas seções a seguir:

/dev

Um diretório /dev contendo um arquivo especial com todos os dispositivos a serem utilizados pelo sistema é fundamental para o Linux. O diretório em si é um diretório comum e pode ser criado com o comando mkdir da forma usual. Os arquivos especiais de dispositivos devem ser criados de uma forma especial, utilizando-se o comando mknod.

Há um atalho, podendo-se copiar o conteúdo do diretório /dev e apagando-se o que for desnecessário. A única exigência é que a cópia seja efetuada com a utilização do parâmetro -R. Isso copiará o diretório sem copiar o conteúdo dos arquivos. Esteja seguro de utilizar um R maiúsculo. Caso seja utilizado r em formato minúsculo, provavelmente será copiado o conteúdo completo de todo o disco rígido -- ou no mínimo, o que couber no disquete! De qualquer forma, é importante estar atento ao comando:

        cp -dpR /dev /mnt

Assumindo-se que o disquete esteja montado em /mnt. A opção dp garante que ligações simbólicas serão copiadas como ligações, ao invés de usar um arquivo de destino, e que os atributos originais do arquivo serão preservados, assim como as informações sobre os donos.

Alternativamente, pode-se usar o programa cpio com a opção -p, uma vez que o cpio lida com arquivos especiais corretamente, e não tentará copiar o seu conteúdo. Pode-se por exemplo, utilizar o seguinte comando:

cd /dev
find . -print | cpio -pmd /mnt/dev

o qual irá copiar todos os arquivos especiais de /dev para /mnt/dev. Na verdade, irá copiar todos os arquivos da árvore de diretórios iniciada em /dev, e criará todos os subdiretórios necessários na árvore de diretórios de destino.

Caso se deseje fazer da forma mais difícil, deve-se usar ls -l para mostrar os números maior e menor dos dispositivos desejados, e criá-los no disquete através do comando mknod.

Uma vez que os dispositivos estejam copiados, é aconselhável verificar se todos os arquivos de dispositivos necessários foram copiados no disco de emergência. Por exemplo, o ftape é utilizado por unidades de fitas, sendo necessário copiar todos eles, caso se pretenda acessar um dispositivo desse tipo a partir do disco de inicialização.

Note que um inode é necessário para cada tipo de arquivo especial de dispositivo, e podem, às vezes, serem um recurso escasso, especialmente em disquetes com sistemas de arquivos configurados. Desta forma é indicada a remoção de qualquer arquivo especial de dispositivos em /dev que não seja necessário no sistema específico. Por exemplo, caso não se tenha discos SCSI, pode-se tranqüilamente remover todos os arquivos de dispositivos começados por sd. Similarmente, caso não se pretenda utilizar portas seriais, então todos os arquivos começados com cua também podem ser removidos.

Deve-se necessariamente ter os seguintes arquivos neste diretório: console, kmem, mem, null, ram, tty1.

/etc

Este diretório deve conter uma série de arquivos de configuração. Na maioria dos sistemas este pode estar dividido em três grupos:

  1. Sempre requeridos, por exemplo rc, fstab, passwd
  2. Podem ser requeridos, mas não há como assegurar
  3. Arquivos desnecessários

Arquivos que não são essenciais podem ser identificados através do comando:

        ls -ltru

Este comando gera uma lista em ordem inversa de último acesso, dependendo de que arquivos não são acessados ou utilizados e que, podem não estar presentes no disquete raiz.

Nos nossos disquetes raiz, temos um número de arquivos de configuração inferior a 15. Isso reduz o trabalho de lidar com um conjunto de três tipos de arquivos.

  1. Os arquivos que devem ser configurados para um sistema:
    1. rc.d/* início do sistema e definição dos programas de cada nível de execução
    2. fstab lista dos sistemas de arquivos que devem ser montados
    3. inittab parâmetros para o processo init , o primeiro que é executado em tempo de inicialização do sistema.
  2. Estes devem ser customizados para a inicialização de um sistema:
    1. passwd lista de usuários, diretórios pessoais, etc...
    2. group grupos de usuários
    3. shadow senha dos usuários. Eventualmente pode não existir.
    Caso a segurança seja um item importante do sistema específico, passwd e shadow devem ser suprimidos, a fim de evitar a cópia de senhas de usuários para fora do sistema, e quando o sistema for inicializado através de disquetes, acessos indesejados serão rejeitados. De qualquer forma, há uma razão para não suprimir passwd e group. O tar (e provavelmente outros programas de arquivamento) armazenam o usuário e o grupo junto com os dados dos arquivos. Caso estes arquivos sejam restaurados no disco rígido a partir de uma fita, os arquivos serão restaurados com seus nomes originais. Caso os nomes dos donos e grupos não existam em passwd/group durante a restauração, as identificações de usuários e grupos (UID e GID) não estarão corretas. Esteja certo de que o arquivo passwd contém ao menos o superusuário (root). Caso se pretenda utilizar outros usuários para acessar o sistema, deve-se estar seguro da existência de seus diretórios pessoais e interpretadores de comando (shell).
  3. Os demais: verificaremos mais adiante as informações sobre este tópico.

Além disso, deve-se somente configurar dois arquivos, e o que eles devem conter é surpreendentemente pequeno.

  • rc deve conter
            #!/bin/sh
            /bin/mount -av
            /bin/hostname Conectiva
    
    Deve-se estar seguro de que os diretórios estão corretos. A execução de hostname não é obrigatória, somente dá um melhor acabamento ao trabalho.
  • fstab deve conter, no mínimo:
            /dev/ram0       /               ext2    defaults
            /dev/fd0        /               ext2    defaults
            /proc           /proc           proc    defaults
    
    Pode-se copiar as entradas de um arquivo fstab, já existente, mas não se deve montar automaticamente qualquer partição do disco rígido; usando-se então o parâmetro noauto, pois o disco rígido pode estar danificado ou sem condições de uso no momento da inicialização do sistema.

O inittab deve ser alterado, de outra forma a linha sysinit executará o rc ou qualquer outro programa básico de inicialização que seja indicado. Ainda para assegurar-se de que usuários em portas seriais não poderão acessar o sistema, pode-se comentar todas as entradas em getty que incluam dispositivos ttys ou ttyS ao final da linha. Deve-se deixar as portas tty para poder-se acessar o sistema a partir do console.

Um arquivo inittab mínimo contém:

        id:2:initdefault:
        si::sysinit:/etc/rc
        1:2345:respawn:/sbin/getty 9600 tty1
        2:23:respawn:/sbin/getty 9600 tty2

O arquivo inittab define o que o sistema executará nos vários estados, inclusive no seu início, em modo multiusuário, etc... Um ponto no qual deve-se ter muito cuidado é o de verificar se todos os comandos informados em inittab referem-se a programas presentes e se o diretório está corretamente indicado. Caso se coloque no disco de emergência os arquivos de comandos apresentados na Seção Listas de exemplo do conteúdo do disco de inicialização como um guia, e após se copie o inittab para o disco sem uma verificação cuidadosa, provavelmente ele falhará, e o problema terá origem na ausência de arquivos ou indicações erradas de diretórios.

Note que alguns comandos não podem ser movidos para qualquer outro lugar, porque têm a sua localização dentro de seu código. Por exemplo em nosso sistema, o /etc/shutdown tem a sua localização definida no fonte do comando /etc/reboot. Caso reboot seja movido para /bin/reboot, e após seja executado o comando shutdown, ele falhará, porque o arquivo reboot não pode ser localizado.

Para todo o restante, deve-se simplesmente copiar os arquivos texto no diretório /etc, mais os executáveis do mesmo diretório que não possam ser definidos como desnecessários. Como um guia, pode-se consultar os exemplos na Seção Listas de exemplo do conteúdo do disco de inicialização. Provavelmente será suficiente copiar somente aqueles arquivos, porém sistemas podem ser muito diferentes, então não se pode estar seguro de que a lista apresentada seja suficiente. O único método de estar seguro é iniciar o sistema com inittab e verificar o que é solicitado.

Muitos sistemas utilizam um diretório /etc/rc.d/ contendo roteiros do interpretador de comandos de diferentes níveis de execução. O mínimo é um simples programa rc, mas pode ser mais simples copiar o inittab e o diretório /etc/rc.d de um sistema já existente, e suprimir os roteiros no diretório rc.d para remover os processamentos não relevantes do ambiente de sistema em disquete.

/bin e /sbin

O diretório /bin é um lugar adequado para utilitários extras necessários à execução de atividades básicas. Utilitários como ls, mv, cat e dd.Veja o Apêndice Listagem de exemplo de conteúdo do disco de inicialização para um exemplo da lista de arquivos que podem estar presentes nos diretórios /bin e /sbin. Ela não inclui nenhum utilitário requerido para restaurar cópias de segurança, tais como cpio, tar e gzip. Isso porque estes programas foram colocados em um disquete de utilitários em separado, visando economizar espaço no disquete de inicialização e raiz. Uma vez que o disquete de inicialização tenha sido carregado, ele é copiado para o disco em memória, deixando a unidade de disquetes livre para montar outro disquete, o disquete de utilitários. Normalmente montamos esse disquete como /usr.

A criação de um disquete de utilitários é descrito na Seção Construindo um disquete de utilitários. É desejável manter uma cópia da mesma versão dos utilitários de cópias de segurança usados para gerar as cópias de segurança disponíveis, não perdendo-se tempo assim tentando-se instalar versões que não podem ler as cópias geradas.

Esteja seguro de incluir os seguintes programas: init, getty ou equivalente, login, mount, algum interpretador que possa executar os programas rc, e uma ligação de sh para o interpretador de comandos.

/lib

No diretório /lib deve-se colocar as bibliotecas compartilhadas e seus carregadores. Caso as bibliotecas necessárias não sejam encontradas no diretório /lib, o sistema não poderá ser iniciado. Com um pouco de sorte pode-se receber uma mensagem de erro dizendo a razão.

Praticamente todos os programas requerem no mínimo a biblioteca libc, libc.so.N, onde N é o número da versão corrente. Ao verificar o diretório /lib, libc.so.5 é normalmente uma ligação simbólica para um arquivo com o número completo da versão.

% ls -l /lib/libc.so*
lrwxrwxrwx  1 root root      14 Nov  1 20:34 /lib/libc.so.5 -> libc.so.5.4.33*
-rwxr-xr-x  1 root root  573176 Jun 12 02:05 /lib/libc.so.5.4.33*

Neste caso, tem-se disponível o arquivo libc.so.5.4.33. Para encontrar outras bibliotecas deve-se verificar todos os binários necessários e verficar as suas dependências com o comando ldd . Por exemplo:

        % ldd /sbin/mke2fs
                libext2fs.so.2 => /lib/libext2fs.so.2
                libcom_err.so.2 => /lib/libcom_err.so.2
                libuuid.so.1 => /lib/libuuid.so.1
                libc.so.5 => /lib/libc.so.5

O arquivo apresentado na coluna da direita é necessário, tendo-se em mente que as bibliotecas listadas podem ser ligações simbólicas.

Em /lib deve-se ainda incluir um carregador de bibliotecas. O carregador será ou o ld.so (para bibliotecas a.out) ou ld-linux.so (para bibliotecas ELF). Caso não se esteja seguro do que será necessário, deve-se executar o comando file na biblioteca. Por exemplo:

% file /lib/libc.so.5.4.33 /lib/libc.so.4.7.2
  /lib/libc.so.4.7.2: Linux/i386 demand-paged executable (QMAGIC), stripped
  /lib/libc.so.5.4.33: ELF 32-bit LSB shared object, Intel 386, version 1, stripped

QMAGIC indica que 4.7.2 é para bibliotecas a.out, e ELF indica que 5.4.33 é para ELF.

Deve-se então copiar o(s) carregador(es) necessário(s) para o sistema de arquivos raiz em construção. Bibliotecas e carregadores devem ser checados cuidadosamente com o binários incluídos. Caso o kernel não possa carregar a biblioteca necessária, normalmente haverá um travamento sem mensagens de erro.

68.4 Módulos

Caso se tenha um kernel modular, deve-se considerar quais módulos devem ser carregados a partir do disco de inicialização após o início do sistema. Pode-se incluir os módulos ftape e zftape caso cópias de segurança tenham sido feitas em um fita, módulos para dispositivos SCSI caso eles estejam presentes, e módulos para suporte a PPP ou SLIP caso se queira acesso a rede em uma emergência.

Estes módulos podem ser colocados em /lib/modules. Deve-se ainda incluir insmod, rmmod e lsmod.

Caso se deseje carregar os módulos automaticamente, pode-se incluir ainda modprobe, depmod e swapout. E caso se use o kerneld, deve-se incluir ainda o /etc/conf.modules.

A principal vantagem de utilizar módulos reside no fato de poder mover módulos não essenciais para um disco de utilitários e carregá-los quando necessário, usando menos espaço no disco raiz. Porém, caso seja necessário lidar com muitos dispositivos diferentes, uma abordagem mais adequada pode residir em construir um único kernel com diversos módulos integrados.

Note que para se ter um sistema de arquivos ext2 compactado, é obrigatória a existência de suporte a disco em memória e sistemas de arquivos ext2. Estes não podem ser disponibilizados como módulos.

68.5 Alguns detalhes finais

Alguns programas de sistema, como o login, apresentam mensagem de advertência caso o arquivo /var/run/utmp e o diretório /var/log não existam. Então:

        mkdir -p /mnt/var/{log,run}
        touch /mnt/var/run/utmp

Finalmente, após ter-se configurado todas as bibliotecas necessárias, deve-se executar o ldconfig para gerar novamente o /etc/ld.so.cache no sistema de arquivos raiz. O cache diz ao carregador onde encontrar as bibliotecas. Para reconstruir o ld.so.cache, execute os seguintes comandos:

        chdir /mnt; chroot /mnt /sbin/ldconfig

O comando chroot é necessário porque ldconfig sempre gera o cache para o sistema de arquivos raiz.

68.6 Empacotando

Uma vez concluída a construção do sistema de arquivos raiz, ele deve ser desmontado, copiado para um arquivo e compactado:

        umount /mnt
        dd if=DISPOSITIVO bs=1k | gzip -v9 > saraiz.gz

Isso pode levar diversos minutos. Ao finalizar estará disponível um arquivo saraiz.gz que é o sistema de arquivos raiz compactado. Deve-se verificar se o arquivo cabe em um disquete. Caso não caiba, deve-se retornar aos passos anteriores e eliminar alguns arquivos. A Seção Reduzindo o tamanho de um sistema de arquivos raiz fornece algumas dicas sobre a redução de tamanho do sistema de arquivos raiz.


Página seguinte Página anterior Índice