Pelo que entendi, o systemd é o daemon "mestre" do Linux, gerenciando todos os outros processos logo após ser inicializado e executar sua função init. Como eu tive esse problema (agora resolvido), de não poder usar nenhum comando systemd no WSL, percebi que ele não possui um processo systemd.
Agora, por curiosidade, eu queria saber, em qual gerenciamento de processos o WSL depende em vez do systemd. Como não encontrei uma resposta satisfatória na "pesquisa geral do google", pensei, vamos tentar aqui.
Atualização: a partir de hoje, a Microsoft integrou o suporte ao Systemd no WSL2, começando com o WSL 0.67.2 (atualmente em versão prévia). Conforme observado na minha resposta original (abaixo) e outras aqui, não é necessário e é opcional.
A versão de visualização 0.67.2 está disponível:
Observe que ele funcionará apenas no Windows 11. As versões mais recentes do WSL não estão disponíveis para o Windows 10.
Neste ponto, eu ainda não testei o recurso, mas em breve o farei.
Meu pensamento inicial é que você deve ter muito cuidado ao usar isso em seu design atual. O devblog faz a declaração:
Em outras palavras, se (por exemplo) você habilitar o MariaDb para executar através de sua unidade Systemd, ele terminará logo após você sair do último shell, a menos que você tenha algum outro serviço em segundo plano em execução. A menos que algo tenha mudado, esta não é uma terminação "segura".
Atualizarei esta resposta com mais informações à medida que souber mais.
Resposta original, que ainda é aplicável a versões lançadas existentes do WSL, especialmente em sistemas Windows 10 que não podem ser atualizados para usar a nova versão mencionada acima.
Ótima pergunta - Tanta coisa divertida para cobrir aqui!
Primeiro, vamos estabelecer alguma terminologia:
Primeiro, um bom ponto de @mascoj nos comentários é que o Systemd não é exigido pelo Linux. Certamente é usado na grande maioria das distribuições Linux, mas existem outras alternativas (como a resposta do @ user1686 menciona) que são anteriores e vêm desde o Systemd. Algumas distribuições usam essas alternativas por padrão e (opinião pessoal) algumas dessas distribuições podem funcionar melhor na WSL como resultado.
Em um nível alto, o Systemd normalmente atende a várias funções:
cron
,sshd
,mariadb
, etc.)A maioria dessas funções pode ser tratada separadamente, mas o Systemd "faz tudo".
Algumas distribuições e sistemas não dependem do Systemd e fazem as coisas de forma menos monolítica. Por exemplo, alguns sistemas fazem com que o sistema init passe o controle para um supervisor de processo separado em algum ponto durante a inicialização. O supervisor de processo pode ou não ser PID1. Se não for, normalmente o processo de inicialização permanece como PID1 e o supervisor de processo é executado sob ele. O supervisor de processo normalmente tem uma lista de serviços que são desejados no momento da inicialização e os executa e monitora.
Algumas distribuições (Artix me vem à mente, e tenho certeza que o Gentoo também) permitem que você misture e combine vários sistemas de inicialização e supervisores de processo diferentes.
Agora vamos abordar a questão do título em alto nível:
WSL2:
É importante entender que, quando você está executando uma distribuição WSL2, essa distribuição não está sendo executada em uma máquina virtual. O próprio WSL2 está executando uma máquina virtual com sua própria distribuição (provavelmente baseada no Mariner , se eu tivesse que adivinhar).
Dentro dessa máquina virtual oculta é onde sua distribuição é executada em seu próprio conjunto de namespaces. Se você executar mais de uma distribuição ao mesmo tempo no WSL2, todas elas serão executadas na mesma VM, cada uma com sua própria:
No entanto, todos eles compartilham o seguinte com a VM WSL2 pai (e, portanto, entre si):
/dev/pts
)/init
binário (mas não processo)Isso é muito, muito semelhante à maneira como os sistemas de contêiner, como Docker ou Podman (e outros), funcionam.
E dentro da maioria dos contêineres (mas certamente não de todos), você achará raro que um supervisor de processo esteja em execução.
A maioria dos contêineres são informados sobre quais serviços devem ser iniciados pelo processo "externo" (como o Docker) que os inicia. No caso do WSL, tradicionalmente existe o
wsl
comando com o qual você informa ao WSL quais serviços devem ser iniciados. Por exemplo (um exemplo simplificado e não necessariamente ótimo):No entanto, uma diferença importante é que, diferentemente dos contêineres tradicionais, o WSL sempre tem seu próprio processo de inicialização que é executado como PID1 (veja abaixo o motivo). Para a maioria dos outros tipos de contêiner, PID1 é o processo que você diz para iniciar primeiro.
WSL1
Embora o WSL1 não esteja tecnicamente "executando em um contêiner/namespace" como o WSL2, ele compartilha o mesmo conceito de Init para interoperabilidade.
Também é importante lembrar que o WSL1 não suporta todas as syscalls do Linux. Quando o WSL1 foi lançado pela primeira vez, sua cobertura estava em torno de 70% . Ele faz um ótimo trabalho ao executar um grande número de ferramentas, mas tenho a sensação de que o número de unidades que o Systemd normalmente tenta exibir provavelmente exporia algumas lacunas.
WSLg
O WSLg é executado no que é chamado de "distribuição do sistema", que é definitivamente baseada na distribuição do Mariner. Uma distribuição do sistema WSLg é criada para cada distribuição WSL2 que tenta executar aplicativos GUI.
Nesse caso, cabe à Microsoft determinar como iniciar os serviços necessários. Você pode criar sua própria distribuição de sistema, se desejar, e a Microsoft fornece uma implementação de referência para começar, mas provavelmente há muito pouca necessidade da funcionalidade do Systemd lá.
Nada disso quer dizer que executar um supervisor de processo no WSL (1 ou 2) não seria útil - seria em alguns casos. Mas, pessoalmente, fico feliz que a WSL deixe isso para o usuário. Isso permite que ele funcione como um contêiner (inicialização rápida, uso eficiente de recursos) por padrão, mas mais como (mas não exatamente) um "SO virtual" completo em outros casos.
E a pergunta principal:
Vamos dividi-lo nas funções que dissemos que o Systemd trata acima:
Sistema PID1/Init: Conforme mencionado acima, o
/init
sistema proprietário do WSL é usado para ambas as funções. Esse especial/init
é necessário porque lida com a integração profunda de interoperabilidade entre Linux e Windows. Os sistemas init tradicionais do Linux, como o Systemd, não têm ideia de como lidar com isso.Em teoria, o WSL2 poderia usar o Systemd para inicializar e configurar alguns serviços especiais para lidar com a integração, mas:
Isso adicionaria sobrecarga a uma inicialização muito simplificada
Algumas distribuições não usam Systemd, então elas teriam que configurar cada distribuição de forma diferente (melhor deixar isso para o usuário, se necessário).
É possível que
/init
ainda precise ser PID1 de qualquer maneira, para continuar a lidar com certos recursos de interoperabilidade mesmo após a inicialização.Como o Systemd exige que seja PID1, isso cria um pouco de conflito. Eu acho que a equipe da Microsoft está trabalhando nisso, mas claramente não é algo que foi resolvido ainda.
Supervisor/gerente de processo: o WSL2 realmente não possui um por padrão. No entanto, como @user1686 apontou em outra resposta , isso não foi um problema até recentemente. Foram criados scripts
service
para cada serviço, com pontos de entrada para o comando (ou similar) iniciar/parar/reiniciar/status.O Ubuntu, pelo menos, ainda fornece muitos desses scripts para serviços. Então, quando você quer iniciar
sshd
, por exemplo, você pode simplesmente executarsudo service ssh start
, que por sua vez chama seu script. O mesmo se você instalar o Maridb (sudo service mysql start
).No entanto, alguns serviços não fornecem scripts no estilo SysVInit. Eles podem fornecer apenas unidades Systemd, pelo menos em distribuições baseadas em Systemd. Isso simplesmente não funcionará (facilmente) em distribuições WSL. Veja esta resposta onde eu abordo as alternativas quando isso acontece.
Executar serviços na inicialização
No Windows 10, ainda não há uma ótima maneira de lidar com isso. Claro, uma distribuição WSL realmente não "inicializar", mas tem um "primeiro início" definido onde você pode querer executar algo.
No Windows 10, o melhor era iniciar os serviços manualmente ou executá-los por meio dos arquivos de inicialização do usuário (por exemplo
~/.bashrc
, ). Veja esta resposta para algumas idéias sobre isso.Mas parece que você está no Windows 11 (já que menciona o WSLg) e, nesse caso, há um recurso que permite especificar um comando (ou série de comandos) para ser executado uma vez quando a distribuição for iniciada. Novamente, veja esta resposta para obter informações sobre como configurar isso.
Executando um gerenciador de processos na inicialização
Usando essas técnicas, é perfeitamente possível executar qualquer supervisor de processo que você quiser, desde que não exija que seja PID1.
Alguns que eu tentei até agora na WSL:
Tanto o s6 quanto o dinit tendem a pensar que estão rodando em uma máquina física/virtual (naturalmente), então eles tentam fazer alguma inicialização que não é necessária no WSL. Consegui remover os itens desnecessários e, em seguida, dinit, pelo menos, funciona muito bem. No entanto, ainda não os transformei em um conjunto reproduzível de instruções para outros.
Executando Systemd
É até possível executar o Systemd, fingindo-o para que ele seja executado como PID1 dentro de um novo namespace dentro de uma distribuição WSL2 (mas não WSL1) (que, como discutimos, já está sendo executada em seu próprio namespace). Eu não recomendo necessariamente, pessoalmente, mas muitas pessoas o fazem. Eu abordo um pouco disso no final desta resposta da AU , então não vou repetir aqui.
Systemd é na verdade um projeto bastante recente, tendo sido iniciado em ~2010. Muitos outros foram usados antes dele: sysvinit, upstart, init-ng, s6, launchd (acho que já teve uma versão Linux). Várias distribuições Linux ainda não usam o systemd por vários motivos.
De todos esses, o systemd é o mais próximo que você poderia chamar de "gerenciador de processos". Na verdade, o Linux não depende de um gerenciador de processos; qualquer processo pode fazer diretamente (fork) um novo processo filho sempre que decidir, descontrolado. (Na verdade, tão descontrolado que quando o systemd começou a codificar coisas como "sair deve matar seus processos restantes", guerras foram travadas por causa disso.)
O verdadeiro trabalho principal do systemd e de outros programas desse tipo é apenas ser um gerenciador de serviços : iniciar automaticamente certos processos específicos, como o daemon responsável por exibir a tela de login (GDM, agetty) e – às vezes – reiniciá-los quando travam . Mas uma vez que você chega à tela de login, todo o resto pode acontecer sem o envolvimento do systemd/init.
De fato, com o sysvinit, o processo de inicialização real fez incrivelmente pouco: praticamente o único serviço que ele supervisionava era o agetty. Literalmente todo o resto foi feito através de scripts de shell comuns que nunca tocaram no init propriamente. O comando para iniciar um serviço? Script de concha. Todo o processo de inicialização inicial? Script de shell que executa mais scripts de shell.
Então, para algo como o WSL, que não quer se comportar como um sistema completo (não deveria ser como uma VM completa que você precisa inicializar antes de usar; iniciar o WSL deveria ser instantâneo, como se você estivesse literalmente executando aplicativos Linux no Windows), o processo de inicialização pode ser bastante mínimo. Eu realmente não sei o que o WSL2 usa, mas pode ser completamente personalizado.
(Para o WSL1, pode até não haver um processo de inicialização, já que o WSL1 nem é uma VM, mas apenas uma coleção de processos especiais que ainda são executados diretamente no Windows.)
O WSL 2 possui um sistema de inicialização personalizado que não é de código aberto (pelo menos não encontrei a fonte). Você pode ver seus processos com ferramentas como
ps
ouhtop
.É um binário multi-chamada que faz pelo menos o seguinte:
Você não pode ver todos esses processos/daemons porque alguns são executados fora de todos os contêineres WSL 2 (no namespace raiz).
Qualquer sistema init que possa ou não existir na distribuição não é usado. Em vez disso, os shells são gerados diretamente usando o ID do usuário configurado.
O Systemd não é uma parte inerente do Linux; muitas distribuições Linux não o utilizam. O WSL estará executando qualquer que seja a sua distribuição Linux instalada.