Especifica a dependência do systemd em qualquer uma das múltiplas unidades?

2

É possível especificar uma dependência do systemd em qualquer uma das várias unidades?

Atualmente, tenho uma unidade Z que depende de pelo menos um da unidade A ou unidade B.

Configurar a unidade A como WantedBy unit Z e a unidade B como WantedBy unit Z funciona principalmente.

No entanto, se apenas uma das unidades A ou B puder iniciar, o processo de inicialização aguardará o tempo limite da outra unidade antes de iniciar a unidade Z. Desejo eliminar esse tempo limite.

As unidades A e B requerem um tempo limite para funcionar corretamente, no entanto, uma vez que uma delas tenha sido iniciada, não há necessidade de esperar que a outra unidade atinja o tempo limite antes de iniciar a unidade Z.

Existe uma maneira de especificar que a unidade Z depende da unidade A ou da unidade B, mas não precisa esperar pela unidade A e pela unidade B antes de iniciar a unidade Z?

No mundo Debian, o sistema de empacotamento usa Provides para especificar algo similar ao que eu espero realizar aqui.

O que estou tentando realizar

O Debian costumava suportar uma opção keyscript em crypttab , mas não reimplementou essa opção quando o upstream reescreveu os scripts de inicialização para a mudança para systemd . Anteriormente, eu usava um keyscript para ler minha chave de uma unidade USB. Atualmente, estou usando um arquivo systemd unit para ocupar o lugar da opção keyscript (unidade A). Isso funciona perfeitamente. No entanto, as unidades USB são propensas a falhas; portanto, para redundância, eu quero carregar uma segunda cópia da minha chave em uma segunda unidade USB. E quero adicionar um segundo arquivo systemd unit para o segundo drive USB (unidade B), para que qualquer unidade USB seja inserida, systemd é capaz de usar esse drive USB e continuar sem tempo limite.

Outras coisas que tentei

Usando Conflicts para especificar que A está em conflito com B e B está em conflito com A. Infelizmente, o systemd processa o conflito antes de tentar iniciar uma das unidades A ou B e remove uma dessas unidades do agendador antes de tentar inicie a unidade restante. Então Z às vezes falha, por exemplo, se A falha, mas B teria conseguido, se B já foi eliminado da consideração devido ao conflito com A.

Usando JobTimeoutSec para reduzir o tempo limite. Infelizmente, isso pode resultar na falha de Z, se o tempo limite A e B.

Sugestões de Michael Hampton. Como ele menciona, o exemplo NTP cria uma dependência fraca entre cada cliente e o destino. Cada cliente NTP quer o destino, mas o destino não depende de cada um dos clientes NTP, então isso funciona. No entanto, o melhor que posso dizer é que uma dependência fraca não puxa a unidade, a menos que a unidade também tenha uma seção [Install] especificando uma dependência adicional. Então, quando eu pego minhas unidades A e B, a WantedBy na seção [Install] cria o tempo limite de bloqueio. Se eu remover a seção [Install] , as unidades A e B serão ignoradas.

    
por Daniel Kauffman 14.09.2016 / 22:05

2 respostas

2

Este é um trabalho para uma unidade de destino do systemd.

Em vez de dar um exemplo artificial, darei um exemplo do mundo real que já está presente em seu sistema.

Considere o NTP. A maioria dos computadores sincroniza via NTP, mas existem três (e talvez mais) clientes NTP que você pode escolher: systemd-timesyncd, chronyd ou (o clássico) ntpd.

Cada uma das unidades de serviço para esses clientes NTP faz parte de um destino chamado time-sync.target e exige isso de maneira fraca como tal.

Before=time-sync.target
Wants=time-sync.target

Assim, quando você inicia qualquer um dos clientes NTP, time-sync.target é inicializado depois que o cliente NTP é iniciado. Observe que time-sync.target está vazio e não faz nada sozinho.

Portanto, se você executar um serviço que requeira que a hora do sistema tenha sido sincronizada e que falhe de outra forma, será possível iniciá-lo somente após o início de time-sync.target .

After=time-sync.target
Requires=time-sync.target

Você deve ser capaz de adaptar isso facilmente ao seu próprio serviço.

    
por 20.09.2016 / 23:57
1

Acho que se esse recurso existisse, seria na página systemd.unit man e não vejo isso lá.

Uma solução pode ser usar um pequeno script bash que seja bem-sucedido assim que A ou B começar, ou falhar se ambos A & B não consegue iniciar.

    
por 20.09.2016 / 21:32

Tags