Na lista de discussão linux-api, foi proposta (RFC) a substituição dos formatos binários obsoletos dos logs do sistema lastlog, btmp, utmp e wtmp por novas bibliotecas compartilhadas que utilizam SQLite como backend. A iniciativa visa resolver problemas acumulados, entre os quais estão a passagem do contador de tempo de 32 bits em 2038, a falta de escalabilidade, baixo desempenho nas consultas e a ausência de atomicidade nas gravações.
Atualmente, os seguintes arquivos binários com estrutura fixa são utilizados para armazenamento de dados sobre sessões e tentativas de autenticação no Linux:
- /var/log/lastlog — время последнего входа (структура «struct lastlog» с полем «ll_time» 32-разрядного типа time_t);
- /var/log/btmp — неудачные попытки входа;
- /var/run/utmp — текущие сеансы;
- /var/log/wtmp — история входов и выходов.
O formato dos dados desses arquivos foi desenvolvido há várias décadas e possui uma série de limitações fundamentais:
- O campo "tv_sec" na estrutura "utmpx" e o campo "ll_time" em "lastlog" são do tipo "int32_t", cujos contadores de tempo vão estar saturados em 19 de janeiro de 2038. Devido a requisitos de compatibilidade ABI, mesmo em sistemas de 64 bits, esses campos permanecem com 32 bits, portanto, o problema afetará todas as instalações do Linux.
- O tamanho fixo dos registros não permite a adição de novos campos (por exemplo, identificador do contêiner, nome do serviço, endereço IP) sem uma substituição total do formato e recompilação de todas as utilidades.
- As utilidades last, lastb, who e lastlog são forçadas a percorrer linearmente o conteúdo dos arquivos. Com grandes logs, a falta de índices que possibilitem filtrar registros de forma eficiente torna a carga no sistema de entrada/saída e a latência nas execuções das consultas inaceitáveis.
- A gravação em um arquivo binário não é uma operação atômica. Em caso de falha, a gravação pode estar parcialmente corrompida.
- Para evitar conflitos durante gravações simultâneas em logs por vários processos (por exemplo, sshd e login), são usadas bloqueios flock, que não garantem atomicidade e podem levar a deadlocks.
O autor do RFC propõe abandonar completamente os formatos binários em favor de bibliotecas compartilhadas especializadas que utilizam SQLite. Para cada tipo de registro, é criada uma biblioteca separada com uma interface C padronizada: liblastlog2, libbtmp2, libutmp2 e libwtmp2. Todas as bibliotecas trabalham com um banco de dados cuja estrutura inclui timestamps de 64 bits (tipo INTEGER) e índices por usuário e tempo. Há a possibilidade de adicionar novos campos sem comprometer a compatibilidade (por meio do ALTER TABLE).
Entre os argumentos a favor do uso do SQLite, menciona-se a utilização do tipo INTEGER de 64 bits para armazenar tempos de época, o uso de índices para reduzir a entrada/saída por meio da consulta seletiva de registros em vez da varredura completa, a possibilidade de adicionar novos campos sem modificar os registros existentes, suporte a transações ACID, e o modo WAL (Write-Ahead Logging) para acesso concorrente sem bloqueios, além da confiabilidade comprovada do SQLite.
Para garantir uma transição suave, é proposta uma estratégia de 'dupla escrita' (dual-write):
- Programas que escrevem em arquivos binários (login, sshd, sudo, cron etc.) serão modificados para que possam realizar a gravação simultaneamente tanto no antigo arquivo binário quanto na nova base de dados SQLite através da biblioteca correspondente.
- Novas versões de utilitários (last2, lastb2, who2, lastlog2) estão sendo desenvolvidas para ler dados das bases SQLite, utilizando índices para operações rápidas. Os antigos utilitários continuarão funcionando com os arquivos anteriores.
- Após alguns anos, quando a maioria dos sistemas tiver sido atualizada, o suporte para gravação em formatos antigos poderá ser desativado, e os utilitários antigos poderão ser considerados obsoletos.
Questões propostas para discussão adicional:
- A viabilidade da divisão em bibliotecas separadas ou da união em uma só (por exemplo, libsession2).
- A escolha dos nomes para as bibliotecas e utilitários (manter os nomes históricos ou passar para denominações mais gerais).
- A localização dos arquivos de banco de dados (/var/lib/ como para o estado das aplicações ou /var/log/ como para logs).
- O mecanismo de versionamento do esquema e migração.
- Os parâmetros de desempenho do SQLite para diferentes cenários (servidores, sistemas embarcados).
- Fornecimento de um backend de fallback que armazena logs em um formato binário simplificado para sistemas onde o SQLite pode ser excessivo (por exemplo, dispositivos embarcados com severas limitações de memória).
Fonte: opennet.ru
