Boot em Sistemas UNIX (Parte 4)
by André Luís Toledo on jun.09, 2008, under Linux, Monster SO

Esta é a quarta parte de nosso estudo sobre o processo de boot em sistemas unix-like, a imagem abaixo resume o conteúdo descrito em Boot em Sistemas UNIX (Parte 1), Boot em Sistemas UNIX (Parte 2) e Boot em Sistemas UNIX (Parte 3).
(Clique na imagem para ampliar)
Neste artigo então vamos entender o processo de boot no Linux a partir deste ponto, ou seja, a partir do momento em que o gerenciador de boot (boot loader) carrega e executa o kernel.
O kernel carregado à memória geralmente é compactado, portanto é descompactado por um aplicativo embutido no inicio arquivo do kernel, assim ele é executado.
Na execução do kernel ele “descobre” seus dispositivos de hardware e através de um parâmetro fornecido pelo boot loader ele monta o sistema de arquivos root (root filesystem) que é representado pelo “/” (barra), e povoa a arvore de diretórios.
Feito isto o kernel chama o primeiro processo a ser executado pelo kernel em nível de usuário, este é o processo init que fica no /sbin/init, este será o pai de todos os processos do sistema.
O linux, assim como os demais unix, trabalha com um sistema de fork-exec, ou divisão e execussão, isso quer diser que todo processo tem um processo pai que se divide e executa esta sua cópia como sendo o processo filho.
Por este motivo, o fato do processo initi ser o pai de todos os processos do sistema tem um série de implicações, as mais obvias são:
1 - Para matar o processo init é necessário que seus filhos seja finalizados antes, então caso tente finalizar o processo init este enviará um sinal para que seus filhos sejam finalizados antes de parar.
2 - É possivel manipular a inicialização e finalização do sistema manipulando o processo init.
Existem dois tipos de processo init, o primeiro é o BSD init, que é mais rústico, mais simples e utilizado pelo freeBSD e algumas distribuições Linux como o Slackware e em distribuições modernas como Ubuntu, este estilo de de inicialização não irei abordar neste artigo, mas no artigo seguinte.
O segundo estilo de processo init é o SysV init que é mais complexo mas tem mais recursos e é mais flexível. É nesse estilo que vamos focar nesse artigo.
O primeiro passo no sistema SysV init é a troca do estado do kernel para multitarefa, então ele busca as informações contidas no arquivo /etc/inittab onde é definido o runlevel (nível de execussão).
Níveis de execussão ou run-levels são estados de trabalho do sistema, definindo como inicializar e finalizar o sistema e quais scripts executar na inicialização e finalização.
Em sistemas baseados em Red Hat Linux possui os seguintes níveis de execussão.
0 - Desliga
1 - Monousuário
2 - Multiusuário sem NFS
3 - Multiusuário com NFS
4 - Reservado
5 - Multiusuário modo gráfico
6 - Reinicialização
S ou s - Não é usado diretamente, mas sim para programas que são executados o inicio do nível 1.
Obs: Não é todo sistema que utiliza o sistema SysV init que possui essa sequência de runlevels, gerlamente os runlevels 0 e 6 são padrões, mas os demais varia de acordo com a versão e distribuição que esta sendo usado.
No /etc/inittab você encontrará uma lista dos runlevels disponíveis, geralmente em forma de comentário:
# 0 - halt
# 1 - Single user mode
# 2 - Multiuser, without NFS (The same as 3, if you do not have networking)
# 3 - Full multiuser mode
# 4 - unused
# 5 - x11
# 6 - reboot (Do not se initdefault to this)
Mesmo que não tenha em forma de comentário, o terá em forma de configuração que segue a seguinte sintaxabaixo, mas sinceramente nunca encontrei um caso onde não tinha os comentário, isto porque somente pelas configurações é complicado descobrir o que cada runlevel faz.
[id]:[nível-de-execussão]:[ação]:[processo]
Onde [id] é uma sequência de 1 a 14 caracteres para nomer a linha, [nível-de-execussão] é um dos valores já informados, [ação] é um dos seguintes valores: respawn, wait, once, boot, bootwait, off, ondemand, initdefault, sysinit, powerwait, powerfail, powerok, ctrlaltdel, kbrequest; e por fim [pocesso] que é o programa a ser executado.
respawn - O processo será reiniciado mesmo que ele termine.
wait - O processo será iniciado assim que o runlevel especificado conseguir entrar e o init irá esperá que termine.
once - O processo será executado assim que o runlevel especificado entrar.
boot - O processo será executado durante o boot do sistema. O arquivo do runlevel é ignorado.
bootwait - O processo será executado durante o boot do sistema, enquando o processo init espera pela finalização. O arquivo do runlevel será ignorado.
off - Este não faz nada.
ondemand - Um processo marcado como um ondemand será executado sempre que o runlevel especificado como ondemand é chamado. Mesmo assim, nenhuma mudança no runlevel ocorrerá.
initdefault - Uma entrada initdefault especifica que o runlevel deferá ser executado logo após o boot do sistema. Se nada existir, o processo init perguntará qual runlevel no console. O arquivo do processo é ignorado.
sysinit - O processo será executado durante o boot do sistema. Ele será executado antes de qualquer boot ou bootwait. O arquivo do runlevel será ignorado.
powerwait - O processo será executado quando houver queda de energia. O processo init geralmente é informado sobre isso por um processo conversando com um UPS conectado ao computador. O processo init esperará pelo processo ser terminado antes de contiruar.
powerfail - Assim como para powerwait, exceto pelo fato que o processo init não espera pela finalização do processo.
powerokwait - Este processo será executado assim que a energia seja restabelecida.
powerfailnow - O processo será executado assim que o processo init for informado que a bateria do UPS externo estiver quase no fim e a energia estiver em falha (Contando que o UPS externo monitora e informa este tipo de situação.).
ctrlaltdel - O processo será executado quando o processo init receber o sinal SIGINT. Isto significa que alguém no console do sistema pressionou a combinação de teclas CTRL+ALT+DEL. Tipicamente implica que se quer executar algum tipo de shutdown ou mesmo entrar em single-user mode ou simplesmente desligar a maquina.
kbrequest - O processo será executado quando o processo init receber um sinal do controlador de teclado que uma combinação especial de teclas foi pressionado no console do sistema.
l0:0:wait:/etc/rc.d/rc 0
l1:1:wait:/etc/rc.d/rc 1
l2:2:wait:/etc/rc.d/rc 2
l3:3:wait:/etc/rc.d/rc 3
l4:4:wait:/etc/rc.d/rc 4
l5:5:wait:/etc/rc.d/rc 5
l6:6:wait:/etc/rc.d/rc 6
Veja que as linhas de id l0, l1, l2, l3, l4, l5 e l6 executam seus respectivos runlevel e esperam até que o conteúdo dos diretórios rc de seus respectivos runlevels. Por exemplo o runlevel 4 iniciará e esperará pela execução dos scripts contidos no diretório /etc/rc.d/rc.4.
Na realidade o conteúdo destes diretórios não são scripts em si, mas sim links simbólicos para os verdadeiros scripts contidos em /etc/rc.d/init.d, e a sintax dos links determina se o script será iniciado ou finalizado.
OBS: É importante que você conheça o conceito de links em sistemas unix, pois não vou explicar nesse artigo, mas num artigo separado.
Por exemplo o script S90httpd é um link que determina a inicialização do processo http neste runlevel.
Neste exemplo, o “S” no inicio do nome link determina que é para inicializar o script /etc/rc.d/init.d/httpd que é para onde este link aponta. Para finalizar este processo ao deixar este runlevel (ao desligar o sistema) deverá haver neste mesmo diretório um link simbólico apontando para o mesmo script porém com o nome do link iniciado pela letra “K”.
O número no nome do link determina a sequencia a ser iniciado, por exemplo, caso o diretório do runlevel a ser iniciado contenha os seguintes links simbólicos:
# ls -l /etc/rc.d/rc.4/
lrwxrwxrwx 1 root root 19 2008-05-20 19:31 K10httpd -> /etc/rc.d/init.d/httpd
lrwxrwxrwx 1 root root 19 2008-05-20 19:31 k25smb -> /etc/rc.d/init.d/smb
lrwxrwxrwx 1 root root 19 2008-05-20 19:31 k60netfs -> /etc/rc.d/init.d/netfs
lrwxrwxrwx 1 root root 19 2008-05-20 19:31 k90network -> /etc/rc.d/init.d/network
lrwxrwxrwx 1 root root 19 2008-05-20 19:31 S10network -> /etc/rc.d/init.d/network
lrwxrwxrwx 1 root root 19 2008-05-20 19:31 S25netfs -> /etc/rc.d/init.d/netfs
lrwxrwxrwx 1 root root 19 2008-05-20 19:31 S60lpd -> /etc/rc.d/init.d/lpd
lrwxrwxrwx 1 root root 19 2008-05-20 19:31 S60smb -> /etc/rc.d/init.d/smb
lrwxrwxrwx 1 root root 19 2008-05-20 19:31 S90httpd -> /etc/rc.d/init.d/httpd
O conteúdo deste diretório indica que na inicialização do runlevel 4 seguirá a seguinte sequencia: Network, Netfs, Lpd, Smb e por fim httpd. Note que os links S60lpd e S60smb tem o mesmo número de sequencia de inicialização, neste caso serão iniciado em ordem alfabética.
Assim, pelo conteúdo do diretório referente ao runlevel em questão, é possível saber quais processos serão iniciados.
Para verificar qual o runlevel seu sistema esta iniciando consulte a linha que o define e que tem a a notação initdefault no lugar de [ação] :
A seguinte linha de /etc/inittab define o runlevel a ser usado por default:
id:3:initdevault:
Também é possível alterar o runlevel do sistema durante sua operação através do comando init.
# init 6
Insto faz com que o sistema saia do runlevel emque esta e inicio o runlevel 6, que significa reboot, ou seja, isso faz o sistema reiniciar, caso passado o número 0 como parâmetro iria desligar o sistema, caso passado o número 1 como parâmetro isso faria o sistema entrar em modo monousuário, e assim por diante.
![]()
(clique na imagem para amplia-la)
A imagem acima mostra a seqüência de execução dos scripts feito pelo processo init, o último processo a ser executado é o mingetty, este processo é responsável pelo login de usuários no sistema, neste ponto o sitema já esta inicializado assim como os serviços a serem iniciados no boot do sistema.
No próximo artigo veremos este mesmo processo pelo estilo BSD init, até lá.






