Trabalhando com init no Debian
Por:
Flavio Torres - ftorres[@]ymail.com
Publicado em: 26/03/2006, atualizado em 06/08/2006.
Trabalhando com init no Debian
Este artigo irá tratar de scripts de inicialização
e manipulação relacionados ao init, está agora dividido
em 2 partes:
1) Ferramentas para manipular os inits.
- rcconf
- update-rc.d
- sysv-rc-conf
- sysvconfig
2) Ferramentas para trabalhar com eles.
- invoke-rc.d
- Na unha
- Script Service1 para Debian
- Script Service2 para Debian
- Script para criação
e uso de um rc.local para o Debian
O que são níveis de execução?
Os Níveis de execução (run levels) são diferentes
modos de funcionamento do GNU/Linux com programas, daemons e recursos
específicos. Em geral, os sistemas GNU/Linux possuem sete níveis
de execução numerados de 0 a 6. O daemon init é o
primeiro programa executado no GNU/Linux (veja através do comando
ps axu | grep init) e responsável
pela carga de todos daemons de inicialização e configuração
do sistema.
Existem dois estilos de init: o BSD e o SystemV. Cada um tem suas peculiaridades.
Sistemas BSD, como o Slackware armazenam seus scripts /etc/rc.d, cada
um deles responsável por uma das etapas da inicialização:
rc.S - Este é o script de Inicialização do Slackware;
rc.K - Carregado quando entramos no runlevel 1, para manutenção
do sistema;
rc.M - Modo multiusuário, utilizado nos demais runlevels;
rc.4 - Aciona o login gráfico (runlevel 4);
rc.0 e rc.6 - Respectivamente desliga e reboota o computador.
rc.sysvinit - Utilizado quando existem scripts no padrão SystemV
para serem iniciados.
O Debian, e sistemas Debian-Like ( Ubuntu, Kurumin ), como também
sistemas RedHat-Like 'Como RedHat' ( Conectiva, RedHat, Fedora ) utilizam
o sistema de init SystemV, onde os scripts de níveis de inicialização
são armazenados em '/etc/init.d' (Listagem: 1) e gerenciados por
links simbóbicos ( symlinks ) que são criados em '/etc/rc?.d',
onde o ? representa o runlevel. (Listagem 2).
Listagem 1:
$ ls -la /etc/init.d/
-rwxr-xr-x 1 root root 560 2006-04-10 13:00 firewall
-rwxr-xr-x 1 root root 811 2004-09-10 12:00 halt
-rwxr-xr-x 1 root root 165 2004-09-10 12:00 hostname.sh
-rwxr-xr-x 1 root root 3344 2005-03-19 22:51 hotplug
-rwxr-xr-x 1 root root 359 2005-03-20 11:09 hotplug-net
-rwxr-xr-x 1 root root 3499 2005-03-22 11:21 hwclockfirst.sh
-rwxr-xr-x 1 root root 3638 2005-03-22 11:21 hwclock.sh
-rwxr-xr-x 1 root root 2240 2005-05-02 10:57 ifupdown
-rwxr-xr-x 1 root root 802 2005-04-04 10:33 ifupdown-clean
-rwxr-xr-x 1 root root 1764 2004-10-24 13:28 inetd
-rwxr-xr-x 1 root root 658 2005-04-10 19:35 initrd-tools.sh
-rwxr-xr-x 1 root root 2923 2005-02-04 17:30 keymap.sh
-rwxr-xr-x 1 root root 1346 2005-05-25 15:21 klogd
Listagem 2:
$ ls -la /etc/rc1.d/
drwxr-xr-x 2 root root 4096 2006-06-09 15:48 .
drwxr-xr-x 72 root root 4096 2006-08-04 18:08 ..
lrwxrwxrwx 1 root root 18 2005-09-05 16:33 K00firewall -> ../init.d/firewall
lrwxrwxrwx 1 root root 14 2005-08-30 08:31 K11cron -> ../init.d/cron
lrwxrwxrwx 1 root root 15 2005-08-30 09:01 K19samba -> ../init.d/samba
lrwxrwxrwx 1 root root 14 2005-09-02 09:50 K20dhcp -> ../init.d/dhcp
lrwxrwxrwx 1 root root 15 2005-08-30 08:31 K20exim4 -> ../init.d/exim4
lrwxrwxrwx 1 root root 15 2005-08-30 08:31 K20inetd -> ../init.d/inetd
lrwxrwxrwx 1 root root 13 2005-08-30 09:01 K20lpd -> ../init.d/lpd
lrwxrwxrwx 1 root root 17 2005-08-30 08:30 K20makedev -> ../init.d/makedev
lrwxrwxrwx 1 root root 15 2005-11-08 15:57 K20mysql -> ../init.d/mysql
lrwxrwxrwx 1 root root 14 2006-03-15 10:47 K20ntop -> ../init.d/ntop
lrwxrwxrwx 1 root root 17 2006-03-28 13:28 K20openvpn -> ../init.d/openvpn
lrwxrwxrwx 1 root root 17 2006-06-03 00:26 K20postfix -> ../init.d/postfix
lrwxrwxrwx 1 root root 19 2006-06-03 00:35 K20saslauthd -> ../init.d/saslauthd
lrwxrwxrwx 1 root root 13 2005-08-30 09:01 K20ssh -> ../init.d/ssh
lrwxrwxrwx 1 root root 17 2006-06-09 15:48 K20sysstat -> ../init.d/sysstat
lrwxrwxrwx 1 root root 17 2006-03-24 09:31 K20winbind -> ../init.d/winbind
lrwxrwxrwx 1 root root 15 2005-08-30 09:11 K30squid -> ../init.d/squid
lrwxrwxrwx 1 root root 17 2005-09-01 11:46 K50proftpd -> ../init.d/proftpd
lrwxrwxrwx 1 root root 20 2005-08-30 09:01 K79nfs-common -> ../init.d/nfs-common
lrwxrwxrwx 1 root root 27 2005-08-30 09:01 K80nfs-kernel-server -> ../init.d/nfs-kernel-server
lrwxrwxrwx 1 root root 17 2005-08-30 09:01 K81portmap -> ../init.d/portmap
lrwxrwxrwx 1 root root 15 2005-08-30 09:01 K85bind9 -> ../init.d/bind9
lrwxrwxrwx 1 root root 13 2005-08-30 08:31 K86ppp -> ../init.d/ppp
lrwxrwxrwx 1 root root 13 2005-08-30 08:31 K89atd -> ../init.d/atd
lrwxrwxrwx 1 root root 15 2005-08-30 08:31 K89klogd -> ../init.d/klogd
lrwxrwxrwx 1 root root 18 2005-08-30 08:31 K90sysklogd -> ../init.d/sysklogd
lrwxrwxrwx 1 root root 17 2005-08-30 09:01 K91apache2 -> ../init.d/apache2
lrwxrwxrwx 1 root root 16 2005-08-30 08:30 S20single -> ../init.d/single
Antes de entrar em qualquer nível de execução, todos
os scripts iniciados com 'K' ( Killed ) são executados; esses scripts
matam ( páram ) processos. Já os scripts iniciados com 'S'
( Started ) são executados; esses scripts iniciam processos. O
número seguido de 'K' ou 'S' indica a ordem na qual o script é
executado. Scripts de menor valor numérico são executados
primeiro. Em nosso exemplo na Listagem 2, o primeiro processo a ser desativado
é o firewall ( K00firewall )
Todos os scripts em /etc/init.d/ aceitam um argumento que pode ser "start"
( iniciar ), "stop" ( parar ), "reload" ( recarregar
), "restart" ( reiniciar ) ou "force-reload" ( forçar-recarregar
) e irão portanto cumprir a tarefa indicada pelo argumento. Esses
scripts podem ser usados mesmo depois que um sistema tenha sido iniciado
para controlar vários processos.
Para determinar o nível de execução em que seu sistema
está funcionando, utilize o comando /sbin/runlevel. Este comando
irá consultar o arquivo /var/run/utmp para determinar o estado
atual e o anterior. Caso o estado anterior não possa ser determinado
é exibida a letra "N" em seu lugar:
$ /sbin/runlevel
N 2
Para mudar para o nível de execução 2, digite ( com
privilégios de superusuário ):# init 3. E confira a mudança
digitando: runlevel. Você deverá ver este resultado:
# /sbin/runlevel
2 3
O nível de execução padrão em uma distribuição
GNU/Linux é definido através do arquivo de configuração
do /etc/inittab através da linha
id:2:initdefault:
NOTA: As distribuições RedHat-Like dispõem
do arquivo rc.local localizado em /etc, que é um script usado para
a administração local, onde novos daemons ( ou scripts pessoais
) devem ser adicionados, caso não deseje adicioná-lo em
algum nível específico de inicialização.
E o que nível de inicialização significa?
Nível 0:
Interrompe a execução do sistema. Todos os programas e
daemons são finalizados. É acionado pelo comando shutdown
-h now.
Nível 1:
Neste nível os sistemas trabalham em modo monousuário,
com um conjunto mínimo de processos ativos. O sistema de arquivos
raiz (root) está montado em modo de leitura. Este nível
de execução é normalmente utilizado quando a inicialização
normal falha por alguma razão, e muito útil para executar
a manutenção do sistema.
Nível 2:
Modo multiusuário (padrão da Debian)
Nível 3:
Modo multiusuário, todos os processos estão ativos.
Nível 4:
Modo multiusuário. Este nível não é utilizado
na maior parte das distribuições.
Nível 5:
Modo multiusuário com login gráfico
Nível 6:
Reinicialização do sistema. Todos os programas e daemons
são encerrados e o sistema é reiniciado. É acionado
pelo comando shutdown -r e o pressionamento de CTRL+ALT+DEL.
Caso deseje adicionar novos serviços para iniciar junto com
o boot, devemos adicionar o script em /etc/init.d/<script>.
Assim sendo, para invocar um script temos: /etc/init.d/<script>
<argumento>
Ex:
# /etc/init.d/sshd start
Este comando iniciará o serviço de ssh.
Usuários de distribuições ligeiramente diferentes,
como Debian-Like e RedHat-Like, sente alguma dificuldade de adaptação,
quando necessita adicionar algum serviço para inicialização
em determinado runlevel, distribuições RedHat-Like dispõem
do utilitário ntsysv, já distribuições
Debian-Like dispõem dos seguintes gerenciadores:
1) rcconf
2) update-rc.d
3) sysv-rc-conf
4) sysvconfig
1) rcconf
O rcconf é um front-end para o 'update-rc.d'.
O rcconf permite você controlar que serviços são
iniciados quando o sistema inicia, ele irá mostrar uma tela onde
você poderá ver o status de cada serviço [*] ou [
].
O rcconf trabalha obtendo a lista de serviços de '/etc/init.d'
e observa nos diretórios '/etc/rc?.d' para determinar se cada serviço
está ligado ou não no boot. Se o número NN ( de '/etc/rc?.d/NNname'
) não é 20 ( padrão ), rcconf salva o nome
do serviço junto ao seu número em '/var/lib/rcconf/services'
para que seja possível reestabelecer o serviço para sua
configuração original.
- Instalação
# apt-get install rcconf
- Atualizar menus
# update-rcconf-guide
- Utilização
# rcconf
Ele irá chamar uma tela demonstrando o que temos de inicialização,
e marcará para iniciar ou não iniciar ( desativar ).
Marcando a desativação, o script passará a ter,
nos respectivos runlevel, o argumento K00script.
2) update-rc.d
Um outro mais interessante e MUITO mais eficiente é o update-rc.d
que permite você ter um melhor entendimento e controle dos seus
scripts nos init desejado.
- Instalação
# apt-get install file-rc update-rc.d
- Utilização
# update-rc.d <nome> start NN runlevel . stop
NN runlevel .
nome é o mesmo nome do arquivo contido em /etc/init.d, NN significa
a ordem em que eles serão iniciados/parados e runlevel especifica
em quais runlevels eles serão iniciados/parados.
Exemplo com o script firewall.
NOTA: O arquivo deve estar dentro do diretório
init.d.
# update-rc.d firewall start 20 2 3 4 5 . stop 20
0 1 6 .
NOTA: Se já existir uma entrada no arquivo como
o nome especificado, update-rc.d não irá fazer nada.
Você também pode deixar os runlevels como padrão:
# update-rc.d <nome> defaults [NN | NN-start
NN-stop]
Colocando o defaults, ele irá deixar os runlevels para inicialização
como: 2, 3, 4 e 5; e para finalização: 0, 1 e 6 ( para saber
mais, leia a manpage do init ). NN indica que o arquivo terá a
mesma prioridade na inicialização/finalização.
Para deixar diferente, especifique NN-start para a inicialização
e NN-stop para finalização.
NOTA: É recomendável sempre especificar
um runlevel para os serviços serem finalizados.
Ex:
# update-rc.d firewall defaults
Já para remover um arquivo da inicialização/finalização,
use:
# update-rc.d [-f] <nome> remove
O -f pode ser usado para que o update-rc.d remova também links
simbólicos. Este comando excluirá os links dos rcN.d, e
consequentemente com que o serviço seja iniciado e parado manualmente,
ou seja, você precisará usar o script em /etc/init.d/firewall
<opcao>.
Ex:
# update-rc.d -f firewall remove
Uma opção que pode ser usada em ambos os 3 comandos é
-n. Ela faz com que update-rc.d simule o que aconteceria.
# update-rc.d -n firewall remove
Não se preocupe, ele irá mostrar a saída corretamente,
porém, não haverá nenhuma alteração.
3) sysv-rc-conf
É uma Ferramenta com interface gráfica para configuração
do runlevel do SysV para o terminal.
- Instalação
# apt-get install sysv-rc-conf
- Dependências:
Os pacotes extra a seguir serão instalados:
libcurses-perl libcurses-ui-perl libterm-readkey-perl
Os NOVOS pacotes a seguir serão instalados:
libcurses-perl libcurses-ui-perl libterm-readkey-perl sysv-rc-conf
- Execução
# sysv-rc-conf
Para incluir o seu script, visualize ele na listagem da esquerda e marque
com um [X] no runlevel 2.
Para excluir, desmarque deixando a opção em branco [].
Para selecionar use a tecla de espaço.
4) sysvconfig
- Instalação
# apt-get install sysvconfig
O comando sysvconfig é um editor escrito em dialog, utilizado
para:
- Habilitar e desabilitar serviços.
- Editar os links dos runlevels
- Restaurar de um arquivo backup o estado original de seus init.
- Apesar de possuir uma interface em dialog, ele também funciona
em modo texto.
Manipulando os
Scripts
Para manipular os scripts, nas distribuições RedHat-Like,
podemos lançar o comando: service <servico>
<argumento>
Ex:
# service sshd start
Já nas distribuições Debian-Like, dispomos do:
5) invoke-rc.d
O comando invoke-rc.d é nada mais que um script que faz o trabalho
bem feito de invocação dos serviços localizados em
/etc/init.d/<servico>, você deve passar como parâmetro
padrão [ start | stop | force-stop | restart | reload | force-reload
| status ].
Ex:
# invoke-rc.d squid reload
Uma dica, caso deseje utilizá-lo como um comando # service <servico>
[ parâmetro ], você pode criar um alias:
# vi ~/.bashrc
alias service='invoke-rc.d'
6) Na Unha
Pronto, para quem gosta de bash, ai esta!
Copie o script para o diretório /etc/init.d/
# cp script /etc/init.d/
Torne o script executável
# chmod +x /etc/init.d/script
Entre no diretorio /etc/rc2.d
# cd /etc/rc2.d/
Crie um link para o seu script
# ln -s /etc/init.d/script /etc/rc2.d/S19script
Obs: Como foi explicado anteriormente os scripts que iniciam com 'S'
passam start como seu argumento, e o '19' assegura que o script seja chamado
antes de quaisquer scripts contendo números 20 ou superiores.
Se você nao precisa que o script seja um dos primeiros a iniciar,
ou melhor que ele seja inciado lá no final do boot, você
pode coloca-lo como 99.
# ln -s /etc/init.d/script /etc/rc2.d/S99script
Para retirar o script da inicialização, apenas remova o
link, assim:
# rm -f /etc/rc2.d/S99script
Obs: Os argumentos K e S devem, obrigatoriamente, estar em Caixa Alta
(maiúscula).
Este problema de iniciar programas no boot é um problema crucial
para os users do Debian e distribuições baseadas nela (arquivos
em /etc/default não fazem efeito no Debian). No próprio
manual dele, tem algumas coisas falando sobre isso. Dêem uma olhada
no site do Debian.
Script Service1
#! /bin/sh
#Script versao 0.01 do service para debian
#Esta é a primeira versão do meu script service, tudo ANTES
de conhecer o invoke-rc.d.
#Flavio Torres - flaviotorres@linuxmasters.info
case "$2" in
start)
echo "Iniciando servico $1 "
/etc/init.d/$1 start
;;
stop)
echo "Parando servico $1 "
/etc/init.d/$1 stop
;;
*)
echo "USO: service <script> {start|stop}"
exit 1
;;
esac
exit 0
|
Para este script funcionar legalzinho, sem ter de executá-lo a
partir de seu diretório vigente, você DEVE incluí-lo
no diretório # echo $PATH do sistema, o mesmo para o script SERVICE2
abaixo.
Service Script2
#!/bin/sh
VERSION="`basename $0` ver. 0.91"
USAGE="Uso: `basename $0` < option > | --status-all |
\
[ service_name [ command | --full-restart ] ]"
SERVICE=
SERVICEDIR="/etc/init.d"
if [ $# -eq 0 ]; then
echo "${USAGE}" >&2
exit 1
fi
while [ $# -gt 0 ]
do
case "${1}" in
--help | -h | --h* )
echo "${USAGE}" >&2
exit 0
;;
--version | -V )
echo "${VERSION}" >&2
exit 0
;;
*)
if [ -z "${SERVICE}" -a $# -eq 1 -a "${1}" =
"--status-all" ]; then
cd "${SERVICEDIR}"
for SERVICE in *; do
case "${SERVICE}" in
functions | halt | killall | single| linuxconf| kudzu | \
*rpmorig | *rpmnew | *rpmsave | *~ | *.orig)
;;
*)
if [ -x "${SERVICEDIR}/${SERVICE}" ]; then
"${SERVICEDIR}/${SERVICE}" status
fi
;;
esac
done
exit 0
elif [ $# -eq 2 -a "${2}" = "--full-restart"
]; then
SERVICE="${1}"
cd "${SERVICEDIR}"
if [ -x "${SERVICEDIR}/${SERVICE}" ]; then
"${SERVICEDIR}/${SERVICE}" stop
"${SERVICEDIR}/${SERVICE}" start
exit $?
fi
elif [ -z "${SERVICE}" ]; then
SERVICE="${1}"
else
OPTIONS="${OPTIONS} ${1}"
fi
shift
;;
esac
done
if [ -x "${SERVICEDIR}/${SERVICE}" ]; then
"${SERVICEDIR}/${SERVICE}" ${OPTIONS}
else
echo "${SERVICE}: Servico desconhecido" >&2
exit 1
fi
|
Script RC.LOCAL
#!/bin/sh
# Script rc.local, este script eh utilizado para fazer manutencao e inicializacao no rc.local
# Flavio Torres - flaviotorres@linuxmasters.info
# Para fazę-lo útil, deve-se adicioná-lo diretorio /usr/bin/
# versao 0.6 - abril de 2006
PATH=/bin:/sbin:/usr/bin:/usr/sbin
export PATH
TESTA(){
if [ $? == 0 ]; then
echo -e [ '\e[40;32;1m OK \e[m' ]
else
echo -e [ '\e[40;31;1 ERRO \e[m' ]
fi
}
case "$1" in
start)
if [ -f /etc/rc.local ]; then
exec /etc/rc.local 2>&1&> /dev/null
else
echo "O arquivo rc.local nao existe, utilize a opcao add."
fi
;;
stop)
echo "Sem acao"
;;
status)
echo "Sem acao"
;;
restart|reload)
$0 stop
$0 start
;;
add)
DIR="/etc/init.d"
ARQ="/etc/rc.local"
if [ -e /etc/rc.local ]; then
printf ""
else
echo "Criando configuracoes..."
touch /etc/rc.local && chmod 755 /etc/rc.local
ln -s /usr/bin/rc.local /etc/init.d/rc.local
update-rc.d rc.local start 99 2 3 4 5 . stop 99 0 1 6 .
TESTA
fi
echo "Entre com o nome do script: "
read NOME
grep $NOME $ARQ
if [ $? == 0 ]; then
echo "^^^, O arquivo ja esta adicionado."
if [ -e $DIR/$NOME ]; then
printf ""
else
chmod 755 $NOME && cp $NOME $DIR
printf "Porem nao existia em $DIR, adicionando..."
TESTA
fi
elif [ -e $DIR/$NOME ]; then
chmod 755 $DIR/$NOME && echo $DIR/$NOME >> $ARQ
TESTA
else
chmod 755 $NOME && cp $NOME $DIR && echo $DIR/$NOME >> $ARQ
TESTA
fi
;;
*)
echo -n "Uso: $0 {add|start|stop|status|restart}"
echo
exit 1
esac
|
Faça o download deste script aqui.
É isto!
Caso tenha algum problema, dica, reclamação ou principalmente
contribuição, por favor envie um e-mail para: flaviotorres@linuxmasters.info
|