quarta-feira, 16 de setembro de 2009

Como Trabalha o Kernel do Linux

Definição da palavra Kernel em um dicionario de Ingles/Ingles:

1.
the inner and usually edible part of a seed or grain or nut or fruit stone
2.
a single whole grain of a cereal
3.
the choicest or most essential or most vital part of some idea or experience
Com isso temos a idéia de que é algo muito importante, pequeno, o centro, o nucleo. O kernel  é o nucleo do Sistema Operacional. Esse nucleo fica constantemente em memoria e é responsavel pela execução das funções mais baixas do sistema como:
  • Gerenciamento dos recursos de Hardware;
  • Gerenciamento de memoria;
  • Controle das operações I/O;
  • Gerenciamento de processos ;
  • Gerenciamento das operações multiusuario/multitarefa;
  • Gerenciamento do Sistema de Arquivos;
O nucleo não faz nada diretamente com o usuario. Todos os serviços são solicitados por programas utilitarios que são interpretados pelo interpretador de comandos e passados ao nucleo.

Entendendo o Kernel
O Kernel disponibiliza serviço para os aplicativos rodando através de inúmeros pontos de entradas conhecidas como chamadas de sistema (system calls).
O kernel utiliza chamadas de sistemas como leitura e escrita para prover acesso ao hardware.

Do ponto de vista de um programador isso parece uma função comum, embora na realidade uma chamada de sistema envolva diferentes interruptores no modo de operação "kernel space"  para o "user space" . Juntos esse conjunto de chamadas de sistema formam uma especie de "maquina virtual" que trabalha antes do hardware real. Um exemplo claro disso é o sistema de arquivos.

Agora que entendemos melhor o que o kernel faz, vamos olhar  mais atentamente a sua organização física. As primeiras versões do kernel eram monoliticas, ou seja, todos os modulos estava compilados dentro de um unico arquivo executavel. O kernel das distribuições mais novas são modulares, ou seja, os modulos podem ser carregados no kernel em tempo de execução, isso faz com que o nucleo do kernel fique menor e não seja necessario reiniciar a maquina para carregar ou substituir novos modulos.
O nucleo do kernel é carregado na memoria na hora do boot e é lido de um arquivo no diretorio "/boot" na maioria das vezes este arquivo é chamado de "vmlinuz-versão_do_kernel". Para ver a versão do kernel corrente utilize o comando:

uname -r

Os modulos ficam no diretorio "/lib/modules/VERSAO_DO_KERNEL"

Gerenciando Modulos

Veremos agora alguns comandos para gerenciar os modulos do seu kernel, como por exemplo o comando para listar os modulos carregados que é o "lsmod", o lsmod vai mostrar uma saída semelhante a esta:


Module                         Size     Used by
vfat                                14464   0
isofs                              36388   0
fat                                  54556   1 vfat
nfs                                 26540   0
lockd                             67720   1 nfs

Esta saida possui quatro campos dividios por nome do modulo que esta carregado, o tamanho do modulos , quantas vezes ele esta sendo utilizado e quais modulos que dependem dele. Podemos carregar um modulo utilizando o comando "modprobe" (podemos tambem utilizar o comando "insmod" porem o modprobe é mais aconselhavel pois ele resolve as dependencias do modulo). Outro ponto muito importante na saída do comando lsmod é o terceiro campo que indica a quantidade de vezes que o modulo esta sendo utilizado pois o linux não vai permitir a removacao de um modulo cujo o campo used seja diferente de zero, no exemplo acima vemos o modulo "isofs" (utilizado para dar suporte ao sistema de arquivos "ISO" que é utilizado em CD's) como o campo used "0" , neste caso podemos remover o modulo com o comando modprobe -r isofs", apos executar este comando o modulo isofs nao vai mais aparecer  quando executarmos o lsmod.
Não é muito comum carregar modulos manualmente no dia a dia, porem se voce precisar carregar um modulo manualmente voce pode incluir parametros especificos de cada modulo para carrega-lo como no exemplo a seguir:

modprobe usb_storage delay_use:3

No exemplo acima habilitamos o parametro "delay_use:3" para o modulo "usb_storage" que define um time-out de 3 segundos para o modulo procurar um novo device. Para saber quais as opções de cada modulo utilizamos  o comando modinfo como no exemplo a seguir:

modinfo usb_storage
filename: /lib/modules/2.6.27.29-0-default/kernel/drivers/usb/storage/usb-storage.ko
license: GPL
description: USB Mass Storage driver for Linux
autor: Matthew Dharm
srcversion: 99E0B653929DE200DF6AF9
depends: libusual,usbcore,scsi_mod
vermagic: 2.6.24-generic SMP mod_unload 586
param: delay_use:seconds to delay before using a new device (uint)

A linha que nos interessa neste caso é a que começa com "param" que mostra os parametros aceitos pelo modulo. Caso voce possua a source do kernel voce tambem pode encontrar uma documentação muito util em /usr/srv/versao_kernel/Documentation/kernel-parameters.txt

Sistema de arquivos /proc

kernel tambem nos fornece inumeras informações que podem ser encontradas no sistema de arquivos "/proc", os arquivos no /proc são criados pelo kernel (alguns voce pode alterar, outros não) um exemplo claro do tipo de informação que podemos encontrar no /proc esta no arquivo /proc/modules que mostra todos os moduls carregados no sistema , no arquivo /proc/meminfo que mostra o status detalhado da memoria do sistema e também o arquivo /proc/net/arp que mostra a tabela ARP.
Dos arquivos citados acima, nenhum pode ser alterado, porem existem arquivos dentro do /proc que podem ser manipulados, como por exemplo o /proc/sys/net/ipv4/ip_forward

echo 1 > /proc/sys/net/ipv4/ip_forward

Agora o encaminhamento de pacotes IP esta habilitado. Outro comando que também pode ser utilizado para executar a mesma tarefa é o "sysctl" como no exemplo a seguir:

sysctl net.ipv4.ip_forward
net.ipv4_ip_forward = 0

Acima sometne visualizamos o valor do ip_forward, para alterar esse valor utilizamos o comando sysctl como abaixo:

sysctl -w net.ipv4.ip_forward = 1

Porem tem um pequeno problema aqui, se reiniciarmos a maquina este arquivo voltara a ter conteudo igual a "0". E como solucionamos isso? A solução é muito simples, utilizamos o arquivo /etc/sysctl.conf para definir os valores que serão carregados em tempo de boot, basta acrescentar a linha abaixo no arquivo /etc/sysctl.conf

net.ipv4.ip_forward = 1

Melhorando a performance.

Muitos dos parametros do /proc/sys que permitem escrita podem ser utilizados para melhorar a performance do Linux, apesar de que a configuração padrão já habilite opções que trabalham muito bem. Um exemplo de como podemos modificar o kernel para melhorar a performance de acordo com o tipo de aplicação que voce vai utilizar esta no guia de instalação do Informix que pede para configurar alguns parametros como o "kernel.shmmax=4398046511104" que define o tamanho maximo de segmento de memoria partilhada para 4GB. (Memoria partilhada é um mecanisco de comunicação entre processos que permite que um segmento de memoria de ser visivel dentro do espaço de endereçamento de multiplos processos.)
Outra modificação que podemos fazer e definir que nossa maquina não vai responder por broadcast de icmp ( o bom e velho ping -b 255.255.255.255) configurando o sysctl da seguinte forma:

sysctl -w net.ipv4.icmp_echo_ignore_broadcasts=1

Agora fica a duvida, para ver os valores eu vou ter que dar cat de arquivo em arquivo ou saber todos os caminhos do comando sysctl? Claro que não, basta utilizar o comando 
sysctl -a

ele vai exibir todos os parametros e seus valores porem ele na fala para que serve cada um deles, porem isso podemos encontrar os detalhes no bom e velho "man proc".

Abraços. 

Nenhum comentário:

Postar um comentário