Upstart e a configuração dos serviços

 Tradicionalmente, utilizamos o sistema SystemV para a inicialização e configuração dos serviços no Linux. O boot começa com o arquivo “/etc/inittab” (que especifica o runlevel padrão e contém comandos para a abertura dos terminais de texto e do ambiente gráfico) e prossegue com a execução de scripts linkados no diretório “/etc/rc5.d/” (ou rc3.d no caso de um servidor configurado para inicializar no runlevel 3, sem a interface gráfica). Neste sistema, ativar ou desativar um serviço é simples, já que basta criar ou remover o link para ele na pasta /etc/rc5.d/, o que pode ser tanto feito manualmente, quanto com a ajuda de utilitários como o update-rc.d ou o “service”.

O SystemV é simples e robusto, mas oferece uma desvantagem crucial, que é o fato de os serviços serem executados sequencialmente, um de cada vez, o que faz com que a inicialização do sistema seja mais demorada e possa ficar engasgada por um longo tempo por causa de algum serviço que está demorando mais do que deveria (como o cliente DHCP tentando obter o endereço IP enquanto o roteador da rede está fora do ar, ou o Exim tentando inicializar enquanto o cabo de rede está desconectado). A menos que você seja um dos que apenas coloca o PC para dormir, sem nunca reiniciá-lo, um longo tempo de boot é seguramente algo que incomoda.

O Upstart oferece uma solução para o problema, oferecendo um sistema de inicialização paralela dos serviços, capaz de reduzir significativamente o tempo de boot (chegando a uma redução de quase 50% em algumas situações), além de oferecer mais recursos em relação à detecção de dispositivos, carregamento de firmwares e assim por diante. Isso fez com que ele fosse adotado como o sistema padrão de inicialização no Ubuntu a partir da versão 6.10. Embora (pelo menos até o 12.04) os antigos scripts do SystemV continuem presentes no Ubuntu, o Upstart passou a receber prioridade e grande maioria dos serviços passaram a ser inicializados através dele.

Como resultado, o boot do Ubuntu é bastante rápido, com um tempo inferior a 30 segundos entre a tela do grub e a tela de login na maioria das máquinas. Por outro lado, a configuração dos serviços é bem diferente do que temos em outras distribuições, o que acaba confundindo a muitos.

Além do Ubuntu, o Upstart foi também utilizado no Fedora, da versão 9 até a versão 14. Entretanto, os desenvolvedores optaram por voltar a utilizar o SystemV a partir da versão 15, embora os pacotes do Upstart continuem disponíveis no repositório para instalação manual. Embora mexer em um componente tão central do sistema seja sempre uma mudança polêmica, o uso do Upstart vem sendo considerado também pelos desenvolvedores de outras distribuições. É esperado também que no futuro o Upstart englobe também funções de agendamento de tarefas, substituindo serviços com o cron e o at, de forma que vale à pena conhecer um pouco mais sobre ele.

O Upstart é baseado no uso de eventos, que podem ser disparados em resposta a algum acontecimento específico (como uma nova interface de rede disponível, por exemplo), ou simplesmente serem executados na hora do boot como parte da inicialização do sistema. A menos que especificado o contrário, o Upstart também se encarrega de verificar a execução dos serviços e reiniciar processos travados ou que não estão funcionando corretamente.

No Fedora e também em versões antigas do Ubuntu (anteriores ao 10.04) os scripts com os eventos do Upstart são armazenados na pasta “/etc/event.d/”. Por enquanto, todas as distribuições que utilizam o Upstart ainda conservam os antigos scripts SystemV na pasta /etc/init.d/ (com os usuais links na pasta /etc/rc5.d/ e compania) mas se você tentar invocar diretamente um dos scripts que já foram migrados, você receberá um aviso de que eles foram convertidos em serviços do Upstart e que devem ser invocados através dele:

Os scripts de invocação do Upstart seguem sempre a mesma estrutura básica, incluindo uma descrição (description), que tem um caráter puramente informativo, uma instrução “start”, que especifica quando ele deve ser iniciado e uma linha “exec”, que especifica o comando que será executado para realizar a tarefa. Um exemplo é o “hostname.conf”, que define o nome da máquina. Ele é um dos scripts mais simples:

description "set system hostname"
start on startup
task
exec hostname -b -F /etc/hostname

Estes scripts podem ser bem mais complexos, indicando que o script deve ser executado como parte da inicialização de outro serviço, indicando diretamente uma série de comandos (em vez de um único comando como no caso do hostname.conf) e assim por diante. Um exemplo é o hwclock.conf, que ajusta o relógio do sistema durante o boot:

description "adjust system clock and timezone"
start on starting mountall
task
script
      . /etc/default/rcS
      [ "$UTC" = "yes" ] && tz="--utc" || tz="--localtime"
      [ "$BADYEAR" = "yes" ] && badyear="--badyear"
      exec hwclock --systz $tz --noadjfile $badyear
end script

Veja que a linha “start” especifica agora “on starting mountall”, que faz com que o script seja executado após o início da execução do “mountall.sh”, o script que monta as partições do HD e é executando no início do boot.

Dando uma olhada no conteúdo do mountall.conf temos a introdução de outro parâmetro interessante, que é o “emits” (“emits virtual-filesystems “, “emits local-filesystems” , “emits remote-filesystems “, etc.). Ele permite que um script emita diferentes sinais que ativam a execução de outros.

Se olharmos o conteúdo do arquivo “udev.conf”, por exemplo, que é o serviço responsável pela detecção de pendrives e outros dispositivos, encontramos a linha start on virtual-filesystems”, que indica que o serviço será executado quando o sinal “virtual-filesystems” é emitido pelo mountall:

description "device node and kernel event manager"
start on virtual-filesystems
stop on runlevel [06]
expect fork
respawn
exec /sbin/udevd --daemon

Scripts mais complexos podem conter também duas seções adicionais, a “pre-start script ” e a “post-start script “, que executam, respectivamente, comandos adicionais que precisam ser executados antes e depois do comando principal. Um bom exemplo é o “cups.conf”, onde o pre-start script executa tarefas como o carregamento de módulos, carregamento de configurações e criação de diretórios, enquanto o post-start script verifica se o serviço subiu corretamente e tenta detectar impressoras USB antigas, cuja detecção é demorada.

Diferente do que temos no SystemV, onde os scripts são numerados e é fácil entender a ordem em que eles são executados, o Upstart temos simplesmente uma salada de scripts dentro da pasta /etc/init/ ou /etc/event.d/ e você precisa realmente ler os scripts para entender a ordem em que eles são executados:

Todos os scripts que fazem parte da pasta são instalados e desinstalados automaticamente juntamente com os respectivos pacotes. Ao remover o pacote “bluez” e suas variações, por exemplo, você automaticamente remove junto o script responsável pela inicialização do Bluetooth. Com isso, você acaba não precisando se preocupar muito com eles na maior parte do tempo, já que se um serviço está instalado, você provavelmente vai desejar que ele seja ativado de qualquer forma.

A principal limitação enquanto escrevo é que não existe uma forma simples de desativar serviços de forma definitiva sem remover os pacotes correspondentes. Todos os scripts que estão na pasta são automaticamente executados, de forma que para desativar um serviço manualmente você precisa ou editar o script (modificando a linha “start” para que ele nunca seja executado) ou, mais simples, mover os scripts que deseja desativar para outra pasta, o que permite restaurá-los mais tarde caso desejado.

Para desativar o bluetooth, por exemplo, você precisaria apenas mover o script bluetooth.conf:

# mkdir /etc/init-disabled
# mv /etc/init/bluetooth.conf /etc/init-disabled/

Por outro lado, o início, parada e reinicio dos serviços pode ser feito de forma bastante simples, através dos comandos “start”, “stop” e “restart”, como em:

# stop bluetooth
# restart udev

Você pode também ver a lista dos serviços em execução através do comando “initctl list”, que em uma instalação padrão do Ubuntu retorna uma longa lista.

Para fazer com que o sistema execute um novo serviço ou algum script que você criou manualmente, basta criar um novo script dentro da pasta “/etc/init/”, seguindo a estrutura que vimos. Este é o exemplo de um script simples, destinado a simplesmente executar um script personalizado durante o boot:

# meuscript.sh
description "Executa o meuscript.sh"
start on started dbus
task
exec /usr/local/bin/meuscript.sh

Veja que usei a linha “start on started dbus “, que faz com que ele seja executado no meio do boot, depois que as partições já foram montadas e o sistema está enumerando os dispositivos disponíveis. Outra opção popular para scripts personalizados é a “start on desktop-session-start “, que faz com que o comando seja executado quando se faz login no ambiente gráfico.

Em resumo, o Upstart pode ser considerado uma evolução do ponto de vista técnico, já que reduz o tempo de inicialização do sistema e oferece uma plataforma mais robusta para a execução dos serviços. Por outro lado ele adiciona uma camada adicional de complexidade, tornando mais difícil a configuração manual do sistema.  

Sobre o Autor

Redes Sociais:

Deixe seu comentário

X