
Quero escrever meus próprios systemd
arquivos de unidade para gerenciar comandos 1 de execução realmente longa (na ordem de horas). Enquanto olhava oArtigo do ArchWiki sobre systemd, diz o seguinte sobre a escolha de um tipo de inicialização:
Type=simple
(padrão): o systemd considera que o serviço foi iniciado imediatamente.O processo não deve bifurcar. Não use este tipo se outros serviços precisarem ser solicitados neste serviço, a menos que esteja ativado por soquete.
Por que o processo não deve ser bifurcado? Está se referindo à bifurcação no estilo do processo de invocação do daemon (bifurca-se o pai e depois sai) ou qualquer tipo de bifurcação?
1 Não quero tmux/screen porque quero uma maneira mais elegante de verificar o status e reiniciar o serviço sem recorrer ao tmux send-keys
.
Responder1
O serviço tem permissão para chamar a fork
chamada do sistema. O Systemd não impedirá isso, nem mesmo notará se isso acontecer. Esta frase refere-se especificamente à prática de bifurcar no início de um daemon para isolar o daemon de seu processo pai. “O processo não deve bifurcar [e sair do pai enquanto executa o serviço em um processo filho]”.
Opágina de manualexplica isso de forma mais detalhada e com uma redação que não leva a essa confusão específica.
Muitos programas destinados a serem usados como daemons têm um modo (geralmente o modo padrão) onde, quando iniciados, eles se isolam de seu pai. O daemon inicia, chama fork()
e o pai sai. O processo filho chama setsid()
para ser executado em seu próprio grupo de processos e sessão e executa o serviço. O objetivo é que se o daemon for invocado a partir de uma linha de comando do shell, o daemon não receberá nenhum sinal do kernel ou do shell, mesmo se algo acontecer ao terminal, como o fechamento do terminal (nesse caso, o shell envia SIGHUP a todos os grupos de processos que conhece). Isso também faz com que o processo de serviço seja adotado pelo init, que o colherá quando sair, evitando umzumbise o daemon foi iniciado por algo que não seria wait()
adequado (isso não aconteceria se o daemon fosse iniciado por um shell).
Quando um daemon é iniciado por um processo de monitoramento como o systemd, a bifurcação é contraproducente. O processo de monitoramento deve reiniciar o serviço se ele falhar, por isso ele precisa saber se o serviço foi encerrado, e isso será difícil se o serviço não for filho direto do processo de monitoramento. O processo de monitoramento nunca deve morrer e não possui um terminal de controle, portanto, não há preocupações com sinais indesejados ou colheita. Portanto, não há razão para que o processo de serviço não seja filho do monitor, e há uma boa razão para que seja.
Responder2
Ignore esta página wiki do Arch.
Ele tem coisas consideravelmente erradas no que diz respeito ao Type
cenário. Além disso , isso não se limita apenas às descrições de simple
. O que diz forking
também está errado.
As recomendações corretas para esse tipo de coisa existem há décadas a mais do que o próprio systemd existe e remontam pelo menos ao início da década de 1990. Como observei emhttps://unix.stackexchange.com/a/476608/5132, no documento do systemd há uma versão recente das recomendações para daemons que repete em grande parte o que os usuários de daemontools, IBM, pessoas que usam inittab
e... bem... eu venho dizendo há décadas. (Já era uma resposta dada com frequência quando a escrevi como tal em 2001.)
Repetir:
Se o seu programa tiver algum mecanismo de "daemonização", que em particular bifurca um filho e sai do processo pai,Desligue issoenão use isso. Graças a daemontools et al. onde isso tem sido um requisito há muito tempo, muitos programas aumentaram a capacidade denão temtais mecanismos nos últimos mais de 20 anos, e outros simplesmente não adotam a "daemonização" como padrão, portanto podem ser usados em seus modos operacionais padrão.
Subsistemas de gerenciamento de serviços iniciam processos de serviçono contexto daemon já. Esses processos não precisam ser "daemonizados". (Na verdade, é uma falácia em muitos sistemas operacionais modernos pensar que os programas, mesmopode"dæmonize" a partir de um contexto de sessão de login, que é o que realmente significa "dæmonization".) Eles já possuem os valores de ambiente e os descritores de arquivos abertos, apropriados ao contexto do daemon, e as várias coisas feitas pela "dæmonization" de fatofrustraralgumas das coisas convencionais que são feitas regularmente com daemons (por exemplo, capturar suas saídas/erros padrão em um log) pelos gerentes de serviço.
Prefira Type=simple
, com abertura antecipada de soquete (onde o gerenciamento de serviço abre soquetes de servidor e os passa como descritores de arquivo já abertos para o programa de serviço), ou Type=notify
.
Type=simple
trata o serviço como pronto (para que os serviços solicitados possam ser iniciados/parados) assim que o processo do serviço é iniciado, com abertura antecipada de soquete empregando semântica de conexão de soquete para atrasar os clientes de serviço, nos pontos em que eles tentam se conectar aos servidores para serviço, até que os servidores estejam realmente prontos.Type=notify
tem a desvantagem de ser peculiar ao systemd e ao Linux (juntamente com os problemas de não ser funcional em processos de curta duração, como shell spawningsystemd-notify
e de empregar análise de formulários legíveis por humanos para formulários legíveis por máquina em um processo privilegiado, onde problemas de analisador têmjá aconteceuno passado), mas tem a vantagem de fornecer um controle mais preciso (do ponto de vista do programa de serviço) de quando o serviço é realmente considerado pronto. Também permite alguma personalização da saída de status.
Os programas de serviço, de ambos os tipos, podem ser bifurcados. Está bifurcandoe então saindo do processo originalesse é o problema.
(Deve-se notar que isso é um problema tanto para a execução de programas a partir de shells quanto para a execução de programas de gerenciadores de serviços, com os usuários vendo os programas serem encerrados e causando outro prompt de shell quase imediatamente. Na verdade, ainda hoje alguém estava perguntando, mais uma vez , sobre a execução de programas a partir do shell que bifurcam e saem do pai, emPor que às vezes quando executo um programa no terminal, ele não funciona no terminal?.)
Type=oneshot
provavelmente não é o que você deseja neste caso específico, pois o serviço é considerado pronto somente quando todo o programa de serviço estiver concluído. Tem seus usos, mas pelo que parece eles não se aplicam a você.
Nunca use Type=forking
. Deveria ser um último recurso de desespero, já que quase nenhum programarealmente fale o protocolo. Eles estão fazendoalgo mais, o que é na verdadenãoeste protocolo, não é corretamente interoperável com este protocolo e, de fato, não sinaliza prontidão.
Leitura adicional
- Jonathan de Boyne Pollard (2001). Erros a evitar ao projetar programas daemon Unix. Respostas dadas com frequência.
- Jonathan de Boyne Pollard (2015).Você realmente não precisa daemonizar. Realmente.. A Casa do Terror do sistema.
- Jonathan de Boyne Pollard (2015).Problemas de protocolo de prontidão com daemons Unix. Respostas dadas com frequência.
- https://unix.stackexchange.com/a/401611/5132