%------------------------------------------------------------------------
\chapter{\cmd{init}}
\label{ch:init}
%------------------------------------------------------------------------

        \begin{chapterquote}
Uuno on numero yksi \\
        \end{chapterquote}

	\noindent
	Este capítulo descreve o processo \cmd{init}, o qual é o primeiro processo 
	de nível de usuário que é iniciado pelo kernel. O \cmd{init} tem diversas 
	tarefas importantes, como iniciar o \cmd{getty} (após o qual os usuário 
	podem acessar o sistema), implementar os níveis de execução, e tomar conta 
	dos processos órfãos. Este capítulo explica como o \cmd{init} é 
	configurado e como fazer uso dos diferentes níveis de execução.
\index{/sbin/init}
\index{init|see{/sbin/init}}
\index{servidores!init|see{/sbin/init}}
	
%%\section{\cmd{init} comes first}
\section{O \cmd{init} vem em primeiro lugar}


	O \cmd{init} é um dos programas absolutamente essenciais para a operação 
	de um sistema \linux, mas que a maioria dos usuários pode ignorar. Uma boa 
	distribuição do \linux\ conterá a configuração de um \cmd{init} que 
	funcionará com a maioria dos sistemas, e não haverá necessidade de fazer 
	absolutamente nada.
	Usualmente o administrador somente irá preocupar-se com o init caso
	necessite lidar com terminais seriais, modens configurados para
	atendimento (e não para chamadas) ou caso deseje mudar o nível de execução
	padrão do sistema.  


	Quando o kernel se auto inicializa (foi carregado em memória, começa a
	rodar e inicializa todos os dispositivos e estruturas de dados), 
	ele finaliza as suas tarefas na inicialização do sistema ao
	iniciar o programa de nível de usuário \cmd{init}. o \cmd{init} é sempre o 
	primeiro processo do sistema (o seu número de processo é sempre igual a~1). 
	%% ??? user level 

	
	O kernel procura pelo \cmd{init} em alguns diretórios que vem sendo 
	usados historicamente para isso, porém a localização correta no \linux\ 
	é o \fn{/sbin/init}. Caso o kernel não consiga encontrá-lo, ele executará o
	programa \fn{/bin/sh} e caso isso também falhe, a inicialização do sistema
	é abortada.           
	

	Quando o \cmd{init} começa, ele finaliza o processo de inicialização ao 
	executar uma série de tarefas administrativas como a checagem dos 
	sistemas de arquivos, limpeza do \fn{/tmp}, início de vários serviços e 
	inicialização do \cmd{getty} para cada terminal e console virtual através 
	dos quais os usuários serão autorizados a acessar o sistema (veja o 
	capítulo~\ref{ch:logins}).   
	

	Após o sistema ter sido adequadamente inicializado, o \cmd{init} reinicia o
	\cmd{getty} para cada terminal após a saída do usuário do sistema 
	(permitindo que o próximo usuário possa acessar o sistema). Além disso, o 
	\cmd{init} adota também todos os processos órfãos: quando um processo 
	inicia um processo filho e é finalizado antes dele, imediatamente o 
	processo restante torna-se filho do \cmd{init}. Isso é importante por 
	várias razões técnicas, mas é bom conhecer para entender as listas de 
	processos e a árvore de processos.\footnote{o \cmd{init} por si só não 
	pode morrer. Você não pode matá-lo mesmo com um SIGKILL.}
	

	Há poucas variantes disponíveis do \cmd{init}. Muitas distribuições do 
	\linux\ usam o \cmd{sysvinit} (escrita por Miquel van Smoorenburg), a qual 
	é baseada no \cmd{init} do System V. As versões BSD do \unix\ tem um 
	\cmd{init} diferente. A diferença reside nos níveis de execução: presentes 
	no System V, mas não no BSD (pelo menos tradicionalmente).
	Essa diferença não é essencial e nós examinaremos somente o \cmd{sysvinit}.

	
%%\section{Configuring \cmd{init} to start \cmd{getty}: the \fn{/etc/inittab} file}
\section{configurando o \cmd{init} para inicializar o \cmd{getty}: o arquivo \fn{/etc/inittab}}

	Quando é inicializado, o  \cmd{init} lê o arquivo de configuração
	\fn{/etc/inittab}. Enquanto o sistema estiver no ar, ele será lido 
	novamente, caso seja enviado um sinal HUP\footnote{usando o comando
	\cmd{kill~-HUP~1}, como root}, tornando desnecessário reinicializar o
	sistema para que as mudanças do \cmd{init} façam efeito.


	O arquivo \fn{/etc/inittab} é um pouco complicado. Começaremos pelo
	caso mais simples, ou seja, configurando as linhas do \cmd{getty}. As 
	linhas do \fn{/etc/inittab} consistem de quatro campo delimitados por dois
	pontos:
		%
\begin{quote}
\textsl{id:nível:ação:processo}
\end{quote}
		%
	Os campos são descritos a seguir. O \fn{/etc/inittab} podem conter
	algumas linhas vazias, e linhas que comecem com `\verb|#|' serão 
	consideradas comentários.
	
	\begin{dispitems}
	\item[id]	
			Identifica a linha no arquivo. Para linhas referentes ao \cmd{getty}
			especifica o terminal em que eles são executados (os caracteres 
			após o \fn{/dev/tty} no nome do arquivo de dispositivo). Para 
			outras linhas não tem efeito (exceto pelas restrições de tamanho), 
			e devem ser únicas.
	\item[nível]
			Os níveis de execução em que a linha deve ser considerada.
			Os níveis de execução são definidos através de dígitos sem
			delimitadores e são melhor descritos na próxima seção.
	\item[ação]
			Define a ação que deve ser tomada pela linha. Por exemplo, 
			\texttt{respawn} para executar novamente o comando do próximo 
			campo, quando este encerra seu processamento ou \texttt{once} para 
			executá-lo somente uma única vez.   
	\item[processo]	
			O comando a ser executado.
	\end{dispitems}
	

	Para iniciar o \cmd{getty}\footnote{atualmente para terminais virtuais do 
	console utiliza-se o \cmd{mingetty}} no primeiro terminal virtual 
	(\fn{/dev/tty1}), 
	em todos os modos de execução multiusuário (de 2 a 5), pode-se informar a 
	seguinte linha:  
		%
\begin{tscreen}
1:12345:respawn:/sbin/getty 9600 tty1
\end{tscreen}
		%
	O primeiro campo diz que a linha deve ser executada para \fn{/dev/tty1}. O
	segundo que ele aplica-se aos níveis de execução de 1 a 5. O terceiro que
	o comando deve ser reinicializado quando o processo termina (ou seja 
	quando um usuário desconectar-se de um terminal, o \cmd{getty} será 
	executado novamente para que outro usuário possa conectar-se). O último 
	campo executa o processo getty no primeiro terminal virtual\footnote{
	Diferentes versões do \cmd{getty} rodam de maneira diferente. Consulte 
	a página de manual para maiores informações}.         
	
	Caso necessite adicionar terminais ou modens para atendimento de chamadas
	ao sistema, deve-se adicionar mais linhas ao arquivo \fn{/etc/inittab}, uma
	para cada terminal ou modem. Para maiores detalhes veja as páginas de
	manual do \man{init}(8), \man{inittab}(5), \man{mingetty}(8) e 
	\man{mgetty}(8). 
	
	Caso o comando falhe ao ser executado, e o \cmd{init} esteja configurado 
	para \texttt{reinicializá-lo}, isso certamente consumirá uma grande 
	quantidade de recursos pois o processo de iniciar o comando se repetirá 
	indefinidamente. Para prevenir esse tipo de problema, o \cmd{init} 
	verificará a freqüência de reinicialização do comando e caso esta seja 
	muito grande, o \cmd{init} aguardará automaticamente por cinco minutos 
	antes de iniciá-lo novamente.     
	
%%\section{Run levels}
\section{Níveis de execução}

	\defin{Nível de execução} é o estado do \cmd{init} e de todo o sistema que 
	define que serviços estarão operacionais.  Eles são identificados por 
	números, de acordo com a tabela~\ref{tab:run-levels}. Não há nenhum 
	consenso de como utilizar os níveis definidos para usuário (de 2 a 5). 
	Alguns administradores de sistema utilizam os níveis de execução para 
	definir quais subsistemas serão executados, por exemplo se o X estará 
	disponível ou as funcionalidades de rede e assim por diante. Outros têm 
	todos os subsistemas sendo ativados e sendo finalizados individualmente, 
	sem mudar o nível de execução, já que este pode ser um pouco complexo para 
	controlar seus sistemas. Cada administrador deve definir qual o método 
	mais adequado às suas necessidades, porém seguir a forma definida pela 
	distribuição em uso deve ser o meio mais simples. 
	
		\begin{table}[h]
		\caption{Níveis de execução}
		\label{tab:run-levels}
		\begin{center}
		\begin{tabular}{ll}
		\hline
		0 & desligue. \\
		1 & monousuário. \\
		2 & multiusuário, sem NFS. \\
		3 & multiusuário completo. \\
		4 & não usado. \\
		5 & X11. \\
		6 & reinicialize. \\
		\hline
		\end{tabular}
		\end{center}
		\end{table}

	Níveis de execução são configurados no \fn{/etc/inittab} por linhas como 
	as seguintes:
		%
\begin{tscreen}
%%l2:2:wait:/etc/init.d/rc 2
l2:2:wait:/etc/rc.d/rc 2
\end{tscreen}
		%
	O primeiro campo é um rótulo arbitrário; o segundo significa que ele se
	aplica ao nível de execução 2. O terceiro significa que o \cmd{init} deve
	executar o comando contido no quarto campo uma única vez, quando o sistema
	entrar neste nível, e que o \cmd{init} deve aguardar que ele seja concluído.
	O \fn{/etc/rc.d/rc} executa todos comandos necessários para iniciar e parar 
	os serviços previstos para o nível 2.     
	
	O comando no quarto campo executa todo o trabalho duro de configurar um
	nível de execução. Ele inicia os serviços que ainda não estejam sendo
	executados e finaliza os serviços que não devem rodar neste nível.
	Exatamente qual o comando a ser utilizado ou como o nível está configurado
	depende de cada distribuição do \linux. 
	

	Quando o \cmd{init} é iniciado, ele procura por uma linha no 
	\fn{/etc/inittab} que especifique o nível de execução padrão: 
		%
\begin{tscreen}
id:3:initdefault:
\end{tscreen}
		%
	Pode-se informar ao init para iniciar o sistema em um outro nível de 
	execução, passando ao kernel argumentos como \texttt{single}
	ou \texttt{emergency}\footnote{argumentos para o kernel podem ser
	passados através do LILO}. 
	Isso permite escolher o modo monousuário, descrito na 
	seção~\ref{sec:single-user-mode}.
	

	Enquanto o sistema está sento executado o comando \cmd{telinit} pode mudar 
	o modo de execução, o que faz com que o \cmd{init} execute o comando 
	apropriado definido no \fn{/etc/inittab}.

%%\section{Special configuration in \fn{/etc/inittab}}
\section{Configurações especiais no \fn{/etc/inittab}}

	O arquivo \fn{/etc/inittab} tem algumas funcionalidades especiais que 
	permitem ações diferenciadas em situações especiais. Estas funcionalidades 
	são definidas através de palavras chaves utilizadas no terceiro campo. 
	Alguns exemplos: 
	
	\begin{dispitems}
	\item[\texttt{powerwait}]
		Permite que o \cmd{init} encerre o sistema na falta de energia 
		elétrica. Assume que o sistema está utilizando uma unidade de 
		alimentação extra (no-break) e que o software da unidade informará 
		sobre a falta de energia. 
		
	\item[\texttt{ctrlaltdel}]
		Permite ao \cmd{init} reinicializar o sistema, quando as teclas 
		\key{control-alt-del} forem pressionadas simultaneamente. Veja que 
		o administrador pode configurar o \key{C-A-D} para executar outra 
		função. Isto é aplicável, por exemplo, nos casos em que o 
		sistema esteja em uma localização pública.

	\item[\texttt{sysinit}]
		Comando que deve ser executado quando o sistema for inicializado. Este
		comando pode limpar o conteúdo do \fn{/tmp}, por exemplo.

	\end{dispitems}
	
	Esta lista não é completa. Veja a página de manual do \man{inittab}(5)
	para todas as possibilidades e detalhes de como utilizá-las.  

%%\section{Booting in single user mode}
\section{Iniciando em modo monousuário}
\label{sec:single-user-mode}

	Um nível de execução extremamente importante é o modo \defin{monousuário}
	\footnote{\defin{single user mode}, nível 1},
	no qual somente o administrador do sistema utiliza a máquina e o menor
	número possível de serviços (inclusive logins) estarão disponíveis. 
	Este modo de execução é necessário para algumas tarefas administrativas, 
	tais como na execução do \cmd{fsck} na partição \fn{/usr}, isto requer que 
	a partição esteja desmontada, o que não pode ocorrer a
	menos que todos os serviços do sistema estejam finalizados.


	Um sistema em execução pode mudar para monousuário através do comando 
	\cmd{telinit}. Durante a inicialização do sistema a palavra \texttt{single} 
	ou \texttt{emergency}, na linha de comando do kernel, faz com que o 
	\cmd{init} seja informado do nível de execução a iniciar (a linha de comando
	do kernel pode variar de sistema para sistema. Depende de como você está 
	inicializando seu sistema).  
	

	A inicialização em modo monousuário pode ser necessária para executar-se o
	comando \cmd{fsck} manualmente, antes de qualquer montagem ou acesso à 
	uma partição \fn{/usr} com problemas (qualquer atividade em um sistema de 
	arquivos inconsistente pode trazer mais problemas, devendo o \cmd{fsck} ser
	executado o mais rapidamente possível).    
	

	Os scripts de inicialização do \cmd{init} automaticamente entrarão em
	modo monousuário caso o comando \cmd{fsck} executado de forma automática
	apresente algum problema durante a inicialização do sistema. Esta é uma
	tentativa de prevenir que o sistema utilize um sistema de arquivos
	danificado e que o \cmd{fsck} não possa corrigir automaticamente. 
	Tais casos são relativamente raros e usualmente envolvem um disco rígido 
	com problemas ou uma versão experimental do kernel, porém é desejável que 
	se esteja preparado. 
	

	Como medida de segurança, um sistema adequadamente configurado pedirá a
	senha do \texttt{root} antes de iniciar um interpretador em modo
	monousuário. De outra forma seria fácil simplesmente informar uma linha
	ao LILO e ganhar acesso ao sistema como \texttt{superusuário}. Caso o 
	problema esteja no arquivo \fn{/etc/passwd}, o melhor é ter-se à mão um 
	disquete de inicialização.   
