Ir para o conteúdoIr para navegação de página: página anterior [tecla de acesso p]/próxima página [tecla de acesso n]
documentation.suse.com / Documentação do SUSE Linux Enterprise Desktop / Guia de Administração / Inicializando um sistema Linux / Daemon systemd
Aplica-se a SUSE Linux Enterprise Desktop 15 SP5

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 .socket

  • Caminho.  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.

Dica
Dica: Saída de terminal e complementação do bash

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:

Tabela 19.1: Comandos de gerenciamento de serviços

Tarefa

Comando systemd

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 httpd.conf modificado. Nem todos os serviços suportam o recarregamento.

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 systemd mostra detalhes, como descrição, executável, status, cgroup e as últimas mensagens emitidas por um serviço (consulte a Seção 19.6.9, “Depurando serviços”). O nível dos detalhes exibidos com o init do System V varia de acordo com cada serviço.

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:

Importante
Importante: Inicialização de serviço

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.

Tabela 19.2: Comandos para habilitar e desabilitar serviços

Tarefa

Comando systemd

Comando init do System V

Habilitar. 

systemctl enable MY_SERVICE(S)

insserv MY_SERVICE(S), chkconfig -a MY_SERVICE(S)

Desabilitar. 

systemctl disable MY_SERVICE(S).service

insserv -r MY_SERVICE(S), chkconfig -d MY_SERVICE(S)

Verificar.  Mostra se um serviço está ou não habilitado.

systemctl is-enabled MY_SERVICE

chkconfig MY_SERVICE

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.

systemctl reenable MY_SERVICE

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.

systemctl mask MY_SERVICE

n/d

Desmascarar.  Só será possível usar novamente um serviço mascarado depois que ele for desmascarado.

systemctl unmask MY_SERVICE

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.

Unidades de destino selecionadas do 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 kernel systemd.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

Tabela 19.3: Níveis de execução do System V e unidades de destino do systemd

Nível de execução do System V

systemd destino

Finalidade

0

runlevel0.target, halt.target, poweroff.target

Encerramento do sistema

1, S

runlevel1.target, rescue.target,

Modo de usuário único

2

runlevel2.target, multi-user.target,

Multiusuário local sem rede remota

3

runlevel3.target, multi-user.target,

Multiusuário completo com rede

4

runlevel4.target

Não usado/Definido pelo usuário

5

runlevel5.target, graphical.target,

Multiusuário completo com rede e gerenciador de exibição

6

runlevel6.target, reboot.target,

Reinicialização do sistema

Importante
Importante: 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 systemd

Comando init do System V

Mudar o destino/nível de execução atual

systemctl isolate MY_TARGET.destino

telinit X

Mudar para o destino/nível de execução padrão

systemctl default

n/d

Obter o destino/nível de execução atual

systemctl list-units --type=target

Com o systemd, normalmente há mais de um destino ativo. O comando lista todos os destinos que estão ativos.

who -r

ou

runlevel

Mudar o nível de execução padrão de forma persistente

Use o Gerenciador de Serviços ou execute o seguinte comando:

ln -sf /usr/lib/systemd/system/ MY_TARGET.target /etc/systemd/system/default.target

Use o Gerenciador de Serviços ou mude a linha

id: X:initdefault:

na /etc/inittab

Mudar o nível de execução padrão para o processo de boot atual

Digite a seguinte opção no prompt de boot

systemd.unit= MY_TARGET.destino

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

systemctl show -p "Requires" MY_TARGET.destino

systemctl show -p "Wants" MY_TARGET.destino

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.

Exemplo 19.1: Listar serviços ativos
# 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:

Exemplo 19.2: Listar serviços com falha
# 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
Image

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:

  1. 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.

    1

    Opcional: use apenas se o script init iniciar um daemon.

    2

    O multi-user.target também inicia o script init ao inicializar no graphical.target. Se ele tiver que ser iniciado apenas ao inicializar no gerenciador de exibição, use o graphical.target aqui.

  2. 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 YaST › Sistema › Services Manager (Gerenciador de Serviços).

Gerenciador de Serviços
Figura 19.1: Gerenciador de Serviços
Mudando o destino padrão do sistema

Para mudar o destino de inicialização do sistema, escolha o destino na caixa suspensa Default System Target (Destino Padrão do Sistema). Os destinos mais usados são Graphical Interface (Interface Gráfica) (iniciando uma tela gráfica de login) e Multiusuário (iniciando o sistema no modo de linha de comando).

Iniciando ou parando um serviço

Selecione um serviço da tabela. A coluna Estado mostra se ele está em execução (Ativo) ou não (Inativo). Para alternar o status, escolha Iniciar ou Parar.

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 Início mostra se ele foi iniciado Manualmente ou Na inicialização. Para alternar o status, escolha Modo de início.

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 Mostrar Detalhes. A saída exibida será idêntica a que foi gerada pelo comando systemctl -l status MY_SERVICE.

19.5 Personalizando systemd

As seções a seguir mostram alguns exemplos de personalização do systemd.

Atenção
Atenção: Impedindo que sua personalização seja sobregravada

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:

  1. 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.

  2. Nesse diretório, crie um arquivo your_modification.conf.

    Verifique se ele contém somente a linha com o valor que deseja modificar.

  3. Grave as mudanças feitas no arquivo

Nota
Nota: Evitando conflitos de nome

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 do systemd

  • 20-25 é reservada para o systemd fornecido pelo SUSE

  • 26-29 é reservada para pacotes do SUSE (diferentes do systemd)

  • 50 é reservada para arquivos drop-in criados com systemctl 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.

  1. 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.

  2. 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.

  3. Para cada serviço desejado, crie um link simbólico de /usr/lib/systemd/system para /etc/systemd/system/MY_TARGET.target.wants.

  4. 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 (consulte man 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 (consulte man 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 before

Toda 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):

Exemplo 19.3: Listar todos os processos pertencentes a um serviço
# 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 para all os processos do cgroup especificado. É possível restringi-lo ao processo control ou main. Este último, por exemplo, é útil para forçar um serviço a recarregar sua configuração enviando SIGHUP:

> 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 o tail -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 o systemctl.

  • 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 e OnTypeSec. 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

http://www.freedesktop.org/wiki/Software/systemd

systemd para administradores

Lennart 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.