Aviso :
Este manual foi substituído por uma versão mais nova e não é mais mantido.
|
[ << ]
[ < ]
[ Início ]
[ > ]
[ >> ]
4. Scripts de inicialização
Conteúdo:
4.a. Runlevels
Carregando seu sistema
Quando você carregar seu sistema, você perceberá textos passarem. Se você prestar
atenção, você verá que o texto é o mesmo toda vez que você reinicia
seu sistema. A seqüência dessas ações é chamada de seqüência de
início e é (mais ou menos) definida estaticamente.
Primeiro, seu gerenciador de inicialização irá carregar a imagem de kernel que você tem definida na
configuração do gerenciador na memória, depois falando para a CPU rodar o
kernel. Quando o kernel é carregado e rodado, ele inicializa todas estruturas e tarefas
específicas do kernel e roda o processo de init.
O processo então verifica que todos sistemas de arquivos (definidos em
/etc/fstab) estão montados e prontos para serem usados. Então ele executa
vários scripts localizados em /etc/init.d, o que inicia os
serviços que você precisa para ter um sistema carregado com sucesso.
Finalmente, quando todos scripts são executados, o init ativa os terminais
(na maior parte só os consoles virtuais que estão escondidos através de Alt-F1,
Alt-F2, etc.) chamando um processo especial chamado agetty.
Este processo irá então certificar-se que você poder se logar nos terminais
rodando login.
Scripts de init
O init não roda os scripts em /etc/init.d aleatoriamente.
Mais ainda, ele não roda todos scripts em /etc/init.d,
só os que são ditos para ele executar. Ele decide que scripts executar
olhando em /etc/runlevels.
Primeiro, o init roda todos scripts de /etc/init.d que têm
links simbólicos dentro de /etc/runlevels/boot. Normalmente, ele irá
iniciar os scripts em ordem alfabética, mas alguns scripts tem informações sobre
dependências neles, avisando o sistema de que outro script deve ser rodado antes
dele poder ser iniciado.
Quando todos scripts de referência de /etc/runlevels/boot são executados,
o init continua carregando os scripts que têm um link simbólico para eles
em /etc/runlevels/default. Novamente, ele usa a ordem alfabética
para decidir que script rodar primeiro, a menos que um script tenha informações
de dependências nele, caso em que a ordem é mudada para a fornecer uma
seqüência de inicialização válida.
Como o init funciona
Claro que o init decide tudo sozinho. Ele precisa de um
arquivo de configuração que especifica que ações devem ser tomadas. Este
arquivo de configuração chama-se /etc/inittab.
Se você lembra da seqüência de inicialização que acabamos de descrever, você irá lembrar-se
que a primeira ação do init é montar os sistemas de arquivos. Isto é definido
na seguinte linha do /etc/inittab:
Listagem de código 1.1: A linha de inicialização de sistema em /etc/inittab |
si::sysinit:/sbin/rc sysinit
|
A linha diz para o init que ele deve rodar /sbin/rc sysinit para
inicializar o sistema. O script /sbin/rc toma conta da
inicialização, o que permite que você diga que o init não faz tanto -- ele
delega tarefas de inicialização do sistema para outro processo.
Segundo, o init executou todos scripts que tinham links simbólicos em
/etc/runlevels/boot. Isto é definido na seguinte linha:
Listagem de código 1.2: A inicialização do sistema, continuado |
rc::bootwait:/sbin/rc boot
|
Novamente o script rc faz as tarefas necessárias. Note que a opção
dada para o rc (boot) é a mesma que o subdiretório de
/etc/runlevels que é usado.
Neste ponto o init verifica seu arquivo de configuração para ver que runlevel ele
deve rodar. Para decidir isso, ele lê a seguinte linha do
/etc/inittab:
Listagem de código 1.3: A linha initdefault |
id:3:initdefault:
|
Neste caso (que é o que a maioria dos usuários do Gentoo usam), o id do runlevel
é 3. Usando essa informação, o init verifica o que ele deverodar para iniciar o
runlevel 3:
Listagem de código 1.4: As definições de runlevel |
l0:0:wait:/sbin/rc shutdown
l1:S1:wait:/sbin/rc single
l2:2:wait:/sbin/rc nonetwork
l3:3:wait:/sbin/rc default
l4:4:wait:/sbin/rc default
l5:5:wait:/sbin/rc default
l6:6:wait:/sbin/rc reboot
|
A linha que define o level 3, novamente, usa o script rc para iniciar os
serviços (agora com o argumento default). Novamente note que o argumento do
rc é o mesmo que o subdiretório de /etc/runlevels.
Quando o rc termina, o init decide que consoles virtuais ele deve
ativar e que comandos precisam ser rodados em cada console:
Listagem de código 1.5: A definição de consoles virtuais |
c1:12345:respawn:/sbin/agetty 38400 tty1 linux
c2:12345:respawn:/sbin/agetty 38400 tty2 linux
c3:12345:respawn:/sbin/agetty 38400 tty3 linux
c4:12345:respawn:/sbin/agetty 38400 tty4 linux
c5:12345:respawn:/sbin/agetty 38400 tty5 linux
c6:12345:respawn:/sbin/agetty 38400 tty6 linux
|
O que é um runlevel?
Você viu que o init usa um esquema de numeração para decidir que
runlevel ele deve ativar. Um runlevel é um estado em que seu sistema
está rodando e contém uma coleção de scripts (scripts de runlevel ou
initscripts) que devem ser executados quando você entra ou sai de um runlevel.
No Gentoo, existem sete runlevels definidos: três runlevels internos, e quatro
definidos pelo usuário. Os runlevels internos são chamados de sysinit,
shutdown e reboot e fazem exatamente o que seus nomes implicam:
iniciar o sistema, desligar o sistema e reiniciar o sistema.
Os runlevels definidos por usuário são aqueles com um subdiretório
/etc/runlevels acompanhante: boot,
default, nonetwork e single. O runlevel
boot inicia todos serviços necessários ao sistema que os outros
runlevels usam. Os três runlevels restantes diferem em que serviços eles iniciam:
O default é usado para operações rotineiras, nonetwork
é usado em caso nenhuma conexão de rede é necessária, e single é
usado para quando você necessita consertar o sistema.
Trabalhando com scripts de init
Os scripts que o processo rc chama podem ser executados com os argumentos
start, stop, restart, pause, zap,
status, ineed, iuse, needsme, usesme ou
broken.
Para iniciar, parar ou reiniciar um serviço (e todos serviços dependentes),
start, stop e restart devem ser usados:
Listagem de código 1.6: Iniciando o postfix |
# /etc/init.d/postfix start
|
Nota:
Só os serviços que precisam (need) do serviço são parados ou reiniciados.
Os outros serviços dependentes (aqueles que usam (use) o serviço mas não precisam
dele) não são tocados.
|
Se você quiser parar um serviço, mas não os serviços que dependem dele, você pode
usar o argumento pause:
Listagem de código 1.7: Parando o postfix mas mantendo os serviços dependentes rodando |
# /etc/init.d/postfix pause
|
Se você quiser ver que status um serviço tem (iniciado, parado, pausado, ...) você
pode usar o argumento status:
Listagem de código 1.8: Informações de status do postfix |
# /etc/init.d/postfix status
|
Se as informações de status disserem que o serviço está rodando, mas você sabe
que não, você pode voltar o status da informação para "parado" com o
argumento zap:
Listagem de código 1.9: Voltando as informações de status para o postfix |
# /etc/init.d/postfix zap
|
Para também pedir que dependências um serviço tem, você pode usar iuse ou
ineed. Com ineed você pode ver que serviços são realmente
necessários para o funcionamento correto do serviço. iuse por outro
lado mostra que serviços são usados pelo serviço, mas não são necessários
para o funcionamento correto.
Listagem de código 1.10: Pedindo uma lista de todos serviços necessários do qual o postfix depende |
# /etc/init.d/postfix ineed
|
De maneira parecida, você pode perguntar que serviços necessitam do serviço (needsme) ou podem
usá-lo (usesme):
Listagem de código 1.11: Pedindo uma lista de todos serviços que precisam do postfix |
# /etc/init.d/postfix needsme
|
Finalmente, você pode perguntar que dependências o serviço precisa que estão faltando:
Listagem de código 1.12: Pedindo uma lista de dependências que estão faltando para o postfix |
# /etc/init.d/postfix broken
|
4.b. Trabalhando com o rc-update
O que é o rc-update?
O sistema de inicialização do Gentoo usa uma árvore de dependências para decidir que serviço precisa ser
iniciado primeiro. Como isso é uma tarefa tediosa e não poderíamos esperar que nossos usuários tivessem
de fazê-lo manualmente, nós criamos ferramentas que facilitam a administração dos
runlevels e scripts de init.
Com o rc-update você pode adicionar ou remover scripts de init de um runlevel. A
ferramenta rc-update irá então pedir automaticamente para o script depscan.sh
reconstruir a árvore de dependências.
Adicionando e removendo serviços
Você já adicionou os scripts de init ao runlevel "default" durante a
instalação do Gentoo. Naquela hora você talvez não tinha idéia do que
"default" era, mas agora você deve ter. O script rc-update necessita de
um segundo argumento que define a ação: add (adicionar), del (remover) ou show (mostrar).
Para adicionar ou remover um script de init, apenas dê ao rc-update o argumento add (adicionar) ou
del (remover), seguido pelo script de init e runlevel. Por exemplo:
Listagem de código 2.1: Removendo o postfix do runlevel default |
# rc-update del postfix default
|
O comando rc-update show irá mostrar todos scripts de init disponíveis e
listar em que runlevels eles executam:
Listagem de código 2.2: Recebendo informações dos scripts de init |
# rc-update show
|
4.c. Configurando serviços
Por que a necessidade de configuração adicional?
Os scripts de init podem ser bem complexos. Portanto, não é realmente desejável fazer
com que os usuários editem o script de init diretamente, o que faria a tarefa mais
capaz de erros. No entanto, é importante poder configurar tal serviço. Por exemplo,
você pode querer dar mais opções ao serviço.
Um segundo motivo para ter a configuração fora do script de init é poder
atualizar os scripts de init sem medo de que mudanças na configuração
sejam desfeitas.
O diretório /etc/conf.d
O Gentoo fornece um jeito fácil de configurar um serviço: cada script de init
que pode ser configurado em um arquivo em /etc/conf.d. Por exemplo,
o script de init do apache2 (chamado de /etc/init.d/apache2) tem um
arquivo de configuração chamado de /etc/conf.d/apache2, que pode conter
as opções que você quer dar ao servidor do Apache 2 quando ele é iniciado:
Listagem de código 3.1: Variável definida em /etc/conf.d/apache2 |
APACHE2_OPTS="-D PHP4"
|
Um arquivo de configuração contém variáveis e somente variáveis (como o
/etc/make.conf), tornando fácil a configuração de serviços. Também
permite a nos dar mais informações sobre as variáveis (como comentários).
4.d. Escrevendo scripts de init
O que eu tenho que fazer?
Não, escrever um script de init não é normalmente necessário já que o Gentoo fornece
scripts de init prontos para todos os serviços fornecidos. No entanto, talvez você queira
instalar um serviço sem usar o Portage, casto tal em que você provavelmente vai ter que
criar um script de init.
Não use o script de init fornecido pelo serviço se ele não for explicitamente
escrito para o Gentoo: os scripts de init do Gentoo não são compatíveis com os
scripts de init usados por outras distribuições!
Arranjo
O arranjo básico de um script de init é mostrado abaixo.
Listagem de código 4.1: Arranjo básico de um script de init |
#!/sbin/runscript
depend() {
}
start() {
}
stop() {
}
restart() {
}
|
Qualquer script de init precisa de uma função start() definida. Todas
outras seções são opcionais.
Dependências
Existem duas dependências que você pode definir: use e need. Como nós
já mencionamos, a dependência need é mais rígida que a dependência
use. Após o tipo de dependência você digitar o serviço de que
você depende, ou a dependência virtual.
Uma dependência virtual é uma dependência que um serviço fornece, mas não é
somente fornecido por aquele serviço. Seu script de init pode depender de um logger
de sistema, mas existem muitos loggers de sistema disponíveis (metalogd, syslog-ng,
sysklogd, ...). Como você não pode precisar (need) de cada um deles (nenhum sistema
normal tem todos esses loggers de sistemas instalados e rodando) nós nos certificamos que
todos esses serviços fornecem (provide) uma dependência virtual.
Vamos ver as informações de dependência do serviço do postfix.
Listagem de código 4.2: Informações de dependência do postfix |
depend() {
need net
use logger dns
provide mta
}
|
Como você pode ver, o serviço do postfix:
-
precisa duma dependência (virtual) net (que é fornecida, por exemplo,
por /etc/init.d/net.eth0)
-
usa uma dependência (virtual) logger (que é fornecida, por exemplo,
por /etc/init.d/syslog-ng)
-
usa uma dependência (virtual) dns (que é fornecida, por exemplo,
por /etc/init.d/named)
-
fornece a dependência (virtual) mta (que é comum para todos servidores de
e-mail)
Controlando a ordem
Em alguns casos você pode não precisar de um serviço, mas que querer que seu serviço seja
iniciado antes (before) (ou depois, after) de outro serviço se ele estiver
disponível no sistema (note a condição - não é mais uma dependência)
e rodar no mesmo runlevel (note a condição - só serviços do
mesmo runlevel estão envolvidos). Você pode fornecer esta informação usando os
ajustes before e after.
Como um exemplo nós vemos as configurações do serviço portmap:
Listagem de código 4.3: A função depend() no serviço portmap |
depend() {
need net
before inetd
before xinetd
}
|
Você também pode usar "*" para englobar todos serviços do mesmo runlevel,
embora isso não seja recomendável.
Listagem de código 4.4: Rodando um script de init como o primeiro script do runlevel |
depend() {
before *
}
|
Funções padrão
Próximo da função do depend(),você também precisa definir a função
start(). Esta contém todos comandos necessários para
iniciar seu serviço. É recomendável usar as funções ebegin e
eend para informar o usuário sobre o que está acontecendo:
Listagem de código 4.5: Exemplo de função start() |
start() {
ebegin "Iniciando meu_serviço"
start-stop-daemon --start --quiet --exec /caminho/para/meu_serviço
eend $?
}
|
Se você precisa de mais exemplos da função start(), por favor leia o código
fonte de scritps de init disponíveis no diretório /etc/init.d.
Para o start-stop-daemon, existe uma excelente página de man disponível se você
precisar de mais informações:
Listagem de código 4.6: Lendo a página de man para o start-stop-daemon |
# man start-stop-daemon
|
Outras funções que você pode definir são: stop() e restart(). Você
não é obrigado a definir essas funções! Nosso sistema de init é inteligente o suficiente para
preencher essas funções sozinho se você usar o start-stop-daemon.
A sintaxe do script de init do Gentoo é baseada em Bourne Again Shell (bash), então você é
livre para usar construções compatíveis com bash dentro de seu script de init.
Adicionando opções personalizadas
Se você quiser que seu script de init suporte mais opções que as que você já
encontrou, você deve adicionar a opção à variável opts variable, e
criar uma função com o mesmo nome da opção. Por exemplo, para suportar uma opção
chamada restartdelay:
Listagem de código 4.7: Suportando a opção restartdelay |
opts="${opts} restartdelay"
restartdelay() {
stop
sleep 3
start
}
|
Variáveis de configuração de serviço
Você não precisa fazer nada para suportar um arquivo de configuração em
/etc/conf.d: se seu script de init é executado, os seguintes arquivos
são automaticamente lidos (isto é, as variáveis estão disponíveis para uso):
- /etc/conf.d/<seu script de init>
- /etc/conf.d/basic
- /etc/rc.conf
Também, se seu script de init fornece uma dependência virtual (como net),
o arquivo associado com aquela dependência (como /etc/conf.d/net)
será lido também.
4.e. Mudando o comportamento do runlevel
Quem pode tirar proveito disso?
Muitos usuários de laptop conhecem a situação: em casa precisam iniciar o net.eth0,
enquanto você não quer iniciar o net.eth0 quando você está fora (já
que não há rede disponível). Como o Gentoo você pode mudar o comportamento do runlevel de
acordo com sua vontade.
Por exemplo você pode criar um segundo runlevel "default" que você pode iniciar que
tem scripts de init associados. Você pode então selecionar na hora da inicialização
que runlevel default você quer usar.
Usando o softlevel
Antes de tudo, criamos o diretório runlevel para o segundo runlevel "default".
Como um exemplo, nós criamos o runlevel offline:
Listagem de código 5.1: Criando um diretório de runlevel |
# mkdir /etc/runlevels/offline
|
Adicione os scripts de init aos runlevels recentemente criados. Por exemplo, se
você quer ter uma cópia exata de seu runlevel default atual sem
o net.eth0:
Listagem de código 5.2: Adicionando os scripts de init necessários |
# cd /etc/runlevels/default
# for service in *; do rc-update add $service offline; done
# rc-update del net.eth0 offline
# rc-update show offline
acpid | offline
domainname | offline
local | offline
net.eth0 |
|
Agora edite sua configuração de gerenciador de inicialização e adicione uma entrada para o
runlevel offline. Por exemplo, no /boot/grub/grub.conf:
Listagem de código 5.3: Adicionando uma entrada para o runlevel offline |
title Gentoo Linux uso offline
root (hd0,0)
kernel (hd0,0)/kernel-2.4.25 root=/dev/hda3 softlevel=offline
|
Pronto, está tudo configurado. Se você iniciar seu sistema e selecionar a nova entrada
na inicialização, o runlevel offline será usado no lugar do
default.
Usando o bootlevel
Usar o bootlevel é completamente análogo ao softlevel. A única
diferença aqui é que você define um segundo runlevel de "boot" ao invés de um segundo
runlevel "default".
[ << ]
[ < ]
[ Início ]
[ > ]
[ >> ]
O conteúdo deste documento está licenciado pela licença Creative Commons -
Attribution / Share Alike.
|