6.26. Iniciando e Parando Serviços (com scripts rc)

Os scripts rc.d são usados ​​para iniciar serviços na inicialização do sistema e para fornecer aos administradores uma maneira padrão de parar, iniciar e reiniciar o serviço. Ports se integram ao sistema de estrutura do rc.d. Detalhes sobre seu uso podem ser encontrados no capitulo sobre rc.d do handbook. A explicação detalhada dos comandos disponíveis é fornecida em rc(8) e rc.sub(8). Finalmente, existe um artigo sobre aspectos práticos do sistema de scripts do rc.d.

Com um port mítico chamadodoorman, o qual precisa iniciar um daemon doormand. Adicione o seguinte ao Makefile:

USE_RC_SUBR=	doormand

Vários scripts podem ser listados e serão instalados. Os scripts devem ser colocados no subdiretório files e um sufixo .in deve ser adicionado ao nome do arquivo. Expansões padrões SUB_LIST serão executadas neste arquivo. Usar as expansões %%PREFIX%% e %%LOCALBASE%% também é fortemente encorajado. Veja mais sobre a SUB_LIST na seção relevante.

A partir do FreeBSD 6.1-RELEASE, scripts locais rc.d (incluindo aqueles instalados pelos ports) estão incluídos no rcorder(8) do sistema base.

Um exemplo simples de script rc.d para iniciar o daemon doormand:

#!/bin/sh

# $FreeBSD$
#
# PROVIDE: doormand
# REQUIRE: LOGIN
# KEYWORD: shutdown
#
# Add these lines to /etc/rc.conf.local or /etc/rc.conf
# to enable this service:
#
# doormand_enable (bool):	Set to NO by default.
#				Set it to YES to enable doormand.
# doormand_config (path):	Set to %%PREFIX%%/etc/doormand/doormand.cf
#				by default.

. /etc/rc.subr

name=doormand
rcvar=doormand_enable

load_rc_config $name

: ${doormand_enable:="NO"}
: ${doormand_config="%%PREFIX%%/etc/doormand/doormand.cf"}

command=%%PREFIX%%/sbin/${name}
pidfile=/var/run/${name}.pid

command_args="-p $pidfile -f $doormand_config"

run_rc_command "$1"

A menos que haja uma boa razão para iniciar o serviço mais cedo, ou ele seja executado como um usuário específico (diferente de root), todos os scripts de ports devem usar:

REQUIRE: LOGIN

Se o script de inicialização iniciar um daemon que deve ser desligado, o seguinte acionará uma parada do serviço no desligamento do sistema:

KEYWORD: shutdown

Se o script não está iniciando um serviço persistente, isso não é necessário.

Para os elementos de configuração opcional o estilo "=" de atribuição de variável padrão é preferível ao estilo ":=", já que o primeiro define um valor padrão apenas se a variável não estiver definida, e o segundo define um se a variável não está definida ou se ela é nula. Um usuário pode muito bem incluir algo como:

doormand_flags=""

no seu rc.conf.local, e uma substituição de variável usando ":=" substituirá inadequadamente a intenção do usuário. A variável _enable não é opcional e deve usar o ":" por padrão.

Importante:

Os Ports não devem iniciar e parar seus serviços durante a instalação e desinstalação. Não abuse das keywords plist descritas em Seção 8.6.13.2, “@preexec command, @postexec command, @preunexec command, @postunexec command executando comandos que modificam o sistema em execução, incluindo iniciar ou interromper serviços.

6.26.1. Pre-Commit Checklist

Antes de contribuir um port com um script rc.d, e mais importante, antes de realizar o commit de um, por favor consulte esta lista de verificação para ter certeza de que ele está pronto.

O port devel/rclint pode verificar a maioria destes itens, mas não substitui uma revisão adequada.

  1. Se este é um novo arquivo, ele tem uma extensão .sh? Se assim for, isso deve ser mudado para apenas file.in uma vez que os arquivos rc.d não podem terminar com essa extensão.

  2. O arquivo tem uma tag $FreeBSD$?

  3. O nome do arquivo (menos .in), a linha PROVIDE e $name são as mesmas? O nome do arquivo ao corresponder com o PROVIDE irá facilitar a depuração, especialmente para problemas de rcorder(8). Combinar o nome do arquivo e o $name torna mais fácil descobrir quais variáveis ​​são relevantes no rc.conf[.local]. Isso também é uma política para todos os novos scripts, incluindo aqueles no sistema base.

  4. A linha REQUIRE está definida para LOGIN? Isso é obrigatório para scripts que são executados como um usuário não root. Se ele for executado como root, há uma boa razão para ele ser executado antes de LOGIN? Caso contrário, ele deve ser executado depois para que os scripts locais possam ser agrupados em um ponto no rcorder(8) depois que quase tudo no sistema base já estiver rodando.

  5. O script inicia um serviço persistente? Em caso afirmativo, ele deve ter o KEYWORD: shutdown.

  6. Certifique-se de que não há um KEYWORD: FreeBSD presente. Isto não foi necessário nem desejável durante anos. Isto também é uma indicação de que o novo script foi copiado/colado de um script antigo, portanto, um cuidado extra deve ser dado à revisão.

  7. Se o script usa uma linguagem interpretada como o perl, o python ou o ruby, certifique-se de que o command_interpreter está definido adequadamente, por exemplo, para o Perl, adicione PERL=${PERL} para a SUB_LIST e utilize %%PERL%%. De outra forma,

    # service name stop

    provavelmente não funcionará corretamente. Consulte service(8) para maiores informações.

  8. Todas as ocorrências de /usr/local foram substituídas por %%PREFIX%%?

  9. As atribuições das variáveis ​​padrão vêm depois de load_rc_config?

  10. Existem atribuições padrões para sequências vazias? Elas devem ser removidas, mas verifique se a opção está documentada nos comentários na parte superior do arquivo.

  11. As variáveis ​​definidas estão realmente sendo utilizadas no script?

  12. As opções listadas no padrão name_flags são realmente obrigatórias? Se assim for, elas devem estar em command_args. A opção -d é uma flag vermelha (com o perdão do trocadilho) aqui, já que geralmente é a opção de "daemonizar" o processo e, portanto, é realmente obrigatório.

  13. O name_flags nunca deve ser incluído em command_args (e vice-versa, embora esse erro seja menos comum).

  14. O script executa qualquer código incondicionalmente? Isso é desaprovado. Normalmente, essas coisas devem ser tratadas através de um start_precmd.

  15. Todos os testes booleanos devem usar a função checkyesno. Nenhum teste deve usar [Yy][Ee][Ss], etc.

  16. Se houver um loop (por exemplo, esperando que algo inicie), ele tem um contador para terminar o loop? Não queremos que a inicialização seja bloqueada para sempre se houver um erro.

  17. O script cria arquivos ou diretórios que precisam de permissões específicas, por exemplo, um pid que precisa ser de propriedade do usuário que executa o processo? Em vez da rotina tradicional touch(1)/chown(8)/chmod(1), considere usar install(1) com os argumentos de linha de comando apropriados para fazer todo o procedimento com um passo.

All FreeBSD documents are available for download at https://download.freebsd.org/ftp/doc/

Questions that are not answered by the documentation may be sent to <freebsd-questions@FreeBSD.org>.
Send questions about this document to <freebsd-doc@FreeBSD.org>.