O que exatamente o init faz?

43

Estou criando uma distribuição Linux e agora preciso de um programa init. Posso codificar c muito bem e sei um pouco sobre linux (não muito, mas estou usando o arch linux para desenvolvimento há 4 anos), então pensei em tentar escrever meu próprio script básico de inicialização em C. apenas imaginando, que tarefas o init faz para configurar o sistema para um shell simples? (Quando pergunto "o que o init faz?", Sei o que é o init e para que serve. Só não sei quais tarefas ele executa.)

Eu não preciso de código e eu possivelmente não precisa mesmo de comandos básicos, mas eu não preciso de ordem em que são executados em.

DividedByZero
fonte
1
Você pode usar o interpretador que desejar para scripts init do estilo SysV, incluindo Perl, awk, bash, (t) csh, binários nativos, ... O Bash é normalmente usado porque é praticamente garantido que ele está disponível no sistema em que esses scripts são. implantado no ponto relevante no processo de inicialização, não porque haja algum acoplamento entre o SysVinit e o bash. O SysVinit define o contrato e cada script é livre para implementá-lo da maneira que seu desenvolvedor achar conveniente.
um CVn

Respostas:

53

O sistema 5 initlhe dirá apenas uma pequena parte da história.

Há uma espécie de miopia que afeta o mundo do Linux. As pessoas pensam que usam algo chamado "Sistema 5 init", e é isso que é tradicional e o melhor lugar para começar. Nem é de fato o caso.

A tradição não é de fato o que essas pessoas dizem que é, para começar. O Sistema 5 inite o Sistema 5 rcdatam do Sistema 5 da AT&T UNIX, que foi quase tão longe após o primeiro UNIX quanto agora (digamos) após a primeira versão do Linux-Mandrake.

1ª edição UNIX só tinha init. Não tinha rc. A linguagem assembly da 1ª edição init( cujo código foi restaurado e disponibilizado por Warren Toomey et al. ) Gerou e reapareceu diretamente 12 gettyprocessos, montou 3 sistemas de arquivos conectados a partir de uma tabela embutida e executou diretamente um programa no diretório inicial de um usuário nomeado mel. A gettytabela também estava diretamente na imagem do programa.

Foi mais uma década depois do UNIX System 5 que surgiu o chamado sistema "Linux" tradicional "init". Em 1992, Miquel van Smoorenburg (re) escreveu um Linux init+ rce suas ferramentas associadas, que as pessoas agora chamam de "Sistema 5 init", mesmo que não seja realmente o software do UNIX System 5 (e não é apenas init)

O Sistema 5 init/ rcnão é o melhor lugar para começar, e mesmo que se acrescente um conhecimento do systemd que não cubra metade do que há para saber. Tem havido muito trabalho na área de design de sistemas init (para Linux e BSDs) que aconteceu apenas nas últimas duas décadas. Todo tipo de decisão de engenharia foi discutida, tomada, projetada, implementada e praticada. Os Unices comerciais também fizeram muito.

Sistemas existentes para estudar e aprender com

Aqui está uma lista incompleta de alguns dos principais sistemas init, além daqueles dois e um ou dois de seus (vários) pontos salientes:

  • O finito de Joachim Nilsson seguiu o caminho de usar um arquivo de configuração mais legível por humanos.
  • O minit de Felix von Leitner foi para um sistema de configuração de sistema de arquivos é o banco de dados, pequenas áreas de memória e dependências de iniciar / parar entre as coisas que initcomeçam.
  • A runit de Gerrit Pape foi para o que eu descrevi anteriormente como a abordagem de apenas quatro scripts shell .
  • O InitNG visava ter dependências, destinos nomeados, vários arquivos de configuração e uma sintaxe de configuração mais flexível, com uma carga completa de mais configurações para processos filhos.
  • o iniciante foi reformulado, modelando o sistema não como serviços e interdependências, mas como eventos e tarefas acionados por eles.
  • O design do nosh inclui transferir todo o gerenciamento de serviços (incluindo até a gettycriação de zumbis e os zumbis) para um gerenciador de serviços separado, e apenas manipular dispositivos / APIs / links simbólicos / diretórios específicos de sistemas operacionais "API" do sistema operacional.
  • Sinit é um init muito simples. Ele executa /bin/rc.initcujo trabalho é iniciar programas, montar o sistema de arquivos, etc. Para isso, você pode usar algo como minirc .

Além disso, há cerca de 10 anos, houve uma discussão entre os usuários do daemontools e outros sobre o uso do svscanprocesso nº 1, o que levou a projetos como o svscan de Paul Jarc como estudo do processo 1 , as idéias de Gerrit Pape e o svscan de Laurent Bercot como o processo 1 .

O que nos leva ao processo nº 1 dos programas.

Que programas do processo nº 1 fazem

As noções sobre o que o processo nº 1 "deve" fazer são, por natureza, subjetivas. Um critério de design objetivo significativo é o que o processo nº 1, no mínimo, deve fazer. O kernel impõe vários requisitos a ele. E sempre há algumas coisas específicas de sistema operacional de vários tipos que ele precisa fazer. Quando se trata do processo nº 1 tradicionalmente realizado, não estamos no mínimo e nunca estivemos realmente.

Há várias coisas que vários kernels do sistema operacional e outros programas exigem do processo nº 1, dos quais simplesmente não podemos escapar.

As pessoas lhe dirão que fork()agir e agir como pai de processos órfãos é a principal função do processo nº 1. Ironicamente, isso é falso. Lidar com processos órfãos é (com os kernels recentes do Linux, conforme explicado em https://unix.stackexchange.com/a/177361/5132 ) uma parte do sistema que pode ser amplamente fatorado fora do processo nº 1 em outros processos, como um gerente de serviço dedicado . Todos esses são gerentes de serviço, que são executados no processo 1:

  • o srcmstrprograma IBM AIX , o System Resource Controller
  • Gerrit Pape's runsvdirde runit
  • Daniel J. Bernstein é svscande daemontools, de Adam Sampson svscande freedt , de Bruce Guenter svscande daemontools-bis, e Laurent Bercot de s6-svscanpartir S6
  • Wayne Marshall's perpdde perp
  • o Service Management Facility no Solaris 10
  • o service-managerde nosh

Da mesma forma, conforme explicado em https://superuser.com/a/888936/38062 , toda a /dev/initctlideia não precisa estar nem perto do processo nº 1. Ironicamente, é o sistema altamente centralizado que demonstra que pode ser movido para fora do processo nº 1.

Por outro lado, as coisas obrigatórias para init, que as pessoas costumam esquecer em seus desenhos off-the-top-of-the-cabeça, são coisas como a manipulação SIGINT, SIGPWR, SIGWINCH, e assim por diante enviados do kernel e articulado dos vários pedidos de mudança de estado do sistema enviados de programas que "sabem" que certos sinais para processar o número 1 significam certas coisas. (Por exemplo: Conforme explicado em https://unix.stackexchange.com/a/196471/5132 , os conjuntos de ferramentas BSD "sabem" que SIGUSR1têm um significado específico.)

Também existem tarefas únicas de inicialização e finalização, das quais não se pode escapar, ou sofrerá muito com isso, como montar sistemas de arquivos "API" ou liberar o cache do sistema de arquivos.

Os princípios básicos para lidar com sistemas de arquivos "API" são um pouco diferentes da operação do initrom 1st Edition UNIX: Um possui uma lista de informações conectadas ao programa e simplesmente mount()todas as entradas da lista. Você encontrará esse mecanismo em sistemas tão diversos quanto o BSD (sic!) init, Através do nariz system-manager, para o systemd.

"configure o sistema para um shell simples"

Como você observou, init=/bin/shnão monta sistemas de arquivos "API", trava de maneira desajeitada, sem descarga de cache quando se digita exit( https://unix.stackexchange.com/a/195978/5132 ), e geralmente deixa ao (super) usuário executar manualmente as ações que tornam o sistema minimamente utilizável.

Para ver o que realmente não tem escolha a não ser fazer nos programas nº 1 do processo e, assim, definir um bom caminho para seu objetivo de projeto declarado, sua melhor opção é observar as sobreposições na operação do runit de Gerrit Pape, Felix von Minit de Leitner e o system-managerprograma do pacote nosh. Os dois primeiros mostram duas tentativas de serem minimalistas, mas ainda lidam com o que é impossível evitar.

O último é útil, sugiro, por sua extensa entrada manual para o system-managerprograma, que detalha exatamente quais sistemas de arquivos "API" são montados, quais tarefas de inicialização são executadas e quais sinais são manipulados; em um sistema que, por padrão , o gerente do sistema gera apenas três outras coisas (o gerente de serviço, um criador de logs acompanhante e o programa para executar as alterações de estado) e só faz o inevitável no processo # 1.

JdeBP
fonte
3
Resposta incrível e muito informativo. Mas eu estou me perguntando onde, nessa grande figura, está o OSX launchd. Às vezes, as pessoas esquecem completamente que o OSX é um (ótimo) membro da grande família * nix.
DavAlPi
4

O System V init no Debian (existem outras variantes e variações) faz o seguinte:

  • Ao inserir um nível de execução, ele chama scripts em /etc/rcX.d/S*ordem alfanumérica, onde Xestá o nível de execução. Esses scripts devem configurar o nível de execução. A configuração típica está iniciando daemons e executa tarefas de configuração para esse nível de execução. Isso é algo único ao entrar no nível de execução.
  • Enquanto estiver em um nível de execução, ele inicia os daemons listados /etc/inittabcomo precisando estar ativos durante esse nível de execução. Se esses daemons pararem de funcionar, eles serão reiniciados. Embora você possa ter qualquer daemon que você deseja gerenciar init, no mínimo você deseja alguns gettypara poder efetuar login. gettySai assim que o login é concluído e o initreinicia, fornecendo um novo prompt de login.
    • Se o daemon reiniciar muitas vezes em pouco tempo, ele pára de tentar reiniciá-lo por um tempo.
    • Só porque algo foi iniciado pelos scripts de kickoff ao entrar no nível de execução não faz initautomaticamente tentar mantê-lo em execução. Você precisa especificar isso separadamente no /etc/inittab.
  • Ao sair de um nível de execução, ele chama os scripts em /etc/rcX.d/K*ordem alfanumérica, onde Xestá o nível de execução. Uma maneira de implementar o encerramento ou reinicialização é definir um nível de execução para esses eventos e fazer com que a última tarefa seja executada no comando haltou reboot.
  • Ele chamará executáveis ​​em resposta a determinados eventos, como eventos de energia ou Ctrl-Alt-Del.
  • Ele escuta em um soquete; se receber determinadas mensagens, mudará o nível de execução.

Portanto, você pode usar initcomo gerenciador de serviço rudimentar, se quiser, mas a principal tarefa hoje em dia é manter gettya disponibilidade para que um usuário possa fazer login e iniciar transições no nível de execução.

Eu estava pensando, que tarefas o init faz para configurar o sistema para um shell simples?

O que você quiser. No Debian, em cada /etc/rcX.ddiretório existe um link simbólico para um script /etc/init.de você pode personalizar ou remover completamente esses scripts. A ordem é estabelecida por cada script anterior com um 00, 01, etc.

Você também pode especificar uma -bopção para init(ou seja, via linha de comando do kernel) se você quiser initgerar um shell. Quando você sai do shell, initmorre e quando initmorre, o kernel entra em pânico.

LawrenceC
fonte
2

O mínimo absoluto que o init deve fazer é executar pelo menos um outro programa e nunca sair. Se o init sair, o sistema trava. Suponho que nem mesmo a execução de um outro programa seja estritamente necessário, mas se você não fizer isso, o init teria que ser responsável por fazer tudo o que se espera que o sistema faça, ou isso não seria muito útil.

hildred
fonte
1
Eu tive sistemas Linux com erros, onde o PID 1 travou, mas o sistema basicamente continuou funcionando. O quão ruim é a falha do PID 1 pode depender da versão do kernel.
Gilles 'SO- stop be evil'
1

init pode fazer o que quiser

init é um executável arbitrário chamado pelo kernel do Linux no final do processo de inicialização (e o único executável).

É normalmente implementado como um executável ELF, mas pode até ser um script de shell com chmod +x: Init como um script de shell

Implementações típicas, como o sysemd, costumam ler arquivos de configuração /etc/initrce, em seguida, dividem vários processos da terra do usuário com base nessas configurações, para implementar vários aspectos do sistema.

No entanto, isso é completamente específico da implementação e, portanto, sua pergunta não pode ser respondida sem especificar uma implementação específica. Por exemplo, eu estou jogando com um initprocesso que simplesmente faz um rebootsyscall para fins educacionais.

O kernel do Linux simplesmente procura o executável no caminho /initpor padrão, mas isso pode ser substituído pelo init=parâmetro de linha de comando do kernel do Linux.

Uma ótima maneira de brincar inité usar o QEMU, pois você pode passar os parâmetros da linha de comando do kernel para o QEMU a partir da linha de comando do QEMU com a -appendopção e sem o medo de bloquear a área de trabalho.

Aqui está minha configuração mínima do Buildroot + QEMU, totalmente automatizada, que facilita a interação com suas próprias unidades para desmistificar o problema.

Ciro Santilli adicionou uma nova foto
fonte
0

Se você está comprometido com o princípio modular "faça uma coisa e faça bem", um initprograma deve iniciar processos.

Iniciar processos

Ele deve ser executado assim que o kernel for descompactado com êxito, cuidando de todas as tarefas rudimentares envolvidas na inicialização de todos os processos iniciais que um sistema requer para operar (como montar unidades encontradas no / etc / fstab, exibir interfaces de rede e em breve).

Como o processo de inicialização e desligamento é essencialmente inverso um do outro, é comum que um programa init também garanta que os processos sejam interrompidos mediante um comando de desligamento.

Parar processos

Isso significa que ele deve interromper os processos de acordo com a página de manual desse processo (em outras palavras, não apenas flagrante kill -9, deve reduzir o processo da maneira que deseja terminar), desmontar unidades e, finalmente, emitir o comando final de desligamento .

Referências

Uma boa referência de como isso é feito por outras pessoas é olhar para os scripts /etc/rc.d do Slackware e também para um sistema init simples que já existe, como o ninit (um sucessor para minit). Possui supervisão de processo (o que significa que, se um processo morre, é relançado), o que provavelmente não é o trabalho do init, mas ainda é bastante básico e simples de entender, especialmente através dos scripts de exemplo do autor.

Klaatu von Schlacker
fonte