Linux Debian

Uma Distribuição Linux (ou simplesmente distro) é um sistema operacional baseado no núcleo Linux, cuja maior parte do software é livre e de código aberto, estando disponível na forma de pacotes compilados previamente (binários), e de código-fonte. São mantidas por indivíduos, por grupos e organizações (como a Red Hat, o Mandriva, a Canonical, que desenvolve o Ubuntu, e a Novell, que mantém o Suse) e comunidades (como o Debian ou o Gentoo). Quase todas as distribuições linux são semelhantes ao sistema Unix, com excepção da distribuição Android, que não inclui interface de linha de comandos nem software para distribuições linux.

O Debian é a variante GNU/Linux mais popular entre servidores web, ou seja, boa parte da internet funciona baseada nele. Desenvolvido a mais de 20 anos, é utilizado desde usuários comuns até servidores de operações bancárias e até mesmo na Estação Espacial Internacional. Mesmo o Ubuntu, a distribuição Linux mais popular, é derivada do Debian – sua versão LTS (Long Term Support) é majoritariamente baseada no debian-testing. O nome Debian (procuncia-se ‘débian’) é uma contração de dois nomes: o de Ian Murdock (programador dos EUA fundador do projeto Debian), e sua namorada na época, Debra.

Na missão de trazer o controle das máquinas para as pessoas, sistemas operacionais livres desempenham um papel fundamental: você não pode estar no controle total de um dispositivo computacional se você não controla seu sistema operacional. O Debian é também um experimento social bastante particular, fortemente ligado à sua independência. Dentro do projeto, os voluntários tomam para si a responsabilidade de todas as atividades que são necessárias para manter o Debian vivo e andando, com suas variadas habilidades pessoais potencializadas em diferentes aplicações. Note que, assim, as escolhas do Debian não são voltadas a interesses comerciais de companhias específicas. Sua comunidade, que envolve milhares de pessoas trabalhando em diferentes “fronts”, é organizada por meritocracia: a autoridade é exercida por aqueles com o maior mérito, avaliado pelas ações passadas dentro do projeto.

Bruce Perens foi o segundo líder do projeto Debian, logo após Ian Murdock. Ele foi o responsável por inspirar os diferentes “codinomes” das versões do Debian, nomes de personagens do filme “Toy Story”. Este filme de animação composto inteiramente por computação gráfica foi produzida pela Pixar Studios, onde Bruce foi funcionário no momento em que esse liderou o projeto Debian. O nome “Sid” tem status especial, uma vez que será eternamente associado ao ramo Unstable (Instável). No filme, esse personagem era o filho vizinho que sempre quebrava os brinquedos – de outra forma, Sid também é um acrônimo de “Still In Development”. Os nomes podem ser vistos na wiki do Debian e na figura a seguir:

Versões Debian e seus codinomes baseados nos personagens de Toy Story. Montagem: ViniRoger.

O suporte a SMB/CIFS do Samba garante excelente comunicação em um contexto Windows. Ele compartilha arquivos e filas de impressão com clientes Windows e inclui software que permite a uma máquina Linux utilizar recursos disponíveis em um servidor Windows.

Instalação

O sistema Debian pode ser instalado a partir de mídias móveis (DV, CD, pendrive, etc) ou mesmo através da rede, a partir de uma imagem baixada gratuitamente do site e copiada para a mídia. Apesar de ser um processo relativamente simples, podem aparecer algumas particularidades, por isso foi feito um artigo só sobre a instalação do Linux Debian – clique no link para consultá-lo.

O software de detecção automática de hardware ajuda muito na instalação no Debian em cada computador. Para aumentar as possibilidades de uso do sistema operacional básico, é incluída uma biblioteca com milhares de softwares, disponível online através de muitos espelhos ao redor do mundo atualizados a cada seis horas, que podem ser baixados e instalados com apenas um comando.

O Gerenciador de Volume Lógico (Logical Volume Manager – LVM) usa uma terminologia particular: uma partição é um “volume lógico” (“logical volume”), que é parte de um “grupo de volumes” (“volume group”), ou uma associação de vários “volumes físicos” (“physical volumes”). Para maior entendimento dos diretórios e partições do Linux, consulte os posts Linux: Primeiros Passos e Particionamento de disco e inicialização de sistema.

O projeto tem simultaneamente três ou quatro versões diferentes de cada programa, para garantir compilação em diferentes arquiteturas e testes para correção de bugs: Experimental, Instável, Teste e Estável. Antes de ser lançado como “stable”, o software passa pelo período de congelamento (“freeze”), onde o desenvolvimento do “testing” é bloqueado; nenhuma atualização mais recente é permitida (apenas pelos gerentes de lançamento) para prevenir novos bugs. Novas versões são lançadas a cada 18 a 24 meses, evitando grandes atualizações em um período muito curto (ou muito longo). Geralmente é uma boa ideia mantê-la atualizada, de forma que possa se beneficiar das recentes evoluções, resolução de falhas de segurança e consertos de bug – o Debian possui um site com um Sistema de Acompanhamento de Bugs.

O Instalador Completamente Automático (FAI – Fully Automatic Installer) instala máquinas usando o sistema de empacotamento, mas ela também usa sua própria infraestrutura para tarefas que são mais específicas para implantações em massa (como iniciação, particionamento, configuração e assim por diante). Em vez de simplesmente duplicar uma instalação de referência, o FAI é um instalador de pleno direito (full-fledged), totalmente configurável através de um conjunto de arquivos e scripts armazenados no servidor. Isso permite economizar tempo para replicar a instalação em um sistema, com seus pacotes e configurações personalizadas. Veja mais sobre o Sistema de pacotes Debian clicando no link.

Alternativamente, existe o Preseeding, que permite fornecer um conjunto de respostas as perguntas do Debconf no momento da instalação através do arquivo “preseed.cfg”. Ou também o Simple-CDD: uma distribuição derivada do Debian, pela seleção de um subconjunto dos pacotes disponíveis, pré configuração deles com o Debconf, adição de software específico, e execução de scripts customizados no final do processo de instalação, de acordo com a sua necessidade. Um perfil é definido por um conjunto de arquivos “profiles/profile.*” e cuja imagem ISO é construída através do comando “build-simple-cdd”.

Padronização

No final da década de 80, duas diferentes e, de certo modo, incompatíveis versões do Unix eram amplamente usadas: a BSD (Berkeley Software Distribution) e o System V (da AT&T). Além disso, cada fabricante incluía seus próprios aprimoramentos não padronizados. Essa divisão no mundo Unix, somada ao fato de que não existiam padrões para os formatos dos programas binários, inibiu bastante o sucesso comercial do Unix.

O padrão POSIX (um acrônimo para “Portable Operating System Interface”, ou “Interface Portável entre Sistemas Operacionais”) é uma família de normas definidas pelo IEEE (Instituto de Engenheiros Eletricistas e Eletrônicos) para a manutenção de compatibilidade entre sistemas operacionais (interface de programação de aplicações, shells de linha de comando, interfaces utilitárias, etc), designada formalmente por IEEE 1003. É constituído por uma série de regras que determinam como o programador deve escrever o código-fonte de seu sistema de modo que ele possa ser portável entre os sistemas operacionais baseados no Unix. Portável nesse caso significa que bastará recompilar o programa, usando o compilador adequado para torná-lo compatível com o sistema desejado, sem a necessidade de fazer alterações no código fonte.

Existem alguns programas utilitários comuns no Unix exigidos pelo POSIX, como o cat, grep, ls, etc. A maioria das opções dos comandos estão disponíveis em uma versão “longa” (uma ou mais palavras relevantes, precedidas de traço duplo) e uma versão “curta” (uma única letra, geralmente a inicial de uma palavra da versão longa, e precedida de um traço).

Scripts de inicialização

O BIOS (Basic Input/Output System ou Sistema Básico de Entrada/Saída) é um programa de computador pré-gravado em memória permanente (firmware) executado por um computador quando ligado. Ele é responsável pelo suporte básico de acesso ao hardware, bem como por iniciar o carregamento do sistema operacional. Veja mais detalhes no post sobre Particionamento de disco e inicialização de sistema.

O kernel (núcleo) tem como principal tarefa a de controlar as partes do hardware – também torna disponíveis para o software de alto nível com uma interface de programação simplificada, para que os aplicativos possam tirar proveito de dispositivos sem ter que se preocupar com detalhes de hardware. Após o carregamento do sistema, o kernel é carregado na memória, junto com os dispositivos que estão no /etc/fstab e no /etc/dev. O kernel exporta muitos detalhes sobre o hardware detectado através dos sistemas de arquivos virtuais /proc/ e /sys/. As aplicações acessam frequentemente os dispositivos por meio de arquivos especiais criados dentro de /dev/: unidades de disco (/dev/hda,/dev/sdc, etc), partições (/dev/hda1,/dev/sdc3, etc), mouses (/dev/input/mouse0), teclados (/dev/input/event0), placas de som (/dev/snd/*), portas seriais (/dev/ttyS*), etc.

A BIOS pega o controle sobre o computador, detectando discos e carregando a Master Boot Record (contém a informação da estrutura organizacional do disco), e executa o bootloader (programa que acessa o disco do computador e carrega o sistema operacional na memória). O bootloader assume, localiza o kernel no disco, carrega e executa. O kernel é então inicializado e começa a pesquisa pela partição e monta a partição contendo o sistema raiz e finalmente o primeiro programa: init.

A “partição raiz” e este init são localizados em um sistema de arquivos virtual que só existe na RAM (daí o seu nome, “initramfs”, anteriormente chamado de “initrd” para “initialization RAM disk”). Este sistema de arquivos é carregado na memoria pelo bootloader, muitas vezes a partir de um arquivo em um disco rígido ou da rede (no caso de um computador sem HD, por exemplo). Ele contém o mínimo exigido pelo kernel para carregar o sistema de arquivos raiz “verdadeiro”. Uma vez que a partição raiz é montada, o initramfs libera o controle para o “init real”, e a máquina voltará para o processo de boot padrão.

O init “real” é responsável por checar a integridade das partições, rodar os serviços da máquina e outras coisas – o Debian usa o estilo “systemd” como default desde a versão 8, sendo utilizado antes o “System V”. Em primeiro lugar, um processo pode se clonar (processo conhecido como “fork” ou divisão), ou seja, aloca um novo, mas idêntico, espaço de memória do processo, e um outro processo para usá-lo com um novo PID – o primeiro processo é chamado de pai e o seguinte de filho. Em muitos casos, este processo filho executa outro programa, sendo sua memória simplesmente substituída pela do novo programa e assim por diante. Em algum momento, um dos processos descendentes do init começa uma interface gráfica para os usuários iniciarem sua sessão, por exemplo. Quando um processo termina a tarefa para a qual ele foi iniciado, ele termina.

Os scripts são armazenados em /etc/init.d e links simbólicos são criados durante a instalação de pacotes pelo programa update-rc.d em /etc/rcX.d, onde o X representa o runlevel. Esses links estão no seguinte formato “SNNnome” (devem ser iniciados) e “KNNnome” (devem ser matados) – NN é um número qualquer que define a ordem de execução.

Sequência de inicialização de um computador rodando Linux. Fonte: Debian Hand Book.
Sequência de inicialização de um computador rodando Linux. Fonte: Debian Hand Book.

No final da inicialização, o init começa a controlar programas para vários consoles virtuais (getty). Ele exibe um prompt, esperando por um nome de usuário, em seguida, executa o usuário login user para iniciar uma sessão.

Todo script do /etc/init.d (e consequentemente dos /etc/rc?.d) suporta os argumentos “start”, “stop” e “restart” que podem ser usados para iniciar, parar e reiniciar os serviços, respectivamente. São conhecidos como “daemons” e seu nome finaliza com a letra “d”. Por exemplo, para reiniciar o servidor apache, executa-se “/etc/init.d/apache restart”. O “update-rc.d” é uma ferramenta de gerenciamento de scripts de inicialização.

Para mudar de runlevel, o comando é “sudo init level_number”. O diretório /etc/init/ possui os arquivos de configuração dos processos inicializados pelo init. Os links simbólicos dos scripts executados quando o sistema entra no runlevel X estão no diretório /etc/rcX.d, onde X pode ter valor de 0 a 6 ou o valor S. Scripts começando com “S” (Start) são serviços iniciados; aqueles que iniciam com “K” (Kill) são os serviços interrompidos. Veja o que são cada um dos níveis:

  • 0 – Modo de desligamento para todos os serviços e desliga a máquina
  • 1 – Modo de manutenção (single user). Usado em casos criticos como por exemplo recuperar senha do root ou dá manutenção no sistema. Apenas o usuário root pode executar nesse nível
  • S – Carrega os serviços essenciais para o sistema, modo similiar ao “1”
  • 2 – Modo multiusuário, usado para rodar o sistema básico em modo texto sem serviços de rede. Uso para fazer update do sistema ou atualizações em massa
  • 3 – Modo multiusuário, roda em modo texto com serviços de rede disponiveis, como samba, ssh e etc
  • 4 – Por padrão, não é usado em distros debian e RedHat, mas uso como multiusuário em modo gráfico sem sem serviços de rede
  • 5 – Modo multiusuário, usado para rodar o ambiente gráfico junto com serviços de rede
  • 6 – Modo de reinicialização do sistema. Todos os serviços são parados e a máquina e reiniciada

O init é o último processo carregado pelo kernel. Um “daemon” (serviço) é um processo iniciado automaticamente pela sequência de inicialização – recebe esse nome para ser entendido como uma espécie de espírito ajudante. Ele continua em execução (em segundo plano, ou seja, sem interação do usuário e sem qualquer interface gráfica) para executar as tarefas de manutenção ou prover serviços a outros processos. O “processo pai” de um daemon é normalmente (mas nem sempre) o processo init (PID=1). O comando “pstree” mostra a árvores de processos que estão rodando no computador.

Veja um exemplo do que acontece durante a execução do comando “ls | sort” no bash de PID 4374:

  1. O shell interpreta o comando digitado nele, entendendo que existem dois programas (ls e sort) com um fluxo de dados que flui de um para o outro (caractere “pipe”); assim, o bash primeiro cria um pipe sem nome (que inicialmente só existe dentro do processo bash em si);
  2. O shell se clona, o que leva a um novo processo bash de PID 4521;
  3. O processo filho herda o pipe, o que significa que é capaz de escrever em seu lado “input”;
  4. O bash redireciona seu fluxo de saída padrão para a entrada deste pipe;
  5. O processo filho executa (e substitui-se com) o programa ls, que lista o conteúdo do diretório atual;
  6. Uma operação similar acontece para o segundo comando: o bash se clona novamente, levando a um novo processo bash com pid #4522. Como também é um processo filho do #4374, também herda o pipe; em seguida o bash conecta sua entrada padrão para a saída do pipe, então executa (e se substitui com) o sort, que classifica sua entrada e exibe os resultados;
  7. Os processos números #4521 e #4522 encerram, e o #4374 (que estava esperando por eles durante a operação), retoma o controle e exibe o prompt, permitindo que o usuário digite um novo comando.

Bibliotecas de funções não são programas propriamente dito, uma vez que não podem ser executados por si próprios, mas coleções de fragmentos de código que podem ser utilizados pelos programas normais. Entre as bibliotecas comuns, estão a a biblioteca padrão C (glibc), que contém as funções básicas como aqueles para abrir arquivos ou conexões de rede e outras que facilitam as interações com o kernel, toolkits gráficos, como Gtk+ e o Qt, e a libpng, que permite carregar, interpretar e salvar imagens no formato PNG.

Os executáveis vinculados dinamicamente são programas muito menores e incompletos do que os executáveis vinculados estaticamente, ou seja, eles precisam de funções de bibliotecas compartilhadas externas para serem executados. Muitas bibliotecas são compiladas em versões 32 (/lib32) e de 64 bits (/lib64) – o diretório “/lib” contém libraries essenciais que podem ser necessárias mesmo em modo “single-user”. O comando “ldd” exibe se são executáveis estáticos ou dinâmicos e as dependências das bibliotecas compartilhadas informadas como argumento.

A biblioteca vista como linux-vdso.so.1 é uma biblioteca virtual ou um Objeto Compartilhado Dinâmico Virtual, que reside somente no espaço de endereço de cada programa. Antigamente, no começo dos processadores x86, as comunicações dos programas do usuário para os serviços do supervisor eram realizadas através da interrupção de um software. Já ld-linux.so.2 e ld-linux-x86-64.so.2 são o código responsável pelo carregamento dinâmico. Elas leem as informações do cabeçalho do executável, que está no formato Executable and Linking Format (ELF), e determinam quais bibliotecas são necessárias para serem carregadas. O loader dinâmico sabe onde procurar os executáveis através do arquivo de configuração “/etc/ld.so.conf” e “/etc/ld.so.conf.cache”, lido pelo programa ldconfig.

É possível definir a variável LD_LIBRARY_PATH para uma lista de diretórios separados por sinais de dois pontos, onde se deve procurar por bibliotecas compartilhadas antes das bibliotecas do sistema especificadas em ld.so.cache. Isso é comum para aplicativos mais antigos, que necessitem de outra versão de biblioteca, ou no desenvolvimento de uma nova biblioteca compartilhada. Para exportar essa variável (inclui-la em processos filho como variável do ambiente), usa-se o comando export.

Codificação de caracteres

O comando locale lista um resumo da configuração atual de vários parâmetros do locale (formato de data, formato de números, etc.), apresentados na forma de um grupo de variáveis de ambiente padrão dedicadas à modificação dinâmica destas configurações. Essas variáveis geralmente estão na forma código-de-idioma_CÓDIGO-DE-PAÍS, algumas vezes com um sufixo para especificar o conjunto de caracteres e codificação a ser usado – a recomendada no Brasil é “pt_BR.UTF-8”. A apresentação abaixo explica muita coisa sobre codificação:

As codificações mais populares para idiomas latinos são limitadas a 256 caracteres, pois usam um único byte para cada caractere. Como isso não é o suficiente para cobrir todas as línguas européias, são necessárias codificações múltiplas, e assim surgiram a ISO-8859-1 (também conhecido como “Latin 1”) até o ISO-8859-15 (ou “Latin 9”), entre outros.

O Unicode (um super catálogo de quase todos os sistemas de escrita de todas as línguas do mundo) foi criado para evitar trocas de codificação. Uma das codificações Unicode, UTF-8, retém todos os 128 símbolos ASCII (códigos 7-bits), mas lida com outros caracteres diferentemente. Estes outros são precedidos por uma sequencia de escape específica de poucos bits, que implicitamente define o tamanho do caractere, o que permite a codificação de todos os caracteres Unicode em uma sequência de um ou mais bytes. Seu uso foi popularizado pelo fato de ser a codificação padrão em documentos XML e nos sistemas Debian.

Consulta

Esse post é um estudo baseado em alguns pontos do livro “O Manual do Administrador Debian” – uma documentação livre, que pode ser distribuída e/ou modificada dentro dos termos da Licença Pública Geral GNU, como publicada pela Fundação do Software Livre, na versão 2 da Licença. Mais informações gerais dos sistemas Linux podem ser vistas no post “Linux: primeiros passos“.

3 comments

Leave a Reply

O seu endereço de e-mail não será publicado. Campos obrigatórios são marcados com *

Esse site utiliza o Akismet para reduzir spam. Aprenda como seus dados de comentários são processados.