Hoje, eu tentava debugar um problema em um servidor. Com o entra e sai da minha sala, telefone tocando, chefe trazendo documentos etc., enquanto reaproveitava uma linha anterior (tecla seta para cima), pensando ter dado um # ls /var/lib, na verdade, dei um # rm -rf /var/lib. Começou a saga…
Os primeiros sentimentos
A coisa começa num abstrato formato de p-q-p emanando no cérebro. Depois vem a necessidade de incorporar Airton Sena para ser bem rápido. Tratava-se do roteador de borda mas, como tudo estava na memória da máquina e ela não usava swap, havia uma enorme possibilidade da rede não cair enquanto eu agisse. Então, calma Eriberto. Você consegue!
O que é o /var/lib?
O /var/lib é um diretório essencial do sistema que contém, dentre outras coisas, a lista de pacotes instalados e parte do sistema APT. Sem ele, não tem apt-get. Então, no desespero, a primeira coisa que fiz foi dar um # apt-get update, para ver do que ele iria reclamar. Fui criando os diretórios não encontrados. Em determinado momento, um arquivo não foi encontrado. Com o comando touch, criei um arquivo vazio com o nome solicitado. No fim, o APT funcionou (apt-cache e apt-get). Mas tinha algo ruim… A base do sistema é criada durante a instalação do Debian e eu não poderia refazê-la com perfeição a partir de um bando de apt-gets…
A nova solução
Bem, rapidamente pensei e resolvi criar e copiar uma estrutura básica de /var/lib para dentro da máquina. Poderia fazer essa cópia via rede, pois a máquina acidentada tinha ssh e rsync ativos. Então, em outra máquina, criei um Debian básico com debootstrap:
# mkdir /tmp/lenny
# debootstrap lenny /tmp/lenny http://ftp.us.debian.org/debian
A seguir, com rsync -av, copiei todo o conteúdo de /tmp/lenny/var/lib/ para dentro do /var/lib da acidentada. Ufa! Estrutura básica montada. Agora, na base de dados do APT (e dpkg), que fica em /var/lib, só existiam os pacotes básicos . Em outras palavras, para o Debian, ele era um recém-nascido. Assim, eu precisava reinstalar todos os pacotes preexistentes. Mas eu não tinha uma lista de pacotes instalados. Agora sei que é importante ter uma relação gerada com dpkg -l dentro do meu backup. Vou implementar isso.
Para descobrir os pacotes necessários, segui a seguinte ordem:
- Inicialmente, para garantir que a lista de pacotes instalados vinda da outra máquina (dentro do conteúdo do /var/lib) estava batendo, mandei o sistema reinstalar cada um dos pacotes listados. Escrevi a seguinte linha para fazer isso:
# for i in $(dpkg -l|grep ^ii|cut -d" " -f3); do apt-get install --reinstall -y $i; done
- Depois, instalei os pacotes básicos, que sempre instalo, como mc, rcconf, less, ntpdate, tcpdump etc.
- Instalei o kernel, pois esse é o mais básico. Usei o linux-image-2.6-686.
- Fiz um # netstat -tunlp para ver os serviços que estavam rodando. Esses são muito importantes, porque podem vir a ter falha de segurança um dia e precisam estar na base de dados do APT para poderem ser atualizados.
- Semelhante ao passo anterior, com base no conteúdo de /etc/init.d, instalei pacotes. Para isso, escrevi a seguinte linha:
# for i in $(ls /etc/init.d); do echo -e '\n' $i; apt-get install $i; done
- Depois de reinstalar o daemons com base no /etc/init.d, fiz um novo # netstat -tunlp para ver se não havia algum serviço de rede indesejado no ar. A seguir, outra verificação, agora incluindo os serviços locais, com # ps ax.
- Agora, o grande final. Eu precisava reinstalar todos os pacotes que tivessem nomes de executáveis, exceto o que eu já tinha instalado. A solução:
# for i in $(ls /bin; ls /sbin; ls /usr/bin; ls /usr/sbin); do echo -e '\n' $i; apt-get install $i; done
- Com a linha anterior, alguns pacotes foram instalados, outros dados como já instalados e vários nomes dados como não existentes. Houve mensagens citando pacotes virtuais e substitutos. Assim, depois de tudo feito, rodei novamente o comando com um egrep mágico e um 2> para desviar erros para o lixo. Veja:
# for i in $(ls /bin; ls /sbin; ls /usr/bin; ls /usr/sbin); do echo -e '\n' $i; apt-get install $i 2> /dev/null; done | egrep -A 5 -B 5 '(virtual|substituem|S\/n)'
- Nesta última linha eu obtive resultados que foram tratados um a um, individualmente.
Bem, foi isso. Espero que este post, um dia, ajude alguém.
Parabéns Eriberto pela solução. O bom é isso, com criatividade e um pouco de experiência o SL não nos impôe limites. Abraço e feliz sysadminday.
Valeu Chico! Cara, acredita que quando postei o link no Twitter pensei em você?
Deu 5 minutos e você postou um comentário. Eu sabia que ia ler.
[]s!!!!
Provavelmente um Junior iria esperar até uma hora de baixa atividade, desligar a máquina e rodar um backup restaurando arquivos do sistema – isso se não percebesse a m.. que fez, e “deixasse pra lá”, pra outro sysadmin descobrir a bomba em um dia qualquer.
São atitudes como essa que explicam a diferença de salários dos Sysadmin Senior/Pleno pros demais. Parabens pelo “Hack”, o equivalente a trocar o motor de um avião em pleno vôo, cheguei a ficar tenso acompanhando os passos! Abraços.
Opa! Valeu!
[]s
Gostei!
Eriberto, os nomes dos diretórios contidos em /usr/share/doc não seriam úteis nesse caso para saber quais pacotes estavam instalados?
Ninja!
Muito bom, Eriberto.
Um abraço
Meu camarada, que jeito de encerrar a semana hein?!
Essa solução é o que podemos chamar de “faca na caveira”!!!
E com certeza a mistura experiência/conhecimento é decisiva nesses momentos.
Já detonei um mirror do repositório debian em produção e a parte do P.Q.P é verdadeira!
Parabéns pela recuperação!
Huahuahua! Great job! Muito bom quando a criatividade se alia ao desespero.
Abraço!
Patriota, valeu!
Adriano, com certeza. Uma excelente ideia. Mas, mesmo assim, a parte do Debian básico (feito com debootstrap) é necessária.
Muito bom! Tem que ter nervos de aço pra consertar uma cagada^Winfelicidade dessas a quente … 🙂
a idéia de guardar a saída do `dpkg -l` no backup é muito boa.
Não tinha nenhuma aplicação guardando dados num subdiretório de /var/lib, né (tipo PostgreSQL/MySQL)?
Abraço!
Fala Terceiro! Inicialmente, parabéns pela organização do FISL.
Não. Como eu disse, era um roteador. Mas tenho duas máquinas de backup, em HA, cada uma com 4 TB. Era só puxar O BD.
O meu problema naquele momento era não parar a rede e não ter que reinstalar tudo do zero. Daria uma hora de trabalho até ajustar tudo.
Abração!
CARACA, que m… da porra… ehehe, sorry for my language… esse post valeu a inscrição no seu RSS, a partir de agora vou te acompanhar 😀
Valeu Allan! Bem vindo.
Olá Eriberto,
Apesar da situação constragedora o post valeu!!!
Será que o dpkg –get-selections > lista_pacotes.txt e um dpkg –set-selections < pacotes.mail não resolveria.
Abs,
Alexos
http://www.alexos.org
Olá Alexandro,
Não resolveria porque o dpkg –get-selections colhe os dados dentro do /var/lib. Então, nada feito.
[]s
Uuau!! Foi um passeio com emoção por dentro do /var/lib hein!! .. Deve ter dado aquele gosto de m.. na boca e aquele calor na ponta das orelhas!! Acontece nas melhores famílias! Mas se saiu bem, foi criativo com o renascimento do /var/lib. Mais uma que aprendemos…
Abraço e cuidado com setas para cima nas sextas-feiras!
Grande Alexandre! É, foi isso mesmo…
Abração!
Que hacking hein?
Acho que se você soubesse usar o ldconfig seria bem mais fácil arrumar isso aí!
Abraços!
ãhh??? O que ldconfig tem a ver como isso?
Fala Eriberto. Mandou bem. Vi este post seu e me identifiquei. Principalmente na parte do P.Q.P, o que eu fiz.
Eu também fiz algo parecido uma fez numa Sexta-Feira as 22:00hs. Tive vários sentimentos rondando a minha cabeça naquele momento. Minha mão esquerda TREMEU (literalmente). E eu falei em voz baixa, não, não, não, o que eu fiz. Tantos anos mexendo com TI e dei um vacilo desses. Mas depois fui voltando ao normal e comecei a buscar a solução. UFAAAAA, as 03:00hs da madrugada consegui achar. Era algo bem manual. Devido a solução ser manual (vários comandos e filtros), perdi o meu final de semana. Mas Deus me ajudou e Segunda-Feira estava tudo funcionando.
Olá Hugo!
Pois é. A vida é assim. Como diz uma pessoa bem próxima a mim, a necessidade faz o sapo pular. ha ha ha
[]s