În lista de discuții linux-api a fost propus (RFC) să se înlocuiească formatele binare depășite ale jurnalelor de sistem lastlog, btmp, utmp și wtmp cu noi biblioteci partajate care utilizează SQLite ca backend. Inițiativa are ca scop rezolvarea problemelor acumulate, printre care se numără depășirea contorilor de timp pe 32 de biți în 2038, lipsa de extensibilitate, performanța scăzută a interogărilor și lipsa atomicității la scriere.
În prezent, pentru stocarea datelor despre sesiuni și încercările de autentificare în Linux se utilizează următoarele fișiere binare cu structură fixă:
- /var/log/lastlog — время последнего входа (структура «struct lastlog» с полем «ll_time» 32-разрядного типа time_t);
- /var/log/btmp — неудачные попытки входа;
- /var/run/utmp — текущие сеансы;
- /var/log/wtmp — история входов и выходов.
Formatul de date al fișierelor a fost dezvoltat cu câteva decenii în urmă și prezintă o serie de limitări fundamentale:
- Câmpul „tv_sec” din structura „utmpx” și câmpul „ll_time” din „lastlog” au tipul „int32_t”, iar valoarea contoarelor de timp pe care se bazează va depăși limita pe 19 ianuarie 2038. Din cauza cerințelor de compatibilitate ABI, chiar și pe sistemele pe 64 de biți, aceste câmpuri rămân pe 32 de biți, astfel că problema va afecta toate instalațiile Linux.
- Dimensiunea fixă a înregistrărilor nu permite adăugarea de noi câmpuri (de exemplu, identificator de container, nume de serviciu, adresă IP) fără a înlocui complet formatul și a recompila toate utilitele.
- Utilitarele last, lastb, who și lastlog trebuie să parcurgă liniar conținutul fișierelor. În cazul unor jurnale foarte mari, fără utilizarea indecșilor care să permită filtrarea eficientă a înregistrărilor, încărcarea pe sistemul de intrare/ieșire și întârzierile în executarea interogărilor devin inacceptabile.
- Scrierea într-un fișier binar nu este o operațiune atomică. În caz de eșec, scrierea poate fi parțial coruptă.
- Pentru a exclude conflictele în timpul scrierii simultane în jurnale de către mai multe procese (de exemplu, sshd și login) se folosesc blocările flock, care nu garantează atomicitatea și pot duce la blocaje reciproce.
Autorul RFC propune renunțarea completă la formatele binare în favoarea bibliotecilor partajate specializate care utilizează SQLite. Pentru fiecare tip de jurnal se creează o bibliotecă separată cu o interfață C uniformă: liblastlog2, libbtmp2, libutmp2 și libwtmp2. Toate bibliotecile lucrează cu o bază de date al cărei schemă include timestamp-uri de 64 de biți (tip INTEGER) și indexuri pe utilizator și timp. Există posibilitatea adăugării de câmpuri noi fără a afecta compatibilitatea (prin ALTER TABLE).
Printre argumentele în favoarea utilizării SQLite se numără utilizarea tipului INTEGER de 64 de biți pentru stocarea timpului epocal, utilizarea indexurilor pentru a reduce I/O prin accesarea selectivă a înregistrărilor, în loc de o scanare completă, posibilitatea adăugării de câmpuri noi fără a schimba înregistrările existente, suportul pentru tranzacții ACID, modul WAL (Write-Ahead Logging) pentru acces concurent fără blocări, stabilitatea dovedită a SQLite.
Pentru a asigura o tranziție lină, se propune o strategie de „scriere dublă” (dual-write):
- Programele care scriu în fișiere binare (login, sshd, sudo, cron etc.) sunt modificate pentru a realiza simultan scrierea atât în fișierul binar vechi, cât și în noua bază de date SQLite prin biblioteca corespunzătoare.
- Se dezvoltă versiuni noi ale utilitarilor (last2, lastb2, who2, lastlog2) care citesc date din bazele de date SQLite, folosind indexuri pentru operare rapidă. Utilitarele vechi continuă să funcționeze cu fișierele anterioare.
- După câțiva ani, când majoritatea sistemelor vor fi actualizate, suportul pentru scrierea în formatele vechi poate fi dezactivat, iar utilitarele vechi pot fi declare învechite.
Întrebările propuse pentru discuții suplimentare:
- Raționamentul pentru separarea în biblioteci distincte sau combinarea într-una singură (de exemplu, libsession2).
- Alegerea numelui pentru biblioteci și utilitare (să păstrăm denumirile istorice sau să trecem la denumiri mai generale).
- Locația fișierelor bazei de date (/var/lib/ ca pentru starea aplicațiilor sau /var/log/ ca pentru jurnale).
- Mecanism de versionare a schemei și migrare.
- Parametrii de performanță SQLite pentru diferite scenarii (servere, sisteme încorporate).
- Furnizarea unui backend fallback care stochează jurnalele într-un format binar simplificat, pentru sistemele pe care SQLite ar putea fi redundant (de exemplu, dispozitive încorporate cu limitări stricte de memorie).
Sursa: opennet.ro
