The linux-api mailing list has proposed (RFC) to replace outdated binary formats of system logs lastlog, btmp, utmp, and wtmp with new shared libraries using SQLite as the backend. The initiative aims to address accumulated issues, including the overflow of 32-bit timestamps in 2038, lack of extensibility, low query performance, and the absence of atomicity in writes.
Currently, the following binary files with a fixed structure are used in Linux for storing session data and authentication attempts:
- /var/log/lastlog — время последнего входа (структура «struct lastlog» с полем «ll_time» 32-разрядного типа time_t);
- /var/log/btmp — неудачные попытки входа;
- /var/run/utmp — текущие сеансы;
- /var/log/wtmp — история входов и выходов.
The data format of these files was developed several decades ago and has a number of fundamental limitations:
- The 'tv_sec' field in the 'utmpx' structure and the 'll_time' field in 'lastlog' are of type 'int32_t', and the time counter values are subject to overflow on January 19, 2038. Due to ABI compatibility requirements, these fields remain 32-bit even on 64-bit systems, meaning the issue will affect all Linux installations.
- The fixed size of records does not allow for adding new fields (for example, container ID, service name, IP address) without completely replacing the format and recompiling all utilities.
- Les utilitaires last, lastb, who et lastlog doivent parcourir linéairement le contenu des fichiers. En cas de journaux volumineux sans utilisation d'index permettant de filtrer efficacement les enregistrements, la charge sur le système d'entrée/sortie et les délais d'exécution des requêtes deviennent inacceptables.
- L'écriture dans un fichier binaire n'est pas une opération atomique. En cas de défaillance, l'écriture peut être partiellement corrompue.
- Pour éviter les conflits lors d'écritures simultanées dans le journal par plusieurs processus (par exemple, sshd et login), des verrous flock sont utilisés, qui ne garantissent pas l'atomicité et peuvent entraîner des blocages mutuels.
L'auteur de la RFC propose d'abandonner complètement les formats binaires au profit de bibliothèques partagées spécialisées utilisant SQLite. Pour chaque type de journal, une bibliothèque distincte avec une interface C uniforme est créée : liblastlog2, libbtmp2, libutmp2 et libwtmp2. Toutes les bibliothèques travaillent avec des bases de données dont le schéma comprend des horodatages de 64 bits (type INTEGER) et des index par utilisateur et par temps. Il est possible d'ajouter de nouveaux champs sans compromettre la compatibilité (via ALTER TABLE).
Parmi les arguments en faveur de l'utilisation de SQLite, on mentionne l'utilisation d'un type INTEGER 64 bits pour stocker le temps épique, l'utilisation d'index pour réduire l'entrée/sortie par l'accès sélectif aux enregistrements au lieu d'un balayage complet, la possibilité d'ajouter de nouveaux champs sans modifier les enregistrements existants, le support des transactions ACID, le mode WAL (Write-Ahead Logging) pour l'accès concurrent sans blocages, et la fiabilité éprouvée de SQLite.
Pour assurer une transition en douceur, une stratégie de « double écriture » (dual-write) est proposée :
- Les programmes qui écrivent dans des fichiers binaires (login, sshd, sudo, cron, etc.) sont modifiés pour effectuer simultanément des écritures dans l'ancien fichier binaire et dans la nouvelle base de données SQLite via la bibliothèque correspondante.
- De nouvelles versions des utilitaires (last2, lastb2, who2, lastlog2) sont en cours de développement pour lire les données des bases SQLite, utilisant des index pour un fonctionnement rapide. Les anciens utilitaires continuent de fonctionner avec les anciens fichiers.
- Dans quelques années, lorsque la grande majorité des systèmes seront mis à jour, le support pour l'écriture dans les anciens formats pourrait être désactivé, et les anciens utilitaires pourraient être déclarés obsolètes.
Les questions soulevées pour discussion supplémentaires :
- La pertinence de diviser en bibliothèques distinctes ou de regrouper en une seule (par exemple, libsession2).
- Choix des noms pour les bibliothèques et les utilitaires (maintenir les noms historiques ou passer à des noms plus généraux).
- Emplacement des fichiers de bases de données (/var/lib/ comme pour l'état des applications ou /var/log/ comme pour les journaux).
- Mécanisme de versioning du schéma et de migration.
- Paramètres de performance SQLite pour différents scénarios (serveurs, systèmes embarqués).
- Fournir un backend fallback qui stocke les journaux dans un format binaire simplifié pour les systèmes où SQLite peut s'avérer redondant (par exemple, dispositifs embarqués avec des contraintes de mémoire strictes).
Source : opennet.ru
