Em sistemas operacionais multitarefas, um daemon, acrônimo de Disk And Execution MONitor (Monitor de Execução e de Disco), é um programa que roda de forma independente em segundo plano (aqueles programinhas que deixam o Windows extremamente lento com o tempo). Tipicamente, daemons tem nomes que terminam com a letra "d"; por exemplo, syslogd é o daemon que gerencia o log do sistema ("system log").
Em um ambiente Unix, o "processo pai" de um daemon é normalmente o processo init (PID=1).
De forma geral, os sistemas operacionais iniciam daemons durante o processo de boot. Os daemons podem fornecer todo tipo de funcionalidade para o sistema. Como agendamento de tarefas (como o cron), servidor web (como o httpd), servidor de banco de dados, entre muitos outros. Se você quiser, você pode criar um daemon seu para a finalidade que você preferir. É o básico disso que vamos ensinar como fazer aqui.
A origem do termo Daemon
A palavra daemon é uma forma alternativa de escrever demon (demônio em inglês). O termo foi trazido para a computação pelos programadores do projeto MAC do MIT. Eles tiraram a idéia do demônio de Maxwell, um ser imaginário de um experimento teórico muito famoso, no qual um demônio trabalharia constantemente em segundo plano, selecionando as partículas de uma caixa.De qualquer forma, os sistemas Unix herdaram essa nomenclatura e, conforme os sistemas baseados em Unix se espalharam, o termo também se espalhou por toda parte.
Algo que também ajudou muito na expansão do termo, foi o fato de o BSD e algumas variantes dele terem adotado um daemon como mascote, porém, temos que ressaltar que o símbolo do BSD é uma variante de artes cristãs. Pois as interpretações, formas e comportamentos de daemons são extremamente diferentes de uma crença para outra.
É interessante notar que os daemons são seres presentes na mitologia grega também, alguns deles eram responsáveis por realizar tarefas de forma a livrar os deuses do incômodo de realizá-las eles mesmos (faziam o trabalho sujo).
Alguns nomes alternativos para daemons são serviços (Windows), subsistema (IBM z/OS), servidor virtual (IBM VM) e tarefa fantasma (XDS UTS).
Implementação no Linux (Ubuntu)
Para a implementação de daemons no Linux vamos utilizar o comando chkconfig. Pelo menos no Xubuntu, que é a distribuição que estou usando no momento, ele não vem instalado por padrão. Por isso, vamos de apt-get (ou yum ou como for na sua distro):sudo apt-get install chkconfig
chkconfig
O chkconfig é um aplicativo de linha de comando que nos permite manipular a hierarquia do diretório /etc/rc[0-6].d liberando o administrador do sistema da tarefa de lidar diretamente com uma grande diversidade de links simbólicos usados nesses diretórios. Em português mais claro: o chkconfig serve para criar, listar ou modificar daemons.A implementação do chkconfig foi feita inspirada no comando chkconfig presente no sistema operacional IRIX. Ao invés de manter as informações de configurações fora da hierarquia de /etc/rc[0-6].d, o chkconfig gere diretamente os links simbólicos em /etc/rc[0-6].d. Isto faz com que todas as configurações relativas a quais serviços serão iniciados com o sistema fiquem reunidas em um só lugar.
Listar os serviços
Quando o chkconfig é executado sem nenhuma opção, ele lista os daemons e seus estados. Veja o resultado parcial da execução no meu computador:jayme@jayme-laptop:~$ chkconfig acpi-support 2345 acpid off alsa-mixer-save off anacron off apache2 on apparmor on apport off atd off aumix on avahi-daemon off binfmt-support on kerneloops on killprocs on rcS off rsync on umountfs 0 umountnfs.sh 0 umountroot 0 unattended-upgrades 0 urandom 0S wpa-ifupdown 0 x11-common on ...
A lista completa é mais que o triplo disso (
Agora, se um nome de serviço é fornecido, ele mostra as informações somente desse serviço, se ele existir. Veja:
jayme@jayme-laptop:~$ chkconfig rsync rsync on jayme@jayme-laptop:~$ chkconfig daemoninexistente daemoninexistente: unknown service
Podemos visualizar a lista de serviços passando o parâmetro --list. Ele mostra a mesma lista de quando executamos sem passar parâmetro algum, mais a lista de níveis de execução em que esse daemon está trabalhando. Não entraremos em detalhes sobre níveis de execução neste artigo, para mais informações leia este artigo aqui. O que é preciso saber mesmo é que cada nível de execução se refere um dos 7 arquivos do /etc/rc.d/rc0.d/ ao /etc/rc.d/rc6.d/ que são chamados em etapas definidas da inicialização do sistema.
Exemplo do uso do --list:
jayme@jayme-laptop:~$ chkconfig --list abrtd 0:off 1:off 2:off 3:on 4:off 5:on 6:off acpid 0:off 1:off 2:off 3:off 4:off 5:off 6:off atd 0:off 1:off 2:off 3:on 4:on 5:on 6:off
Para verificar quais são os processos que são inicializados juntos com o seu sistema é preciso saber em qual o nível de execução seu sistema é carregado. Geralmente isso ocorre no nível 3 e, por isso, nosso exemplo será nesse nível:
jayme@jayme-laptop:~$ chkconfig --list | grep 3:on acpi-support 0:off 1:off 2:on 3:on 4:on 5:on 6:off apache2 0:off 1:off 2:on 3:on 4:on 5:on 6:off aumix 0:off 1:off 2:on 3:on 4:on 5:on 6:off binfmt-support 0:off 1:off 2:on 3:on 4:on 5:on 6:off
Para verificar a configuração de inicialização de um serviço em especial, use, por exemplo:
jayme@jayme-laptop:~$ chkconfig --list apache2 apache2 0:off 1:off 2:on 3:on 4:on 5:on 6:off
Adicionar um novo serviço para a inicialização
Utilizamos a opção --add para adicionar um novo serviço a inicialização do sistema.O exemplo a seguir mostra como adicionar um novo serviço a lista de inicialização do sistema:
jayme@jayme-laptop:~$ chkconfig --list iptables jayme@jayme-laptop:~$ chkconfig --add iptables jayme@jayme-laptop:~$ chkconfig --list iptables iptables 0:off 1:off 2:on 3:on 4:on 5:on 6:off
Nota: chkconfig --add só adiciona um serviço já existente a lista de inicialização. Se o serviço não existir, primeiro você deverá instalá-lo ou criá-lo. É bem óbvio, mas é no óbvio, no básico, onde costumamos mais errar. Fique de olho.
Remover um serviço da lista de inicialização
O exemplo a seguir mostra que o serviço ip6tables está configurado para ser inicializado com o sistema:jayme@jayme-laptop:~$ chkconfig --list ip6tables ip6tables 0:off 1:off 2:off 3:on 4:off 5:off 6:offPara removê-lo da lista de inicialização, use a opção --del:
jayme@jayme-laptop:~$ chkconfig --del ip6tables jayme@jayme-laptop:~$ chkconfig --list | grep ip6tables
Ativar e desativar um serviço em algum nível de execução
Eventualmente você pode não querer apagar o serviço como um todo. Você pode querer só desativá-lo em alguns níveis de execução. O exemplo a seguir vai desativar o serviço nfsserver no nível 5:jayme@jayme-laptop:~$ chkconfig --level 5 nfsserver off
Você pode combinar vários níveis de uma vez também. Por exemplo, os níveis 3 e 5:
jayme@jayme-laptop:~$ chkconfig --level 35 nfsserver off
Scripts dentro da hierarquia de rc.d
Toda vez que você adicionar ou remover um serviço utilizando o chkconfig, ele faz o seguinte aos arquivos nos subdiretórios de /etc/rc.d:- chkconfig -add: cria links simbólicos para os comandos de início e parada do serviço adicionado nos diretórios rc correspondentes aos níveis definidos.
- chkconfig -del: remove o link simbólicos dos diretórios rc referentes aos níveis especificados.
O exemplo a seguir mostra um serviço chamado xinetd que esta habilitado para rodar tanto no level 3 quanto no 5.
Logo, o xinetd vai ter dois arquivos dentro do diretório rc3.d, e dois arquivos dentro de rc5.d. O arquivo cujo nome começa com K é usado ao desligar a máquina (K vem de kill). Já o arquivo que é usado para inicializar o seu processo é iniciado com S (S vem de start).
jayme@jayme-laptop:~$ chkconfig --list xinetd xinetd 0:off 1:off 2:off 3:on 4:off 5:on 6:offServiços baseados no xinetd:
jayme@jayme-laptop:~$ cd /etc/rc.d/rc3.d jayme@jayme-laptop:~$ ls | grep xinetd K08xinetd S14xinetd
jayme@jayme-laptop:~$ cd /etc/rc.d/rc5.d jayme@jayme-laptop:~$ ls | grep xinetd K08xinetd S14xinetdVeja os nomes dos arquivos obtidos com as iniciais para inicialização e desligamento. Para ilustrar, veja a listagem do conteúdo de /etc/rc4.d/ do meu sistema:
jayme@jayme-laptop:~$ chkconfig --list | grep 3:on jayme@jayme-laptop:~$ sudo ls -la /etc/rc4.d/* -rw-r--r-- 1 root root 677 2012-01-20 08:03 /etc/rc4.d/README lrwxrwxrwx 1 root root 20 2012-07-26 07:22 /etc/rc4.d/S20fancontrol -> ../init.d/fancontrol lrwxrwxrwx 1 root root 20 2012-07-26 07:22 /etc/rc4.d/S20kerneloops -> ../init.d/kerneloops lrwxrwxrwx 1 root root 15 2012-07-26 07:22 /etc/rc4.d/S21aumix -> ../init.d/aumix lrwxrwxrwx 1 root root 19 2012-07-26 07:22 /etc/rc4.d/S25bluetooth -> ../init.d/bluetooth lrwxrwxrwx 1 root root 14 2012-07-26 07:22 /etc/rc4.d/S50cups -> ../init.d/cups lrwxrwxrwx 1 root root 20 2012-07-26 07:22 /etc/rc4.d/S50pulseaudio -> ../init.d/pulseaudio lrwxrwxrwx 1 root root 15 2012-07-26 07:22 /etc/rc4.d/S50rsync -> ../init.d/rsync lrwxrwxrwx 1 root root 15 2012-07-26 07:22 /etc/rc4.d/S50saned -> ../init.d/saned lrwxrwxrwx 1 root root 19 2012-07-26 07:22 /etc/rc4.d/S70dns-clean -> ../init.d/dns-clean lrwxrwxrwx 1 root root 18 2012-07-26 07:22 /etc/rc4.d/S70pppd-dns -> ../init.d/pppd-dns lrwxrwxrwx 1 root root 24 2012-07-26 13:31 /etc/rc4.d/S90binfmt-support -> ../init.d/binfmt-support lrwxrwxrwx 1 root root 17 2012-07-26 13:31 /etc/rc4.d/S91apache2 -> ../init.d/apache2 lrwxrwxrwx 1 root root 22 2012-07-26 07:22 /etc/rc4.d/S99acpi-support -> ../init.d/acpi-support lrwxrwxrwx 1 root root 21 2012-07-26 07:22 /etc/rc4.d/S99grub-common -> ../init.d/grub-common lrwxrwxrwx 1 root root 18 2012-07-26 07:22 /etc/rc4.d/S99ondemand -> ../init.d/ondemand lrwxrwxrwx 1 root root 18 2012-07-26 07:22 /etc/rc4.d/S99rc.local -> ../init.d/rc.local
Note que no meu sistema, o caminho não é /etc/rc.d/rc4.d é /etc/rc4.d/. Conforme a distribuição com que você estiver trabalhando, a diferença de local pode ser maior ainda. Então fique atento.
Como iniciar um daemon/processo com o sistema
Bem, agora que já demos uma idéia básica sobre o chkconfig, vamos iniciar um. Primeiro, execute o comando:
insserv #se retornar isto sudo: insserv: command not found
Não precisa entrar em pânico. É só um link simbólico faltando no seu sistema que pode ser criado com o seguinte comando:
ln -s /usr/lib/insserv/insserv /sbin/insserv
Tente executar novamente. É para estar tudo ok. Aqui no meu computador é mostrada uma lista enorme de erros quando executo. Mas é porque há muitos serviços criados por métodos alternativos ao uso de chkconfig. Para sumir com as mensagens, seria necessário converter todos os serviços para chkconfig. O que, cá entre nós, é muito trabalho para pouco retorno.
Para iniciar o nosso daemon usando o chkconfig teremos que escrever um shell script chamando os serviços que queremos e seguir um layout padrão dele. Aqui está o script que montei para executar o django-celery na inicialização do sistema:
### BEGIN INIT INFO # Provides: djcelery # Required-Start: $remote_fs $syslog # Required-Stop: $remote_fs $syslog # Default-Start: 2 3 4 5 # Default-Stop: 0 1 6 # Short-Description: Start django celery daemon at boot time # Description: Enable service provided by daemon. ### END INIT INFO # chkconfig: 345 80 20 # description: django-celery daemon # processname: djcelery # /etc/init.d/djcelery case "$1" in start) echo -e "Starting djcelery service\n" #To run it as root: python /home/meuprojeto/wsgi/dev/meuprojeto/async_tasks/start_djcelery.py ;; stop) echo -e "Stopping djcelery\n" #To run it as root: #/path/to/command/to/stop/counter #Or to run it as some other user: #/bin/su - username -c /path/to/command/to/stop/counter #echo "." kill -9 `ps -ef | grep -i 'meuprojeto/manage.py celeryd' | grep -v grep | awk '{print $2}'` ;; *) echo "Usage: /etc/init.d/djcelery {start|stop}" exit 1 esac exit 0
No caso, o daemon já estava pronto. Era o daemon do django-celery que faz a comunicação entre o django e o celery (ferramenta similar ao cron). E permite que dentro do django possamos agendar tarefas. Bem útil isso. Enfim. O assunto é outro.
Note que há dois comandos aí dentro no case: start e stop. Sabe quando vamos iniciar ou parar, por exemplo, o apache? /etc/init.d/apache2 stop ou /etc/init.d/apache2 start. Vem daí. É preciso implementar cada um dos casos que quiser. Só o start e o stop que são obrigatórios. Já que é preciso iniciar e parar o daemon em algum momento e o sistema é quem fará isso por você.
Por padrão, crie o seu arquivo para chamar o seu daemon em /etc/init.d/. Depois dê a ele permissão de execução e execute o chkconfig:
chmod +x /etc/init.d/seuScript chkconfig seuScript
Se não houver nenhum erro de sintaxe, seu daemon/processo deverá ter sido adicionado a inicialização do sistema.
Como finalmente criar um daemon
Bem, um daemon é só um processo que não termina. Fica sempre realizando algumas operações de tempo em tempo ou o tempo todo. Ou seja, um daemon em si é muito simples de ser feito. O problema é integrá-lo ao sistema.Um exemplo de daemon bem simplérrimo em bash script:
while [ 1 ]; do echo "DAEMON EXEMPLO RODANDO"; sleep 10; #pausa de 10 segundos done;
Com isso, você pode por exemplo, fazer todas as suas operações na linguagem que preferir, e chamá-la de tempo em tempo através de um script simples como esse e gerenciá-lo através do outro script mais acima (o para a integração utilizando chkconfig).
Implementação de daemons(serviços) no Windows
Alguns exemplos e fontes para se criar seus próprios serviços no windows:
- Exemplo em Visual Basic
- Exemplo simples via shell (em inglês)
- Resposta do suporte da microsoft utilizando o sc.exe (em inglês)
- Exemplo em C# (em inglês)
Implementação de daemons independentes de SO
Como temos diversas linguagens feitas para trabalharem na web como Python, Java, PHP, ASP, etc. Podemos elaborar daemons utilizando-as, uma vez que vão funcionar em qualquer sistema operacional. Infelizmente, às vezes ocorrem alguns problemas por causa de alguma pequena diferença na implementação da linguagem de um sistema para outro, além de restrições do seu servidor.Um exemplo de implementação de um daemon em PHP pode ser visto aqui. Mas tome cuidado, um erro num laço infinito e toda a memória da sua máquina vai ser consumida rapidamente até sua máquina travar.
Neste fórum tem uma discussão de como criar daemons em Java.
E neste site tem um esqueleto de um código para criar daemons em Python.
Basta dar uma pesquisada por aí que tem até que bastante material sobre isso.
Espero ter sido útil! ;)
Fontes:
http://en.wikipedia.org/wiki/Daemon_(computing), http://pt.wikipedia.org/wiki/Daemon, http://pt.wikipedia.org/wiki/Daemon_(computa%C3%A7%C3%A3o), http://www.thegeekstuff.com/2011/06/chkconfig-examples/, http://www.linuxquestions.org/questions/linux-server-73/creating-an-initscript-that-chkconfig-identifies-829496/, http://loginroot.com/ubuntu-12-04-64bit-sbininsserv-no-such-file-or-directory/, http://carlo-hamalainen.net/blog/2012/05/13/insserv-warning-script-k01vmware-missing-lsb-tags-and-overrides/
5 comentários:
Muito bom o post, tirou todas as minhas duvidas..
Obrigado pelo compartilhamento!
Não tem por onde! ;)
realmente muito bom! me salvou na ultima parte do tcc
Muito bom artigo. muito util.
Parabéns! Muito explicativo, sem rodeios e simples.
Postar um comentário