Myhro Blog

Carregando um kernel manualmente com o kexec

Conheci o kexec por um acaso. É o tipo de ferramenta que, se alguém tivesse me mostrado sem exemplificar com um caso de uso específico, não enxergaria a menor utilidade. A ideia é muito simples, como seu próprio nome sugere: executar (carregar) um kernel. Você pode se perguntar porque alguém precisaria de uma ferramenta para realizar um processo que normalmente é executado por um gerenciador de boot, como o GRUB. Uma das respostas possíveis é: nem sempre você tem a possibilidade de alterar as configurações de inicialização da máquina.

Este é o caso da DigitalOcean, uma empresa nova-iorquina que oferece servidores virtuais a preços extremamente acessíveis. O painel de administração das máquinas virtuais é muito bem feito, possuindo uma interface extremamente simples, que ao mesmo tempo oferece todas as opções necessárias para configurá-las. Entretanto, há um problema: só é possível inicializar as máquinas Linux (únicas oferecidas até o momento) com os kerneis pré-definidos por eles. Não é possível, por exemplo, recompilar seu próprio kernel ou mesmo trocá-lo por uma versão atualizada com novas correções de segurança.

Isto normalmente não é um problema, pois eles oferecem uma quantidade até razoável de kerneis diferentes no painel de administração. O problema é quando você precisa de uma combinação menos convencional, como atualizar o Debian para a versão testing ou unstable, utilizando um kernel qual não está disponível. E isto era justamente o que eu precisava para rodar o Docker no Debian, ou pelo menos atualizar o kernel, se não fosse fazer isto com todo o sistema.

A solução para esta situação é carregar um kernel “na mão”, utilizando o comando kexec, que no Debian está disponível no pacote kexec-tools. Partindo do pressuposto que você já tenha instalado (via apt-get, compilado, etc.) o kernel qual deseja carregar, basta executar o comando kexec -l [arquivo-kernel] --initrd=[arquivo-initrd]. Por exemplo:

[root@debian-docker:~]# uname -a
Linux debian-docker 3.2.0-4-amd64 #1 SMP Debian 3.2.41-2+deb7u2 x86_64 GNU/Linux
[root@debian-docker:~]# ls -lh /boot/
total 33M
-rw-r--r-- 1 root root 148K Mar 26 05:11 config-3.13-1-amd64
-rw-r--r-- 1 root root 127K Mar 26  2013 config-3.2.0-4-amd64
drwxr-xr-x 2 root root 4.0K Apr  6 19:42 grub
-rw-r--r-- 1 root root  13M Apr  6 19:50 initrd.img-3.13-1-amd64
-rw-r--r-- 1 root root 9.8M May  3  2013 initrd.img-3.2.0-4-amd64
-rw-r--r-- 1 root root 2.3M Mar 26 05:11 System.map-3.13-1-amd64
-rw-r--r-- 1 root root 2.1M Mar 26  2013 System.map-3.2.0-4-amd64
-rw-r--r-- 1 root root 2.8M Mar 26 05:08 vmlinuz-3.13-1-amd64
-rw-r--r-- 1 root root 2.8M Mar 26  2013 vmlinuz-3.2.0-4-amd64
[root@debian-docker:~]# kexec -l /boot/vmlinuz-3.13-1-amd64 --initrd=/boot/initrd.img-3.13-1-amd64

Neste momento, o normal seria executar o kernel previamente carregado com o comando kexec -e. Entretanto, não obtive sucesso quando tentei fazer isso e em todas as vezes a máquina simplesmente travava. O que resolveu meu problema foi executar o comando dpkg-reconfigure kexec-tools, respondendo Yes na pergunta ”Should kexec-tools handle reboots?” e No na pergunta ”Read GRUB configuration file to load the kernel?”. Isto faz com que o kernel a ser inicializado passe a ser o que foi carregado no kexec, sem influência do que estiver configurado no GRUB.

A partir disto, basta reiniciar a máquina, seja pelo painel de administração ou através do comando reboot. Na próxima vez que você se conectar, verifique a versão do kernel, para confirmar se tudo ocorreu como esperado:

[root@debian-docker:~]# uname -a
Linux debian-docker 3.13-1-amd64 #1 SMP Debian 3.13.7-1 (2014-03-25) x86_64 GNU/Linux

Minicurso: Introdução ao Python/Django

Estarei ministrando um minicurso de Introdução ao Python/Django nos dias 02 (quarta-feira) e 04 (sexta-feira) de Abril, com possibilidade de mais uma aula no dia 09 (quarta-feira) de Abril de 2014, dependendo de como as coisas fluirem. O local de realização do mesmo será o Laboratório II (o primeiro à direita do corredor) do Centro de Ciências Exatas e Tecnológicas, prédio 03, do Campus Universitário Prof. Darcy Ribeiro da Unimontes, localizado na cidade de Montes Claros. O horário previsto é das 19h às 22h30m.

A ideia surgiu a partir desta postagem feita pelo meu prezado colega de curso Jader Gabriel no grupo do Curso de Sistemas de Informação da Unimontes no Facebook, sugerindo um curso de Python e/ou Django, provavelmente pago. É importante destacar que este minicurso é gratuito e aberto a todos os acadêmicos do CCET, não sendo de forma alguma restrito ao Curso de Sistemas de Informação ou aos cursos ligados ao Departamento de Ciências da Computação (DCC) - embora estes sejam os principais interessados. O único pré-requisito é saber o básico de lógica de programação, embora ter noções de orientação a objetos fosse interessante.

Caso deseje se inscrever, por favor utilize este formulário do Google Drive. Estão previstas 22 (vinte e duas) vagas, para evitar que alguém fique sem computador caso ocorra algum problema com as máquinas durante o andamento do minicurso. O Google Drive não limita o número de inscrições, portanto, caso você consiga se inscrever, não quer dizer necessariamente que sua vaga está garantida. Farei o possível para encerrá-las assim que o limite for atingido, de forma a evitar que isto aconteça. As vagas serão distribuídas por ordem cronológica de inscrição e as mesmas serão posteriormente confirmadas via e-mail.

Atualização: a última vaga foi preenchida às 21h17m do dia 26/03/2014 (quarta-feira) e com isto as inscrições foram encerradas.

Atualização: estão disponíveis para download os slides utilizados no minicurso e o projeto de exemplo gerado.

Vim + Plugins = Pathogen

A escolha de um editor decente e universal não é fácil. Antes de começar a utilizar o Vim corriqueiramente, passei por diversos outros como:

  • Bloco de notas: Um editor sincero. Não espere nada além de realmente editar textos.
  • Joe: Muito bacana. Já havia decorado boa parte dos seus milhares de atalhos.
  • nano: É sério que alguém ainda usa isso? Já implementaram o ”undo”, pelo menos?
  • Notepad++: Um editor acima da média, mas Windows-only.

Todos eles tinham pelo menos um ou vários desses problemas:

  • Não funcionava sem ambiente gráfico (modo texto).
  • Não possuía syntax highlighting.
  • Não sabia lidar com quebras de linha de diferentes sistemas operacionais (CR+LF vs. LF).
  • Não salvava em UTF-8.
  • Não trocava TAB por n espaços.

E ainda havia o mais grave de todos: não estavam disponíveis em todas as máquinas quais utilizo. Foi somente a partir deste momento, que não deve ter acontecido há muito mais do que dois anos atrás, que decidi de vez por utilizar o Vim sempre que fosse necessário editar qualquer arquivo texto que fosse. Sempre que logo em uma máquina qual não estou familiarizado, tenho a certeza (se é que podemos ter certeza de algo nessa vida) de que pelo menos o comando vi (que na verdade faz parte do pacote vim-tiny, sendo uma versão menor e simplificada do Vim) estará disponível.

Acontece que utilizar apenas o editor puro nem sempre é o suficiente. Uma parte considerável das surpresas no estilo ”Wow! O Vim faz isso?!” é proporcionada pelos plugins desenvolvidos por terceiros. Entretanto, além de muitos deles possuírem passos de instalação crípticos, é complicado manter todos devidamente atualizados. Foi a partir daí que passei a usar o Tim Pope’s pathogen.vim, em um daqueles momentos onde sempre me pergunto: ”Por que é que não fiz isso antes?!”.

Após instalar o Pathogen, o que consiste basicamente em salvar o script em ~/.vim/autoload/pathogen.vim e adicionar a linha execute pathogen#infect() ao seu ~/.vimrc, basta criar o diretório ~/.vim/bundle/ e simplesmente clonar lá o repositório (muitos estão no GitHub) do plugin qual deseja utilizar. A grande maioria dos plugins estará disponível a partir deste processo, mas alguns, mais complexos, podem exigir a adição de algumas informações no arquivo ~/.vimrc.

Por exemplo, para instalar o Syntastic, um plugin que verifica seu código a cada vez que o arquivo é salvo, indicando possíveis erros quais serão encontrados na compilação ou quando for interpretado, suportando dezenas de linguagens de programação, basta realizar os seguintes passos:

[myhro@wheezy:~]$ cd ~/.vim/bundle/
[myhro@wheezy:~/.vim/bundle]$ git clone https://github.com/scrooloose/syntastic.git
Cloning into 'syntastic'...
remote: Reusing existing pack: 9852, done.
remote: Counting objects: 40, done.
remote: Compressing objects: 100% (39/39), done.
remote: Total 9892 (delta 15), reused 0 (delta 0)
Receiving objects: 100% (9892/9892), 2.48 MiB | 247 KiB/s, done.
Resolving deltas: 100% (4773/4773), done.
[myhro@wheezy:~/.vim/bundle]$ ls
syntastic
[myhro@wheezy:~/.vim/bundle]$ 

E pronto. O Syntastic está instalado. Para atualizá-lo, bastará entrar em seu diretório e rodar um git fetch seguido de git merge origin/master ou simplesmente um git pull origin.

Vagrant: Introdução

O Vagrant é uma ferramenta criada originalmente para o VirtualBox, mas que hoje suporta uma grande variedade de sistemas de virtualização, qual fornece uma fina camada para facilitar a criação, gerenciamento e utilização de ambientes de desenvolvimento virtuais. O velho problema conhecido como “na minha máquina funciona” é sanado pela raiz, visto que através de pouquíssimos passos, todos os desenvolvedores tem acesso a um ambiente praticamente idêntico, onde as únicas diferenças residem na versão do VirtualBox instalada ou nas modificações realizadas no sistema operacional da máquina virtual utilizada.

Para começar a utilizar o Vagrant, são necessários basicamente três componentes:

  • O VirtualBox, que além de ser o provider padrão, é uma excelente ferramenta de virtualização, gratuita e largamente utilizada.
  • O próprio Vagrant, que é responsável por fornecer os comandos e ler os arquivos de configuração para gerenciamento das máquinas virtuais.
  • Uma box, que nada mais é do que uma máquina virtual criada no VirtualBox ou outro provider cujas configurações e imagem de disco foram exportadas e compactadas em um único arquivo.

O processo de instalação de ambos VirtualBox e Vagrant varia de acordo com o sistema operacional utilizado, podendo ser Windows, Linux ou Mac OS X, mas ainda assim é muito simples. Vale ressaltar que o VirtualBox também suporta Solaris, mas o Vagrant não. O que importa é que ao final você terá o comando vagrant, através do qual realizará todo o processo de adicionar/criar/inicializar/desligar máquinas virtuais, sem precisar utilizar a interface do VirtualBox diretamente para isto.

Após realizar a instalação de ambos, é necessário adicionar pelo menos uma nova box. Há uma página com diversas boxes de várias distribuições Linux ou BSD, mas neste exemplo utilizaremos uma que criei a partir de uma instalação mínima do Debian “Wheezy” 7.0. A sintaxe do comando é vagrant box add {nome} {url}, onde o nome escolhido será utilizado para se referir à mesma em outros comandos. A URL não precissa ser necessariamente um link HTTP, podendo ser também o caminho de um arquivo em outro diretório, por exemplo.

[myhro@wheezy:~]$ vagrant box list
There are no installed boxes! Use `vagrant box add` to add some.
[myhro@wheezy:~]$ vagrant box add wheezy32 http://myhro.info/dl/wheezy32.box 
Downloading or copying the box...
Extracting box...te: 2.6M/s, Estimated time remaining: 0:00:01)
Successfully added box 'wheezy32' with provider 'virtualbox'!
[myhro@wheezy:~]$ vagrant box list
wheezy32 (virtualbox)

Após a box ser copiada, basta, na pasta do projeto qual irá utilizar esta máquina virtual, utilizar o comando vagrant init {nome}. É importante que se faça isso na pasta correta por dois motivos: o primeiro é que a pasta atual será compartilhada no diretório /vagrant/ da máquina virtual, não necessitando copiar seus arquivos por outros meios para acessá-los. O segundo motivo é que será criado um arquivo chamado VagrantFile, que é um simples arquivo-texto onde todas as configurações necessárias para adaptação da máquina estarão presentes. Desta forma, este arquivo pode ser compartilhado com os demais membros do projeto, tornando o ambiente ainda mais homogêneo.

[myhro@wheezy:~]$ cd project/
[myhro@wheezy:~/project]$ vagrant init wheezy32
A `Vagrantfile` has been placed in this directory. You are now
ready to `vagrant up` your first virtual environment! Please read
the comments in the Vagrantfile as well as documentation on
`vagrantup.com` for more information on using Vagrant.

Em seguida, basta colocar a máquina pra rodar com o comando vagrant up:

[myhro@wheezy:~/project]$ vagrant up
Bringing machine 'default' up with 'virtualbox' provider...
[default] Importing base box 'wheezy32'...
[default] Matching MAC address for NAT networking...
[default] Setting the name of the VM...
[default] Clearing any previously set forwarded ports...
[default] Creating shared folders metadata...
[default] Clearing any previously set network interfaces...
[default] Preparing network interfaces based on configuration...
[default] Forwarding ports...
[default] -- 22 => 2222 (adapter 1)
[default] Booting VM...
[default] Waiting for machine to boot. This may take a few minutes...
[default] Machine booted and ready!
[default] Mounting shared folders...
[default] -- /vagrant

Caso neste momento a máquina virtual não seja inicializada e apareça uma mensagem de erro dizendo que a mesma entrou no estado “gurumeditation”, pode ser que as instruções de virtualização do processador da máquina física estejam desabilitadas, ou mesmo não estejam disponíveis. É interessante verificar no setup da BIOS/UEFI se é possível habilitá-las.

A partir daí, é possível, por exemplo, logar na máquina com o comando vagrant ssh e instalar/configurar/executar o que for necessário. Os exemplos contidos no arquivo VagrantFile ensinam como redirecionar outras portas, fazendo com que um servidor web rodando na máquina virtual se torne acessível a partir do browser na máquina físical qual a está rodando.

myhro@wheezy:~/project]$ vagrant ssh
Linux wheezy32 3.2.0-4-686-pae #1 SMP Debian 3.2.51-1 i686

The programs included with the Debian GNU/Linux system are free software;
the exact distribution terms for each program are described in the
individual files in /usr/share/doc/*/copyright.

Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent
permitted by applicable law.
Last login: Wed Jun 19 15:19:38 2013
[vagrant@wheezy32:~]$ df -h
Filesystem      Size  Used Avail Use% Mounted on
rootfs          4.0G 1022M  2.8G  27% /
udev             10M     0   10M   0% /dev
tmpfs            51M  196K   51M   1% /run
/dev/sda1       4.0G 1022M  2.8G  27% /
tmpfs           5.0M     0  5.0M   0% /run/lock
tmpfs           101M     0  101M   0% /run/shm
none            257G  120G  138G  47% /vagrant
[vagrant@wheezy32:~]$ free -m
total       used       free     shared    buffers     cached
Mem:           502        103        398          0         11         62
-/+ buffers/cache:         29        472
Swap:            0          0          0
[vagrant@wheezy32:~]$ logout
Connection to 127.0.0.1 closed.
[myhro@wheezy:~/project]$ 

E após utilizar a máquina, basta colocá-la para “dormir” com o comando vagrant suspend ou desligá-la com vagrant halt. Mas o comando mais legal mesmo é o salva-vidas vagrant destroy:

[myhro@wheezy:~/project]$ vagrant destroy
Are you sure you want to destroy the 'default' VM? [y/N] y
[default] Forcing shutdown of VM...
[default] Destroying VM and associated drives...

Este comando, como o próprio nome sugere, destrói completamente a máquina virtual. A princípio pode parecer algo exagerado, mas é a coisa mais rápida e prática a se fazer quando algo der errado, como quando a máquina não iniciar mais depois de alguma modificação realizada. Depois disso, basta iniciá-la novamente, recriando-a do zero, com comando vagrant up, que também serve para quando a mesma está desligada ou suspensa.

Implicações do Envelhecimento

Acredito que não seja algo assim tão recente, mas ultimamente, mais do que nunca, tenho me sentido velho. Alguns poderiam dizer que estou novo pra isso, visto que ainda me encontro na faixa dos “vinte e poucos anos”, mas este é o sentimento que me acomete. Passei a notar isto quando percebi que estava me tornando cada vez mais impaciente, principalmente ao lidar com pessoas, sem necessariamente destacar um grupo específico. Este fato se torna ainda mais curioso quando lembro que, quando criança, minha avó dizia que uma das coisas que mais admirava em mim era a paciência.

Até pouco tempo atrás, uma das coisas que mais me interessava era participar de discussões. Por mais que não fossem assuntos realmente importantes, me parecia agradável discutí-los, seja “ganhando” ou “perdendo”, simplesmente porque considero construtivo o fato de que expor duas opiniões contrárias, em uma boa proporção das vezes, enriquece o intelecto dos debatentes. O próprio fato de formular afirmações ou perguntas coerentes já é um pequeno exercício intelectual. Hoje, uma das coisas que mais me empenho em fazer no dia-a-dia é evitar qualquer discussão cujo ponto central não me pareça verdadeiramente importante.

É bastante curioso o fato de nos tornarmos mais seletivos com o passar dos anos, escolhendo a dedo quem ou o que merece uma fatia do nosso tempo. Talvez seja porque depois de vivenciarmos algumas experiências, conseguimos separar com uma certa clareza o que poderia ser produtivo ou simplesmente um sangue-suga do nosso ânimo. De certa forma, este sentimento de velhice está aliado à sensação horrível de se desanimar só de pensar em determinada possibilidade ou se comprometer a realizar determinada tarefa.

Sempre acreditei que a parte reconfortante no fato de ser velho, se é que existe alguma, é a certeza de que não há muito com o que se preocupar, visto que não há muito a ser feito, já que tudo irá em breve acabar. Quem sabe seja possível fazer algo parecido enquanto a velhice ainda não tenha realmente chegado, buscando conforto em uma sensação, ainda que incômoda, capaz de trazer algum benefício se analisada por outro lado.