Introduzido no Debian 7, o systemd agora é o sistema de inicialização padrão do Debian Linux (e possivelmente da maioria das distribuições baseadas no Debian, como por exemplo o Raspbian). Ele fornece monitoração avançada, registro e capacidade de gerenciamento de serviços.
Embora ele seja projetado como um substituto do sysvinit e, como tal, faça uso dos scripts de inicialização SysV já existentes, o pacote systemd pode ser seguramente instalado em conjunto com o sysvinit e iniciado através da opção do kernel init=/bin/systemd. O pacote systemd-sysv fornece o substituto do /sbin/init.
Para mais informações sobre esse assunto, veja o wiki (http://wiki.debian.org/systemd) do Debian.
Esse post mostra como usar o systemd para fazer com que o sistema operacional execute automaticamente um script. Para exemplificar, será utilizado um script que envia um email para o administrador do sistema para que este saiba que o equipamento que foi reiniciado ou desligado está novamente disponível para acesso.
1. Pré-requisitos
Para conseguir executar com sucesso os exemplos desse post é necessário que alguns pré-requisitos sejam atendidos. Abaixo estão listados os pré-requisitos e também links para ajudar a configurar o ambiente de forma correta:
- Privilégio de usuário root no sistema operacional ou sudo: Tornando o Raspbian mais seguro
- Cliente de email configurado: Envio de email pelo gmail
2. Criando o script de envio de email
1 2 | mkdir /root/scripts nano /root/scripts/email_startup.sh |
2.1. Conteúdo do script
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 | #!/bin/bash # Define caminho dos binarios PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" # Carrega uptime up=("$(uptime -p | awk '{$1=""; sub(" ", " "); print}')") # Carrega nome do host host=("$(hostname)") # Carrega IPs do host # Ajustar NR==1 conforme o equipamento em que será usado o script meu_ip=("$(ifconfig | awk '/inet addr/{print substr($2,6)}' | awk 'NR==1{print $1}')") # Carrega data/hora atual data=("$(date +"%Y-%m-%d")") hora=("$(date +"%T")") # Carrega servicos iniciados durante o boot, ordenados alfabeticamente servicos=("$(ls -1 /etc/rc$(runlevel| cut -d" " -f2).d/S* | awk -F'[0-9][0-9]' '{print " Servico :-> " $2}' | sort -k 3)") #Carrega apenas o nome dos modulos carregados ordenando alfabeticamente modulos=("$(lsmod | awk '{ print $1 }' | awk '{if(NR>1)print}' | sort -k 1)") # Carrega logs informativos de inicializacao log=("$(dmesg -l info)") ### Define parametros de e-mail ### email="endereco_email@destinatario.com" # E-mail do destinatario do alerta assunto=$host": [Alert] Start Up ["$meu_ip"]" # Assunto do email # Envio de email de alerta printf "%b " "Sistema [$host] ($meu_ip) iniciado em $data as $hora. Modulos Carregados: $modulos Servicos Iniciados: $servicos *** LOG DE INICIALIZACAO *** $log *** FIM *** Uptime: $up" | mail -s "$assunto" "$email" |
2.2. Tornando o script executável
1 | chmod 664 /root/scripts/email_startup.sh |
3. Configurando a execução do script
Após a criação do script, devemos definir como deve ser sua execução pelo systemd, para tanto é imprescindível que o administrador do sistema saiba quais são os serviços e módulos que são iniciados durante o boot, quanto tempo demoram para “subir” e a sequência de inicialização.
3.1. Investigando a inicialização
Para verificar a sequência e o tempo de inicialização dos serviços controlados pelo systemd deve-se executar alguns comandos. O principal comando é o systemd-analyze plot > systemd.svg que gera um relatório com todas as inicializações, sequência e tempo de inicialização individual.
Segundo a Wikipédia:
SVG é a abreviatura de Scalable Vector Graphics que pode ser traduzido do inglês como gráficos vetoriais escaláveis. Trata-se de uma linguagem XML para descrever de forma vetorial desenhos e gráficos bidimensionais, quer de forma estática, quer dinâmica ou animada. Umas das principais características dos gráficos vetoriais, é que não perdem qualidade ao serem ampliados. A grande diferença entre o SVG e outros formatos vetoriais, é o fato de ser um formato aberto, não sendo propriedade de nenhuma empresa. Foi criado pela World Wide Web Consortium, responsável pela definição de outros padrões, como o HTML e o XHTML.
Como não utilizo ambiente gráfico em meus Raspberry Pi, envio o arquivo por email para que eu consiga visualizar seu conteúdo. Assim sendo, uso o comando:
1 | echo "Segue arquivo" | mail -s "Analise systemd" meu@email.com -A systemd.svg |
Caso o parâmetro -A não funcione, envio o conteúdo do arquivo por email para que eu consiga visualizar seu conteúdo:
1 | cat systemd.svg | mail -s "Relatorio systemd" destinatario@gmail.com |
Ao receber o email na minha estação de trabalho, copio o corpo da mensagem e salvo em um arquivo texto porém com a extensão .svg.
Esse procedimento deverá resultar em uma “imagem” com um gráfico. Para conseguir visualiza-la pode-se utilizar um navegador como Chrome, Chromium ou Firefox. Ou então algum programa de imagem ImageMagick, gimp, inkscape, etc. Abaixo um exemplo:
4. Configurando a execução do script pelo systemd
4.1. Criando a definição da inicialização
Deve-se criar um arquivo de configuração o qual será responsável por definir os parâmetros da inicialização.
1 | nano /etc/systemd/system/startupalert.service |
O conteúdo do arquivo deverá ser semelhante à:
1 2 3 4 5 6 7 8 9 10 | [Unit] Description=Startup email alert After=exim4.service ntp.service [Service] Type=oneshot ExecStart=/root/scripts/email_startup.sh [Install] WantedBy=multi-user.target |
Uma das minhas maiores dificuldades em entender o funcionamento desta nova forma de inicialização foi de onde vinham os valores relacionados aos parâmetro After e WantedBy. O arquivo criado no passo 2.1 foi de suma importância para um melhor entendimento do funcionamento do systemd .
No exemplo desse post, o parâmetro After define que o script será executado após o carregamento dos serviços exim4 e ntp . Eu defini esses “pré-requisitos” uma vez que o script a ser executado precisa usar o serviço de envio de email e também da hora correta do sistema.
O parâmetro WantedBy define que o término da execução do serviço é necessário para que o serviço multi-user.target seja iniciado, ou seja, multi-user.target é pré-requisito para multi-user.target.Vide imagem anterior e note no final a linha que contém o texto startupalert.service
4.2. Efetivando a configuração
O próximo, e último, passo é informar ao systemd que existe um novo “serviço” que deve ser iniciado durante o processo de boot. Para isso, basta executar os comandos:
1 | systemctl enable startupalert.service |
1 | systemctl daemon-reload |
Lembre-se de executar o comando systemctl daemon-reload sempre que fizer alterações no arquivo de configuração do serviço ( startupalert.service).
5. Testando a solução
Como o script será executado durante cada inicialização do sistema, para testar se está tudo funcionando basta reiniciar o equipamento e aguardar o recebimento do email de alerta gerado pelo script de exemplo desse post.
1 | reboot |
6. Outros comandos úteis
O systemd é uma ferramenta bastante poderosa e fornece alguns comandos bem interessantes, sendo eles:
1 2 3 | systemd-analyze systemd-analyze critical-chain systemd-analyze dot |
Além dos comandos do próprio systemd, existe o comando journalctl o qual mostra a execução do “serviço”.
1 | journalctl -u startupalert.service |
Para mostrar as mensagens de log da inicialização atual:
1 | journalctl -u startupalert.service -b |
Para itens nomeados como <alguma_coisa>.service, você pode usar somente <alguma_coisa>, assim:
1 | journalctl -u alguma_coisa |
Mas para os demais (sockets, targets, timers, etc), você precisa ser explícito.