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.
Respostas:
O sistema 5
init
lhe 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
init
e o Sistema 5rc
datam 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 tinharc
. A linguagem assembly da 1ª ediçãoinit
( cujo código foi restaurado e disponibilizado por Warren Toomey et al. ) Gerou e reapareceu diretamente 12getty
processos, 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 nomeadomel
. Agetty
tabela 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
+rc
e suas ferramentas associadas, que as pessoas agora chamam de "Sistema 5init
", mesmo que não seja realmente o software do UNIX System 5 (e não é apenasinit
)O Sistema 5
init
/rc
nã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:
init
começam.getty
criaçã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./bin/rc.init
cujo 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
svscan
processo 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:srcmstr
programa IBM AIX , o System Resource Controllerrunsvdir
de runitsvscan
de daemontools, de Adam Sampsonsvscan
de freedt , de Bruce Guentersvscan
de daemontools-bis, e Laurent Bercot des6-svscan
partir S6perpd
de perpservice-manager
de noshDa mesma forma, conforme explicado em https://superuser.com/a/888936/38062 , toda a
/dev/initctl
ideia 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çãoSIGINT
,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" queSIGUSR1
tê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
init
rom 1st Edition UNIX: Um possui uma lista de informações conectadas ao programa e simplesmentemount()
todas as entradas da lista. Você encontrará esse mecanismo em sistemas tão diversos quanto o BSD (sic!)init
, Através do narizsystem-manager
, para o systemd."configure o sistema para um shell simples"
Como você observou,
init=/bin/sh
não monta sistemas de arquivos "API", trava de maneira desajeitada, sem descarga de cache quando se digitaexit
( 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-manager
programa 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-manager
programa, 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.fonte
launchd
. Às vezes, as pessoas esquecem completamente que o OSX é um (ótimo) membro da grande família * nix.O System V init no Debian (existem outras variantes e variações) faz o seguinte:
/etc/rcX.d/S*
ordem alfanumérica, ondeX
está 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./etc/inittab
como 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 gerenciarinit
, no mínimo você deseja algunsgetty
para poder efetuar login.getty
Sai assim que o login é concluído e oinit
reinicia, fornecendo um novo prompt de login.init
automaticamente tentar mantê-lo em execução. Você precisa especificar isso separadamente no/etc/inittab
./etc/rcX.d/K*
ordem alfanumérica, ondeX
está 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 comandohalt
oureboot
.Portanto, você pode usar
init
como gerenciador de serviço rudimentar, se quiser, mas a principal tarefa hoje em dia é mantergetty
a disponibilidade para que um usuário possa fazer login e iniciar transições no nível de execução.O que você quiser. No Debian, em cada
/etc/rcX.d
diretório existe um link simbólico para um script/etc/init.d
e você pode personalizar ou remover completamente esses scripts. A ordem é estabelecida por cada script anterior com um00
,01
, etc.Você também pode especificar uma
-b
opção parainit
(ou seja, via linha de comando do kernel) se você quiserinit
gerar um shell. Quando você sai do shell,init
morre e quandoinit
morre, o kernel entra em pânico.fonte
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.
fonte
init
pode fazer o que quiserinit é 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 shellImplementações típicas, como o sysemd, costumam ler arquivos de configuração
/etc/initrc
e, 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
init
processo que simplesmente faz umreboot
syscall para fins educacionais.O kernel do Linux simplesmente procura o executável no caminho
/init
por padrão, mas isso pode ser substituído peloinit=
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-append
opçã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.
fonte
Se você está comprometido com o princípio modular "faça uma coisa e faça bem", um
init
programa 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.
fonte