Gentoo Logo

Aviso : Este documento não é válido 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() {
  (Informações de dependências)
}

start() {
  (Comandos necessários para iniciar o serviço)
}

stop() {
  (Comandos necessários para parar o serviço)
}

restart() {
  (Comandos necessários para reiniciar o serviço)
}

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    # Esperar 3 segundos antes de começar de novo
  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

(Copie todos serviços do runlevel default para o runlevel offline)
# cd /etc/runlevels/default
# for service in *; do rc-update add $service offline; done
(Remova serviços não desejados do runlevel offline)
# rc-update del net.eth0 offline
(Mostrar serviços ativos para o runlevel offline)
# rc-update show offline
(Exemplo parcial de saída)
               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 ] [ > ] [ >> ]


Imprimir

View all

Atualizado 19 de dezembro de 2005

A versão original deste documento foi atualizada em 18 de dezembro de 2013

Resumo: O Gentoo usa um formato especial de scripts de inicialização que, além de outras coisas, permite decisões baseadas em dependências e scripts virtuais. Este capítulo explica todos estes aspectos e como trabalhar com estes scripts.

Sven Vermeulen
Autor

Roy Marples
Autor

Daniel Robbins
Autor

Chris Houser
Autor

Jerry Alexandratos
Autor

Seemant Kulleen
Desenvolvedor do Gentoo x86

Tavis Ormandy
Desenvolvedor do Gentoo Alpha

Jason Huebel
Desenvolvedor do Gentoo AMD64

Guy Martin
Desenvolvedor do Gentoo HPPA

Pieter Van den Abeele
Desenvolvedor do Gentoo PPC

Joe Kallar
Desenvolvedor do Gentoo SPARC

John P. Davis
Editor

Pierre-Henri Jondot
Editor

Eric Stockbridge
Editor

Rajiv Manglani
Editor

Jungmin Seo
Editor

Stoyan Zhekov
Editor

Jared Hudson
Editor

Colin Morey
Editor

Jorge Paulo
Editor

Carl Anderson
Editor

Jon Portnoy
Editor

Zack Gilburd
Editor

Jack Morgan
Editor

Benny Chuang
Editor

Erwin
Editor

Joshua Kinard
Editor

Tobias Scherbaum
Editor

Xavier Neys
Editor

Grant Goodyear
Revisor

Gerald J. Normandin Jr.
Revisor

Donnie Berkholz
Revisor

Ken Nowack
Revisor

Lars Weiler
Colaborador

Enderson Maia
Tradutor Responsável

Marcelo Góes
Tradutor

Eduardo Magalhães
Tradutor

Marcelo Azambuja
Tradutor

Marcos Vinicius Buzo
Tradutor

Donate to support our development efforts.

Copyright 2001-2014 Gentoo Foundation, Inc. Questions, Comments? Contact us.