Discuta este tópico no fórum

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

quinta-feira, 16 de março de 2017

OpenWRT/LEDE: Debugando código dentro do roteador (e corrigindo bugs)

Mais um artigo da série OpenWRT/LEDE.

Fazer o debug de um programa muda a forma de desenvolvimento de um código. É imensamente melhor do que usar printf ao longo do código. Você pode ver os valores de qualquer variável, adicionar paradas condicionais, ver onde ele engasgou, etc. Para tudo isto, basta compilar seu código com os símbolos de debug, acesso ao código fonte (ajuda) e um debugger.

Uma das coisas que eu acho fantástico no mundo Linux é, diante de um problema, instalar os símbolos, código fonte e disparar um debugger. Isto com o processo rodado! Apesar dos programas instalados não conterem os símbolos, normalmente a distribuição fornece estes símbolos em um pacote a parte. Eu parto de um processo problemático em execução para um passo a passo dentro do código em poucos minutos. Fantástico!

Agora voltamos ao tema do artigo: como posso "debugar" dentro do OpenWRT/LEDE? Temos os símbolos nos executáveis? Não, são removidos antes de serem empacotados pelo sstrip. Mesmo que não fossem, normalmente você não teria espaço no roteador para instalar um executável com os símbolos de debug e mais o código fonte (ao menos que tenha expandido o disco com uma unidade externa). O gdb seria até pequeno, mas é sem símbolos e o fonte ele não tem muita utilidade. Mesmo se tivesse tudo isso, ainda debugar pelo gdb remotamente não é a forma mais amigável para este trabalho. Para coisas maiores, uma interface gráfica pode deixar o trabalho mais agradável.

Felizmente o OpenWRT/LEDE já está preparado para esta interação. Vamos tomar como exemplo o sane-backends, pacote que mantenho no OpenWRT/LEDE. Ele estava com um comportamento engraçado. O scanner aparecia na listagem mas sempre falhava ao escanear. Rodando localmente um escaneamento, eu obtinha:
root@router.lan3:~# scanimage >/dev/null
Trace/breakpoint trap
Parei o xinetd (que estava aguardando pelos pedidos do saned) e rodei o saned em modo debug. Novamente, o famigerado erro:
root@router.lan3:~# saned -d 128

[saned] main: starting debug mode (level 2)
[saned] saned (AF-indep+IPv6) from sane-backends 1.0.25 starting up
[saned] do_bindings: [0] bind failed: Address in use
[saned] check_host: access by remote host: ::ffff:192.168.3.20
[saned] init: access granted to luizluca@::ffff:192.168.3.20
Trace/breakpoint trap
Não fui apresentado, mas pelo nome, parece algo explicitamente introduzido. Alguma verificação falhou e abortou o programa. Sem mais informações por meio de mensagens, resta o debug do código.

O primeiro passo é ter os fontes e os códigos compilados. Provavelmente tudo isso se aplica caso opte por usar o SDK, mas vou, a princípio considerar que você está usando a árvore completa do projeto. Você precisa dos fontes e configurar o ambiente para compilar, ao menos, o sane-backend. Esta preparação já foi feita em outro artigo sobre compilação a partir dos fontes.

No roteador, eu irei debugar o programa saned, que não contém informações de debug. No pacote, ele é bem reduzido (menos que 33 kbytes):
$ tar --to-stdout -xzf bin/packages/mips_24kc/packages/sane-daemon_1.0.25-2_mips_24kc.ipk ./data.tar.gz | tar tzv ./usr/sbin/saned

-rwxr-xr-x root/root     32900 2017-03-12 22:40 ./usr/sbin/saned
Porém, antes de ser limpo pelo sstrip, ele tinha:
$ stat -c "%A %U %G %y %s %n" staging_dir/target-mips_24kc_musl-1.1.16/root-ar71xx/usr/sbin/saned
-rwxr-xr-x luizluca deluca 2017-03-12 22:40:49.510354194 -0300 44200 staging_dir/target-mips_24kc_musl-1.1.16/root-ar71xx/usr/sbin/saned
Agora vamos recompilar o pacote com os símbolos. Você pode fazer isso adicionando a opção no menuconfig para incluir os símbolo de debug em toda a árvore. Eu prefiro adicionar pontualmente os símbolos em alguns pacotes. Para isto, basta incluir a configuração extra na chamada do make:
$ make -j5 package/sane-backends/{clean,compile} CONFIG_DEBUG=y
Adicione ainda um V=s se quiser ver muitas letrinhas passando (ou precisar resolver problemas de compilação). Se fizer, observe um -g3 a mais nos argumentos do gcc.

O resultado é um executável relativamente maior:
$ stat -c "%A %U %G %y %s %n" staging_dir/target-mips_24kc_musl-1.1.16/root-ar71xx/usr/sbin/saned -rwxr-xr-x luizluca deluca 2017-03-12 23:56:52.157169597 -0300 188296 staging_dir/target-mips_24kc_musl-1.1.16/root-ar71xx/usr/sbin/saned
Mas o ipkg continua exatamente igual, pois os símbolos ainda foram removidos antes do empacotamento.

No meu caso, uso o driver hplip. Então, incluí em todo o processo anterior este pacote. Além de adicionar no menuconfig, o make ficou assim:
$ make -j5 package/{sane-backends,hplip}/clean package/{sane-backends,hplip}/compile CONFIG_DEBUG=y
Tudo pronto, agora vamos ao roteador. Vou instalar o gdbserver. Como o nome já diz, é um servidor do gdb, permitindo que um gdb na minha máquina use um executável rodando em uma máquina remota.
root@router.lan3:~# opkg install gdbserver
E agora, repito o comando do saned mas pelo gdbserver:

root@router.lan3:~# gdbserver :9000 /usr/sbin/saned -d 128Process /usr/sbin/saned created; pid = 4391Listening on port 9000
A princípio, ele inicia o processo parado, aguardando a conexão do gdb e sua autorização para continuar. No lado do computador, o OpenWRT/LEDE já fornece um "facilitador" para configurar o gdb remoto:
$ ./scripts/remote-gdb router:9000 staging_dir/target-mips_24kc_musl-1.1.16/root-ar71xx/usr/sbin/saned
Pronto! Estou com o debugger na mão. Peço ao gdb para parar ao receber qualquer sinal ("catch signal all"). Depois, libero a execução ("cont") até chegar em algo interessante.
Thread 1 "saned" hit Catchpoint 1 (signal SIGTRAP), memcpy (__n=270, __os=0x77dc3a76 <ms+770086>, __od=0x77dc3a74 <ms+770084>)    at /home/luizluca/prog-local/lede/17.01/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/include/fortify/string.h:4848 __builtin_trap();
(gdb) bt#0  memcpy (__n=270, __os=0x77dc3a76 <ms+770086>, __od=0x77dc3a74 <ms+770084>) at /home/luizluca/prog-local/lede/17.01/staging_dir/toolchain-mips_24kc_gcc-5.4.0_musl-1.1.16/include/fortify/string.h:48#1  device_id (fd=1,     buffer=0x77dc3a74 <ms+770084> "\001\020MFG:HP;MDL:Officejet J4660 series;CMD:MLC,PCL,PML,DW-PCL,DESKJET,DYN;1284.4DL:4d,4e,1;CLS:PRINTER;DES:CB786A;SN:BR145GF09J052W;S:038000C484001021002c1f0005cc2d8002b;J:", ' ' <repete 20 vezes>, ";Z:0102,050"..., size=1024) at io/hpmud/musb.c:773#2  0x77cbe5cd in musb_open (pd=<optimized out>) at io/hpmud/musb.c:1160#3  0x77cb8067 in hpmud_open_device (uri=<optimized out>, iomode=HPMUD_DOT4_MODE, dd=0x41b0a4) at io/hpmud/hpmud.c:539#4  0x77ebbc51 in sclpml_open (device=0x418a96 "/usb/Officejet_J4660_series?serial=BR145GF09J052W", pHandle=0x7ffffaf4) at scan/sane/sclpml.c:2016#5  0x77eb02f7 in sane_hpaio_open (devicename=0x418a96 "/usb/Officejet_J4660_series?serial=BR145GF09J052W", pHandle=0x7ffffaf4) at scan/sane/hpaio.c:267#6  0x77f3f673 in sane_dll_open (full_name=<optimized out>, meta_handle=0x0) at dll.c:1201#7  0x77f31e97 in sane_open (name=<optimized out>, h=<optimized out>) at dll-s.c:23#8  0x00403391 in process_request (w=0x418198 <wire>) at saned.c:1916#9  0x00403a99 in handle_connection (fd=<optimized out>) at saned.c:2283#10 0x00402031 in run_standalone (argv=<optimized out>, argc=3) at saned.c:3167#11 main (argc=<optimized out>, argv=<optimized out>) at saned.c:3345

Hum... fortify... O LEDE introduziu opções de compilação que restringem alguns comportamentos inseguros (_FORTITY_SOURCE), "fortificando" o programa contra ataques. Pela pilha, isso foi dentro do hplip. Acho que ele tem algum problema...

A chamada em questão foi em io/hpmud/musb.c, linha 773:

 771     if (len > 2)
 772         len -= 2;
 773     memcpy(buffer, buffer+2, len);    /* remove length */
 774     buffer[len]=0;
 775     DBG("read actual device_id successfully fd=%d len=%d\n", fd, len);

Opa! Copiando o buffer sobre ele mesmo para tirar os dois primeiros bytes? OK, mas não usando memcpy! Muito feio! Isto nunca era para dar certo... O memcpy simplesmente copia de um lado para outro, desconsiderando sobreposição. Isto quer dizer, pode copiar do começo ao fim (ou o inverso), em blocos de vários bytes, etc. Foi sorte ter funcionado até agora (e funcionou?). A alternativa correta é o memmove, que verifica possíveis sobreposições e decide se copia de trás para frente, ou do início ao fim. Caso não tenha sobreposições, simplesmente chama o memcpy. E  claro que temos sobreposições aqui!

Vamos tentar a última versão 3.16.11 do hplip? Não, ainda está lá o memcpy. Vamos precisar fazer um patch.

A melhor forma de trabalhar com patches dos programas empacotados no OpenWRT/LEDE é pelo quilt. Ele gerencia os patches de forma menos dolorida, em especial para atualizar os endereços depois de uma mudança de versão, onde os "hunks" funcionaram. Como acabei de atualizar a versão do hplip, devem ocorrer mudanças nos fontes e os patches existentes precisam ser atualizados:
$ make package/hplip/{clean,prepare} QUILT=y
$ cd build_dir/target-mips_24kc_musl-1.1.16/hplip-3.16.11
$ quilt push
Aplicando caminho 010-libusb_fix.patch
patching file configure.in
Hunk #1 succeeded at 561 (offset 38 lines).
Agora no caminho 010-libusb_fix.patch
 
$ quilt refresh # atualizar o endereço do patch
Patch atualizado 010-libusb_fix.patch
Tudo certo até aqui. Patch atualizado sem esforço.
$ quilt push
Aplicando caminho 020-remove_cups_dep_on_scan.patch
patching file scan/sane/hpaio.c
Hunk #2 FAILED at 172.
Hunk #3 FAILED at 232.
Hunk #4 FAILED at 259.
3 out of 4 hunks FAILED -- rejects in file scan/sane/hpaio.c
patching file Makefile.am
Hunk #1 succeeded at 60 with fuzz 1 (offset 1 line).
Caminho 020-remove_cups_dep_on_scan.patch não aplica (force com -f)
Hum... conflito. Preciso intervir manualmente.
$ quilt push -fAplicando caminho 020-remove_cups_dep_on_scan.patchpatching file scan/sane/hpaio.cHunk #2 FAILED at 172.Hunk #3 FAILED at 232.Hunk #4 FAILED at 259.3 out of 4 hunks FAILED -- saving rejects to file scan/sane/hpaio.c.rejpatching file Makefile.amHunk #1 succeeded at 60 with fuzz 1 (offset 1 line).Caminho 020-remove_cups_dep_on_scan.patch aplicado (forçado; necessita ser atualizado)
$ quilt edit scan/sane/hpaio.c<faz a mágica para resolver o conflito...>$ quilt refresh
Agora vamos, enfim, fazer o novo patch:
$ quilt new 030-replace_unsafe_memcpy_with_memmove.patch$ quilt edit io/hpmud/musb.c<troca o memcpy por memmove>$ quilt refresh
De volta a raiz do projeto, pedimos que ele atualize os patches: 
make package/hplip/update QUILT=y
E, por fim, limpar e recompilar:
make package/hplip/{clean,compile} CONFIG_DEBUG=y
Tudo compilado, só copiar, instalar e testar

$ scp bin/packages/mips_24kc/packages/hplip-* root@router:/tmp
root@router.lan3:~# opkg install /tmp/*hplip*
Upgrading hplip-common on root from 3.15.7-1 to 3.16.11-1...
Upgrading hplip-sane on root from 3.15.7-1 to 3.16.11-1...
Configuring hplip-common.
Configuring hplip-sane.
root@router.lan3:~# 
E...

Funcinou!


Infelizmente, o "funcionar" é não mostram uma mensagem de erro e não abortar o processo. Não faz muito sentido colar a saída.

Agora, para a cereja do bolo, bug submetido ao hplip.

Até a próxima. Happy Hacking!

domingo, 12 de março de 2017

OpenWRT/LEDE: Compilando a partir dos fontes

Mais um artigo da série OpenWRT/LEDE.

Dificilmente alguém vai precisar compilar o seu sistema operacional. Isto se aplica também aos ambientes embarcados. O OpenWRT/LEDE fornece o acréscimo de programas por pacotes, a personalização dos pacotes de uma firmware, ou mesmo um ambiente de desenvolvimento para compilar pacotes individuais. Tudo isso evita em muito a necessidade de recompilar todo o ambiente. Todavia, às vezes é inevitável.

Sempre que a mudança não é em "um pacote", vai precisar recompilar a árvore. Mudança de um parâmetro do kernel? Parâmetro do gerenciador de boot? Alguma outra coisa? Pode se preparar para recompilar tudo. E tudo é bastante coisa. O ambiente não só recompila o que vai no roteador mas compiladores, ligadores, ferramentas de geração de firmware, sistema de arquivos, etc. Tudo para ser o mais independente possível do sistema operacional onde está sendo compilado.

Como eu começo? Primeiro precisa de algumas ferramentas básicas, como o git, o gcc (para compilar o gcc do OpenWRT/LEDE, o make e algumas bibliotecas de desenvolvimento para compilar o menuconfig. Já existem algumas linhas de comando prontas para instalar estes requisitos no site do LEDE. Vale a olhada. Depois, só baixar os fontes. Vou pegar o atual ramo estável do LEDE:
git clone --branch lede-17.01 https://github.com/lede-project/source.git
E depois configurar o ambiente:
make menuconfig
No menuconfig, você pode configurar todo seu ambiente. Normalmente você terá que configurar, ao menos, o alvo (target) e, preferencialmente, o modelo do roteador (por padrão, ele gera firmware para todos!). Este é o local para adicionar os pacotes. A simbologia é:
  • [*] significa que o pacote estará na firmware gerada ou uma opção foi selecionada;
  • [M] significa que o pacote será gerado (ipk) mas não estará na firmware;
  • [ ] significa que o pacote não será compilado ou opção não selecionada.
Saindo e salvando, basta compilar:
make
Ou, se tiver processadores sobrando, deixar o make usar diversos processadores:
make -j9
Não achei no menu um pacote! Busque apertando "/" no menuconfig. Ainda não o Luci! A maioria dos pacotes estão nos feeds adicionais, por padrão sem pacotes incluídos. Para incluir o "meu-pacote-querido":
./scripts/feeds update
./scripts/feeds install meu-pacote-querido
E ele aparecerá no menu (previamente ainda não selecionado).

Ao terminar o processo do make, sua firmware estará em:
  • bin/targets/<alvo configurado>/generic/
Os pacotes estarão em:
  • bin/targets/<alvo configurado>/generic/packages/ (para os específicos deste alvo)
  • bin/packages/<arquitetura>/luci (para pacotes da arquitetura que o <alvo configurado> pertence)
Você está pronto para se divertir. Só gravar a nova firmware ou copiar e instalar os novos pacotes.

Quer mudar algo depois? Mexer em um pacote? As receitas estarão em packages ou em feeds. Se mudar um pacote, como o sane-backends, pode recompilá-lo individualmente:
make package/meu-pacote-querido/compile
Ou rodar simplesmente o make geral e deixar ele encontrar o que falta fazer (vai demorar mais). Se tiver problemas, pode mostrar as informações da compilação:
make package/meu-pacote-querido/compile V=s
É isso pessoal. Espero que esta informação ajude nos primeiros passos de desenvolvimento do OpenWRT/LEDE. Quem sabe não ajude a revelar um novo desenvolvedor para o projeto?

Happy hacking!

quinta-feira, 2 de março de 2017

OpenWRT/LEDE: atualizando para LEDE 17.01.0

Mais um artigo da série sobre o OpenWRT/LEDE.

Como citei no post anterior, o sucessor do OpenWRT é o LEDE. E este acaba de lançar a sua primeira versão: 17.01.0.

Sim, este artigo repete diversos pontos do artigo de atualização anterior. Afinal, apesar da mudança no nome, ainda é a mesma base.

96,72% dos problemas com instalação/atualização com LEDE que ajudo é em relação a escolha incorreta da imagem da firmware. Como sempre, recomendo a versão squashfs, que possui modo de recuperação. Pegue o arquivo no download da última versão estável e nunca em um endereço qualquer, mesmo que seja na wiki do OpenWRT/LEDE. Normalmente a wiki referencia a versão em desenvolvimento, que não é a que você quer. As versões dentro de "releases", exceto as com o rc (release candidate) são estáveis. Pegue preferencialmente a mais nova (com número maior). Evite qualquer firmware que tenha no caminho palavras como "trunk", "snapshot" ou "rc1", "rc2"... exceto se estiver testando algo. As versõe estáveis também referenciam a versão do LEDE no nome como em "lede-17.01.0-r3205-59508e3-ar71xx-generic-tl-wr2543-v1-squashfs-sysupgrade.bin", ao contrário da versão instável/em desenvolvimento "lede-ar71xx-generic-tl-wr2543-v1-squashfs-sysupgrade.bin".

A nomeclatura da versão é parecida com a adotada pelo OpenWRT: ano.mês.correção. O ano/mês se referem ao momento que foi criado um ramo nos fontes para o lançamento da nova versão. Já o último número é apenas um sequencial de correção. Então, para quem usa uma versão 17.01.x, a próxima 17.01.x+1 conterá apenas bugs resolvidos (em especial, os de segurança) e deve ser considerada como recomendada. Prometeram lançar versões de correções periodicamente. Vamos acompanhar

Em downloads, navegue para releases, a versão desejada (17.01.0 até agora), "targets"  e seguindo o caminho da "arquitetura alvo" em uso no seu roteador. Se você já é um usuário do OpenWRT, você pode vê-la olhando o arquivo /etc/openwrt_release:
root@router:~~# cat /etc/openwrt_release
DISTRIB_ID='OpenWrt'
DISTRIB_RELEASE='15.05'
DISTRIB_REVISION='r46767'
DISTRIB_CODENAME='chaos_calmer'
DISTRIB_TARGET='ar71xx/generic'
DISTRIB_DESCRIPTION='OpenWrt Chaos Calmer 15.05'
DISTRIB_TAINTS=''
A diferença no LEDE para o OpenWRT é a presença do "targets" e, no mesmo nível, "packages". Comentei esta diferença no post anterior, mas normalmente o "packages" não é para você e será usado quase que exclusivamente pelo opkg de forma transparente.

OK, chegamos a uma lista enorme de firmwares! Vamos entender o que significa cada parte do nome do arquivo. O formato mudou um pouco no LEDE. Tomemos por exemplo "lede-17.01.0-r3205-59508e3-ar71xx-generic-tl-wr2543-v1-squashfs-sysupgrade.bin":
  • lede é o sistema operacional que você está instalando ;-)
  • 17.01.0 é a versão do lede. Em firmwares instáveis, este campo não existe!
  • r3205 é um sequencial do número de mudanças no fonte. Serve para saber se um arquivo é mais velho do que outro.
    • Caso apareça algo a mais como r3205+2, significa que alguém deve ter feito 2 mudanças não oficiais sobre a versão r3205.
  • 59508e3 é a versão resumida do hash da última mudança no git. Você pode usar comandos git sobre ela nos fontes do LEDE como "git log 59508e3".
  • ar71xx é a família do SoC (chip) do seu dispositivo. Você descobre isso na wiki do projeto ou abrindo o seu roteador e lendo os CI.
  • generic é o formato do layout da flash. Normalmente será o "generic", exceto para casos especiais.
  • tl-wr2543-v1 este é o modelo do seu roteador! Observe em especial a versão do HW (v1) pois ela pode mudar completamente o dispositivo, inclusive de família do SoC.
  • squashfs é o tipo do armazenamento da imagem. Nesta, existe uma cópia imutável dos arquivos (ROM) e o resto da flash é usada para, de forma transparente, guardar as modificações (overlay). Tudo parece editável para o usuário. A diferença é que você pode, a qualquer momento, apagar as diferenças e restaurar o sistema pós-instalação. Pode existir também o formato jffs2. Neste, não existe uma ROM e tudo pode ser realmente apagado. Alterou o arquivo errado? Vai ter que recuperar pela serial, JTAG ou arrancando a flash. Não recomendo!\
  • sysupgrade é a função da firmware. Esta é para atualizar de um OpenWRT/LEDE para outro (e, em alguns casos, de outros firmwares alternativos como DD-WRT). Porém, não deve ser reconhecido pela firmware original do roteador. Para primeira instalação, ainda com a firmware original, use a variante "factory".
Finalmente, é muito importante ler a wiki do seu roteador independente se ele já funcionava na versão anterior! São poucos minutos de leitura que podem salvar horas de trabalho ou mesmo seu roteador. Durante esta fase de OpenWRT e LEDE, sugiro que procurem na wiki de ambos os projetos.

Bem, se eu simplesmente ir na interface, fornecer a nova imagem, ele vai funcionar? Provavelmente, mas talvez não é a maneira que dê menos trabalho. A atualização pode preservar as configurações mas não os programas instalados. Se você tem raiz expandida em unidade externa, a encrenca é ainda maior.

Mas eu nunca instalei um programa! OK, use a interface web e provavelmente todas as configurações serão migradas sem problemas. Já testei isto em mais de um roteador e funcionou sem problemas. Mas faça o backup antes! Caso tenha instalado algum pacote, continue lendo.

Em primeiro lugar, precisamos do plano de retorno caso a nova versão não se comporte como o esperado. Faça sempre um backup geral do seu sistema. No processo de upgrade, eu sugiro que sejam feitas as três formas diferentes de backup que eu comento no artigo sobre o temabackup gerado pelo sistema, lista de pacotes instalados e todos os arquivos do overlay. Este último serve apenas para o plano de retorno caso algo importante não funcione para você na nova versão (e para recuperar algo que não entrou no backup do sistema).

Agora, finalmente, você está pronto para enviar a nova firmware. Se você usa um armazenamento externo para expandir a raiz, leia até o final deste post antes de iniciar o processo! Faça o upgrade pela interface web ou pelo terminal. Inclusive, você pode baixar o arquivo diretamente no roteador. Ex:

# cd /tmp
# wget http://downloads.lede-project.org/releases/17.01.0/targets/.../generic/lede-17.01.0-r3205-59508e3-....-squashfs-sysupgrade.bin
# sysupgrade lede-17.01.0-r3205-59508e3-....-squashfs-sysupgrade.bin

Só cuidado ao colar a URL. O downloads.lede-project.org usa HTTPS por padrão mas o wget do OpenWRT não tem suporte para HTTPS (por padrão). Contudo, o downloads.lede-project.org aceita http sem problemas, só tirar o "s" se tiver problemas.

E pode fazer pela Wifi? Os fabricantes não recomendam usar sempre um computador "conectado por cabo"? Sim, e já tive problemas com atualização a partir da firmware do fabricante por não escutar isto. Mas não com OpenWRT/LEDE. Se estiver atualizando (e não instalando a primeira vez!), pode fazer pela Wifi sem problemas. Quando a gravação for iniciada, todo o processo já está independente do computador cliente. Só não pode faltar energia ;-)

E depois do "Enter"/"Gravar", é a hora que você reza. Sempre dá um frio na barriga.

Se optar por preservar as configurações, tudo que seria guardado em um backup do sistema (listado pelo "sysupgrade -l") será restaurado. Se você instalou algum pacote e guardou a lista do que foi instalado (lembra que eu sugeri há alguns parágrafos atrás?), esta é a hora que você reinstala os pacotes desejados. Se for instalar manualmente, procure instalar os pacotes de mais alto nível (ex: "luci-app-minidlna" antes de "minidlna"), pois eles irão, por dependência, baixar os pacotes requeridos. No final do processo, é bom refazer a listagem do que está instalado e comparar com o que você tinha na versão anterior.

Podem ser criados arquivos sufixados com "-opkg" em /etc/. Este são arquivos de configuração originais do pacote e são criados pois você modificou algo na configuração. Sugiro que verifique se não existe alguma coisa introduzida neste pacote que deveria ser adicionada no seu arquivo de configuração. Eu gosto do diff ou do "vim -d" para este trabalho comparando o arquivoconf com arquivoconf-opkg. Ao final do processo, eu gosto de apagar qualquer -opkg para deixar claro que apliquei tudo que queria.

As atualizações de segurança serão disponibilizadas por meio de atualização de pacotes (exceto as que exijam mudar o kernel). Para listar os pacotes atualizáveis:

# opkg update
# opkg list-upgradable

O maior problema é que estas atualizações de segurança, quando de pacotes embutidos oriundas na firmware instalada, ocuparão o espaço duas vezes no roteador pois ao substituir arquivos existentes na firmware inicial, ainda será preservado a versão em somente leitura para recuperação. Se for um problema para seu caso, a alternativa é esperar a próxima versão com a correção ou gerar uma nova firmware com o pacote atualizado.

Por fim, faça um novo backup geral. É sempre bom preservar o seu trabalho.

Se precisar retornar a versão anterior do OpenWRT, realize a gravação da firmware antiga, entre no modo de recuperação e restaure a overlay.

Se você não usa uma unidade externa para expandir o espaço interno, seu trabalho acabou. Para os demais, o processo é um pouco mais complicado... Ao atualizar o sistema, você terá um kernel novo que é incompatível com os módulos de kernel ou mesmo com as bibliotecas existentes na unidade externa, que ainda pertencentes à versão anterior. Você precisaria reinstalá-los. Esta é a sugestão de como proceder:

Em primeiro lugar, gere todos os backups sugeridos anteriormente. É importante preservar seu trabalho anterior. Ainda sem instalar a nova firmware, reinicie o sistema sem a unidade externa. Se você seguiu minha sugestão de manter uma configuração básica na flash interna, você ainda terá um ambiente funcional. Com isto, ele vai usar somente a flash interna (com a configuração que você tinha antes de usar a unidade externa).

Ainda com a unidade externa desconectada, faça o procedimento de atualização descrito neste artigo para quem não usa raiz expandida, inclusive com a etapa de backups. Você terá que preservar os dois conjuntos de backups: com e sem a unidade externa em uso. Ao final do processo, você deverá ter a sua configuração básica restabelecida. Caso tenha optado por não preservar as configurações na gravação, você pode aproveitar o backup gerado quando a unidade externa estava desconectada (o segundo) para restaurar as configurações.

Neste momento, a unidade externa ainda está com os programas da versão anterior, que são geralmente incompatíveis com a nova versão (os módulos de kernel sempre o são). Por isto, precisamos nos livrar de todos os arquivos da versão anterior do OpenWRT presentes na unidade externa. Na unidade externa, na partição usada como overlay, remova todo o conteúdo ou mova tudo para um subdiretório (ou para outra unidade se não estiver com espaço livre) afim de que este não seja usado. Como sugestão, crie um "openwrt-versao-xxx" e mova tudo para lá. Refaça a configuração de uso de uma unidade externa (que no mínimo será reinstalar os pacotes necessários). Reinicie o sistema. Você deve estar agora com mais espaço na raiz.

Neste ponto, você ainda terá as mesmas configurações que tinha quando usou o sistema sem a unidade externa. Envie o primeiro backup da versão anterior feito com a unidade externa conectada (primeiro backup). Na sequência, reinstale os pacotes extras, assim como é feito para ambientes sem a raiz expandida. Complete o trabalho com aquele backup final.

Espero que apreciem a nova versão. De agora em diante, vou apenas focar em configurações específicas para LEDE 17.01.0, que ainda podem funcionar nas versões OpenWRT 15.05, 14.07, 12.09 e 10.03.1.

Se pintar um problema, tem sempre o fórum deste blog. Até a próxima.