19 Daemon systemd
#
O systemd
é responsável pela inicialização do sistema e tem o ID de processo 1. O systemd
é iniciado diretamente pelo kernel e resiste ao sinal 9, que normalmente termina os processos. Todos os outros programas são iniciados diretamente pelo systemd
ou por um de seus processos filho. O systemd
é um substituto do daemon init do System V e é totalmente compatível com o init do System V (por meio do suporte a scripts init).
A principal vantagem do systemd
é que ele acelera consideravelmente o tempo de boot ao paralelizar as inicializações de serviços. Além disso, o systemd
apenas inicia um serviço quando é realmente necessário. Os daemons não são iniciados incondicionalmente no momento da inicialização, mas quando são solicitados pela primeira vez. O systemd
também suporta Grupos de Controle de Kernel (cgroups), criando instantâneos e restaurando o estado do sistema. Para obter mais detalhes, consulte http://www.freedesktop.org/wiki/Software/systemd/.
19.1 Conceito do systemd
#
A seção a seguir explica o conceito por trás do systemd
.
O systemd
é um gerenciador de sistema e sessão para Linux, compatível com os scripts init do System V e do LSB. Os principais recursos do systemd
são:
recursos de paralelização
ativação de soquete e D-Bus para iniciar serviços
iniciar daemons sob demanda
monitoramento de processos usando cgroups do Linux
criação de instantâneos e restauração do estado do sistema
manutenção dos pontos de montagem e automount
implementação de uma lógica elaborada de controle de serviço baseada em dependência transacional
19.1.1 Arquivo unit #
O arquivo de configuração unit contém informações sobre serviço, soquete, dispositivo, ponto de montagem, ponto de automount, arquivo de troca (swap) ou partição, destino de inicialização, caminho do sistema de arquivos monitorado, temporizador controlado e supervisionado pelo systemd
, instantâneo de estado do sistema temporário, fração de gerenciamento de recursos ou grupo de processos criados externamente.
O “arquivo unit” é um termo genérico usado pelo systemd
para o seguinte:
Serviço. Informações sobre um processo (por exemplo, a execução de um daemon); o arquivo termina com .service
Destinos. Usado para agrupar unidades e como pontos de sincronização durante a inicialização; o arquivo termina com .target
Soquetes. Informações sobre um soquete de rede, IPC ou FIFO do sistema de arquivos, para ativação baseada em soquete (como
inetd
); o arquivo termina com .socketCaminho. Usado para acionar outras unidades (por exemplo, executar um serviço quando houver mudanças nos arquivos); o arquivo termina com .path
Timer. Informações sobre um temporizador controlado, para ativação baseada em temporizador; o arquivo termina com .timer
Ponto de montagem. Normalmente, gerado de forma automática pelo gerador fstab. O arquivo termina com .mount
Ponto de automount. Informações sobre um ponto de automount do sistema de arquivos; o arquivo termina com .automount
Swap. Informações sobre um dispositivo ou arquivo de troca para paginação de memória; o arquivo termina com .swap
Dispositivo. Informações sobre uma unidade de dispositivo conforme exposta na árvore de dispositivos do sysfs/udev(7); o arquivo termina com .device
Escopo/Fração. Um conceito de gerenciamento hierárquico de recursos de um grupo de processos; o arquivo termina com .scope/.slice
Para obter mais informações sobre arquivos de unidade do systemd
, acesse http://www.freedesktop.org/software/systemd/man/systemd.unit.html
19.2 Uso básico #
O sistema init do System V usa vários comandos para gerenciar serviços: scripts init, insserv
, telinit
e outros. O systemd
facilita gerenciar serviços, já que existe apenas um comando para ser memorizado para a maioria das tarefas de gerenciamento de serviços: systemctl
. Ele usa a notação “command plus subcommand”, como git
ou zypper
:
systemctl GENERAL OPTIONS SUBCOMMAND SUBCOMMAND OPTIONS
Consulte man 1 systemctl
para obter o manual completo.
Se a saída chegar a um terminal (e não a um pipe ou arquivo, por exemplo), por padrão, os comandos systemd
enviarão uma saída extensa para um pager. Use a opção --no-pager
para desativar o modo de paginação.
O systemd
também suporta a complementação do bash, que permite digitar as primeiras letras de um subcomando e pressionar →|. Esse recurso está disponível apenas no shell bash
e requer a instalação do pacote bash-completion
.
19.2.1 Gerenciando serviços em um sistema em execução #
Os subcomandos de gerenciamento de serviços são os mesmos usados para gerenciar um serviço com o init do System V (start
, stop
...). A sintaxe geral dos comandos de gerenciamento de serviços é a seguinte:
systemd
systemctl reload|restart|start|status|stop|... MY_SERVICE(S)
- Init do System V
rcMY_SERVICE(S) reload|restart|start|status|stop|...
O systemd
permite gerenciar vários serviços de uma só vez. Em vez de executar os scripts init um após o outro como acontece com o init do System V, execute um comando da seguinte forma:
>
sudo
systemctl start MY_1ST_SERVICE MY_2ND_SERVICE
Para listar todos os serviços disponíveis no sistema:
>
sudo
systemctl list-unit-files --type=service
A tabela a seguir lista os comandos de gerenciamento de serviços mais importantes para o systemd
e o init do System V:
Tarefa |
Comando |
Comando init do System V |
---|---|---|
Iniciando. |
start |
start |
Parar. |
stop |
stop |
Reiniciar. Encerra os serviços e os inicia na sequência. Se algum serviço ainda não estiver em execução, ele será iniciado. |
restart |
restart |
Reiniciar condicionalmente. Reinicia os serviços se já estiverem em execução. Não faz nada para os serviços que não estão em execução. |
try-restart |
try-restart |
Recarregar.
Instrui os serviços a recarregarem seus arquivos de configuração sem interromper a operação. Caso de uso: instruir o Apache a recarregar um arquivo de configuração |
reload |
reload |
Recarregar ou reiniciar. Recarrega os serviços quando o recarregamento é suportado; do contrário, reinicia-os. Se algum serviço ainda não estiver em execução, ele será iniciado. |
reload-or-restart |
n/a |
Recarregar ou reiniciar condicionalmente. Recarrega os serviços se o recarregamento for suportado; do contrário reinicia-os, se estiverem em execução. Não faz nada para os serviços que não estão em execução. |
reload-or-try-restart |
n/a |
Obter informações detalhadas sobre status.
Lista as informações sobre o status dos serviços. O comando |
status |
status |
Obter informações resumidas sobre status. Mostra se os serviços estão ou não ativos. |
is-active |
status |
19.2.2 Habilitando/Desabilitando serviços permanentemente #
Os comandos de gerenciamento de serviços mencionados na seção anterior permitem manipular serviços na seção atual. O systemd
também permite habilitar ou desabilitar serviços permanentemente para serem iniciados automaticamente quando solicitados ou para ficarem sempre indisponíveis. É possível fazer isso com o YaST ou por linha de comando.
19.2.2.1 Habilitando/Desabilitando serviços na linha de comando #
A tabela a seguir lista os comandos de habilitação e desabilitação pelo systemd
e pelo init do System V:
Ao habilitar um serviço na linha de comando, ele não é iniciado automaticamente. Ele é programado para iniciar na próxima inicialização do sistema ou mudança de nível de execução/destino. Para iniciar um serviço logo depois de habilitá-lo, execute explicitamente systemctl start
MY_SERVICE
ou rc
MY_SERVICE start
.
Tarefa |
Comando |
Comando init do System V |
---|---|---|
Habilitar. |
|
|
Desabilitar. |
|
|
Verificar. Mostra se um serviço está ou não habilitado. |
|
|
Reabilitar. Semelhante a reiniciar um serviço, este comando primeiro desabilita e depois habilita um serviço. Útil para restaurar um serviço aos seus padrões. |
|
n/d |
Mascarar. Após “desabilitar” um serviço, ele ainda poderá ser iniciado manualmente. Para desabilitar um serviço completamente, é necessário mascará-lo. Use com cuidado. |
|
n/d |
Desmascarar. Só será possível usar novamente um serviço mascarado depois que ele for desmascarado. |
|
n/d |
19.3 Inicialização do sistema e gerenciamento de destino #
Todo o processo de inicialização e encerramento do sistema é mantido pelo systemd
. Desse ponto de vista, o kernel pode ser considerado um processo em segundo plano para manter todos os outros processos e ajustar o horário da CPU e o acesso ao hardware de acordo com as solicitações de outros programas.
19.3.1 Comparação entre destinos e níveis de execução #
Com o init do System V, o sistema era inicializado no chamado “Nível de execução”. O nível de execução define como o sistema é iniciado e quais serviços estão disponíveis no sistema em execução. Os níveis de execução são numerados: os mais conhecidos são 0
(encerramento do sistema), 3
(multiusuário com rede) e 5
(multiusuário com rede e gerenciador de exibição).
O systemd
apresenta um novo conceito usando as chamadas “unidades de destino”. No entanto, ele continua totalmente compatível com o conceito de nível de execução. As unidades de destino são nomeadas, e não numeradas, e possuem finalidades específicas. Por exemplo, os destinos local-fs.target
e swap.target
montam sistemas de arquivos locais e espaços de troca.
O destino graphical.target
oferece recursos de sistema multiusuário com rede e gerenciador de exibição e equivale ao nível de execução 5. Destinos complexos, como graphical.target
, agem como destinos “meta”, combinando um subconjunto de outros destinos. Como o systemd
facilita criar destinos personalizados combinando destinos existentes, ele oferece excelente flexibilidade.
A lista a seguir mostra as unidades de destino mais importantes do systemd
. Para ver a lista completa, consulte man 7 systemd.special
.
systemd
#default.target
O destino que é inicializado por padrão. Não um destino “real”, mas um link simbólico para outro destino, como
graphic.target
. Pode ser modificado permanentemente pelo YaST (consulte a Seção 19.4, “Gerenciando serviços com o YaST”). Para mudá-lo em uma sessão, use o parâmetro do kernelsystemd.unit=MY_TARGET.target
no prompt de boot.emergency.target
Inicia o shell de emergência no console. Use-o apenas no prompt de boot como
systemd.unit=emergency.target
.graphical.target
Inicia um sistema com suporte a rede multiusuário e um gerenciador de exibição.
halt.target
Encerra o sistema.
mail-transfer-agent.target
Inicia todos os serviços necessários para enviar e receber e-mails.
multi-user.target
Inicia um sistema multiusuário com rede.
reboot.target
Reinicializa o sistema.
rescue.target
Inicia um sistema de usuário único sem rede.
Para continuar compatível com o sistema de nível de execução init do System V, o systemd
oferece destinos especiais chamados runlevelX.target
que mapeiam os níveis de execução correspondentes numerados X.
Para saber o destino atual, use o comando: systemctl get-default
systemd
#
Nível de execução do System V |
|
Finalidade |
---|---|---|
0 |
|
Encerramento do sistema |
1, S |
|
Modo de usuário único |
2 |
|
Multiusuário local sem rede remota |
3 |
|
Multiusuário completo com rede |
4 |
|
Não usado/Definido pelo usuário |
5 |
|
Multiusuário completo com rede e gerenciador de exibição |
6 |
|
Reinicialização do sistema |
systemd
ignora /etc/inittab
Os níveis de execução em um sistema init do System V são configurados em /etc/inittab
. O systemd
não usa essa configuração. Consulte a Seção 19.5.4, “Criando destinos personalizados” para obter instruções sobre como criar seu próprio destino inicializável.
19.3.1.1 Comandos para mudar os destinos #
Use os seguintes comandos para operar com unidades de destino:
Tarefa |
Comando |
Comando init do System V |
---|---|---|
Mudar o destino/nível de execução atual |
|
|
Mudar para o destino/nível de execução padrão |
|
n/d |
Obter o destino/nível de execução atual |
Com o |
ou
|
Mudar o nível de execução padrão de forma persistente |
Use o Gerenciador de Serviços ou execute o seguinte comando:
|
Use o Gerenciador de Serviços ou mude a linha
na |
Mudar o nível de execução padrão para o processo de boot atual |
Digite a seguinte opção no prompt de boot
|
Digite o número do nível de execução desejado no prompt de boot. |
Mostrar as dependências de um destino/nível de execução |
“Requires” lista as dependências obrigatórias (hard) (aquelas que devem ser resolvidas), enquanto “Wants” lista as dependências desejadas (soft) (aquelas que são resolvidas quando possível). |
n/d |
19.3.2 Depurando a inicialização do sistema #
O systemd
oferece os meios para a análise dos processos de inicialização do sistema. É possível revisar a lista de todos os serviços e os respectivos status (em vez de analisar o /var/log/
). O systemd
permite também explorar o procedimento de inicialização para descobrir quanto tempo leva para inicializar cada serviço.
19.3.2.1 Revisar inicialização dos serviços #
Para revisar a lista completa dos serviços que foram iniciados desde a inicialização do sistema, digite o comando systemctl
. Ele lista todos os serviços ativos, conforme mostrado a seguir (resumidamente). Para obter mais informações sobre um determinado serviço, use systemctl status
MY_SERVICE
.
#
systemctl
UNIT LOAD ACTIVE SUB JOB DESCRIPTION
[...]
iscsi.service loaded active exited Login and scanning of iSC+
kmod-static-nodes.service loaded active exited Create list of required s+
libvirtd.service loaded active running Virtualization daemon
nscd.service loaded active running Name Service Cache Daemon
chronyd.service loaded active running NTP Server Daemon
polkit.service loaded active running Authorization Manager
postfix.service loaded active running Postfix Mail Transport Ag+
rc-local.service loaded active exited /etc/init.d/boot.local Co+
rsyslog.service loaded active running System Logging Service
[...]
LOAD = Reflects whether the unit definition was properly loaded.
ACTIVE = The high-level unit activation state, i.e. generalization of SUB.
SUB = The low-level unit activation state, values depend on unit type.
161 loaded units listed. Pass --all to see loaded but inactive units, too.
To show all installed unit files use 'systemctl list-unit-files'.
Para restringir a saída a serviços com falha na inicialização, use a opção --failed
:
#
systemctl --failed
UNIT LOAD ACTIVE SUB JOB DESCRIPTION
apache2.service loaded failed failed apache
NetworkManager.service loaded failed failed Network Manager
plymouth-start.service loaded failed failed Show Plymouth Boot Screen
[...]
19.3.2.2 Depurar o tempo de inicialização #
Para depurar o tempo de inicialização do sistema, o systemd
oferece o comando systemd-analyze
. Ele mostra o tempo total de inicialização, uma lista dos serviços solicitados por tempo de inicialização e também gera um gráfico SVG mostrando o tempo que os serviços levaram para serem iniciados em relação a outros serviços.
- Listando o tempo de inicialização do sistema
#
systemd-analyze Startup finished in 2666ms (kernel) + 21961ms (userspace) = 24628ms- Listando o tempo de inicialização dos serviços
#
systemd-analyze blame 15.000s backup-rpmdb.service 14.879s mandb.service 7.646s backup-sysconfig.service 4.940s postfix.service 4.921s logrotate.service 4.640s libvirtd.service 4.519s display-manager.service 3.921s btrfsmaintenance-refresh.service 3.466s lvm2-monitor.service 2.774s plymouth-quit-wait.service 2.591s firewalld.service 2.137s initrd-switch-root.service 1.954s ModemManager.service 1.528s rsyslog.service 1.378s apparmor.service [...]- Gráficos do tempo de inicialização dos serviços
#
systemd-analyze plot > jupiter.example.com-startup.svg
19.3.2.3 Revisar o processo de inicialização completo #
Os comandos acima listam os serviços que são iniciados e os respectivos tempos de inicialização. Para obter uma visão geral mais detalhada, especifique os parâmetros a seguir no prompt de boot para instruir o systemd
a criar um registro verboso do procedimento completo de inicialização.
systemd.log_level=debug systemd.log_target=kmsg
Agora o systemd
grava suas mensagens de registro no buffer de anel do kernel. Veja esse buffer com dmesg
:
>
dmesg -T | less
19.3.3 Compatibilidade com o System V #
O systemd
é compatível com o System V, o que ainda permite usar os scripts init existentes do System V. Entretanto, há pelo menos um problema conhecido em que o script init do System V não funciona com o systemd
out-of-the-box: iniciar um serviço como outro usuário por meio de su
ou sudo
nos scripts init resulta em falha do script, gerando um erro de “Acesso negado”.
Ao mudar o usuário com su
ou sudo
, é iniciada uma sessão PAM. Essa sessão será terminada após a conclusão do script init. Como consequência, o serviço que foi iniciado pelo script init também será terminado. Para solucionar esse erro, faça o seguinte:
Crie um agrupador de arquivo de serviço com o mesmo nome do script init e mais a extensão de nome de arquivo
.service
:[Unit] Description=DESCRIPTION After=network.target [Service] User=USER Type=forking1 PIDFile=PATH TO PID FILE1 ExecStart=PATH TO INIT SCRIPT start ExecStop=PATH TO INIT SCRIPT stop ExecStopPost=/usr/bin/rm -f PATH TO PID FILE1 [Install] WantedBy=multi-user.target2
Substitua todos os valores gravados em UPPERCASE LETTERS pelos valores apropriados.
Inicie o daemon com
systemctl start APPLICATION
.
19.4 Gerenciando serviços com o YaST #
O gerenciamento básico de serviços também pode ser feito com o módulo Gerenciador de Serviços do YaST. Ele permite iniciar, parar, habilitar e desabilitar serviços. Ele permite também mostrar o status e mudar o destino padrão de um serviço. Inicie o módulo do YaST em
› › (Gerenciador de Serviços).- Mudando o
Para mudar o destino de inicialização do sistema, escolha o destino na caixa suspensa
(Destino Padrão do Sistema). Os destinos mais usados são (Interface Gráfica) (iniciando uma tela gráfica de login) e (iniciando o sistema no modo de linha de comando).- Iniciando ou parando um serviço
Selecione um serviço da tabela. A coluna
mostra se ele está em execução ( ) ou não ( ). Para alternar o status, escolha ou .Quando um serviço é iniciado ou parado, seu status muda na sessão que está em execução. Para mudar seu status em todas as reinicializações, é necessário habilitá-lo ou desabilitá-lo.
- Definindo o comportamento de inicialização dos serviços
Os serviços podem ser iniciados automaticamente no momento da inicialização ou manualmente. Selecione um serviço da tabela. A coluna
mostra se ele foi iniciado ou . Para alternar o status, escolha .Para mudar o status de um serviço na sessão atual, você precisa iniciá-lo ou interrompê-lo conforme descrito acima.
- Ver uma mensagem de status
Para ver a mensagem de status de um serviço, selecione-o na lista e escolha
. A saída exibida será idêntica a que foi gerada pelo comandosystemctl
-l
status MY_SERVICE.
19.5 Personalizando systemd
#
As seções a seguir mostram alguns exemplos de personalização do systemd
.
Ao personalizar o systemd
, use sempre o diretório /etc/systemd/
, nunca use o /usr/lib/systemd/
. Do contrário, as mudanças serão sobregravadas na próxima atualização do systemd
.
19.5.1 Personalizando os arquivos unit #
A maneira recomendada de personalizar arquivos unit é usar o comando systemctl edit SERVICE
. Esse comando inicia o editor de texto padrão e cria um diretório com o arquivo override.conf
em /etc/systemd/system/NAME.service.d/
. O comando também garante que o processo systemd
em execução seja notificado sobre as mudanças.
Se preferir, você poderá abrir uma cópia do arquivo original para edição em vez de um arquivo em branco executando systemctl edit --full
SERVICE
. Ao editar o arquivo, não remova nenhuma das seções existentes.
Como exercício, mude por quanto tempo o sistema aguarda pela inicialização do MariaDB. Como root, execute systemctl edit --full
mariadb.service
. O arquivo aberto terá aparência similar à seguinte:
[Unit] Description=MySQL server Wants=basic.target Conflicts=mariadb.target After=basic.target network.target [Install] WantedBy=multi-user.target Alias=mysql.service [Service] Restart=on-abort Type=notify ExecStartPre=/usr/lib/mysql/mysql-systemd-helper install ExecStartPre=/usr/lib/mysql/mysql-systemd-helper upgrade ExecStart=/usr/lib/mysql/mysql-systemd-helper start # Configures the time to wait for start-up/stop TimeoutSec=300 # Prevent writes to /usr, /boot, and /etc ProtectSystem=full # Prevent accessing /home, /root and /run/user ProtectHome=true UMask=007
Ajuste o valor de TimeoutSec
e grave as mudanças. Para habilitar as mudanças, execute systemctl
daemon-reload
como root.
Para obter mais informações, consulte as páginas de manual que podem ser chamadas com o comando man 1 systemctl
.
19.5.2 Criando arquivos drop-in #
Para pequenas mudanças de um arquivo de configuração, use os chamados arquivos drop-in. Esses arquivos permitem estender a configuração dos arquivos de unidade sem ter que editá-los ou anulá-los realmente.
Por exemplo, para mudar um valor único no serviço FOOBAR localizado em /usr/lib/systemd/system/FOOBAR.SERVICE
, faça o seguinte:
Crie um diretório chamado
/etc/systemd/system/FOOBAR.service.d/
.Observe o sufixo
.d
. O diretório deve receber outro nome de acordo com o serviço que você deseja corrigir com o arquivo dropin.Nesse diretório, crie um arquivo
your_modification.conf
.Verifique se ele contém somente a linha com o valor que deseja modificar.
Grave as mudanças feitas no arquivo
Para evitar conflitos de nome entre os arquivos drop-in e os arquivos fornecidos pelo SUSE, é recomendável prefixar todos os nomes de arquivos drop-in com um número de dois dígitos e um traço: por exemplo, 80-override.conf
.
As seguintes faixas são reservadas:
0-19
é reservada para upstream dosystemd
20-25
é reservada para osystemd
fornecido pelo SUSE26-29
é reservada para pacotes do SUSE (diferentes do systemd)50
é reservada para arquivos drop-in criados comsystemctl set-property
.
Use um número de dois dígitos acima dessa faixa para garantir que nenhum dos arquivos drop-in fornecidos pelo SUSE anule os seus próprios arquivos drop-in.
Você pode usar systemctl cat $UNIT
para listar e verificar quais arquivos são levados em consideração na configuração dos units.
19.5.3 Convertendo serviços xinetd
em systemd
#
Desde o lançamento do SUSE Linux Enterprise Desktop 15, a infraestrutura do xinetd
foi removida. Esta seção descreve como converter arquivos existentes de serviço do xinetd
em soquetes do systemd
.
Para cada arquivo de serviço do xinetd
, você precisa de pelo menos dois arquivos de unidade do systemd
: o arquivo de soquete (*.socket
) e um arquivo de serviço associado (*.service
). O arquivo de soquete informa ao systemd
qual soquete criar, e o arquivo de serviço informa ao systemd
qual executável iniciar.
Considere o seguinte arquivo de serviço do xinetd
de exemplo:
#
cat /etc/xinetd.d/example
service example
{
socket_type = stream
protocol = tcp
port = 10085
wait = no
user = user
group = users
groups = yes
server = /usr/libexec/example/exampled
server_args = -auth=bsdtcp exampledump
disable = no
}
Para convertê-lo em systemd
, você precisa dos dois arquivos correspondentes a seguir:
#
cat /usr/lib/systemd/system/example.socket
[Socket]
ListenStream=0.0.0.0:10085
Accept=false
[Install]
WantedBy=sockets.target
#
cat /usr/lib/systemd/system/example.service
[Unit]
Description=example
[Service]
ExecStart=/usr/libexec/example/exampled -auth=bsdtcp exampledump
User=user
Group=users
StandardInput=socket
Para obter uma lista completa das opções de arquivo de systemd
“soquete” e de “serviço”, consulte as páginas de manual do systemd.socket e do systemd.service (man 5 systemd.socket
, man 5 systemd.service
).
19.5.4 Criando destinos personalizados #
Nos sistemas init SUSE do System V, o nível de execução 4 não costuma ser usado para permitir que administradores criem sua própria configuração de nível de execução. O systemd
permite criar qualquer número de destinos personalizados. A sugestão é começar adaptando um destino existente, como graphical.target
.
Copie o arquivo de configuração
/usr/lib/systemd/system/graphical.target
para/etc/systemd/system/MY_TARGET.target
e ajuste-o de acordo com as suas necessidades.O arquivo de configuração copiado na etapa anterior já inclui as dependências obrigatórias (“hard”) do destino. Para cobrir também as dependências desejadas (“soft”), crie um diretório
/etc/systemd/system/MY_TARGET.target.wants
.Para cada serviço desejado, crie um link simbólico de
/usr/lib/systemd/system
para/etc/systemd/system/MY_TARGET.target.wants
.Após concluir a configuração do destino, recarregue a configuração do
systemd
para disponibilizar o novo destino:>
sudo
systemctl daemon-reload
19.6 Uso avançado #
As seções a seguir abordam tópicos avançados para administradores do sistema. Para conferir uma documentação ainda mais avançada do systemd
, consulte a série de Lennart Pöttering sobre o systemd
para administradores em http://0pointer.de/blog/projects.
19.6.1 Limpando diretórios temporários #
O systemd
suporta a limpeza de diretórios temporários regularmente. A configuração da versão do sistema anterior é automaticamente migrada e ativada. O tmpfiles.d
, que é responsável por gerenciar arquivos temporários, lê a configuração nos arquivos /etc/tmpfiles.d/*.conf
, /run/tmpfiles.d/*.conf
e /usr/lib/tmpfiles.d/*.conf
. A configuração armazenada no /etc/tmpfiles.d/*.conf
anula as configurações relacionadas dos outros dois diretórios (/usr/lib/tmpfiles.d/*.conf
é o local onde os pacotes armazenam seus arquivos de configuração).
O formato da configuração é de uma linha por caminho incluindo ação e caminho; e, opcionalmente, modo, propriedade e os campos de idade e argumento, dependendo da ação. O exemplo a seguir desvincula os arquivos de bloqueio do X11:
Type Path Mode UID GID Age Argument r /tmp/.X[0-9]*-lock
Para obter o status do temporizador tmpfile:
>
sudo
systemctl status systemd-tmpfiles-clean.timer systemd-tmpfiles-clean.timer - Daily Cleanup of Temporary Directories Loaded: loaded (/usr/lib/systemd/system/systemd-tmpfiles-clean.timer; static) Active: active (waiting) since Tue 2018-04-09 15:30:36 CEST; 1 weeks 6 days ago Docs: man:tmpfiles.d(5) man:systemd-tmpfiles(8) Apr 09 15:30:36 jupiter systemd[1]: Starting Daily Cleanup of Temporary Directories. Apr 09 15:30:36 jupiter systemd[1]: Started Daily Cleanup of Temporary Directories.
Para obter mais informações sobre como lidar com os arquivos temporários, consulte man 5
tmpfiles.d
.
19.6.2 Registro do sistema #
A Seção 19.6.9, “Depurando serviços” explica como ver mensagens de registro de determinado serviço. No entanto, a exibição de mensagens de registro não se restringe a registros de serviços. É possível também acessar e consultar as mensagens de registro completas gravadas pelo systemd
, o chamado “Diário”. Use o comando journalctl
para exibir as mensagens de registro completas começando pelas entradas mais antigas. Consulte man 1
journalctl
para ver as opções. Por exemplo, aplicação de filtros ou mudança do formato de saída.
19.6.3 Instantâneos #
É possível gravar o estado atual do systemd
em um instantâneo nomeado e mais tarde revertê-lo com o subcomando isolate
. Isso é útil para testar serviços ou destinos personalizados, pois permite retornar para um estado definido a qualquer momento. Um instantâneo só fica disponível na sessão atual e é apagado automaticamente na reinicialização. O nome do instantâneo deve terminar com .snapshot
.
- Criar um instantâneo
>
sudo
systemctl snapshot MY_SNAPSHOT.snapshot- Apagar um instantâneo
>
sudo
systemctl delete MY_SNAPSHOT.snapshot- Ver um instantâneo
>
sudo
systemctl show MY_SNAPSHOT.snapshot- Ativar um instantâneo
>
sudo
systemctl isolate MY_SNAPSHOT.snapshot
19.6.4 Carregando módulos do kernel #
Com o systemd
, é possível carregar os módulos do kernel automaticamente no momento da inicialização, usando o arquivo de configuração em /etc/modules-load.d
. O arquivo deve ser nomeado MODULE.conf e ter o seguinte conteúdo:
# load module MODULE at boot time MODULE
Se um pacote instalar um arquivo de configuração para carregar um módulo do kernel, o arquivo será instalado em /usr/lib/modules-load.d
. Se houver dois arquivos de configuração com o mesmo nome, aquele em /etc/modules-load.d
terá precedência.
Para obter mais informações, consulte a página de manual de modules-load.d(5)
.
19.6.5 Executando ações antes de carregar um serviço #
Com o System V, as ações init que precisam ser executadas antes de carregar um serviço tinham que ser especificadas em /etc/init.d/before.local
. Esse procedimento não é mais suportado com o systemd
. Se você precisa executar ações antes de iniciar serviços, faça o seguinte:
- Carregando módulos do kernel
Crie um arquivo drop-in no diretório
/etc/modules-load.d
(consulteman modules-load.d
para ver a sintaxe)- Criando arquivos ou diretórios, limpando diretórios, mudando a propriedade
Crie um arquivo drop-in em
/etc/tmpfiles.d
(consulteman tmpfiles.d
para ver a sintaxe)- Outras tarefas
Crie um arquivo de serviço de sistema, por exemplo
/etc/systemd/system/before.service
, com base no seguinte gabarito:[Unit] Before=NAME OF THE SERVICE YOU WANT THIS SERVICE TO BE STARTED BEFORE [Service] Type=oneshot RemainAfterExit=true ExecStart=YOUR_COMMAND # beware, executable is run directly, not through a shell, check the man pages # systemd.service and systemd.unit for full syntax [Install] # target in which to start the service WantedBy=multi-user.target #WantedBy=graphical.target
Quando o arquivo de serviço é criado, você deve executar os seguintes comandos (como
root
):>
sudo
systemctl daemon-reload>
sudo
systemctl enable beforeToda vez que você modifica o arquivo de serviço, deve executar:
>
sudo
systemctl daemon-reload
19.6.6 Grupos de controle (cgroups) do kernel #
Em um sistema init tradicional do System V, nem sempre é possível atribuir claramente um processo ao serviço que o gerou. Alguns serviços, como o Apache, geram diversos processos de terceiros (por exemplo, processos CGI ou Java) que, por sua vez, geram mais processos. Isso dificulta ou até impossibilita uma atribuição clara. Além do mais, um serviço pode não ser terminado corretamente, deixando alguns filhos ativos.
O systemd
resolve este problema colocando cada serviço em seu próprio grupo de controle (cgroup). Cgroups são recursos do kernel que possibilitam agregar processos e todos os seus filhos em grupos hierárquicos organizados. O systemd
nomeia cada cgroup de acordo com seu serviço. Como um processo não privilegiado não pode “deixar” seu cgroup, essa é uma forma eficiente de rotular todos os processos gerados por um serviço com o nome do serviço.
Para listar todos os processos pertencentes a um serviço, use o comando systemd-cgls
. O resultado será parecido com o seguinte exemplo (resumido):
#
systemd-cgls --no-pager
├─1 /usr/lib/systemd/systemd --switched-root --system --deserialize 20
├─user.slice
│ └─user-1000.slice
│ ├─session-102.scope
│ │ ├─12426 gdm-session-worker [pam/gdm-password]
│ │ ├─15831 gdm-session-worker [pam/gdm-password]
│ │ ├─15839 gdm-session-worker [pam/gdm-password]
│ │ ├─15858 /usr/lib/gnome-terminal-server
[...]
└─system.slice
├─systemd-hostnamed.service
│ └─17616 /usr/lib/systemd/systemd-hostnamed
├─cron.service
│ └─1689 /usr/sbin/cron -n
├─postfix.service
│ ├─ 1676 /usr/lib/postfix/master -w
│ ├─ 1679 qmgr -l -t fifo -u
│ └─15590 pickup -l -t fifo -u
├─sshd.service
│ └─1436 /usr/sbin/sshd -D
[...]
Consulte o Chapter 10, Kernel control groups para obter mais informações sobre os cgroups.
19.6.7 Terminando os serviços (enviando sinais) #
Conforme explicado na Seção 19.6.6, “Grupos de controle (cgroups) do kernel”, nem sempre é possível atribuir um processo a seu processo de serviço pai em um sistema init do System V. Isso dificulta parar um serviço e todos os seus filhos. Os processos filhos que não forem terminados permanecerão como processos zumbis.
O conceito do systemd
de confinar cada serviço em um cgroup possibilita identificar todos os processos filhos de um serviço e, portanto, permite enviar um sinal a cada um desses processos. Use systemctl kill
para enviar sinais aos serviços. Para ver uma lista dos sinais disponíveis, consulte man 7 signals
.
- Enviando
SIGTERM
para um serviço SIGTERM
é o sinal padrão que é enviado.>
sudo
systemctl kill MY_SERVICE- Enviando SIGNAL para um serviço
Use a opção
-s
para especificar o sinal que deve ser enviado.>
sudo
systemctl kill -s SIGNAL MY_SERVICE- Selecionando processos
Por padrão, o comando
kill
envia o sinal paraall
os processos do cgroup especificado. É possível restringi-lo ao processocontrol
oumain
. Este último, por exemplo, é útil para forçar um serviço a recarregar sua configuração enviandoSIGHUP
:>
sudo
systemctl kill -s SIGHUP --kill-who=main MY_SERVICE
19.6.8 Notas importantes sobre o serviço D-Bus #
O serviço D-BUS é o barramento de mensagem para comunicação entre clientes systemd
e o gerenciador systemd que está sendo executado como pid 1. Embora o dbus
seja um daemon independente, ele é parte integrante da infraestrutura do init.
Terminar ou reiniciar o dbus
no sistema em execução é semelhante a uma tentativa de terminar ou reiniciar o pid 1. Isso interromperá a comunicação entre cliente e servidor systemd
e inutilizará a maioria das funções do systemd
.
Portanto, terminar ou reiniciar o dbus
não é recomendado nem suportado.
A atualização do dbus
ou dos pacotes relacionados ao dbus
requer uma reinicialização. Quando estiver em dúvida se uma reinicialização é necessária, execute o comando sudo zypper ps
-s
. Se dbus
aparecer entre os serviços listados, será necessário reinicializar o sistema.
Saiba que o dbus
é atualizado mesmo quando as atualizações automáticas estão configuradas para ignorar os pacotes que exigem reinicialização.
19.6.9 Depurando serviços #
Por padrão, o systemd
não é muito verboso. Se um serviço for iniciado com êxito, nenhuma saída será gerada. Em caso de falha, uma breve mensagem de erro será exibida. Porém, o systemctl
status
oferece os meios de depurar a inicialização e operação de um serviço.
O systemd
já vem com um mecanismo de registro (“The Journal” — O Diário) que registra as mensagens do sistema. Isso permite exibir as mensagens de serviço juntamente com as mensagens de status. O comando status
funciona de forma parecida com o comando tail
e também exibe as mensagens de registro em formatos diferentes, o que faz dele uma poderosa ferramenta de depuração.
- Mostrar falha na inicialização de serviço
Sempre que houver falha ao iniciar um serviço, use
systemctl status MY_SERVICE
para obter a mensagem de erro detalhada:#
systemctl start apache2 Job failed. See system journal and 'systemctl status' for details.#
systemctl status apache2 Loaded: loaded (/usr/lib/systemd/system/apache2.service; disabled) Active: failed (Result: exit-code) since Mon, 04 Apr 2018 16:52:26 +0200; 29s ago Process: 3088 ExecStart=/usr/sbin/start_apache2 -D SYSTEMD -k start (code=exited, status=1/FAILURE) CGroup: name=systemd:/system/apache2.service Apr 04 16:52:26 g144 start_apache2[3088]: httpd2-prefork: Syntax error on line 205 of /etc/apache2/httpd.conf: Syntax error on li...alHost>- Mostrar as últimas N mensagens de serviço
O comportamento padrão do subcomando
status
é exibir as dez últimas mensagens emitidas por um serviço. Para mudar o número de mensagens exibidas, use o parâmetro--lines=N
:>
sudo
systemctl status chronyd>
sudo
systemctl --lines=20 status chronyd- Mostrar as mensagens de serviço no modo de anexação
Para exibir um “fluxo ao vivo” das mensagens de serviço, use a opção
--follow
, que funciona como otail
-f
:>
sudo
systemctl --follow status chronyd- Formato de saída das mensagens
O parâmetro
--output=MODE
permite mudar o formato de saída das mensagens de serviço. Os modos mais importantes disponíveis são:short
O formato padrão. Mostra as mensagens de registro com uma marcação de horário legível.
verbose
Saída completa com todos os campos.
cat
Saída resumida sem marcações de horário.
19.7 Unidades do temporizador do systemd
#
Semelhante ao cron, as unidades do temporizador do systemd
oferecem um mecanismo para programar tarefas no Linux. Embora as unidades do temporizador do systemd
tenham a mesma finalidade que o cron, elas oferecem várias vantagens.
As tarefas programadas usando uma unidade do temporizador podem depender de outros serviços do
systemd
.As unidades do temporizador são tratadas como serviços regulares do
systemd
, portanto, podem ser gerenciadas com osystemctl
.Os temporizadores podem ser em tempo real e monotônicos.
As unidades de tempo são registradas no diário do
systemd
, o que facilita o monitoramento e a solução de problemas.
As unidades do temporizador do systemd
são identificadas pela extensão de nome de arquivo .timer
.
19.7.1 Tipos de temporizador do systemd
#
As unidades do temporizador podem usar temporizadores monotônicos e em tempo real.
Semelhante ao cron, os temporizadores em tempo real são acionados com base em eventos do calendário. Os temporizadores em tempo real são definidos usando a opção
OnCalendar
.Os temporizadores monotônicos são acionados em um tempo especificado decorrido a partir de um determinado ponto inicial. O último pode ser um evento de boot do sistema ou de ativação da unidade do sistema. Há várias opções para definir temporizadores monotônicos, incluindo
OnBootSec
,OnUnitActiveSec
eOnTypeSec
. Os temporizadores monotônicos não são persistentes e são redefinidos após cada reinicialização.
19.7.2 Temporizadores e unidades de serviço do systemd
#
Cada unidade do temporizador deve ter um arquivo de unidade do systemd
correspondente que ela controla. Em outras palavras, o arquivo .timer
ativa e gerencia o arquivo .service
correspondente. Quando usado com um temporizador, o arquivo .service
não requer uma seção [Install]
, já que o serviço é gerenciado pelo temporizador.
19.7.3 Exemplo prático #
Para entender os conceitos básicos das unidades do temporizador do systemd
, configuramos um temporizador que aciona o script shell foo.sh
.
A primeira etapa é criar uma unidade de serviço do systemd
que controle o script shell. Para fazer isso, abra um novo arquivo de texto para edição e adicione a seguinte definição de unidade de serviço:
[Unit] Description="Foo shell script" [Service] ExecStart=/usr/local/bin/foo.sh
Grave o arquivo com o nome foo.service
no diretório /etc/systemd/system/
.
Em seguida, abra um novo arquivo de texto para edição e adicione a seguinte definição do temporizador:
[Unit] Description="Run foo shell script" [Timer] OnBootSec=5min OnUnitActiveSec=24h Unit=foo.service [Install] WantedBy=multi-user.target
A seção [Timer]
no exemplo acima especifica qual serviço acionar (foo.service
) e quando acioná-lo. Nesse caso, a opção OnBootSec
especifica um temporizador monotônico que aciona o serviço cinco minutos após o boot do sistema, enquanto a opção OnUnitActiveSec
aciona o serviço 24 horas após a ativação do serviço (ou seja, o temporizador acionará o serviço uma vez por dia). Por fim, a opção WantedBy
especifica que o temporizador deve ser iniciado quando o sistema atingir o destino de multiusuários.
Em vez de um temporizador monotônico, você pode especificar um em tempo real usando a opção OnCalendar
. A seguinte definição do temporizador em tempo real aciona a unidade de serviço relacionada uma vez por semana, começando na segunda-feira às 12:00.
[Timer] OnCalendar=weekly Persistent=true
A opção Persistent=true
indica que o serviço será acionado logo após a ativação do temporizador, se o temporizador tiver perdido o último horário de início (por exemplo, porque o sistema estava desligado).
A opção OnCalendar
também pode ser usada para definir horários e datas específicos para acionar um serviço usando o seguinte formato: DayOfWeek Year-Month-Day Hour:Minute:Second
. O exemplo abaixo aciona um serviço às 5:00 todos os dias:
OnCalendar=*-*-* 5:00:00
Você pode usar um asterisco para especificar qualquer valor e vírgulas para listar os valores possíveis. Use dois valores separados por .. para indicar uma faixa contígua. O exemplo a seguir aciona um serviço às 18:00 todas as sextas-feiras do mês:
OnCalendar=Fri *-*-1..7 18:00:00
Para acionar um serviço em horários diferentes, você pode especificar várias entradas OnCalendar
:
OnCalendar=Mon..Fri 10:00 OnCalendar=Sat,Sun 22:00
No exemplo acima, um serviço é acionado às 10:00 nos dias da semana e às 22:00 nos fins de semana.
Quando você terminar de editar o arquivo de unidade do temporizador, grave-o com o nome foo.timer
no diretório /etc/systemd/system/
. Para verificar se os arquivos de unidade criados estão corretos, execute o seguinte comando:
>
sudo
systemd-analyze verify /etc/systemd/system/foo.*
Se o comando não retornar nenhuma saída, os arquivos foram aprovados na verificação.
Para iniciar o temporizador, use o comando sudo systemctl start
foo.timer
. Para habilitar o temporizador na inicialização, execute o comando sudo systemctl enable foo.timer
.
19.7.4 Gerenciando temporizadores do systemd
#
Como os temporizadores são tratados como unidades regulares do systemd
, você pode gerenciá-los usando o systemctl
. Você pode iniciar um temporizador com systemctl start
, habilitar um temporizador com systemctl enable
e assim por diante. Além disso, você pode listar todos os temporizadores ativos usando o comando systemctl
list-timers
. Para listar todos os temporizadores, incluindo os inativos, execute o comando systemctl list-timers --all
.
19.8 Mais informações #
Para obter mais informações sobre o systemd
, consulte os seguintes recursos online:
- Home page
systemd
para administradoresLennart Pöttering, um dos criadores do
systemd
, escreveu uma série de entradas de blog (13 até o fechamento deste capítulo). Encontre-os em http://0pointer.de/blog/projects.