Discuta este tópico no fórum

Se este conteúdo te ajudou, deixe um presente!

domingo, 31 de março de 2013

OpenWRT: Expandindo o espaço do disco com unidade externa

O grande limitador de um roteador com OpenWRT não está no software que ele usa. Afinal de contas, rodando um Linux, é possível montar um servidor completo. O que restringe os usos do roteador são suas características fisicas, principalmente disco e memória. Processador também é um limitador importante para operações de tempo real, como streaming de conteúdo multimídia, mas pouco podemos fazer para melhorar o processador. Ao menos para o disco e a memória temos alguma alternativa. Sim, também é possível trocar os chips da placa por outros de maior capacidade, mas o que eu vou mostrar aqui é algo bem menos intrusivo.

Como já escrevi anteriormente, em imagens squashfs, OpenWRT divide o sistema de arquivos em duas partes: uma imagem base e as suas alterações. A primeira, chamada de "rom", é um sistema de arquivos completo, imutável, e somente é modificado na gravação de uma nova firmware. O usuário nem nota esta característica pois qualquer alteração efetuada nesta imagem são guardados em uma segunda área de disco, o chamado "overlay". O espaço livre do disco é, na verdade, o espaço disponível na "overlay". Seguindo esta estrutura, não adianta apagar coisas do disco que sejam provenientes da "rom" pois eles somente serão marcados como apagados e não serão liberados do disco.

Por padrão, o "kernel" e a "rom" dividem a flash do roteador e o que sobra fica para a "overlay". Quanto maior as duas primeiras, menos espaço "livre", e tudo isto em uma flash de 4 ou 8MB. O que vamos fazer é configurar o OpenWRT para usar uma unidade externa como a "overlay", expandindo o limite disponível.

O primeiro passo é escolher a unidade externa. No meu caso vai ser um pendrive antigo de 128MB, mas pode ser qualquer dispositivo de armazenamento USB. A configuração inicial é a mesma apresentada no último post. Se conectar o dispositivo e ele aparecer em /mnt ou no comando mount, você está pronto para a segunda etapa.

É bom ter uma configuração funcional antes de iniciar o processo. Caso você remova o disco externo, você terá seu roteador com esta configuração. Sugiro algo simples com a capacidade de acessar a internet.

A montagem automática funciona muito bem para dispositivos de uso eventual. Porém, como será um dispositivo permanente, o ideal é fixar algumas configurações. A primeira coisa a ser melhorada é o ponto de montagem. "/dev/sda5" não diz muito a quem está lendo e quando se trata de discos, é importante não errar a unidade. Também, se for conectada mais de uma unidade, a ordem que estes discos aparecem dependem da ordem de conexão. O primeiro será o sda, o segundo sdb e assim por diante. O ideal é a ordem dos discos não influencie. Para estas configurações, existe o arquivo "/etc/config/fstab". A entrada que nos interessa é a de montagem. Você pode ter quantas entradas destas desejar. No meu caso, terei 2: uma para a partição do HD externo e outra para a nova "overlay".

Atualizado em 2015-09-30: para versões mais novas (como a CC), o recomendado é gerar a configuração "/etc/config/fstab" com:

# block detect >/etc/config/fstab

Depois é só ajustar os valores (normalmente só o enable)

Existem três características que podem ser usadas para identificar um disco no OpenWRT (também suportadas em Linux "convencionais"): dispositivo, nome e uuid. O primeiro é o nome do arquivo que representa o dispositivo, em geral /dev/sd??. Como já comentei, este nome depende da ordem de conexão dos discos e deve ser evitado. A segunda forma, pelo nome, usa o nome ou rótulo dado ao sistema de arquivos, configurado na formatação ou posteriormente. Para partições ext2/3/4, o comando é o tune2fs. O terceiro é o uuid. Ele funciona como um identificador único e é gerado na criação do disco (tune2fs também pode alterá-lo). Se gerado aleatoriamente, é desprezível a possibilidade de conflito. Apesar da segurança do uuid, prefiro a contextualização que o nome me fornece. Estas propriedades dos discos podem ser visualizadas com o comando "blkid". Como usarei dois discos, foram adicionadas as seguintes linhas no meu arquivo /etc/config/fstab:
config mount
        option target   /mnt/usb-dados
        #option device  /dev/sda1
        option label    "usb-dados"
        #option uuid    "b7dc2020-b12a-431e-98d3-619a..."
        option fstype   ext4
        option options  rw,sync
        option enabled  1
        option enabled_fsck 0
config mount
        option target /mnt/extroot
        option label "openwrt-extroot"
        option fstype ext3
        option options rw,sync
        option enabled 1
        option enabled_fsck 0
Para registro, deixei intencionalmente as opções para apontamento por dispositivo e uuid. Porém, estas opções, por estarem comentadas, não serão lidas. Reiniciando o serviço fstab ou o roteador, você terá o disco identificado como usb-dados montado em /mnt/usb-dados e o nomeado "openwrt-extroot" em /mnt/extroot. O caminho deste segundo é temporário e logo será substituído.

Se as partições retornarem de um reboot montadas, é hora de migrar da "overlay" interna para a externa. O primeiro passo é configurar em  /etc/config/fstab a nova partição como a "overlay". E isto depende da versão que você está usando do OpenWRT. Para a versão 12.09, ainda em desenvolvimento, basta trocar onde antes era "/mnt/extroot", colocar "/overlay". Para a versão 10.04.1, backfire, é necessário instalar o pacote "block-extroot" adicionar a opção "option is_rootfs 1" e não alterar a opção target para "/overlay".

Agora basta popular a nova partição Copie os arquivos da "overlay" atual para a nova:
tar -C /overlay -cvf - . | tar -C /mnt/extroot -xf -
Lembre-se de ajustar o nome em negrito para o ponto de montagem em uso pela futura "overlay". Mas preciso usar o tar? É bom pois ele copia todos os atributos necessários e não sei se o cp do busybox faria melhor.

Se tudo der certo, só falta reiniciar. Antes, minhas montagem antes de reiniciar eram estas:
# mount
rootfs on / type rootfs (rw)
/dev/root on /rom type squashfs (ro,relatime)
proc on /proc type proc (rw,noatime)
sysfs on /sys type sysfs (rw,noatime)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime,size=30856k)
tmpfs on /dev type tmpfs (rw,noatime,size=512k,mode=755)
devpts on /dev/pts type devpts (rw,noatime,mode=600)
/dev/mtdblock3 on /overlay type jffs2 (rw,noatime)
overlayfs:/overlay on / type overlayfs (rw,relatime,lowerdir=/,upperdir=/overlay)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
none on /proc/bus/usb type usbfs (rw,relatime)
/dev/sda5 on /mnt/usb-dados type ext4 (rw,sync,relatime,user_xattr,barrier=1,data=ordered)
/dev/sdb1 on /mnt/extroot type ext3 (rw,sync,relatime,user_xattr,barrier=1,nodelalloc,data=ordered)
E com a nova "overlay" ficaram:
/dev/root on /rom type squashfs (ro,relatime)
proc on /proc type proc (rw,noatime)
sysfs on /sys type sysfs (rw,noatime)
tmpfs on /tmp type tmpfs (rw,nosuid,nodev,noatime,size=30856k)
tmpfs on /dev type tmpfs (rw,noatime,size=512k,mode=755)
devpts on /dev/pts type devpts (rw,noatime,mode=600)
/dev/sdb1 on /overlay type ext3 (rw,sync,relatime,user_xattr,barrier=1,nodelalloc,data=ordered)
overlayfs:/overlay on / type overlayfs (rw,relatime,lowerdir=/,upperdir=/overlay)
debugfs on /sys/kernel/debug type debugfs (rw,relatime)
/dev/sda5 on /mnt/usb-dados type ext4 (rw,sync,relatime,user_xattr,barrier=1,data=ordered)
none on /proc/bus/usb type usbfs (rw,relatime)
E, principalmente, o espaço livre:
# df -h
Filesystem                Size      Used Available Use% Mounted on
rootfs                  117.6M     13.7M     97.8M  12% /
(...)
Pronto! É espaço de sobra para instalar o que eu pretendo utilizar no roteador. Apesar de ser apenas 128MB, é muito mais do que os 6MB restantes da flash interna. Nos próximos posts, farei a configuração do samba, servidor de impressão e cliente torrent. Até mais e Feliz Páscoa.